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

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 (279) hide show
  1. package/lib/commonjs/a11y/hooks/useA11yLabel.js +4 -3
  2. package/lib/commonjs/a11y/hooks/useA11yLabel.js.map +1 -1
  3. package/lib/commonjs/a11y/hooks/useAccessibilityActivateAction.js +25 -0
  4. package/lib/commonjs/a11y/hooks/useAccessibilityActivateAction.js.map +1 -0
  5. package/lib/commonjs/a11y/index.js +11 -0
  6. package/lib/commonjs/a11y/index.js.map +1 -1
  7. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +20 -0
  8. package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  9. package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.js +1 -0
  10. package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.js.map +1 -1
  11. package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js +19 -2
  12. package/lib/commonjs/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js.map +1 -1
  13. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js +2 -1
  14. package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  15. package/lib/commonjs/components/AttachmentPicker/components/AttachmentTypePickerButton.js +9 -1
  16. package/lib/commonjs/components/AttachmentPicker/components/AttachmentTypePickerButton.js.map +1 -1
  17. package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js +2 -2
  18. package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
  19. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +1 -1
  20. package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  21. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js +1 -1
  22. package/lib/commonjs/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  23. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.js +16 -4
  24. package/lib/commonjs/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.js.map +1 -1
  25. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js +3 -0
  26. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -1
  27. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +5 -0
  28. package/lib/commonjs/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  29. package/lib/commonjs/components/MessageInput/components/InputButtons/AttachButton.js +12 -3
  30. package/lib/commonjs/components/MessageInput/components/InputButtons/AttachButton.js.map +1 -1
  31. package/lib/commonjs/components/MessageInput/components/OutputButtons/EditButton.js +1 -0
  32. package/lib/commonjs/components/MessageInput/components/OutputButtons/EditButton.js.map +1 -1
  33. package/lib/commonjs/components/MessageInput/components/OutputButtons/SendButton.js +1 -0
  34. package/lib/commonjs/components/MessageInput/components/OutputButtons/SendButton.js.map +1 -1
  35. package/lib/commonjs/components/MessageList/MessageFlashList.js +19 -2
  36. package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -1
  37. package/lib/commonjs/components/MessageList/MessageList.js +19 -2
  38. package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
  39. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js +12 -6
  40. package/lib/commonjs/components/MessageList/ScrollToBottomButton.js.map +1 -1
  41. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js +1 -0
  42. package/lib/commonjs/components/MessageList/UnreadMessagesNotification.js.map +1 -1
  43. package/lib/commonjs/components/MessageList/hooks/useScrollToBottomAccessibilityAction.js +47 -0
  44. package/lib/commonjs/components/MessageList/hooks/useScrollToBottomAccessibilityAction.js.map +1 -0
  45. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js +12 -4
  46. package/lib/commonjs/components/MessageMenu/MessageActionListItem.js.map +1 -1
  47. package/lib/commonjs/components/MessageMenu/MessageReactionPicker.js +1 -0
  48. package/lib/commonjs/components/MessageMenu/MessageReactionPicker.js.map +1 -1
  49. package/lib/commonjs/components/MessageMenu/ReactionButton.js +9 -6
  50. package/lib/commonjs/components/MessageMenu/ReactionButton.js.map +1 -1
  51. package/lib/commonjs/components/Poll/components/CreatePollHeader.js +2 -0
  52. package/lib/commonjs/components/Poll/components/CreatePollHeader.js.map +1 -1
  53. package/lib/commonjs/components/Poll/components/MultipleVotesSettings.js +2 -0
  54. package/lib/commonjs/components/Poll/components/MultipleVotesSettings.js.map +1 -1
  55. package/lib/commonjs/components/Poll/components/PollModalHeader.js +1 -0
  56. package/lib/commonjs/components/Poll/components/PollModalHeader.js.map +1 -1
  57. package/lib/commonjs/components/Reply/Reply.js +1 -0
  58. package/lib/commonjs/components/Reply/Reply.js.map +1 -1
  59. package/lib/commonjs/components/ui/Avatar/Avatar.js +6 -3
  60. package/lib/commonjs/components/ui/Avatar/Avatar.js.map +1 -1
  61. package/lib/commonjs/components/ui/Button/Button.js +16 -3
  62. package/lib/commonjs/components/ui/Button/Button.js.map +1 -1
  63. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js +21 -1
  64. package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
  65. package/lib/commonjs/i18n/en.json +35 -1
  66. package/lib/commonjs/i18n/es.json +35 -1
  67. package/lib/commonjs/i18n/fr.json +35 -1
  68. package/lib/commonjs/i18n/he.json +35 -1
  69. package/lib/commonjs/i18n/hi.json +35 -1
  70. package/lib/commonjs/i18n/it.json +35 -1
  71. package/lib/commonjs/i18n/ja.json +35 -1
  72. package/lib/commonjs/i18n/ko.json +35 -1
  73. package/lib/commonjs/i18n/nl.json +35 -1
  74. package/lib/commonjs/i18n/pt-br.json +35 -1
  75. package/lib/commonjs/i18n/ru.json +35 -1
  76. package/lib/commonjs/i18n/tr.json +35 -1
  77. package/lib/commonjs/mock-builders/DB/mock.js +3 -1
  78. package/lib/commonjs/mock-builders/DB/mock.js.map +1 -1
  79. package/lib/commonjs/test-utils/BetterSqlite.js +3 -2
  80. package/lib/commonjs/test-utils/BetterSqlite.js.map +1 -1
  81. package/lib/commonjs/version.json +1 -1
  82. package/lib/module/a11y/hooks/useA11yLabel.js +4 -3
  83. package/lib/module/a11y/hooks/useA11yLabel.js.map +1 -1
  84. package/lib/module/a11y/hooks/useAccessibilityActivateAction.js +25 -0
  85. package/lib/module/a11y/hooks/useAccessibilityActivateAction.js.map +1 -0
  86. package/lib/module/a11y/index.js +11 -0
  87. package/lib/module/a11y/index.js.map +1 -1
  88. package/lib/module/components/AttachmentPicker/AttachmentPicker.js +20 -0
  89. package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
  90. package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.js +1 -0
  91. package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.js.map +1 -1
  92. package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js +19 -2
  93. package/lib/module/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.js.map +1 -1
  94. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js +2 -1
  95. package/lib/module/components/AttachmentPicker/components/AttachmentPickerContent.js.map +1 -1
  96. package/lib/module/components/AttachmentPicker/components/AttachmentTypePickerButton.js +9 -1
  97. package/lib/module/components/AttachmentPicker/components/AttachmentTypePickerButton.js.map +1 -1
  98. package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js +2 -2
  99. package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
  100. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +1 -1
  101. package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
  102. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js +1 -1
  103. package/lib/module/components/ImageGallery/components/ImageGalleryVideoControl.js.map +1 -1
  104. package/lib/module/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.js +16 -4
  105. package/lib/module/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.js.map +1 -1
  106. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js +3 -0
  107. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecorder.js.map +1 -1
  108. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js +5 -0
  109. package/lib/module/components/MessageInput/components/AudioRecorder/AudioRecordingButton.js.map +1 -1
  110. package/lib/module/components/MessageInput/components/InputButtons/AttachButton.js +12 -3
  111. package/lib/module/components/MessageInput/components/InputButtons/AttachButton.js.map +1 -1
  112. package/lib/module/components/MessageInput/components/OutputButtons/EditButton.js +1 -0
  113. package/lib/module/components/MessageInput/components/OutputButtons/EditButton.js.map +1 -1
  114. package/lib/module/components/MessageInput/components/OutputButtons/SendButton.js +1 -0
  115. package/lib/module/components/MessageInput/components/OutputButtons/SendButton.js.map +1 -1
  116. package/lib/module/components/MessageList/MessageFlashList.js +19 -2
  117. package/lib/module/components/MessageList/MessageFlashList.js.map +1 -1
  118. package/lib/module/components/MessageList/MessageList.js +19 -2
  119. package/lib/module/components/MessageList/MessageList.js.map +1 -1
  120. package/lib/module/components/MessageList/ScrollToBottomButton.js +12 -6
  121. package/lib/module/components/MessageList/ScrollToBottomButton.js.map +1 -1
  122. package/lib/module/components/MessageList/UnreadMessagesNotification.js +1 -0
  123. package/lib/module/components/MessageList/UnreadMessagesNotification.js.map +1 -1
  124. package/lib/module/components/MessageList/hooks/useScrollToBottomAccessibilityAction.js +47 -0
  125. package/lib/module/components/MessageList/hooks/useScrollToBottomAccessibilityAction.js.map +1 -0
  126. package/lib/module/components/MessageMenu/MessageActionListItem.js +12 -4
  127. package/lib/module/components/MessageMenu/MessageActionListItem.js.map +1 -1
  128. package/lib/module/components/MessageMenu/MessageReactionPicker.js +1 -0
  129. package/lib/module/components/MessageMenu/MessageReactionPicker.js.map +1 -1
  130. package/lib/module/components/MessageMenu/ReactionButton.js +9 -6
  131. package/lib/module/components/MessageMenu/ReactionButton.js.map +1 -1
  132. package/lib/module/components/Poll/components/CreatePollHeader.js +2 -0
  133. package/lib/module/components/Poll/components/CreatePollHeader.js.map +1 -1
  134. package/lib/module/components/Poll/components/MultipleVotesSettings.js +2 -0
  135. package/lib/module/components/Poll/components/MultipleVotesSettings.js.map +1 -1
  136. package/lib/module/components/Poll/components/PollModalHeader.js +1 -0
  137. package/lib/module/components/Poll/components/PollModalHeader.js.map +1 -1
  138. package/lib/module/components/Reply/Reply.js +1 -0
  139. package/lib/module/components/Reply/Reply.js.map +1 -1
  140. package/lib/module/components/ui/Avatar/Avatar.js +6 -3
  141. package/lib/module/components/ui/Avatar/Avatar.js.map +1 -1
  142. package/lib/module/components/ui/Button/Button.js +16 -3
  143. package/lib/module/components/ui/Button/Button.js.map +1 -1
  144. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js +21 -1
  145. package/lib/module/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
  146. package/lib/module/i18n/en.json +35 -1
  147. package/lib/module/i18n/es.json +35 -1
  148. package/lib/module/i18n/fr.json +35 -1
  149. package/lib/module/i18n/he.json +35 -1
  150. package/lib/module/i18n/hi.json +35 -1
  151. package/lib/module/i18n/it.json +35 -1
  152. package/lib/module/i18n/ja.json +35 -1
  153. package/lib/module/i18n/ko.json +35 -1
  154. package/lib/module/i18n/nl.json +35 -1
  155. package/lib/module/i18n/pt-br.json +35 -1
  156. package/lib/module/i18n/ru.json +35 -1
  157. package/lib/module/i18n/tr.json +35 -1
  158. package/lib/module/mock-builders/DB/mock.js +3 -1
  159. package/lib/module/mock-builders/DB/mock.js.map +1 -1
  160. package/lib/module/test-utils/BetterSqlite.js +3 -2
  161. package/lib/module/test-utils/BetterSqlite.js.map +1 -1
  162. package/lib/module/version.json +1 -1
  163. package/lib/typescript/a11y/a11yUtils.d.ts +3 -3
  164. package/lib/typescript/a11y/a11yUtils.d.ts.map +1 -1
  165. package/lib/typescript/a11y/hooks/useA11yLabel.d.ts +2 -1
  166. package/lib/typescript/a11y/hooks/useA11yLabel.d.ts.map +1 -1
  167. package/lib/typescript/a11y/hooks/useAccessibilityActivateAction.d.ts +17 -0
  168. package/lib/typescript/a11y/hooks/useAccessibilityActivateAction.d.ts.map +1 -0
  169. package/lib/typescript/a11y/index.d.ts +1 -0
  170. package/lib/typescript/a11y/index.d.ts.map +1 -1
  171. package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
  172. package/lib/typescript/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.d.ts.map +1 -1
  173. package/lib/typescript/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.d.ts.map +1 -1
  174. package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerContent.d.ts.map +1 -1
  175. package/lib/typescript/components/AttachmentPicker/components/AttachmentTypePickerButton.d.ts +2 -1
  176. package/lib/typescript/components/AttachmentPicker/components/AttachmentTypePickerButton.d.ts.map +1 -1
  177. package/lib/typescript/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.d.ts +5 -2
  178. package/lib/typescript/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.d.ts.map +1 -1
  179. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecorder.d.ts.map +1 -1
  180. package/lib/typescript/components/MessageInput/components/AudioRecorder/AudioRecordingButton.d.ts.map +1 -1
  181. package/lib/typescript/components/MessageInput/components/InputButtons/AttachButton.d.ts +1 -0
  182. package/lib/typescript/components/MessageInput/components/InputButtons/AttachButton.d.ts.map +1 -1
  183. package/lib/typescript/components/MessageInput/components/OutputButtons/EditButton.d.ts.map +1 -1
  184. package/lib/typescript/components/MessageInput/components/OutputButtons/SendButton.d.ts.map +1 -1
  185. package/lib/typescript/components/MessageList/MessageFlashList.d.ts.map +1 -1
  186. package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
  187. package/lib/typescript/components/MessageList/ScrollToBottomButton.d.ts +2 -0
  188. package/lib/typescript/components/MessageList/ScrollToBottomButton.d.ts.map +1 -1
  189. package/lib/typescript/components/MessageList/UnreadMessagesNotification.d.ts.map +1 -1
  190. package/lib/typescript/components/MessageList/hooks/useScrollToBottomAccessibilityAction.d.ts +20 -0
  191. package/lib/typescript/components/MessageList/hooks/useScrollToBottomAccessibilityAction.d.ts.map +1 -0
  192. package/lib/typescript/components/MessageMenu/MessageActionListItem.d.ts.map +1 -1
  193. package/lib/typescript/components/MessageMenu/MessageReactionPicker.d.ts.map +1 -1
  194. package/lib/typescript/components/MessageMenu/ReactionButton.d.ts.map +1 -1
  195. package/lib/typescript/components/Poll/components/CreatePollHeader.d.ts.map +1 -1
  196. package/lib/typescript/components/Poll/components/MultipleVotesSettings.d.ts.map +1 -1
  197. package/lib/typescript/components/Poll/components/PollModalHeader.d.ts.map +1 -1
  198. package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
  199. package/lib/typescript/components/ui/Avatar/Avatar.d.ts.map +1 -1
  200. package/lib/typescript/components/ui/Button/Button.d.ts +10 -1
  201. package/lib/typescript/components/ui/Button/Button.d.ts.map +1 -1
  202. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts +1 -1
  203. package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts.map +1 -1
  204. package/lib/typescript/i18n/en.json +35 -1
  205. package/lib/typescript/i18n/es.json +35 -1
  206. package/lib/typescript/i18n/fr.json +35 -1
  207. package/lib/typescript/i18n/he.json +35 -1
  208. package/lib/typescript/i18n/hi.json +35 -1
  209. package/lib/typescript/i18n/it.json +35 -1
  210. package/lib/typescript/i18n/ja.json +35 -1
  211. package/lib/typescript/i18n/ko.json +35 -1
  212. package/lib/typescript/i18n/nl.json +35 -1
  213. package/lib/typescript/i18n/pt-br.json +35 -1
  214. package/lib/typescript/i18n/ru.json +35 -1
  215. package/lib/typescript/i18n/tr.json +35 -1
  216. package/lib/typescript/test-utils/BetterSqlite.d.ts.map +1 -1
  217. package/lib/typescript/utils/i18n/Streami18n.d.ts +34 -0
  218. package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
  219. package/package.json +1 -1
  220. package/src/__tests__/offline-support/offline-feature.tsx +40 -34
  221. package/src/a11y/a11yUtils.ts +2 -2
  222. package/src/a11y/hooks/useA11yLabel.ts +7 -4
  223. package/src/a11y/hooks/useAccessibilityActivateAction.ts +44 -0
  224. package/src/a11y/index.ts +1 -0
  225. package/src/components/AttachmentPicker/AttachmentPicker.tsx +23 -1
  226. package/src/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentMediaPicker.tsx +1 -0
  227. package/src/components/AttachmentPicker/components/AttachmentMediaPicker/AttachmentPickerItem.tsx +15 -2
  228. package/src/components/AttachmentPicker/components/AttachmentPickerContent.tsx +1 -0
  229. package/src/components/AttachmentPicker/components/AttachmentTypePickerButton.tsx +9 -0
  230. package/src/components/ChannelList/__tests__/ChannelListView.test.tsx +16 -5
  231. package/src/components/ImageGallery/__tests__/ImageGalleryFooter.test.tsx +9 -3
  232. package/src/components/ImageGallery/__tests__/ImageGalleryHeader.test.tsx +4 -1
  233. package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +2 -2
  234. package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +1 -1
  235. package/src/components/ImageGallery/components/ImageGalleryVideoControl.tsx +1 -1
  236. package/src/components/MessageInput/components/AttachmentPreview/AttachmentRemoveControl.tsx +18 -2
  237. package/src/components/MessageInput/components/AudioRecorder/AudioRecorder.tsx +3 -0
  238. package/src/components/MessageInput/components/AudioRecorder/AudioRecordingButton.tsx +8 -1
  239. package/src/components/MessageInput/components/InputButtons/AttachButton.tsx +13 -3
  240. package/src/components/MessageInput/components/OutputButtons/EditButton.tsx +1 -0
  241. package/src/components/MessageInput/components/OutputButtons/SendButton.tsx +1 -0
  242. package/src/components/MessageList/MessageFlashList.tsx +23 -2
  243. package/src/components/MessageList/MessageList.tsx +23 -2
  244. package/src/components/MessageList/ScrollToBottomButton.tsx +18 -6
  245. package/src/components/MessageList/UnreadMessagesNotification.tsx +1 -0
  246. package/src/components/MessageList/__tests__/MessageList.test.tsx +186 -0
  247. package/src/components/MessageList/__tests__/ScrollToBottomButton.test.tsx +2 -2
  248. package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.tsx.snap +2 -0
  249. package/src/components/MessageList/hooks/useScrollToBottomAccessibilityAction.ts +74 -0
  250. package/src/components/MessageMenu/MessageActionListItem.tsx +10 -4
  251. package/src/components/MessageMenu/MessageReactionPicker.tsx +1 -0
  252. package/src/components/MessageMenu/ReactionButton.tsx +7 -9
  253. package/src/components/MessageMenu/__tests__/MessageReactionPicker.test.tsx +13 -15
  254. package/src/components/MessageMenu/__tests__/MessageUserReactions.test.tsx +20 -18
  255. package/src/components/MessageMenu/__tests__/ReactionButton.test.tsx +18 -5
  256. package/src/components/Poll/components/CreatePollHeader.tsx +2 -0
  257. package/src/components/Poll/components/MultipleVotesSettings.tsx +2 -0
  258. package/src/components/Poll/components/PollModalHeader.tsx +1 -0
  259. package/src/components/Reply/Reply.tsx +4 -1
  260. package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +3 -0
  261. package/src/components/ui/Avatar/Avatar.tsx +2 -1
  262. package/src/components/ui/Button/Button.tsx +26 -0
  263. package/src/components/ui/Button/__tests__/Button.test.tsx +44 -0
  264. package/src/contexts/accessibilityContext/AccessibilityContext.tsx +35 -1
  265. package/src/i18n/en.json +35 -1
  266. package/src/i18n/es.json +35 -1
  267. package/src/i18n/fr.json +35 -1
  268. package/src/i18n/he.json +35 -1
  269. package/src/i18n/hi.json +35 -1
  270. package/src/i18n/it.json +35 -1
  271. package/src/i18n/ja.json +35 -1
  272. package/src/i18n/ko.json +35 -1
  273. package/src/i18n/nl.json +35 -1
  274. package/src/i18n/pt-br.json +35 -1
  275. package/src/i18n/ru.json +35 -1
  276. package/src/i18n/tr.json +35 -1
  277. package/src/mock-builders/DB/mock.ts +2 -1
  278. package/src/test-utils/BetterSqlite.ts +3 -1
  279. package/src/version.json +1 -1
