stream-chat-react-native-core 9.2.0-beta.2 → 9.2.0-beta.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (386) hide show
  1. package/README.md +1 -1
  2. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js +2 -2
  3. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  4. package/lib/commonjs/components/Channel/Channel.js +10 -1
  5. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  6. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +26 -3
  7. package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  8. package/lib/commonjs/components/ChannelList/ChannelList.js +29 -4
  9. package/lib/commonjs/components/ChannelList/ChannelList.js.map +1 -1
  10. package/lib/commonjs/components/ChannelList/hooks/useChannelActions.js +314 -11
  11. package/lib/commonjs/components/ChannelList/hooks/useChannelActions.js.map +1 -1
  12. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +202 -15
  13. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  14. package/lib/commonjs/components/MessageInput/MessageComposer.js +1 -1
  15. package/lib/commonjs/components/MessageInput/MessageComposerLeadingView.js +1 -1
  16. package/lib/commonjs/components/MessageInput/MessageComposerLeadingView.js.map +1 -1
  17. package/lib/commonjs/components/MessageInput/MessageInputHeaderView.js +1 -1
  18. package/lib/commonjs/components/MessageInput/MessageInputHeaderView.js.map +1 -1
  19. package/lib/commonjs/components/MessageInput/MessageInputTrailingView.js +1 -1
  20. package/lib/commonjs/components/MessageInput/MessageInputTrailingView.js.map +1 -1
  21. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.js +7 -13
  22. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.js.map +1 -1
  23. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js +27 -6
  24. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -1
  25. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +29 -9
  26. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  27. package/lib/commonjs/components/MessageInput/components/OutputButtons/index.js +1 -1
  28. package/lib/commonjs/components/MessageList/MessageFlashList.js +5 -2
  29. package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -1
  30. package/lib/commonjs/components/MessageList/MessageList.js +5 -2
  31. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  32. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js +23 -2
  33. package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  34. package/lib/commonjs/components/Notifications/Notification.js +230 -0
  35. package/lib/commonjs/components/Notifications/Notification.js.map +1 -0
  36. package/lib/commonjs/components/Notifications/NotificationList.js +120 -0
  37. package/lib/commonjs/components/Notifications/NotificationList.js.map +1 -0
  38. package/lib/commonjs/components/Notifications/NotificationTargetContext.js +45 -0
  39. package/lib/commonjs/components/Notifications/NotificationTargetContext.js.map +1 -0
  40. package/lib/commonjs/components/Notifications/hooks/index.js +59 -0
  41. package/lib/commonjs/components/Notifications/hooks/index.js.map +1 -0
  42. package/lib/commonjs/components/Notifications/hooks/useNotificationApi.js +133 -0
  43. package/lib/commonjs/components/Notifications/hooks/useNotificationApi.js.map +1 -0
  44. package/lib/commonjs/components/Notifications/hooks/useNotificationListController.js +133 -0
  45. package/lib/commonjs/components/Notifications/hooks/useNotificationListController.js.map +1 -0
  46. package/lib/commonjs/components/Notifications/hooks/useNotificationTarget.js +26 -0
  47. package/lib/commonjs/components/Notifications/hooks/useNotificationTarget.js.map +1 -0
  48. package/lib/commonjs/components/Notifications/hooks/useNotifications.js +26 -0
  49. package/lib/commonjs/components/Notifications/hooks/useNotifications.js.map +1 -0
  50. package/lib/commonjs/components/Notifications/hooks/useSystemNotifications.js +22 -0
  51. package/lib/commonjs/components/Notifications/hooks/useSystemNotifications.js.map +1 -0
  52. package/lib/commonjs/components/Notifications/index.js +59 -0
  53. package/lib/commonjs/components/Notifications/index.js.map +1 -0
  54. package/lib/commonjs/components/Notifications/notificationTarget.js +220 -0
  55. package/lib/commonjs/components/Notifications/notificationTarget.js.map +1 -0
  56. package/lib/commonjs/components/Notifications/notificationTranslations.js +137 -0
  57. package/lib/commonjs/components/Notifications/notificationTranslations.js.map +1 -0
  58. package/lib/commonjs/components/Poll/components/PollOption.js +14 -9
  59. package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
  60. package/lib/commonjs/components/Poll/hooks/usePollState.js +35 -3
  61. package/lib/commonjs/components/Poll/hooks/usePollState.js.map +1 -1
  62. package/lib/commonjs/components/Thread/Thread.js +19 -11
  63. package/lib/commonjs/components/Thread/Thread.js.map +1 -1
  64. package/lib/commonjs/components/ThreadList/ThreadList.js +30 -9
  65. package/lib/commonjs/components/ThreadList/ThreadList.js.map +1 -1
  66. package/lib/commonjs/components/index.js +11 -0
  67. package/lib/commonjs/components/index.js.map +1 -1
  68. package/lib/commonjs/contexts/componentsContext/defaultComponents.js +4 -0
  69. package/lib/commonjs/contexts/componentsContext/defaultComponents.js.map +1 -1
  70. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +37 -0
  71. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  72. package/lib/commonjs/contexts/themeContext/utils/theme.js +13 -0
  73. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  74. package/lib/commonjs/hooks/index.js +11 -0
  75. package/lib/commonjs/hooks/index.js.map +1 -1
  76. package/lib/commonjs/hooks/useAudioPlayer.js +34 -1
  77. package/lib/commonjs/hooks/useAudioPlayer.js.map +1 -1
  78. package/lib/commonjs/hooks/useInAppNotificationsState.js.map +1 -1
  79. package/lib/commonjs/hooks/useLazyRef.js +13 -0
  80. package/lib/commonjs/hooks/useLazyRef.js.map +1 -0
  81. package/lib/commonjs/i18n/en.json +60 -1
  82. package/lib/commonjs/i18n/es.json +62 -3
  83. package/lib/commonjs/i18n/fr.json +60 -1
  84. package/lib/commonjs/i18n/he.json +60 -1
  85. package/lib/commonjs/i18n/hi.json +60 -1
  86. package/lib/commonjs/i18n/it.json +60 -1
  87. package/lib/commonjs/i18n/ja.json +60 -1
  88. package/lib/commonjs/i18n/ko.json +60 -1
  89. package/lib/commonjs/i18n/nl.json +60 -1
  90. package/lib/commonjs/i18n/pt-br.json +60 -1
  91. package/lib/commonjs/i18n/ru.json +60 -1
  92. package/lib/commonjs/i18n/tr.json +60 -1
  93. package/lib/commonjs/state-store/audio-player-pool.js +1 -0
  94. package/lib/commonjs/state-store/audio-player-pool.js.map +1 -1
  95. package/lib/commonjs/state-store/audio-player.js +92 -13
  96. package/lib/commonjs/state-store/audio-player.js.map +1 -1
  97. package/lib/commonjs/theme/generated/dark/StreamTokens.android.js +16 -16
  98. package/lib/commonjs/theme/generated/dark/StreamTokens.android.js.map +1 -1
  99. package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js +8 -8
  100. package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js.map +1 -1
  101. package/lib/commonjs/theme/generated/dark/StreamTokens.web.js +8 -8
  102. package/lib/commonjs/theme/generated/dark/StreamTokens.web.js.map +1 -1
  103. package/lib/commonjs/theme/generated/light/StreamTokens.android.js +16 -16
  104. package/lib/commonjs/theme/generated/light/StreamTokens.android.js.map +1 -1
  105. package/lib/commonjs/theme/generated/light/StreamTokens.ios.js +8 -8
  106. package/lib/commonjs/theme/generated/light/StreamTokens.ios.js.map +1 -1
  107. package/lib/commonjs/theme/generated/light/StreamTokens.web.js +8 -8
  108. package/lib/commonjs/theme/generated/light/StreamTokens.web.js.map +1 -1
  109. package/lib/commonjs/utils/animations/createBoundedZoomTransition.js +151 -0
  110. package/lib/commonjs/utils/animations/createBoundedZoomTransition.js.map +1 -0
  111. package/lib/commonjs/utils/{transitions.js → animations/transitions.js} +6 -0
  112. package/lib/commonjs/utils/animations/transitions.js.map +1 -0
  113. package/lib/commonjs/version.json +1 -1
  114. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js +2 -2
  115. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  116. package/lib/module/components/Channel/Channel.js +10 -1
  117. package/lib/module/components/Channel/Channel.js.map +1 -1
  118. package/lib/module/components/Channel/hooks/useMessageListPagination.js +26 -3
  119. package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -1
  120. package/lib/module/components/ChannelList/ChannelList.js +29 -4
  121. package/lib/module/components/ChannelList/ChannelList.js.map +1 -1
  122. package/lib/module/components/ChannelList/hooks/useChannelActions.js +314 -11
  123. package/lib/module/components/ChannelList/hooks/useChannelActions.js.map +1 -1
  124. package/lib/module/components/Message/hooks/useMessageActionHandlers.js +202 -15
  125. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  126. package/lib/module/components/MessageInput/MessageComposer.js +1 -1
  127. package/lib/module/components/MessageInput/MessageComposerLeadingView.js +1 -1
  128. package/lib/module/components/MessageInput/MessageComposerLeadingView.js.map +1 -1
  129. package/lib/module/components/MessageInput/MessageInputHeaderView.js +1 -1
  130. package/lib/module/components/MessageInput/MessageInputHeaderView.js.map +1 -1
  131. package/lib/module/components/MessageInput/MessageInputTrailingView.js +1 -1
  132. package/lib/module/components/MessageInput/MessageInputTrailingView.js.map +1 -1
  133. package/lib/module/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.js +7 -13
  134. package/lib/module/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.js.map +1 -1
  135. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js +27 -6
  136. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -1
  137. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +29 -9
  138. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  139. package/lib/module/components/MessageInput/components/OutputButtons/index.js +1 -1
  140. package/lib/module/components/MessageList/MessageFlashList.js +5 -2
  141. package/lib/module/components/MessageList/MessageFlashList.js.map +1 -1
  142. package/lib/module/components/MessageList/MessageList.js +5 -2
  143. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  144. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js +23 -2
  145. package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
  146. package/lib/module/components/Notifications/Notification.js +230 -0
  147. package/lib/module/components/Notifications/Notification.js.map +1 -0
  148. package/lib/module/components/Notifications/NotificationList.js +120 -0
  149. package/lib/module/components/Notifications/NotificationList.js.map +1 -0
  150. package/lib/module/components/Notifications/NotificationTargetContext.js +45 -0
  151. package/lib/module/components/Notifications/NotificationTargetContext.js.map +1 -0
  152. package/lib/module/components/Notifications/hooks/index.js +59 -0
  153. package/lib/module/components/Notifications/hooks/index.js.map +1 -0
  154. package/lib/module/components/Notifications/hooks/useNotificationApi.js +133 -0
  155. package/lib/module/components/Notifications/hooks/useNotificationApi.js.map +1 -0
  156. package/lib/module/components/Notifications/hooks/useNotificationListController.js +133 -0
  157. package/lib/module/components/Notifications/hooks/useNotificationListController.js.map +1 -0
  158. package/lib/module/components/Notifications/hooks/useNotificationTarget.js +26 -0
  159. package/lib/module/components/Notifications/hooks/useNotificationTarget.js.map +1 -0
  160. package/lib/module/components/Notifications/hooks/useNotifications.js +26 -0
  161. package/lib/module/components/Notifications/hooks/useNotifications.js.map +1 -0
  162. package/lib/module/components/Notifications/hooks/useSystemNotifications.js +22 -0
  163. package/lib/module/components/Notifications/hooks/useSystemNotifications.js.map +1 -0
  164. package/lib/module/components/Notifications/index.js +59 -0
  165. package/lib/module/components/Notifications/index.js.map +1 -0
  166. package/lib/module/components/Notifications/notificationTarget.js +220 -0
  167. package/lib/module/components/Notifications/notificationTarget.js.map +1 -0
  168. package/lib/module/components/Notifications/notificationTranslations.js +137 -0
  169. package/lib/module/components/Notifications/notificationTranslations.js.map +1 -0
  170. package/lib/module/components/Poll/components/PollOption.js +14 -9
  171. package/lib/module/components/Poll/components/PollOption.js.map +1 -1
  172. package/lib/module/components/Poll/hooks/usePollState.js +35 -3
  173. package/lib/module/components/Poll/hooks/usePollState.js.map +1 -1
  174. package/lib/module/components/Thread/Thread.js +19 -11
  175. package/lib/module/components/Thread/Thread.js.map +1 -1
  176. package/lib/module/components/ThreadList/ThreadList.js +30 -9
  177. package/lib/module/components/ThreadList/ThreadList.js.map +1 -1
  178. package/lib/module/components/index.js +11 -0
  179. package/lib/module/components/index.js.map +1 -1
  180. package/lib/module/contexts/componentsContext/defaultComponents.js +4 -0
  181. package/lib/module/contexts/componentsContext/defaultComponents.js.map +1 -1
  182. package/lib/module/contexts/messageInputContext/MessageInputContext.js +37 -0
  183. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  184. package/lib/module/contexts/themeContext/utils/theme.js +13 -0
  185. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  186. package/lib/module/hooks/index.js +11 -0
  187. package/lib/module/hooks/index.js.map +1 -1
  188. package/lib/module/hooks/useAudioPlayer.js +34 -1
  189. package/lib/module/hooks/useAudioPlayer.js.map +1 -1
  190. package/lib/module/hooks/useInAppNotificationsState.js.map +1 -1
  191. package/lib/module/hooks/useLazyRef.js +13 -0
  192. package/lib/module/hooks/useLazyRef.js.map +1 -0
  193. package/lib/module/i18n/en.json +60 -1
  194. package/lib/module/i18n/es.json +62 -3
  195. package/lib/module/i18n/fr.json +60 -1
  196. package/lib/module/i18n/he.json +60 -1
  197. package/lib/module/i18n/hi.json +60 -1
  198. package/lib/module/i18n/it.json +60 -1
  199. package/lib/module/i18n/ja.json +60 -1
  200. package/lib/module/i18n/ko.json +60 -1
  201. package/lib/module/i18n/nl.json +60 -1
  202. package/lib/module/i18n/pt-br.json +60 -1
  203. package/lib/module/i18n/ru.json +60 -1
  204. package/lib/module/i18n/tr.json +60 -1
  205. package/lib/module/state-store/audio-player-pool.js +1 -0
  206. package/lib/module/state-store/audio-player-pool.js.map +1 -1
  207. package/lib/module/state-store/audio-player.js +92 -13
  208. package/lib/module/state-store/audio-player.js.map +1 -1
  209. package/lib/module/theme/generated/dark/StreamTokens.android.js +16 -16
  210. package/lib/module/theme/generated/dark/StreamTokens.android.js.map +1 -1
  211. package/lib/module/theme/generated/dark/StreamTokens.ios.js +8 -8
  212. package/lib/module/theme/generated/dark/StreamTokens.ios.js.map +1 -1
  213. package/lib/module/theme/generated/dark/StreamTokens.web.js +8 -8
  214. package/lib/module/theme/generated/dark/StreamTokens.web.js.map +1 -1
  215. package/lib/module/theme/generated/light/StreamTokens.android.js +16 -16
  216. package/lib/module/theme/generated/light/StreamTokens.android.js.map +1 -1
  217. package/lib/module/theme/generated/light/StreamTokens.ios.js +8 -8
  218. package/lib/module/theme/generated/light/StreamTokens.ios.js.map +1 -1
  219. package/lib/module/theme/generated/light/StreamTokens.web.js +8 -8
  220. package/lib/module/theme/generated/light/StreamTokens.web.js.map +1 -1
  221. package/lib/module/utils/animations/createBoundedZoomTransition.js +151 -0
  222. package/lib/module/utils/animations/createBoundedZoomTransition.js.map +1 -0
  223. package/lib/module/utils/{transitions.js → animations/transitions.js} +6 -0
  224. package/lib/module/utils/animations/transitions.js.map +1 -0
  225. package/lib/module/version.json +1 -1
  226. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerContent.d.ts.map +1 -1
  227. package/lib/typescript/components/Channel/Channel.d.ts +1 -0
  228. package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
  229. package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -1
  230. package/lib/typescript/components/ChannelList/ChannelList.d.ts +1 -0
  231. package/lib/typescript/components/ChannelList/ChannelList.d.ts.map +1 -1
  232. package/lib/typescript/components/ChannelList/hooks/useChannelActions.d.ts.map +1 -1
  233. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  234. package/lib/typescript/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.d.ts.map +1 -1
  235. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecorder.d.ts.map +1 -1
  236. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingButton.d.ts.map +1 -1
  237. package/lib/typescript/components/MessageList/MessageFlashList.d.ts.map +1 -1
  238. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  239. package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
  240. package/lib/typescript/components/Notifications/Notification.d.ts +31 -0
  241. package/lib/typescript/components/Notifications/Notification.d.ts.map +1 -0
  242. package/lib/typescript/components/Notifications/NotificationList.d.ts +28 -0
  243. package/lib/typescript/components/Notifications/NotificationList.d.ts.map +1 -0
  244. package/lib/typescript/components/Notifications/NotificationTargetContext.d.ts +14 -0
  245. package/lib/typescript/components/Notifications/NotificationTargetContext.d.ts.map +1 -0
  246. package/lib/typescript/components/Notifications/hooks/index.d.ts +6 -0
  247. package/lib/typescript/components/Notifications/hooks/index.d.ts.map +1 -0
  248. package/lib/typescript/components/Notifications/hooks/useNotificationApi.d.ts +48 -0
  249. package/lib/typescript/components/Notifications/hooks/useNotificationApi.d.ts.map +1 -0
  250. package/lib/typescript/components/Notifications/hooks/useNotificationListController.d.ts +14 -0
  251. package/lib/typescript/components/Notifications/hooks/useNotificationListController.d.ts.map +1 -0
  252. package/lib/typescript/components/Notifications/hooks/useNotificationTarget.d.ts +3 -0
  253. package/lib/typescript/components/Notifications/hooks/useNotificationTarget.d.ts.map +1 -0
  254. package/lib/typescript/components/Notifications/hooks/useNotifications.d.ts +14 -0
  255. package/lib/typescript/components/Notifications/hooks/useNotifications.d.ts.map +1 -0
  256. package/lib/typescript/components/Notifications/hooks/useSystemNotifications.d.ts +9 -0
  257. package/lib/typescript/components/Notifications/hooks/useSystemNotifications.d.ts.map +1 -0
  258. package/lib/typescript/components/Notifications/index.d.ts +6 -0
  259. package/lib/typescript/components/Notifications/index.d.ts.map +1 -0
  260. package/lib/typescript/components/Notifications/notificationTarget.d.ts +55 -0
  261. package/lib/typescript/components/Notifications/notificationTarget.d.ts.map +1 -0
  262. package/lib/typescript/components/Notifications/notificationTranslations.d.ts +7 -0
  263. package/lib/typescript/components/Notifications/notificationTranslations.d.ts.map +1 -0
  264. package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
  265. package/lib/typescript/components/Poll/hooks/usePollState.d.ts.map +1 -1
  266. package/lib/typescript/components/Thread/Thread.d.ts +1 -0
  267. package/lib/typescript/components/Thread/Thread.d.ts.map +1 -1
  268. package/lib/typescript/components/ThreadList/ThreadList.d.ts +3 -1
  269. package/lib/typescript/components/ThreadList/ThreadList.d.ts.map +1 -1
  270. package/lib/typescript/components/index.d.ts +1 -0
  271. package/lib/typescript/components/index.d.ts.map +1 -1
  272. package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts +3 -0
  273. package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts.map +1 -1
  274. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
  275. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts +13 -0
  276. package/lib/typescript/contexts/themeContext/ThemeContext.d.ts.map +1 -1
  277. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +13 -0
  278. package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
  279. package/lib/typescript/hooks/index.d.ts +1 -0
  280. package/lib/typescript/hooks/index.d.ts.map +1 -1
  281. package/lib/typescript/hooks/useAudioPlayer.d.ts.map +1 -1
  282. package/lib/typescript/hooks/useInAppNotificationsState.d.ts +6 -0
  283. package/lib/typescript/hooks/useInAppNotificationsState.d.ts.map +1 -1
  284. package/lib/typescript/hooks/useLazyRef.d.ts +7 -0
  285. package/lib/typescript/hooks/useLazyRef.d.ts.map +1 -0
  286. package/lib/typescript/i18n/en.json +60 -1
  287. package/lib/typescript/i18n/es.json +62 -3
  288. package/lib/typescript/i18n/fr.json +60 -1
  289. package/lib/typescript/i18n/he.json +60 -1
  290. package/lib/typescript/i18n/hi.json +60 -1
  291. package/lib/typescript/i18n/it.json +60 -1
  292. package/lib/typescript/i18n/ja.json +60 -1
  293. package/lib/typescript/i18n/ko.json +60 -1
  294. package/lib/typescript/i18n/nl.json +60 -1
  295. package/lib/typescript/i18n/pt-br.json +60 -1
  296. package/lib/typescript/i18n/ru.json +60 -1
  297. package/lib/typescript/i18n/tr.json +60 -1
  298. package/lib/typescript/state-store/audio-player-pool.d.ts.map +1 -1
  299. package/lib/typescript/state-store/audio-player.d.ts +13 -0
  300. package/lib/typescript/state-store/audio-player.d.ts.map +1 -1
  301. package/lib/typescript/utils/animations/createBoundedZoomTransition.d.ts +21 -0
  302. package/lib/typescript/utils/animations/createBoundedZoomTransition.d.ts.map +1 -0
  303. package/lib/typescript/utils/animations/transitions.d.ts +21 -0
  304. package/lib/typescript/utils/animations/transitions.d.ts.map +1 -0
  305. package/lib/typescript/utils/i18n/Streami18n.d.ts +59 -0
  306. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  307. package/package.json +2 -2
  308. package/src/components/AttachmentPicker/components/AttachmentPickerContent.tsx +3 -3
  309. package/src/components/AttachmentPicker/components/__tests__/AttachmentPickerContent.test.tsx +19 -18
  310. package/src/components/Channel/Channel.tsx +15 -1
  311. package/src/components/Channel/__tests__/useMessageListPagination.test.tsx +34 -2
  312. package/src/components/Channel/hooks/useMessageListPagination.tsx +19 -3
  313. package/src/components/ChannelList/ChannelList.tsx +27 -5
  314. package/src/components/ChannelList/hooks/__tests__/useChannelActions.test.tsx +123 -0
  315. package/src/components/ChannelList/hooks/useChannelActions.ts +181 -12
  316. package/src/components/Message/hooks/__tests__/useMessageActionHandlers.test.tsx +131 -0
  317. package/src/components/Message/hooks/useMessageActionHandlers.ts +133 -23
  318. package/src/components/MessageInput/MessageComposer.tsx +1 -1
  319. package/src/components/MessageInput/MessageComposerLeadingView.tsx +1 -1
  320. package/src/components/MessageInput/MessageInputHeaderView.tsx +1 -1
  321. package/src/components/MessageInput/MessageInputTrailingView.tsx +1 -1
  322. package/src/components/MessageInput/components/AttachmentPreview/AttachmentUploadPreviewList.tsx +1 -10
  323. package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx +10 -2
  324. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +27 -13
  325. package/src/components/MessageInput/components/OutputButtons/index.tsx +1 -1
  326. package/src/components/MessageList/MessageFlashList.tsx +3 -1
  327. package/src/components/MessageList/MessageList.tsx +3 -1
  328. package/src/components/MessageList/__tests__/MessageList.test.tsx +35 -0
  329. package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.tsx.snap +1 -1
  330. package/src/components/MessageMenu/hooks/useFetchReactions.ts +17 -2
  331. package/src/components/Notifications/Notification.tsx +253 -0
  332. package/src/components/Notifications/NotificationList.tsx +160 -0
  333. package/src/components/Notifications/NotificationTargetContext.tsx +45 -0
  334. package/src/components/Notifications/__tests__/NotificationList.test.tsx +480 -0
  335. package/src/components/Notifications/__tests__/notificationTarget.test.ts +157 -0
  336. package/src/components/Notifications/hooks/__tests__/useNotificationApi.test.tsx +172 -0
  337. package/src/components/Notifications/hooks/__tests__/useNotificationTarget.test.tsx +85 -0
  338. package/src/components/Notifications/hooks/index.ts +5 -0
  339. package/src/components/Notifications/hooks/useNotificationApi.ts +248 -0
  340. package/src/components/Notifications/hooks/useNotificationListController.ts +160 -0
  341. package/src/components/Notifications/hooks/useNotificationTarget.ts +37 -0
  342. package/src/components/Notifications/hooks/useNotifications.ts +43 -0
  343. package/src/components/Notifications/hooks/useSystemNotifications.ts +33 -0
  344. package/src/components/Notifications/index.ts +5 -0
  345. package/src/components/Notifications/notificationTarget.ts +305 -0
  346. package/src/components/Notifications/notificationTranslations.ts +142 -0
  347. package/src/components/Poll/components/PollOption.tsx +10 -6
  348. package/src/components/Poll/hooks/usePollState.ts +26 -2
  349. package/src/components/Thread/Thread.tsx +24 -16
  350. package/src/components/ThreadList/ThreadList.tsx +33 -9
  351. package/src/components/index.ts +2 -0
  352. package/src/contexts/componentsContext/defaultComponents.ts +4 -0
  353. package/src/contexts/messageInputContext/MessageInputContext.tsx +36 -0
  354. package/src/contexts/themeContext/utils/theme.ts +26 -0
  355. package/src/hooks/index.ts +1 -0
  356. package/src/hooks/useAudioPlayer.ts +44 -3
  357. package/src/hooks/useInAppNotificationsState.ts +6 -0
  358. package/src/hooks/useLazyRef.ts +15 -0
  359. package/src/i18n/en.json +60 -1
  360. package/src/i18n/es.json +62 -3
  361. package/src/i18n/fr.json +60 -1
  362. package/src/i18n/he.json +60 -1
  363. package/src/i18n/hi.json +60 -1
  364. package/src/i18n/it.json +60 -1
  365. package/src/i18n/ja.json +60 -1
  366. package/src/i18n/ko.json +60 -1
  367. package/src/i18n/nl.json +60 -1
  368. package/src/i18n/pt-br.json +60 -1
  369. package/src/i18n/ru.json +60 -1
  370. package/src/i18n/tr.json +60 -1
  371. package/src/state-store/__tests__/audio-player.test.ts +45 -0
  372. package/src/state-store/audio-player-pool.ts +1 -0
  373. package/src/state-store/audio-player.ts +108 -16
  374. package/src/theme/generated/dark/StreamTokens.android.ts +16 -16
  375. package/src/theme/generated/dark/StreamTokens.ios.ts +8 -8
  376. package/src/theme/generated/dark/StreamTokens.web.ts +8 -8
  377. package/src/theme/generated/light/StreamTokens.android.ts +16 -16
  378. package/src/theme/generated/light/StreamTokens.ios.ts +8 -8
  379. package/src/theme/generated/light/StreamTokens.web.ts +8 -8
  380. package/src/utils/animations/createBoundedZoomTransition.ts +117 -0
  381. package/src/utils/{transitions.ts → animations/transitions.ts} +6 -0
  382. package/src/version.json +1 -1
  383. package/lib/commonjs/utils/transitions.js.map +0 -1
  384. package/lib/module/utils/transitions.js.map +0 -1
  385. package/lib/typescript/utils/transitions.d.ts +0 -9
  386. package/lib/typescript/utils/transitions.d.ts.map +0 -1
