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

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 +232 -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 +232 -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 +254 -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
@@ -1,27 +1,31 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { fireEvent, render, screen } from '@testing-library/react-native';
4
- import type { CommandSuggestion } from 'stream-chat';
5
-
6
- import {
7
- AttachmentCommandNativePickerItem,
8
- AttachmentCommandPickerItem,
9
- } from '../AttachmentPickerContent';
4
+ import { type CommandSuggestion, notifyCommandDisabled } from 'stream-chat';
10
5
 
11
6
  jest.mock('stream-chat', () => ({
12
7
  CommandSearchSource: jest.fn(() => ({
13
8
  query: jest.fn(() => ({ items: [] })),
14
9
  })),
10
+ notifyCommandDisabled: jest.fn(),
15
11
  }));
16
12
 
13
+ import {
14
+ AttachmentCommandNativePickerItem,
15
+ AttachmentCommandPickerItem,
16
+ } from '../AttachmentPickerContent';
17
+
17
18
  jest.mock('../AttachmentMediaPicker/AttachmentMediaPicker', () => ({
18
19
  AttachmentMediaPicker: () => null,
19
20
  }));
20
21
 
22
+ const mockNotifyCommandDisabled = jest.mocked(notifyCommandDisabled);
21
23
  const mockClose = jest.fn((callback?: () => void) => callback?.());
22
24
  const mockFocus = jest.fn();
23
- const mockIsCommandDisabled = jest.fn();
24
25
  const mockSetCommand = jest.fn();
26
+ const mockMessageComposer = {
27
+ textComposer: { setCommand: mockSetCommand },
28
+ };
25
29
 