@@ -1,5 +1,7 @@
1
+ import { useContext } from 'react';
2
+
1
3
  import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
2
- import { useTranslationContext } from '../../contexts/translationContext/TranslationContext';
4
+ import { TranslationContext } from '../../contexts/translationContext/TranslationContext';
3
5
 
4
6
  /**
5
7
  * Returns the translated `a11y/...` label when the AccessibilityContext is enabled,
@@ -8,12 +10,13 @@ import { useTranslationContext } from '../../contexts/translationContext/Transla
8
10
  * default disabled-state.
9
11
  *
10
12
  * Example:
11
- * const label = useA11yLabel('a11y/Avatar of {{name}}', { name });
13
+ * const labelParams = useMemo(() => ({ name }), [name]);
14
+ * const label = useA11yLabel('a11y/Avatar of {{name}}', labelParams);
12
15
  * <Image accessibilityLabel={label} />
13
16
  */
14
17
  export const useA11yLabel = (key: string, params?: Record<string, unknown>): string | undefined => {
15
18
  const { enabled } = useAccessibilityContext();
16
- const { t } = useTranslationContext();
17
- if (!enabled) return undefined;
19
+ const { t } = useContext(TranslationContext);
20
+ if (!enabled || !key) return undefined;
18
21
  return t(key, params);
19
22
  };
