stream-chat-react-native-core 9.3.1-beta.6 → 9.3.1-beta.8

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 (329) hide show
  1. package/lib/commonjs/a11y/hooks/useAnnounceOnShow.js +27 -0
  2. package/lib/commonjs/a11y/hooks/useAnnounceOnShow.js.map +1 -0
  3. package/lib/commonjs/a11y/index.js +11 -0
  4. package/lib/commonjs/a11y/index.js.map +1 -1
  5. package/lib/commonjs/components/Accessibility/CompositeAccessibilityProbe.js +29 -0
  6. package/lib/commonjs/components/Accessibility/CompositeAccessibilityProbe.js.map +1 -0
  7. package/lib/commonjs/components/Accessibility/HiddenA11yText.js +30 -0
  8. package/lib/commonjs/components/Accessibility/HiddenA11yText.js.map +1 -0
  9. package/lib/commonjs/components/Accessibility/OverlayA11yShield.js +37 -0
  10. package/lib/commonjs/components/Accessibility/OverlayA11yShield.js.map +1 -0
  11. package/lib/commonjs/components/Accessibility/index.js +22 -0
  12. package/lib/commonjs/components/Accessibility/index.js.map +1 -1
  13. package/lib/commonjs/components/Attachment/Gallery.js +10 -0
  14. package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
  15. package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +31 -29
  16. package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
  17. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js +11 -5
  18. package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
  19. package/lib/commonjs/components/ChannelPreview/ChannelPreviewStatus.js +18 -2
  20. package/lib/commonjs/components/ChannelPreview/ChannelPreviewStatus.js.map +1 -1
  21. package/lib/commonjs/components/ChannelPreview/ChannelPreviewUnreadCount.js +8 -2
  22. package/lib/commonjs/components/ChannelPreview/ChannelPreviewUnreadCount.js.map +1 -1
  23. package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js +3 -0
  24. package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
  25. package/lib/commonjs/components/ImageGallery/ImageGallery.js +56 -1
  26. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  27. package/lib/commonjs/components/Message/MessageItemView/Headers/MessageReminderHeader.js +2 -0
  28. package/lib/commonjs/components/Message/MessageItemView/Headers/MessageReminderHeader.js.map +1 -1
  29. package/lib/commonjs/components/Message/MessageItemView/Headers/SentToChannelHeader.js +2 -0
  30. package/lib/commonjs/components/Message/MessageItemView/Headers/SentToChannelHeader.js.map +1 -1
  31. package/lib/commonjs/components/Message/MessageItemView/MessageContent.js +26 -4
  32. package/lib/commonjs/components/Message/MessageItemView/MessageContent.js.map +1 -1
  33. package/lib/commonjs/components/Message/MessageItemView/MessageFooter.js +2 -0
  34. package/lib/commonjs/components/Message/MessageItemView/MessageFooter.js.map +1 -1
  35. package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js +7 -3
  36. package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js.map +1 -1
  37. package/lib/commonjs/components/Message/MessageItemView/MessageRepliesAvatars.js +2 -0
  38. package/lib/commonjs/components/Message/MessageItemView/MessageRepliesAvatars.js.map +1 -1
  39. package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js +35 -30
  40. package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js.map +1 -1
  41. package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js +16 -6
  42. package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
  43. package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListClustered.js +19 -6
  44. package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListClustered.js.map +1 -1
  45. package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListItem.js +10 -1
  46. package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListItem.js.map +1 -1
  47. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +6 -1
  48. package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  49. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +8 -0
  50. package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  51. package/lib/commonjs/components/MessageList/InlineDateSeparator.js +8 -1
  52. package/lib/commonjs/components/MessageList/InlineDateSeparator.js.map +1 -1
  53. package/lib/commonjs/components/MessageMenu/ReactionButton.js +0 -7
  54. package/lib/commonjs/components/MessageMenu/ReactionButton.js.map +1 -1
  55. package/lib/commonjs/components/Poll/Poll.js +2 -17
  56. package/lib/commonjs/components/Poll/Poll.js.map +1 -1
  57. package/lib/commonjs/components/Poll/components/PollOption.js +6 -1
  58. package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
  59. package/lib/commonjs/components/Reply/Reply.js +43 -6
  60. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  61. package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js +17 -11
  62. package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js.map +1 -1
  63. package/lib/commonjs/components/ui/Badge/BadgeNotification.js +3 -1
  64. package/lib/commonjs/components/ui/Badge/BadgeNotification.js.map +1 -1
  65. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js +6 -22
  66. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
  67. package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
  68. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +1 -0
  69. package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  70. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +4 -1
  71. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  72. package/lib/commonjs/i18n/ar.json +26 -8
  73. package/lib/commonjs/i18n/en.json +23 -5
  74. package/lib/commonjs/i18n/es.json +23 -5
  75. package/lib/commonjs/i18n/fr.json +23 -5
  76. package/lib/commonjs/i18n/he.json +23 -5
  77. package/lib/commonjs/i18n/hi.json +24 -6
  78. package/lib/commonjs/i18n/it.json +23 -5
  79. package/lib/commonjs/i18n/ja.json +23 -5
  80. package/lib/commonjs/i18n/ko.json +23 -5
  81. package/lib/commonjs/i18n/nl.json +24 -6
  82. package/lib/commonjs/i18n/pt-br.json +25 -7
  83. package/lib/commonjs/i18n/ru.json +23 -5
  84. package/lib/commonjs/i18n/tr.json +24 -6
  85. package/lib/commonjs/state-store/image-gallery-state-store.js +13 -0
  86. package/lib/commonjs/state-store/image-gallery-state-store.js.map +1 -1
  87. package/lib/commonjs/utils/i18n/getDateString.js +26 -1
  88. package/lib/commonjs/utils/i18n/getDateString.js.map +1 -1
  89. package/lib/commonjs/version.json +1 -1
  90. package/lib/module/a11y/hooks/useAnnounceOnShow.js +27 -0
  91. package/lib/module/a11y/hooks/useAnnounceOnShow.js.map +1 -0
  92. package/lib/module/a11y/index.js +11 -0
  93. package/lib/module/a11y/index.js.map +1 -1
  94. package/lib/module/components/Accessibility/CompositeAccessibilityProbe.js +29 -0
  95. package/lib/module/components/Accessibility/CompositeAccessibilityProbe.js.map +1 -0
  96. package/lib/module/components/Accessibility/HiddenA11yText.js +30 -0
  97. package/lib/module/components/Accessibility/HiddenA11yText.js.map +1 -0
  98. package/lib/module/components/Accessibility/OverlayA11yShield.js +37 -0
  99. package/lib/module/components/Accessibility/OverlayA11yShield.js.map +1 -0
  100. package/lib/module/components/Accessibility/index.js +22 -0
  101. package/lib/module/components/Accessibility/index.js.map +1 -1
  102. package/lib/module/components/Attachment/Gallery.js +10 -0
  103. package/lib/module/components/Attachment/Gallery.js.map +1 -1
  104. package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +31 -29
  105. package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
  106. package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js +11 -5
  107. package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
  108. package/lib/module/components/ChannelPreview/ChannelPreviewStatus.js +18 -2
  109. package/lib/module/components/ChannelPreview/ChannelPreviewStatus.js.map +1 -1
  110. package/lib/module/components/ChannelPreview/ChannelPreviewUnreadCount.js +8 -2
  111. package/lib/module/components/ChannelPreview/ChannelPreviewUnreadCount.js.map +1 -1
  112. package/lib/module/components/ChannelPreview/ChannelPreviewView.js +3 -0
  113. package/lib/module/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
  114. package/lib/module/components/ImageGallery/ImageGallery.js +56 -1
  115. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  116. package/lib/module/components/Message/MessageItemView/Headers/MessageReminderHeader.js +2 -0
  117. package/lib/module/components/Message/MessageItemView/Headers/MessageReminderHeader.js.map +1 -1
  118. package/lib/module/components/Message/MessageItemView/Headers/SentToChannelHeader.js +2 -0
  119. package/lib/module/components/Message/MessageItemView/Headers/SentToChannelHeader.js.map +1 -1
  120. package/lib/module/components/Message/MessageItemView/MessageContent.js +26 -4
  121. package/lib/module/components/Message/MessageItemView/MessageContent.js.map +1 -1
  122. package/lib/module/components/Message/MessageItemView/MessageFooter.js +2 -0
  123. package/lib/module/components/Message/MessageItemView/MessageFooter.js.map +1 -1
  124. package/lib/module/components/Message/MessageItemView/MessageReplies.js +7 -3
  125. package/lib/module/components/Message/MessageItemView/MessageReplies.js.map +1 -1
  126. package/lib/module/components/Message/MessageItemView/MessageRepliesAvatars.js +2 -0
  127. package/lib/module/components/Message/MessageItemView/MessageRepliesAvatars.js.map +1 -1
  128. package/lib/module/components/Message/MessageItemView/MessageStatus.js +35 -30
  129. package/lib/module/components/Message/MessageItemView/MessageStatus.js.map +1 -1
  130. package/lib/module/components/Message/MessageItemView/MessageTextContainer.js +16 -6
  131. package/lib/module/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
  132. package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListClustered.js +19 -6
  133. package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListClustered.js.map +1 -1
  134. package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListItem.js +10 -1
  135. package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListItem.js.map +1 -1
  136. package/lib/module/components/Message/hooks/useCreateMessageContext.js +6 -1
  137. package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
  138. package/lib/module/components/Message/hooks/useMessageActionHandlers.js +8 -0
  139. package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
  140. package/lib/module/components/MessageList/InlineDateSeparator.js +8 -1
  141. package/lib/module/components/MessageList/InlineDateSeparator.js.map +1 -1
  142. package/lib/module/components/MessageMenu/ReactionButton.js +0 -7
  143. package/lib/module/components/MessageMenu/ReactionButton.js.map +1 -1
  144. package/lib/module/components/Poll/Poll.js +2 -17
  145. package/lib/module/components/Poll/Poll.js.map +1 -1
  146. package/lib/module/components/Poll/components/PollOption.js +6 -1
  147. package/lib/module/components/Poll/components/PollOption.js.map +1 -1
  148. package/lib/module/components/Reply/Reply.js +43 -6
  149. package/lib/module/components/Reply/Reply.js.map +1 -1
  150. package/lib/module/components/ui/Avatar/ChannelAvatar.js +17 -11
  151. package/lib/module/components/ui/Avatar/ChannelAvatar.js.map +1 -1
  152. package/lib/module/components/ui/Badge/BadgeNotification.js +3 -1
  153. package/lib/module/components/ui/Badge/BadgeNotification.js.map +1 -1
  154. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js +6 -22
  155. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
  156. package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
  157. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +1 -0
  158. package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
  159. package/lib/module/contexts/overlayContext/OverlayProvider.js +4 -1
  160. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  161. package/lib/module/i18n/ar.json +26 -8
  162. package/lib/module/i18n/en.json +23 -5
  163. package/lib/module/i18n/es.json +23 -5
  164. package/lib/module/i18n/fr.json +23 -5
  165. package/lib/module/i18n/he.json +23 -5
  166. package/lib/module/i18n/hi.json +24 -6
  167. package/lib/module/i18n/it.json +23 -5
  168. package/lib/module/i18n/ja.json +23 -5
  169. package/lib/module/i18n/ko.json +23 -5
  170. package/lib/module/i18n/nl.json +24 -6
  171. package/lib/module/i18n/pt-br.json +25 -7
  172. package/lib/module/i18n/ru.json +23 -5
  173. package/lib/module/i18n/tr.json +24 -6
  174. package/lib/module/state-store/image-gallery-state-store.js +13 -0
  175. package/lib/module/state-store/image-gallery-state-store.js.map +1 -1
  176. package/lib/module/utils/i18n/getDateString.js +26 -1
  177. package/lib/module/utils/i18n/getDateString.js.map +1 -1
  178. package/lib/module/version.json +1 -1
  179. package/lib/typescript/a11y/hooks/useAnnounceOnShow.d.ts +21 -0
  180. package/lib/typescript/a11y/hooks/useAnnounceOnShow.d.ts.map +1 -0
  181. package/lib/typescript/a11y/index.d.ts +1 -0
  182. package/lib/typescript/a11y/index.d.ts.map +1 -1
  183. package/lib/typescript/components/Accessibility/CompositeAccessibilityProbe.d.ts +30 -0
  184. package/lib/typescript/components/Accessibility/CompositeAccessibilityProbe.d.ts.map +1 -0
  185. package/lib/typescript/components/Accessibility/HiddenA11yText.d.ts +25 -0
  186. package/lib/typescript/components/Accessibility/HiddenA11yText.d.ts.map +1 -0
  187. package/lib/typescript/components/Accessibility/OverlayA11yShield.d.ts +20 -0
  188. package/lib/typescript/components/Accessibility/OverlayA11yShield.d.ts.map +1 -0
  189. package/lib/typescript/components/Accessibility/index.d.ts +2 -0
  190. package/lib/typescript/components/Accessibility/index.d.ts.map +1 -1
  191. package/lib/typescript/components/Attachment/Gallery.d.ts.map +1 -1
  192. package/lib/typescript/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.d.ts.map +1 -1
  193. package/lib/typescript/components/ChannelPreview/ChannelPreviewMutedStatus.d.ts.map +1 -1
  194. package/lib/typescript/components/ChannelPreview/ChannelPreviewStatus.d.ts.map +1 -1
  195. package/lib/typescript/components/ChannelPreview/ChannelPreviewUnreadCount.d.ts.map +1 -1
  196. package/lib/typescript/components/ChannelPreview/ChannelPreviewView.d.ts.map +1 -1
  197. package/lib/typescript/components/ImageGallery/ImageGallery.d.ts.map +1 -1
  198. package/lib/typescript/components/Message/MessageItemView/Headers/MessageReminderHeader.d.ts.map +1 -1
  199. package/lib/typescript/components/Message/MessageItemView/Headers/SentToChannelHeader.d.ts.map +1 -1
  200. package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts +1 -1
  201. package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts.map +1 -1
  202. package/lib/typescript/components/Message/MessageItemView/MessageFooter.d.ts.map +1 -1
  203. package/lib/typescript/components/Message/MessageItemView/MessageReplies.d.ts.map +1 -1
  204. package/lib/typescript/components/Message/MessageItemView/MessageRepliesAvatars.d.ts.map +1 -1
  205. package/lib/typescript/components/Message/MessageItemView/MessageStatus.d.ts.map +1 -1
  206. package/lib/typescript/components/Message/MessageItemView/MessageTextContainer.d.ts +1 -1
  207. package/lib/typescript/components/Message/MessageItemView/MessageTextContainer.d.ts.map +1 -1
  208. package/lib/typescript/components/Message/MessageItemView/ReactionList/ReactionListClustered.d.ts.map +1 -1
  209. package/lib/typescript/components/Message/MessageItemView/ReactionList/ReactionListItem.d.ts.map +1 -1
  210. package/lib/typescript/components/Message/MessageOverlayWrapper.d.ts +1 -1
  211. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
  212. package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
  213. package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
  214. package/lib/typescript/components/MessageList/InlineDateSeparator.d.ts.map +1 -1
  215. package/lib/typescript/components/MessageMenu/ReactionButton.d.ts.map +1 -1
  216. package/lib/typescript/components/Poll/Poll.d.ts.map +1 -1
  217. package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
  218. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  219. package/lib/typescript/components/ui/Avatar/ChannelAvatar.d.ts.map +1 -1
  220. package/lib/typescript/components/ui/Badge/BadgeNotification.d.ts +5 -0
  221. package/lib/typescript/components/ui/Badge/BadgeNotification.d.ts.map +1 -1
  222. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts +32 -2
  223. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts.map +1 -1
  224. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +8 -0
  225. package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
  226. package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
  227. package/lib/typescript/contexts/overlayContext/OverlayProvider.d.ts.map +1 -1
  228. package/lib/typescript/hooks/useTranslatedMessage.d.ts +1 -1
  229. package/lib/typescript/i18n/ar.json +26 -8
  230. package/lib/typescript/i18n/en.json +23 -5
  231. package/lib/typescript/i18n/es.json +23 -5
  232. package/lib/typescript/i18n/fr.json +23 -5
  233. package/lib/typescript/i18n/he.json +23 -5
  234. package/lib/typescript/i18n/hi.json +24 -6
  235. package/lib/typescript/i18n/it.json +23 -5
  236. package/lib/typescript/i18n/ja.json +23 -5
  237. package/lib/typescript/i18n/ko.json +23 -5
  238. package/lib/typescript/i18n/nl.json +24 -6
  239. package/lib/typescript/i18n/pt-br.json +25 -7
  240. package/lib/typescript/i18n/ru.json +23 -5
  241. package/lib/typescript/i18n/tr.json +24 -6
  242. package/lib/typescript/state-store/image-gallery-state-store.d.ts +5 -1
  243. package/lib/typescript/state-store/image-gallery-state-store.d.ts.map +1 -1
  244. package/lib/typescript/utils/i18n/Streami18n.d.ts +22 -4
  245. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  246. package/lib/typescript/utils/i18n/getDateString.d.ts +28 -0
  247. package/lib/typescript/utils/i18n/getDateString.d.ts.map +1 -1
  248. package/package.json +1 -1
  249. package/src/a11y/hooks/useAnnounceOnShow.ts +44 -0
  250. package/src/a11y/index.ts +1 -0
  251. package/src/components/Accessibility/CompositeAccessibilityProbe.tsx +48 -0
  252. package/src/components/Accessibility/HiddenA11yText.tsx +49 -0
  253. package/src/components/Accessibility/OverlayA11yShield.tsx +49 -0
  254. package/src/components/Accessibility/__tests__/OverlayA11yShield.test.tsx +83 -0
  255. package/src/components/Accessibility/index.ts +2 -0
  256. package/src/components/Attachment/Gallery.tsx +14 -2
  257. package/src/components/Channel/__tests__/ownCapabilities.test.tsx +25 -2
  258. package/src/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.tsx +19 -16
  259. package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx +8 -1
  260. package/src/components/ChannelPreview/ChannelPreviewStatus.tsx +26 -6
  261. package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx +5 -1
  262. package/src/components/ChannelPreview/ChannelPreviewView.tsx +3 -0
  263. package/src/components/ImageGallery/ImageGallery.tsx +82 -4
  264. package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +13 -3
  265. package/src/components/ImageGallery/__tests__/ImageGalleryAdjustable.test.tsx +141 -0
  266. package/src/components/Message/MessageItemView/Headers/MessageReminderHeader.tsx +7 -1
  267. package/src/components/Message/MessageItemView/Headers/SentToChannelHeader.tsx +7 -1
  268. package/src/components/Message/MessageItemView/MessageContent.tsx +34 -4
  269. package/src/components/Message/MessageItemView/MessageFooter.tsx +6 -1
  270. package/src/components/Message/MessageItemView/MessageReplies.tsx +9 -7
  271. package/src/components/Message/MessageItemView/MessageRepliesAvatars.tsx +5 -1
  272. package/src/components/Message/MessageItemView/MessageStatus.tsx +36 -39
  273. package/src/components/Message/MessageItemView/MessageTextContainer.tsx +27 -4
  274. package/src/components/Message/MessageItemView/ReactionList/ReactionListClustered.tsx +24 -10
  275. package/src/components/Message/MessageItemView/ReactionList/ReactionListItem.tsx +7 -1
  276. package/src/components/Message/MessageItemView/__tests__/Message.test.tsx +10 -3
  277. package/src/components/Message/MessageItemView/__tests__/MessageReplies.test.tsx +10 -2
  278. package/src/components/Message/MessageItemView/__tests__/MessageStatus.test.tsx +10 -7
  279. package/src/components/Message/MessageItemView/__tests__/ReactionListBottom.test.tsx +1 -1
  280. package/src/components/Message/hooks/useCreateMessageContext.ts +12 -1
  281. package/src/components/Message/hooks/useMessageActionHandlers.ts +7 -0
  282. package/src/components/MessageInput/__tests__/__snapshots__/AttachButton.test.tsx.snap +3 -0
  283. package/src/components/MessageInput/__tests__/__snapshots__/SendButton.test.tsx.snap +2 -0
  284. package/src/components/MessageList/InlineDateSeparator.tsx +10 -3
  285. package/src/components/MessageMenu/ReactionButton.tsx +0 -7
  286. package/src/components/MessageMenu/__tests__/ReactionButton.test.tsx +1 -14
  287. package/src/components/Poll/Poll.tsx +2 -26
  288. package/src/components/Poll/components/PollOption.tsx +7 -1
  289. package/src/components/Reply/Reply.tsx +58 -7
  290. package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +9 -0
  291. package/src/components/ui/Avatar/ChannelAvatar.tsx +39 -29
  292. package/src/components/ui/Badge/BadgeNotification.tsx +11 -2
  293. package/src/contexts/accessibilityContext/AccessibilityContext.tsx +60 -36
  294. package/src/contexts/messageContext/MessageContext.tsx +8 -0
  295. package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +5 -1
  296. package/src/contexts/overlayContext/OverlayProvider.tsx +2 -1
  297. package/src/i18n/ar.json +26 -8
  298. package/src/i18n/en.json +23 -5
  299. package/src/i18n/es.json +23 -5
  300. package/src/i18n/fr.json +23 -5
  301. package/src/i18n/he.json +23 -5
  302. package/src/i18n/hi.json +24 -6
  303. package/src/i18n/it.json +23 -5
  304. package/src/i18n/ja.json +23 -5
  305. package/src/i18n/ko.json +23 -5
  306. package/src/i18n/nl.json +24 -6
  307. package/src/i18n/pt-br.json +25 -7
  308. package/src/i18n/ru.json +23 -5
  309. package/src/i18n/tr.json +24 -6
  310. package/src/state-store/__tests__/image-gallery-state-store.test.ts +1 -0
  311. package/src/state-store/image-gallery-state-store.ts +13 -1
  312. package/src/utils/i18n/getDateString.ts +57 -0
  313. package/src/version.json +1 -1
  314. package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js +0 -150
  315. package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js.map +0 -1
  316. package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js +0 -59
  317. package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js.map +0 -1
  318. package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js +0 -150
  319. package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js.map +0 -1
  320. package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js +0 -59
  321. package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js.map +0 -1
  322. package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts +0 -25
  323. package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts.map +0 -1
  324. package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts +0 -8
  325. package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts.map +0 -1
  326. package/src/components/Poll/hooks/__tests__/usePollAccessibilityActions.test.tsx +0 -358
  327. package/src/components/Poll/hooks/__tests__/usePollAccessibilityLabel.test.tsx +0 -142
  328. package/src/components/Poll/hooks/usePollAccessibilityActions.ts +0 -191
  329. package/src/components/Poll/hooks/usePollAccessibilityLabel.ts +0 -75
