stream-chat-react-native-core 5.28.1 → 5.29.0-beta.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.
Files changed (381) hide show
  1. package/lib/commonjs/components/Attachment/Attachment.js +2 -2
  2. package/lib/commonjs/components/Attachment/Attachment.js.map +1 -1
  3. package/lib/commonjs/components/Attachment/AudioAttachment.js +247 -115
  4. package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
  5. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js +30 -50
  6. package/lib/commonjs/components/Attachment/FileAttachmentGroup.js.map +1 -1
  7. package/lib/commonjs/components/Attachment/VideoThumbnail.js +3 -3
  8. package/lib/commonjs/components/Attachment/VideoThumbnail.js.map +1 -1
  9. package/lib/commonjs/components/Channel/Channel.js +43 -1
  10. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  11. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +24 -0
  12. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  13. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +6 -6
  14. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  15. package/lib/commonjs/components/Message/Message.js +1 -1
  16. package/lib/commonjs/components/Message/Message.js.map +1 -1
  17. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +1 -1
  18. package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
  19. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js +1 -1
  20. package/lib/commonjs/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  21. package/lib/commonjs/components/Message/hooks/useMessageActions.js +4 -2
  22. package/lib/commonjs/components/Message/hooks/useMessageActions.js.map +1 -1
  23. package/lib/commonjs/components/MessageInput/FileUploadPreview.js +55 -74
  24. package/lib/commonjs/components/MessageInput/FileUploadPreview.js.map +1 -1
  25. package/lib/commonjs/components/MessageInput/InputButtons.js +1 -1
  26. package/lib/commonjs/components/MessageInput/InputButtons.js.map +1 -1
  27. package/lib/commonjs/components/MessageInput/MessageInput.js +250 -43
  28. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  29. package/lib/commonjs/components/MessageInput/SendButton.js +9 -7
  30. package/lib/commonjs/components/MessageInput/SendButton.js.map +1 -1
  31. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js +221 -0
  32. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -0
  33. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +121 -0
  34. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -0
  35. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.js +68 -0
  36. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.js.map +1 -0
  37. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js +75 -0
  38. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js.map +1 -0
  39. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js +87 -0
  40. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js.map +1 -0
  41. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.js +47 -0
  42. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.js.map +1 -0
  43. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js +452 -0
  44. package/lib/commonjs/components/MessageInput/hooks/useAudioController.js.map +1 -0
  45. package/lib/commonjs/components/MessageInput/utils/audioSampling.js +91 -0
  46. package/lib/commonjs/components/MessageInput/utils/audioSampling.js.map +1 -0
  47. package/lib/commonjs/components/MessageInput/utils/normalizeAudioLevel.js +18 -0
  48. package/lib/commonjs/components/MessageInput/utils/normalizeAudioLevel.js.map +1 -0
  49. package/lib/commonjs/components/ProgressControl/ProgressControl.js +57 -40
  50. package/lib/commonjs/components/ProgressControl/ProgressControl.js.map +1 -1
  51. package/lib/commonjs/components/ProgressControl/WaveProgressBar.js +162 -0
  52. package/lib/commonjs/components/ProgressControl/WaveProgressBar.js.map +1 -0
  53. package/lib/commonjs/components/Reply/Reply.js +45 -20
  54. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  55. package/lib/commonjs/components/index.js +66 -0
  56. package/lib/commonjs/components/index.js.map +1 -1
  57. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +23 -12
  58. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  59. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +24 -0
  60. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  61. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js +76 -28
  62. package/lib/commonjs/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  63. package/lib/commonjs/contexts/themeContext/utils/theme.js +62 -7
  64. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  65. package/lib/commonjs/i18n/en.json +3 -1
  66. package/lib/commonjs/i18n/es.json +64 -62
  67. package/lib/commonjs/i18n/fr.json +64 -62
  68. package/lib/commonjs/i18n/he.json +64 -62
  69. package/lib/commonjs/i18n/hi.json +64 -62
  70. package/lib/commonjs/i18n/it.json +64 -62
  71. package/lib/commonjs/i18n/ja.json +64 -62
  72. package/lib/commonjs/i18n/ko.json +64 -62
  73. package/lib/commonjs/i18n/nl.json +64 -62
  74. package/lib/commonjs/i18n/pt-BR.json +64 -62
  75. package/lib/commonjs/i18n/ru.json +64 -62
  76. package/lib/commonjs/i18n/tr.json +64 -62
  77. package/lib/commonjs/icons/ArrowLeft.js +27 -0
  78. package/lib/commonjs/icons/ArrowLeft.js.map +1 -0
  79. package/lib/commonjs/icons/ArrowUp.js +26 -0
  80. package/lib/commonjs/icons/ArrowUp.js.map +1 -0
  81. package/lib/commonjs/icons/Audio.js +24 -24
  82. package/lib/commonjs/icons/Audio.js.map +1 -1
  83. package/lib/commonjs/icons/CircleStop.js +27 -0
  84. package/lib/commonjs/icons/CircleStop.js.map +1 -0
  85. package/lib/commonjs/icons/Delete.js +17 -6
  86. package/lib/commonjs/icons/Delete.js.map +1 -1
  87. package/lib/commonjs/icons/Lock.js +30 -0
  88. package/lib/commonjs/icons/Lock.js.map +1 -0
  89. package/lib/commonjs/icons/Mic.js +30 -0
  90. package/lib/commonjs/icons/Mic.js.map +1 -0
  91. package/lib/commonjs/icons/Pause.js +15 -20
  92. package/lib/commonjs/icons/Pause.js.map +1 -1
  93. package/lib/commonjs/icons/Play.js +18 -10
  94. package/lib/commonjs/icons/Play.js.map +1 -1
  95. package/lib/commonjs/icons/SendCheck.js +30 -0
  96. package/lib/commonjs/icons/SendCheck.js.map +1 -0
  97. package/lib/commonjs/icons/SendRight.js +24 -6
  98. package/lib/commonjs/icons/SendRight.js.map +1 -1
  99. package/lib/commonjs/icons/SendUp.js +24 -6
  100. package/lib/commonjs/icons/SendUp.js.map +1 -1
  101. package/lib/commonjs/icons/Stop.js +19 -0
  102. package/lib/commonjs/icons/Stop.js.map +1 -0
  103. package/lib/commonjs/icons/index.js +77 -0
  104. package/lib/commonjs/icons/index.js.map +1 -1
  105. package/lib/commonjs/native.js +10 -1
  106. package/lib/commonjs/native.js.map +1 -1
  107. package/lib/commonjs/utils/getTrimmedAttachmentTitle.js +11 -0
  108. package/lib/commonjs/utils/getTrimmedAttachmentTitle.js.map +1 -0
  109. package/lib/commonjs/version.json +1 -1
  110. package/lib/module/components/Attachment/Attachment.js +2 -2
  111. package/lib/module/components/Attachment/Attachment.js.map +1 -1
  112. package/lib/module/components/Attachment/AudioAttachment.js +247 -115
  113. package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
  114. package/lib/module/components/Attachment/FileAttachmentGroup.js +30 -50
  115. package/lib/module/components/Attachment/FileAttachmentGroup.js.map +1 -1
  116. package/lib/module/components/Attachment/VideoThumbnail.js +3 -3
  117. package/lib/module/components/Attachment/VideoThumbnail.js.map +1 -1
  118. package/lib/module/components/Channel/Channel.js +43 -1
  119. package/lib/module/components/Channel/Channel.js.map +1 -1
  120. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +24 -0
  121. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  122. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +6 -6
  123. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  124. package/lib/module/components/Message/Message.js +1 -1
  125. package/lib/module/components/Message/Message.js.map +1 -1
  126. package/lib/module/components/Message/MessageSimple/MessageContent.js +1 -1
  127. package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
  128. package/lib/module/components/Message/MessageSimple/MessageSimple.js +1 -1
  129. package/lib/module/components/Message/MessageSimple/MessageSimple.js.map +1 -1
  130. package/lib/module/components/Message/hooks/useMessageActions.js +4 -2
  131. package/lib/module/components/Message/hooks/useMessageActions.js.map +1 -1
  132. package/lib/module/components/MessageInput/FileUploadPreview.js +55 -74
  133. package/lib/module/components/MessageInput/FileUploadPreview.js.map +1 -1
  134. package/lib/module/components/MessageInput/InputButtons.js +1 -1
  135. package/lib/module/components/MessageInput/InputButtons.js.map +1 -1
  136. package/lib/module/components/MessageInput/MessageInput.js +250 -43
  137. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  138. package/lib/module/components/MessageInput/SendButton.js +9 -7
  139. package/lib/module/components/MessageInput/SendButton.js.map +1 -1
  140. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js +221 -0
  141. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -0
  142. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +121 -0
  143. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -0
  144. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.js +68 -0
  145. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.js.map +1 -0
  146. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js +75 -0
  147. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.js.map +1 -0
  148. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js +87 -0
  149. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.js.map +1 -0
  150. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.js +47 -0
  151. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.js.map +1 -0
  152. package/lib/module/components/MessageInput/hooks/useAudioController.js +452 -0
  153. package/lib/module/components/MessageInput/hooks/useAudioController.js.map +1 -0
  154. package/lib/module/components/MessageInput/utils/audioSampling.js +91 -0
  155. package/lib/module/components/MessageInput/utils/audioSampling.js.map +1 -0
  156. package/lib/module/components/MessageInput/utils/normalizeAudioLevel.js +18 -0
  157. package/lib/module/components/MessageInput/utils/normalizeAudioLevel.js.map +1 -0
  158. package/lib/module/components/ProgressControl/ProgressControl.js +57 -40
  159. package/lib/module/components/ProgressControl/ProgressControl.js.map +1 -1
  160. package/lib/module/components/ProgressControl/WaveProgressBar.js +162 -0
  161. package/lib/module/components/ProgressControl/WaveProgressBar.js.map +1 -0
  162. package/lib/module/components/Reply/Reply.js +45 -20
  163. package/lib/module/components/Reply/Reply.js.map +1 -1
  164. package/lib/module/components/index.js +66 -0
  165. package/lib/module/components/index.js.map +1 -1
  166. package/lib/module/contexts/messageInputContext/MessageInputContext.js +23 -12
  167. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  168. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +24 -0
  169. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  170. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js +76 -28
  171. package/lib/module/contexts/messageInputContext/hooks/useMessageDetailsForState.js.map +1 -1
  172. package/lib/module/contexts/themeContext/utils/theme.js +62 -7
  173. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  174. package/lib/module/i18n/en.json +3 -1
  175. package/lib/module/i18n/es.json +64 -62
  176. package/lib/module/i18n/fr.json +64 -62
  177. package/lib/module/i18n/he.json +64 -62
  178. package/lib/module/i18n/hi.json +64 -62
  179. package/lib/module/i18n/it.json +64 -62
  180. package/lib/module/i18n/ja.json +64 -62
  181. package/lib/module/i18n/ko.json +64 -62
  182. package/lib/module/i18n/nl.json +64 -62
  183. package/lib/module/i18n/pt-BR.json +64 -62
  184. package/lib/module/i18n/ru.json +64 -62
  185. package/lib/module/i18n/tr.json +64 -62
  186. package/lib/module/icons/ArrowLeft.js +27 -0
  187. package/lib/module/icons/ArrowLeft.js.map +1 -0
  188. package/lib/module/icons/ArrowUp.js +26 -0
  189. package/lib/module/icons/ArrowUp.js.map +1 -0
  190. package/lib/module/icons/Audio.js +24 -24
  191. package/lib/module/icons/Audio.js.map +1 -1
  192. package/lib/module/icons/CircleStop.js +27 -0
  193. package/lib/module/icons/CircleStop.js.map +1 -0
  194. package/lib/module/icons/Delete.js +17 -6
  195. package/lib/module/icons/Delete.js.map +1 -1
  196. package/lib/module/icons/Lock.js +30 -0
  197. package/lib/module/icons/Lock.js.map +1 -0
  198. package/lib/module/icons/Mic.js +30 -0
  199. package/lib/module/icons/Mic.js.map +1 -0
  200. package/lib/module/icons/Pause.js +15 -20
  201. package/lib/module/icons/Pause.js.map +1 -1
  202. package/lib/module/icons/Play.js +18 -10
  203. package/lib/module/icons/Play.js.map +1 -1
  204. package/lib/module/icons/SendCheck.js +30 -0
  205. package/lib/module/icons/SendCheck.js.map +1 -0
  206. package/lib/module/icons/SendRight.js +24 -6
  207. package/lib/module/icons/SendRight.js.map +1 -1
  208. package/lib/module/icons/SendUp.js +24 -6
  209. package/lib/module/icons/SendUp.js.map +1 -1
  210. package/lib/module/icons/Stop.js +19 -0
  211. package/lib/module/icons/Stop.js.map +1 -0
  212. package/lib/module/icons/index.js +77 -0
  213. package/lib/module/icons/index.js.map +1 -1
  214. package/lib/module/native.js +10 -1
  215. package/lib/module/native.js.map +1 -1
  216. package/lib/module/utils/getTrimmedAttachmentTitle.js +11 -0
  217. package/lib/module/utils/getTrimmedAttachmentTitle.js.map +1 -0
  218. package/lib/module/version.json +1 -1
  219. package/lib/typescript/components/Attachment/Attachment.d.ts.map +1 -1
  220. package/lib/typescript/components/Attachment/AudioAttachment.d.ts +3 -8
  221. package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
  222. package/lib/typescript/components/Attachment/FileAttachmentGroup.d.ts.map +1 -1
  223. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  224. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +15 -3
  225. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts.map +1 -1
  226. package/lib/typescript/components/ImageGallery/components/ImageGalleryVideoControl.d.ts.map +1 -1
  227. package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts.map +1 -1
  228. package/lib/typescript/components/Message/MessageSimple/MessageSimple.d.ts.map +1 -1
  229. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts +1 -1
  230. package/lib/typescript/components/MessageInput/FileUploadPreview.d.ts.map +1 -1
  231. package/lib/typescript/components/MessageInput/InputButtons.d.ts.map +1 -1
  232. package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
  233. package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
  234. package/lib/typescript/components/MessageInput/SendButton.d.ts.map +1 -1
  235. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecorder.d.ts +51 -0
  236. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecorder.d.ts.map +1 -0
  237. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingButton.d.ts +43 -0
  238. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingButton.d.ts.map +1 -0
  239. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.d.ts +29 -0
  240. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.d.ts.map +1 -0
  241. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.d.ts +22 -0
  242. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.d.ts.map +1 -0
  243. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.d.ts +31 -0
  244. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.d.ts.map +1 -0
  245. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.d.ts +19 -0
  246. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.d.ts.map +1 -0
  247. package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts +28 -0
  248. package/lib/typescript/components/MessageInput/hooks/useAudioController.d.ts.map +1 -0
  249. package/lib/typescript/components/MessageInput/utils/audioSampling.d.ts +11 -0
  250. package/lib/typescript/components/MessageInput/utils/audioSampling.d.ts.map +1 -0
  251. package/lib/typescript/components/MessageInput/utils/normalizeAudioLevel.d.ts +5 -0
  252. package/lib/typescript/components/MessageInput/utils/normalizeAudioLevel.d.ts.map +1 -0
  253. package/lib/typescript/components/ProgressControl/ProgressControl.d.ts +2 -2
  254. package/lib/typescript/components/ProgressControl/ProgressControl.d.ts.map +1 -1
  255. package/lib/typescript/components/ProgressControl/WaveProgressBar.d.ts +11 -0
  256. package/lib/typescript/components/ProgressControl/WaveProgressBar.d.ts.map +1 -0
  257. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  258. package/lib/typescript/components/index.d.ts +6 -0
  259. package/lib/typescript/components/index.d.ts.map +1 -1
  260. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +70 -4
  261. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  262. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  263. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
  264. package/lib/typescript/contexts/messageInputContext/hooks/useMessageDetailsForState.d.ts.map +1 -1
  265. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +62 -7
  266. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  267. package/lib/typescript/i18n/en.json +3 -1
  268. package/lib/typescript/i18n/es.json +64 -62
  269. package/lib/typescript/i18n/fr.json +64 -62
  270. package/lib/typescript/i18n/he.json +64 -62
  271. package/lib/typescript/i18n/hi.json +64 -62
  272. package/lib/typescript/i18n/it.json +64 -62
  273. package/lib/typescript/i18n/ja.json +64 -62
  274. package/lib/typescript/i18n/ko.json +64 -62
  275. package/lib/typescript/i18n/nl.json +64 -62
  276. package/lib/typescript/i18n/pt-BR.json +64 -62
  277. package/lib/typescript/i18n/ru.json +64 -62
  278. package/lib/typescript/i18n/tr.json +64 -62
  279. package/lib/typescript/icons/ArrowLeft.d.ts +8 -0
  280. package/lib/typescript/icons/ArrowLeft.d.ts.map +1 -0
  281. package/lib/typescript/icons/ArrowUp.d.ts +9 -0
  282. package/lib/typescript/icons/ArrowUp.d.ts.map +1 -0
  283. package/lib/typescript/icons/Audio.d.ts.map +1 -1
  284. package/lib/typescript/icons/CircleStop.d.ts +8 -0
  285. package/lib/typescript/icons/CircleStop.d.ts.map +1 -0
  286. package/lib/typescript/icons/Delete.d.ts +5 -1
  287. package/lib/typescript/icons/Delete.d.ts.map +1 -1
  288. package/lib/typescript/icons/Lock.d.ts +9 -0
  289. package/lib/typescript/icons/Lock.d.ts.map +1 -0
  290. package/lib/typescript/icons/Mic.d.ts +8 -0
  291. package/lib/typescript/icons/Mic.d.ts.map +1 -0
  292. package/lib/typescript/icons/Pause.d.ts +3 -1
  293. package/lib/typescript/icons/Pause.d.ts.map +1 -1
  294. package/lib/typescript/icons/Play.d.ts +3 -1
  295. package/lib/typescript/icons/Play.d.ts.map +1 -1
  296. package/lib/typescript/icons/SendCheck.d.ts +8 -0
  297. package/lib/typescript/icons/SendCheck.d.ts.map +1 -0
  298. package/lib/typescript/icons/SendRight.d.ts +5 -1
  299. package/lib/typescript/icons/SendRight.d.ts.map +1 -1
  300. package/lib/typescript/icons/SendUp.d.ts +5 -1
  301. package/lib/typescript/icons/SendUp.d.ts.map +1 -1
  302. package/lib/typescript/icons/Stop.d.ts +4 -0
  303. package/lib/typescript/icons/Stop.d.ts.map +1 -0
  304. package/lib/typescript/icons/index.d.ts +7 -0
  305. package/lib/typescript/icons/index.d.ts.map +1 -1
  306. package/lib/typescript/native.d.ts +49 -0
  307. package/lib/typescript/native.d.ts.map +1 -1
  308. package/lib/typescript/types/types.d.ts +6 -0
  309. package/lib/typescript/types/types.d.ts.map +1 -1
  310. package/lib/typescript/utils/Streami18n.d.ts +2 -0
  311. package/lib/typescript/utils/Streami18n.d.ts.map +1 -1
  312. package/lib/typescript/utils/getTrimmedAttachmentTitle.d.ts +2 -0
  313. package/lib/typescript/utils/getTrimmedAttachmentTitle.d.ts.map +1 -0
  314. package/package.json +1 -1
  315. package/src/components/Attachment/Attachment.tsx +7 -2
  316. package/src/components/Attachment/AudioAttachment.tsx +223 -119
  317. package/src/components/Attachment/FileAttachmentGroup.tsx +35 -55
  318. package/src/components/Attachment/VideoThumbnail.tsx +1 -1
  319. package/src/components/Channel/Channel.tsx +32 -0
  320. package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +24 -0
  321. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +1 -1
  322. package/src/components/ImageGallery/__tests__/ImageGalleryVideoControl.test.tsx +2 -2
  323. package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +2 -7
  324. package/src/components/Message/Message.tsx +1 -1
  325. package/src/components/Message/MessageSimple/MessageContent.tsx +2 -1
  326. package/src/components/Message/MessageSimple/MessageSimple.tsx +2 -1
  327. package/src/components/Message/hooks/useMessageActions.tsx +2 -2
  328. package/src/components/MessageInput/FileUploadPreview.tsx +67 -98
  329. package/src/components/MessageInput/InputButtons.tsx +2 -1
  330. package/src/components/MessageInput/MessageInput.tsx +320 -49
  331. package/src/components/MessageInput/SendButton.tsx +7 -3
  332. package/src/components/MessageInput/__tests__/MessageInput.test.js +0 -1
  333. package/src/components/MessageInput/__tests__/__snapshots__/SendButton.test.js.snap +132 -48
  334. package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx +313 -0
  335. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +192 -0
  336. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingInProgress.tsx +114 -0
  337. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingLockIndicator.tsx +85 -0
  338. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingPreview.tsx +102 -0
  339. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingWaveform.tsx +62 -0
  340. package/src/components/MessageInput/hooks/useAudioController.tsx +288 -0
  341. package/src/components/MessageInput/utils/audioSampling.ts +108 -0
  342. package/src/components/MessageInput/utils/normalizeAudioLevel.ts +20 -0
  343. package/src/components/ProgressControl/ProgressControl.tsx +69 -40
  344. package/src/components/ProgressControl/WaveProgressBar.tsx +180 -0
  345. package/src/components/Reply/Reply.tsx +89 -56
  346. package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +38 -20
  347. package/src/components/index.ts +6 -0
  348. package/src/contexts/messageInputContext/MessageInputContext.tsx +95 -10
  349. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +25 -0
  350. package/src/contexts/messageInputContext/hooks/useMessageDetailsForState.ts +80 -27
  351. package/src/contexts/themeContext/utils/theme.ts +111 -14
  352. package/src/i18n/en.json +3 -1
  353. package/src/i18n/es.json +64 -62
  354. package/src/i18n/fr.json +64 -62
  355. package/src/i18n/he.json +64 -62
  356. package/src/i18n/hi.json +64 -62
  357. package/src/i18n/it.json +64 -62
  358. package/src/i18n/ja.json +64 -62
  359. package/src/i18n/ko.json +64 -62
  360. package/src/i18n/nl.json +64 -62
  361. package/src/i18n/pt-BR.json +64 -62
  362. package/src/i18n/ru.json +64 -62
  363. package/src/i18n/tr.json +64 -62
  364. package/src/icons/ArrowLeft.tsx +18 -0
  365. package/src/icons/ArrowUp.tsx +19 -0
  366. package/src/icons/Audio.tsx +24 -24
  367. package/src/icons/CircleStop.tsx +18 -0
  368. package/src/icons/Delete.tsx +14 -8
  369. package/src/icons/Lock.tsx +22 -0
  370. package/src/icons/Mic.tsx +20 -0
  371. package/src/icons/Pause.tsx +12 -11
  372. package/src/icons/Play.tsx +9 -13
  373. package/src/icons/SendCheck.tsx +18 -0
  374. package/src/icons/SendRight.tsx +16 -7
  375. package/src/icons/SendUp.tsx +16 -7
  376. package/src/icons/Stop.tsx +12 -0
  377. package/src/icons/index.ts +7 -0
  378. package/src/native.ts +69 -0
  379. package/src/types/types.ts +6 -0
  380. package/src/utils/getTrimmedAttachmentTitle.ts +5 -0
  381. package/src/version.json +1 -1