26
30
  jest.mock('../../../../contexts', () => ({
27
31
  useAttachmentPickerContext: jest.fn(() => ({
@@ -30,10 +34,7 @@ jest.mock('../../../../contexts', () => ({
30
34
  useBottomSheetContext: jest.fn(() => ({
31
35
  close: mockClose,
32
36
  })),
33
- useMessageComposer: jest.fn(() => ({
34
- isCommandDisabled: mockIsCommandDisabled,
35
- textComposer: { setCommand: mockSetCommand },
36
- })),
37
+ useMessageComposer: jest.fn(() => mockMessageComposer),
37
38
  useMessageInputContext: jest.fn(() => ({
38
39
  inputBoxRef: { current: { focus: mockFocus } },
39
40
  })),
@@ -73,30 +74,30 @@ describe('AttachmentPickerContent commands', () => {
73
74
  beforeEach(() => {
74
75
  mockClose.mockClear();
75
76
  mockFocus.mockClear();
76
- mockIsCommandDisabled.mockReset();
77
+ mockNotifyCommandDisabled.mockReset();
77
78
  mockSetCommand.mockClear();
78
79
  });
79
80
 
80
- it('does not focus the input when a disabled command is pressed', () => {
81
- mockIsCommandDisabled.mockReturnValue(true);
81
+ it('does not focus the input when a disabled command notification is emitted', () => {
82
+ mockNotifyCommandDisabled.mockReturnValue(true);
82
83
 
83
84
  render(<AttachmentCommandPickerItem item={command} />);
84
85
 
85
86
  fireEvent.press(screen.getByText('ban'));
86
87
 
87
- expect(mockIsCommandDisabled).toHaveBeenCalledWith(command);
88
+ expect(mockNotifyCommandDisabled).toHaveBeenCalledWith(mockMessageComposer, command);
88
89
  expect(mockSetCommand).not.toHaveBeenCalled();
89
90
  expect(mockFocus).not.toHaveBeenCalled();
90
91
  });
91
92
 
92
- it('does not close the picker or focus the input when a disabled command is pressed in native picker mode', () => {
93
- mockIsCommandDisabled.mockReturnValue(true);
93
+ it('does not close the picker or focus the input when a disabled command notification is emitted in native picker mode', () => {
94
+ mockNotifyCommandDisabled.mockReturnValue(true);
94
95
 
95
96
  render(<AttachmentCommandNativePickerItem item={command} />);
96
97
 
97
98
  fireEvent.press(screen.getByText('ban'));
98
99
 
99
- expect(mockIsCommandDisabled).toHaveBeenCalledWith(command);
100
+ expect(mockNotifyCommandDisabled).toHaveBeenCalledWith(mockMessageComposer, command);
100
101
  expect(mockSetCommand).not.toHaveBeenCalled();
101
102
  expect(mockClose).not.toHaveBeenCalled();
102
103
  expect(mockFocus).not.toHaveBeenCalled();
@@ -118,6 +118,8 @@ import type { KeyboardCompatibleViewProps } from '../KeyboardCompatibleView/Keyb
118
118
  import { Emoji } from '../MessageMenu/EmojiPickerList';
119
119
  import { emojis } from '../MessageMenu/emojis';
120
120
  import { toUnicodeScalarString } from '../MessageMenu/utils/toUnicodeScalarString';
121
+ import { getChannelNotificationHostId } from '../Notifications/notificationTarget';
122
+ import { NotificationTargetProvider } from '../Notifications/NotificationTargetContext';
121
123
 
122
124
  export type MarkReadFunctionOptions = {
123
125
  /**
@@ -352,6 +354,7 @@ export type ChannelPropsWithContext = Pick<ChannelContextValue, 'channel'> &
352
354
  * Load the channel at a specified message instead of the most recent message.
353
355
  */
354
356
  messageId?: string;
357
+ notificationHostId?: string;
355
358
  /**
356
359
  * @deprecated
357
360
  * The time interval for throttling while updating the message state
@@ -1789,6 +1792,9 @@ export type ChannelProps = Partial<Omit<ChannelPropsWithContext, 'channel' | 'th
1789
1792
  export const Channel = (props: PropsWithChildren<ChannelProps>) => {
1790
1793
  const { client, enableOfflineSupport, isOnline, isMessageAIGenerated } = useChatContext();
1791
1794
  const { t } = useTranslationContext();
1795
+ const notificationHostId =
1796
+ props.notificationHostId ??
1797
+ (props.channel?.cid ? getChannelNotificationHostId(props.channel.cid) : undefined);
1792
1798
 
1793
1799
  const threadFromProps = props?.thread;
1794
1800
  const threadInstance = (threadFromProps as ThreadType)?.threadInstance as Thread;
@@ -1808,7 +1814,7 @@ export const Channel = (props: PropsWithChildren<ChannelProps>) => {
1808
1814
  props.threadList ? threadMessage?.id : undefined,
1809
1815
  );
1810
1816
 
1811
- return (
1817
+ const channelWithContext = (
1812
1818
  <ChannelWithContext
1813
1819
  {...{
1814
1820
  client,
@@ -1826,6 +1832,14 @@ export const Channel = (props: PropsWithChildren<ChannelProps>) => {
1826
1832
  }}
1827
1833
  />
1828
1834
  );
1835
+
1836
+ return notificationHostId ? (
1837
+ <NotificationTargetProvider hostId={notificationHostId} panel='channel'>
1838
+ {channelWithContext}
1839
+ </NotificationTargetProvider>
1840
+ ) : (
1841
+ channelWithContext
1842
+ );
1829
1843
  };
1830
1844
 
1831
1845
  const useStyles = () => {
@@ -1,16 +1,30 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+
1
3
  import { act, cleanup, renderHook, waitFor } from '@testing-library/react-native';
2
4
  import type { Channel as ChannelType, LocalMessage, StreamChat } from 'stream-chat';
3
5
 
6
+ import { ChatProvider } from '../../../contexts/chatContext/ChatContext';
4
7
  import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
5
8
  import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
6
9
  import { generateChannelResponse } from '../../../mock-builders/generator/channel';
7
10
  import { generateMessage } from '../../../mock-builders/generator/message';
8
11
  import { generateUser } from '../../../mock-builders/generator/user';
9
12
  import { getTestClientWithUser } from '../../../mock-builders/mock';
13
+ import { NotificationTargetProvider } from '../../Notifications/NotificationTargetContext';
10
14
  import { channelInitialState } from '../hooks/useChannelDataState';
11
15
  import * as ChannelStateHooks from '../hooks/useChannelDataState';
12
16
  import { useMessageListPagination } from '../hooks/useMessageListPagination';
13
17
 
18
+ const createChatWrapper =
19
+ (client: StreamChat) =>
20
+ ({ children }: PropsWithChildren) => (
21
+ <ChatProvider value={{ client } as never}>
22
+ <NotificationTargetProvider hostId='channel:messaging:general' panel='channel'>
23
+ {children}
24
+ </NotificationTargetProvider>
25
+ </ChatProvider>
26
+ );
27
+
14
28
  describe('useMessageListPagination', () => {
15
29
  let chatClient: StreamChat;
16
30
  let channel: ChannelType;
@@ -618,7 +632,7 @@ describe('useMessageListPagination', () => {
618
632
  };
619
633
 
620
634
  // Mock query if needed
621
- const queryMock = jest.fn();
635
+ const queryMock = jest.fn().mockResolvedValue({ messages: [] });
622
636
  channel.query = queryMock as unknown as typeof channel.query;
623
637
 
624
638
  // Set up mocks
@@ -626,9 +640,12 @@ describe('useMessageListPagination', () => {
626
640
  mockedHook(channelInitialState, { jumpToMessageFinished: jumpToMessageFinishedMock });
627
641
  const setChannelUnreadStateMock = jest.fn();
628
642
  const setTargetedMessageIdMock = jest.fn((message) => message);
643
+ const addNotificationSpy = jest.spyOn(chatClient.notifications, 'add');
629
644
 
630
645
  // Render hook
631
- const { result } = renderHook(() => useMessageListPagination({ channel }));
646
+ const { result } = renderHook(() => useMessageListPagination({ channel }), {
647
+ wrapper: createChatWrapper(chatClient),
648
+ });
632
649
 
633
650
  // Act
634
651
  await act(async () => {
@@ -642,6 +659,21 @@ describe('useMessageListPagination', () => {
642
659
  // Assert
643
660
  await waitFor(() => {
644
661
  expect(queryMock).toHaveBeenCalledTimes(expectedQueryCalls);
662
+ if (expectedQueryCalls) {
663
+ expect(addNotificationSpy).toHaveBeenCalledWith({
664
+ message: 'Failed to jump to the first unread message',
665
+ options: {
666
+ originalError: expect.any(Error),
667
+ severity: 'error',
668
+ tags: ['target:channel:channel:messaging:general'],
669
+ type: 'channel:jumpToFirstUnread:failed',
670
+ },
671
+ origin: {
672
+ context: { feature: 'jumpToFirstUnread' },
673
+ emitter: 'Channel',
674
+ },
675
+ });
676
+ }
645
677
  expect(jumpToMessageFinishedMock).toHaveBeenCalledTimes(
646
678
  expectedJumpToMessageFinishedCalls,
647
679
  );
@@ -6,8 +6,10 @@ import { Channel, ChannelState, MessageResponse } from 'stream-chat';
6
6
  import { useChannelMessageDataState } from './useChannelDataState';
7
7
 
8
8
  import { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext';
9
+ import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
9
10
  import { useStableCallback } from '../../../hooks';
10
11
  import { findInMessagesByDate, findInMessagesById } from '../../../utils/utils';
12
+ import { useNotificationApi } from '../../Notifications';
11
13
 
12
14
  const defaultDebounceInterval = 500;
13
15
  const debounceOptions = {
@@ -22,6 +24,8 @@ const debounceOptions = {
22
24
  * @param channel The channel object for which the message list pagination is being handled.
23
25
  */
24
26
  export const useMessageListPagination = ({ channel }: { channel: Channel }) => {
27
+ const { addNotification } = useNotificationApi();
28
+ const { t } = useTranslationContext();
25
29
  const {
26
30
  copyMessagesStateFromChannel,
27
31
  jumpToLatestMessage,
@@ -180,6 +184,18 @@ export const useMessageListPagination = ({ channel }: { channel: Channel }) => {
180
184
  },
181
185
  );
182
186
 
187
+ const notifyJumpToFirstUnreadError = useStableCallback((error: unknown) => {
188
+ addNotification({
189
+ message: t('Failed to jump to the first unread message'),
190
+ options: {
191
+ ...(error instanceof Error ? { originalError: error } : {}),
192
+ severity: 'error',
193
+ type: 'channel:jumpToFirstUnread:failed',
194
+ },
195
+ origin: { context: { feature: 'jumpToFirstUnread' }, emitter: 'Channel' },
196
+ });
197
+ });
198
+
183
199
  /**
184
200
  * Loads channel at first unread message.
185
201
  */
@@ -225,7 +241,7 @@ export const useMessageListPagination = ({ channel }: { channel: Channel }) => {
225
241
  } catch (error) {
226
242
  setLoading(false);
227
243
  loadMoreFinished(channel.state.messagePagination.hasPrev, messagesState);
228
- console.log('Loading channel at first unread message failed with error:', error);
244
+ notifyJumpToFirstUnreadError(error);
229
245
  return;
230
246
  }
231
247
 
@@ -275,7 +291,7 @@ export const useMessageListPagination = ({ channel }: { channel: Channel }) => {
275
291
  } catch (error) {
276
292
  setLoading(false);
277
293
  loadMoreFinished(channel.state.messagePagination.hasPrev, channel.state.messages);
278
- console.log('Loading channel at first unread message failed with error:', error);
294
+ notifyJumpToFirstUnreadError(error);
279
295
  return;
280
296
  }
281
297
  }
@@ -296,7 +312,7 @@ export const useMessageListPagination = ({ channel }: { channel: Channel }) => {
296
312
  setTargetedMessage(firstUnreadMessageId);
297
313
  }
298
314
  } catch (error) {
299
- console.log('Loading channel at first unread message failed with error:', error);
315
+ notifyJumpToFirstUnreadError(error);
300
316
  }
301
317
  },
302
318
  );
@@ -1,5 +1,6 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
2
 
3
+ import { StyleSheet, View } from 'react-native';
3
4
  import type { FlatList } from 'react-native-gesture-handler';
4
5
 
5
6
  import {
@@ -21,8 +22,12 @@ import {
21
22
  ChannelsProvider,
22
23
  } from '../../contexts/channelsContext/ChannelsContext';
23
24
  import { useChatContext } from '../../contexts/chatContext/ChatContext';
25
+ import { useComponentsContext } from '../../contexts/componentsContext/ComponentsContext';
24
26
  import { SwipeRegistryProvider } from '../../contexts/swipeableContext/SwipeRegistryContext';
27
+ import { useLazyRef } from '../../hooks/useLazyRef';
25
28
  import type { ChannelListEventListenerOptions } from '../../types/types';
29
+ import { generateRandomId } from '../../utils/utils';
30
+ import { NotificationTargetProvider } from '../Notifications/NotificationTargetContext';
26
31
 
27
32
  export type ChannelListProps = Partial<
28
33
  Pick<
@@ -206,6 +211,7 @@ export type ChannelListProps = Partial<
206
211
  * - The return type has to be Channel[] (which is the return type of StreamChat.queryChannels)
207
212
  */
208
213
  queryChannelsOverride?: QueryChannelsRequestType;
214
+ notificationHostId?: string;
209
215
  };
210
216
 
211
217
  const DEFAULT_FILTERS = {};
@@ -244,12 +250,16 @@ export const ChannelList = (props: ChannelListProps) => {
244
250
  setFlatListRef,
245
251
  sort = DEFAULT_SORT,
246
252
  queryChannelsOverride,
253
+ notificationHostId: notificationHostIdProp,
247
254
  mutedStatusPosition = 'inlineTitle',
248
255
  swipeActionsEnabled = true,
249
256
  } = props;
250
257
 
251
258
  const [forceUpdate, setForceUpdate] = useState(0);
259
+ const fallbackNotificationHostIdRef = useLazyRef(() => `channel-list:${generateRandomId()}`);
260
+ const notificationHostId = notificationHostIdProp ?? fallbackNotificationHostIdRef.current;
252
261
  const { client, enableOfflineSupport } = useChatContext();
262
+ const { NotificationList } = useComponentsContext();
253
263
  const channelManager = useMemo(() => client.createChannelManager({}), [client]);
254
264
 
255
265
  /**
@@ -368,10 +378,22 @@ export const ChannelList = (props: ChannelListProps) => {
368
378
  });
369
379
 
370
380
  return (
371
- <ChannelsProvider value={channelsContext}>
372
- <SwipeRegistryProvider>
373
- <ChannelListView />
374
- </SwipeRegistryProvider>
375
- </ChannelsProvider>
381
+ <NotificationTargetProvider hostId={notificationHostId} panel='channel-list'>
382
+ <ChannelsProvider value={channelsContext}>
383
+ <SwipeRegistryProvider>
384
+ <View style={styles.container}>
385
+ <ChannelListView />
386
+ <NotificationList />
387
+ </View>
388
+ </SwipeRegistryProvider>
389
+ </ChannelsProvider>
390
+ </NotificationTargetProvider>
376
391
  );
377
392
  };
393
+
394
+ const styles = StyleSheet.create({
395
+ container: {
396
+ backgroundColor: 'transparent',
397
+ flex: 1,
398
+ },
399
+ });
@@ -0,0 +1,123 @@
1
+ import React, { PropsWithChildren } from 'react';
2
+
3
+ import { act, renderHook } from '@testing-library/react-native';
4
+ import type { Channel } from 'stream-chat';
5
+
6
+ import { ChatProvider } from '../../../../contexts/chatContext/ChatContext';
7
+ import { useChannelActions } from '../useChannelActions';
8
+
9
+ const createWrapper =
10
+ (client: unknown) =>
11
+ ({ children }: PropsWithChildren) => (
12
+ <ChatProvider value={{ client } as never}>{children}</ChatProvider>
13
+ );
14
+
15
+ const createClient = () => ({
16
+ blockUser: jest.fn(),
17
+ notifications: {
18
+ add: jest.fn(),
19
+ remove: jest.fn(),
20
+ startTimeout: jest.fn(),
21
+ },
22
+ muteUser: jest.fn(),
23
+ unBlockUser: jest.fn(),
24
+ unmuteUser: jest.fn(),
25
+ userID: 'current-user-id',
26
+ });
27
+
28
+ const createChannel = (client: ReturnType<typeof createClient>) =>
29
+ ({
30
+ archive: jest.fn(),
31
+ getClient: () => client,
32
+ mute: jest.fn(),
33
+ pin: jest.fn(),
34
+ removeMembers: jest.fn(),
35
+ state: {
36
+ members: {
37
+ current: { user: { id: 'current-user-id' } },
38
+ other: { user: { id: 'other-user-id', name: 'Other User' } },
39
+ },
40
+ },
41
+ unarchive: jest.fn(),
42
+ unmute: jest.fn(),
43
+ unpin: jest.fn(),
44
+ }) as unknown as Channel;
45
+
46
+ describe('useChannelActions', () => {
47
+ it('notifies when channel mute succeeds', async () => {
48
+ const client = createClient();
49
+ const channel = createChannel(client);
50
+ const { result } = renderHook(() => useChannelActions(channel), {
51
+ wrapper: createWrapper(client),
52
+ });
53
+
54
+ await act(async () => {
55
+ await result.current.muteChannel();
56
+ });
57
+
58
+ expect(channel.mute).toHaveBeenCalledTimes(1);
59
+ expect(client.notifications.add).toHaveBeenCalledWith({
60
+ message: 'Channel muted',
61
+ options: {
62
+ severity: 'success',
63
+ type: 'api:channel:mute:success',
64
+ },
65
+ origin: {
66
+ context: { channel },
67
+ emitter: 'ChannelActions',
68
+ },
69
+ });
70
+ });
71
+
72
+ it('notifies when channel mute fails', async () => {
73
+ const error = new Error('mute failed');
74
+ const client = createClient();
75
+ const channel = createChannel(client);
76
+ jest.mocked(channel.mute).mockRejectedValue(error);
77
+ const { result } = renderHook(() => useChannelActions(channel), {
78
+ wrapper: createWrapper(client),
79
+ });
80
+
81
+ await act(async () => {
82
+ await result.current.muteChannel();
83
+ });
84
+
85
+ expect(client.notifications.add).toHaveBeenCalledWith({
86
+ message: 'Failed to update channel mute status',
87
+ options: {
88
+ originalError: error,
89
+ severity: 'error',
90
+ type: 'api:channel:mute:failed',
91
+ },
92
+ origin: {
93
+ context: { channel },
94
+ emitter: 'ChannelActions',
95
+ },
96
+ });
97
+ });
98
+
99
+ it('notifies when a direct channel user is blocked', async () => {
100
+ const client = createClient();
101
+ const channel = createChannel(client);
102
+ const { result } = renderHook(() => useChannelActions(channel), {
103
+ wrapper: createWrapper(client),
104
+ });
105
+
106
+ await act(async () => {
107
+ await result.current.blockUser();
108
+ });
109
+
110
+ expect(client.blockUser).toHaveBeenCalledWith('other-user-id');
111
+ expect(client.notifications.add).toHaveBeenCalledWith({
112
+ message: 'User blocked',
113
+ options: {
114
+ severity: 'success',
115
+ type: 'api:user:block:success',
116
+ },
117
+ origin: {
118
+ context: { channel },
119
+ emitter: 'ChannelActions',
120
+ },
121
+ });
122
+ });
123
+ });