@magmamath/students-features 0.9.106 → 0.9.107-rc.10

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.
Files changed (246) hide show
  1. package/dist/commonjs/features/voiceRecord/components/VoiceRecord.js +81 -0
  2. package/dist/commonjs/features/voiceRecord/components/VoiceRecord.js.map +1 -0
  3. package/dist/commonjs/features/voiceRecord/components/VoiceRecordButton.js +72 -0
  4. package/dist/commonjs/features/voiceRecord/components/VoiceRecordButton.js.map +1 -0
  5. package/dist/commonjs/features/voiceRecord/components/VoiceRecordDeleteButton.js +32 -0
  6. package/dist/commonjs/features/voiceRecord/components/VoiceRecordDeleteButton.js.map +1 -0
  7. package/dist/commonjs/features/voiceRecord/components/VoiceRecordDevider.js +27 -0
  8. package/dist/commonjs/features/voiceRecord/components/VoiceRecordDevider.js.map +1 -0
  9. package/dist/commonjs/features/voiceRecord/components/VoiceRecordTimer.js +49 -0
  10. package/dist/commonjs/features/voiceRecord/components/VoiceRecordTimer.js.map +1 -0
  11. package/dist/commonjs/features/voiceRecord/constants.js +18 -0
  12. package/dist/commonjs/features/voiceRecord/constants.js.map +1 -0
  13. package/dist/commonjs/features/voiceRecord/helpers.js +138 -0
  14. package/dist/commonjs/features/voiceRecord/helpers.js.map +1 -0
  15. package/dist/commonjs/features/voiceRecord/hooks/useVoiceRecorder.js +75 -0
  16. package/dist/commonjs/features/voiceRecord/hooks/useVoiceRecorder.js.map +1 -0
  17. package/dist/commonjs/features/voiceRecord/hooks/useVoiceRecorderAnimation.js +22 -0
  18. package/dist/commonjs/features/voiceRecord/hooks/useVoiceRecorderAnimation.js.map +1 -0
  19. package/dist/commonjs/features/voiceRecord/index.js +72 -0
  20. package/dist/commonjs/features/voiceRecord/index.js.map +1 -0
  21. package/dist/commonjs/features/voiceRecord/modal/VoiceRecordDeleteModal.js +93 -0
  22. package/dist/commonjs/features/voiceRecord/modal/VoiceRecordDeleteModal.js.map +1 -0
  23. package/dist/commonjs/features/voiceRecord/modal/VoiceRecordUndoModal.js +75 -0
  24. package/dist/commonjs/features/voiceRecord/modal/VoiceRecordUndoModal.js.map +1 -0
  25. package/dist/commonjs/features/voiceRecord/model/Recorder.model.js +37 -0
  26. package/dist/commonjs/features/voiceRecord/model/Recorder.model.js.map +1 -0
  27. package/dist/commonjs/features/voiceRecord/model/VoiceRecord.model.js +151 -0
  28. package/dist/commonjs/features/voiceRecord/model/VoiceRecord.model.js.map +1 -0
  29. package/dist/commonjs/features/voiceRecord/model/VoiceRecordApi.js +29 -0
  30. package/dist/commonjs/features/voiceRecord/model/VoiceRecordApi.js.map +1 -0
  31. package/dist/commonjs/features/voiceRecord/model/VoiceRecordCollection.js +30 -0
  32. package/dist/commonjs/features/voiceRecord/model/VoiceRecordCollection.js.map +1 -0
  33. package/dist/commonjs/features/voiceRecord/types.js +6 -0
  34. package/dist/commonjs/features/voiceRecord/types.js.map +1 -0
  35. package/dist/commonjs/index.js +12 -0
  36. package/dist/commonjs/index.js.map +1 -1
  37. package/dist/commonjs/shared/translation/localization/ca.json +13 -0
  38. package/dist/commonjs/shared/translation/localization/de.json +13 -0
  39. package/dist/commonjs/shared/translation/localization/en.json +13 -0
  40. package/dist/commonjs/shared/translation/localization/gb.json +13 -0
  41. package/dist/commonjs/shared/translation/localization/sct.json +13 -0
  42. package/dist/commonjs/shared/translation/localization/sw.json +13 -0
  43. package/dist/module/features/voiceRecord/components/VoiceRecord.js +73 -0
  44. package/dist/module/features/voiceRecord/components/VoiceRecord.js.map +1 -0
  45. package/dist/module/features/voiceRecord/components/VoiceRecordButton.js +66 -0
  46. package/dist/module/features/voiceRecord/components/VoiceRecordButton.js.map +1 -0
  47. package/dist/module/features/voiceRecord/components/VoiceRecordDeleteButton.js +26 -0
  48. package/dist/module/features/voiceRecord/components/VoiceRecordDeleteButton.js.map +1 -0
  49. package/dist/module/features/voiceRecord/components/VoiceRecordDevider.js +21 -0
  50. package/dist/module/features/voiceRecord/components/VoiceRecordDevider.js.map +1 -0
  51. package/dist/module/features/voiceRecord/components/VoiceRecordTimer.js +43 -0
  52. package/dist/module/features/voiceRecord/components/VoiceRecordTimer.js.map +1 -0
  53. package/dist/module/features/voiceRecord/constants.js +14 -0
  54. package/dist/module/features/voiceRecord/constants.js.map +1 -0
  55. package/dist/module/features/voiceRecord/helpers.js +127 -0
  56. package/dist/module/features/voiceRecord/helpers.js.map +1 -0
  57. package/dist/module/features/voiceRecord/hooks/useVoiceRecorder.js +70 -0
  58. package/dist/module/features/voiceRecord/hooks/useVoiceRecorder.js.map +1 -0
  59. package/dist/module/features/voiceRecord/hooks/useVoiceRecorderAnimation.js +17 -0
  60. package/dist/module/features/voiceRecord/hooks/useVoiceRecorderAnimation.js.map +1 -0
  61. package/dist/module/features/voiceRecord/index.js +9 -0
  62. package/dist/module/features/voiceRecord/index.js.map +1 -0
  63. package/dist/module/features/voiceRecord/modal/VoiceRecordDeleteModal.js +86 -0
  64. package/dist/module/features/voiceRecord/modal/VoiceRecordDeleteModal.js.map +1 -0
  65. package/dist/module/features/voiceRecord/modal/VoiceRecordUndoModal.js +69 -0
  66. package/dist/module/features/voiceRecord/modal/VoiceRecordUndoModal.js.map +1 -0
  67. package/dist/module/features/voiceRecord/model/Recorder.model.js +32 -0
  68. package/dist/module/features/voiceRecord/model/Recorder.model.js.map +1 -0
  69. package/dist/module/features/voiceRecord/model/VoiceRecord.model.js +146 -0
  70. package/dist/module/features/voiceRecord/model/VoiceRecord.model.js.map +1 -0
  71. package/dist/module/features/voiceRecord/model/VoiceRecordApi.js +24 -0
  72. package/dist/module/features/voiceRecord/model/VoiceRecordApi.js.map +1 -0
  73. package/dist/module/features/voiceRecord/model/VoiceRecordCollection.js +25 -0
  74. package/dist/module/features/voiceRecord/model/VoiceRecordCollection.js.map +1 -0
  75. package/dist/module/features/voiceRecord/types.js +4 -0
  76. package/dist/module/features/voiceRecord/types.js.map +1 -0
  77. package/dist/module/index.js +1 -0
  78. package/dist/module/index.js.map +1 -1
  79. package/dist/module/shared/translation/localization/ca.json +13 -0
  80. package/dist/module/shared/translation/localization/de.json +13 -0
  81. package/dist/module/shared/translation/localization/en.json +13 -0
  82. package/dist/module/shared/translation/localization/gb.json +13 -0
  83. package/dist/module/shared/translation/localization/sct.json +13 -0
  84. package/dist/module/shared/translation/localization/sw.json +13 -0
  85. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecord.d.ts +10 -0
  86. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecord.d.ts.map +1 -0
  87. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordButton.d.ts +11 -0
  88. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordButton.d.ts.map +1 -0
  89. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordDeleteButton.d.ts +7 -0
  90. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordDeleteButton.d.ts.map +1 -0
  91. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordDevider.d.ts +3 -0
  92. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordDevider.d.ts.map +1 -0
  93. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordTimer.d.ts +11 -0
  94. package/dist/typescript/commonjs/features/voiceRecord/components/VoiceRecordTimer.d.ts.map +1 -0
  95. package/dist/typescript/commonjs/features/voiceRecord/constants.d.ts +11 -0
  96. package/dist/typescript/commonjs/features/voiceRecord/constants.d.ts.map +1 -0
  97. package/dist/typescript/commonjs/features/voiceRecord/helpers.d.ts +29 -0
  98. package/dist/typescript/commonjs/features/voiceRecord/helpers.d.ts.map +1 -0
  99. package/dist/typescript/commonjs/features/voiceRecord/hooks/useVoiceRecorder.d.ts +5 -0
  100. package/dist/typescript/commonjs/features/voiceRecord/hooks/useVoiceRecorder.d.ts.map +1 -0
  101. package/dist/typescript/commonjs/features/voiceRecord/hooks/useVoiceRecorderAnimation.d.ts +6 -0
  102. package/dist/typescript/commonjs/features/voiceRecord/hooks/useVoiceRecorderAnimation.d.ts.map +1 -0
  103. package/dist/typescript/commonjs/features/voiceRecord/index.d.ts +7 -0
  104. package/dist/typescript/commonjs/features/voiceRecord/index.d.ts.map +1 -0
  105. package/dist/typescript/commonjs/features/voiceRecord/modal/VoiceRecordDeleteModal.d.ts +13 -0
  106. package/dist/typescript/commonjs/features/voiceRecord/modal/VoiceRecordDeleteModal.d.ts.map +1 -0
  107. package/dist/typescript/commonjs/features/voiceRecord/modal/VoiceRecordUndoModal.d.ts +13 -0
  108. package/dist/typescript/commonjs/features/voiceRecord/modal/VoiceRecordUndoModal.d.ts.map +1 -0
  109. package/dist/typescript/commonjs/features/voiceRecord/model/Recorder.model.d.ts +15 -0
  110. package/dist/typescript/commonjs/features/voiceRecord/model/Recorder.model.d.ts.map +1 -0
  111. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecord.model.d.ts +39 -0
  112. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecord.model.d.ts.map +1 -0
  113. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecordApi.d.ts +5 -0
  114. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecordApi.d.ts.map +1 -0
  115. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecordCollection.d.ts +10 -0
  116. package/dist/typescript/commonjs/features/voiceRecord/model/VoiceRecordCollection.d.ts.map +1 -0
  117. package/dist/typescript/commonjs/features/voiceRecord/types.d.ts +43 -0
  118. package/dist/typescript/commonjs/features/voiceRecord/types.d.ts.map +1 -0
  119. package/dist/typescript/commonjs/index.d.ts +1 -0
  120. package/dist/typescript/commonjs/index.d.ts.map +1 -1
  121. package/dist/typescript/commonjs/shared/translation/constants.d.ts +78 -0
  122. package/dist/typescript/commonjs/shared/translation/constants.d.ts.map +1 -1
  123. package/dist/typescript/commonjs/shared/translation/model.d.ts +26 -0
  124. package/dist/typescript/commonjs/shared/translation/model.d.ts.map +1 -1
  125. package/dist/typescript/commonjs/types/common.types.d.ts +3 -0
  126. package/dist/typescript/commonjs/types/common.types.d.ts.map +1 -1
  127. package/dist/typescript/module/features/voiceRecord/components/VoiceRecord.d.ts +10 -0
  128. package/dist/typescript/module/features/voiceRecord/components/VoiceRecord.d.ts.map +1 -0
  129. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordButton.d.ts +11 -0
  130. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordButton.d.ts.map +1 -0
  131. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordDeleteButton.d.ts +7 -0
  132. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordDeleteButton.d.ts.map +1 -0
  133. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordDevider.d.ts +3 -0
  134. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordDevider.d.ts.map +1 -0
  135. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordTimer.d.ts +11 -0
  136. package/dist/typescript/module/features/voiceRecord/components/VoiceRecordTimer.d.ts.map +1 -0
  137. package/dist/typescript/module/features/voiceRecord/constants.d.ts +11 -0
  138. package/dist/typescript/module/features/voiceRecord/constants.d.ts.map +1 -0
  139. package/dist/typescript/module/features/voiceRecord/helpers.d.ts +29 -0
  140. package/dist/typescript/module/features/voiceRecord/helpers.d.ts.map +1 -0
  141. package/dist/typescript/module/features/voiceRecord/hooks/useVoiceRecorder.d.ts +5 -0
  142. package/dist/typescript/module/features/voiceRecord/hooks/useVoiceRecorder.d.ts.map +1 -0
  143. package/dist/typescript/module/features/voiceRecord/hooks/useVoiceRecorderAnimation.d.ts +6 -0
  144. package/dist/typescript/module/features/voiceRecord/hooks/useVoiceRecorderAnimation.d.ts.map +1 -0
  145. package/dist/typescript/module/features/voiceRecord/index.d.ts +7 -0
  146. package/dist/typescript/module/features/voiceRecord/index.d.ts.map +1 -0
  147. package/dist/typescript/module/features/voiceRecord/modal/VoiceRecordDeleteModal.d.ts +13 -0
  148. package/dist/typescript/module/features/voiceRecord/modal/VoiceRecordDeleteModal.d.ts.map +1 -0
  149. package/dist/typescript/module/features/voiceRecord/modal/VoiceRecordUndoModal.d.ts +13 -0
  150. package/dist/typescript/module/features/voiceRecord/modal/VoiceRecordUndoModal.d.ts.map +1 -0
  151. package/dist/typescript/module/features/voiceRecord/model/Recorder.model.d.ts +15 -0
  152. package/dist/typescript/module/features/voiceRecord/model/Recorder.model.d.ts.map +1 -0
  153. package/dist/typescript/module/features/voiceRecord/model/VoiceRecord.model.d.ts +39 -0
  154. package/dist/typescript/module/features/voiceRecord/model/VoiceRecord.model.d.ts.map +1 -0
  155. package/dist/typescript/module/features/voiceRecord/model/VoiceRecordApi.d.ts +5 -0
  156. package/dist/typescript/module/features/voiceRecord/model/VoiceRecordApi.d.ts.map +1 -0
  157. package/dist/typescript/module/features/voiceRecord/model/VoiceRecordCollection.d.ts +10 -0
  158. package/dist/typescript/module/features/voiceRecord/model/VoiceRecordCollection.d.ts.map +1 -0
  159. package/dist/typescript/module/features/voiceRecord/types.d.ts +43 -0
  160. package/dist/typescript/module/features/voiceRecord/types.d.ts.map +1 -0
  161. package/dist/typescript/module/index.d.ts +1 -0
  162. package/dist/typescript/module/index.d.ts.map +1 -1
  163. package/dist/typescript/module/shared/translation/constants.d.ts +78 -0
  164. package/dist/typescript/module/shared/translation/constants.d.ts.map +1 -1
  165. package/dist/typescript/module/shared/translation/model.d.ts +26 -0
  166. package/dist/typescript/module/shared/translation/model.d.ts.map +1 -1
  167. package/dist/typescript/module/types/common.types.d.ts +3 -0
  168. package/dist/typescript/module/types/common.types.d.ts.map +1 -1
  169. package/package.json +9 -3
  170. package/src/features/voiceRecord/components/VoiceRecord.tsx +73 -0
  171. package/src/features/voiceRecord/components/VoiceRecordButton.tsx +86 -0
  172. package/src/features/voiceRecord/components/VoiceRecordDeleteButton.tsx +24 -0
  173. package/src/features/voiceRecord/components/VoiceRecordDevider.tsx +17 -0
  174. package/src/features/voiceRecord/components/VoiceRecordTimer.tsx +53 -0
  175. package/src/features/voiceRecord/constants.ts +10 -0
  176. package/src/features/voiceRecord/helpers.ts +167 -0
  177. package/src/features/voiceRecord/hooks/useVoiceRecorder.ts +85 -0
  178. package/src/features/voiceRecord/hooks/useVoiceRecorderAnimation.ts +19 -0
  179. package/src/features/voiceRecord/index.ts +6 -0
  180. package/src/features/voiceRecord/modal/VoiceRecordDeleteModal.tsx +106 -0
  181. package/src/features/voiceRecord/modal/VoiceRecordUndoModal.tsx +82 -0
  182. package/src/features/voiceRecord/model/Recorder.model.ts +40 -0
  183. package/src/features/voiceRecord/model/VoiceRecord.model.ts +178 -0
  184. package/src/features/voiceRecord/model/VoiceRecordApi.ts +25 -0
  185. package/src/features/voiceRecord/model/VoiceRecordCollection.ts +26 -0
  186. package/src/features/voiceRecord/types.ts +49 -0
  187. package/src/index.ts +1 -0
  188. package/src/shared/translation/localization/ca.json +13 -0
  189. package/src/shared/translation/localization/de.json +13 -0
  190. package/src/shared/translation/localization/en.json +13 -0
  191. package/src/shared/translation/localization/gb.json +13 -0
  192. package/src/shared/translation/localization/sct.json +13 -0
  193. package/src/shared/translation/localization/sw.json +13 -0
  194. package/src/types/common.types.ts +1 -0
  195. package/.editorconfig +0 -15
  196. package/.eslintignore +0 -2
  197. package/.eslintrc +0 -22
  198. package/.gitattributes +0 -3
  199. package/.github/actions/setup/action.yml +0 -37
  200. package/.github/workflows/ci.yml +0 -73
  201. package/.gitignore +0 -84
  202. package/.idea/.gitignore +0 -8
  203. package/.idea/codeStyles/Project.xml +0 -62
  204. package/.idea/codeStyles/codeStyleConfig.xml +0 -5
  205. package/.idea/copilot.data.migration.agent.xml +0 -6
  206. package/.idea/copilot.data.migration.ask.xml +0 -6
  207. package/.idea/copilot.data.migration.ask2agent.xml +0 -6
  208. package/.idea/copilot.data.migration.edit.xml +0 -6
  209. package/.idea/inspectionProfiles/Project_Default.xml +0 -8
  210. package/.idea/jsLinters/eslint.xml +0 -6
  211. package/.idea/modules.xml +0 -8
  212. package/.idea/prettier.xml +0 -7
  213. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_30_12_2025,_11_06_[Changes]/shelved.patch +0 -18
  214. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_30_12_2025,_11_07_[Changes]/shelved.patch +0 -18
  215. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_30_12_2025__11_06__Changes_.xml +0 -4
  216. package/.idea/shelf/Uncommitted_changes_before_Checkout_at_30_12_2025__11_07__Changes_.xml +0 -4
  217. package/.idea/students-features.iml +0 -12
  218. package/.idea/vcs.xml +0 -6
  219. package/.idea/workspace.xml +0 -646
  220. package/.nvmrc +0 -1
  221. package/.prettierrc +0 -11
  222. package/.release-it.json +0 -17
  223. package/.watchmanconfig +0 -1
  224. package/.yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs +0 -541
  225. package/.yarn/plugins/@yarnpkg/plugin-workspace-tools.cjs +0 -28
  226. package/.yarn/releases/yarn-3.6.1.cjs +0 -874
  227. package/babel.config.js +0 -5
  228. package/bob.config.js +0 -25
  229. package/example/.expo/README.md +0 -8
  230. package/example/.expo/devices.json +0 -3
  231. package/example/.expo/web/cache/production/images/favicon/favicon-24272cdaeff82cc5facdaccd982a6f05b60c4504704bbf94c19a6388659880bb-contain-transparent/favicon-48.png +0 -0
  232. package/example/app.json +0 -30
  233. package/example/assets/adaptive-icon.png +0 -0
  234. package/example/assets/favicon.png +0 -0
  235. package/example/assets/icon.png +0 -0
  236. package/example/assets/splash-icon.png +0 -0
  237. package/example/babel.config.js +0 -28
  238. package/example/index.js +0 -8
  239. package/example/metro.config.js +0 -18
  240. package/example/package.json +0 -25
  241. package/example/src/App.tsx +0 -8
  242. package/example/tsconfig.json +0 -6
  243. package/example/yarn.lock +0 -6552
  244. package/tsconfig.build.json +0 -4
  245. package/tsconfig.json +0 -34
  246. package/yarn.lock +0 -8623
