stream-chat-react 11.13.1 → 11.15.0

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 (203) hide show
  1. package/dist/{Window-44a85f63.js → Window-847d5d88.js} +13943 -397
  2. package/dist/browser.full-bundle.js +17317 -3876
  3. package/dist/browser.full-bundle.js.map +1 -1
  4. package/dist/browser.full-bundle.min.js +4 -4
  5. package/dist/browser.full-bundle.min.js.map +1 -1
  6. package/dist/components/Attachment/Audio.d.ts.map +1 -1
  7. package/dist/components/Attachment/Audio.js +7 -4
  8. package/dist/components/Attachment/Card.d.ts +1 -1
  9. package/dist/components/Attachment/Card.d.ts.map +1 -1
  10. package/dist/components/Attachment/Card.js +4 -2
  11. package/dist/components/Attachment/VoiceRecording.d.ts.map +1 -1
  12. package/dist/components/Attachment/VoiceRecording.js +6 -4
  13. package/dist/components/Attachment/audioSampling.d.ts +10 -0
  14. package/dist/components/Attachment/audioSampling.d.ts.map +1 -0
  15. package/dist/components/Attachment/audioSampling.js +83 -0
  16. package/dist/components/Attachment/components/FileSizeIndicator.js +2 -2
  17. package/dist/components/Attachment/components/WaveProgressBar.d.ts +3 -10
  18. package/dist/components/Attachment/components/WaveProgressBar.d.ts.map +1 -1
  19. package/dist/components/Attachment/components/WaveProgressBar.js +23 -90
  20. package/dist/components/Attachment/hooks/useAudioController.d.ts +11 -3
  21. package/dist/components/Attachment/hooks/useAudioController.d.ts.map +1 -1
  22. package/dist/components/Attachment/hooks/useAudioController.js +89 -26
  23. package/dist/components/Attachment/index.d.ts +1 -0
  24. package/dist/components/Attachment/index.d.ts.map +1 -1
  25. package/dist/components/Attachment/index.js +1 -0
  26. package/dist/components/Attachment/utils.d.ts +5 -3
  27. package/dist/components/Attachment/utils.d.ts.map +1 -1
  28. package/dist/components/Attachment/utils.js +1 -0
  29. package/dist/components/Channel/Channel.d.ts +5 -1
  30. package/dist/components/Channel/Channel.d.ts.map +1 -1
  31. package/dist/components/Channel/Channel.js +2 -0
  32. package/dist/components/ChannelSearch/SearchResults.d.ts +2 -2
  33. package/dist/components/ChannelSearch/SearchResults.d.ts.map +1 -1
  34. package/dist/components/ChannelSearch/SearchResults.js +1 -1
  35. package/dist/components/ChannelSearch/hooks/useChannelSearch.d.ts +1 -1
  36. package/dist/components/ChannelSearch/hooks/useChannelSearch.d.ts.map +1 -1
  37. package/dist/components/ChannelSearch/hooks/useChannelSearch.js +1 -1
  38. package/dist/components/Emojis/EmojiPicker.d.ts +2 -2
  39. package/dist/components/Emojis/index.cjs.js +2 -3
  40. package/dist/components/MediaRecorder/AudioRecorder/AudioRecorder.d.ts +3 -0
  41. package/dist/components/MediaRecorder/AudioRecorder/AudioRecorder.d.ts.map +1 -0
  42. package/dist/components/MediaRecorder/AudioRecorder/AudioRecorder.js +24 -0
  43. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingButtons.d.ts +4 -0
  44. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingButtons.d.ts.map +1 -0
  45. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingButtons.js +5 -0
  46. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingInProgress.d.ts +3 -0
  47. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingInProgress.d.ts.map +1 -0
  48. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingInProgress.js +47 -0
  49. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.d.ts +8 -0
  50. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.d.ts.map +1 -0
  51. package/dist/components/MediaRecorder/AudioRecorder/AudioRecordingPreview.js +21 -0
  52. package/dist/components/MediaRecorder/AudioRecorder/RecordingTimer.d.ts +6 -0
  53. package/dist/components/MediaRecorder/AudioRecorder/RecordingTimer.d.ts.map +1 -0
  54. package/dist/components/MediaRecorder/AudioRecorder/RecordingTimer.js +9 -0
  55. package/dist/components/MediaRecorder/AudioRecorder/index.d.ts +4 -0
  56. package/dist/components/MediaRecorder/AudioRecorder/index.d.ts.map +1 -0
  57. package/dist/components/MediaRecorder/AudioRecorder/index.js +3 -0
  58. package/dist/components/MediaRecorder/RecordingPermissionDeniedNotification.d.ts +8 -0
  59. package/dist/components/MediaRecorder/RecordingPermissionDeniedNotification.d.ts.map +1 -0
  60. package/dist/components/MediaRecorder/RecordingPermissionDeniedNotification.js +21 -0
  61. package/dist/components/MediaRecorder/classes/AmplitudeRecorder.d.ts +55 -0
  62. package/dist/components/MediaRecorder/classes/AmplitudeRecorder.d.ts.map +1 -0
  63. package/dist/components/MediaRecorder/classes/AmplitudeRecorder.js +93 -0
  64. package/dist/components/MediaRecorder/classes/BrowserPermission.d.ts +23 -0
  65. package/dist/components/MediaRecorder/classes/BrowserPermission.d.ts.map +1 -0
  66. package/dist/components/MediaRecorder/classes/BrowserPermission.js +98 -0
  67. package/dist/components/MediaRecorder/classes/MediaRecorderController.d.ts +83 -0
  68. package/dist/components/MediaRecorder/classes/MediaRecorderController.d.ts.map +1 -0
  69. package/dist/components/MediaRecorder/classes/MediaRecorderController.js +313 -0
  70. package/dist/components/MediaRecorder/classes/index.d.ts +4 -0
  71. package/dist/components/MediaRecorder/classes/index.d.ts.map +1 -0
  72. package/dist/components/MediaRecorder/classes/index.js +2 -0
  73. package/dist/components/MediaRecorder/hooks/index.d.ts +2 -0
  74. package/dist/components/MediaRecorder/hooks/index.d.ts.map +1 -0
  75. package/dist/components/MediaRecorder/hooks/index.js +1 -0
  76. package/dist/components/MediaRecorder/hooks/useMediaRecorder.d.ts +20 -0
  77. package/dist/components/MediaRecorder/hooks/useMediaRecorder.d.ts.map +1 -0
  78. package/dist/components/MediaRecorder/hooks/useMediaRecorder.js +73 -0
  79. package/dist/components/MediaRecorder/index.d.ts +6 -0
  80. package/dist/components/MediaRecorder/index.d.ts.map +1 -0
  81. package/dist/components/MediaRecorder/index.js +5 -0
  82. package/dist/components/MediaRecorder/observable/BehaviorSubject.d.ts +11 -0
  83. package/dist/components/MediaRecorder/observable/BehaviorSubject.d.ts.map +1 -0
  84. package/dist/components/MediaRecorder/observable/BehaviorSubject.js +34 -0
  85. package/dist/components/MediaRecorder/observable/Observable.d.ts +18 -0
  86. package/dist/components/MediaRecorder/observable/Observable.d.ts.map +1 -0
  87. package/dist/components/MediaRecorder/observable/Observable.js +29 -0
  88. package/dist/components/MediaRecorder/observable/Observer.d.ts +10 -0
  89. package/dist/components/MediaRecorder/observable/Observer.d.ts.map +1 -0
  90. package/dist/components/MediaRecorder/observable/Observer.js +3 -0
  91. package/dist/components/MediaRecorder/observable/Subject.d.ts +16 -0
  92. package/dist/components/MediaRecorder/observable/Subject.d.ts.map +1 -0
  93. package/dist/components/MediaRecorder/observable/Subject.js +70 -0
  94. package/dist/components/MediaRecorder/observable/Subscription.d.ts +11 -0
  95. package/dist/components/MediaRecorder/observable/Subscription.d.ts.map +1 -0
  96. package/dist/components/MediaRecorder/observable/Subscription.js +13 -0
  97. package/dist/components/MediaRecorder/observable/index.d.ts +6 -0
  98. package/dist/components/MediaRecorder/observable/index.d.ts.map +1 -0
  99. package/dist/components/MediaRecorder/observable/index.js +5 -0
  100. package/dist/components/MediaRecorder/transcode/audioProcessing.d.ts +16 -0
  101. package/dist/components/MediaRecorder/transcode/audioProcessing.d.ts.map +1 -0
  102. package/dist/components/MediaRecorder/transcode/audioProcessing.js +51 -0
  103. package/dist/components/MediaRecorder/transcode/index.d.ts +8 -0
  104. package/dist/components/MediaRecorder/transcode/index.d.ts.map +1 -0
  105. package/dist/components/MediaRecorder/transcode/index.js +18 -0
  106. package/dist/components/MediaRecorder/transcode/mp3.d.ts +2 -0
  107. package/dist/components/MediaRecorder/transcode/mp3.d.ts.map +1 -0
  108. package/dist/components/MediaRecorder/transcode/mp3.js +53 -0
  109. package/dist/components/MediaRecorder/transcode/wav.d.ts +8 -0
  110. package/dist/components/MediaRecorder/transcode/wav.d.ts.map +1 -0
  111. package/dist/components/MediaRecorder/transcode/wav.js +117 -0
  112. package/dist/components/Message/MessageSimple.d.ts.map +1 -1
  113. package/dist/components/Message/MessageSimple.js +3 -2
  114. package/dist/components/MessageInput/AttachmentPreviewList.d.ts +2 -1
  115. package/dist/components/MessageInput/AttachmentPreviewList.d.ts.map +1 -1
  116. package/dist/components/MessageInput/AttachmentPreviewList.js +66 -20
  117. package/dist/components/MessageInput/CooldownTimer.d.ts.map +1 -1
  118. package/dist/components/MessageInput/CooldownTimer.js +4 -17
  119. package/dist/components/MessageInput/MessageInput.d.ts +10 -0
  120. package/dist/components/MessageInput/MessageInput.d.ts.map +1 -1
  121. package/dist/components/MessageInput/MessageInputFlat.d.ts.map +1 -1
  122. package/dist/components/MessageInput/MessageInputFlat.js +31 -9
  123. package/dist/components/MessageInput/MessageInputSmall.d.ts.map +1 -1
  124. package/dist/components/MessageInput/MessageInputSmall.js +3 -2
  125. package/dist/components/MessageInput/SendButton.d.ts +8 -0
  126. package/dist/components/MessageInput/SendButton.d.ts.map +1 -0
  127. package/dist/components/MessageInput/SendButton.js +9 -0
  128. package/dist/components/MessageInput/hooks/useAttachments.d.ts +5 -2
  129. package/dist/components/MessageInput/hooks/useAttachments.d.ts.map +1 -1
  130. package/dist/components/MessageInput/hooks/useAttachments.js +87 -3
  131. package/dist/components/MessageInput/hooks/useCreateMessageInputContext.d.ts.map +1 -1
  132. package/dist/components/MessageInput/hooks/useCreateMessageInputContext.js +12 -2
  133. package/dist/components/MessageInput/hooks/useMessageInputState.d.ts +22 -7
  134. package/dist/components/MessageInput/hooks/useMessageInputState.d.ts.map +1 -1
  135. package/dist/components/MessageInput/hooks/useMessageInputState.js +31 -5
  136. package/dist/components/MessageInput/hooks/useSubmitHandler.d.ts +2 -2
  137. package/dist/components/MessageInput/hooks/useSubmitHandler.d.ts.map +1 -1
  138. package/dist/components/MessageInput/hooks/useSubmitHandler.js +15 -6
  139. package/dist/components/MessageInput/hooks/useTimeElapsed.d.ts +10 -0
  140. package/dist/components/MessageInput/hooks/useTimeElapsed.d.ts.map +1 -0
  141. package/dist/components/MessageInput/hooks/useTimeElapsed.js +30 -0
  142. package/dist/components/MessageInput/hooks/useTimer.d.ts +4 -0
  143. package/dist/components/MessageInput/hooks/useTimer.d.ts.map +1 -0
  144. package/dist/components/MessageInput/hooks/useTimer.js +20 -0
  145. package/dist/components/MessageInput/hooks/utils.d.ts +1 -0
  146. package/dist/components/MessageInput/hooks/utils.d.ts.map +1 -1
  147. package/dist/components/MessageInput/hooks/utils.js +24 -7
  148. package/dist/components/MessageInput/icons.d.ts +5 -6
  149. package/dist/components/MessageInput/icons.d.ts.map +1 -1
  150. package/dist/components/MessageInput/icons.js +13 -10
  151. package/dist/components/MessageInput/index.d.ts +1 -0
  152. package/dist/components/MessageInput/index.d.ts.map +1 -1
  153. package/dist/components/MessageInput/index.js +1 -0
  154. package/dist/components/MessageInput/types.d.ts +36 -1
  155. package/dist/components/MessageInput/types.d.ts.map +1 -1
  156. package/dist/components/ReactFileUtilities/types.d.ts +1 -0
  157. package/dist/components/ReactFileUtilities/types.d.ts.map +1 -1
  158. package/dist/components/ReactFileUtilities/utils.d.ts +9 -1
  159. package/dist/components/ReactFileUtilities/utils.d.ts.map +1 -1
  160. package/dist/components/ReactFileUtilities/utils.js +25 -0
  161. package/dist/components/Reactions/utils/utils.d.ts +2 -1
  162. package/dist/components/Reactions/utils/utils.d.ts.map +1 -1
  163. package/dist/components/index.d.ts +1 -0
  164. package/dist/components/index.d.ts.map +1 -1
  165. package/dist/components/index.js +1 -0
  166. package/dist/constants/limits.d.ts +1 -0
  167. package/dist/constants/limits.d.ts.map +1 -1
  168. package/dist/constants/limits.js +1 -0
  169. package/dist/context/ComponentContext.d.ts +7 -4
  170. package/dist/context/ComponentContext.d.ts.map +1 -1
  171. package/dist/context/MessageInputContext.d.ts +4 -1
  172. package/dist/context/MessageInputContext.d.ts.map +1 -1
  173. package/dist/css/v2/index.css +3 -1
  174. package/dist/css/v2/index.layout.css +3 -1
  175. package/dist/i18n/Streami18n.d.ts +14 -0
  176. package/dist/i18n/Streami18n.d.ts.map +1 -1
  177. package/dist/i18n/de.json +14 -0
  178. package/dist/i18n/en.json +14 -0
  179. package/dist/i18n/es.json +14 -0
  180. package/dist/i18n/fr.json +14 -0
  181. package/dist/i18n/hi.json +14 -0
  182. package/dist/i18n/it.json +14 -0
  183. package/dist/i18n/ja.json +14 -0
  184. package/dist/i18n/ko.json +14 -0
  185. package/dist/i18n/nl.json +14 -0
  186. package/dist/i18n/pt.json +14 -0
  187. package/dist/i18n/ru.json +14 -0
  188. package/dist/i18n/tr.json +14 -0
  189. package/dist/index.cjs.js +22 -4
  190. package/dist/scss/v2/AttachmentList/AttachmentList-layout.scss +56 -8
  191. package/dist/scss/v2/AttachmentList/AttachmentList-theme.scss +22 -4
  192. package/dist/scss/v2/ImageCarousel/ImageCarousel-layout.scss +11 -2
  193. package/dist/scss/v2/ImageCarousel/ImageCarousel-theme.scss +14 -0
  194. package/dist/scss/v2/_global-theme-variables.scss +13 -13
  195. package/dist/utils/mergeDeep.d.ts +4 -0
  196. package/dist/utils/mergeDeep.d.ts.map +1 -0
  197. package/dist/utils/mergeDeep.js +5 -0
  198. package/dist/version.d.ts +1 -1
  199. package/dist/version.js +1 -1
  200. package/package.json +6 -3
  201. package/dist/components/MessageInput/hooks/useFileState.d.ts +0 -7
  202. package/dist/components/MessageInput/hooks/useFileState.d.ts.map +0 -1
  203. package/dist/components/MessageInput/hooks/useFileState.js +0 -8