@@ -0,0 +1,288 @@
1
+ import { useEffect, useRef, useState } from 'react';
2
+
3
+ import { Alert, Platform } from 'react-native';
4
+
5
+ import { useMessageInputContext } from '../../../contexts/messageInputContext/MessageInputContext';
6
+ import {
7
+ Audio,
8
+ AudioRecordingReturnType,
9
+ PlaybackStatus,
10
+ RecordingStatus,
11
+ Sound,
12
+ SoundReturnType,
13
+ triggerHaptic,
14
+ } from '../../../native';
15
+ import { File } from '../../../types/types';
16
+ import { resampleWaveformData } from '../utils/audioSampling';
17
+ import { normalizeAudioLevel } from '../utils/normalizeAudioLevel';
18
+
19
+ export type RecordingStatusStates = 'idle' | 'recording' | 'stopped';
20
+
21
+ /**
22
+ * The hook that controls all the async audio core features including start/stop or recording, player, upload/delete of the recorded audio.
23
+ */
24
+ export const useAudioController = () => {
25
+ const [micLocked, setMicLocked] = useState(false);
26
+ const [permissionsGranted, setPermissionsGranted] = useState(true);
27
+ const [paused, setPaused] = useState<boolean>(true);
28
+ const [position, setPosition] = useState<number>(0);
29
+ const [progress, setProgress] = useState<number>(0);
30
+ const [waveformData, setWaveformData] = useState<number[]>([]);
31
+ const [isScheduledForSubmit, setIsScheduleForSubmit] = useState(false);
32
+ const [recording, setRecording] = useState<AudioRecordingReturnType>(undefined);
33
+ const [recordingDuration, setRecordingDuration] = useState<number>(0);
34
+ const [recordingStatus, setRecordingStatus] = useState<RecordingStatusStates>('idle');
35
+
36
+ const { sendMessage, uploadNewFile } = useMessageInputContext();
37
+
38
+ // For playback support in Expo CLI apps
39
+ const soundRef = useRef<SoundReturnType | null>(null);
40
+
41
+ // Effect to stop the player when the component unmounts
42
+ useEffect(
43
+ () => () => {
44
+ stopVoicePlayer();
45
+ },
46
+ [],
47
+ );
48
+
49
+ useEffect(() => {
50
+ if (isScheduledForSubmit) {
51
+ sendMessage();
52
+ setIsScheduleForSubmit(false);
53
+ }
54
+ }, [isScheduledForSubmit, sendMessage]);
55
+
56
+ const onVoicePlayerProgressHandler = (currentPosition: number, playbackDuration: number) => {
57
+ const currentProgress = currentPosition / playbackDuration;
58
+ if (currentProgress === 1) {
59
+ setPaused(true);
60
+ setProgress(0);
61
+ } else {
62
+ setProgress(currentProgress);
63
+ }
64
+ };
65
+
66
+ const onVoicePlayerPlaybackStatusUpdate = (status: PlaybackStatus) => {
67
+ if (status.shouldPlay === undefined || status.shouldPlay === true) {
68
+ setPosition(status?.currentPosition || status?.positionMillis);
69
+ setRecordingDuration(status.duration || status.durationMillis);
70
+
71
+ if (status.didJustFinish) {
72
+ onVoicePlayerProgressHandler(status.durationMillis, status.durationMillis);
73
+ } else {
74
+ // For Native CLI
75
+ if (status.currentPosition && status.duration)
76
+ onVoicePlayerProgressHandler(status.currentPosition, status.duration);
77
+ // For Expo CLI
78
+ else if (status.positionMillis && status.durationMillis)
79
+ onVoicePlayerProgressHandler(status.positionMillis, status.durationMillis);
80
+ }
81
+ }
82
+ };
83
+
84
+ const onVoicePlayerPlayPause = async () => {
85
+ if (paused) {
86
+ if (progress === 0) await startVoicePlayer();
87
+ else {
88
+ // For Native CLI
89
+ if (Audio.resumePlayer) await Audio.resumePlayer();
90
+ // For Expo CLI
91
+ if (soundRef.current?.playAsync) await soundRef.current.playAsync();
92
+ }
93
+ } else {
94
+ // For Native CLI
95
+ if (Audio.pausePlayer) await Audio.pausePlayer();
96
+ // For Expo CLI
97
+ if (soundRef.current?.pauseAsync) await soundRef.current.pauseAsync();
98
+ }
99
+ setPaused(!paused);
100
+ };
101
+
102
+ /**
103
+ * Function to start playing voice recording to preview it after recording.
104
+ */
105
+ const startVoicePlayer = async () => {
106
+ if (!recording) return;
107
+ // For Native CLI
108
+ if (Audio.startPlayer)
109
+ await Audio.startPlayer(recording, {}, onVoicePlayerPlaybackStatusUpdate);
110
+ // For Expo CLI
111
+ if (recording && typeof recording !== 'string') {
112
+ const uri = recording.getURI();
113
+ if (uri) {
114
+ soundRef.current = await Sound.initializeSound(
115
+ { uri },
116
+ {},
117
+ onVoicePlayerPlaybackStatusUpdate,
118
+ );
119
+ if (soundRef.current?.playAsync && soundRef.current.setProgressUpdateIntervalAsync) {
120
+ await soundRef.current.playAsync();
121
+ await soundRef.current.setProgressUpdateIntervalAsync(
122
+ Platform.OS === 'android' ? 100 : 60,
123
+ );
124
+ }
125
+ }
126
+ }
127
+ };
128
+
129
+ /**
130
+ * Function to stop playing voice recording.
131
+ */
132
+ const stopVoicePlayer = async () => {
133
+ // For Native CLI
134
+ if (Audio.stopPlayer) {
135
+ await Audio.stopPlayer();
136
+ }
137
+ // For Expo CLI
138
+ if (recording && typeof recording !== 'string') {
139
+ if (soundRef.current?.stopAsync && soundRef.current?.unloadAsync) {
140
+ await soundRef.current.stopAsync();
141
+ await soundRef.current?.unloadAsync();
142
+ }
143
+ }
144
+ };
145
+
146
+ const onRecordingStatusUpdate = (status: RecordingStatus) => {
147
+ if (status.isDoneRecording === true) {
148
+ return;
149
+ }
150
+ setRecordingDuration(status?.currentPosition || status.durationMillis);
151
+ // For expo android the lower bound is -120 so we need to normalize according to it. The `status.currentMetering` is undefined for Expo CLI apps, so we can use it.
152
+ const lowerBound = Platform.OS === 'ios' || status.currentMetering ? -60 : -120;
153
+ const normalizedAudioLevel = normalizeAudioLevel(
154
+ status.currentMetering || status.metering,
155
+ lowerBound,
156
+ );
157
+ setWaveformData((prev) => [...prev, normalizedAudioLevel]);
158
+ };
159
+
160
+ /**
161
+ * Function to start voice recording.
162
+ */
163
+ const startVoiceRecording = async () => {
164
+ setRecordingStatus('recording');
165
+ const recordingInfo = await Audio.startRecording(
166
+ {
167
+ isMeteringEnabled: true,
168
+ },
169
+ onRecordingStatusUpdate,
170
+ );
171
+ const accessGranted = recordingInfo.accessGranted;
172
+ if (accessGranted) {
173
+ setPermissionsGranted(true);
174
+ const recording = recordingInfo.recording;
175
+ if (recording && typeof recording !== 'string') {
176
+ recording.setProgressUpdateInterval(Platform.OS === 'android' ? 100 : 60);
177
+ }
178
+ setRecording(recording);
179
+ await stopVoicePlayer();
180
+ } else {
181
+ setPermissionsGranted(false);
182
+ resetState();
183
+ Alert.alert('Please allow Audio permissions in settings.');
184
+ }
185
+ };
186
+
187
+ /**
188
+ * Function to stop voice recording.
189
+ */
190
+ const stopVoiceRecording = async () => {
191
+ if (recording) {
192
+ // For Expo CLI
193
+ if (typeof recording !== 'string') {
194
+ await recording.stopAndUnloadAsync();
195
+ await Audio.stopRecording();
196
+ }
197
+ // For RN CLI
198
+ else {
199
+ await Audio.stopRecording();
200
+ }
201
+ }
202
+ setRecordingStatus('stopped');
203
+ };
204
+
205
+ /**
206
+ * Function to reset the state of the message input for async voice messages.
207
+ */
208
+ const resetState = () => {
209
+ setRecording(undefined);
210
+ setRecordingStatus('idle');
211
+ setMicLocked(false);
212
+ setWaveformData([]);
213
+ setPaused(true);
214
+ setPosition(0);
215
+ setProgress(0);
216
+ };
217
+
218
+ /**
219
+ * Function to delete voice recording.
220
+ */
221
+ const deleteVoiceRecording = async () => {
222
+ if (recordingStatus === 'recording') {
223
+ await stopVoiceRecording();
224
+ }
225
+ if (!paused) {
226
+ await stopVoicePlayer();
227
+ }
228
+ resetState();
229
+ triggerHaptic('impactMedium');
230
+ };
231
+
232
+ /**
233
+ * Function to upload or send voice recording.
234
+ * @param multiSendEnabled boolean
235
+ */
236
+ const uploadVoiceRecording = async (multiSendEnabled: boolean) => {
237
+ if (!paused) {
238
+ await stopVoicePlayer();
239
+ }
240
+ if (recordingStatus === 'recording') {
241
+ await stopVoiceRecording();
242
+ }
243
+
244
+ const durationInSeconds = parseFloat((recordingDuration / 1000).toFixed(3));
245
+
246
+ const resampledWaveformData = resampleWaveformData(waveformData, 100);
247
+
248
+ const file: File = {
249
+ duration: durationInSeconds,
250
+ mimeType: 'audio/aac',
251
+ name: `audio_recording_${new Date().toISOString()}.aac`,
252
+ type: 'voiceRecording',
253
+ uri: typeof recording !== 'string' ? (recording?.getURI() as string) : (recording as string),
254
+ waveform_data: resampledWaveformData,
255
+ };
256
+
257
+ if (multiSendEnabled) {
258
+ await uploadNewFile(file);
259
+ } else {
260
+ // FIXME: cannot call handleSubmit() directly as the function has stale reference to file uploads
261
+ await uploadNewFile(file);
262
+ setIsScheduleForSubmit(true);
263
+ }
264
+ resetState();
265
+ };
266
+
267
+ return {
268
+ deleteVoiceRecording,
269
+ micLocked,
270
+ onVoicePlayerPlayPause,
271
+ paused,
272
+ permissionsGranted,
273
+ position,
274
+ progress,
275
+ recording,
276
+ recordingDuration,
277
+ recordingStatus,
278
+ setMicLocked,
279
+ setRecording,
280
+ setRecordingDuration,
281
+ setRecordingStatus,
282
+ setWaveformData,
283
+ startVoiceRecording,
284
+ stopVoiceRecording,
285
+ uploadVoiceRecording,
286
+ waveformData,
287
+ };
288
+ };
@@ -0,0 +1,108 @@
1
+ export const resampleWaveformData = (waveformData: number[], amplitudesCount: number) =>
2
+ waveformData.length === amplitudesCount
3
+ ? waveformData
4
+ : waveformData.length > amplitudesCount
5
+ ? downSample(waveformData, amplitudesCount)
6
+ : upSample(waveformData, amplitudesCount);
7
+
8
+ /**
9
+ * The downSample function uses the Largest-Triangle-Three-Buckets (LTTB) algorithm.
10
+ * See the thesis Downsampling Time Series for Visual Representation by Sveinn Steinarsson for more (https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf)
11
+ * @param data
12
+ * @param targetOutputSize
13
+ */
14
+ export function downSample(data: number[], targetOutputSize: number): number[] {
15
+ if (data.length <= targetOutputSize || targetOutputSize === 0) {
16
+ return data;
17
+ }
18
+
19
+ if (targetOutputSize === 1) return [mean(data)];
20
+
21
+ const result: number[] = [];
22
+ // bucket size adjusted due to the fact that the first and the last item in the original data array is kept in target output
23
+ const bucketSize = (data.length - 2) / (targetOutputSize - 2);
24
+ let lastSelectedPointIndex = 0;
25
+ result.push(data[lastSelectedPointIndex]); // Always add the first point
26
+ let maxAreaPoint, maxArea, triangleArea;
27
+
28
+ for (let bucketIndex = 1; bucketIndex < targetOutputSize - 1; bucketIndex++) {
29
+ const previousBucketRefPoint = data[lastSelectedPointIndex];
30
+ const nextBucketMean = getNextBucketMean(data, bucketIndex, bucketSize);
31
+
32
+ const currentBucketStartIndex = Math.floor((bucketIndex - 1) * bucketSize) + 1;
33
+ const nextBucketStartIndex = Math.floor(bucketIndex * bucketSize) + 1;
34
+ const countUnitsBetweenAtoC = 1 + nextBucketStartIndex - currentBucketStartIndex;
35
+
36
+ maxArea = triangleArea = -1;
37
+
38
+ for (
39
+ let currentPointIndex = currentBucketStartIndex;
40
+ currentPointIndex < nextBucketStartIndex;
41
+ currentPointIndex++
42
+ ) {
43
+ const countUnitsBetweenAtoB = Math.abs(currentPointIndex - currentBucketStartIndex) + 1;
44
+ const countUnitsBetweenBtoC = countUnitsBetweenAtoC - countUnitsBetweenAtoB;
45
+ const currentPointValue = data[currentPointIndex];
46
+
47
+ triangleArea = triangleAreaHeron(
48
+ triangleBase(Math.abs(previousBucketRefPoint - currentPointValue), countUnitsBetweenAtoB),
49
+ triangleBase(Math.abs(currentPointValue - nextBucketMean), countUnitsBetweenBtoC),
50
+ triangleBase(Math.abs(previousBucketRefPoint - nextBucketMean), countUnitsBetweenAtoC),
51
+ );
52
+
53
+ if (triangleArea > maxArea) {
54
+ maxArea = triangleArea;
55
+ maxAreaPoint = data[currentPointIndex];
56
+ lastSelectedPointIndex = currentPointIndex;
57
+ }
58
+ }
59
+
60
+ if (typeof maxAreaPoint !== 'undefined') result.push(maxAreaPoint);
61
+ }
62
+
63
+ result.push(data[data.length - 1]); // Always add the last point
64
+
65
+ return result;
66
+ }
67
+
68
+ const triangleAreaHeron = (a: number, b: number, c: number) => {
69
+ const s = (a + b + c) / 2;
70
+ return Math.sqrt(s * (s - a) * (s - b) * (s - c));
71
+ };
72
+
73
+ const triangleBase = (a: number, b: number) => Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
74
+ const mean = (values: number[]) => values.reduce((acc, value) => acc + value, 0) / values.length;
75
+ export const divMod = (num: number, divisor: number) => [Math.floor(num / divisor), num % divisor];
76
+
77
+ const getNextBucketMean = (data: number[], currentBucketIndex: number, bucketSize: number) => {
78
+ const nextBucketStartIndex = Math.floor(currentBucketIndex * bucketSize) + 1;
79
+ let nextNextBucketStartIndex = Math.floor((currentBucketIndex + 1) * bucketSize) + 1;
80
+ nextNextBucketStartIndex =
81
+ nextNextBucketStartIndex < data.length ? nextNextBucketStartIndex : data.length;
82
+
83
+ return mean(data.slice(nextBucketStartIndex, nextNextBucketStartIndex));
84
+ };
85
+
86
+ export const upSample = (values: number[], targetSize: number) => {
87
+ if (!values.length) {
88
+ console.warn('Cannot extend empty array of amplitudes.');
89
+ return values;
90
+ }
91
+
92
+ if (values.length > targetSize) {
93
+ console.warn('Requested to extend the waveformData that is longer than the target list size');
94
+ return values;
95
+ }
96
+
97
+ if (targetSize === values.length) return values;
98
+
99
+ // eslint-disable-next-line prefer-const
100
+ let [bucketSize, remainder] = divMod(targetSize, values.length);
101
+ const result: number[] = [];
102
+
103
+ for (let i = 0; i < values.length; i++) {
104
+ const extra = remainder && remainder-- ? 1 : 0;
105
+ result.push(...Array(bucketSize + extra).fill(values[i]));
106
+ }
107
+ return result;
108
+ };
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Utility function to normalize the audio level.
3
+ */
4
+ export const normalizeAudioLevel = (value: number, lowerBound: number) => {
5
+ // For Native CLI, the lower bound is around -50
6
+ const upperBound = 0;
7
+
8
+ const delta = upperBound - lowerBound;
9
+
10
+ // In Native CLI Android, the value is undefined for loud audio
11
+ if (value === undefined) return 1;
12
+
13
+ if (value < lowerBound) {
14
+ return 0;
15
+ } else if (value >= upperBound) {
16
+ return 1;
17
+ } else {
18
+ return Math.abs((value - lowerBound) / delta);
19
+ }
20
+ };
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
- import { StyleSheet, View } from 'react-native';
2
+ import { Dimensions, StyleSheet, View } from 'react-native';
3
3
  import { PanGestureHandler } from 'react-native-gesture-handler';