@@ -0,0 +1,178 @@
1
+ import { attach, combine, createEffect, createEvent, createStore, restore, sample } from 'effector'
2
+ import {
3
+ ensureRecordingPermissions,
4
+ generateAudioFormData,
5
+ getAudioDurationMs,
6
+ getAvailableInputs,
7
+ uploadAudioFileRequestGenerator,
8
+ } from '../helpers'
9
+ import { AudioApi, VoiceRecordNotificationTypes, VoiceRecordStackItem } from '../types'
10
+ import { t } from '../../../shared/translation'
11
+ import { RecorderModel } from './Recorder.model'
12
+ import { VoiceRecordsCollection } from './VoiceRecordCollection'
13
+
14
+ type VoiceRecordModelParams = {
15
+ api: AudioApi
16
+ notification: VoiceRecordNotificationTypes
17
+ events: VoiceRecordEvents
18
+ }
19
+
20
+ type UploadParams = {
21
+ uri: string
22
+ currentKey: string
23
+ }
24
+
25
+ type VoiceRecordEvents = {
26
+ deleteRecord: () => void
27
+ undoRecord: () => void
28
+ }
29
+
30
+ type DeleteCurrentRecordingProps = {
31
+ notification?: boolean
32
+ }
33
+ type DeleteCurrentRecordingValues = {
34
+ currentKey: string
35
+ notification?: boolean
36
+ }
37
+
38
+ export class VoiceRecordModel {
39
+ public readonly recorderModel: RecorderModel
40
+ public readonly collection: VoiceRecordsCollection
41
+ public readonly api: AudioApi
42
+ public readonly notification: VoiceRecordNotificationTypes
43
+ public readonly events: VoiceRecordEvents
44
+
45
+ public readonly setCurrentKey = createEvent<string>()
46
+ public readonly setUri = createEvent<string>()
47
+ public readonly setCurrentRecord = createEvent<any>()
48
+ public readonly reset = createEvent()
49
+
50
+ public readonly $currentKey = restore(this.setCurrentKey, '')
51
+ public readonly $currentRecord = createStore<VoiceRecordStackItem | null>(null).reset(this.reset)
52
+ public readonly $uri = restore(this.setUri, '').reset(this.reset)
53
+
54
+ public readonly deleteCurrentRecording = attach({
55
+ source: this.$currentKey,
56
+ mapParams: (props: DeleteCurrentRecordingProps | void, currentKey) => ({
57
+ notification: true,
58
+ ...props,
59
+ currentKey,
60
+ }),
61
+ effect: createEffect(({ currentKey, notification }: DeleteCurrentRecordingValues) => {
62
+ const recordingItem = this.collection.get(currentKey)
63
+
64
+ this.abortUploadIfInProgress(recordingItem)
65
+ this.resetRecordingState(currentKey)
66
+
67
+ if (notification) {
68
+ this.notification.info(t('voiceRecorder.recordingDeleted'))
69
+ }
70
+ }),
71
+ })
72
+
73
+ public readonly initializeRecording = createEffect(async () => {
74
+ this.deleteCurrentRecording({ notification: false })
75
+
76
+ const hasPermissions = await ensureRecordingPermissions()
77
+ if (!hasPermissions) {
78
+ this.notification.error(t('voiceRecorder.noMicrophoneAccess'))
79
+ return
80
+ }
81
+
82
+ const inputs = await getAvailableInputs(this.recorderModel.recorder)
83
+ this.recorderModel.setAvailableInputs(inputs)
84
+
85
+ if (inputs.length === 0) {
86
+ this.notification.error(t('voiceRecorder.noMicrophoneFound'))
87
+ return
88
+ }
89
+
90
+ return this.recorderModel.start()
91
+ })
92
+
93
+ constructor({ api, notification, events }: VoiceRecordModelParams) {
94
+ this.api = api
95
+ this.notification = notification
96
+ this.events = events
97
+ this.recorderModel = new RecorderModel()
98
+ this.collection = new VoiceRecordsCollection()
99
+
100
+ this.setupUploadHandler()
101
+ this.setupCurrentRecordSync()
102
+ }
103
+
104
+ private abortUploadIfInProgress(recordingItem: ReturnType<VoiceRecordsCollection['get']>) {
105
+ if (!recordingItem?.id && recordingItem?.controller) {
106
+ recordingItem.controller.abort()
107
+ }
108
+ }
109
+
110
+ private resetRecordingState(currentKey: string) {
111
+ this.recorderModel.reset()
112
+ this.reset()
113
+ this.collection.delete(currentKey)
114
+ }
115
+
116
+ private async handleAudioUpload({ uri, currentKey }: UploadParams) {
117
+ const durationMs = await getAudioDurationMs(uri)
118
+ const formData = await generateAudioFormData({ audioFileUri: uri, durationMs })
119
+ const { uploadAudio, controller } = uploadAudioFileRequestGenerator(formData, this.api)
120
+
121
+ const audioUploadPromise = uploadAudio()
122
+ .then((data) => {
123
+ // Check if the item still exists (wasn't deleted during upload)
124
+ if (this.collection.get(currentKey)) {
125
+ this.collection.update(currentKey, { id: data.id })
126
+ }
127
+ return data
128
+ })
129
+ .catch((error) => {
130
+ if (error.name === 'CanceledError') return
131
+ this.notification.error(t('voiceRecorder.uploadFailed'))
132
+ })
133
+
134
+ this.collection.add(currentKey, {
135
+ durationMs,
136
+ audioUploadPromise,
137
+ controller,
138
+ uri,
139
+ })
140
+
141
+ return audioUploadPromise
142
+ }
143
+
144
+ private setupUploadHandler() {
145
+ sample({
146
+ clock: this.setUri,
147
+ source: this.$currentKey,
148
+ filter: (currentKey, uri) => !!uri && !!currentKey,
149
+ fn: (currentKey, uri) => ({ currentKey, uri }),
150
+ target: createEffect(({ uri, currentKey }: UploadParams) =>
151
+ this.handleAudioUpload({ uri, currentKey }),
152
+ ),
153
+ })
154
+ }
155
+
156
+ private setupCurrentRecordSync() {
157
+ sample({
158
+ source: this.$currentKey,
159
+ fn: (currentKey) => this.collection.get(currentKey),
160
+ target: createEffect((recordingItem?: VoiceRecordStackItem) => {
161
+ if (!recordingItem) {
162
+ this.reset()
163
+ return
164
+ }
165
+
166
+ this.setCurrentRecord(recordingItem)
167
+
168
+ if (recordingItem.durationMs) {
169
+ this.recorderModel.setAudioFileDurationMs(recordingItem.durationMs)
170
+ }
171
+
172
+ if (recordingItem.uri) {
173
+ this.setUri(recordingItem.uri)
174
+ }
175
+ }),
176
+ })
177
+ }
178
+ }
@@ -0,0 +1,25 @@
1
+ import { createEffect } from 'effector'
2
+ import { AudioApi } from '../types'
3
+ import { createControllerEffect } from './../../../lib/effector/createControllerEffect'
4
+
5
+ export class VoiceRecordApi {
6
+ // public readonly uploadAudioFileFx
7
+
8
+ // public readonly abortUpload = createEffect(() => {
9
+ // if (this.uploadAudioFileFx.pending.getState()) {
10
+ // this.uploadAudioFileFx.controller.abort()
11
+ // }
12
+ // })
13
+
14
+ constructor(api: AudioApi) {
15
+ // this.uploadAudioFileFx = createControllerEffect((audioFileFormData: FormData, config) =>
16
+ // api.uploadAudioFile(
17
+ // { audioFileFormData },
18
+ // //@ts-ignore
19
+ // {
20
+ // signal: config?.signal,
21
+ // },
22
+ // ),
23
+ // )
24
+ }
25
+ }
@@ -0,0 +1,26 @@
1
+ import { VoiceRecordStackItem } from '../types'
2
+
3
+ export class VoiceRecordsCollection {
4
+ public readonly collection: Map<string, VoiceRecordStackItem> = new Map()
5
+
6
+ public add(key: string, item: VoiceRecordStackItem) {
7
+ this.collection.set(key, item)
8
+ }
9
+
10
+ public update(key: string, item: Partial<VoiceRecordStackItem>) {
11
+ const existingItem = this.collection.get(key) || {}
12
+ this.collection.set(key, { ...existingItem, ...item })
13
+ }
14
+
15
+ public delete(key: string) {
16
+ this.collection.delete(key)
17
+ }
18
+
19
+ public get(key: string) {
20
+ return this.collection.get(key)
21
+ }
22
+
23
+ public clear() {
24
+ this.collection.clear()
25
+ }
26
+ }
@@ -0,0 +1,49 @@
1
+ import { WithAbortSignal } from 'src/types/common.types'
2
+ import { getAvailableInputs } from './helpers'
3
+ import { VoiceRecordModel } from './model/VoiceRecord.model'
4
+
5
+ export type VoiceRecordNotificationTypes = {
6
+ info: (message: string) => void
7
+ error: (message: string) => void
8
+ warning: (message: string) => void
9
+ }
10
+
11
+ export type UploadAudioPayload = WithAbortSignal<{
12
+ audioFileFormData: FormData
13
+ }>
14
+
15
+ type AudioTranscriptResponse = {
16
+ text: string
17
+ }
18
+ type UploadAudioResponse = {
19
+ id: string
20
+ fileName: string
21
+ fileType: string
22
+ }
23
+
24
+ export type AudioApi = {
25
+ uploadAudioFile: (data: UploadAudioPayload) => Promise<UploadAudioResponse>
26
+ getAudioFileTranscript: (audioFileId: string) => Promise<AudioTranscriptResponse>
27
+ }
28
+ //'exiericeid-probleid-attemptnumber'
29
+ export type VoiceRecordStackItem = {
30
+ solutionId?: string
31
+ id?: string //it exists after upload to server
32
+ durationMs?: number
33
+ uri?: string
34
+ audioUploadPromise?: Promise<void | UploadAudioResponse>
35
+ controller?: AbortController
36
+ }
37
+
38
+ export type VoiceRecordStack = {
39
+ [problemId: string]: VoiceRecordStackItem
40
+ }
41
+
42
+ export type AvailableAudioInputs = Awaited<ReturnType<typeof getAvailableInputs>>
43
+
44
+ export type VoiceRecordDeleteModalParams = {
45
+ model: VoiceRecordModel
46
+ }
47
+ export type VoiceRecordUndoModalParams = {
48
+ model: VoiceRecordModel
49
+ }
package/src/index.ts CHANGED
@@ -10,3 +10,4 @@ export * from './features/gifCelebrations'
10
10
  export * from './features/exampleSolution'
