@memori.ai/memori-react 8.45.1 → 8.45.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -0
- package/dist/components/Chat/Chat.js +4 -1
- package/dist/components/Chat/Chat.js.map +1 -1
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.d.ts +4 -1
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js +7 -57
- package/dist/components/ChatHistoryDrawer/ChatResumeDrawer.js.map +1 -1
- package/dist/components/IconButton/IconButton.d.ts +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.d.ts +1 -1
- package/dist/components/MemoriWidget/MemoriWidget.js +2 -1
- package/dist/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/dist/components/PositionPopover/PositionPopover.js +38 -25
- package/dist/components/PositionPopover/PositionPopover.js.map +1 -1
- package/dist/components/UploadButton/UploadButton.js +3 -0
- package/dist/components/UploadButton/UploadButton.js.map +1 -1
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js +14 -2
- package/dist/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/dist/components/layouts/chat.css +27 -4
- package/dist/context/widgetSurfaceContext.js +2 -2
- package/dist/context/widgetSurfaceContext.js.map +1 -1
- package/dist/helpers/constants.d.ts +3 -2
- package/dist/helpers/constants.js +19 -20
- package/dist/helpers/constants.js.map +1 -1
- package/dist/helpers/positionPopover.d.ts +2 -1
- package/dist/helpers/positionPopover.js +12 -3
- package/dist/helpers/positionPopover.js.map +1 -1
- package/dist/helpers/tts/muteSpeaker.js +4 -3
- package/dist/helpers/tts/muteSpeaker.js.map +1 -1
- package/dist/helpers/usePressTooltip.js +2 -1
- package/dist/helpers/usePressTooltip.js.map +1 -1
- package/dist/helpers/utils.d.ts +2 -1
- package/dist/helpers/utils.js +7 -1
- package/dist/helpers/utils.js.map +1 -1
- package/dist/icons/MemoriIcon.js +1 -1
- package/dist/icons/MemoriIcon.js.map +1 -1
- package/dist/styles.css +1 -2
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/esm/components/Chat/Chat.js +4 -1
- package/esm/components/Chat/Chat.js.map +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.d.ts +1 -1
- package/esm/components/MemoriWidget/MemoriWidget.js +2 -1
- package/esm/components/MemoriWidget/MemoriWidget.js.map +1 -1
- package/esm/components/UploadButton/UploadButton.js +4 -1
- package/esm/components/UploadButton/UploadButton.js.map +1 -1
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js +16 -4
- package/esm/components/UploadButton/UploadDocuments/UploadDocuments.js.map +1 -1
- package/esm/components/layouts/chat.css +27 -4
- package/esm/helpers/constants.d.ts +3 -2
- package/esm/helpers/constants.js +18 -19
- package/esm/helpers/constants.js.map +1 -1
- package/esm/helpers/utils.d.ts +2 -1
- package/esm/helpers/utils.js +6 -1
- package/esm/helpers/utils.js.map +1 -1
- package/esm/styles.css +1 -2
- package/esm/version.d.ts +1 -1
- package/esm/version.js +1 -1
- package/package.json +6 -7
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.d.ts +0 -3
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.js +0 -64
- package/dist/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.js.map +0 -1
- package/dist/testUtils.d.ts +0 -5
- package/dist/testUtils.js +0 -18
- package/dist/testUtils.js.map +0 -1
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.d.ts +0 -3
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.js +0 -62
- package/esm/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.js.map +0 -1
- package/src/I18nWrapper.tsx +0 -13
- package/src/__snapshots__/index.test.tsx.snap +0 -96
- package/src/components/AgeVerificationModal/AgeVerificationModal.css +0 -95
- package/src/components/AgeVerificationModal/AgeVerificationModal.stories.tsx +0 -46
- package/src/components/AgeVerificationModal/AgeVerificationModal.test.tsx +0 -33
- package/src/components/AgeVerificationModal/AgeVerificationModal.tsx +0 -99
- package/src/components/AgeVerificationModal/__snapshots__/AgeVerificationModal.test.tsx.snap +0 -19
- package/src/components/Auth/Auth.css +0 -57
- package/src/components/Auth/Auth.stories.tsx +0 -90
- package/src/components/Auth/Auth.test.tsx +0 -63
- package/src/components/Auth/Auth.tsx +0 -201
- package/src/components/Auth/__snapshots__/Auth.test.tsx.snap +0 -143
- package/src/components/Avatar/Avatar.css +0 -151
- package/src/components/Avatar/Avatar.stories.tsx +0 -160
- package/src/components/Avatar/Avatar.test.tsx +0 -158
- package/src/components/Avatar/Avatar.tsx +0 -245
- package/src/components/Avatar/AvatarView/AvatarComponent/Shadow/DynamicShadow.tsx +0 -103
- package/src/components/Avatar/AvatarView/AvatarComponent/avatarComponent.tsx +0 -105
- package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/fullbodyAvatar.tsx +0 -338
- package/src/components/Avatar/AvatarView/AvatarComponent/components/FullbodyAvatar/types.ts +0 -44
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarAnimator.ts +0 -1091
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/AvatarPositionController.ts +0 -83
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controllers/MorphTargetController.ts +0 -301
- package/src/components/Avatar/AvatarView/AvatarComponent/components/controls.tsx +0 -100
- package/src/components/Avatar/AvatarView/AvatarComponent/components/halfbodyAvatar.tsx +0 -152
- package/src/components/Avatar/AvatarView/AvatarComponent/components/loader.tsx +0 -31
- package/src/components/Avatar/AvatarView/AvatarComponent/constants.ts +0 -141
- package/src/components/Avatar/AvatarView/AvatarComponent/lights/Lights.tsx +0 -145
- package/src/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.css +0 -111
- package/src/components/Avatar/AvatarView/AvatarComponent/positionControls/positionControls.tsx +0 -201
- package/src/components/Avatar/AvatarView/AvatarView.stories.tsx +0 -254
- package/src/components/Avatar/AvatarView/index.tsx +0 -194
- package/src/components/Avatar/AvatarView/utils/hideHands.ts +0 -11
- package/src/components/Avatar/AvatarView/utils/useEyeBlink.ts +0 -100
- package/src/components/Avatar/AvatarView/utils/useHeadMovement.ts +0 -72
- package/src/components/Avatar/AvatarView/utils/useLoadingMorphAnim.ts +0 -38
- package/src/components/Avatar/AvatarView/utils/useMouthAnimation.ts +0 -93
- package/src/components/Avatar/AvatarView/utils/useSmile.ts +0 -39
- package/src/components/Avatar/AvatarView/utils/utils.ts +0 -55
- package/src/components/Avatar/__snapshots__/Avatar.test.tsx.snap +0 -246
- package/src/components/Blob/Blob.css +0 -286
- package/src/components/Blob/Blob.stories.tsx +0 -53
- package/src/components/Blob/Blob.test.tsx +0 -18
- package/src/components/Blob/Blob.tsx +0 -26
- package/src/components/Blob/__snapshots__/Blob.test.tsx.snap +0 -80
- package/src/components/BlockedMemoriBadge/BlockedMemoriBadge.css +0 -40
- package/src/components/BlockedMemoriBadge/BlockedMemoriBadge.stories.tsx +0 -58
- package/src/components/BlockedMemoriBadge/BlockedMemoriBadge.test.tsx +0 -53
- package/src/components/BlockedMemoriBadge/BlockedMemoriBadge.tsx +0 -74
- package/src/components/BlockedMemoriBadge/__snapshots__/BlockedMemoriBadge.test.tsx.snap +0 -181
- package/src/components/ChangeMode/ChangeMode.css +0 -22
- package/src/components/ChangeMode/ChangeMode.stories.tsx +0 -50
- package/src/components/ChangeMode/ChangeMode.test.tsx +0 -24
- package/src/components/ChangeMode/ChangeMode.tsx +0 -51
- package/src/components/ChangeMode/__snapshots__/ChangeMode.test.tsx.snap +0 -107
- package/src/components/Chat/Chat.css +0 -285
- package/src/components/Chat/Chat.stories.tsx +0 -1684
- package/src/components/Chat/Chat.test.tsx +0 -372
- package/src/components/Chat/Chat.tsx +0 -778
- package/src/components/Chat/__snapshots__/Chat.test.tsx.snap +0 -6816
- package/src/components/ChatBubble/ChatBubble.css +0 -430
- package/src/components/ChatBubble/ChatBubble.stories.tsx +0 -1192
- package/src/components/ChatBubble/ChatBubble.test.tsx +0 -481
- package/src/components/ChatBubble/ChatBubble.tsx +0 -776
- package/src/components/ChatBubble/__snapshots__/ChatBubble.test.tsx.snap +0 -8734
- package/src/components/ChatHistoryDrawer/ChatHistory.css +0 -587
- package/src/components/ChatHistoryDrawer/ChatHistory.stories.tsx +0 -410
- package/src/components/ChatHistoryDrawer/ChatHistory.test.tsx +0 -107
- package/src/components/ChatHistoryDrawer/ChatHistory.tsx +0 -1298
- package/src/components/ChatHistoryDrawer/__snapshots__/ChatHistory.test.tsx.snap +0 -27
- package/src/components/ChatInputs/ChatInputs.css +0 -340
- package/src/components/ChatInputs/ChatInputs.stories.tsx +0 -251
- package/src/components/ChatInputs/ChatInputs.tsx +0 -487
- package/src/components/ChatTextArea/ChatTextArea.css +0 -185
- package/src/components/ChatTextArea/ChatTextArea.stories.tsx +0 -55
- package/src/components/ChatTextArea/ChatTextArea.test.tsx +0 -28
- package/src/components/ChatTextArea/ChatTextArea.tsx +0 -171
- package/src/components/ChatTextArea/__snapshots__/ChatTextArea.test.tsx.snap +0 -68
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.css +0 -36
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.stories.tsx +0 -296
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.test.tsx +0 -31
- package/src/components/CompletionProviderStatus/CompletionProviderStatus.tsx +0 -232
- package/src/components/CompletionProviderStatus/__snapshots__/CompletionProviderStatus.test.tsx.snap +0 -96
- package/src/components/ContentPreviewModal/ContentPreviewModal.css +0 -128
- package/src/components/ContentPreviewModal/ContentPreviewModal.tsx +0 -67
- package/src/components/ContentPreviewModal/index.ts +0 -2
- package/src/components/CustomGLBModelViewer/ModelViewer.css +0 -11
- package/src/components/CustomGLBModelViewer/ModelViewer.stories.tsx +0 -58
- package/src/components/CustomGLBModelViewer/ModelViewer.test.tsx +0 -13
- package/src/components/CustomGLBModelViewer/ModelViewer.tsx +0 -37
- package/src/components/CustomGLBModelViewer/__snapshots__/ModelViewer.test.tsx.snap +0 -20
- package/src/components/DateSelector/DateSelector.css +0 -158
- package/src/components/DateSelector/DateSelector.stories.tsx +0 -47
- package/src/components/DateSelector/DateSelector.test.tsx +0 -149
- package/src/components/DateSelector/DateSelector.tsx +0 -251
- package/src/components/DateSelector/__snapshots__/DateSelector.test.tsx.snap +0 -1954
- package/src/components/ErrorBoundary/ErrorBoundary.tsx +0 -54
- package/src/components/ExpertsDrawer/ExpertsDrawer.css +0 -67
- package/src/components/ExpertsDrawer/ExpertsDrawer.stories.tsx +0 -54
- package/src/components/ExpertsDrawer/ExpertsDrawer.test.tsx +0 -53
- package/src/components/ExpertsDrawer/ExpertsDrawer.tsx +0 -69
- package/src/components/ExpertsDrawer/__snapshots__/ExpertsDrawer.test.tsx.snap +0 -11
- package/src/components/ExportHistoryButton/ExportHistoryButton.css +0 -22
- package/src/components/FeedbackButtons/FeedbackButtons.css +0 -107
- package/src/components/FeedbackButtons/FeedbackButtons.stories.tsx +0 -52
- package/src/components/FeedbackButtons/FeedbackButtons.test.tsx +0 -11
- package/src/components/FeedbackButtons/FeedbackButtons.tsx +0 -152
- package/src/components/FeedbackButtons/__snapshots__/FeedbackButtons.test.tsx.snap +0 -42
- package/src/components/FilePreview/FilePreview.css +0 -358
- package/src/components/FilePreview/FilePreview.stories.tsx +0 -63
- package/src/components/FilePreview/FilePreview.test.tsx +0 -26
- package/src/components/FilePreview/FilePreview.tsx +0 -277
- package/src/components/FilePreview/__snapshots__/FilePreview.test.tsx.snap +0 -185
- package/src/components/Header/ChatConsumptionDropdown.test.tsx +0 -117
- package/src/components/Header/ChatConsumptionDropdown.tsx +0 -275
- package/src/components/Header/Header.css +0 -282
- package/src/components/Header/Header.stories.tsx +0 -338
- package/src/components/Header/Header.test.tsx +0 -371
- package/src/components/Header/Header.tsx +0 -442
- package/src/components/Header/__snapshots__/Header.test.tsx.snap +0 -964
- package/src/components/KnownFacts/KnownFacts.css +0 -19
- package/src/components/KnownFacts/KnownFacts.stories.tsx +0 -80
- package/src/components/KnownFacts/KnownFacts.test.tsx +0 -57
- package/src/components/KnownFacts/KnownFacts.tsx +0 -376
- package/src/components/KnownFacts/__snapshots__/KnownFacts.test.tsx.snap +0 -19
- package/src/components/LoginDrawer/LoginDrawer.css +0 -1616
- package/src/components/LoginDrawer/LoginDrawer.stories.tsx +0 -102
- package/src/components/LoginDrawer/LoginDrawer.test.tsx +0 -199
- package/src/components/LoginDrawer/LoginDrawer.tsx +0 -600
- package/src/components/LoginDrawer/__snapshots__/LoginDrawer.test.tsx.snap +0 -91
- package/src/components/MediaWidget/DocumentCard.test.tsx +0 -45
- package/src/components/MediaWidget/DocumentCard.tsx +0 -19
- package/src/components/MediaWidget/MediaItemWidget.css +0 -1398
- package/src/components/MediaWidget/MediaItemWidget.stories.tsx +0 -423
- package/src/components/MediaWidget/MediaItemWidget.test.tsx +0 -248
- package/src/components/MediaWidget/MediaItemWidget.tsx +0 -997
- package/src/components/MediaWidget/MediaItemWidget.types.ts +0 -65
- package/src/components/MediaWidget/MediaItemWidget.utils.test.ts +0 -367
- package/src/components/MediaWidget/MediaItemWidget.utils.ts +0 -227
- package/src/components/MediaWidget/MediaPreviewModal.test.tsx +0 -271
- package/src/components/MediaWidget/MediaPreviewModal.tsx +0 -425
- package/src/components/MediaWidget/MediaWidget.css +0 -131
- package/src/components/MediaWidget/MediaWidget.stories.tsx +0 -319
- package/src/components/MediaWidget/MediaWidget.test.tsx +0 -41
- package/src/components/MediaWidget/MediaWidget.tsx +0 -107
- package/src/components/MediaWidget/__snapshots__/DocumentCard.test.tsx.snap +0 -24
- package/src/components/MediaWidget/__snapshots__/MediaItemWidget.test.tsx.snap +0 -791
- package/src/components/MediaWidget/__snapshots__/MediaWidget.test.tsx.snap +0 -154
- package/src/components/MemoriArtifactSystem/ArtifactDrawer.stories.tsx +0 -2299
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.css +0 -163
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/ArtifactActions.tsx +0 -250
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/CopyButton.stories.tsx +0 -30
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyButtonWithDropdown.tsx +0 -467
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/components/CopyMenuItem.tsx +0 -89
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/hooks/useCopyArtifact.ts +0 -619
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/index.ts +0 -9
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/styles.css +0 -489
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/test/CopyButtonTest.tsx +0 -90
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/types.ts +0 -73
- package/src/components/MemoriArtifactSystem/components/ArtifactActions/utils/PDFExporter.ts +0 -454
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.css +0 -1059
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/ArtifactDrawer.tsx +0 -431
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/components/TabSwitch.css +0 -150
- package/src/components/MemoriArtifactSystem/components/ArtifactDrawer/components/TabSwitch.tsx +0 -79
- package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.css +0 -253
- package/src/components/MemoriArtifactSystem/components/ArtifactHandler/ArtifactHandler.tsx +0 -561
- package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.css +0 -355
- package/src/components/MemoriArtifactSystem/components/ArtifactPreview/ArtifactPreview.tsx +0 -160
- package/src/components/MemoriArtifactSystem/context/ArtifactContext.tsx +0 -167
- package/src/components/MemoriArtifactSystem/types/artifact.types.ts +0 -35
- package/src/components/MemoriArtifactSystem/utils/ArtifactAPI.test.tsx +0 -308
- package/src/components/MemoriArtifactSystem/utils/ArtifactAPI.tsx +0 -379
- package/src/components/MemoriArtifactSystem/utils/applyEdits.test.ts +0 -85
- package/src/components/MemoriArtifactSystem/utils/applyEdits.ts +0 -173
- package/src/components/MemoriWidget/MemoriWidget.css +0 -220
- package/src/components/MemoriWidget/MemoriWidget.stories.tsx +0 -274
- package/src/components/MemoriWidget/MemoriWidget.tsx +0 -3930
- package/src/components/MicrophoneButton/MicrophoneButton.css +0 -142
- package/src/components/MicrophoneButton/MicrophoneButton.stories.tsx +0 -52
- package/src/components/MicrophoneButton/MicrophoneButton.tsx +0 -128
- package/src/components/PositionDrawer/PositionDrawer.stories.tsx +0 -51
- package/src/components/PositionDrawer/PositionDrawer.test.tsx +0 -39
- package/src/components/PositionDrawer/PositionDrawer.tsx +0 -50
- package/src/components/PositionDrawer/__snapshots__/PositionDrawer.test.tsx.snap +0 -17
- package/src/components/PoweredBy/PoweredBy.css +0 -47
- package/src/components/PoweredBy/PoweredBy.stories.tsx +0 -75
- package/src/components/PoweredBy/PoweredBy.test.tsx +0 -15
- package/src/components/PoweredBy/PoweredBy.tsx +0 -44
- package/src/components/PoweredBy/__snapshots__/PoweredBy.test.tsx.snap +0 -55
- package/src/components/SendOnEnterMenu/SendOnEnterMenu.css +0 -47
- package/src/components/SendOnEnterMenu/SendOnEnterMenu.stories.tsx +0 -58
- package/src/components/SendOnEnterMenu/SendOnEnterMenu.test.tsx +0 -17
- package/src/components/SendOnEnterMenu/SendOnEnterMenu.tsx +0 -82
- package/src/components/SendOnEnterMenu/__snapshots__/SendOnEnterMenu.test.tsx.snap +0 -57
- package/src/components/SettingsDrawer/SettingsDrawer.css +0 -24
- package/src/components/SettingsDrawer/SettingsDrawer.stories.tsx +0 -94
- package/src/components/SettingsDrawer/SettingsDrawer.test.tsx +0 -202
- package/src/components/SettingsDrawer/SettingsDrawer.tsx +0 -255
- package/src/components/SettingsDrawer/__snapshots__/SettingsDrawer.test.tsx.snap +0 -59
- package/src/components/ShareButton/ShareButton.css +0 -73
- package/src/components/ShareButton/ShareButton.stories.tsx +0 -98
- package/src/components/ShareButton/ShareButton.test.tsx +0 -53
- package/src/components/ShareButton/ShareButton.tsx +0 -395
- package/src/components/ShareButton/__snapshots__/ShareButton.test.tsx.snap +0 -316
- package/src/components/Snippet/Snippet.css +0 -142
- package/src/components/Snippet/Snippet.stories.tsx +0 -286
- package/src/components/Snippet/Snippet.test.tsx +0 -176
- package/src/components/Snippet/Snippet.tsx +0 -148
- package/src/components/Snippet/__snapshots__/Snippet.test.tsx.snap +0 -603
- package/src/components/StartPanel/StartPanel.css +0 -273
- package/src/components/StartPanel/StartPanel.stories.tsx +0 -404
- package/src/components/StartPanel/StartPanel.test.tsx +0 -360
- package/src/components/StartPanel/StartPanel.tsx +0 -426
- package/src/components/StartPanel/__snapshots__/StartPanel.test.tsx.snap +0 -1986
- package/src/components/Typing/Typing.stories.tsx +0 -130
- package/src/components/Typing/Typing.test.tsx +0 -62
- package/src/components/Typing/Typing.tsx +0 -154
- package/src/components/Typing/__snapshots__/Typing.test.tsx.snap +0 -133
- package/src/components/UploadButton/UploadButton.css +0 -542
- package/src/components/UploadButton/UploadButton.stories.tsx +0 -376
- package/src/components/UploadButton/UploadButton.test.tsx +0 -11
- package/src/components/UploadButton/UploadButton.tsx +0 -684
- package/src/components/UploadButton/UploadDocuments/UploadDocuments.tsx +0 -405
- package/src/components/UploadButton/UploadImages/UploadImages.tsx +0 -538
- package/src/components/UploadButton/__snapshots__/UploadButton.test.tsx.snap +0 -165
- package/src/components/VenueWidget/VenueWidget.css +0 -163
- package/src/components/VenueWidget/VenueWidget.stories.tsx +0 -66
- package/src/components/VenueWidget/VenueWidget.test.tsx +0 -49
- package/src/components/VenueWidget/VenueWidget.tsx +0 -458
- package/src/components/VenueWidget/__snapshots__/VenueWidget.test.tsx.snap +0 -370
- package/src/components/WhyThisAnswer/WhyThisAnswer.css +0 -171
- package/src/components/WhyThisAnswer/WhyThisAnswer.stories.tsx +0 -285
- package/src/components/WhyThisAnswer/WhyThisAnswer.test.tsx +0 -245
- package/src/components/WhyThisAnswer/WhyThisAnswer.tsx +0 -233
- package/src/components/WhyThisAnswer/__snapshots__/WhyThisAnswer.test.tsx.snap +0 -27
- package/src/components/icons/AI.tsx +0 -34
- package/src/components/icons/Alert.tsx +0 -31
- package/src/components/icons/ArrowUp.tsx +0 -28
- package/src/components/icons/Bug.tsx +0 -81
- package/src/components/icons/Chat.tsx +0 -30
- package/src/components/icons/ChevronDown.tsx +0 -26
- package/src/components/icons/ChevronLeft.tsx +0 -28
- package/src/components/icons/ChevronRight.tsx +0 -28
- package/src/components/icons/ChevronUp.tsx +0 -24
- package/src/components/icons/Clear.tsx +0 -23
- package/src/components/icons/Close.tsx +0 -30
- package/src/components/icons/Code.tsx +0 -24
- package/src/components/icons/Copy.tsx +0 -23
- package/src/components/icons/DeepThought.tsx +0 -38
- package/src/components/icons/Delete.tsx +0 -23
- package/src/components/icons/Document.tsx +0 -50
- package/src/components/icons/Download.tsx +0 -23
- package/src/components/icons/Edit.tsx +0 -17
- package/src/components/icons/Expand.tsx +0 -23
- package/src/components/icons/Eye.tsx +0 -17
- package/src/components/icons/EyeInvisible.tsx +0 -24
- package/src/components/icons/Facebook.tsx +0 -23
- package/src/components/icons/Feedback.tsx +0 -24
- package/src/components/icons/File.tsx +0 -17
- package/src/components/icons/FileExcel.tsx +0 -23
- package/src/components/icons/FilePdf.tsx +0 -23
- package/src/components/icons/FileWord.tsx +0 -23
- package/src/components/icons/Fullscreen.tsx +0 -23
- package/src/components/icons/FullscreenExit.tsx +0 -23
- package/src/components/icons/GasStation.tsx +0 -36
- package/src/components/icons/Group.tsx +0 -30
- package/src/components/icons/History.tsx +0 -33
- package/src/components/icons/Image.tsx +0 -37
- package/src/components/icons/Info.tsx +0 -31
- package/src/components/icons/Link.tsx +0 -17
- package/src/components/icons/Linkedin.tsx +0 -23
- package/src/components/icons/Loading.tsx +0 -28
- package/src/components/icons/Logout.tsx +0 -27
- package/src/components/icons/Mail.tsx +0 -17
- package/src/components/icons/MapMarker.tsx +0 -26
- package/src/components/icons/MenuHorizontal.tsx +0 -29
- package/src/components/icons/MenuVertical.tsx +0 -29
- package/src/components/icons/Message.tsx +0 -23
- package/src/components/icons/Microphone.tsx +0 -23
- package/src/components/icons/Minus.tsx +0 -23
- package/src/components/icons/MinusCircle.tsx +0 -24
- package/src/components/icons/PaperClip.tsx +0 -23
- package/src/components/icons/Picture.tsx +0 -23
- package/src/components/icons/Plus.tsx +0 -18
- package/src/components/icons/Preview.tsx +0 -29
- package/src/components/icons/Print.tsx +0 -38
- package/src/components/icons/QuestionHelp.tsx +0 -30
- package/src/components/icons/Refresh.tsx +0 -30
- package/src/components/icons/SelectIcon.tsx +0 -28
- package/src/components/icons/Send.tsx +0 -17
- package/src/components/icons/Setting.tsx +0 -23
- package/src/components/icons/Share.tsx +0 -23
- package/src/components/icons/Sound.tsx +0 -23
- package/src/components/icons/SoundDeactivated.tsx +0 -27
- package/src/components/icons/Telegram.tsx +0 -26
- package/src/components/icons/ThumbDown.tsx +0 -29
- package/src/components/icons/ThumbUp.tsx +0 -29
- package/src/components/icons/Translation.tsx +0 -24
- package/src/components/icons/Twitter.tsx +0 -23
- package/src/components/icons/Upload.tsx +0 -34
- package/src/components/icons/User.tsx +0 -17
- package/src/components/icons/Warning.tsx +0 -24
- package/src/components/icons/WhatsApp.tsx +0 -24
- package/src/components/icons/icons.stories.css +0 -5
- package/src/components/icons/icons.stories.tsx +0 -81
- package/src/components/icons/loading.css +0 -14
- package/src/components/layouts/Chat.test.tsx +0 -40
- package/src/components/layouts/Chat.tsx +0 -69
- package/src/components/layouts/FullBody/FullBody.stories.tsx +0 -110
- package/src/components/layouts/FullPage.test.tsx +0 -65
- package/src/components/layouts/FullPage.tsx +0 -80
- package/src/components/layouts/HiddenChat.test.tsx +0 -40
- package/src/components/layouts/HiddenChat.tsx +0 -233
- package/src/components/layouts/Totem/Totem.stories.tsx +0 -131
- package/src/components/layouts/Totem.test.tsx +0 -40
- package/src/components/layouts/Totem.tsx +0 -49
- package/src/components/layouts/WebsiteAssistant.test.tsx +0 -40
- package/src/components/layouts/WebsiteAssistant.tsx +0 -132
- package/src/components/layouts/ZoomedFullBody/ZoomedFullBody.stories.tsx +0 -131
- package/src/components/layouts/ZoomedFullBody.test.tsx +0 -40
- package/src/components/layouts/ZoomedFullBody.tsx +0 -81
- package/src/components/layouts/__snapshots__/Chat.test.tsx.snap +0 -457
- package/src/components/layouts/__snapshots__/FullPage.test.tsx.snap +0 -1045
- package/src/components/layouts/__snapshots__/HiddenChat.test.tsx.snap +0 -460
- package/src/components/layouts/__snapshots__/Totem.test.tsx.snap +0 -566
- package/src/components/layouts/__snapshots__/WebsiteAssistant.test.tsx.snap +0 -59
- package/src/components/layouts/__snapshots__/ZoomedFullBody.test.tsx.snap +0 -523
- package/src/components/layouts/chat.css +0 -451
- package/src/components/layouts/hidden-chat.css +0 -276
- package/src/components/layouts/layouts.stories.tsx +0 -231
- package/src/components/layouts/totem.css +0 -221
- package/src/components/layouts/website-assistant.css +0 -677
- package/src/components/layouts/zoomed-full-body.css +0 -18
- package/src/components/ui/Alert.css +0 -93
- package/src/components/ui/Alert.stories.tsx +0 -137
- package/src/components/ui/Alert.test.tsx +0 -129
- package/src/components/ui/Alert.tsx +0 -123
- package/src/components/ui/Button.css +0 -167
- package/src/components/ui/Button.stories.tsx +0 -156
- package/src/components/ui/Button.test.tsx +0 -74
- package/src/components/ui/Button.tsx +0 -107
- package/src/components/ui/Card.css +0 -65
- package/src/components/ui/Card.stories.tsx +0 -95
- package/src/components/ui/Card.test.tsx +0 -47
- package/src/components/ui/Card.tsx +0 -48
- package/src/components/ui/Checkbox.css +0 -116
- package/src/components/ui/Checkbox.stories.tsx +0 -74
- package/src/components/ui/Checkbox.test.tsx +0 -28
- package/src/components/ui/Checkbox.tsx +0 -58
- package/src/components/ui/ConfirmDialog.css +0 -42
- package/src/components/ui/ConfirmDialog.stories.tsx +0 -216
- package/src/components/ui/ConfirmDialog.test.tsx +0 -124
- package/src/components/ui/ConfirmDialog.tsx +0 -58
- package/src/components/ui/Details.css +0 -66
- package/src/components/ui/Drawer.css +0 -270
- package/src/components/ui/Drawer.stories.tsx +0 -267
- package/src/components/ui/Drawer.test.tsx +0 -130
- package/src/components/ui/Drawer.tsx +0 -293
- package/src/components/ui/Dropdown.css +0 -173
- package/src/components/ui/Dropdown.tsx +0 -63
- package/src/components/ui/Expandable.css +0 -15
- package/src/components/ui/Expandable.stories.tsx +0 -180
- package/src/components/ui/Expandable.test.tsx +0 -107
- package/src/components/ui/Expandable.tsx +0 -121
- package/src/components/ui/Modal.css +0 -98
- package/src/components/ui/Modal.stories.tsx +0 -171
- package/src/components/ui/Modal.test.tsx +0 -111
- package/src/components/ui/Modal.tsx +0 -117
- package/src/components/ui/Select.css +0 -138
- package/src/components/ui/Select.stories.tsx +0 -79
- package/src/components/ui/Select.test.tsx +0 -84
- package/src/components/ui/Select.tsx +0 -79
- package/src/components/ui/Slider.css +0 -192
- package/src/components/ui/Slider.stories.tsx +0 -63
- package/src/components/ui/Slider.tsx +0 -142
- package/src/components/ui/Spin.css +0 -31
- package/src/components/ui/Spin.stories.tsx +0 -64
- package/src/components/ui/Spin.test.tsx +0 -41
- package/src/components/ui/Spin.tsx +0 -31
- package/src/components/ui/Table.css +0 -132
- package/src/components/ui/Tooltip.css +0 -171
- package/src/components/ui/Tooltip.stories.tsx +0 -109
- package/src/components/ui/Tooltip.test.tsx +0 -102
- package/src/components/ui/Tooltip.tsx +0 -163
- package/src/components/ui/__snapshots__/Alert.test.tsx.snap +0 -59
- package/src/components/ui/__snapshots__/Button.test.tsx.snap +0 -204
- package/src/components/ui/__snapshots__/Card.test.tsx.snap +0 -321
- package/src/components/ui/__snapshots__/Checkbox.test.tsx.snap +0 -131
- package/src/components/ui/__snapshots__/ConfirmDialog.test.tsx.snap +0 -35
- package/src/components/ui/__snapshots__/Drawer.test.tsx.snap +0 -67
- package/src/components/ui/__snapshots__/Expandable.test.tsx.snap +0 -159
- package/src/components/ui/__snapshots__/Modal.test.tsx.snap +0 -59
- package/src/components/ui/__snapshots__/Select.test.tsx.snap +0 -254
- package/src/components/ui/__snapshots__/Spin.test.tsx.snap +0 -193
- package/src/components/ui/__snapshots__/Tooltip.test.tsx.snap +0 -113
- package/src/components/ui/definitions.stories.tsx +0 -139
- package/src/context/visemeContext.tsx +0 -384
- package/src/helpers/chatPdfExport.ts +0 -544
- package/src/helpers/configuration.ts +0 -42
- package/src/helpers/constants.ts +0 -267
- package/src/helpers/convertDocument.test.ts +0 -67
- package/src/helpers/convertDocument.ts +0 -35
- package/src/helpers/credits.ts +0 -54
- package/src/helpers/error.test.ts +0 -29
- package/src/helpers/error.ts +0 -278
- package/src/helpers/imageCompression.ts +0 -230
- package/src/helpers/llmUsage.ts +0 -328
- package/src/helpers/markedExtendedTables.js +0 -217
- package/src/helpers/media.test.ts +0 -169
- package/src/helpers/media.ts +0 -81
- package/src/helpers/message.test.ts +0 -126
- package/src/helpers/message.ts +0 -219
- package/src/helpers/nats/getNatsConfig.ts +0 -148
- package/src/helpers/nats/isSessionExpiredError.test.ts +0 -38
- package/src/helpers/nats/isSessionExpiredError.ts +0 -51
- package/src/helpers/nats/useNats.test.tsx +0 -81
- package/src/helpers/nats/useNats.ts +0 -204
- package/src/helpers/nats/useNatsSession.test.ts +0 -16
- package/src/helpers/nats/useNatsSession.ts +0 -460
- package/src/helpers/piiDetection.test.ts +0 -186
- package/src/helpers/piiDetection.ts +0 -91
- package/src/helpers/sanitizer.ts +0 -17
- package/src/helpers/statistics.ts +0 -58
- package/src/helpers/stt/useSTT.ts +0 -515
- package/src/helpers/translations.ts +0 -39
- package/src/helpers/tts/ttsVoiceUtility.ts +0 -275
- package/src/helpers/tts/useTTS.ts +0 -621
- package/src/helpers/utils.test.ts +0 -321
- package/src/helpers/utils.ts +0 -586
- package/src/helpers/venue.ts +0 -36
- package/src/i18n.ts +0 -39
- package/src/index.stories.tsx +0 -220
- package/src/index.test.tsx +0 -156
- package/src/index.tsx +0 -592
- package/src/locales/de.json +0 -680
- package/src/locales/en.json +0 -754
- package/src/locales/es.json +0 -682
- package/src/locales/fr.json +0 -682
- package/src/locales/it.json +0 -750
- package/src/mocks/data.ts +0 -790
- package/src/styles.css +0 -126
- package/src/types/integration.test.ts +0 -32
- package/src/types/integration.ts +0 -31
- package/src/types/layout.ts +0 -50
- package/src/version.ts +0 -2
|
@@ -1,621 +0,0 @@
|
|
|
1
|
-
// Improved useTTS.ts with race condition fix
|
|
2
|
-
import { useState, useCallback, useEffect, useRef } from 'react';
|
|
3
|
-
import { sanitizeText } from '../sanitizer';
|
|
4
|
-
import { getLocalConfig, setLocalConfig } from '../configuration';
|
|
5
|
-
import { useViseme } from '../../context/visemeContext';
|
|
6
|
-
import { IAudioContext } from 'standardized-audio-context';
|
|
7
|
-
import { isAndroid } from '../utils';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Configurazione per il TTS
|
|
11
|
-
*/
|
|
12
|
-
export interface TTSConfig {
|
|
13
|
-
provider: 'azure' | 'openai';
|
|
14
|
-
voice?: string;
|
|
15
|
-
model?: string;
|
|
16
|
-
region?: string; // richiesto per Azure
|
|
17
|
-
tenant?: string; // Tenant identifier for multi-tenant applications
|
|
18
|
-
layout?: 'DEFAULT' | 'ZOOMED_FULL_BODY' | 'FULLPAGE' | 'TOTEM';
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
type VisemeData = {
|
|
22
|
-
visemeId: number;
|
|
23
|
-
audioOffset: number;
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Opzioni per l'hook useTTS
|
|
28
|
-
*/
|
|
29
|
-
export interface UseTTSOptions {
|
|
30
|
-
apiUrl?: string;
|
|
31
|
-
continuousSpeech?: boolean;
|
|
32
|
-
onEndSpeakStartListen?: () => void;
|
|
33
|
-
preview?: boolean;
|
|
34
|
-
disableSpeaker?: boolean;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Create our own simplified audio context interface for better typing
|
|
38
|
-
interface SimpleAudioWrapper {
|
|
39
|
-
currentTime: number;
|
|
40
|
-
state: 'running' | 'suspended' | 'closed';
|
|
41
|
-
onstatechange: ((this: AudioContext, ev: Event) => any) | null;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Hook unificato che gestisce la sintesi vocale
|
|
46
|
-
*/
|
|
47
|
-
export function useTTS(
|
|
48
|
-
config: TTSConfig,
|
|
49
|
-
options: UseTTSOptions = {},
|
|
50
|
-
autoStart: boolean = false,
|
|
51
|
-
defaultEnableAudio: boolean = true,
|
|
52
|
-
defaultSpeakerActive: boolean = true
|
|
53
|
-
) {
|
|
54
|
-
// Stato locale
|
|
55
|
-
const [isPlaying, setIsPlaying] = useState(false);
|
|
56
|
-
const [speakerMuted, setSpeakerMuted] = useState(
|
|
57
|
-
getLocalConfig(
|
|
58
|
-
'muteSpeaker',
|
|
59
|
-
!defaultEnableAudio || !defaultSpeakerActive || autoStart
|
|
60
|
-
)
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
// Get viseme methods from your context
|
|
64
|
-
const { addViseme, resetVisemeQueue, startProcessing, stopProcessing } =
|
|
65
|
-
useViseme();
|
|
66
|
-
const [hasUserActivatedSpeak, setHasUserActivatedSpeak] = useState(false);
|
|
67
|
-
|
|
68
|
-
// Helper function to check if audio should be played.
|
|
69
|
-
// When defaultEnableAudio is false, default to muted so we never play before the sync effect runs.
|
|
70
|
-
const shouldPlayAudio = (text?: string) => {
|
|
71
|
-
const currentSpeakerMuted = getLocalConfig(
|
|
72
|
-
'muteSpeaker',
|
|
73
|
-
!defaultEnableAudio
|
|
74
|
-
);
|
|
75
|
-
return (
|
|
76
|
-
text &&
|
|
77
|
-
text.trim() &&
|
|
78
|
-
!options.preview &&
|
|
79
|
-
!currentSpeakerMuted &&
|
|
80
|
-
defaultEnableAudio
|
|
81
|
-
);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
// Riferimenti
|
|
85
|
-
const audioRef = useRef<HTMLAudioElement | null>(null);
|
|
86
|
-
const audioWrapperRef = useRef<SimpleAudioWrapper | null>(null);
|
|
87
|
-
const globalSpeakRef = useRef<Function | null>(null);
|
|
88
|
-
const visemeLoadedRef = useRef<boolean>(false);
|
|
89
|
-
const isSpeakingRef = useRef<boolean>(false);
|
|
90
|
-
const timeoutRef = useRef<NodeJS.Timeout | null>(null);
|
|
91
|
-
const isMountedRef = useRef<boolean>(true);
|
|
92
|
-
const currentChunkAudioRef = useRef<HTMLAudioElement | null>(null);
|
|
93
|
-
const apiUrl = options.apiUrl || '/api/tts';
|
|
94
|
-
|
|
95
|
-
// Load viseme data into the queue
|
|
96
|
-
const loadVisemeData = useCallback(
|
|
97
|
-
(visemeData: VisemeData[]) => {
|
|
98
|
-
resetVisemeQueue();
|
|
99
|
-
visemeLoadedRef.current = false;
|
|
100
|
-
|
|
101
|
-
if (visemeData && visemeData.length > 0) {
|
|
102
|
-
visemeData.forEach(viseme => {
|
|
103
|
-
addViseme(viseme.visemeId, viseme.audioOffset);
|
|
104
|
-
});
|
|
105
|
-
visemeLoadedRef.current = true;
|
|
106
|
-
return true;
|
|
107
|
-
} else {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
},
|
|
111
|
-
[addViseme, resetVisemeQueue]
|
|
112
|
-
);
|
|
113
|
-
|
|
114
|
-
// Create audio wrapper for viseme processing
|
|
115
|
-
const createAudioWrapper = useCallback(() => {
|
|
116
|
-
if (!audioRef.current) {
|
|
117
|
-
return null;
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
// Create a clean wrapper for this audio session
|
|
121
|
-
const wrapper: SimpleAudioWrapper = {
|
|
122
|
-
state: 'running',
|
|
123
|
-
onstatechange: null,
|
|
124
|
-
get currentTime() {
|
|
125
|
-
return audioRef.current ? audioRef.current.currentTime : 0;
|
|
126
|
-
},
|
|
127
|
-
};
|
|
128
|
-
|
|
129
|
-
// Add event listeners to update the state
|
|
130
|
-
const handlePause = () => {
|
|
131
|
-
wrapper.state = 'suspended';
|
|
132
|
-
if (wrapper.onstatechange) {
|
|
133
|
-
wrapper.onstatechange.call(null as any, new Event('statechange'));
|
|
134
|
-
}
|
|
135
|
-
};
|
|
136
|
-
|
|
137
|
-
const handlePlay = () => {
|
|
138
|
-
wrapper.state = 'running';
|
|
139
|
-
if (wrapper.onstatechange) {
|
|
140
|
-
wrapper.onstatechange.call(null as any, new Event('statechange'));
|
|
141
|
-
}
|
|
142
|
-
};
|
|
143
|
-
|
|
144
|
-
const handleEnded = () => {
|
|
145
|
-
wrapper.state = 'closed';
|
|
146
|
-
if (wrapper.onstatechange) {
|
|
147
|
-
wrapper.onstatechange.call(null as any, new Event('statechange'));
|
|
148
|
-
}
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
// Attach event listeners to the audio element
|
|
152
|
-
audioRef.current.addEventListener('pause', handlePause);
|
|
153
|
-
audioRef.current.addEventListener('play', handlePlay);
|
|
154
|
-
audioRef.current.addEventListener('ended', handleEnded);
|
|
155
|
-
|
|
156
|
-
// Store cleanup function
|
|
157
|
-
const cleanupEventListeners = () => {
|
|
158
|
-
if (audioRef.current) {
|
|
159
|
-
audioRef.current.removeEventListener('pause', handlePause);
|
|
160
|
-
audioRef.current.removeEventListener('play', handlePlay);
|
|
161
|
-
audioRef.current.removeEventListener('ended', handleEnded);
|
|
162
|
-
}
|
|
163
|
-
};
|
|
164
|
-
|
|
165
|
-
// Store the cleanup function on the wrapper for later use
|
|
166
|
-
(wrapper as any).cleanup = cleanupEventListeners;
|
|
167
|
-
|
|
168
|
-
return wrapper;
|
|
169
|
-
}, []);
|
|
170
|
-
|
|
171
|
-
/**
|
|
172
|
-
* Performs a complete cleanup of audio and viseme resources
|
|
173
|
-
*/
|
|
174
|
-
const cleanup = useCallback(() => {
|
|
175
|
-
if (timeoutRef.current) {
|
|
176
|
-
clearTimeout(timeoutRef.current);
|
|
177
|
-
timeoutRef.current = null;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
if (audioWrapperRef.current && (audioWrapperRef.current as any).cleanup) {
|
|
181
|
-
(audioWrapperRef.current as any).cleanup();
|
|
182
|
-
}
|
|
183
|
-
audioWrapperRef.current = null;
|
|
184
|
-
|
|
185
|
-
stopProcessing();
|
|
186
|
-
resetVisemeQueue(); // ADD THIS LINE - ensure viseme queue is cleared
|
|
187
|
-
|
|
188
|
-
if (audioRef.current?.src) {
|
|
189
|
-
URL.revokeObjectURL(audioRef.current.src);
|
|
190
|
-
audioRef.current = null;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Clear chunk audio reference
|
|
194
|
-
if (currentChunkAudioRef.current) {
|
|
195
|
-
currentChunkAudioRef.current = null;
|
|
196
|
-
}
|
|
197
|
-
|
|
198
|
-
visemeLoadedRef.current = false;
|
|
199
|
-
// Don't reset isSpeakingRef here - let the speak function manage it
|
|
200
|
-
}, [stopProcessing, resetVisemeQueue]);
|
|
201
|
-
|
|
202
|
-
/**
|
|
203
|
-
* Stops audio playback and cleans up
|
|
204
|
-
*/
|
|
205
|
-
const stop = useCallback((): void => {
|
|
206
|
-
// Stop the main audio element
|
|
207
|
-
if (audioRef.current) {
|
|
208
|
-
audioRef.current.pause();
|
|
209
|
-
audioRef.current.currentTime = 0;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
// Stop the current chunk audio element if it exists
|
|
213
|
-
if (currentChunkAudioRef.current) {
|
|
214
|
-
currentChunkAudioRef.current.pause();
|
|
215
|
-
currentChunkAudioRef.current.currentTime = 0;
|
|
216
|
-
currentChunkAudioRef.current = null;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
setIsPlaying(false);
|
|
220
|
-
cleanup();
|
|
221
|
-
isSpeakingRef.current = false;
|
|
222
|
-
|
|
223
|
-
const e = new CustomEvent('MemoriAudioEnded');
|
|
224
|
-
document.dispatchEvent(e);
|
|
225
|
-
}, [cleanup]);
|
|
226
|
-
|
|
227
|
-
/**
|
|
228
|
-
* Emette l'evento di fine riproduzione
|
|
229
|
-
*/
|
|
230
|
-
const emitEndSpeakEvent = useCallback(() => {
|
|
231
|
-
const e = new CustomEvent('MemoriEndSpeak');
|
|
232
|
-
document.dispatchEvent(e);
|
|
233
|
-
|
|
234
|
-
if (options.continuousSpeech && options.onEndSpeakStartListen) {
|
|
235
|
-
options.onEndSpeakStartListen();
|
|
236
|
-
}
|
|
237
|
-
}, [options.continuousSpeech, options.onEndSpeakStartListen]);
|
|
238
|
-
|
|
239
|
-
// Helper per creare i chunk
|
|
240
|
-
const createChunks = useCallback(
|
|
241
|
-
(text: string, maxLength: number = 800): string[] => {
|
|
242
|
-
if (text.length <= maxLength) {
|
|
243
|
-
return [text];
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const sentences = text.split(/[.!?]+/).filter(s => s.trim().length > 0);
|
|
247
|
-
const chunks: string[] = [];
|
|
248
|
-
let currentChunk = '';
|
|
249
|
-
|
|
250
|
-
for (const sentence of sentences) {
|
|
251
|
-
const sentenceWithPunct = sentence.trim() + '.';
|
|
252
|
-
if (
|
|
253
|
-
(currentChunk + sentenceWithPunct).length > maxLength &&
|
|
254
|
-
currentChunk.length > 0
|
|
255
|
-
) {
|
|
256
|
-
chunks.push(currentChunk.trim());
|
|
257
|
-
currentChunk = sentenceWithPunct;
|
|
258
|
-
} else {
|
|
259
|
-
currentChunk += sentenceWithPunct + ' ';
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
if (currentChunk.trim().length > 0) {
|
|
264
|
-
chunks.push(currentChunk.trim());
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
return chunks;
|
|
268
|
-
},
|
|
269
|
-
[]
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
// Helper per riprodurre un singolo chunk
|
|
273
|
-
// Helper function to handle text-to-speech for a single chunk of text
|
|
274
|
-
const speakChunk = useCallback(
|
|
275
|
-
async (chunkText: string): Promise<void> => {
|
|
276
|
-
// Make API request to TTS endpoint
|
|
277
|
-
const response = await fetch(options.apiUrl || '/api/tts', {
|
|
278
|
-
method: 'POST',
|
|
279
|
-
headers: {
|
|
280
|
-
'Content-Type': 'application/json',
|
|
281
|
-
},
|
|
282
|
-
body: JSON.stringify({
|
|
283
|
-
text: chunkText,
|
|
284
|
-
tenant: config.tenant || 'www.aisuru.com',
|
|
285
|
-
voice: config.voice,
|
|
286
|
-
model: config.model || 'tts-1',
|
|
287
|
-
region: config.region,
|
|
288
|
-
provider: config.provider,
|
|
289
|
-
// Include viseme data for certain layout types that need lip sync
|
|
290
|
-
includeVisemes:
|
|
291
|
-
config.layout === 'ZOOMED_FULL_BODY' ||
|
|
292
|
-
config.layout === 'FULLPAGE' ||
|
|
293
|
-
config.layout === 'DEFAULT' ||
|
|
294
|
-
config.layout === 'TOTEM',
|
|
295
|
-
}),
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
// Handle API errors
|
|
299
|
-
if (!response.ok) {
|
|
300
|
-
const errorData = await response.json().catch(() => ({}));
|
|
301
|
-
throw new Error(errorData.error || `API error: ${response.status}`);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
// Get audio blob from response and create URL
|
|
305
|
-
const audioBlob = await response.blob();
|
|
306
|
-
const audioUrl = URL.createObjectURL(audioBlob);
|
|
307
|
-
|
|
308
|
-
// Check if speaker is muted after receiving TTS result
|
|
309
|
-
if (!shouldPlayAudio(chunkText)) {
|
|
310
|
-
URL.revokeObjectURL(audioUrl);
|
|
311
|
-
return;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
// Clean up if speaking was cancelled
|
|
315
|
-
if (!isSpeakingRef.current || !isMountedRef.current) {
|
|
316
|
-
URL.revokeObjectURL(audioUrl);
|
|
317
|
-
return;
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
// Parse viseme data from response headers if available
|
|
321
|
-
let hasVisemeData = false;
|
|
322
|
-
const visemeDataHeader = response.headers.get('X-Viseme-Data');
|
|
323
|
-
if (visemeDataHeader) {
|
|
324
|
-
try {
|
|
325
|
-
const visemeData: VisemeData[] = JSON.parse(visemeDataHeader);
|
|
326
|
-
hasVisemeData = loadVisemeData(visemeData);
|
|
327
|
-
} catch (err) {
|
|
328
|
-
console.error('[useTTS] Error parsing viseme data:', err);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Clean up if speaking was cancelled
|
|
333
|
-
if (!isSpeakingRef.current || !isMountedRef.current) {
|
|
334
|
-
URL.revokeObjectURL(audioUrl);
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
// Create audio element with Android optimizations
|
|
339
|
-
const audio = new Audio();
|
|
340
|
-
audio.preload = 'auto'; // Force preloading for Android compatibility
|
|
341
|
-
audio.src = audioUrl;
|
|
342
|
-
audioRef.current = audio;
|
|
343
|
-
currentChunkAudioRef.current = audio;
|
|
344
|
-
|
|
345
|
-
// Clean up previous wrapper before creating a new one
|
|
346
|
-
if (audioWrapperRef.current && (audioWrapperRef.current as any).cleanup) {
|
|
347
|
-
(audioWrapperRef.current as any).cleanup();
|
|
348
|
-
audioWrapperRef.current = null;
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// Create audio wrapper for viseme processing if needed
|
|
352
|
-
if (hasVisemeData) {
|
|
353
|
-
audioWrapperRef.current = createAudioWrapper();
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
// Return promise that resolves when audio finishes playing
|
|
357
|
-
return new Promise<void>((resolve, reject) => {
|
|
358
|
-
if (!audioRef.current) {
|
|
359
|
-
reject(new Error('Audio element not found'));
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
|
|
363
|
-
const handleCanPlay = async () => {
|
|
364
|
-
try {
|
|
365
|
-
// Check if playback was cancelled
|
|
366
|
-
if (!isSpeakingRef.current || !isMountedRef.current) {
|
|
367
|
-
URL.revokeObjectURL(audioUrl);
|
|
368
|
-
resolve();
|
|
369
|
-
return;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
// Play audio first, then start viseme processing
|
|
373
|
-
try {
|
|
374
|
-
// Start viseme processing AFTER audio starts playing
|
|
375
|
-
if (hasVisemeData && audioWrapperRef.current) {
|
|
376
|
-
startProcessing(
|
|
377
|
-
audioWrapperRef.current as unknown as IAudioContext
|
|
378
|
-
);
|
|
379
|
-
}
|
|
380
|
-
await audioRef.current?.play();
|
|
381
|
-
} catch (playError) {
|
|
382
|
-
// Retry once for Android compatibility
|
|
383
|
-
await new Promise(r => setTimeout(r, 100));
|
|
384
|
-
if (hasVisemeData && audioWrapperRef.current) {
|
|
385
|
-
startProcessing(
|
|
386
|
-
audioWrapperRef.current as unknown as IAudioContext
|
|
387
|
-
);
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
await audioRef.current?.play();
|
|
391
|
-
}
|
|
392
|
-
} catch (e) {
|
|
393
|
-
// Clean up on error
|
|
394
|
-
URL.revokeObjectURL(audioUrl);
|
|
395
|
-
reject(e);
|
|
396
|
-
}
|
|
397
|
-
};
|
|
398
|
-
|
|
399
|
-
audioRef.current.addEventListener('canplaythrough', handleCanPlay, {
|
|
400
|
-
once: true,
|
|
401
|
-
});
|
|
402
|
-
|
|
403
|
-
// When audio finishes playing
|
|
404
|
-
audioRef.current.onended = () => {
|
|
405
|
-
// Clean up resources
|
|
406
|
-
URL.revokeObjectURL(audioUrl);
|
|
407
|
-
if (currentChunkAudioRef.current === audio) {
|
|
408
|
-
currentChunkAudioRef.current = null;
|
|
409
|
-
}
|
|
410
|
-
resolve();
|
|
411
|
-
};
|
|
412
|
-
|
|
413
|
-
// Handle audio errors
|
|
414
|
-
audioRef.current.onerror = () => {
|
|
415
|
-
// Clean up resources
|
|
416
|
-
URL.revokeObjectURL(audioUrl);
|
|
417
|
-
if (currentChunkAudioRef.current === audio) {
|
|
418
|
-
currentChunkAudioRef.current = null;
|
|
419
|
-
}
|
|
420
|
-
reject(new Error('Audio playback failed'));
|
|
421
|
-
};
|
|
422
|
-
|
|
423
|
-
// Start loading the audio
|
|
424
|
-
audioRef.current?.load();
|
|
425
|
-
});
|
|
426
|
-
},
|
|
427
|
-
[
|
|
428
|
-
config,
|
|
429
|
-
options,
|
|
430
|
-
loadVisemeData,
|
|
431
|
-
createAudioWrapper,
|
|
432
|
-
startProcessing,
|
|
433
|
-
isSpeakingRef,
|
|
434
|
-
isMountedRef,
|
|
435
|
-
speakerMuted,
|
|
436
|
-
defaultEnableAudio,
|
|
437
|
-
]
|
|
438
|
-
);
|
|
439
|
-
|
|
440
|
-
/**
|
|
441
|
-
* Sintetizza il testo in audio e lo riproduce
|
|
442
|
-
*/
|
|
443
|
-
const speak = useCallback(
|
|
444
|
-
async (text: string): Promise<void> => {
|
|
445
|
-
if (!isMountedRef.current) {
|
|
446
|
-
return;
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
// Early exit conditions before setting speaking flag
|
|
450
|
-
if (!shouldPlayAudio(text)) {
|
|
451
|
-
// Still set hasUserActivatedSpeak to true when audio is disabled
|
|
452
|
-
// so the chat can start properly
|
|
453
|
-
if (!hasUserActivatedSpeak) {
|
|
454
|
-
setHasUserActivatedSpeak(true);
|
|
455
|
-
}
|
|
456
|
-
emitEndSpeakEvent();
|
|
457
|
-
return;
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// Stop any existing playback first (before checking/setting speaking flag)
|
|
461
|
-
if (isPlaying) {
|
|
462
|
-
stop();
|
|
463
|
-
}
|
|
464
|
-
|
|
465
|
-
// Now check if we're already processing a request
|
|
466
|
-
if (isSpeakingRef.current) {
|
|
467
|
-
return;
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Set the flag after all the early exits and cleanup
|
|
471
|
-
isSpeakingRef.current = true;
|
|
472
|
-
|
|
473
|
-
if (!hasUserActivatedSpeak) {
|
|
474
|
-
setHasUserActivatedSpeak(true);
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
try {
|
|
478
|
-
setIsPlaying(true);
|
|
479
|
-
|
|
480
|
-
// CHUNKING LOGIC: Dividi il testo in chunk se necessario
|
|
481
|
-
const chunks = createChunks(text, 500);
|
|
482
|
-
|
|
483
|
-
// Riproduci tutti i chunk in sequenza
|
|
484
|
-
// Il loop itera su ogni chunk di testo che deve essere riprodotto
|
|
485
|
-
for (let i = 0; i < chunks.length; i++) {
|
|
486
|
-
// Controlla se il componente è ancora montato e se non è stato interrotto
|
|
487
|
-
if (!isSpeakingRef.current || !isMountedRef.current) {
|
|
488
|
-
break; // Interrompe il loop se il componente viene smontato
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
// Attende che il chunk corrente venga riprodotto prima di passare al successivo
|
|
492
|
-
await speakChunk(chunks[i]);
|
|
493
|
-
|
|
494
|
-
// Se ci sono altri chunk da riprodurre, aggiunge una piccola pausa
|
|
495
|
-
if (
|
|
496
|
-
i < chunks.length - 1 &&
|
|
497
|
-
isSpeakingRef.current &&
|
|
498
|
-
isMountedRef.current
|
|
499
|
-
) {
|
|
500
|
-
// Crea una Promise che si risolve dopo 300ms
|
|
501
|
-
// Questo crea una pausa tra un chunk e l'altro
|
|
502
|
-
// setTimeout viene wrappato in una Promise per poter usare await
|
|
503
|
-
await new Promise(resolve => setTimeout(resolve, 300));
|
|
504
|
-
}
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
setIsPlaying(false);
|
|
508
|
-
isSpeakingRef.current = false;
|
|
509
|
-
emitEndSpeakEvent();
|
|
510
|
-
|
|
511
|
-
// Dispatch custom event to notify MemoriWidget that audio has ended
|
|
512
|
-
const e = new CustomEvent('MemoriAudioEnded');
|
|
513
|
-
document.dispatchEvent(e);
|
|
514
|
-
} catch (err) {
|
|
515
|
-
console.error('[speak] Error during playback:', err);
|
|
516
|
-
setIsPlaying(false);
|
|
517
|
-
isSpeakingRef.current = false;
|
|
518
|
-
|
|
519
|
-
if (timeoutRef.current) {
|
|
520
|
-
clearTimeout(timeoutRef.current);
|
|
521
|
-
timeoutRef.current = null;
|
|
522
|
-
}
|
|
523
|
-
|
|
524
|
-
cleanup();
|
|
525
|
-
|
|
526
|
-
emitEndSpeakEvent();
|
|
527
|
-
|
|
528
|
-
// Dispatch custom event to notify MemoriWidget that audio has ended
|
|
529
|
-
const e = new CustomEvent('MemoriAudioEnded');
|
|
530
|
-
document.dispatchEvent(e);
|
|
531
|
-
}
|
|
532
|
-
},
|
|
533
|
-
[
|
|
534
|
-
config,
|
|
535
|
-
speakerMuted,
|
|
536
|
-
options.preview,
|
|
537
|
-
hasUserActivatedSpeak,
|
|
538
|
-
stop,
|
|
539
|
-
cleanup,
|
|
540
|
-
createChunks,
|
|
541
|
-
speakChunk,
|
|
542
|
-
emitEndSpeakEvent,
|
|
543
|
-
isPlaying,
|
|
544
|
-
defaultEnableAudio,
|
|
545
|
-
]
|
|
546
|
-
);
|
|
547
|
-
/**
|
|
548
|
-
* Imposta lo stato del muto
|
|
549
|
-
*/
|
|
550
|
-
const toggleMute = useCallback(
|
|
551
|
-
(mute?: boolean) => {
|
|
552
|
-
const newMuteState = mute !== undefined ? mute : !speakerMuted;
|
|
553
|
-
|
|
554
|
-
setSpeakerMuted(newMuteState);
|
|
555
|
-
|
|
556
|
-
// Update local config for persistence
|
|
557
|
-
setLocalConfig('muteSpeaker', newMuteState);
|
|
558
|
-
|
|
559
|
-
if (newMuteState && isPlaying) {
|
|
560
|
-
stop();
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
// Always clean up viseme state when toggling mute
|
|
564
|
-
// This ensures fresh start when unmuting
|
|
565
|
-
// if (newMuteState) {
|
|
566
|
-
// console.log('[useTTS] Muting - resetting viseme queue and stopping processing');
|
|
567
|
-
// resetVisemeQueue();
|
|
568
|
-
// stopProcessing();
|
|
569
|
-
// } else {
|
|
570
|
-
// console.log('[useTTS] Unmuting - visemes will restart on next speak call');
|
|
571
|
-
// // When unmuting, ensure viseme processing can restart properly
|
|
572
|
-
// // The visemes will be loaded fresh on the next speak call
|
|
573
|
-
// }
|
|
574
|
-
},
|
|
575
|
-
[speakerMuted, isPlaying, stop, resetVisemeQueue, stopProcessing]
|
|
576
|
-
);
|
|
577
|
-
|
|
578
|
-
/**
|
|
579
|
-
* Aggiorna la variabile globale quando cambia isPlaying
|
|
580
|
-
*/
|
|
581
|
-
useEffect(() => {
|
|
582
|
-
if (typeof window !== 'undefined') {
|
|
583
|
-
(window as any).memoriSpeaking = isPlaying;
|
|
584
|
-
}
|
|
585
|
-
}, [isPlaying]);
|
|
586
|
-
|
|
587
|
-
/**
|
|
588
|
-
* Hook per esporre la funzione speak globalmente
|
|
589
|
-
*/
|
|
590
|
-
useEffect(() => {
|
|
591
|
-
if (typeof window !== 'undefined') {
|
|
592
|
-
globalSpeakRef.current = (window as any).speak;
|
|
593
|
-
(window as any).speak = speak;
|
|
594
|
-
|
|
595
|
-
return () => {
|
|
596
|
-
(window as any).speak = globalSpeakRef.current;
|
|
597
|
-
};
|
|
598
|
-
}
|
|
599
|
-
}, [speak]);
|
|
600
|
-
|
|
601
|
-
/**
|
|
602
|
-
* Pulizia delle risorse al dismount
|
|
603
|
-
*/
|
|
604
|
-
useEffect(() => {
|
|
605
|
-
return () => {
|
|
606
|
-
isSpeakingRef.current = false;
|
|
607
|
-
isMountedRef.current = false;
|
|
608
|
-
stop();
|
|
609
|
-
};
|
|
610
|
-
}, [stop]);
|
|
611
|
-
|
|
612
|
-
return {
|
|
613
|
-
speak,
|
|
614
|
-
stop,
|
|
615
|
-
isPlaying,
|
|
616
|
-
speakerMuted,
|
|
617
|
-
toggleMute,
|
|
618
|
-
hasUserActivatedSpeak,
|
|
619
|
-
setHasUserActivatedSpeak,
|
|
620
|
-
};
|
|
621
|
-
}
|