@@ -0,0 +1,44 @@
1
+ import type { AccessibilityActionEvent, AccessibilityProps } from 'react-native';
2
+
3
+ import { useAccessibilityContext } from '../../contexts/accessibilityContext/AccessibilityContext';
4
+
5
+ export type UseAccessibilityActivateActionProps<TPressEvent> = {
6
+ onPress?: ((event: TPressEvent) => void) | null;
7
+ shouldHandleActivate?: boolean;
8
+ };
9
+
10
+ export type UseAccessibilityActivateActionResult =
11
+ | {
12
+ accessibilityActions?: AccessibilityProps['accessibilityActions'];
13
+ onAccessibilityAction?: AccessibilityProps['onAccessibilityAction'];
14
+ }
15
+ | undefined;
16
+
17
+ const accessibilityActivateActions: NonNullable<AccessibilityProps['accessibilityActions']> = [
18
+ { name: 'activate' },
19
+ ];
20
+
21
+ /**
22
+ * Adds the standard screen-reader `activate` action for labeled pressables when
23
+ * SDK accessibility is enabled. Some Android pressable implementations don't
24
+ * reliably map TalkBack double-tap to `onPress`, so this bridges the generated
25
+ * accessibility action back to the existing press handler.
26
+ */
27
+ export const useAccessibilityActivateAction = <TPressEvent>({
28
+ onPress,
29
+ shouldHandleActivate = false,
30
+ }: UseAccessibilityActivateActionProps<TPressEvent>): UseAccessibilityActivateActionResult => {
31
+ const { enabled } = useAccessibilityContext();
32
+ const shouldHandleAccessibilityActivate = enabled && shouldHandleActivate && !!onPress;
33
+
34
+ if (!shouldHandleAccessibilityActivate) return undefined;
35
+
36
+ return {
37
+ accessibilityActions: accessibilityActivateActions,
38
+ onAccessibilityAction: (event: AccessibilityActionEvent) => {
39
+ if (event.nativeEvent.actionName !== 'activate') return;
40
+
41
+ onPress(event as unknown as TPressEvent);
42
+ },
43
+ };
44
+ };
package/src/a11y/index.ts CHANGED
@@ -4,3 +4,4 @@ export * from './hooks/useReducedMotionPreference';
4
4
  export * from './hooks/useResolvedModalAccessibilityProps';