@@ -0,0 +1,142 @@
1
+ import type { TFunction } from 'i18next';
2
+ import type { Notification } from 'stream-chat';
3
+
4
+ const normalizeReason = (notification?: Notification) => {
5
+ const reason = notification?.metadata?.reason;
6
+ if (typeof reason !== 'string' || !reason.length) return undefined;
7
+
8
+ return reason.toLowerCase();
9
+ };
10
+
11
+ const withReasonFallback = ({
12
+ fallbackTranslationKey,
13
+ notification,
14
+ reasonTranslationKey,
15
+ t,
16
+ }: {
17
+ fallbackTranslationKey: string;
18
+ notification?: Notification;
19
+ reasonTranslationKey: string;
20
+ t: TFunction;
21
+ }) => {
22
+ const reason = normalizeReason(notification);
23
+ if (!reason) return t(fallbackTranslationKey);
24
+
25
+ return t(reasonTranslationKey, { reason });
26
+ };
27
+
28
+ const translateAttachmentUploadBlocked = ({
29
+ notification,
30
+ t,
31
+ }: {
32
+ notification?: Notification;
33
+ t: TFunction;
34
+ }) => {
35
+ const rawReason = notification?.metadata?.reason;
36
+ let reason = t('unsupported file type');
37
+ if (typeof rawReason !== 'string') reason = t('unknown error');
38
+ if (rawReason === 'size_limit') reason = t('size limit');
39
+
40
+ return t('Attachment upload blocked due to {{reason}}', { reason });
41
+ };
42
+
43
+ const translateAttachmentUploadFailed = ({
44
+ notification,
45
+ t,
46
+ }: {
47
+ notification?: Notification;
48
+ t: TFunction;
49
+ }) =>
50
+ withReasonFallback({
51
+ fallbackTranslationKey: 'Error uploading attachment',
52
+ notification,
53
+ reasonTranslationKey: 'Attachment upload failed due to {{reason}}',
54
+ t,
55
+ });
56
+
57
+ const translatePollCreateFailed = ({
58
+ notification,
59
+ t,
60
+ }: {
61
+ notification?: Notification;
62
+ t: TFunction;
63
+ }) =>
64
+ withReasonFallback({
65
+ fallbackTranslationKey: 'Failed to create the poll',
66
+ notification,
67
+ reasonTranslationKey: 'Failed to create the poll due to {{reason}}',
68
+ t,
69
+ });
70
+
71
+ const translatePollEndFailed = ({
72
+ notification,
73
+ t,
74
+ }: {
75
+ notification?: Notification;
76
+ t: TFunction;
77
+ }) =>
78
+ withReasonFallback({
79
+ fallbackTranslationKey: 'Failed to end the poll',
80
+ notification,
81
+ reasonTranslationKey: 'Failed to end the poll due to {{reason}}',
82
+ t,
83
+ });
84
+
85
+ const translateCommandDisabled = ({
86
+ notification,
87
+ t,
88
+ }: {
89
+ notification?: Notification;
90
+ t: TFunction;
91
+ }) => {
92
+ const reason = normalizeReason(notification);
93
+
94
+ if (reason === 'editing') {
95
+ return t('Command not available while editing');
96
+ }
97
+
98
+ if (reason === 'quoted_message') {
99
+ return t('Command not available while replying');
100
+ }
101
+
102
+ return t(notification?.message || 'Command not available');
103
+ };
104
+
105
+ const notificationTranslatorsByType: Record<
106
+ string,
107
+ (options: { notification: Notification; t: TFunction }) => string
108
+ > = {
109
+ 'api:attachment:upload:failed': translateAttachmentUploadFailed,
110
+ 'api:location:create:failed': ({ t }) => t('Failed to share location'),
111
+ 'api:location:share:failed': ({ t }) => t('Failed to share location'),
112
+ 'api:poll:create:failed': translatePollCreateFailed,
113
+ 'api:poll:end:failed': translatePollEndFailed,
114
+ 'api:poll:end:success': ({ t }) => t('Poll ended'),
115
+ 'api:reply:search:failed': ({ t }) => t('Thread has not been found'),
116
+ 'browser:audio:playback:error': ({ notification, t }) =>
117
+ notification.message ? t(notification.message) : t('Error reproducing the recording'),
118
+ 'browser:location:get:failed': ({ t }) => t('Failed to retrieve location'),
119
+ 'channel:jumpToFirstUnread:failed': ({ t }) => t('Failed to jump to the first unread message'),
120
+ 'validation:attachment:file:missing': ({ t }) => t('File is required for upload attachment'),
121
+ 'validation:attachment:id:missing': ({ t }) => t('Local upload attachment missing local id'),
122
+ 'validation:attachment:upload:blocked': translateAttachmentUploadBlocked,
123
+ 'validation:attachment:upload:in-progress': ({ t }) =>
124
+ t('Wait until all attachments have uploaded'),
125
+ 'validation:command:disabled': translateCommandDisabled,
126
+ 'validation:poll:castVote:limit': ({ t }) =>
127
+ t('Reached the vote limit. Remove an existing vote first.'),
128
+ };
129
+
130
+ export const getNotificationDisplayMessage = ({
131
+ notification,
132
+ t,
133
+ }: {
134
+ notification: Notification;
135
+ t: TFunction;
136
+ }) => {
137
+ const translator = notification.type
138
+ ? notificationTranslatorsByType[notification.type]
139
+ : undefined;
140
+
141
+ return translator ? translator({ notification, t }) : t(notification.message);
142
+ };
@@ -20,6 +20,7 @@ import { useComponentsContext } from '../../../contexts/componentsContext/Compon
20
20
 