11
11
  export * from './features/keyboard'
12
12
  export * from './shared/icons'
13
+ export * from './features/voiceRecord'
@@ -39,5 +39,18 @@
39
39
  "volume": "Volume",
40
40
  "weight": "Weight",
41
41
  "time": "Time"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Delete recording?",
45
+ "youWontBeAbleToRecover": "You won't be able to recover this file once it's gone.",
46
+ "recordingDeleted": "Recording successfully deleted",
47
+ "delete": "Delete",
48
+ "cancel": "Cancel",
49
+ "noMicrophoneAccess": "No microphone access",
50
+ "noMicrophoneFound": "No microphone found",
51
+ "uploadFailed": "Upload failed. Please try again.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -39,5 +39,18 @@
39
39
  "volume": "Volumen",
40
40
  "weight": "Gewicht",
41
41
  "time": "Zeit"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Aufnahme löschen?",
45
+ "youWontBeAbleToRecover": "Du kannst die Datei nicht wiederherstellen, wenn sie einmal gelöscht ist.",
46
+ "recordingDeleted": "Aufnahme gelöscht.",
47
+ "delete": "Löschen",
48
+ "cancel": "Abbrechen",
49
+ "noMicrophoneAccess": "Kein Mikrofon-Zugriff.",
50
+ "noMicrophoneFound": "Kein Mikrofon gefunden.",
51
+ "uploadFailed": "Hochladen fehlgeschlagen. Bitte versuche es erneut.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -39,5 +39,18 @@
39
39
  "volume": "Volume",