5
5
  export * from './hooks/useAnnounceOnStateChange';
6
6
  export * from './hooks/useA11yLabel';
7
+ export * from './hooks/useAccessibilityActivateAction';
@@ -6,11 +6,13 @@ import {
6
6
  Platform,
7
7
  View,
8
8
  LayoutChangeEvent,
9
+ useWindowDimensions,
9
10
  } from 'react-native';
10
11
 
11
12
  import { runOnJS, useAnimatedReaction, useSharedValue } from 'react-native-reanimated';
12
13
 
13
14
  import { useBottomSheetSpringConfigs } from '@gorhom/bottom-sheet';
15
+ import type { BottomSheetBackgroundProps } from '@gorhom/bottom-sheet';
14
16
  import dayjs from 'dayjs';
15
17
  import duration from 'dayjs/plugin/duration';
16
18
 
@@ -38,13 +40,14 @@ export const AttachmentPicker = () => {
38
40
  attachmentPickerStore,
39
41
  attachmentPickerBottomSheetHeight,
40
42
  bottomSheetRef: ref,
43
+ bottomInset,
41
44
  disableAttachmentPicker,
42
45
  } = useAttachmentPickerContext();
43
46
  const { AttachmentPickerContent, AttachmentPickerSelectionBar } = useComponentsContext();
44
47
  const {
45
48
  theme: { semantics },
46
49
  } = useTheme();
47
-
50
+ const { height: windowHeight } = useWindowDimensions();
48
51
  const [currentIndex, setCurrentIndexInternal] = useState(-1);
49
52
  const currentIndexRef = useRef<number>(currentIndex);