@@ -1,358 +0,0 @@
1
- import React from 'react';
2
-
3
- import type { AccessibilityActionEvent } from 'react-native';
4
-
5
- import { act, renderHook } from '@testing-library/react-native';
6
-
7
- import { AccessibilityProvider } from '../../../../contexts/accessibilityContext/AccessibilityContext';
8
- import { TranslationProvider } from '../../../../contexts/translationContext/TranslationContext';
9
- import { usePollAccessibilityActions } from '../usePollAccessibilityActions';
10
-
11
- const mockOpenAddComment = jest.fn();
12
- const mockOpenAllComments = jest.fn();
13
- const mockOpenAllOptions = jest.fn();
14
- const mockOpenSuggestOption = jest.fn();
15
- const mockOpenViewResults = jest.fn();
16
- const mockEndVote = jest.fn();
17
- const mockToggleVote = jest.fn();
18
-
19
- jest.mock('../../contexts/PollUIStateContext', () => ({
20
- usePollUIStateContext: () => ({
21
- openAddComment: mockOpenAddComment,
22
- openAllComments: mockOpenAllComments,
23
- openAllOptions: mockOpenAllOptions,
24
- openSuggestOption: mockOpenSuggestOption,
25
- openViewResults: mockOpenViewResults,
26
- }),
27
- }));
28
-
29
- jest.mock('../usePollStateStore', () => ({
30
- usePollStateStore: (selector: (state: unknown) => unknown) => selector(mockPollState),
31
- }));
32
-
33
- jest.mock('../useEndVote', () => ({
34
- useEndVote: () => mockEndVote,
35
- }));
36
-
37
- jest.mock('../usePollVoteToggle', () => ({
38
- usePollVoteToggle: () => mockToggleVote,
39
- }));
40
-
41
- const mockChatContext = { client: { userID: 'me' } };
42
- const mockOwnCapabilities = { castPollVote: true };
43
-
44
- jest.mock('../../../../contexts', () => {
45
- const actual = jest.requireActual('../../../../contexts');
46
- return {
47
- ...actual,
48
- useChatContext: () => mockChatContext,
49
- useOwnCapabilitiesContext: () => mockOwnCapabilities,
50
- };
51
- });
52
-
53
- let mockPollState: Record<string, unknown> = {};
54
-
55
- const setPollState = (state: Record<string, unknown>) => {
56
- mockPollState = state;
57
- };
58
-
59
- const setCastPollVote = (allowed: boolean) => {
60
- mockOwnCapabilities.castPollVote = allowed;
61
- };
62
-
63
- const setUserID = (id: string) => {
64
- mockChatContext.client.userID = id;
65
- };
66
-
67
- const t = (key: string, vars?: Record<string, unknown>) => {
68
- if (!vars) return key;
69
- if (key === 'a11y/Vote on {{option}}') return `Vote on ${vars.option}`;
70
- return key;
71
- };
72
-
73
- const wrapper =
74
- (enabled: boolean) =>
75
- ({ children }: { children: React.ReactNode }) => (
76
- <AccessibilityProvider value={{ enabled }}>
77
- <TranslationProvider
78
- value={
79
- {
80
- t,
81
- tDateTimeParser: () => null,
82
- } as never
83
- }
84
- >
85
- {children}
86
- </TranslationProvider>
87
- </AccessibilityProvider>
88
- );
89
-
90
- const buildOption = (id: string, text: string) => ({ id, text });
91
-
92
- const fireAction = (
93
- handler: ((event: AccessibilityActionEvent) => void) | undefined,
94
- actionName: string,
95
- ) => {
96
- handler?.({ nativeEvent: { actionName } } as AccessibilityActionEvent);
97
- };
98
-
99
- beforeEach(() => {
100
- mockOpenAddComment.mockClear();
101
- mockOpenAllComments.mockClear();
102
- mockOpenAllOptions.mockClear();
103
- mockOpenSuggestOption.mockClear();
104
- mockOpenViewResults.mockClear();
105
- mockEndVote.mockClear();
106
- mockToggleVote.mockClear();
107
- setCastPollVote(true);
108
- setUserID('me');
109
- });
110
-
111
- describe('usePollAccessibilityActions', () => {
112
- it('returns undefined when accessibility is disabled', () => {
113
- setPollState({
114
- allow_answers: true,
115
- allow_user_suggested_options: true,
116
- created_by: { id: 'me' },
117
- is_closed: false,
118
- options: [buildOption('o1', 'A')],
119
- });
120
-
121
- const { result } = renderHook(() => usePollAccessibilityActions(), {
122
- wrapper: wrapper(false),
123
- });
124
-
125
- expect(result.current.accessibilityActions).toBeUndefined();
126
- expect(result.current.onAccessibilityAction).toBeUndefined();
127
- });
128
-
129
- it('every action uses the same human label for name and label', () => {
130
- setPollState({
131
- allow_answers: true,
132
- allow_user_suggested_options: true,
133
- created_by: { id: 'me' },
134
- is_closed: false,
135
- options: [buildOption('o1', 'Pizza'), buildOption('o2', 'Pasta')],
136
- });
137
-
138
- const { result } = renderHook(() => usePollAccessibilityActions(), {
139
- wrapper: wrapper(true),
140
- });
141
-
142
- const actions = result.current.accessibilityActions;
143
- expect(actions).toBeDefined();
144
- for (const action of actions ?? []) {
145
- expect(action.name).toBe(action.label);
146
- }
147
- });
148
-
149
- it('exposes only View Results for an ended poll', () => {
150
- setPollState({
151
- allow_answers: true,
152
- allow_user_suggested_options: true,
153
- created_by: { id: 'me' },
154
- is_closed: true,
155
- options: [buildOption('o1', 'A'), buildOption('o2', 'B')],
156
- });
157
-
158
- const { result } = renderHook(() => usePollAccessibilityActions(), {
159
- wrapper: wrapper(true),
160
- });
161
-
162
- const labels = result.current.accessibilityActions?.map((a) => a.label);
163
- expect(labels).toEqual(['View Results']);
164
- });
165
-
166
- it('lists vote actions with the option text, plus End vote / Add comment / Suggest option for creator', () => {
167
- setPollState({
168
- allow_answers: true,
169
- allow_user_suggested_options: true,
170
- created_by: { id: 'me' },
171
- is_closed: false,
172
- options: [buildOption('o1', 'Pizza'), buildOption('o2', 'Pasta')],
173
- });
174
-
175
- const { result } = renderHook(() => usePollAccessibilityActions(), {
176
- wrapper: wrapper(true),
177
- });
178
-
179
- const labels = result.current.accessibilityActions?.map((a) => a.label);
180
- expect(labels).toEqual([
181
- 'View Results',
182
- 'Vote on Pizza',
183
- 'Vote on Pasta',
184
- 'a11y/End vote',
185
- 'Add a comment',
186
- 'Suggest an option',
187
- ]);
188
- });
189
-
190
- it('omits End vote when the current user is not the creator', () => {
191
- setUserID('someone-else');
192
- setPollState({
193
- allow_answers: false,
194
- allow_user_suggested_options: false,
195
- created_by: { id: 'me' },
196
- is_closed: false,
197
- options: [buildOption('o1', 'Pizza')],
198
- });
199
-
200
- const { result } = renderHook(() => usePollAccessibilityActions(), {
201
- wrapper: wrapper(true),
202
- });
203
-
204
- const labels = result.current.accessibilityActions?.map((a) => a.label);
205
- expect(labels).toEqual(['View Results', 'Vote on Pizza']);
206
- });
207
-
208
- it('omits vote actions when the user lacks castPollVote capability', () => {
209
- setCastPollVote(false);
210
- setPollState({
211
- allow_answers: true,
212
- allow_user_suggested_options: false,
213
- created_by: { id: 'somebody' },
214
- is_closed: false,
215
- options: [buildOption('o1', 'Pizza')],
216
- });
217
-
218
- const { result } = renderHook(() => usePollAccessibilityActions(), {
219
- wrapper: wrapper(true),
220
- });
221
-
222
- const labels = result.current.accessibilityActions?.map((a) => a.label);
223
- expect(labels?.some((l) => l?.startsWith('Vote on'))).toBe(false);
224
- });
225
-
226
- it('exposes "View N comments" when the poll has answers', () => {
227
- setPollState({
228
- allow_answers: false,
229
- allow_user_suggested_options: false,
230
- answers_count: 4,
231
- created_by: { id: 'somebody' },
232
- is_closed: true,
233
- options: [buildOption('o1', 'A')],
234
- });
235
-
236
- const { result } = renderHook(() => usePollAccessibilityActions(), {
237
- wrapper: wrapper(true),
238
- });
239
-
240
- const labels = result.current.accessibilityActions?.map((a) => a.label);
241
- expect(labels).toContain('View {{count}} comments');
242
- });
243
-
244
- it('omits "View N comments" when there are no answers', () => {
245
- setPollState({
246
- allow_answers: false,
247
- allow_user_suggested_options: false,
248
- answers_count: 0,
249
- created_by: { id: 'somebody' },
250
- is_closed: true,
251
- options: [buildOption('o1', 'A')],
252
- });
253
-
254
- const { result } = renderHook(() => usePollAccessibilityActions(), {
255
- wrapper: wrapper(true),
256
- });
257
-
258
- const labels = result.current.accessibilityActions?.map((a) => a.label);
259
- expect(labels?.some((l) => l?.includes('comments'))).toBe(false);
260
- });
261
-
262
- it('exposes Show all options when options exceed the visible cap', () => {
263
- const manyOptions = Array.from({ length: 12 }, (_, i) => buildOption(`o${i}`, `Option ${i}`));
264
- setPollState({
265
- allow_answers: false,
266
- allow_user_suggested_options: false,
267
- created_by: { id: 'somebody' },
268
- is_closed: true,
269
- options: manyOptions,
270
- });
271
-
272
- const { result } = renderHook(() => usePollAccessibilityActions(), {
273
- wrapper: wrapper(true),
274
- });
275
-
276
- const labels = result.current.accessibilityActions?.map((a) => a.label);
277
- expect(labels).toContain('a11y/Show all options');
278
- });
279
-
280
- it('routes each action to the right side effect', () => {
281
- setPollState({
282
- allow_answers: true,
283
- allow_user_suggested_options: true,
284
- created_by: { id: 'me' },
285
- is_closed: false,
286
- options: [buildOption('o1', 'Pizza'), buildOption('o2', 'Pasta')],
287
- });
288
-
289
- const { result } = renderHook(() => usePollAccessibilityActions(), {
290
- wrapper: wrapper(true),
291
- });
292
-
293
- act(() => {
294
- fireAction(result.current.onAccessibilityAction, 'View Results');
295
- });
296
- expect(mockOpenViewResults).toHaveBeenCalledTimes(1);
297
-
298
- act(() => {
299
- fireAction(result.current.onAccessibilityAction, 'a11y/End vote');
300
- });
301
- expect(mockEndVote).toHaveBeenCalledTimes(1);
302
-
303
- act(() => {
304
- fireAction(result.current.onAccessibilityAction, 'Add a comment');
305
- });
306
- expect(mockOpenAddComment).toHaveBeenCalledTimes(1);
307
-
308
- act(() => {
309
- fireAction(result.current.onAccessibilityAction, 'Suggest an option');
310
- });
311
- expect(mockOpenSuggestOption).toHaveBeenCalledTimes(1);
312
-
313
- act(() => {
314
- fireAction(result.current.onAccessibilityAction, 'Vote on Pasta');
315
- });
316
- expect(mockToggleVote).toHaveBeenCalledWith('o2');
317
- });
318
-
319
- it('routes the "View N comments" action to openAllComments', () => {
320
- setPollState({
321
- allow_answers: false,
322
- allow_user_suggested_options: false,
323
- answers_count: 7,
324
- created_by: { id: 'somebody' },
325
- is_closed: true,
326
- options: [buildOption('o1', 'A')],
327
- });
328
-
329
- const { result } = renderHook(() => usePollAccessibilityActions(), {
330
- wrapper: wrapper(true),
331
- });
332
-
333
- act(() => {
334
- fireAction(result.current.onAccessibilityAction, 'View {{count}} comments');
335
- });
336
- expect(mockOpenAllComments).toHaveBeenCalledTimes(1);
337
- });
338
-
339
- it('ignores unknown action names', () => {
340
- setPollState({
341
- allow_answers: true,
342
- allow_user_suggested_options: true,
343
- created_by: { id: 'me' },
344
- is_closed: false,
345
- options: [buildOption('o1', 'Pizza')],
346
- });
347
-
348
- const { result } = renderHook(() => usePollAccessibilityActions(), {
349
- wrapper: wrapper(true),
350
- });
351
-
352
- act(() => {
353
- fireAction(result.current.onAccessibilityAction, 'streamPollVoteOption_o1');
354
- });
355
- expect(mockToggleVote).not.toHaveBeenCalled();
356
- expect(mockOpenViewResults).not.toHaveBeenCalled();
357
- });
358
- });
@@ -1,142 +0,0 @@
1
- import React from 'react';
2
-
3
- import { renderHook } from '@testing-library/react-native';
4
-
5
- import { AccessibilityProvider } from '../../../../contexts/accessibilityContext/AccessibilityContext';
6
- import { TranslationProvider } from '../../../../contexts/translationContext/TranslationContext';
7
- import { usePollAccessibilityLabel } from '../usePollAccessibilityLabel';
8
-
9
- jest.mock('../usePollStateStore', () => ({
10
- usePollStateStore: (selector: (state: unknown) => unknown) => selector(mockPollState),
11
- }));
12
-
13
- let mockPollState: Record<string, unknown> = {};
14
-
15
- const setPollState = (state: Record<string, unknown>) => {
16
- mockPollState = state;
17
- };
18
-
19
- const t = (key: string, vars?: Record<string, unknown>) => {
20
- if (!vars) return key;
21
- if (key === '{{count}} votes') return `${vars.count} votes`;
22
- if (key === 'Select up to {{count}}') return `Select up to ${vars.count}`;
23
- if (key === '+{{count}} More Options') return `+${vars.count} More Options`;
24
- return key;
25
- };
26
-
27
- const wrapper =
28
- (enabled: boolean) =>
29
- ({ children }: { children: React.ReactNode }) => (
30
- <AccessibilityProvider value={{ enabled }}>
31
- <TranslationProvider
32
- value={
33
- {
34
- t,
35
- tDateTimeParser: () => null,
36
- } as never
37
- }
38
- >
39
- {children}
40
- </TranslationProvider>
41
- </AccessibilityProvider>
42
- );
43
-
44
- const buildOption = (id: string, text: string) => ({ id, text });
45
-
46
- describe('usePollAccessibilityLabel', () => {
47
- it('returns undefined when accessibility is disabled', () => {
48
- setPollState({
49
- enforce_unique_vote: false,
50
- is_closed: true,
51
- max_votes_allowed: 0,
52
- name: 'Lunch?',
53
- options: [buildOption('o1', 'Pizza')],
54
- vote_counts_by_option: { o1: 3 },
55
- });
56
-
57
- const { result } = renderHook(() => usePollAccessibilityLabel(), {
58
- wrapper: wrapper(false),
59
- });
60
-
61
- expect(result.current).toBeUndefined();
62
- });
63
-
64
- it('builds composite label for an ended poll', () => {
65
- setPollState({
66
- enforce_unique_vote: false,
67
- is_closed: true,
68
- max_votes_allowed: 0,
69
- name: 'Test',
70
- options: [buildOption('o1', 'Option 1'), buildOption('o2', 'Option 2')],
71
- vote_counts_by_option: { o1: 0, o2: 0 },
72
- });
73
-
74
- const { result } = renderHook(() => usePollAccessibilityLabel(), {
75
- wrapper: wrapper(true),
76
- });
77
-
78
- expect(result.current).toBe(
79
- 'Test, Poll has ended, Option 1: 0 votes, Option 2: 0 votes, a11y/Activate to view results',
80
- );
81
- });
82
-
83
- it('uses "Select one" for an open enforce-unique-vote poll', () => {
84
- setPollState({
85
- enforce_unique_vote: true,
86
- is_closed: false,
87
- max_votes_allowed: 0,
88
- name: 'Pick a venue',
89
- options: [buildOption('o1', 'Cafe')],
90
- vote_counts_by_option: { o1: 2 },
91
- });
92
-
93
- const { result } = renderHook(() => usePollAccessibilityLabel(), {
94
- wrapper: wrapper(true),
95
- });
96
-
97
- expect(result.current).toBe(
98
- 'Pick a venue, Select one, Cafe: 2 votes, a11y/Activate to view results',
99
- );
100
- });
101
-
102
- it('uses "Select up to N" when maxVotesAllowed is set', () => {
103
- setPollState({
104
- enforce_unique_vote: false,
105
- is_closed: false,
106
- max_votes_allowed: 3,
107
- name: 'Top picks',
108
- options: [buildOption('o1', 'A')],
109
- vote_counts_by_option: { o1: 1 },
110
- });
111
-
112
- const { result } = renderHook(() => usePollAccessibilityLabel(), {
113
- wrapper: wrapper(true),
114
- });
115
-
116
- expect(result.current).toBe(
117
- 'Top picks, Select up to 3, A: 1 votes, a11y/Activate to view results',
118
- );
119
- });
120
-
121
- it('appends overflow hint when options exceed the visible cap', () => {
122
- const manyOptions = Array.from({ length: 12 }, (_, i) => buildOption(`o${i}`, `Option ${i}`));
123
- const counts = Object.fromEntries(manyOptions.map((o) => [o.id, 0]));
124
-
125
- setPollState({
126
- enforce_unique_vote: false,
127
- is_closed: false,
128
- max_votes_allowed: 0,
129
- name: 'Big poll',
130
- options: manyOptions,
131
- vote_counts_by_option: counts,
132
- });
133
-
134
- const { result } = renderHook(() => usePollAccessibilityLabel(), {
135
- wrapper: wrapper(true),
136
- });
137
-
138
- expect(result.current).toContain('+7 More Options');
139
- expect(result.current).toContain('Option 0: 0 votes');
140
- expect(result.current).not.toContain('Option 5:');
141
- });
142
- });
@@ -1,191 +0,0 @@
1
- import { useMemo } from 'react';
2
-
3
- import type { AccessibilityActionEvent, AccessibilityProps } from 'react-native';
4
-
5
- import { PollOption, PollState, UserResponse } from 'stream-chat';
6
-
7
- import { useEndVote } from './useEndVote';
8
-
9
- import { usePollStateStore } from './usePollStateStore';
10
-
11
- import { usePollVoteToggle } from './usePollVoteToggle';
12
-
13
- import {
14
- useChatContext,
15
- useOwnCapabilitiesContext,
16
- useTranslationContext,
17
- } from '../../../contexts';
18
- import { useAccessibilityContext } from '../../../contexts/accessibilityContext/AccessibilityContext';
19
- import { useStableCallback } from '../../../hooks';
20
- import { defaultPollOptionCount } from '../../../utils/constants';
21
- import { usePollUIStateContext } from '../contexts/PollUIStateContext';
22
-
23
- type AccessibilityAction = NonNullable<AccessibilityProps['accessibilityActions']>[number];
24
- type OnAccessibilityAction = NonNullable<AccessibilityProps['onAccessibilityAction']>;
25
-
26
- type PollA11yActionsSelectorResult = {
27
- allowAnswers: boolean | undefined;
28
- allowUserSuggestedOptions: boolean | undefined;
29
- answersCount: number;
30
- createdBy: UserResponse | null;
31
- isClosed: boolean | undefined;
32
- options: PollOption[];
33
- };
34
-
35
- const a11yActionsSelector = (state: PollState): PollA11yActionsSelectorResult => ({
36
- allowAnswers: state.allow_answers,
37
- allowUserSuggestedOptions: state.allow_user_suggested_options,
38
- answersCount: state.answers_count,
39
- createdBy: state.created_by,
40
- isClosed: state.is_closed,
41
- options: state.options,
42
- });
43
-
44
- export type UsePollAccessibilityActionsResult = {
45
- accessibilityActions: readonly AccessibilityAction[] | undefined;
46
- onAccessibilityAction: OnAccessibilityAction | undefined;
47
- };
48
-
49
- type ActionKind =
50
- | { type: 'addComment' }
51
- | { type: 'endVote' }
52
- | { type: 'showAllComments' }
53
- | { type: 'showAllOptions' }
54
- | { type: 'suggestOption' }
55
- | { type: 'viewResults' }
56
- | { type: 'vote'; optionId: string };
57
-
58
- /**
59
- * Returns the `accessibilityActions` array and `onAccessibilityAction` handler
60
- * for the poll composite container. Action set is gated by poll state +
61
- * capabilities so each rotor entry corresponds to an interaction the user is
62
- * actually allowed to perform. Returns `undefined`s when a11y is disabled.
63
- *
64
- * NOTE: We set both `name` and `label` to the same human-readable string on
65
- * every action. iOS Fabric (new architecture, on by default in RN 0.81+) uses
66
- * `accessibilityAction.name` as the string VoiceOver reads — `label` is
67
- * ignored on that path (RCTViewComponentView.mm). iOS legacy (Paper) and
68
- * Android both read `label`. Using the same value for both fields means the
69
- * announcement is human-readable on every platform/architecture. Dispatch
70
- * uses the action name as the lookup key into an internal kind map, so the
71
- * raw strings never need to be exposed to consumers.
72
- */
73
- export const usePollAccessibilityActions = (): UsePollAccessibilityActionsResult => {
74
- const { enabled } = useAccessibilityContext();
75
- const { t } = useTranslationContext();
76
- const { client } = useChatContext();
77
- const { castPollVote } = useOwnCapabilitiesContext();
78
- const { allowAnswers, allowUserSuggestedOptions, answersCount, createdBy, isClosed, options } =
79
- usePollStateStore(a11yActionsSelector);
80
- const { openAddComment, openAllComments, openAllOptions, openSuggestOption, openViewResults } =
81
- usePollUIStateContext();
82
- const toggleVote = usePollVoteToggle();
83
- const endVote = useEndVote();
84
-
85
- const canVote = !isClosed && !!castPollVote;
86
- const canEnd = !isClosed && createdBy?.id === client.userID;
87
- const canComment = !isClosed && !!allowAnswers;
88
- const canSuggest = !isClosed && !!allowUserSuggestedOptions;
89
- const hasMoreOptions = !!options && options.length > defaultPollOptionCount;
90
- const hasComments = answersCount > 0;
91
-
92
- const { accessibilityActions, actionKindByName } = useMemo<{
93
- accessibilityActions: readonly AccessibilityAction[] | undefined;
94
- actionKindByName: Map<string, ActionKind> | undefined;
95
- }>(() => {
96
- if (!enabled) {
97
- return { accessibilityActions: undefined, actionKindByName: undefined };
98
- }
99
-
100
- const actions: AccessibilityAction[] = [];
101
- const kindByName = new Map<string, ActionKind>();
102
-
103
- const push = (name: string, kind: ActionKind) => {
104
- actions.push({ label: name, name });
105
- kindByName.set(name, kind);
106
- };
107
-
108
- push(t('View Results'), { type: 'viewResults' });
109
-
110
- if (canVote && options) {
111
- for (const option of options.slice(0, defaultPollOptionCount)) {
112
- push(t('a11y/Vote on {{option}}', { option: option.text }), {
113
- optionId: option.id,
114
- type: 'vote',
115
- });
116
- }
117
- }
118
-
119
- if (hasMoreOptions) {
120
- push(t('a11y/Show all options'), { type: 'showAllOptions' });
121
- }
122
-
123
- if (canEnd) {
124
- push(t('a11y/End vote'), { type: 'endVote' });
125
- }
126
-
127
- if (canComment) {
128
- push(t('Add a comment'), { type: 'addComment' });
129
- }
130
-
131
- if (canSuggest) {
132
- push(t('Suggest an option'), { type: 'suggestOption' });
133
- }
134
-
135
- if (hasComments) {
136
- push(t('View {{count}} comments', { count: answersCount }), { type: 'showAllComments' });
137
- }
138
-
139
- return { accessibilityActions: actions, actionKindByName: kindByName };
140
- }, [
141
- answersCount,
142
- canComment,
143
- canEnd,
144
- canSuggest,
145
- canVote,
146
- enabled,
147
- hasComments,
148
- hasMoreOptions,
149
- options,
150
- t,
151
- ]);
152
-
153
- const onAccessibilityAction = useStableCallback((event: AccessibilityActionEvent) => {
154
- const kind = actionKindByName?.get(event.nativeEvent.actionName);
155
- if (!kind) return;
156
-
157
- switch (kind.type) {
158
- case 'viewResults':
159
- openViewResults();
160
- return;
161
- case 'showAllOptions':
162
- openAllOptions();
163
- return;
164
- case 'endVote':
165
- void endVote();
166
- return;
167
- case 'addComment':
168
- openAddComment();
169
- return;
170
- case 'suggestOption':
171
- openSuggestOption();
172
- return;
173
- case 'showAllComments':
174
- openAllComments();
175
- return;
176
- case 'vote':
177
- void toggleVote(kind.optionId);
178
- return;
179
- default:
180
- return;
181
- }
182
- });
183
-
184
- return useMemo(
185
- () => ({
186
- accessibilityActions,
187
- onAccessibilityAction: enabled ? onAccessibilityAction : undefined,
188
- }),
189
- [accessibilityActions, enabled, onAccessibilityAction],
190
- );
191
- };