40
40
  "weight": "Weight",
41
41
  "time": "Time"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Delete recording?",
45
+ "youWontBeAbleToRecover": "You won't be able to recover this file once it's gone.",
46
+ "recordingDeleted": "Recording successfully deleted",
47
+ "delete": "Delete",
48
+ "cancel": "Cancel",
49
+ "noMicrophoneAccess": "No microphone access",
50
+ "noMicrophoneFound": "No microphone found",
51
+ "uploadFailed": "Upload failed. Please try again.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -39,5 +39,18 @@
39
39
  "volume": "Volume",
40
40
  "weight": "Weight",
41
41
  "time": "Time"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Delete recording?",
45
+ "youWontBeAbleToRecover": "You won't be able to recover this file once it's gone.",
46
+ "recordingDeleted": "Recording successfully deleted",
47
+ "delete": "Delete",
48
+ "cancel": "Cancel",
49
+ "noMicrophoneAccess": "No microphone access",
50
+ "noMicrophoneFound": "No microphone found",
51
+ "uploadFailed": "Upload failed. Please try again.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -39,5 +39,18 @@
39
39
  "volume": "Volume",
40
40
  "weight": "Weight",
41
41
  "time": "Time"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Delete recording?",
45
+ "youWontBeAbleToRecover": "You won't be able to recover this file once it's gone.",
46
+ "recordingDeleted": "Recording successfully deleted",
47
+ "delete": "Delete",
48
+ "cancel": "Cancel",
49
+ "noMicrophoneAccess": "No microphone access",
50
+ "noMicrophoneFound": "No microphone found",
51
+ "uploadFailed": "Upload failed. Please try again.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -39,5 +39,18 @@
39
39
  "volume": "Volym",