50
53
  const setCurrentIndex = useStableCallback((_: number, toIndex: number) => {
@@ -99,6 +102,10 @@ export const AttachmentPicker = () => {
99
102
  const selectionBarRef = useRef<number | null>(null);
100
103
 
101
104
  const initialSnapPoint = attachmentPickerBottomSheetHeight;
105
+ const pickerTopInset = Math.max(
106
+ 0,
107
+ windowHeight - attachmentPickerBottomSheetHeight - bottomInset,
108
+ );
102
109
 
103
110
  /**
104
111
  * Snap points changing cause a rerender of the position,
@@ -150,8 +157,13 @@ export const AttachmentPicker = () => {
150
157
 
151
158
  return (
152
159
  <BottomSheet
160
+ accessible={false}
161
+ accessibilityLabel={null}
162
+ accessibilityRole={null}
153
163
  android_keyboardInputMode='adjustResize'
164
+ backgroundComponent={AttachmentPickerBackground}
154
165
  backgroundStyle={backgroundStyle}
166
+ bottomInset={bottomInset}
155
167
  enablePanDownToClose={false}
156
168
  enableContentPanningGesture={false}
157
169
  enableDynamicSizing={false}
@@ -162,6 +174,7 @@ export const AttachmentPicker = () => {
162
174
  // @ts-ignore
163
175
  ref={ref}
164
176
  snapPoints={snapPoints}
177
+ topInset={pickerTopInset}
165
178
  animationConfigs={animationConfigs}
166
179
  >
167
180
  <View onLayout={onAttachmentPickerSelectionBarLayout}>
@@ -178,4 +191,13 @@ export const AttachmentPicker = () => {
178
191
 
179
192
  const RenderNull = () => null;
180
193
 
194
+ const AttachmentPickerBackground = ({ pointerEvents, style }: BottomSheetBackgroundProps) => (
195
+ <View
196
+ accessible={false}
197
+ importantForAccessibility='no'
198
+ pointerEvents={pointerEvents}
199
+ style={style}
200
+ />
201
+ );
202
+
181
203
  AttachmentPicker.displayName = 'AttachmentPicker';
@@ -172,6 +172,7 @@ export const AttachmentMediaPicker = (props: AttachmentPickerContentProps) => {
172
172
  numColumns={numberOfColumns}
173
173
  onEndReached={photoError ? undefined : getMorePhotos}
174
174
  renderItem={renderAttachmentPickerItem}
175
+ showsVerticalScrollIndicator={false}
175
176
  testID={'attachment-picker-list'}
176
177
  updateCellsBatchingPeriod={16}
177
178
  />
@@ -6,6 +6,7 @@ import { FileReference, isLocalImageAttachment, isLocalVideoAttachment } from 's
6
6
 
7
7
  import { isIosLimited, type PhotoContentItemType } from './shared';
8
8
 
9
+ import { useA11yLabel } from '../../../../a11y/hooks/useA11yLabel';
9
10
  import { useAttachmentPickerContext } from '../../../../contexts';
10
11
  import { useComponentsContext } from '../../../../contexts/componentsContext/ComponentsContext';
11
12
  import { useAttachmentManagerState } from '../../../../contexts/messageInputContext/hooks/useAttachmentManagerState';
@@ -52,9 +53,11 @@ const AttachmentVideo = (props: AttachmentPickerItemType) => {
52
53
  const { duration: videoDuration, thumb_url } = asset;
53
54
 
54
55
  const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2;
56
+ const selected = selectedIndex !== -1;
57
+ const accessibilityLabel = useA11yLabel(selected ? 'a11y/Deselect video' : 'a11y/Select video');
55
58
 
56
59
  const onPressVideo = async () => {
57
- if (selectedIndex !== -1) {
60
+ if (selected) {
58
61
  const attachment = attachments[selectedIndex];
59
62
  if (attachment) {
60
63
  attachmentManager.removeAttachments([attachment.localMetadata.id]);
@@ -70,6 +73,10 @@ const AttachmentVideo = (props: AttachmentPickerItemType) => {
70
73
 
71
74
  return (
72
75
  <BottomSheetTouchableOpacity
76
+ accessible={accessibilityLabel ? true : undefined}
77
+ accessibilityLabel={accessibilityLabel}
78
+ accessibilityRole={accessibilityLabel ? 'button' : undefined}
79
+ accessibilityState={accessibilityLabel ? { selected } : undefined}
73
80
  onPress={onPressVideo}
74
81
  style={[
75
82
  {
@@ -110,11 +117,13 @@ const AttachmentImage = (props: AttachmentPickerItemType) => {
110
117
  );
111
118
 
112
119
  const size = vw(100) / (numberOfAttachmentPickerImageColumns || 3) - 2;
120
+ const selected = selectedIndex !== -1;
121
+ const accessibilityLabel = useA11yLabel(selected ? 'a11y/Deselect image' : 'a11y/Select image');
113
122
 
114
123
  const { uri } = asset;
115
124
 
116
125
  const onPressImage = async () => {
117
- if (selectedIndex !== -1) {
126
+ if (selected) {
118
127
  const attachment = attachments[selectedIndex];
119
128
  if (attachment) {
120
129
  await attachmentManager.removeAttachments([attachment.localMetadata.id]);
@@ -130,6 +139,10 @@ const AttachmentImage = (props: AttachmentPickerItemType) => {
130
139
 
131
140
  return (
132
141
  <BottomSheetTouchableOpacity
142
+ accessible={accessibilityLabel ? true : undefined}
143
+ accessibilityLabel={accessibilityLabel}
144
+ accessibilityRole={accessibilityLabel ? 'button' : undefined}
145
+ accessibilityState={accessibilityLabel ? { selected } : undefined}
133
146
  onPress={onPressImage}
134
147
  style={[
135
148
  {
@@ -141,6 +141,7 @@ export const AttachmentCommandPicker = () => {
141
141
  renderItem={renderItem}
142
142
  data={commands}
143
143
  keyExtractor={keyExtractor}
144
+ showsVerticalScrollIndicator={false}
144
145
  />
145
146
  </>
146
147
  );
@@ -28,12 +28,14 @@ import { Button, ButtonProps } from '../../ui';
28
28
  import { BottomSheetModal } from '../../UIComponents';
29
29
 
30
30
  export type AttachmentTypePickerButtonProps = Pick<ButtonProps, 'selected' | 'onPress'> & {
31
+ accessibilityLabelKey?: string;
31
32
  Icon: ButtonProps['LeadingIcon'];
32
33
  } & Pick<PressableProps, 'testID'>;
33
34
 
34
35
  const hitSlop = { bottom: 15, top: 15 };
35
36
 
36
37
  export const AttachmentTypePickerButton = ({
38
+ accessibilityLabelKey,
37
39
  testID,
38
40
  selected,
39
41
  onPress: onPressProp,
@@ -52,6 +54,7 @@ export const AttachmentTypePickerButton = ({
52
54
 
53
55
  return (
54
56
  <Button
57
+ accessibilityLabelKey={accessibilityLabelKey}
55
58
  testID={testID}
56
59
  hitSlop={hitSlop}
57
60
  onPress={onPress}
@@ -80,6 +83,7 @@ export const MediaPickerButton = () => {
80
83
 
81
84
  return hasImagePicker ? (
82
85
  <AttachmentTypePickerButton
86
+ accessibilityLabelKey='a11y/Open photo picker'
83
87
  testID='upload-photo-touchable'
84
88
  Icon={Picture}
85
89
  selected={selectedPicker === 'images'}
@@ -113,6 +117,7 @@ export const CameraPickerButton = () => {
113
117
  return hasCameraPicker ? (
114
118
  <>
115
119
  <AttachmentTypePickerButton
120
+ accessibilityLabelKey='a11y/Open camera'
116
121
  testID='take-photo-touchable'
117
122
  Icon={Camera}
118
123
  selected={selectedPicker === 'camera-photo'}
@@ -120,6 +125,7 @@ export const CameraPickerButton = () => {
120
125
  />
121
126
  {Platform.OS === 'android' ? (
122
127
  <AttachmentTypePickerButton
128
+ accessibilityLabelKey='a11y/Open video recorder'
123
129
  Icon={VideoIcon}
124
130
  selected={selectedPicker === 'camera-video'}
125
131
  onPress={onVideoRecorderPickerPress}
@@ -144,6 +150,7 @@ export const FilePickerButton = () => {
144
150
 
145
151
  return hasFilePicker ? (
146
152
  <AttachmentTypePickerButton
153
+ accessibilityLabelKey='a11y/Open file picker'
147
154
  testID='upload-file-touchable'
148
155
  Icon={FilePickerIcon}
149
156
  selected={selectedPicker === 'files'}
@@ -171,6 +178,7 @@ export const PollPickerButton = () => {
171
178
 
172
179
  return !threadList && hasCreatePoll && ownCapabilities.sendPoll ? ( // do not allow poll creation in threads
173
180
  <AttachmentTypePickerButton
181
+ accessibilityLabelKey='a11y/Open poll creation'
174
182
  testID='create-poll-touchable'
175
183
  Icon={PollThumbnail}
176
184
  selected={selectedPicker === 'polls'}
@@ -198,6 +206,7 @@ export const CommandsPickerButton = () => {
198
206
  return hasCommands ? (
199
207
  <>
200
208
  <AttachmentTypePickerButton
209
+ accessibilityLabelKey='a11y/Open commands'
201
210
  testID='commands-touchable'
202
211
  Icon={CommandsIcon}
203
212
  selected={selectedPicker === 'commands'}
@@ -1,13 +1,12 @@
1
1
  import React from 'react';
2
2
 
3
3
  import { cleanup, render, waitFor } from '@testing-library/react-native';
4
- import type { StreamChat } from 'stream-chat';
4
+ import type { Channel, QueryChannelsRequestType, StreamChat } from 'stream-chat';
5
5
 
6
6
  import type { ChannelsContextValue } from '../../../contexts/channelsContext/ChannelsContext';
7
7
  import { ChannelsProvider } from '../../../contexts/channelsContext/ChannelsContext';
8
8
  import { ChatContext, ChatProvider } from '../../../contexts/chatContext/ChatContext';
9
9
  import { getOrCreateChannelApi } from '../../../mock-builders/api/getOrCreateChannel';
10
- import { queryChannelsApi } from '../../../mock-builders/api/queryChannels';
11
10
  import { useMockedApis } from '../../../mock-builders/api/useMockedApis';
12
11
  import { generateChannelResponse } from '../../../mock-builders/generator/channel';
13
12
  import { getTestClientWithUser } from '../../../mock-builders/mock';
@@ -16,6 +15,11 @@ import { ChannelList } from '../ChannelList';
16
15
  import { ChannelListView } from '../ChannelListView';
17
16
 
18
17
  let chatClient: StreamChat;
18
+ let defaultChannels: Channel[];
19
+ let queryChannelsResponse: Channel[];
20
+
21
+ const queryChannelsOverride: QueryChannelsRequestType = () =>
22
+ Promise.resolve(queryChannelsResponse);
19
23
 
20
24
  /**
21
25
  * Renders the full ChannelList (which now always uses ChannelListView internally).
@@ -31,6 +35,7 @@ const Component = () => (
31
35
  $in: ['vishal', 'neil'],
32
36
  },
33
37
  }}
38
+ queryChannelsOverride={queryChannelsOverride}
34
39
  />
35
40
  </ChatProvider>
36
41
  )}
@@ -90,13 +95,19 @@ describe('ChannelListView', () => {
90
95
  chatClient = await getTestClientWithUser({ id: 'vishal' });
91
96
  const c1 = generateChannelResponse();
92
97
  const c2 = generateChannelResponse();
93
- useMockedApis(chatClient, [getOrCreateChannelApi(c1), getOrCreateChannelApi(c2)]);
98
+ useMockedApis(chatClient, [getOrCreateChannelApi(c1)]);
94
99
  const channel1 = chatClient.channel(c1.channel.type, c1.channel.id);
95
100
  await channel1.watch();
101
+ useMockedApis(chatClient, [getOrCreateChannelApi(c2)]);
96
102
  const channel2 = chatClient.channel(c2.channel.type, c2.channel.id);
97
103
  await channel2.watch();
98
- useMockedApis(chatClient, [queryChannelsApi([channel1, channel2])]);
104
+ defaultChannels = [channel1, channel2];
105
+ });
106
+
107
+ beforeEach(() => {
108
+ queryChannelsResponse = defaultChannels;
99
109
  });
110
+
100
111
  afterEach(cleanup);
101
112
 
102
113
  it('renders without crashing', async () => {
@@ -107,7 +118,7 @@ describe('ChannelListView', () => {
107
118
  });
108
119
 
109
120
  it('renders the `EmptyStateIndicator` when no channels are present', async () => {
110
- useMockedApis(chatClient, [queryChannelsApi([])]);
121
+ queryChannelsResponse = [];
111
122
  const { getByTestId } = render(<Component />);
112
123
  await waitFor(() => {
113
124
  expect(getByTestId('empty-channel-state-title')).toBeTruthy();
@@ -59,7 +59,10 @@ const ImageGalleryComponentVideo = (props: ImageGalleryProps) => {
59
59
  });
60
60
 
61
61
  return (
62
- <OverlayProvider value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}>
62
+ <OverlayProvider
63
+ accessibility={{ enabled: true }}
64
+ value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}
65
+ >
63
66
  {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
64
67
  <WithComponents overrides={{ ImageGalleryHeader: undefined as any }}>
65
68
  <ImageGalleryContext.Provider
@@ -101,7 +104,10 @@ const ImageGalleryComponentImage = (
101
104
  });
102
105
 
103
106
  return (
104
- <OverlayProvider value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}>
107
+ <OverlayProvider
108
+ accessibility={{ enabled: true }}
109
+ value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}
110
+ >
105
111
  {/* eslint-disable-next-line @typescript-eslint/no-explicit-any */}
106
112
  <WithComponents overrides={{ ImageGalleryHeader: undefined as any }}>
107
113
  <ImageGalleryContext.Provider
@@ -129,7 +135,7 @@ describe('ImageGalleryFooter', () => {
129
135
  });
130
136
  });
