@magmamath/students-features 0.9.113 → 0.9.114-rc.1
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/dist/commonjs/features/chatbot/components/ChatInput/RequestHintButton.js.map +1 -1
- package/dist/commonjs/features/chatbot/components/ChatMessage/MessageButtonsBlock.js.map +1 -1
- package/dist/commonjs/features/chatbot/components/ChatMessage/MessageTextToSpeech.js +8 -48
- package/dist/commonjs/features/chatbot/components/ChatMessage/MessageTextToSpeech.js.map +1 -1
- package/dist/commonjs/features/chatbot/constants.js +4 -4
- package/dist/commonjs/features/chatbot/constants.js.map +1 -1
- package/dist/commonjs/features/gifCelebrations/helpers.js +1 -0
- package/dist/commonjs/features/gifCelebrations/helpers.js.map +1 -1
- package/dist/commonjs/features/voice/constants.js +22 -0
- package/dist/commonjs/features/voice/constants.js.map +1 -0
- package/dist/commonjs/features/voice/helpers.js +211 -0
- package/dist/commonjs/features/voice/helpers.js.map +1 -0
- package/dist/commonjs/features/voice/index.js +138 -0
- package/dist/commonjs/features/voice/index.js.map +1 -0
- package/dist/commonjs/features/voice/model/index.js +68 -0
- package/dist/commonjs/features/voice/model/index.js.map +1 -0
- package/dist/commonjs/features/voice/playing/components/VoiceIcon.js +49 -0
- package/dist/commonjs/features/voice/playing/components/VoiceIcon.js.map +1 -0
- package/dist/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdown.js +208 -0
- package/dist/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdown.js.map +1 -0
- package/dist/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdownItem.js +108 -0
- package/dist/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdownItem.js.map +1 -0
- package/dist/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.js +50 -0
- package/dist/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.js.map +1 -0
- package/dist/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.js +34 -0
- package/dist/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/Player.model.js +87 -0
- package/dist/commonjs/features/voice/playing/model/Player.model.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/VoicePlayer.model.js +244 -0
- package/dist/commonjs/features/voice/playing/model/VoicePlayer.model.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsCollection.js +41 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsCollection.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsDownloader.model.js +39 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsDownloader.model.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsDropdown.model.js +15 -0
- package/dist/commonjs/features/voice/playing/model/VoiceTranscriptionsDropdown.model.js.map +1 -0
- package/dist/commonjs/features/voice/playing/model/index.js +47 -0
- package/dist/commonjs/features/voice/playing/model/index.js.map +1 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecord.js +74 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecord.js.map +1 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordButton.js +61 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordButton.js.map +1 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordDeleteButton.js +35 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordDeleteButton.js.map +1 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordDevider.js +27 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordDevider.js.map +1 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordTimer.js +50 -0
- package/dist/commonjs/features/voice/recording/components/VoiceRecordTimer.js.map +1 -0
- package/dist/commonjs/features/voice/recording/hooks/useVoiceRecorder.js +59 -0
- package/dist/commonjs/features/voice/recording/hooks/useVoiceRecorder.js.map +1 -0
- package/dist/commonjs/features/voice/recording/hooks/useVoiceRecorderAnimation.js +22 -0
- package/dist/commonjs/features/voice/recording/hooks/useVoiceRecorderAnimation.js.map +1 -0
- package/dist/commonjs/features/voice/recording/modal/ModalFooterButtons.js +53 -0
- package/dist/commonjs/features/voice/recording/modal/ModalFooterButtons.js.map +1 -0
- package/dist/commonjs/features/voice/recording/modal/VoiceRecordDeleteModal.js +78 -0
- package/dist/commonjs/features/voice/recording/modal/VoiceRecordDeleteModal.js.map +1 -0
- package/dist/commonjs/features/voice/recording/modal/VoiceRecordUndoModal.js +51 -0
- package/dist/commonjs/features/voice/recording/modal/VoiceRecordUndoModal.js.map +1 -0
- package/dist/commonjs/features/voice/recording/model/Recorder.model.js +54 -0
- package/dist/commonjs/features/voice/recording/model/Recorder.model.js.map +1 -0
- package/dist/commonjs/features/voice/recording/model/Uploader.model.js +44 -0
- package/dist/commonjs/features/voice/recording/model/Uploader.model.js.map +1 -0
- package/dist/commonjs/features/voice/recording/model/VoiceRecord.model.js +239 -0
- package/dist/commonjs/features/voice/recording/model/VoiceRecord.model.js.map +1 -0
- package/dist/commonjs/features/voice/recording/model/VoiceRecordCollection.js +30 -0
- package/dist/commonjs/features/voice/recording/model/VoiceRecordCollection.js.map +1 -0
- package/dist/commonjs/features/voice/recording/model/index.js +34 -0
- package/dist/commonjs/features/voice/recording/model/index.js.map +1 -0
- package/dist/commonjs/features/voice/types.js +6 -0
- package/dist/commonjs/features/voice/types.js.map +1 -0
- package/dist/commonjs/index.js +12 -0
- package/dist/commonjs/index.js.map +1 -1
- package/dist/commonjs/shared/components/PlayButton.js +70 -0
- package/dist/commonjs/shared/components/PlayButton.js.map +1 -0
- package/dist/commonjs/shared/translation/localization/ca.json +17 -0
- package/dist/commonjs/shared/translation/localization/de.json +17 -0
- package/dist/commonjs/shared/translation/localization/en.json +17 -0
- package/dist/commonjs/shared/translation/localization/gb.json +17 -0
- package/dist/commonjs/shared/translation/localization/sct.json +17 -0
- package/dist/commonjs/shared/translation/localization/sw.json +17 -0
- package/dist/module/features/chatbot/components/ChatInput/RequestHintButton.js.map +1 -1
- package/dist/module/features/chatbot/components/ChatMessage/MessageButtonsBlock.js.map +1 -1
- package/dist/module/features/chatbot/components/ChatMessage/MessageTextToSpeech.js +9 -49
- package/dist/module/features/chatbot/components/ChatMessage/MessageTextToSpeech.js.map +1 -1
- package/dist/module/features/chatbot/constants.js +5 -5
- package/dist/module/features/chatbot/constants.js.map +1 -1
- package/dist/module/features/gifCelebrations/helpers.js +1 -0
- package/dist/module/features/gifCelebrations/helpers.js.map +1 -1
- package/dist/module/features/voice/constants.js +18 -0
- package/dist/module/features/voice/constants.js.map +1 -0
- package/dist/module/features/voice/helpers.js +194 -0
- package/dist/module/features/voice/helpers.js.map +1 -0
- package/dist/module/features/voice/index.js +20 -0
- package/dist/module/features/voice/index.js.map +1 -0
- package/dist/module/features/voice/model/index.js +15 -0
- package/dist/module/features/voice/model/index.js.map +1 -0
- package/dist/module/features/voice/playing/components/VoiceIcon.js +41 -0
- package/dist/module/features/voice/playing/components/VoiceIcon.js.map +1 -0
- package/dist/module/features/voice/playing/components/VoiceTranscriptionsDropdown.js +201 -0
- package/dist/module/features/voice/playing/components/VoiceTranscriptionsDropdown.js.map +1 -0
- package/dist/module/features/voice/playing/components/VoiceTranscriptionsDropdownItem.js +102 -0
- package/dist/module/features/voice/playing/components/VoiceTranscriptionsDropdownItem.js.map +1 -0
- package/dist/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.js +45 -0
- package/dist/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.js.map +1 -0
- package/dist/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.js +29 -0
- package/dist/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.js.map +1 -0
- package/dist/module/features/voice/playing/model/Player.model.js +82 -0
- package/dist/module/features/voice/playing/model/Player.model.js.map +1 -0
- package/dist/module/features/voice/playing/model/VoicePlayer.model.js +234 -0
- package/dist/module/features/voice/playing/model/VoicePlayer.model.js.map +1 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsCollection.js +36 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsCollection.js.map +1 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsDownloader.model.js +34 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsDownloader.model.js.map +1 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsDropdown.model.js +10 -0
- package/dist/module/features/voice/playing/model/VoiceTranscriptionsDropdown.model.js.map +1 -0
- package/dist/module/features/voice/playing/model/index.js +8 -0
- package/dist/module/features/voice/playing/model/index.js.map +1 -0
- package/dist/module/features/voice/recording/components/VoiceRecord.js +67 -0
- package/dist/module/features/voice/recording/components/VoiceRecord.js.map +1 -0
- package/dist/module/features/voice/recording/components/VoiceRecordButton.js +55 -0
- package/dist/module/features/voice/recording/components/VoiceRecordButton.js.map +1 -0
- package/dist/module/features/voice/recording/components/VoiceRecordDeleteButton.js +29 -0
- package/dist/module/features/voice/recording/components/VoiceRecordDeleteButton.js.map +1 -0
- package/dist/module/features/voice/recording/components/VoiceRecordDevider.js +21 -0
- package/dist/module/features/voice/recording/components/VoiceRecordDevider.js.map +1 -0
- package/dist/module/features/voice/recording/components/VoiceRecordTimer.js +44 -0
- package/dist/module/features/voice/recording/components/VoiceRecordTimer.js.map +1 -0
- package/dist/module/features/voice/recording/hooks/useVoiceRecorder.js +54 -0
- package/dist/module/features/voice/recording/hooks/useVoiceRecorder.js.map +1 -0
- package/dist/module/features/voice/recording/hooks/useVoiceRecorderAnimation.js +17 -0
- package/dist/module/features/voice/recording/hooks/useVoiceRecorderAnimation.js.map +1 -0
- package/dist/module/features/voice/recording/modal/ModalFooterButtons.js +47 -0
- package/dist/module/features/voice/recording/modal/ModalFooterButtons.js.map +1 -0
- package/dist/module/features/voice/recording/modal/VoiceRecordDeleteModal.js +71 -0
- package/dist/module/features/voice/recording/modal/VoiceRecordDeleteModal.js.map +1 -0
- package/dist/module/features/voice/recording/modal/VoiceRecordUndoModal.js +45 -0
- package/dist/module/features/voice/recording/modal/VoiceRecordUndoModal.js.map +1 -0
- package/dist/module/features/voice/recording/model/Recorder.model.js +49 -0
- package/dist/module/features/voice/recording/model/Recorder.model.js.map +1 -0
- package/dist/module/features/voice/recording/model/Uploader.model.js +39 -0
- package/dist/module/features/voice/recording/model/Uploader.model.js.map +1 -0
- package/dist/module/features/voice/recording/model/VoiceRecord.model.js +234 -0
- package/dist/module/features/voice/recording/model/VoiceRecord.model.js.map +1 -0
- package/dist/module/features/voice/recording/model/VoiceRecordCollection.js +25 -0
- package/dist/module/features/voice/recording/model/VoiceRecordCollection.js.map +1 -0
- package/dist/module/features/voice/recording/model/index.js +7 -0
- package/dist/module/features/voice/recording/model/index.js.map +1 -0
- package/dist/module/features/voice/types.js +4 -0
- package/dist/module/features/voice/types.js.map +1 -0
- package/dist/module/index.js +1 -0
- package/dist/module/index.js.map +1 -1
- package/dist/module/shared/components/PlayButton.js +64 -0
- package/dist/module/shared/components/PlayButton.js.map +1 -0
- package/dist/module/shared/translation/localization/ca.json +17 -0
- package/dist/module/shared/translation/localization/de.json +17 -0
- package/dist/module/shared/translation/localization/en.json +17 -0
- package/dist/module/shared/translation/localization/gb.json +17 -0
- package/dist/module/shared/translation/localization/sct.json +17 -0
- package/dist/module/shared/translation/localization/sw.json +17 -0
- package/dist/typescript/commonjs/features/chatbot/components/ChatInput/RequestHintButton.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/chatbot/components/ChatMessage/MessageButtonsBlock.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/chatbot/components/ChatMessage/MessageTextToSpeech.d.ts +2 -2
- package/dist/typescript/commonjs/features/chatbot/components/ChatMessage/MessageTextToSpeech.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/chatbot/constants.d.ts +5 -5
- package/dist/typescript/commonjs/features/chatbot/constants.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/gifCelebrations/helpers.d.ts.map +1 -1
- package/dist/typescript/commonjs/features/voice/constants.d.ts +15 -0
- package/dist/typescript/commonjs/features/voice/constants.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/helpers.d.ts +46 -0
- package/dist/typescript/commonjs/features/voice/helpers.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/index.d.ts +13 -0
- package/dist/typescript/commonjs/features/voice/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/model/index.d.ts +11 -0
- package/dist/typescript/commonjs/features/voice/model/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceIcon.d.ts +8 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceIcon.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdown.d.ts +15 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdown.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdownItem.d.ts +12 -0
- package/dist/typescript/commonjs/features/voice/playing/components/VoiceTranscriptionsDropdownItem.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.d.ts +16 -0
- package/dist/typescript/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.d.ts +11 -0
- package/dist/typescript/commonjs/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/Player.model.d.ts +21 -0
- package/dist/typescript/commonjs/features/voice/playing/model/Player.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoicePlayer.model.d.ts +41 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoicePlayer.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsCollection.d.ts +26 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsCollection.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsDownloader.model.d.ts +18 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsDownloader.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsDropdown.model.d.ts +7 -0
- package/dist/typescript/commonjs/features/voice/playing/model/VoiceTranscriptionsDropdown.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/playing/model/index.d.ts +7 -0
- package/dist/typescript/commonjs/features/voice/playing/model/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecord.d.ts +10 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecord.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordButton.d.ts +10 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordButton.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordDeleteButton.d.ts +8 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordDeleteButton.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordDevider.d.ts +3 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordDevider.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordTimer.d.ts +11 -0
- package/dist/typescript/commonjs/features/voice/recording/components/VoiceRecordTimer.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/hooks/useVoiceRecorder.d.ts +5 -0
- package/dist/typescript/commonjs/features/voice/recording/hooks/useVoiceRecorder.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/hooks/useVoiceRecorderAnimation.d.ts +6 -0
- package/dist/typescript/commonjs/features/voice/recording/hooks/useVoiceRecorderAnimation.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/ModalFooterButtons.d.ts +12 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/ModalFooterButtons.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/VoiceRecordDeleteModal.d.ts +11 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/VoiceRecordDeleteModal.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/VoiceRecordUndoModal.d.ts +11 -0
- package/dist/typescript/commonjs/features/voice/recording/modal/VoiceRecordUndoModal.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/model/Recorder.model.d.ts +19 -0
- package/dist/typescript/commonjs/features/voice/recording/model/Recorder.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/model/Uploader.model.d.ts +18 -0
- package/dist/typescript/commonjs/features/voice/recording/model/Uploader.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/model/VoiceRecord.model.d.ts +50 -0
- package/dist/typescript/commonjs/features/voice/recording/model/VoiceRecord.model.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/model/VoiceRecordCollection.d.ts +10 -0
- package/dist/typescript/commonjs/features/voice/recording/model/VoiceRecordCollection.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/recording/model/index.d.ts +5 -0
- package/dist/typescript/commonjs/features/voice/recording/model/index.d.ts.map +1 -0
- package/dist/typescript/commonjs/features/voice/types.d.ts +58 -0
- package/dist/typescript/commonjs/features/voice/types.d.ts.map +1 -0
- package/dist/typescript/commonjs/index.d.ts +1 -0
- package/dist/typescript/commonjs/index.d.ts.map +1 -1
- package/dist/typescript/commonjs/shared/components/PlayButton.d.ts +18 -0
- package/dist/typescript/commonjs/shared/components/PlayButton.d.ts.map +1 -0
- package/dist/typescript/commonjs/shared/translation/constants.d.ts +102 -0
- package/dist/typescript/commonjs/shared/translation/constants.d.ts.map +1 -1
- package/dist/typescript/commonjs/shared/translation/model.d.ts +34 -0
- package/dist/typescript/commonjs/shared/translation/model.d.ts.map +1 -1
- package/dist/typescript/commonjs/types/common.types.d.ts +3 -0
- package/dist/typescript/commonjs/types/common.types.d.ts.map +1 -1
- package/dist/typescript/module/features/chatbot/components/ChatInput/RequestHintButton.d.ts.map +1 -1
- package/dist/typescript/module/features/chatbot/components/ChatMessage/MessageButtonsBlock.d.ts.map +1 -1
- package/dist/typescript/module/features/chatbot/components/ChatMessage/MessageTextToSpeech.d.ts +2 -2
- package/dist/typescript/module/features/chatbot/components/ChatMessage/MessageTextToSpeech.d.ts.map +1 -1
- package/dist/typescript/module/features/chatbot/constants.d.ts +5 -5
- package/dist/typescript/module/features/chatbot/constants.d.ts.map +1 -1
- package/dist/typescript/module/features/gifCelebrations/helpers.d.ts.map +1 -1
- package/dist/typescript/module/features/voice/constants.d.ts +15 -0
- package/dist/typescript/module/features/voice/constants.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/helpers.d.ts +46 -0
- package/dist/typescript/module/features/voice/helpers.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/index.d.ts +13 -0
- package/dist/typescript/module/features/voice/index.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/model/index.d.ts +11 -0
- package/dist/typescript/module/features/voice/model/index.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceIcon.d.ts +8 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceIcon.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceTranscriptionsDropdown.d.ts +15 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceTranscriptionsDropdown.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceTranscriptionsDropdownItem.d.ts +12 -0
- package/dist/typescript/module/features/voice/playing/components/VoiceTranscriptionsDropdownItem.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.d.ts +16 -0
- package/dist/typescript/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.d.ts +11 -0
- package/dist/typescript/module/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/Player.model.d.ts +21 -0
- package/dist/typescript/module/features/voice/playing/model/Player.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/VoicePlayer.model.d.ts +41 -0
- package/dist/typescript/module/features/voice/playing/model/VoicePlayer.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsCollection.d.ts +26 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsCollection.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsDownloader.model.d.ts +18 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsDownloader.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsDropdown.model.d.ts +7 -0
- package/dist/typescript/module/features/voice/playing/model/VoiceTranscriptionsDropdown.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/playing/model/index.d.ts +7 -0
- package/dist/typescript/module/features/voice/playing/model/index.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecord.d.ts +10 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecord.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordButton.d.ts +10 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordButton.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordDeleteButton.d.ts +8 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordDeleteButton.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordDevider.d.ts +3 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordDevider.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordTimer.d.ts +11 -0
- package/dist/typescript/module/features/voice/recording/components/VoiceRecordTimer.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/hooks/useVoiceRecorder.d.ts +5 -0
- package/dist/typescript/module/features/voice/recording/hooks/useVoiceRecorder.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/hooks/useVoiceRecorderAnimation.d.ts +6 -0
- package/dist/typescript/module/features/voice/recording/hooks/useVoiceRecorderAnimation.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/modal/ModalFooterButtons.d.ts +12 -0
- package/dist/typescript/module/features/voice/recording/modal/ModalFooterButtons.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/modal/VoiceRecordDeleteModal.d.ts +11 -0
- package/dist/typescript/module/features/voice/recording/modal/VoiceRecordDeleteModal.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/modal/VoiceRecordUndoModal.d.ts +11 -0
- package/dist/typescript/module/features/voice/recording/modal/VoiceRecordUndoModal.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/model/Recorder.model.d.ts +19 -0
- package/dist/typescript/module/features/voice/recording/model/Recorder.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/model/Uploader.model.d.ts +18 -0
- package/dist/typescript/module/features/voice/recording/model/Uploader.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/model/VoiceRecord.model.d.ts +50 -0
- package/dist/typescript/module/features/voice/recording/model/VoiceRecord.model.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/model/VoiceRecordCollection.d.ts +10 -0
- package/dist/typescript/module/features/voice/recording/model/VoiceRecordCollection.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/recording/model/index.d.ts +5 -0
- package/dist/typescript/module/features/voice/recording/model/index.d.ts.map +1 -0
- package/dist/typescript/module/features/voice/types.d.ts +58 -0
- package/dist/typescript/module/features/voice/types.d.ts.map +1 -0
- package/dist/typescript/module/index.d.ts +1 -0
- package/dist/typescript/module/index.d.ts.map +1 -1
- package/dist/typescript/module/shared/components/PlayButton.d.ts +18 -0
- package/dist/typescript/module/shared/components/PlayButton.d.ts.map +1 -0
- package/dist/typescript/module/shared/translation/constants.d.ts +102 -0
- package/dist/typescript/module/shared/translation/constants.d.ts.map +1 -1
- package/dist/typescript/module/shared/translation/model.d.ts +34 -0
- package/dist/typescript/module/shared/translation/model.d.ts.map +1 -1
- package/dist/typescript/module/types/common.types.d.ts +3 -0
- package/dist/typescript/module/types/common.types.d.ts.map +1 -1
- package/package.json +11 -4
- package/src/features/chatbot/components/ChatInput/RequestHintButton.tsx +0 -1
- package/src/features/chatbot/components/ChatMessage/MessageButtonsBlock.tsx +1 -1
- package/src/features/chatbot/components/ChatMessage/MessageTextToSpeech.tsx +9 -51
- package/src/features/chatbot/constants.ts +4 -4
- package/src/features/gifCelebrations/helpers.ts +1 -0
- package/src/features/voice/constants.ts +14 -0
- package/src/features/voice/helpers.ts +254 -0
- package/src/features/voice/index.ts +17 -0
- package/src/features/voice/model/index.ts +13 -0
- package/src/features/voice/playing/components/VoiceIcon.tsx +38 -0
- package/src/features/voice/playing/components/VoiceTranscriptionsDropdown.tsx +239 -0
- package/src/features/voice/playing/components/VoiceTranscriptionsDropdownItem.tsx +127 -0
- package/src/features/voice/playing/hooks/useVoiceTranscriptionsDropdown.ts +54 -0
- package/src/features/voice/playing/hooks/useVoiceTranscriptionsDropdownItemAnimation.ts +40 -0
- package/src/features/voice/playing/model/Player.model.ts +92 -0
- package/src/features/voice/playing/model/VoicePlayer.model.ts +282 -0
- package/src/features/voice/playing/model/VoiceTranscriptionsCollection.ts +53 -0
- package/src/features/voice/playing/model/VoiceTranscriptionsDownloader.model.ts +43 -0
- package/src/features/voice/playing/model/VoiceTranscriptionsDropdown.model.ts +12 -0
- package/src/features/voice/playing/model/index.ts +6 -0
- package/src/features/voice/recording/components/VoiceRecord.tsx +65 -0
- package/src/features/voice/recording/components/VoiceRecordButton.tsx +63 -0
- package/src/features/voice/recording/components/VoiceRecordDeleteButton.tsx +25 -0
- package/src/features/voice/recording/components/VoiceRecordDevider.tsx +17 -0
- package/src/features/voice/recording/components/VoiceRecordTimer.tsx +49 -0
- package/src/features/voice/recording/hooks/useVoiceRecorder.ts +62 -0
- package/src/features/voice/recording/hooks/useVoiceRecorderAnimation.ts +19 -0
- package/src/features/voice/recording/modal/ModalFooterButtons.tsx +54 -0
- package/src/features/voice/recording/modal/VoiceRecordDeleteModal.tsx +82 -0
- package/src/features/voice/recording/modal/VoiceRecordUndoModal.tsx +50 -0
- package/src/features/voice/recording/model/Recorder.model.ts +62 -0
- package/src/features/voice/recording/model/Uploader.model.ts +48 -0
- package/src/features/voice/recording/model/VoiceRecord.model.ts +278 -0
- package/src/features/voice/recording/model/VoiceRecordCollection.ts +26 -0
- package/src/features/voice/recording/model/index.ts +4 -0
- package/src/features/voice/types.ts +69 -0
- package/src/index.ts +1 -0
- package/src/shared/components/PlayButton.tsx +84 -0
- package/src/shared/translation/localization/ca.json +17 -0
- package/src/shared/translation/localization/de.json +17 -0
- package/src/shared/translation/localization/en.json +17 -0
- package/src/shared/translation/localization/gb.json +17 -0
- package/src/shared/translation/localization/sct.json +17 -0
- package/src/shared/translation/localization/sw.json +17 -0
- package/src/types/common.types.ts +1 -0
- package/dist/commonjs/features/chatbot/TTS_HIGHLIGHTING.md +0 -120
- package/dist/module/features/chatbot/TTS_HIGHLIGHTING.md +0 -120
- package/src/features/chatbot/TTS_HIGHLIGHTING.md +0 -120
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Typography,
|
|
3
|
+
ScrollableList,
|
|
4
|
+
CaretDownIcon,
|
|
5
|
+
COLORS,
|
|
6
|
+
IS_WEB,
|
|
7
|
+
} from '@magmamath/react-native-ui'
|
|
8
|
+
import { useUnit } from 'effector-react'
|
|
9
|
+
import React, { useRef, useEffect, useState, useCallback } from 'react'
|
|
10
|
+
import { TouchableOpacity, StyleProp, ViewStyle, FlatList, View, StyleSheet } from 'react-native'
|
|
11
|
+
import Animated, { FadeIn, FadeOut } from 'react-native-reanimated'
|
|
12
|
+
import { AnswerAudio } from '../../types'
|
|
13
|
+
import { useVoiceTranscriptionsDropdown } from '../hooks/useVoiceTranscriptionsDropdown'
|
|
14
|
+
import { VoicePlayerModel, PlayerState, VoiceTranscriptionItem } from '../model'
|
|
15
|
+
import { VoiceTranscriptionsDropdownItem } from './VoiceTranscriptionsDropdownItem'
|
|
16
|
+
import { DROPDOWN_MAX_CONTENT_HEIGHT, NO_AUDIO_BE_MESSAGE } from '../../constants'
|
|
17
|
+
import { useText } from '../../../../shared/translation'
|
|
18
|
+
import { PlayButton } from '../../../../shared/components/PlayButton'
|
|
19
|
+
import { getActiveAttempt, getAudioStatus } from '../../helpers'
|
|
20
|
+
|
|
21
|
+
const AnimatedTouchableOpacity = Animated.createAnimatedComponent(TouchableOpacity)
|
|
22
|
+
|
|
23
|
+
type VoiceTranscriptionsDropdownProps = {
|
|
24
|
+
style?: StyleProp<ViewStyle>
|
|
25
|
+
model: VoicePlayerModel
|
|
26
|
+
answers: AnswerAudio[]
|
|
27
|
+
attemptOffset?: number
|
|
28
|
+
onAttemptOffsetChange?: (offset: number) => void
|
|
29
|
+
attemptsCount?: number
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export const VoiceTranscriptionsDropdown = ({
|
|
33
|
+
style,
|
|
34
|
+
model,
|
|
35
|
+
answers,
|
|
36
|
+
attemptOffset,
|
|
37
|
+
onAttemptOffsetChange,
|
|
38
|
+
attemptsCount,
|
|
39
|
+
}: VoiceTranscriptionsDropdownProps) => {
|
|
40
|
+
const scrollRef = useRef<FlatList | null>(null)
|
|
41
|
+
const t = useText()
|
|
42
|
+
|
|
43
|
+
const [currentAttempt, transcriptsLoaded, playerState] = useUnit([
|
|
44
|
+
model.$currentAttempt,
|
|
45
|
+
model.$transcriptsLoaded,
|
|
46
|
+
model.$playerState,
|
|
47
|
+
])
|
|
48
|
+
|
|
49
|
+
const [attempts, setAttempts] = useState<VoiceTranscriptionItem[]>([])
|
|
50
|
+
const activeAttempt = getActiveAttempt(attemptOffset, attemptsCount)
|
|
51
|
+
|
|
52
|
+
const answersKey = answers.map((a) => `${a._id}:${a.audioFileId ?? ''}`).join(',')
|
|
53
|
+
const answersRef = useRef(answers)
|
|
54
|
+
answersRef.current = answers
|
|
55
|
+
|
|
56
|
+
const { listAnimatedStyle, iconAnimatedStyle, onListLayout } = useVoiceTranscriptionsDropdown(
|
|
57
|
+
model.dropdown,
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
const hasActiveTranscript =
|
|
61
|
+
activeAttempt !== null && answers?.[activeAttempt - 1]?.audioFileId !== undefined
|
|
62
|
+
|
|
63
|
+
const playButtonState = {
|
|
64
|
+
isActive: playerState !== PlayerState.IDLE,
|
|
65
|
+
isLoading: playerState === PlayerState.LOADING,
|
|
66
|
+
status: getAudioStatus(playerState),
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const scrollToAttempt = useCallback(
|
|
70
|
+
(attemptNumber: number) => {
|
|
71
|
+
const index = attempts.findIndex((item) => item.attemptNumber === attemptNumber)
|
|
72
|
+
if (index !== -1) {
|
|
73
|
+
scrollRef.current?.scrollToIndex({ index, animated: true, viewPosition: 0 })
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
[attempts],
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
const handleItemToggle = useCallback(
|
|
80
|
+
(attempt: number) => {
|
|
81
|
+
if (onAttemptOffsetChange && attemptsCount !== undefined) {
|
|
82
|
+
onAttemptOffsetChange(attemptsCount - attempt)
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
[onAttemptOffsetChange, attemptsCount],
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
const handlePlayPress = useCallback(() => {
|
|
89
|
+
if (activeAttempt) {
|
|
90
|
+
model.togglePlayPause(activeAttempt)
|
|
91
|
+
}
|
|
92
|
+
}, [model, activeAttempt])
|
|
93
|
+
|
|
94
|
+
const handleScrollToIndexFailed = useCallback((info: { index: number }) => {
|
|
95
|
+
setTimeout(() => {
|
|
96
|
+
scrollRef.current?.scrollToIndex({ index: info.index, animated: true, viewPosition: 0 })
|
|
97
|
+
}, 100)
|
|
98
|
+
}, [])
|
|
99
|
+
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
model.reinitializePlayer()
|
|
102
|
+
return () => model.cleanup()
|
|
103
|
+
}, [model])
|
|
104
|
+
|
|
105
|
+
useEffect(() => {
|
|
106
|
+
if (answersRef.current.some((answer) => answer.audioFileId)) {
|
|
107
|
+
model.initializeWithAudios(answersRef.current)
|
|
108
|
+
model.loadAllTranscripts()
|
|
109
|
+
}
|
|
110
|
+
}, [model, answersKey])
|
|
111
|
+
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (answers.length > 0 && !answers.find((answer) => answer.drawing)) {
|
|
114
|
+
model.dropdown.setExpanded(true)
|
|
115
|
+
}
|
|
116
|
+
model.stopAudio()
|
|
117
|
+
}, [attemptOffset])
|
|
118
|
+
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const allAttempts = model.getAllAttempts()
|
|
121
|
+
const validAttempts = allAttempts.filter(
|
|
122
|
+
(item) => typeof item.attemptNumber === 'number' && !isNaN(item.attemptNumber),
|
|
123
|
+
)
|
|
124
|
+
setAttempts(validAttempts)
|
|
125
|
+
}, [answersKey, transcriptsLoaded, currentAttempt, model])
|
|
126
|
+
|
|
127
|
+
useEffect(() => {
|
|
128
|
+
if (activeAttempt !== null) {
|
|
129
|
+
scrollToAttempt(activeAttempt)
|
|
130
|
+
}
|
|
131
|
+
}, [activeAttempt, hasActiveTranscript, scrollToAttempt, model])
|
|
132
|
+
|
|
133
|
+
const renderItem = useCallback(
|
|
134
|
+
({ item }: { item: VoiceTranscriptionItem }) => {
|
|
135
|
+
const isLoading = model.isTranscriptLoading(item.attemptNumber)
|
|
136
|
+
const transcript = model.getTranscript(item.attemptNumber)
|
|
137
|
+
const isActive = activeAttempt === item.attemptNumber
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
<VoiceTranscriptionsDropdownItem
|
|
141
|
+
isLoading={isActive && isLoading}
|
|
142
|
+
attempt={item.attemptNumber}
|
|
143
|
+
content={
|
|
144
|
+
transcript && transcript !== NO_AUDIO_BE_MESSAGE
|
|
145
|
+
? transcript
|
|
146
|
+
: t('voice.transcriptNotAvailable')
|
|
147
|
+
}
|
|
148
|
+
isActive={isActive}
|
|
149
|
+
onToggle={handleItemToggle}
|
|
150
|
+
scrollToAttempt={scrollToAttempt}
|
|
151
|
+
/>
|
|
152
|
+
)
|
|
153
|
+
},
|
|
154
|
+
[model, activeAttempt, t, handleItemToggle, scrollToAttempt],
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
return (
|
|
158
|
+
<Animated.View style={[styles.container, style]}>
|
|
159
|
+
<View style={styles.header}>
|
|
160
|
+
<Typography style={styles.title} variant="h7">
|
|
161
|
+
{t('voice.transcriptions')}
|
|
162
|
+
</Typography>
|
|
163
|
+
{hasActiveTranscript && (
|
|
164
|
+
<Animated.View entering={FadeIn.duration(120)} exiting={FadeOut.duration(120)}>
|
|
165
|
+
<PlayButton
|
|
166
|
+
state={playButtonState}
|
|
167
|
+
onPress={handlePlayPress}
|
|
168
|
+
activityIndicatorColor={COLORS.NEUTRAL_1}
|
|
169
|
+
/>
|
|
170
|
+
</Animated.View>
|
|
171
|
+
)}
|
|
172
|
+
</View>
|
|
173
|
+
|
|
174
|
+
<Animated.View style={[listAnimatedStyle, { overflow: 'hidden' }]}>
|
|
175
|
+
<View onLayout={onListLayout} style={styles.listContainer}>
|
|
176
|
+
<ScrollableList
|
|
177
|
+
bounces={false}
|
|
178
|
+
ref={scrollRef}
|
|
179
|
+
hideShadow
|
|
180
|
+
data={attempts}
|
|
181
|
+
keyExtractor={(item) => item._id}
|
|
182
|
+
onScrollToIndexFailed={handleScrollToIndexFailed}
|
|
183
|
+
renderItem={renderItem}
|
|
184
|
+
style={IS_WEB && styles.list}
|
|
185
|
+
contentContainerStyle={styles.listContent}
|
|
186
|
+
/>
|
|
187
|
+
</View>
|
|
188
|
+
</Animated.View>
|
|
189
|
+
|
|
190
|
+
<AnimatedTouchableOpacity
|
|
191
|
+
style={[styles.expandButton, iconAnimatedStyle]}
|
|
192
|
+
onPress={() => model.dropdown.toggleExpand()}
|
|
193
|
+
>
|
|
194
|
+
<CaretDownIcon size={22} />
|
|
195
|
+
</AnimatedTouchableOpacity>
|
|
196
|
+
</Animated.View>
|
|
197
|
+
)
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const styles = StyleSheet.create({
|
|
201
|
+
container: {
|
|
202
|
+
position: 'absolute',
|
|
203
|
+
top: 56,
|
|
204
|
+
left: 8,
|
|
205
|
+
width: 222,
|
|
206
|
+
maxHeight: 405,
|
|
207
|
+
minHeight: 51,
|
|
208
|
+
padding: 4,
|
|
209
|
+
boxShadow: '0px 1px 3px 0px rgba(51, 51, 51, 0.25)',
|
|
210
|
+
borderRadius: 12,
|
|
211
|
+
backgroundColor: COLORS.NEUTRAL_1,
|
|
212
|
+
overflow: 'hidden',
|
|
213
|
+
},
|
|
214
|
+
header: {
|
|
215
|
+
flexDirection: 'row',
|
|
216
|
+
justifyContent: 'space-between',
|
|
217
|
+
alignItems: 'center',
|
|
218
|
+
padding: 4,
|
|
219
|
+
marginBottom: 4,
|
|
220
|
+
height: 32,
|
|
221
|
+
},
|
|
222
|
+
title: {
|
|
223
|
+
color: COLORS.NEUTRAL_9,
|
|
224
|
+
marginLeft: 4,
|
|
225
|
+
},
|
|
226
|
+
list: { flex: 1 },
|
|
227
|
+
expandButton: {
|
|
228
|
+
justifyContent: 'center',
|
|
229
|
+
alignItems: 'center',
|
|
230
|
+
},
|
|
231
|
+
listContainer: {
|
|
232
|
+
position: 'absolute',
|
|
233
|
+
maxHeight: DROPDOWN_MAX_CONTENT_HEIGHT,
|
|
234
|
+
width: '100%',
|
|
235
|
+
},
|
|
236
|
+
listContent: {
|
|
237
|
+
paddingHorizontal: 4,
|
|
238
|
+
},
|
|
239
|
+
})
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { Pressable, StyleSheet, View } from 'react-native'
|
|
2
|
+
import React, { memo, useCallback } from 'react'
|
|
3
|
+
import {
|
|
4
|
+
Button,
|
|
5
|
+
ButtonSize,
|
|
6
|
+
ButtonVariant,
|
|
7
|
+
COLORS,
|
|
8
|
+
Loader,
|
|
9
|
+
LoaderColor,
|
|
10
|
+
LoaderSize,
|
|
11
|
+
Typography,
|
|
12
|
+
} from '@magmamath/react-native-ui'
|
|
13
|
+
import Animated, { runOnJS, useAnimatedReaction } from 'react-native-reanimated'
|
|
14
|
+
import { useVoiceTranscriptionsDropdownItemAnimation } from '../hooks/useVoiceTranscriptionsDropdownItemAnimation'
|
|
15
|
+
import { useText } from '../../../../shared/translation'
|
|
16
|
+
|
|
17
|
+
type VoiceTranscriptionsDropdownItemProps = {
|
|
18
|
+
attempt: number
|
|
19
|
+
content: string
|
|
20
|
+
isActive: boolean
|
|
21
|
+
isLoading?: boolean
|
|
22
|
+
onToggle: (attempt: number) => void
|
|
23
|
+
scrollToAttempt: (attempt: number) => void
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export const VoiceTranscriptionsDropdownItem = memo(
|
|
27
|
+
({
|
|
28
|
+
attempt,
|
|
29
|
+
content,
|
|
30
|
+
isActive,
|
|
31
|
+
isLoading,
|
|
32
|
+
onToggle,
|
|
33
|
+
scrollToAttempt,
|
|
34
|
+
}: VoiceTranscriptionsDropdownItemProps) => {
|
|
35
|
+
const t = useText()
|
|
36
|
+
|
|
37
|
+
const { contentAnimatedStyle, onLayout, progress } =
|
|
38
|
+
useVoiceTranscriptionsDropdownItemAnimation(isActive)
|
|
39
|
+
|
|
40
|
+
const handleScrollToAttempt = useCallback(
|
|
41
|
+
(attemptNumber: number) => {
|
|
42
|
+
setTimeout(() => {
|
|
43
|
+
scrollToAttempt(attemptNumber)
|
|
44
|
+
}, 300)
|
|
45
|
+
},
|
|
46
|
+
[scrollToAttempt],
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
useAnimatedReaction(
|
|
50
|
+
() => progress.value,
|
|
51
|
+
(progress) => {
|
|
52
|
+
if (progress === 1 && isActive) {
|
|
53
|
+
runOnJS(handleScrollToAttempt)(attempt)
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
[progress, attempt, isActive],
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
return (
|
|
60
|
+
<View style={styles.container}>
|
|
61
|
+
<Pressable disabled={isActive} style={styles.itemHeader} onPress={() => onToggle(attempt)}>
|
|
62
|
+
<Button
|
|
63
|
+
onPress={() => !isActive && onToggle(attempt)}
|
|
64
|
+
size={ButtonSize.SMALL}
|
|
65
|
+
variant={ButtonVariant.TERTIARY}
|
|
66
|
+
style={{
|
|
67
|
+
text: {
|
|
68
|
+
textTransform: 'uppercase',
|
|
69
|
+
color: isActive ? COLORS.NEUTRAL_9 : COLORS.NEUTRAL_7,
|
|
70
|
+
},
|
|
71
|
+
}}
|
|
72
|
+
>
|
|
73
|
+
{t('voice.attempt', { number: String(attempt) })}
|
|
74
|
+
</Button>
|
|
75
|
+
</Pressable>
|
|
76
|
+
{isLoading ? (
|
|
77
|
+
<View style={styles.loaderContainer}>
|
|
78
|
+
<Loader size={LoaderSize.SMALL} color={LoaderColor.BLUE} />
|
|
79
|
+
</View>
|
|
80
|
+
) : (
|
|
81
|
+
<Animated.View style={contentAnimatedStyle}>
|
|
82
|
+
<View onLayout={onLayout} style={styles.contentWrapper}>
|
|
83
|
+
<Typography
|
|
84
|
+
variant="h8"
|
|
85
|
+
style={[
|
|
86
|
+
styles.itemContent,
|
|
87
|
+
{
|
|
88
|
+
color: isActive ? COLORS.NEUTRAL_9 : COLORS.NEUTRAL_7,
|
|
89
|
+
},
|
|
90
|
+
]}
|
|
91
|
+
>
|
|
92
|
+
{content}
|
|
93
|
+
</Typography>
|
|
94
|
+
</View>
|
|
95
|
+
</Animated.View>
|
|
96
|
+
)}
|
|
97
|
+
</View>
|
|
98
|
+
)
|
|
99
|
+
},
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
const styles = StyleSheet.create({
|
|
103
|
+
container: {
|
|
104
|
+
borderTopWidth: 1,
|
|
105
|
+
borderColor: COLORS.NEUTRAL_3,
|
|
106
|
+
},
|
|
107
|
+
itemHeader: {
|
|
108
|
+
flexDirection: 'row',
|
|
109
|
+
justifyContent: 'space-between',
|
|
110
|
+
alignItems: 'center',
|
|
111
|
+
width: '100%',
|
|
112
|
+
paddingVertical: 8,
|
|
113
|
+
},
|
|
114
|
+
itemContent: {
|
|
115
|
+
paddingHorizontal: 8,
|
|
116
|
+
},
|
|
117
|
+
contentWrapper: {
|
|
118
|
+
width: '100%',
|
|
119
|
+
position: 'absolute',
|
|
120
|
+
},
|
|
121
|
+
loaderContainer: {
|
|
122
|
+
justifyContent: 'center',
|
|
123
|
+
alignItems: 'center',
|
|
124
|
+
paddingTop: 4,
|
|
125
|
+
paddingBottom: 8,
|
|
126
|
+
},
|
|
127
|
+
})
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import { useUnit } from 'effector-react'
|
|
3
|
+
import { useAnimatedStyle, useSharedValue, withTiming, interpolate } from 'react-native-reanimated'
|
|
4
|
+
import { VoiceTranscriptionsDropdownModel } from '../model/VoiceTranscriptionsDropdown.model'
|
|
5
|
+
import { DROPDOWN_MAX_CONTENT_HEIGHT } from '../../constants'
|
|
6
|
+
import { LayoutChangeEvent } from 'react-native'
|
|
7
|
+
|
|
8
|
+
export const useVoiceTranscriptionsDropdown = (model: VoiceTranscriptionsDropdownModel) => {
|
|
9
|
+
const isExpanded = useUnit(model.$isExpanded)
|
|
10
|
+
|
|
11
|
+
const contentHeight = useSharedValue(0)
|
|
12
|
+
const animationProgress = useSharedValue(isExpanded ? 1 : 0)
|
|
13
|
+
|
|
14
|
+
const onListLayout = (event: LayoutChangeEvent) => {
|
|
15
|
+
const measuredHeight = event.nativeEvent.layout.height
|
|
16
|
+
if (measuredHeight > 0) {
|
|
17
|
+
contentHeight.value = measuredHeight
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const listAnimatedStyle = useAnimatedStyle(() => {
|
|
22
|
+
const height = interpolate(
|
|
23
|
+
animationProgress.value,
|
|
24
|
+
[0, 1],
|
|
25
|
+
[0, contentHeight.value || DROPDOWN_MAX_CONTENT_HEIGHT],
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
const opacity = interpolate(animationProgress.value, [0, 0.3, 1], [0, 0, 1])
|
|
29
|
+
|
|
30
|
+
return {
|
|
31
|
+
height,
|
|
32
|
+
opacity,
|
|
33
|
+
}
|
|
34
|
+
}, [animationProgress, contentHeight])
|
|
35
|
+
|
|
36
|
+
const iconAnimatedStyle = useAnimatedStyle(() => {
|
|
37
|
+
const rotation = interpolate(animationProgress.value, [0, 1], [0, 180])
|
|
38
|
+
|
|
39
|
+
return {
|
|
40
|
+
transform: [{ rotate: `${rotation}deg` }],
|
|
41
|
+
}
|
|
42
|
+
}, [animationProgress])
|
|
43
|
+
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
animationProgress.value = withTiming(isExpanded ? 1 : 0, { duration: 300 })
|
|
46
|
+
}, [isExpanded, animationProgress])
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
isExpanded,
|
|
50
|
+
listAnimatedStyle,
|
|
51
|
+
iconAnimatedStyle,
|
|
52
|
+
onListLayout,
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { useEffect } from 'react'
|
|
2
|
+
import { LayoutChangeEvent } from 'react-native'
|
|
3
|
+
import {
|
|
4
|
+
useSharedValue,
|
|
5
|
+
withTiming,
|
|
6
|
+
useDerivedValue,
|
|
7
|
+
useAnimatedStyle,
|
|
8
|
+
interpolate,
|
|
9
|
+
} from 'react-native-reanimated'
|
|
10
|
+
|
|
11
|
+
export const useVoiceTranscriptionsDropdownItemAnimation = (isExpanded: boolean) => {
|
|
12
|
+
const height = useSharedValue(0)
|
|
13
|
+
const progress = useSharedValue(isExpanded ? 1 : 0)
|
|
14
|
+
|
|
15
|
+
useEffect(() => {
|
|
16
|
+
progress.value = withTiming(isExpanded ? 1 : 0)
|
|
17
|
+
}, [isExpanded, progress])
|
|
18
|
+
|
|
19
|
+
const derivedHeight = useDerivedValue(() => height.value * progress.value, [height, progress])
|
|
20
|
+
|
|
21
|
+
const contentAnimatedStyle = useAnimatedStyle(() => {
|
|
22
|
+
const opacity = interpolate(progress.value, [0, 0.3, 1], [0, 0, 1])
|
|
23
|
+
|
|
24
|
+
return {
|
|
25
|
+
height: derivedHeight.value,
|
|
26
|
+
opacity,
|
|
27
|
+
overflow: 'hidden',
|
|
28
|
+
}
|
|
29
|
+
}, [progress, derivedHeight])
|
|
30
|
+
|
|
31
|
+
const onLayout = (event: LayoutChangeEvent) => {
|
|
32
|
+
height.value = event.nativeEvent.layout.height
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return {
|
|
36
|
+
contentAnimatedStyle,
|
|
37
|
+
onLayout,
|
|
38
|
+
progress,
|
|
39
|
+
}
|
|
40
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { createEffect, createEvent, restore } from 'effector'
|
|
2
|
+
import { AudioPlayer, createAudioPlayer } from 'expo-audio'
|
|
3
|
+
|
|
4
|
+
export enum PlayerState {
|
|
5
|
+
PLAYING = 'playing',
|
|
6
|
+
PAUSED = 'paused',
|
|
7
|
+
LOADING = 'loading',
|
|
8
|
+
IDLE = 'idle',
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class PlayerModel {
|
|
12
|
+
public player: AudioPlayer | null = createAudioPlayer()
|
|
13
|
+
|
|
14
|
+
public readonly reset = createEvent()
|
|
15
|
+
public readonly setPlayerState = createEvent<PlayerState>()
|
|
16
|
+
public readonly playbackFinished = createEvent()
|
|
17
|
+
|
|
18
|
+
public readonly $playerState = restore(this.setPlayerState, PlayerState.IDLE).reset(this.reset)
|
|
19
|
+
|
|
20
|
+
public readonly pause = createEffect(() => {
|
|
21
|
+
if (this.player) {
|
|
22
|
+
this.player.pause()
|
|
23
|
+
this.setPlayerState(PlayerState.PAUSED)
|
|
24
|
+
} else {
|
|
25
|
+
console.warn('Cannot pause: audio player not initialized')
|
|
26
|
+
}
|
|
27
|
+
})
|
|
28
|
+
|
|
29
|
+
public readonly stop = createEffect(() => {
|
|
30
|
+
if (this.player) {
|
|
31
|
+
this.player.replace('')
|
|
32
|
+
this.setPlayerState(PlayerState.IDLE)
|
|
33
|
+
} else {
|
|
34
|
+
console.warn('Cannot stop: audio player not initialized')
|
|
35
|
+
}
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
public readonly resume = createEffect(() => {
|
|
39
|
+
if (this.player) {
|
|
40
|
+
this.player.play()
|
|
41
|
+
this.setPlayerState(PlayerState.PLAYING)
|
|
42
|
+
} else {
|
|
43
|
+
console.warn('Cannot resume: audio player not initialized')
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
|
|
47
|
+
public readonly play = createEffect(async (uri: string) => {
|
|
48
|
+
if (!this.player) {
|
|
49
|
+
console.warn('Audio player not initialized')
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
this.player.replace(uri)
|
|
54
|
+
|
|
55
|
+
const waitForLoad = () => {
|
|
56
|
+
if (this.player && this.player.isLoaded) {
|
|
57
|
+
const unsubscribe = this.player.addListener('playbackStatusUpdate', (status) => {
|
|
58
|
+
if (status.didJustFinish) {
|
|
59
|
+
this.playbackFinished()
|
|
60
|
+
unsubscribe?.remove?.()
|
|
61
|
+
this.setPlayerState(PlayerState.IDLE)
|
|
62
|
+
}
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
this.player.play()
|
|
66
|
+
this.setPlayerState(PlayerState.PLAYING)
|
|
67
|
+
} else {
|
|
68
|
+
setTimeout(waitForLoad, 10)
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
waitForLoad()
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
public reinitialize() {
|
|
76
|
+
if (!this.player) {
|
|
77
|
+
this.player = createAudioPlayer()
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
public release() {
|
|
82
|
+
if (this.player) {
|
|
83
|
+
try {
|
|
84
|
+
this.stop()
|
|
85
|
+
this.player.remove()
|
|
86
|
+
} catch (error) {}
|
|
87
|
+
this.player.release()
|
|
88
|
+
this.player = null
|
|
89
|
+
}
|
|
90
|
+
this.reset()
|
|
91
|
+
}
|
|
92
|
+
}
|