4
4
  import Animated, {
5
5
  cancelAnimation,
@@ -14,66 +14,65 @@ import { useTheme } from '../../contexts/themeContext/ThemeContext';
14
14
  export type ProgressControlProps = {
15
15
  duration: number;
16
16
  filledColor: string;
17
- onPlayPause: (status?: boolean) => void;
18
17
  progress: number;
19
18
  testID: string;
20
- width: number;
19
+ width: number | string;
20
+ onPlayPause?: (status?: boolean) => void;
21
21
  onProgressDrag?: (progress: number) => void;
22
22
  };
23
23
 
24
24
  const height = 2;
25
- const styles = StyleSheet.create({
26
- containerStyle: {
27
- borderRadius: 50,
28
- height,
29
- },
30
- innerStyle: {
31
- height,
32
- },
33
- progressControlThumbStyle: {
34
- borderRadius: 5,
35
- elevation: 6,
36
- height: 20,
37
- shadowOffset: {
38
- height: 3,
39
- width: 0,
40
- },
41
- shadowOpacity: 0.27,
42
- shadowRadius: 4.65,
43
- top: -11,
44
- width: 5,
45
- },
46
- });
47
25
 
48
26
  const ProgressControlThumb = () => {
49
27
  const {
50
28
  theme: {
51
- colors: { black },
29
+ colors: { black, grey_dark, static_white },
52
30
  },
53
31
  } = useTheme();
54
32
  return (
55
33
  <View
56
- style={[styles.progressControlThumbStyle, { backgroundColor: '#ffffff', shadowColor: black }]}
34
+ style={[
35
+ styles.progressControlThumbStyle,
36
+ { backgroundColor: static_white, borderColor: grey_dark, shadowColor: black },
37
+ ]}
57
38
  />
58
39
  );
59
40
  };
60
41
 
61
42
  export const ProgressControl = React.memo(
62
43
  (props: ProgressControlProps) => {
63
- const { duration, filledColor, onPlayPause, onProgressDrag, progress, testID, width } = props;
44
+ const {
45
+ duration,
46
+ filledColor: filledColorFromProp,
47
+ onPlayPause,
48
+ onProgressDrag,
49
+ progress,
50
+ testID,
51
+ width,
52
+ } = props;
53
+ const { width: windowWidth } = Dimensions.get('screen');
54
+ const widthInNumbers = width
55
+ ? typeof width === 'string'
56
+ ? (windowWidth * Number(width?.substring(0, width.length - 1))) / 100
57
+ : width
58
+ : 0;
64
59
  const {
65
60
  theme: {
66
61
  colors: { grey_dark },
62
+ progressControl: { container, filledColor: filledColorFromTheme, filledStyles, thumb },
67
63
  },
68
64
  } = useTheme();
69
65
 
70
66
  const state = useSharedValue(0);
71
67
  const translateX = useSharedValue(0);
68
+ const filledColor = filledColorFromProp || filledColorFromTheme;
72
69
 
73
70
  useEffect(() => {
74
- state.value = progress * width;
75
- translateX.value = progress * width;
76
- }, [progress]);
71
+ if (progress <= 1) {
72
+ state.value = progress * widthInNumbers;
73
+ translateX.value = progress * widthInNumbers;
74
+ }
75
+ }, [progress, widthInNumbers]);
77
76
 
78
77
  const animatedStyles = useAnimatedStyle(() => ({
79
78
  backgroundColor: filledColor,
@@ -88,33 +87,36 @@ export const ProgressControl = React.memo(
88
87
  {
89
88
  onActive: (event) => {
90
89
  state.value = translateX.value + event.translationX;
91
- if (state.value > width) state.value = width;
90
+ if (state.value > widthInNumbers) state.value = widthInNumbers;
92
91
  else if (state.value < 0) state.value = 0;
93
92
  },
94
93
  onFinish: () => {
95
94
  translateX.value = state.value;
96
- const dragFinishLocationInSeconds = (state.value / width) * duration;
95
+ const dragFinishLocationInSeconds = (state.value / widthInNumbers) * duration;
97
96
  if (onProgressDrag) runOnJS(onProgressDrag)(dragFinishLocationInSeconds);
98
- runOnJS(onPlayPause)(false);
97
+ if (onPlayPause) runOnJS(onPlayPause)(false);
99
98
  },
100
99
  onStart: () => {
101
- runOnJS(onPlayPause)(true);
100
+ if (onPlayPause) runOnJS(onPlayPause)(true);
102
101
  cancelAnimation(translateX);
103
102
  state.value = translateX.value;
104
103
  },
105
104
  },
106
- [duration],
105
+ [duration, widthInNumbers],
107
106
  );
107
+
108
108
  return (
109
- <View style={[styles.containerStyle, { backgroundColor: grey_dark, width }]}>
110
- <Animated.View style={[styles.innerStyle, animatedStyles]} />
109
+ <View
110
+ style={[styles.container, { backgroundColor: grey_dark, width: widthInNumbers }, container]}
111
+ >
112
+ <Animated.View style={[styles.filledStyle, animatedStyles, filledStyles]} />
111
113
 
112
114
  <PanGestureHandler
113
115
  maxPointers={1}
114
116
  onGestureEvent={onProgressDrag ? onGestureEvent : undefined}
115
117
  testID={testID}
116
118
  >
117
- <Animated.View style={[thumbStyles]}>
119
+ <Animated.View style={[thumbStyles, thumb]}>
118
120
  {onProgressDrag && <ProgressControlThumb />}
119
121
  </Animated.View>
120
122
  </PanGestureHandler>
@@ -122,10 +124,37 @@ export const ProgressControl = React.memo(
122
124
  );
123
125
  },
124
126
  (prevProps, nextProps) => {
125
- if (prevProps.duration === nextProps.duration && prevProps.progress === nextProps.progress)
127
+ if (
128
+ prevProps.duration === nextProps.duration &&
129
+ prevProps.progress === nextProps.progress &&
130
+ prevProps.width === nextProps.width
131
+ )
126
132
  return true;
127
133
  else return false;
128
134
  },
129
135
  );
130
136
 
137
+ const styles = StyleSheet.create({
138
+ container: {
139
+ borderRadius: 50,
140
+ height,
141
+ },
142
+ filledStyle: {
143
+ height,
144
+ },
145
+ progressControlThumbStyle: {
146
+ borderRadius: 5,
147
+ borderWidth: 0.2,
148
+ elevation: 6,
149
+ height: 20,
150
+ shadowOffset: {
151
+ height: 3,
152
+ width: 0,
153
+ },
154
+ shadowOpacity: 0.27,
155
+ shadowRadius: 4.65,
156
+ top: -11,
157
+ width: 5,
158
+ },
159
+ });
131
160
  ProgressControl.displayName = 'ProgressControl';