131
137
 
132
- it('render image gallery footer component with Share Button and Grid Icon', async () => {
138
+ it('render image gallery footer component with share and grid buttons', async () => {
133
139
  render(<ImageGalleryComponentVideo />);
134
140
 
135
141
  await waitFor(() => {
@@ -47,7 +47,10 @@ const ImageGalleryComponent = (props: ImageGalleryProps) => {
47
47
  }, [imageGalleryStateStore]);
48
48
 
49
49
  return (
50
- <OverlayProvider value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}>
50
+ <OverlayProvider
51
+ accessibility={{ enabled: true }}
52
+ value={{ overlayOpacity: { value: 1 } as SharedValue<number> }}
53
+ >
51
54
  <ImageGalleryContext.Provider
52
55
  value={
53
56
  {
@@ -134,7 +134,7 @@ export const ImageGalleryFooterWithContext = (props: ImageGalleryFooterProps) =>
134
134
  </Text>
135
135
  </View>
136
136
  <Button
137
- accessibilityLabel='Grid Icon'
137
+ accessibilityLabelKey='a11y/Grid Icon'
138
138
  variant='secondary'
139
139
  type='ghost'
140
140
  size='md'
@@ -166,7 +166,7 @@ const ShareButton = ({ share, savingInProgress }: ShareButtonProps) => {
166
166
  </View>
167
167
  ) : (
168
168
  <Button
169
- accessibilityLabel='Share Button'
169
+ accessibilityLabelKey='a11y/Share Button'
170
170
  variant='secondary'
171
171
  type='ghost'
172
172
  size='md'
@@ -74,7 +74,7 @@ export const ImageGalleryHeader = (props: ImageGalleryHeaderProps) => {
74
74
  <ReanimatedSafeAreaView edges={['top']} style={[styles.container, headerStyle]}>
75
75
  <View style={styles.innerContainer}>
76
76
  <Button
77
- accessibilityLabel='Hide Overlay'
77
+ accessibilityLabelKey='a11y/Hide Overlay'
78
78
  variant='secondary'
79
79
  type='ghost'
80
80
  size='md'
@@ -74,7 +74,7 @@ export const ImageGalleryVideoControl = React.memo((props: ImageGalleryVideoCont
74
74
  <View style={[styles.container, container]}>
75
75
  <View style={styles.leftContainer}>
76
76
  <Button
77
- accessibilityLabel='Play Pause Button'
77
+ accessibilityLabelKey='a11y/Play Pause Button'
78
78
  variant='secondary'
79
79
  type='ghost'
80
80
  size='md'
@@ -2,13 +2,22 @@ import React, { useMemo } from 'react';
2
2
 
3
3
  import { Pressable, PressableProps, StyleSheet } from 'react-native';
4
4
 
5
+ import { useA11yLabel } from '../../../../a11y/hooks/useA11yLabel';
5
6
  import { useTheme } from '../../../../contexts/themeContext/ThemeContext';
6
7
  import { NewClose } from '../../../../icons/xmark';
7
8
  import { primitives } from '../../../../theme';
8
9
 
9
- type AttachmentRemoveControlProps = PressableProps;
10
+ type AttachmentRemoveControlProps = PressableProps & {
11
+ accessibilityLabelKey?: string;
12
+ accessibilityLabelParams?: Record<string, unknown>;
13
+ };
10
14
 
11
- export const AttachmentRemoveControl = ({ onPress }: AttachmentRemoveControlProps) => {
15
+ export const AttachmentRemoveControl = ({
16
+ accessibilityLabelKey = 'a11y/Remove attachment',
17
+ accessibilityLabelParams,
18
+ onPress,
19
+ ...rest
20
+ }: AttachmentRemoveControlProps) => {
12
21
  const {
13
22
  theme: {
14
23
  semantics,
@@ -18,9 +27,15 @@ export const AttachmentRemoveControl = ({ onPress }: AttachmentRemoveControlProp
18
27
  },
19
28
  } = useTheme();
20
29
  const styles = useStyles();
30
+ const translatedAccessibilityLabel = useA11yLabel(
31
+ accessibilityLabelKey,
32
+ accessibilityLabelParams,
33
+ );
21
34
 
22
35
  return (
23
36
  <Pressable
37
+ accessibilityLabel={translatedAccessibilityLabel}
38
+ accessibilityRole='button'
24
39
  hitSlop={15}
25
40
  onPress={onPress}
26
41
  style={({ pressed }) => [
@@ -31,6 +46,7 @@ export const AttachmentRemoveControl = ({ onPress }: AttachmentRemoveControlProp
31
46
  dismiss,
32
47
  ]}
33
48
  testID='remove-upload-preview'
49
+ {...rest}
34
50
  >
35
51
  <NewClose
36
52
  height={16}
@@ -59,6 +59,7 @@ const StopRecording = ({
59
59
 
60
60
  return (
61
61
  <Button
62
+ accessibilityLabelKey='a11y/Stop voice recording'
62
63
  variant='destructive'
63
64
  type='outline'
64
65
  size='sm'
@@ -83,6 +84,7 @@ const UploadRecording = ({
83
84
 
84
85
  return (
85
86
  <Button
87
+ accessibilityLabelKey='a11y/Send voice recording'
86
88
  variant='primary'
87
89
  type='solid'
88
90
  onPress={onUploadVoiceRecording}
@@ -104,6 +106,7 @@ const DeleteRecording = ({
104
106
  };
105
107
  return (
106
108
  <Button
109
+ accessibilityLabelKey='a11y/Delete voice recording'
107
110
  variant='secondary'
108
111
  type='outline'
109
112
  size='sm'
@@ -10,6 +10,7 @@ import Animated, {
10
10
  withSpring,
11
11
  } from 'react-native-reanimated';
12
12
 
13
+ import { useA11yLabel } from '../../../../a11y/hooks/useA11yLabel';
13
14
  import { useActiveAudioPlayer } from '../../../../contexts/audioPlayerContext/AudioPlayerContext';
14
15
  import {
15
16
  MessageInputContextValue,
@@ -83,6 +84,7 @@ export const AudioRecordingButtonWithContext = (props: AudioRecordingButtonProps
83
84
  const pressed = useSharedValue(false);
84
85
 
85
86
  const { t } = useTranslationContext();
87
+ const startVoiceRecordingAccessibilityLabel = useA11yLabel('a11y/Start voice recording');
86
88
  const {
87
89
  theme: {
88
90
  messageComposer: { micButtonContainer },
@@ -238,7 +240,12 @@ export const AudioRecordingButtonWithContext = (props: AudioRecordingButtonProps
238
240
 
239
241
  return (
240
242
  <GestureDetector gesture={Gesture.Simultaneous(panGesture, tapGesture)}>
241
- <Animated.View style={[styles.container, animatedStyle, micButtonContainer]}>
243
+ <Animated.View
244
+ accessibilityLabel={startVoiceRecordingAccessibilityLabel}
245
+ accessibilityRole='button'
246
+ accessible
247
+ style={[styles.container, animatedStyle, micButtonContainer]}
248
+ >
242
249
  <Mic height={20} width={20} strokeWidth={1.5} stroke={buttonStyles.foregroundColor} />
243
250
  </Animated.View>
244
251
  </GestureDetector>
@@ -10,6 +10,7 @@ import {
10
10
  useMessageInputContext,
11
11
  } from '../../../../contexts/messageInputContext/MessageInputContext';
12
12
  import { useStableCallback } from '../../../../hooks';
13
+ import { useAttachmentPickerState } from '../../../../hooks/useAttachmentPickerState';
13
14
  import { Plus } from '../../../../icons/plus';
14
15
  import { Button } from '../../../ui/';
15
16
 
@@ -18,6 +19,7 @@ type AttachButtonPropsWithContext = Pick<MessageInputContextValue, 'handleAttach
18
19
  disabled?: boolean;
19
20
  /** Function that opens attachment options bottom sheet */
20
21
  handleOnPress?: ((event: GestureResponderEvent) => void) & (() => void);
22
+ isAttachmentPickerOpen?: boolean;
21
23
  } & { toggleAttachmentPicker: () => void };
22
24
 
23
25
  const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
@@ -25,6 +27,7 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
25
27
  disabled = false,
26
28
  handleAttachButtonPress,
27
29
  handleOnPress,
30
+ isAttachmentPickerOpen = false,
28
31
  toggleAttachmentPicker,
29
32
  } = props;
30
33
 
@@ -45,6 +48,9 @@ const AttachButtonWithContext = (props: AttachButtonPropsWithContext) => {
45
48
 
46
49
  return (
47
50
  <Button
51
+ accessibilityLabelKey={
52
+ isAttachmentPickerOpen ? 'a11y/Close attachments' : 'a11y/Add attachment'
53
+ }
48
54
  variant='secondary'
49
55
  type='outline'
50
56
  size='lg'
@@ -61,15 +67,17 @@ const areEqual = (
61
67
  prevProps: AttachButtonPropsWithContext,
62
68
  nextProps: AttachButtonPropsWithContext,
63
69
  ) => {
64
- const { handleOnPress: prevHandleOnPress } = prevProps;
65
- const { handleOnPress: nextHandleOnPress } = nextProps;
70
+ const { handleOnPress: prevHandleOnPress, isAttachmentPickerOpen: prevIsAttachmentPickerOpen } =
71
+ prevProps;
72
+ const { handleOnPress: nextHandleOnPress, isAttachmentPickerOpen: nextIsAttachmentPickerOpen } =
73
+ nextProps;
66
74
 
67
75
  const handleOnPressEqual = prevHandleOnPress === nextHandleOnPress;
68
76
  if (!handleOnPressEqual) {
69
77
  return false;
70
78
  }
71
79
 
72
- return true;
80
+ return prevIsAttachmentPickerOpen === nextIsAttachmentPickerOpen;
73
81
  };
74
82
 
75
83
  const MemoizedAttachButton = React.memo(
@@ -86,6 +94,7 @@ export const AttachButton = (props: AttachButtonProps) => {
86
94
  const { disableAttachmentPicker } = useAttachmentPickerContext();
87
95
  const { inputBoxRef, handleAttachButtonPress, openAttachmentPicker } = useMessageInputContext();
88
96
  const { attachmentPickerStore } = useAttachmentPickerContext();
97
+ const { selectedPicker } = useAttachmentPickerState();
89
98
 
90
99
  const toggleAttachmentPicker = useStableCallback(() => {
91
100
  if (attachmentPickerStore.state.getLatestValue().selectedPicker) {
@@ -100,6 +109,7 @@ export const AttachButton = (props: AttachButtonProps) => {
100
109
  {...{
101
110
  disableAttachmentPicker,
102
111
  handleAttachButtonPress,
112
+ isAttachmentPickerOpen: !!selectedPicker,
103
113
  toggleAttachmentPicker,
104
114
  }}
105
115
  {...props}
@@ -26,6 +26,7 @@ export const EditButton = (props: EditButtonProps) => {
26
26
 
27
27
  return (
28
28
  <Button
29
+ accessibilityLabelKey='a11y/Save edited message'
29
30
  variant='primary'
30
31
  type='solid'
31
32
  LeadingIcon={Tick}
@@ -26,6 +26,7 @@ export const SendButton = (props: SendButtonProps) => {
26
26
 
27
27
  return (
28
28
  <Button
29
+ accessibilityLabelKey='a11y/Send message'
29
30
  variant='primary'
30
31
  type='solid'
31
32
  disabled={disabled}