21
21
  import { Check } from '../../../icons';
22
22
  import { primitives } from '../../../theme';
23
+ import { useNotificationApi } from '../../Notifications';
23
24
  import { ProgressBar } from '../../ProgressControl/ProgressBar';
24
25
  import { UserAvatarStack } from '../../ui/Avatar/AvatarStack';
25
26
  import { useIsPollCreatedByCurrentUser } from '../hook/useIsPollCreatedByCurrentUser';
@@ -160,6 +161,7 @@ export const PollOption = ({ option, showProgressBar = true, forceIncoming }: Po
160
161
  export const VoteButton = ({ onPress, option }: PollVoteButtonProps) => {
161
162
  const { message, poll } = usePollContext();
162
163
  const { isClosed, ownVotesByOptionId } = usePollState();
164
+ const { runWithNotificationTarget } = useNotificationApi();
163
165
  const ownCapabilities = useOwnCapabilitiesContext();
164
166
  const {
165
167
  theme: { semantics },
@@ -178,12 +180,14 @@ export const VoteButton = ({ onPress, option }: PollVoteButtonProps) => {
178
180
  } = useTheme();
179
181
 
180
182
  const toggleVote = useCallback(async () => {
181
- if (ownVotesByOptionId[option.id]) {
182
- await poll.removeVote(ownVotesByOptionId[option.id]?.id, message.id);
183
- } else {
184
- await poll.castVote(option.id, message.id);
185
- }
186
- }, [message.id, option.id, ownVotesByOptionId, poll]);
183
+ await runWithNotificationTarget(async () => {
184
+ if (ownVotesByOptionId[option.id]) {
185
+ await poll.removeVote(ownVotesByOptionId[option.id]?.id, message.id);
186
+ } else {
187
+ await poll.castVote(option.id, message.id);
188
+ }
189
+ });
190
+ }, [message.id, option.id, ownVotesByOptionId, poll, runWithNotificationTarget]);
187
191
 
188
192
  const onPressHandler = useCallback(() => {
189
193
  if (onPress) {
@@ -14,7 +14,8 @@ import {
14
14
 
15
15
  import { usePollStateStore } from './usePollStateStore';
16
16
 
17
- import { usePollContext } from '../../../contexts';
17
+ import { usePollContext, useTranslationContext } from '../../../contexts';
18
+ import { useNotificationApi } from '../../Notifications';
18
19
 
19
20
  export type UsePollStateSelectorReturnType = {
20
21
  allowAnswers: boolean | undefined;
@@ -62,6 +63,8 @@ const selector = (nextValue: PollState): UsePollStateSelectorReturnType => ({
62
63
 
63
64
  export const usePollState = (): UsePollStateReturnType => {
64
65
  const { message, poll } = usePollContext();
66
+ const { addNotification } = useNotificationApi();
67
+ const { t } = useTranslationContext();
65
68
  const {
66
69
  allowAnswers,
67
70
  allowUserSuggestedOptions,
@@ -91,7 +94,28 @@ export const usePollState = (): UsePollStateReturnType => {
91
94
  (answerText: string) => poll.addAnswer(answerText, message.id),
92
95
  [message.id, poll],
93
96
  );
94
- const endVote = useCallback(() => poll.close(), [poll]);
97
+ const endVote = useCallback(async () => {
98
+ try {
99
+ const response = await poll.close();
100
+ addNotification({
101
+ message: t('Poll ended'),
102
+ options: { severity: 'success', type: 'api:poll:end:success' },
103
+ origin: { emitter: 'PollActions' },
104
+ });
105
+ return response;
106
+ } catch (error) {
107
+ addNotification({
108
+ message: t('Failed to end the poll'),
109
+ options: {
110
+ ...(error instanceof Error ? { originalError: error } : {}),
111
+ severity: 'error',
112
+ type: 'api:poll:end:failed',
113
+ },
114
+ origin: { emitter: 'PollActions' },
115
+ });
116
+ throw error;
117
+ }
118
+ }, [addNotification, poll, t]);
95
119
 
96
120
  return {
97
121
  addComment,
@@ -10,6 +10,8 @@ import { ThreadContextValue, useThreadContext } from '../../contexts/threadConte
10
10
  import type { MessageComposerProps } from '../MessageInput/MessageComposer';
11
11
  import { MessageFlashList, MessageFlashListProps } from '../MessageList/MessageFlashList';
12
12
  import { MessageListProps } from '../MessageList/MessageList';
13
+ import { getThreadNotificationHostId } from '../Notifications/notificationTarget';
14
+ import { NotificationTargetProvider } from '../Notifications/NotificationTargetContext';
13
15
 
14
16
  let FlashList;
15
17
 
@@ -56,6 +58,7 @@ type ThreadPropsWithContext = Pick<ChatContextValue, 'client'> &
56
58
  * Call custom function on closing thread if handling thread state elsewhere
57
59
  */
58
60
  onThreadDismount?: () => void;
61
+ notificationHostId?: string;
59
62
  shouldUseFlashList?: boolean;
60
63
  };
61
64
 
@@ -70,6 +73,7 @@ const ThreadWithContext = (props: ThreadPropsWithContext) => {
70
73
  disabled,
71
74
  loadMoreThread,
72
75
  onThreadDismount,
76
+ notificationHostId: notificationHostIdProp,
73
77
  parentMessagePreventPress = true,
74
78
  thread,
75
79
  threadInstance,
@@ -120,26 +124,30 @@ const ThreadWithContext = (props: ThreadPropsWithContext) => {
120
124
  return null;
121
125
  }
122
126
 
127
+ const notificationHostId = notificationHostIdProp ?? getThreadNotificationHostId(thread.id);
128
+
123
129
  return (
124
130
  <React.Fragment key={`thread-${thread.id}`}>
125
- {FlashList && shouldUseFlashList ? (
126
- <MessageFlashList
127
- HeaderComponent={MemoizedThreadFooterComponent}
128
- threadList
129
- {...additionalMessageFlashListProps}
130
- />
131
- ) : (
132
- <MessageList
133
- FooterComponent={MemoizedThreadFooterComponent}
131
+ <NotificationTargetProvider hostId={notificationHostId} panel='thread'>
132
+ {FlashList && shouldUseFlashList ? (
133
+ <MessageFlashList
134
+ HeaderComponent={MemoizedThreadFooterComponent}
135
+ threadList
136
+ {...additionalMessageFlashListProps}
137
+ />
138
+ ) : (
139
+ <MessageList
140
+ FooterComponent={MemoizedThreadFooterComponent}
141
+ threadList
142
+ {...additionalMessageListProps}
143
+ />
144
+ )}
145
+ <MessageComposer
146
+ additionalTextInputProps={additionalTextInputProps}
134
147
  threadList
135
- {...additionalMessageListProps}
148
+ {...additionalMessageComposerProps}
136
149
  />
137
- )}
138
- <MessageComposer
139
- additionalTextInputProps={additionalTextInputProps}
140
- threadList
141
- {...additionalMessageComposerProps}
142
- />
150
+ </NotificationTargetProvider>
143
151
  </React.Fragment>
144
152
  );
145
153
  };
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect } from 'react';
2
- import { FlatList, View } from 'react-native';
2
+ import { FlatList, StyleSheet, View } from 'react-native';
3
3
 
4
4
  import { Thread, ThreadManagerState } from 'stream-chat';
5
5
 
@@ -14,9 +14,12 @@ import {
14
14
  useThreadsContext,
15
15
  } from '../../contexts/threadsContext/ThreadsContext';
16
16
  import { useStateStore } from '../../hooks';
17
+ import { useLazyRef } from '../../hooks/useLazyRef';
18
+ import { generateRandomId } from '../../utils/utils';
17
19
 
18
20
  import { EmptyStateIndicator } from '../Indicators/EmptyStateIndicator';
19
21
  import { LoadingIndicator } from '../Indicators/LoadingIndicator';
22
+ import { NotificationTargetProvider } from '../Notifications/NotificationTargetContext';
20
23
 
21
24
  const selector = (nextValue: ThreadManagerState) =>
22
25
  ({
@@ -28,7 +31,9 @@ const selector = (nextValue: ThreadManagerState) =>
28
31
  export type ThreadListProps = Pick<
29
32
  ThreadsContextValue,
30
33
  'additionalFlatListProps' | 'isFocused' | 'onThreadSelect'
31
- >;
34
+ > & {
35
+ notificationHostId?: string;
36
+ };
32
37
 
33
38
  export const DefaultThreadListEmptyPlaceholder = () => <EmptyStateIndicator listType='threads' />;
34
39
 
@@ -76,9 +81,11 @@ export const DefaultThreadListComponent = () => {
76
81
  };
77
82
 
78
83
  export const ThreadList = (props: ThreadListProps) => {
79
- const { isFocused = true } = props;
80
- const { ThreadListComponent: ThreadListContent } = useComponentsContext();
84
+ const { isFocused = true, notificationHostId: notificationHostIdProp } = props;
85
+ const { NotificationList, ThreadListComponent: ThreadListContent } = useComponentsContext();
81
86
  const { client } = useChatContext();
87
+ const fallbackNotificationHostIdRef = useLazyRef(() => `thread-list:${generateRandomId()}`);
88
+ const notificationHostId = notificationHostIdProp ?? fallbackNotificationHostIdRef.current;
82
89
 
83
90
  useEffect(() => {
84
91
  if (!client) {
@@ -109,10 +116,27 @@ export const ThreadList = (props: ThreadListProps) => {
109
116
  const { isLoading, isLoadingNext, threads } = useStateStore(client.threads.state, selector);
110
117
 
111
118
  return (
112
- <ThreadsProvider
113
- value={{ isLoading, isLoadingNext, loadMore: client.threads.loadNextPage, threads, ...props }}
114
- >
115
- <ThreadListContent />
116
- </ThreadsProvider>
119
+ <NotificationTargetProvider hostId={notificationHostId} panel='thread-list'>
120
+ <ThreadsProvider
121
+ value={{
122
+ isLoading,
123
+ isLoadingNext,
124
+ loadMore: client.threads.loadNextPage,
125
+ threads,
126
+ ...props,
127
+ }}
128
+ >
129
+ <View style={styles.container}>
130
+ <ThreadListContent />
131
+ <NotificationList />
132
+ </View>
133
+ </ThreadsProvider>
134
+ </NotificationTargetProvider>
117
135
  );
118
136
  };
137
+
138
+ const styles = StyleSheet.create({
139
+ container: {
140
+ flex: 1,
141
+ },
142
+ });
@@ -175,6 +175,8 @@ export * from './MessageMenu/MessageReactionPicker';
175
175
  export * from './MessageMenu/utils/toUnicodeScalarString';
176
176
  export * from './MessageMenu/hooks/useFetchReactions';
177
177
 
178
+ export * from './Notifications';
179
+
178
180
  export * from './ProgressControl/ProgressControl';
179
181
  export * from './ProgressControl/WaveProgressBar';
180
182
  export * from './Poll';
@@ -130,6 +130,7 @@ import { MessageReactionPicker } from '../../components/MessageMenu/MessageReact
130
130
  import { MessageUserReactions } from '../../components/MessageMenu/MessageUserReactions';
131
131
  import { MessageUserReactionsAvatar } from '../../components/MessageMenu/MessageUserReactionsAvatar';
132
132
  import { MessageUserReactionsItem } from '../../components/MessageMenu/MessageUserReactionsItem';
133
+ import { Notification, NotificationIcon, NotificationList } from '../../components/Notifications';
133
134
  import { PollAnswersListContent } from '../../components/Poll/components/PollAnswersList';
134
135
  import { PollButtons } from '../../components/Poll/components/PollButtons';
135
136
  import { PollAllOptionsContent } from '../../components/Poll/components/PollOption';
@@ -245,6 +246,9 @@ const components = {
245
246
  MessageUserReactionsAvatar,
246
247
  MessageUserReactionsItem,
247
248
  NetworkDownIndicator,
249
+ Notification,
250
+ NotificationIcon,
251
+ NotificationList,
248
252
  ChannelPreview: ChannelPreviewView,
249
253
  ChannelPreviewAvatar: ChannelAvatar,
250
254
  ChannelPreviewLastMessage: ChannelLastMessagePreview,
@@ -26,6 +26,7 @@ import { useMessageComposer } from './hooks/useMessageComposer';
26
26
  import { dismissKeyboard } from '../../components/KeyboardCompatibleView/KeyboardControllerAvoidingView';
27
27
  import { parseLinksFromText } from '../../components/Message/MessageItemView/utils/parseLinks';
28
28
  import { useAudioRecorder } from '../../components/MessageInput/hooks/useAudioRecorder';
29
+ import { useNotificationApi } from '../../components/Notifications';
29
30
  import { useStableCallback } from '../../hooks/useStableCallback';
30
31
  import {
31
32
  createAttachmentsCompositionMiddleware,
@@ -220,6 +221,7 @@ export const MessageInputProvider = ({
220
221
  const { clearEditingState } = useMessageComposerAPIContext();
221
222
  const { thread } = useThreadContext();
222
223
  const { t } = useTranslationContext();
224
+ const { addNotification } = useNotificationApi();
223
225
  const inputBoxRef = useRef<InputBoxRef | null>(null);
224
226
 
225
227
  const [showPollCreationDialog, setShowPollCreationDialog] = useState(false);
@@ -407,6 +409,23 @@ export const MessageInputProvider = ({
407
409
  clearEditingState();
408
410
  await value.editMessage({ localMessage, options: sendOptions });
409
411
  } catch (error) {
412
+ addNotification(
413
+ {
414
+ message: t('Edit message request failed'),
415
+ options: {
416
+ ...(error instanceof Error ? { originalError: error } : {}),
417
+ severity: 'error',
418
+ },
419
+ origin: { emitter: 'MessageComposer' },
420
+ },
421
+ {
422
+ incident: {
423
+ domain: 'api',
424
+ entity: 'message',
425
+ operation: 'edit',
426
+ },
427
+ },
428
+ );
410
429
  throw new Error('Error while editing message');
411
430
  }
412
431
  } else {
@@ -433,6 +452,23 @@ export const MessageInputProvider = ({
433
452
  options: sendOptions,
434
453
  });
435
454
  } catch (error) {
455
+ addNotification(
456
+ {
457
+ message: t('Send message request failed'),
458
+ options: {
459
+ ...(error instanceof Error ? { originalError: error } : {}),
460
+ severity: 'error',
461
+ },
462
+ origin: { emitter: 'MessageComposer' },
463
+ },
464
+ {
465
+ incident: {
466
+ domain: 'api',
467
+ entity: 'message',
468
+ operation: 'send',
469
+ },
470
+ },
471
+ );
436
472
  throw new Error('Error while sending message');
437
473
  }
438
474
  }
@@ -532,6 +532,19 @@ export type Theme = {
532
532
  rightButtonContainer: ViewStyle;
533
533
  };
534
534
  };
535
+ notification: {
536
+ actionButton: ViewStyle;
537
+ actionButtonText: TextStyle;
538
+ actionsContainer: ViewStyle;
539
+ closeButton: ViewStyle;
540
+ container: ViewStyle;
541
+ contentContainer: ViewStyle;
542
+ iconContainer: ViewStyle;
543
+ message: TextStyle;
544
+ };
545
+ notificationList: {
546
+ container: ViewStyle;
547
+ };
535
548
  messageMenu: {
536
549
  actionList: {
537
550
  container: ViewStyle;
@@ -1457,6 +1470,19 @@ export const defaultTheme: Theme = {
1457
1470
  },
1458
1471
  unreadMessagesNotificationContainer: {},
1459
1472
  },
1473
+ notification: {
1474
+ actionButton: {},
1475
+ actionButtonText: {},
1476
+ actionsContainer: {},
1477
+ closeButton: {},
1478
+ container: {},
1479
+ contentContainer: {},
1480
+ iconContainer: {},
1481
+ message: {},
1482
+ },
1483
+ notificationList: {
1484
+ container: {},
1485
+ },
1460
1486
  messageMenu: {
1461
1487
  actionList: {
1462
1488
  container: {},
@@ -12,6 +12,7 @@ export * from './useQueryReminders';
12
12
  export * from './useAfterKeyboardOpenCallback';
13
13
  export * from './useClientNotifications';
14
14
  export * from './useInAppNotificationsState';
15
+ export * from '../components/Notifications/hooks';
15
16
  export * from './usePortalSettledCallback';
16
17
  export * from './useRAFCoalescedValue';
17
18
  export * from './useAudioPlayer';
@@ -1,7 +1,10 @@
1
- import { useMemo } from 'react';
1
+ import { useCallback, useMemo } from 'react';
2
2
 
3
+ import { useNotificationApi } from '../components/Notifications';
3
4
  import { useAudioPlayerContext } from '../contexts/audioPlayerContext/AudioPlayerContext';
4
- import { AudioPlayerOptions } from '../state-store/audio-player';
5
+ import { useChatContext } from '../contexts/chatContext/ChatContext';
6
+ import { useTranslationContext } from '../contexts/translationContext/TranslationContext';
7
+ import { AudioPlayerErrorCode, AudioPlayerOptions } from '../state-store/audio-player';
5
8
 
6
9
  export type UseAudioPlayerProps = {
7
10
  /**
@@ -40,19 +43,57 @@ export const useAudioPlayer = ({
40
43
  id: fileId,
41
44
  }: UseAudioPlayerProps) => {
42
45
  const { audioPlayerPool } = useAudioPlayerContext();
46
+ const { addNotification } = useNotificationApi();
47
+ const { client } = useChatContext();
48
+ const { t } = useTranslationContext();
49
+ const hasNotificationManager = !!client?.notifications;
43
50
  const id = makeAudioPlayerId({ id: fileId, requester, src: uri ?? '' });
51
+ const onError = useCallback(
52
+ ({ errCode, error }: { errCode: AudioPlayerErrorCode; error?: Error }) => {
53
+ if (!hasNotificationManager) return;
54
+
55
+ const errorMessages: Record<AudioPlayerErrorCode, string> = {
56
+ 'failed-to-start': t('Failed to play the recording'),
57
+ 'not-playable': t('Recording format is not supported and cannot be reproduced'),
58
+ 'seek-not-supported': t('Cannot seek in the recording'),
59
+ };
60
+ const message = errorMessages[errCode];
61
+
62
+ addNotification({
63
+ message,
64
+ options: {
65
+ originalError: error ?? new Error(message),
66
+ severity: 'error',
67
+ type: 'browser:audio:playback:error',
68
+ },
69
+ origin: { emitter: 'AudioPlayer' },
70
+ });
71
+ },
72
+ [addNotification, hasNotificationManager, t],
73
+ );
44
74
  const audioPlayer = useMemo(
45
75
  () =>
46
76
  audioPlayerPool?.getOrAddPlayer({
47
77
  duration: duration ?? 0,
48
78
  id,
49
79
  mimeType: mimeType ?? '',
80
+ onError,
50
81
  playbackRates,
51
82
  previewVoiceRecording,
52
83
  type: type ?? 'audio',
53
84
  uri: uri ?? '',
54
85
  }),
55
- [audioPlayerPool, duration, id, mimeType, playbackRates, previewVoiceRecording, type, uri],
86
+ [
87
+ audioPlayerPool,
88
+ duration,
89
+ id,
90
+ mimeType,
91
+ onError,
92
+ playbackRates,
93
+ previewVoiceRecording,
94
+ type,
95
+ uri,
96
+ ],
56
97
  );
57
98
 
58
99
  return audioPlayer;
@@ -14,6 +14,12 @@ const selector = ({ notifications }: InAppNotificationsState) => ({
14
14
  notifications,
15
15
  });
16
16
 
17
+ /**
18
+ * @deprecated Prefer the client-backed notification APIs exported from
19
+ * `components/Notifications` (`useNotificationApi`, `useNotifications`, and
20
+ * `NotificationList`). This hook is kept for apps that already render their own
21
+ * legacy in-app notification store.
22
+ */
17
23
  export const useInAppNotificationsState = () => {
18
24
  const { notifications } = useStateStore(inAppNotificationsStore, selector);
19
25
 
@@ -0,0 +1,15 @@
1
+ import { type RefObject, useRef } from 'react';
2
+
3
+ /**
4
+ * Creates a stable ref whose initial value is computed only once.
5
+ * Use this when the initial ref value is expensive or allocates an object.
6
+ */
7
+ export const useLazyRef = <T>(getInitialValue: () => T) => {
8
+ const ref = useRef<T | null>(null);
9
+
10
+ if (ref.current === null) {
11
+ ref.current = getInitialValue();
12
+ }
13
+
14
+ return ref as RefObject<T>;
15
+ };