40
40
  "weight": "Vikt",
41
41
  "time": "Tid"
42
+ },
43
+ "voiceRecorder": {
44
+ "deleteRecording": "Radera inspelningen?",
45
+ "youWontBeAbleToRecover": "Du kommer inte att kunna återställa filen när den väl är borta.",
46
+ "recordingDeleted": "Recording deleted",
47
+ "delete": "Radera",
48
+ "cancel": "Avbryt",
49
+ "noMicrophoneAccess": "Ingen mikrofonåtkomst",
50
+ "noMicrophoneFound": "Ingen mikrofon hittades",
51
+ "uploadFailed": "Uppladdning misslyckades. Försök igen.",
52
+ "redoRecording": "Redo recording?",
53
+ "redo": "Redo",
54
+ "thisWillRemoveRecording": "This will remove your previous recording."
42
55
  }
43
56
  }
@@ -2,3 +2,4 @@ export type Size = {
2
2
  width: number
3
3
  height: number
4
4
  }
5
+ export type WithAbortSignal<T> = T & { signal?: AbortSignal }
package/.editorconfig DELETED
@@ -1,15 +0,0 @@
1
- # EditorConfig helps developers define and maintain consistent
2
- # coding styles between different editors and IDEs
3
- # editorconfig.org
4
-
5
- root = true
6
-
7
- [*]
8
-
9
- indent_style = space
10
- indent_size = 2
11
-
12
- end_of_line = lf
13
- charset = utf-8
14
- trim_trailing_whitespace = true
15
- insert_final_newline = true
package/.eslintignore DELETED
@@ -1,2 +0,0 @@
1
- node_modules/
2
- ./lib/
package/.eslintrc DELETED
@@ -1,22 +0,0 @@
1
- {
2
- "env": {
3
- "browser": true,
4
- "es2020": true
5
- },
6
- "extends": [
7
- "eslint:recommended",
8
- "plugin:@typescript-eslint/recommended",
9
- "plugin:react-hooks/recommended",
10
- "plugin:storybook/recommended",
11
- "prettier"
12
- ],
13
- "parser": "@typescript-eslint/parser",
14
- "parserOptions": {
15
- "ecmaVersion": "latest",
16
- "sourceType": "module"
17
- },
18
- "plugins": ["react-refresh"],
19
- "rules": {
20
- "react-refresh/only-export-components": "warn"
21
- }
22
- }
package/.gitattributes DELETED
@@ -1,3 +0,0 @@
1
- *.pbxproj -text
2
- # specific for windows script files
3
- *.bat text eol=crlf
@@ -1,37 +0,0 @@
1
- name: Setup
2
- description: Setup Node.js and install dependencies
3
-
4
- inputs:
5
- npmrc-auth-token:
6
- required: true
7
-
8
- runs:
9
- using: composite
10
- steps:
11
- - name: Setup Node.js
12
- uses: actions/setup-node@v3
13
- with:
14
- node-version-file: .nvmrc
15
-
16
- - name: Create .npmrc
17
- shell: bash
18
- run: |
19
- echo "registry=https://registry.npmjs.org" > .npmrc
20
- echo "//registry.npmjs.org/:_authToken=${{ inputs.npmrc-auth-token }}" >> .npmrc
21
-
22
- - name: Cache dependencies
23
- id: yarn-cache
24
- uses: actions/cache@v3
25
- with:
26
- path: |
27
- **/node_modules
28
- .yarn/install-state.gz
29
- key: ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}-${{ hashFiles('**/package.json', '!node_modules/**') }}
30
- restore-keys: |
31
- ${{ runner.os }}-yarn-${{ hashFiles('yarn.lock') }}
32
- ${{ runner.os }}-yarn-
33
-
34
- - name: Install dependencies
35
- if: steps.yarn-cache.outputs.cache-hit != 'true'
36
- run: yarn install --immutable
37
- shell: bash
@@ -1,73 +0,0 @@
1
- name: CI
2
-
3
- on:
4
- push:
5
- branches:
6
- - main
7
- pull_request:
8
- branches:
9
- - main
10
- merge_group:
11
- types:
12
- - checks_requested
13
-
14
- jobs:
15
- lint:
16
- runs-on: ubuntu-latest
17
- steps:
18
- - name: Checkout
19
- uses: actions/checkout@v3
20
-
21
- - name: Setup
22
- uses: ./.github/actions/setup
23
- with:
24
- npmrc-auth-token: ${{ secrets.MAGMA_NPMRC_TOKEN }}
25
-
26
- - name: Lint files
27
- run: yarn lint
28
-
29
- - name: Typecheck files
30
- run: yarn typecheck
31
-
32
- test:
33
- runs-on: ubuntu-latest
34
- steps:
35
- - name: Checkout
36
- uses: actions/checkout@v3
37
-
38
- - name: Setup
39
- uses: ./.github/actions/setup
40
- with:
41
- npmrc-auth-token: ${{ secrets.MAGMA_NPMRC_TOKEN }}
42
-
43
- - name: Run unit tests
44
- run: yarn test --maxWorkers=2 --coverage
45
-
46
- build-library:
47
- runs-on: ubuntu-latest
48
- steps:
49
- - name: Checkout
50
- uses: actions/checkout@v3
51
-
52
- - name: Setup
53
- uses: ./.github/actions/setup
54
- with:
55
- npmrc-auth-token: ${{ secrets.MAGMA_NPMRC_TOKEN }}
56
-
57
- - name: Build package
58
- run: yarn prepare
59
-
60
- build-web:
61
- runs-on: ubuntu-latest
62
- steps:
63
- - name: Checkout
64
- uses: actions/checkout@v3
65
-
66
- - name: Setup
67
- uses: ./.github/actions/setup
68
- with:
69
- npmrc-auth-token: ${{ secrets.MAGMA_NPMRC_TOKEN }}
70
-
71
- - name: Build example for Web
72
- run: |
73
- yarn example expo export --platform web
package/.gitignore DELETED
@@ -1,84 +0,0 @@
1
- # OSX
2
- #
3
- .DS_Store
4
-
5
- # XDE
6
- .expo/
7
-
8
- # VSCode
9
- .vscode/
10
- jsconfig.json
11
-
12
- # Xcode
13
- #
14
- build/
15
- *.pbxuser
16
- !default.pbxuser
17
- *.mode1v3
18
- !default.mode1v3
19
- *.mode2v3
20
- !default.mode2v3
21
- *.perspectivev3
22
- !default.perspectivev3
23
- xcuserdata
24
- *.xccheckout
25
- *.moved-aside
26
- DerivedData
27
- *.hmap
28
- *.ipa
29
- *.xcuserstate
30
- project.xcworkspace
31
-
32
- # Android/IJ
33
- #
34
- .classpath
35
- .cxx
36
- .gradle
37
- .idea
38
- .project
39
- .settings
40
- local.properties
41
- android.iml
42
-
43
- # Cocoapods
44
- #
45
- example/ios/Pods
46
-
47
- # Ruby
48
- example/vendor/
49
-
50
- # node.js
51
- #
52
- node_modules/
53
- npm-debug.log
54
- yarn-debug.log
55
- yarn-error.log
56
-
57
- # BUCK
58
- buck-out/
59
- \.buckd/
60
- android/app/libs
61
- android/keystores/debug.keystore
62
-
63
- # Yarn
64
- .yarn/*
65
- !.yarn/patches
66
- !.yarn/plugins
67
- !.yarn/releases
68
- !.yarn/sdks
69
- !.yarn/versions
70
-
71
- # Expo
72
- .expo/
73
-
74
- # Turborepo
75
- .turbo/
76
-
77
- # generated by bob
78
- dist/
79
- !src/lib/
80
-
81
- # React Native Codegen
82
- ios/generated
83
- android/generated
84
- .npmrc
package/.idea/.gitignore DELETED
@@ -1,8 +0,0 @@
1
- # Default ignored files
2
- /shelf/
3
- /workspace.xml
4
- # Editor-based HTTP Client requests
5
- /httpRequests/
6
- # Datasource local storage ignored files
7
- /dataSources/
8
- /dataSources.local.xml