@@ -1 +1 @@
1
- {"version":3,"file":"Audio.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/Audio.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,MAAM,UAAU,CACpB,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E;IACF,EAAE,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;CACpC,CAAC;AAwGF;;GAEG;AACH,eAAO,MAAM,KAAK,gJAAwD,CAAC"}
1
+ {"version":3,"file":"Audio.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/Audio.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAO9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAC;AAEnE,MAAM,MAAM,UAAU,CACpB,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E;IACF,EAAE,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;CACpC,CAAC;AA2GF;;GAEG;AACH,eAAO,MAAM,KAAK,gJAAwD,CAAC"}
@@ -5,8 +5,9 @@ import { useAudioController } from './hooks/useAudioController';
5
5
  import { useChatContext } from '../../context/ChatContext';
6
6
  var AudioV1 = function (_a) {
7
7
  var og = _a.og;
8
- var asset_url = og.asset_url, description = og.description, image_url = og.image_url, text = og.text, title = og.title;
9
- var _b = useAudioController(), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, togglePlay = _b.togglePlay;
8
+ // fixme: pass mimeType if available
9
+ var asset_url = og.asset_url, description = og.description, image_url = og.image_url, mime_type = og.mime_type, text = og.text, title = og.title;
10
+ var _b = useAudioController({ mimeType: mime_type }), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, togglePlay = _b.togglePlay;
10
11
  return (React.createElement("div", { className: 'str-chat__audio' },
11
12
  React.createElement("div", { className: 'str-chat__audio__wrapper' },
12
13
  React.createElement("audio", { ref: audioRef },
@@ -27,8 +28,10 @@ var AudioV1 = function (_a) {
27
28
  };
28
29
  var AudioV2 = function (_a) {
29
30
  var og = _a.og;
30
- var asset_url = og.asset_url, file_size = og.file_size, title = og.title;
31
- var _b = useAudioController(), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, seek = _b.seek, togglePlay = _b.togglePlay;
31
+ var asset_url = og.asset_url, file_size = og.file_size, mime_type = og.mime_type, title = og.title;
32
+ var _b = useAudioController({
33
+ mimeType: mime_type,
34
+ }), audioRef = _b.audioRef, isPlaying = _b.isPlaying, progress = _b.progress, seek = _b.seek, togglePlay = _b.togglePlay;
32
35
  if (!asset_url)
33
36
  return null;
34
37
  var dataTestId = 'audio-widget';
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { AudioProps } from './Audio';
3
3
  import type { RenderAttachmentProps } from './utils';
4
- export declare const CardAudio: ({ og: { asset_url, author_name, og_scrape_url, text, title, title_link }, }: AudioProps) => React.JSX.Element;
4
+ export declare const CardAudio: ({ og: { asset_url, author_name, mime_type, og_scrape_url, text, title, title_link }, }: AudioProps) => React.JSX.Element;
5
5
  export type CardProps = RenderAttachmentProps['attachment'];
6
6
  /**
7
7
  * Simple Card Layout for displaying links
@@ -1 +1 @@
1
- {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAWrC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA2MrD,eAAO,MAAM,SAAS,gFAEnB,UAAU,sBA8BZ,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAQ5D;;GAEG;AACH,eAAO,MAAM,IAAI,UATc,SAAS,sBAS+B,CAAC"}
1
+ {"version":3,"file":"Card.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/Card.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAWrC,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAC;AA2MrD,eAAO,MAAM,SAAS,2FAEnB,UAAU,sBAgCZ,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG,qBAAqB,CAAC,YAAY,CAAC,CAAC;AAQ5D;;GAEG;AACH,eAAO,MAAM,IAAI,UATc,SAAS,sBAS+B,CAAC"}
@@ -94,8 +94,10 @@ var CardV2 = function (props) {
94
94
  React.createElement(CardContent, __assign({}, props))));
95
95
  };
96
96
  export var CardAudio = function (_a) {
97
- var _b = _a.og, asset_url = _b.asset_url, author_name = _b.author_name, og_scrape_url = _b.og_scrape_url, text = _b.text, title = _b.title, title_link = _b.title_link;
98
- var _c = useAudioController(), audioRef = _c.audioRef, isPlaying = _c.isPlaying, progress = _c.progress, seek = _c.seek, togglePlay = _c.togglePlay;
97
+ var _b = _a.og, asset_url = _b.asset_url, author_name = _b.author_name, mime_type = _b.mime_type, og_scrape_url = _b.og_scrape_url, text = _b.text, title = _b.title, title_link = _b.title_link;
98
+ var _c = useAudioController({
99
+ mimeType: mime_type,
100
+ }), audioRef = _c.audioRef, isPlaying = _c.isPlaying, progress = _c.progress, seek = _c.seek, togglePlay = _c.togglePlay;
99
101
  var url = title_link || og_scrape_url;
100
102
  var dataTestId = 'card-audio-widget';
101
103
  var rootClassName = 'str-chat__message-attachment-card-audio-widget';
@@ -1 +1 @@
1
- {"version":3,"file":"VoiceRecording.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/VoiceRecording.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,MAAM,MAAM,yBAAyB,CACnC,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,YAAY,CAAC,GAAG;IAChE,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kCAAmC,yBAAyB,6BA8D5F,CAAC;AAEF,MAAM,MAAM,yBAAyB,CACnC,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,YAAY,CAAC,CAAC;AAEhE,eAAO,MAAM,oBAAoB,mBAAoB,yBAAyB,sBA4B7E,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC7B,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E;IACF,gEAAgE;IAChE,UAAU,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC3C,gGAAgG;IAChG,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,cAAc,6BAA8B,mBAAmB,sBAKzE,CAAC"}
1
+ {"version":3,"file":"VoiceRecording.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/VoiceRecording.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAQ9C,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,aAAa,CAAC;AAI7D,MAAM,MAAM,yBAAyB,CACnC,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,YAAY,CAAC,GAAG;IAChE,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,oBAAoB,kCAAmC,yBAAyB,6BAiE5F,CAAC;AAEF,MAAM,MAAM,yBAAyB,CACnC,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E,IAAI,CAAC,mBAAmB,CAAC,kBAAkB,CAAC,EAAE,YAAY,CAAC,CAAC;AAEhE,eAAO,MAAM,oBAAoB,mBAAoB,yBAAyB,sBA4B7E,CAAC;AAEF,MAAM,MAAM,mBAAmB,CAC7B,kBAAkB,SAAS,yBAAyB,GAAG,yBAAyB,IAC9E;IACF,gEAAgE;IAChE,UAAU,EAAE,UAAU,CAAC,kBAAkB,CAAC,CAAC;IAC3C,gGAAgG;IAChG,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,eAAO,MAAM,cAAc,6BAA8B,mBAAmB,sBAKzE,CAAC"}
@@ -8,13 +8,15 @@ var rootClassName = 'str-chat__message-attachment__voice-recording-widget';
8
8
  export var VoiceRecordingPlayer = function (_a) {
9
9
  var attachment = _a.attachment, playbackRates = _a.playbackRates;
10
10
  var t = useTranslationContext('VoiceRecordingPlayer').t;
11
- var asset_url = attachment.asset_url, duration = attachment.duration, mime_type = attachment.mime_type, _b = attachment.title, title = _b === void 0 ? t('Voice message') : _b, waveform_data = attachment.waveform_data;
12
- var _c = useAudioController({
11
+ var asset_url = attachment.asset_url, _b = attachment.duration, duration = _b === void 0 ? 0 : _b, mime_type = attachment.mime_type, _c = attachment.title, title = _c === void 0 ? t('Voice message') : _c, waveform_data = attachment.waveform_data;
12
+ var _d = useAudioController({
13
13
  durationSeconds: duration !== null && duration !== void 0 ? duration : 0,
14
+ mimeType: mime_type,
14
15
  playbackRates: playbackRates,
15
- }), audioRef = _c.audioRef, increasePlaybackRate = _c.increasePlaybackRate, isPlaying = _c.isPlaying, playbackRate = _c.playbackRate, progress = _c.progress, secondsElapsed = _c.secondsElapsed, seek = _c.seek, togglePlay = _c.togglePlay;
16
+ }), audioRef = _d.audioRef, increasePlaybackRate = _d.increasePlaybackRate, isPlaying = _d.isPlaying, playbackRate = _d.playbackRate, progress = _d.progress, secondsElapsed = _d.secondsElapsed, seek = _d.seek, togglePlay = _d.togglePlay;
16
17
  if (!asset_url)
17
18
  return null;
19
+ var displayedDuration = secondsElapsed || duration;
18
20
  return (React.createElement("div", { className: rootClassName, "data-testid": 'voice-recording-widget' },
19
21
  React.createElement("audio", { ref: audioRef },
20
22
  React.createElement("source", { "data-testid": 'audio-source', src: asset_url, type: mime_type })),
@@ -22,7 +24,7 @@ export var VoiceRecordingPlayer = function (_a) {
22
24
  React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__metadata' },
23
25
  React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__title', "data-testid": 'voice-recording-title', title: title }, title),
24
26
  React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__audio-state' },
25
- React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__timer' }, attachment.duration ? (displayDuration(secondsElapsed)) : (React.createElement(FileSizeIndicator, { fileSize: attachment.file_size, maximumFractionDigits: 0 }))),
27
+ React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__timer' }, attachment.duration ? (displayDuration(displayedDuration)) : (React.createElement(FileSizeIndicator, { fileSize: attachment.file_size, maximumFractionDigits: 0 }))),
26
28
  React.createElement(WaveProgressBar, { progress: progress, seek: seek, waveformData: waveform_data || [] }))),
27
29
  React.createElement("div", { className: 'str-chat__message-attachment__voice-recording-widget__right-section' }, isPlaying ? (React.createElement(PlaybackRateButton, { disabled: !audioRef.current, onClick: increasePlaybackRate },
28
30
  playbackRate.toFixed(1),
@@ -0,0 +1,10 @@
1
+ export declare const resampleWaveformData: (waveformData: number[], amplitudesCount: number) => number[];
2
+ /**
3
+ * The downSample function uses the Largest-Triangle-Three-Buckets (LTTB) algorithm.
4
+ * See the thesis Downsampling Time Series for Visual Representation by Sveinn Steinarsson for more (https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf)
5
+ * @param data
6
+ * @param targetOutputSize
7
+ */
8
+ export declare function downSample(data: number[], targetOutputSize: number): number[];
9
+ export declare const upSample: (values: number[], targetSize: number) => number[];
10
+ //# sourceMappingURL=audioSampling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audioSampling.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/audioSampling.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,oBAAoB,iBAAkB,MAAM,EAAE,mBAAmB,MAAM,aAKvC,CAAC;AAE9C;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CAoD7E;AAgBD,eAAO,MAAM,QAAQ,WAAY,MAAM,EAAE,cAAc,MAAM,aAsB5D,CAAC"}
@@ -0,0 +1,83 @@
1
+ import { divMod } from './utils';
2
+ export var resampleWaveformData = function (waveformData, amplitudesCount) {
3
+ return waveformData.length === amplitudesCount
4
+ ? waveformData
5
+ : waveformData.length > amplitudesCount
6
+ ? downSample(waveformData, amplitudesCount)
7
+ : upSample(waveformData, amplitudesCount);
8
+ };
9
+ /**
10
+ * The downSample function uses the Largest-Triangle-Three-Buckets (LTTB) algorithm.
11
+ * See the thesis Downsampling Time Series for Visual Representation by Sveinn Steinarsson for more (https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf)
12
+ * @param data
13
+ * @param targetOutputSize
14
+ */
15
+ export function downSample(data, targetOutputSize) {
16
+ if (data.length <= targetOutputSize || targetOutputSize === 0) {
17
+ return data;
18
+ }
19
+ if (targetOutputSize === 1)
20
+ return [mean(data)];
21
+ var result = [];
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
+ var bucketSize = (data.length - 2) / (targetOutputSize - 2);
24
+ var lastSelectedPointIndex = 0;
25
+ result.push(data[lastSelectedPointIndex]); // Always add the first point
26
+ var maxAreaPoint, maxArea, triangleArea;
27
+ for (var bucketIndex = 1; bucketIndex < targetOutputSize - 1; bucketIndex++) {
28
+ var previousBucketRefPoint = data[lastSelectedPointIndex];
29
+ var nextBucketMean = getNextBucketMean(data, bucketIndex, bucketSize);
30
+ var currentBucketStartIndex = Math.floor((bucketIndex - 1) * bucketSize) + 1;
31
+ var nextBucketStartIndex = Math.floor(bucketIndex * bucketSize) + 1;
32
+ var countUnitsBetweenAtoC = 1 + nextBucketStartIndex - currentBucketStartIndex;
33
+ maxArea = triangleArea = -1;
34
+ for (var currentPointIndex = currentBucketStartIndex; currentPointIndex < nextBucketStartIndex; currentPointIndex++) {
35
+ var countUnitsBetweenAtoB = Math.abs(currentPointIndex - currentBucketStartIndex) + 1;
36
+ var countUnitsBetweenBtoC = countUnitsBetweenAtoC - countUnitsBetweenAtoB;
37
+ var currentPointValue = data[currentPointIndex];
38
+ triangleArea = triangleAreaHeron(triangleBase(Math.abs(previousBucketRefPoint - currentPointValue), countUnitsBetweenAtoB), triangleBase(Math.abs(currentPointValue - nextBucketMean), countUnitsBetweenBtoC), triangleBase(Math.abs(previousBucketRefPoint - nextBucketMean), countUnitsBetweenAtoC));
39
+ if (triangleArea > maxArea) {
40
+ maxArea = triangleArea;
41
+ maxAreaPoint = data[currentPointIndex];
42
+ lastSelectedPointIndex = currentPointIndex;
43
+ }
44
+ }
45
+ if (typeof maxAreaPoint !== 'undefined')
46
+ result.push(maxAreaPoint);
47
+ }
48
+ result.push(data[data.length - 1]); // Always add the last point
49
+ return result;
50
+ }
51
+ var triangleAreaHeron = function (a, b, c) {
52
+ var s = (a + b + c) / 2;
53
+ return Math.sqrt(s * (s - a) * (s - b) * (s - c));
54
+ };
55
+ var triangleBase = function (a, b) { return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); };
56
+ var mean = function (values) { return values.reduce(function (acc, value) { return acc + value; }, 0) / values.length; };
57
+ var getNextBucketMean = function (data, currentBucketIndex, bucketSize) {
58
+ var nextBucketStartIndex = Math.floor(currentBucketIndex * bucketSize) + 1;
59
+ var nextNextBucketStartIndex = Math.floor((currentBucketIndex + 1) * bucketSize) + 1;
60
+ nextNextBucketStartIndex =
61
+ nextNextBucketStartIndex < data.length ? nextNextBucketStartIndex : data.length;
62
+ return mean(data.slice(nextBucketStartIndex, nextNextBucketStartIndex));
63
+ };
64
+ export var upSample = function (values, targetSize) {
65
+ if (!values.length) {
66
+ console.warn('Cannot extend empty array of amplitudes.');
67
+ return values;
68
+ }
69
+ if (values.length > targetSize) {
70
+ console.warn('Requested to extend the waveformData that is longer than the target list size');
71
+ return values;
72
+ }
73
+ if (targetSize === values.length)
74
+ return values;
75
+ // eslint-disable-next-line prefer-const
76
+ var _a = divMod(targetSize, values.length), bucketSize = _a[0], remainder = _a[1];
77
+ var result = [];
78
+ for (var i = 0; i < values.length; i++) {
79
+ var extra = remainder && remainder-- ? 1 : 0;
80
+ result.push.apply(result, Array(bucketSize + extra).fill(values[i]));
81
+ }
82
+ return result;
83
+ };
@@ -1,8 +1,8 @@
1
1
  import React from 'react';
2
- import prettybytes from 'pretty-bytes';
2
+ import { prettifyFileSize } from '../../MessageInput/hooks/utils';
3
3
  export var FileSizeIndicator = function (_a) {
4
4
  var fileSize = _a.fileSize, maximumFractionDigits = _a.maximumFractionDigits;
5
5
  if (!(fileSize && Number.isFinite(Number(fileSize))))
6
6
  return null;
7
- return (React.createElement("span", { className: 'str-chat__message-attachment-file--item-size', "data-testid": 'file-size-indicator' }, prettybytes(fileSize, { maximumFractionDigits: maximumFractionDigits })));
7
+ return (React.createElement("span", { className: 'str-chat__message-attachment-file--item-size', "data-testid": 'file-size-indicator' }, prettifyFileSize(fileSize, maximumFractionDigits)));
8
8
  };
@@ -1,7 +1,8 @@
1
- import React, { MouseEventHandler } from 'react';
1
+ import React from 'react';
2
+ import type { SeekFn } from '../hooks/useAudioController';
2
3
  type WaveProgressBarProps = {
3
4
  /** Function that allows to change the track progress */
4
- seek: MouseEventHandler<HTMLDivElement>;
5
+ seek: SeekFn;
5
6
  /** The array of fractional number values between 0 and 1 representing the height of amplitudes */
6
7
  waveformData: number[];
7
8
  /** Allows to specify the number of bars into which the original waveformData array should be resampled */
@@ -10,13 +11,5 @@ type WaveProgressBarProps = {
10
11
  progress?: number;
11
12
  };
12
13
  export declare const WaveProgressBar: ({ amplitudesCount, progress, seek, waveformData, }: WaveProgressBarProps) => React.JSX.Element | null;
13
- /**
14
- * The downSample function uses the Largest-Triangle-Three-Buckets (LTTB) algorithm.
15
- * See the thesis Downsampling Time Series for Visual Representation by Sveinn Steinarsson for more (https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf)
16
- * @param data
17
- * @param targetOutputSize
18
- */
19
- export declare function downSample(data: number[], targetOutputSize: number): number[];
20
- export declare const upSample: (values: number[], targetSize: number) => number[];
21
14
  export {};
22
15
  //# sourceMappingURL=WaveProgressBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"WaveProgressBar.d.ts","sourceRoot":"","sources":["../../../../src/components/Attachment/components/WaveProgressBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,iBAAiB,EAA6B,MAAM,OAAO,CAAC;AAI5E,KAAK,oBAAoB,GAAG;IAC1B,wDAAwD;IACxD,IAAI,EAAE,iBAAiB,CAAC,cAAc,CAAC,CAAC;IACxC,kGAAkG;IAClG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AACF,eAAO,MAAM,eAAe,uDAKzB,oBAAoB,6BAqEtB,CAAC;AAEF;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,gBAAgB,EAAE,MAAM,GAAG,MAAM,EAAE,CAoD7E;AAoBD,eAAO,MAAM,QAAQ,WAAY,MAAM,EAAE,cAAc,MAAM,aAsB5D,CAAC"}
1
+ {"version":3,"file":"WaveProgressBar.d.ts","sourceRoot":"","sources":["../../../../src/components/Attachment/components/WaveProgressBar.tsx"],"names":[],"mappings":"AAAA,OAAO,KAON,MAAM,OAAO,CAAC;AAGf,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,6BAA6B,CAAC;AAE1D,KAAK,oBAAoB,GAAG;IAC1B,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,kGAAkG;IAClG,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,0GAA0G;IAC1G,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mEAAmE;IACnE,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,eAAe,uDAKzB,oBAAoB,6BA2EtB,CAAC"}
@@ -1,37 +1,45 @@
1
- import React, { useMemo, useRef, useState } from 'react';
1
+ import { __assign } from "tslib";
2
+ import React, { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
2
3
  import clsx from 'clsx';
3
- import { divMod } from '../utils';
4
+ import { resampleWaveformData } from '../audioSampling';
4
5
  export var WaveProgressBar = function (_a) {
5
6
  var _b = _a.amplitudesCount, amplitudesCount = _b === void 0 ? 40 : _b, _c = _a.progress, progress = _c === void 0 ? 0 : _c, seek = _a.seek, waveformData = _a.waveformData;
6
7
  var _d = useState(null), progressIndicator = _d[0], setProgressIndicator = _d[1];
7
8
  var isDragging = useRef(false);
8
- var handleMouseDown = function () {
9
+ var rootRef = useRef(null);
10
+ var handleDragStart = function (e) {
11
+ e.preventDefault();
9
12
  if (!progressIndicator)
10
13
  return;
11
14
  isDragging.current = true;
12
15
  progressIndicator.style.cursor = 'grabbing';
13
16
  };
14
- var handleMouseMove = function (event) {
17
+ var handleDrag = function (e) {
15
18
  if (!isDragging.current)
16
19
  return;
17
- seek(event);
20
+ // Due to throttling of seek, it is necessary to create a copy (snapshot) of the event.
21
+ // Otherwise, the event would be nullified at the point when the throttled function is executed.
22
+ seek(__assign({}, e));
18
23
  };
19
- var handleMouseUp = function () {
24
+ var handleDragStop = useCallback(function () {
20
25
  if (!progressIndicator)
21
26
  return;
22
27
  isDragging.current = false;
23
28
  progressIndicator.style.removeProperty('cursor');
24
- };
25
- var resampledWaveformData = useMemo(function () {
26
- return waveformData.length === amplitudesCount
27
- ? waveformData
28
- : waveformData.length > amplitudesCount
29
- ? downSample(waveformData, amplitudesCount)
30
- : upSample(waveformData, amplitudesCount);
31
- }, [amplitudesCount, waveformData]);
29
+ }, [progressIndicator]);
30
+ var resampledWaveformData = useMemo(function () { return resampleWaveformData(waveformData, amplitudesCount); }, [
31
+ amplitudesCount,
32
+ waveformData,
33
+ ]);
34
+ useEffect(function () {
35
+ document.addEventListener('pointerup', handleDragStop);
36
+ return function () {
37
+ document.removeEventListener('pointerup', handleDragStop);
38
+ };
39
+ }, [handleDragStop]);
32
40
  if (!waveformData.length)
33
41
  return null;
34
- return (React.createElement("div", { className: 'str-chat__wave-progress-bar__track', "data-testid": 'wave-progress-bar-track', onClick: seek, onMouseDown: handleMouseDown, onMouseLeave: handleMouseUp, onMouseMove: handleMouseMove, onMouseUp: handleMouseUp, role: 'progressbar' },
42
+ return (React.createElement("div", { className: 'str-chat__wave-progress-bar__track', "data-testid": 'wave-progress-bar-track', onClick: seek, onPointerDown: handleDragStart, onPointerMove: handleDrag, onPointerUp: handleDragStop, ref: rootRef, role: 'progressbar' },
35
43
  resampledWaveformData.map(function (amplitude, i) {
36
44
  var _a;
37
45
  return (React.createElement("div", { className: clsx('str-chat__wave-progress-bar__amplitude-bar', (_a = {},
@@ -44,78 +52,3 @@ export var WaveProgressBar = function (_a) {
44
52
  }),
45
53
  React.createElement("div", { className: 'str-chat__wave-progress-bar__progress-indicator', "data-testid": 'wave-progress-bar-progress-indicator', ref: setProgressIndicator, style: { left: "".concat(progress < 0 ? 0 : progress > 100 ? 100 : progress, "%") } })));
46
54
  };
47
- /**
48
- * The downSample function uses the Largest-Triangle-Three-Buckets (LTTB) algorithm.
49
- * See the thesis Downsampling Time Series for Visual Representation by Sveinn Steinarsson for more (https://skemman.is/bitstream/1946/15343/3/SS_MSthesis.pdf)
50
- * @param data
51
- * @param targetOutputSize
52
- */
53
- export function downSample(data, targetOutputSize) {
54
- if (data.length <= targetOutputSize || targetOutputSize === 0) {
55
- return data;
56
- }
57
- if (targetOutputSize === 1)
58
- return [mean(data)];
59
- var result = [];
60
- // bucket size adjusted due to the fact that the first and the last item in the original data array is kept in target output
61
- var bucketSize = (data.length - 2) / (targetOutputSize - 2);
62
- var lastSelectedPointIndex = 0;
63
- result.push(data[lastSelectedPointIndex]); // Always add the first point
64
- var maxAreaPoint, maxArea, triangleArea;
65
- for (var bucketIndex = 1; bucketIndex < targetOutputSize - 1; bucketIndex++) {
66
- var previousBucketRefPoint = data[lastSelectedPointIndex];
67
- var nextBucketMean = getNextBucketMean(data, bucketIndex, bucketSize);
68
- var currentBucketStartIndex = Math.floor((bucketIndex - 1) * bucketSize) + 1;
69
- var nextBucketStartIndex = Math.floor(bucketIndex * bucketSize) + 1;
70
- var countUnitsBetweenAtoC = 1 + nextBucketStartIndex - currentBucketStartIndex;
71
- maxArea = triangleArea = -1;
72
- for (var currentPointIndex = currentBucketStartIndex; currentPointIndex < nextBucketStartIndex; currentPointIndex++) {
73
- var countUnitsBetweenAtoB = Math.abs(currentPointIndex - currentBucketStartIndex) + 1;
74
- var countUnitsBetweenBtoC = countUnitsBetweenAtoC - countUnitsBetweenAtoB;
75
- var currentPointValue = data[currentPointIndex];
76
- triangleArea = triangleAreaHeron(triangleBase(Math.abs(previousBucketRefPoint - currentPointValue), countUnitsBetweenAtoB), triangleBase(Math.abs(currentPointValue - nextBucketMean), countUnitsBetweenBtoC), triangleBase(Math.abs(previousBucketRefPoint - nextBucketMean), countUnitsBetweenAtoC));
77
- if (triangleArea > maxArea) {
78
- maxArea = triangleArea;
79
- maxAreaPoint = data[currentPointIndex];
80
- lastSelectedPointIndex = currentPointIndex;
81
- }
82
- }
83
- if (typeof maxAreaPoint !== 'undefined')
84
- result.push(maxAreaPoint);
85
- }
86
- result.push(data[data.length - 1]); // Always add the last point
87
- return result;
88
- }
89
- var triangleAreaHeron = function (a, b, c) {
90
- var s = (a + b + c) / 2;
91
- return Math.sqrt(s * (s - a) * (s - b) * (s - c));
92
- };
93
- var triangleBase = function (a, b) { return Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2)); };
94
- var mean = function (values) { return values.reduce(function (acc, value) { return acc + value; }, 0) / values.length; };
95
- var getNextBucketMean = function (data, currentBucketIndex, bucketSize) {
96
- var nextBucketStartIndex = Math.floor(currentBucketIndex * bucketSize) + 1;
97
- var nextNextBucketStartIndex = Math.floor((currentBucketIndex + 1) * bucketSize) + 1;
98
- nextNextBucketStartIndex =
99
- nextNextBucketStartIndex < data.length ? nextNextBucketStartIndex : data.length;
100
- return mean(data.slice(nextBucketStartIndex, nextNextBucketStartIndex));
101
- };
102
- export var upSample = function (values, targetSize) {
103
- if (!values.length) {
104
- console.warn('Cannot extend empty array of amplitudes.');
105
- return values;
106
- }
107
- if (values.length > targetSize) {
108
- console.warn('Requested to extend the waveformData that is longer than the target list size');
109
- return values;
110
- }
111
- if (targetSize === values.length)
112
- return values;
113
- // eslint-disable-next-line prefer-const
114
- var _a = divMod(targetSize, values.length), bucketSize = _a[0], remainder = _a[1];
115
- var result = [];
116
- for (var i = 0; i < values.length; i++) {
117
- var extra = remainder && remainder-- ? 1 : 0;
118
- result.push.apply(result, Array(bucketSize + extra).fill(values[i]));
119
- }
120
- return result;
121
- };
@@ -1,19 +1,27 @@
1
1
  export declare const elementIsPlaying: (audioElement: HTMLAudioElement | null) => boolean | null;
2
+ export type SeekFn = (params: {
3
+ clientX: number;
4
+ currentTarget: HTMLDivElement;
5
+ }) => void;
2
6
  type AudioControllerParams = {
3
7
  /** Audio duration in seconds. */
4
8
  durationSeconds?: number;
9
+ /** The audio MIME type that is checked before the audio is played. If the type is not supported the controller registers error in playbackError. */
10
+ mimeType?: string;
5
11
  /** An array of fractional numeric values of playback speed to override the defaults (1.0, 1.5, 2.0) */
6
12
  playbackRates?: number[];
7
13
  };
8
- export declare const useAudioController: ({ durationSeconds, playbackRates, }?: AudioControllerParams) => {
14
+ export declare const useAudioController: ({ durationSeconds, mimeType, playbackRates, }?: AudioControllerParams) => {
9
15
  audioRef: import("react").MutableRefObject<HTMLAudioElement | null>;
16
+ canPlayRecord: boolean;
10
17
  increasePlaybackRate: () => void;
11
18
  isPlaying: boolean;
19
+ playbackError: Error | undefined;
12
20
  playbackRate: number;
13
21
  progress: number;
14
22
  secondsElapsed: number;
15
- seek: import("react").MouseEventHandler<HTMLDivElement>;
16
- togglePlay: () => void;
23
+ seek: SeekFn;
24
+ togglePlay: () => Promise<void>;
17
25
  };
18
26
  export {};
19
27
  //# sourceMappingURL=useAudioController.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useAudioController.d.ts","sourceRoot":"","sources":["../../../../src/components/Attachment/hooks/useAudioController.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,gBAAgB,iBAAkB,gBAAgB,GAAG,IAAI,mBACR,CAAC;AAI/D,KAAK,qBAAqB,GAAG;IAC3B,iCAAiC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,kBAAkB,yCAG5B,qBAAqB;;;;;;;;;CAmFvB,CAAC"}
1
+ {"version":3,"file":"useAudioController.d.ts","sourceRoot":"","sources":["../../../../src/components/Attachment/hooks/useAudioController.ts"],"names":[],"mappings":"AAOA,eAAO,MAAM,gBAAgB,iBAAkB,gBAAgB,GAAG,IAAI,mBACR,CAAC;AAM/D,MAAM,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,cAAc,CAAA;CAAE,KAAK,IAAI,CAAC;AAE1F,KAAK,qBAAqB,GAAG;IAC3B,iCAAiC;IACjC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oJAAoJ;IACpJ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,uGAAuG;IACvG,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B,CAAC;AAEF,eAAO,MAAM,kBAAkB,mDAI5B,qBAAqB;;;;;;;;;;;CA8HvB,CAAC"}
@@ -1,29 +1,81 @@
1
- import { useCallback, useEffect, useRef, useState } from 'react';
1
+ import { __awaiter, __generator } from "tslib";
2
+ import throttle from 'lodash.throttle';
3
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
2
4
  import { useChannelActionContext, useTranslationContext } from '../../../context';
5
+ var isSeekable = function (audioElement) {
6
+ return !(audioElement.duration === Infinity || isNaN(audioElement.duration));
7
+ };
3
8
  export var elementIsPlaying = function (audioElement) {
4
9
  return audioElement && !(audioElement.paused || audioElement.ended);
5
10
  };
11
+ var logError = function (e) { return console.error('[AUDIO PLAYER]', e); };
6
12
  var DEFAULT_PLAYBACK_RATES = [1.0, 1.5, 2.0];
7
13
  export var useAudioController = function (_a) {
8
- var _b = _a === void 0 ? {} : _a, durationSeconds = _b.durationSeconds, _c = _b.playbackRates, playbackRates = _c === void 0 ? DEFAULT_PLAYBACK_RATES : _c;
14
+ var _b = _a === void 0 ? {} : _a, durationSeconds = _b.durationSeconds, mimeType = _b.mimeType, _c = _b.playbackRates, playbackRates = _c === void 0 ? DEFAULT_PLAYBACK_RATES : _c;
9
15
  var addNotification = useChannelActionContext('useAudioController').addNotification;
10
16
  var t = useTranslationContext('useAudioController').t;
11
17
  var _d = useState(false), isPlaying = _d[0], setIsPlaying = _d[1];
12
- var _e = useState(0), secondsElapsed = _e[0], setSecondsElapsed = _e[1];
13
- var _f = useState(0), playbackRateIndex = _f[0], setPlaybackRateIndex = _f[1];
18
+ var _e = useState(), playbackError = _e[0], setPlaybackError = _e[1];
19
+ var _f = useState(true), canPlayRecord = _f[0], setCanPlayRecord = _f[1];
20
+ var _g = useState(0), secondsElapsed = _g[0], setSecondsElapsed = _g[1];
21
+ var _h = useState(0), playbackRateIndex = _h[0], setPlaybackRateIndex = _h[1];
22
+ var playTimeout = useRef();
14
23
  var audioRef = useRef(null);
15
- var togglePlay = useCallback(function () {
16
- if (!audioRef.current)
17
- return;
18
- if (!elementIsPlaying(audioRef.current)) {
19
- audioRef.current.play();
20
- setIsPlaying(true);
21
- }
22
- else {
23
- audioRef.current.pause();
24
- setIsPlaying(false);
25
- }
26
- }, []);
24
+ var registerError = useCallback(function (e) {
25
+ logError(e);
26
+ setPlaybackError(e);
27
+ addNotification(e.message, 'error');
28
+ }, [addNotification]);
29
+ var togglePlay = useCallback(function () { return __awaiter(void 0, void 0, void 0, function () {
30
+ var e_1;
31
+ return __generator(this, function (_a) {
32
+ switch (_a.label) {
33
+ case 0:
34
+ if (!audioRef.current)
35
+ return [2 /*return*/];
36
+ clearTimeout(playTimeout.current);
37
+ playTimeout.current = undefined;
38
+ if (mimeType && !audioRef.current.canPlayType(mimeType)) {
39
+ registerError(new Error(t('Recording format is not supported and cannot be reproduced')));
40
+ setCanPlayRecord(false);
41
+ return [2 /*return*/];
42
+ }
43
+ if (!elementIsPlaying(audioRef.current)) return [3 /*break*/, 1];
44
+ audioRef.current.pause();
45
+ setIsPlaying(false);
46
+ return [3 /*break*/, 6];
47
+ case 1:
48
+ playTimeout.current = setTimeout(function () {
49
+ if (!audioRef.current)
50
+ return;
51
+ try {
52
+ audioRef.current.pause();
53
+ }
54
+ catch (e) {
55
+ registerError(new Error(t('Failed to play the recording')));
56
+ }
57
+ }, 2000);
58
+ _a.label = 2;
59
+ case 2:
60
+ _a.trys.push([2, 4, 5, 6]);
61
+ return [4 /*yield*/, audioRef.current.play()];
62
+ case 3:
63
+ _a.sent();
64
+ setIsPlaying(true);
65
+ return [3 /*break*/, 6];
66
+ case 4:
67
+ e_1 = _a.sent();
68
+ registerError(e_1);
69
+ setIsPlaying(false);
70
+ return [3 /*break*/, 6];
71
+ case 5:
72
+ clearTimeout(playTimeout.current);
73
+ playTimeout.current = undefined;
74
+ return [7 /*endfinally*/];
75
+ case 6: return [2 /*return*/];
76
+ }
77
+ });
78
+ }); }, [mimeType, registerError, t]);
27
79
  var increasePlaybackRate = function () {
28
80
  setPlaybackRateIndex(function (prev) {
29
81
  if (!audioRef.current)
@@ -33,16 +85,24 @@ export var useAudioController = function (_a) {
33
85
  return nextIndex;
34
86
  });
35
87
  };
36
- var seek = useCallback(function (_a) {
37
- var clientX = _a.clientX, currentTarget = _a.currentTarget;
38
- if (!audioRef.current)
39
- return;
40
- var _b = currentTarget.getBoundingClientRect(), width = _b.width, x = _b.x;
41
- var ratio = (clientX - x) / width;
42
- var currentTime = ratio * audioRef.current.duration;
43
- setSecondsElapsed(currentTime);
44
- audioRef.current.currentTime = currentTime;
45
- }, []);
88
+ var seek = useMemo(function () {
89
+ return throttle(function (_a) {
90
+ var clientX = _a.clientX, currentTarget = _a.currentTarget;
91
+ if (!(currentTarget && audioRef.current))
92
+ return;
93
+ if (!isSeekable(audioRef.current)) {
94
+ registerError(new Error(t('Cannot seek in the recording')));
95
+ return;
96
+ }
97
+ var _b = currentTarget.getBoundingClientRect(), width = _b.width, x = _b.x;
98
+ var ratio = (clientX - x) / width;
99
+ if (ratio > 1 || ratio < 0)
100
+ return;
101
+ var currentTime = ratio * audioRef.current.duration;
102
+ setSecondsElapsed(currentTime);
103
+ audioRef.current.currentTime = currentTime;
104
+ }, 16);
105
+ }, [registerError, t]);
46
106
  useEffect(function () {
47
107
  if (!audioRef.current)
48
108
  return;
@@ -55,6 +115,7 @@ export var useAudioController = function (_a) {
55
115
  audioElement.addEventListener('ended', handleEnded);
56
116
  var handleError = function () {
57
117
  addNotification(t('Error reproducing the recording'), 'error');
118
+ setIsPlaying(false);
58
119
  };
59
120
  audioElement.addEventListener('error', handleError);
60
121
  var handleTimeupdate = function () {
@@ -70,8 +131,10 @@ export var useAudioController = function (_a) {
70
131
  }, [addNotification, durationSeconds, t]);
71
132
  return {
72
133
  audioRef: audioRef,
134
+ canPlayRecord: canPlayRecord,
73
135
  increasePlaybackRate: increasePlaybackRate,
74
136
  isPlaying: isPlaying,
137
+ playbackError: playbackError,
75
138
  playbackRate: playbackRates[playbackRateIndex],
76
139
  progress: audioRef.current && secondsElapsed ? (secondsElapsed / audioRef.current.duration) * 100 : 0,
77
140
  secondsElapsed: secondsElapsed,
@@ -2,6 +2,7 @@ export * from './Attachment';
2
2
  export * from './AttachmentActions';
3
3
  export * from './AttachmentContainer';
4
4
  export * from './Audio';
5
+ export * from './audioSampling';
5
6
  export * from './Card';
6
7
  export * from './components';
7
8
  export * from './UnsupportedAttachment';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/components/Attachment/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,qBAAqB,CAAC;AACpC,cAAc,uBAAuB,CAAC;AACtC,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC;AAChC,cAAc,QAAQ,CAAC;AACvB,cAAc,cAAc,CAAC;AAC7B,cAAc,yBAAyB,CAAC;AACxC,cAAc,kBAAkB,CAAC;AACjC,cAAc,SAAS,CAAC"}
@@ -2,6 +2,7 @@ export * from './Attachment';
2
2
  export * from './AttachmentActions';
3
3
  export * from './AttachmentContainer';
4
4
  export * from './Audio';
5
+ export * from './audioSampling';
5
6
  export * from './Card';
6
7
  export * from './components';
7
8
  export * from './UnsupportedAttachment';
@@ -2,6 +2,7 @@ import React, { PropsWithChildren, ReactNode } from 'react';
2
2
  import type { Attachment } from 'stream-chat';
3
3
  import type { ATTACHMENT_GROUPS_ORDER, AttachmentProps } from './Attachment';
4
4
  import type { DefaultStreamChatGenerics } from '../../types/types';
5
+ import type { LocalAttachment, VoiceRecordingAttachment } from '../MessageInput';
5
6
  export declare const SUPPORTED_VIDEO_FORMATS: string[];
6
7
  export type AttachmentComponentType = typeof ATTACHMENT_GROUPS_ORDER[number];
7
8
  export type GroupedRenderedAttachment = Record<AttachmentComponentType, ReactNode[]>;
@@ -22,10 +23,11 @@ export type RenderGalleryProps<StreamChatGenerics extends DefaultStreamChatGener
22
23
  export declare const isScrapedContent: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => string | undefined;
23
24
  export declare const isUploadedImage: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => boolean;
24
25
  export declare const isGalleryAttachmentType: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(output: Attachment<StreamChatGenerics> | GalleryAttachment<StreamChatGenerics>) => output is GalleryAttachment<StreamChatGenerics>;
25
- export declare const isAudioAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => boolean;
26
- export declare const isVoiceRecordingAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => boolean;
26
+ export declare const isAudioAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics> | LocalAttachment<StreamChatGenerics>) => boolean;
27
+ export declare const isVoiceRecordingAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics> | LocalAttachment<StreamChatGenerics>) => attachment is VoiceRecordingAttachment<import("stream-chat").DefaultGenerics>;
28
+ export declare const isLocalAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: LocalAttachment<StreamChatGenerics>) => attachment is LocalAttachment<StreamChatGenerics>;
27
29
  export declare const isFileAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => boolean | "" | undefined;
28
- export declare const isMediaAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics>) => boolean;
30
+ export declare const isMediaAttachment: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(attachment: Attachment<StreamChatGenerics> | LocalAttachment<StreamChatGenerics>) => boolean;
29
31
  export declare const isSvgAttachment: (attachment: Attachment) => boolean;
30
32
  /**
31
33
  * @deprecated will be removed in the next major release,