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.
- package/lib/commonjs/a11y/hooks/useAnnounceOnShow.js +27 -0
- package/lib/commonjs/a11y/hooks/useAnnounceOnShow.js.map +1 -0
- package/lib/commonjs/a11y/index.js +11 -0
- package/lib/commonjs/a11y/index.js.map +1 -1
- package/lib/commonjs/components/Accessibility/CompositeAccessibilityProbe.js +29 -0
- package/lib/commonjs/components/Accessibility/CompositeAccessibilityProbe.js.map +1 -0
- package/lib/commonjs/components/Accessibility/HiddenA11yText.js +30 -0
- package/lib/commonjs/components/Accessibility/HiddenA11yText.js.map +1 -0
- package/lib/commonjs/components/Accessibility/OverlayA11yShield.js +37 -0
- package/lib/commonjs/components/Accessibility/OverlayA11yShield.js.map +1 -0
- package/lib/commonjs/components/Accessibility/index.js +22 -0
- package/lib/commonjs/components/Accessibility/index.js.map +1 -1
- package/lib/commonjs/components/Attachment/Gallery.js +10 -0
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +31 -29
- package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js +11 -5
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewStatus.js +18 -2
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewStatus.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewUnreadCount.js +8 -2
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewUnreadCount.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js +3 -0
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js +56 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/Headers/MessageReminderHeader.js +2 -0
- package/lib/commonjs/components/Message/MessageItemView/Headers/MessageReminderHeader.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/Headers/SentToChannelHeader.js +2 -0
- package/lib/commonjs/components/Message/MessageItemView/Headers/SentToChannelHeader.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageContent.js +26 -4
- package/lib/commonjs/components/Message/MessageItemView/MessageContent.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageFooter.js +2 -0
- package/lib/commonjs/components/Message/MessageItemView/MessageFooter.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js +7 -3
- package/lib/commonjs/components/Message/MessageItemView/MessageReplies.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageRepliesAvatars.js +2 -0
- package/lib/commonjs/components/Message/MessageItemView/MessageRepliesAvatars.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js +35 -30
- package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js +16 -6
- package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListClustered.js +19 -6
- package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListClustered.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListItem.js +10 -1
- package/lib/commonjs/components/Message/MessageItemView/ReactionList/ReactionListItem.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +6 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js +8 -0
- package/lib/commonjs/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
- package/lib/commonjs/components/MessageList/InlineDateSeparator.js +8 -1
- package/lib/commonjs/components/MessageList/InlineDateSeparator.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/ReactionButton.js +0 -7
- package/lib/commonjs/components/MessageMenu/ReactionButton.js.map +1 -1
- package/lib/commonjs/components/Poll/Poll.js +2 -17
- package/lib/commonjs/components/Poll/Poll.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollOption.js +6 -1
- package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
- package/lib/commonjs/components/Reply/Reply.js +43 -6
- package/lib/commonjs/components/Reply/Reply.js.map +1 -1
- package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js +17 -11
- package/lib/commonjs/components/ui/Avatar/ChannelAvatar.js.map +1 -1
- package/lib/commonjs/components/ui/Badge/BadgeNotification.js +3 -1
- package/lib/commonjs/components/ui/Badge/BadgeNotification.js.map +1 -1
- package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js +6 -22
- package/lib/commonjs/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
- package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js +1 -0
- package/lib/commonjs/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +4 -1
- package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
- package/lib/commonjs/i18n/ar.json +26 -8
- package/lib/commonjs/i18n/en.json +23 -5
- package/lib/commonjs/i18n/es.json +23 -5
- package/lib/commonjs/i18n/fr.json +23 -5
- package/lib/commonjs/i18n/he.json +23 -5
- package/lib/commonjs/i18n/hi.json +24 -6
- package/lib/commonjs/i18n/it.json +23 -5
- package/lib/commonjs/i18n/ja.json +23 -5
- package/lib/commonjs/i18n/ko.json +23 -5
- package/lib/commonjs/i18n/nl.json +24 -6
- package/lib/commonjs/i18n/pt-br.json +25 -7
- package/lib/commonjs/i18n/ru.json +23 -5
- package/lib/commonjs/i18n/tr.json +24 -6
- package/lib/commonjs/state-store/image-gallery-state-store.js +13 -0
- package/lib/commonjs/state-store/image-gallery-state-store.js.map +1 -1
- package/lib/commonjs/utils/i18n/getDateString.js +26 -1
- package/lib/commonjs/utils/i18n/getDateString.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/a11y/hooks/useAnnounceOnShow.js +27 -0
- package/lib/module/a11y/hooks/useAnnounceOnShow.js.map +1 -0
- package/lib/module/a11y/index.js +11 -0
- package/lib/module/a11y/index.js.map +1 -1
- package/lib/module/components/Accessibility/CompositeAccessibilityProbe.js +29 -0
- package/lib/module/components/Accessibility/CompositeAccessibilityProbe.js.map +1 -0
- package/lib/module/components/Accessibility/HiddenA11yText.js +30 -0
- package/lib/module/components/Accessibility/HiddenA11yText.js.map +1 -0
- package/lib/module/components/Accessibility/OverlayA11yShield.js +37 -0
- package/lib/module/components/Accessibility/OverlayA11yShield.js.map +1 -0
- package/lib/module/components/Accessibility/index.js +22 -0
- package/lib/module/components/Accessibility/index.js.map +1 -1
- package/lib/module/components/Attachment/Gallery.js +10 -0
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +31 -29
- package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js +11 -5
- package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewStatus.js +18 -2
- package/lib/module/components/ChannelPreview/ChannelPreviewStatus.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewUnreadCount.js +8 -2
- package/lib/module/components/ChannelPreview/ChannelPreviewUnreadCount.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js +3 -0
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js +56 -1
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/Headers/MessageReminderHeader.js +2 -0
- package/lib/module/components/Message/MessageItemView/Headers/MessageReminderHeader.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/Headers/SentToChannelHeader.js +2 -0
- package/lib/module/components/Message/MessageItemView/Headers/SentToChannelHeader.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageContent.js +26 -4
- package/lib/module/components/Message/MessageItemView/MessageContent.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageFooter.js +2 -0
- package/lib/module/components/Message/MessageItemView/MessageFooter.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageReplies.js +7 -3
- package/lib/module/components/Message/MessageItemView/MessageReplies.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageRepliesAvatars.js +2 -0
- package/lib/module/components/Message/MessageItemView/MessageRepliesAvatars.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageStatus.js +35 -30
- package/lib/module/components/Message/MessageItemView/MessageStatus.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageTextContainer.js +16 -6
- package/lib/module/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListClustered.js +19 -6
- package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListClustered.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListItem.js +10 -1
- package/lib/module/components/Message/MessageItemView/ReactionList/ReactionListItem.js.map +1 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js +6 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/module/components/Message/hooks/useMessageActionHandlers.js +8 -0
- package/lib/module/components/Message/hooks/useMessageActionHandlers.js.map +1 -1
- package/lib/module/components/MessageList/InlineDateSeparator.js +8 -1
- package/lib/module/components/MessageList/InlineDateSeparator.js.map +1 -1
- package/lib/module/components/MessageMenu/ReactionButton.js +0 -7
- package/lib/module/components/MessageMenu/ReactionButton.js.map +1 -1
- package/lib/module/components/Poll/Poll.js +2 -17
- package/lib/module/components/Poll/Poll.js.map +1 -1
- package/lib/module/components/Poll/components/PollOption.js +6 -1
- package/lib/module/components/Poll/components/PollOption.js.map +1 -1
- package/lib/module/components/Reply/Reply.js +43 -6
- package/lib/module/components/Reply/Reply.js.map +1 -1
- package/lib/module/components/ui/Avatar/ChannelAvatar.js +17 -11
- package/lib/module/components/ui/Avatar/ChannelAvatar.js.map +1 -1
- package/lib/module/components/ui/Badge/BadgeNotification.js +3 -1
- package/lib/module/components/ui/Badge/BadgeNotification.js.map +1 -1
- package/lib/module/contexts/accessibilityContext/AccessibilityContext.js +6 -22
- package/lib/module/contexts/accessibilityContext/AccessibilityContext.js.map +1 -1
- package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js +1 -0
- package/lib/module/contexts/overlayContext/MessageOverlayHostLayer.js.map +1 -1
- package/lib/module/contexts/overlayContext/OverlayProvider.js +4 -1
- package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
- package/lib/module/i18n/ar.json +26 -8
- package/lib/module/i18n/en.json +23 -5
- package/lib/module/i18n/es.json +23 -5
- package/lib/module/i18n/fr.json +23 -5
- package/lib/module/i18n/he.json +23 -5
- package/lib/module/i18n/hi.json +24 -6
- package/lib/module/i18n/it.json +23 -5
- package/lib/module/i18n/ja.json +23 -5
- package/lib/module/i18n/ko.json +23 -5
- package/lib/module/i18n/nl.json +24 -6
- package/lib/module/i18n/pt-br.json +25 -7
- package/lib/module/i18n/ru.json +23 -5
- package/lib/module/i18n/tr.json +24 -6
- package/lib/module/state-store/image-gallery-state-store.js +13 -0
- package/lib/module/state-store/image-gallery-state-store.js.map +1 -1
- package/lib/module/utils/i18n/getDateString.js +26 -1
- package/lib/module/utils/i18n/getDateString.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/a11y/hooks/useAnnounceOnShow.d.ts +21 -0
- package/lib/typescript/a11y/hooks/useAnnounceOnShow.d.ts.map +1 -0
- package/lib/typescript/a11y/index.d.ts +1 -0
- package/lib/typescript/a11y/index.d.ts.map +1 -1
- package/lib/typescript/components/Accessibility/CompositeAccessibilityProbe.d.ts +30 -0
- package/lib/typescript/components/Accessibility/CompositeAccessibilityProbe.d.ts.map +1 -0
- package/lib/typescript/components/Accessibility/HiddenA11yText.d.ts +25 -0
- package/lib/typescript/components/Accessibility/HiddenA11yText.d.ts.map +1 -0
- package/lib/typescript/components/Accessibility/OverlayA11yShield.d.ts +20 -0
- package/lib/typescript/components/Accessibility/OverlayA11yShield.d.ts.map +1 -0
- package/lib/typescript/components/Accessibility/index.d.ts +2 -0
- package/lib/typescript/components/Accessibility/index.d.ts.map +1 -1
- package/lib/typescript/components/Attachment/Gallery.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewMutedStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewUnreadCount.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewView.d.ts.map +1 -1
- package/lib/typescript/components/ImageGallery/ImageGallery.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/Headers/MessageReminderHeader.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/Headers/SentToChannelHeader.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageContent.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageFooter.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageReplies.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageRepliesAvatars.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageStatus.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageTextContainer.d.ts +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageTextContainer.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/ReactionList/ReactionListClustered.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/ReactionList/ReactionListItem.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageOverlayWrapper.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useMessageActionHandlers.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/InlineDateSeparator.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/ReactionButton.d.ts.map +1 -1
- package/lib/typescript/components/Poll/Poll.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
- package/lib/typescript/components/Reply/Reply.d.ts.map +1 -1
- package/lib/typescript/components/ui/Avatar/ChannelAvatar.d.ts.map +1 -1
- package/lib/typescript/components/ui/Badge/BadgeNotification.d.ts +5 -0
- package/lib/typescript/components/ui/Badge/BadgeNotification.d.ts.map +1 -1
- package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts +32 -2
- package/lib/typescript/contexts/accessibilityContext/AccessibilityContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +8 -0
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
- package/lib/typescript/contexts/overlayContext/MessageOverlayHostLayer.d.ts.map +1 -1
- package/lib/typescript/contexts/overlayContext/OverlayProvider.d.ts.map +1 -1
- package/lib/typescript/hooks/useTranslatedMessage.d.ts +1 -1
- package/lib/typescript/i18n/ar.json +26 -8
- package/lib/typescript/i18n/en.json +23 -5
- package/lib/typescript/i18n/es.json +23 -5
- package/lib/typescript/i18n/fr.json +23 -5
- package/lib/typescript/i18n/he.json +23 -5
- package/lib/typescript/i18n/hi.json +24 -6
- package/lib/typescript/i18n/it.json +23 -5
- package/lib/typescript/i18n/ja.json +23 -5
- package/lib/typescript/i18n/ko.json +23 -5
- package/lib/typescript/i18n/nl.json +24 -6
- package/lib/typescript/i18n/pt-br.json +25 -7
- package/lib/typescript/i18n/ru.json +23 -5
- package/lib/typescript/i18n/tr.json +24 -6
- package/lib/typescript/state-store/image-gallery-state-store.d.ts +5 -1
- package/lib/typescript/state-store/image-gallery-state-store.d.ts.map +1 -1
- package/lib/typescript/utils/i18n/Streami18n.d.ts +22 -4
- package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
- package/lib/typescript/utils/i18n/getDateString.d.ts +28 -0
- package/lib/typescript/utils/i18n/getDateString.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/a11y/hooks/useAnnounceOnShow.ts +44 -0
- package/src/a11y/index.ts +1 -0
- package/src/components/Accessibility/CompositeAccessibilityProbe.tsx +48 -0
- package/src/components/Accessibility/HiddenA11yText.tsx +49 -0
- package/src/components/Accessibility/OverlayA11yShield.tsx +49 -0
- package/src/components/Accessibility/__tests__/OverlayA11yShield.test.tsx +83 -0
- package/src/components/Accessibility/index.ts +2 -0
- package/src/components/Attachment/Gallery.tsx +14 -2
- package/src/components/Channel/__tests__/ownCapabilities.test.tsx +25 -2
- package/src/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.tsx +19 -16
- package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx +8 -1
- package/src/components/ChannelPreview/ChannelPreviewStatus.tsx +26 -6
- package/src/components/ChannelPreview/ChannelPreviewUnreadCount.tsx +5 -1
- package/src/components/ChannelPreview/ChannelPreviewView.tsx +3 -0
- package/src/components/ImageGallery/ImageGallery.tsx +82 -4
- package/src/components/ImageGallery/__tests__/ImageGallery.test.tsx +13 -3
- package/src/components/ImageGallery/__tests__/ImageGalleryAdjustable.test.tsx +141 -0
- package/src/components/Message/MessageItemView/Headers/MessageReminderHeader.tsx +7 -1
- package/src/components/Message/MessageItemView/Headers/SentToChannelHeader.tsx +7 -1
- package/src/components/Message/MessageItemView/MessageContent.tsx +34 -4
- package/src/components/Message/MessageItemView/MessageFooter.tsx +6 -1
- package/src/components/Message/MessageItemView/MessageReplies.tsx +9 -7
- package/src/components/Message/MessageItemView/MessageRepliesAvatars.tsx +5 -1
- package/src/components/Message/MessageItemView/MessageStatus.tsx +36 -39
- package/src/components/Message/MessageItemView/MessageTextContainer.tsx +27 -4
- package/src/components/Message/MessageItemView/ReactionList/ReactionListClustered.tsx +24 -10
- package/src/components/Message/MessageItemView/ReactionList/ReactionListItem.tsx +7 -1
- package/src/components/Message/MessageItemView/__tests__/Message.test.tsx +10 -3
- package/src/components/Message/MessageItemView/__tests__/MessageReplies.test.tsx +10 -2
- package/src/components/Message/MessageItemView/__tests__/MessageStatus.test.tsx +10 -7
- package/src/components/Message/MessageItemView/__tests__/ReactionListBottom.test.tsx +1 -1
- package/src/components/Message/hooks/useCreateMessageContext.ts +12 -1
- package/src/components/Message/hooks/useMessageActionHandlers.ts +7 -0
- package/src/components/MessageInput/__tests__/__snapshots__/AttachButton.test.tsx.snap +3 -0
- package/src/components/MessageInput/__tests__/__snapshots__/SendButton.test.tsx.snap +2 -0
- package/src/components/MessageList/InlineDateSeparator.tsx +10 -3
- package/src/components/MessageMenu/ReactionButton.tsx +0 -7
- package/src/components/MessageMenu/__tests__/ReactionButton.test.tsx +1 -14
- package/src/components/Poll/Poll.tsx +2 -26
- package/src/components/Poll/components/PollOption.tsx +7 -1
- package/src/components/Reply/Reply.tsx +58 -7
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +9 -0
- package/src/components/ui/Avatar/ChannelAvatar.tsx +39 -29
- package/src/components/ui/Badge/BadgeNotification.tsx +11 -2
- package/src/contexts/accessibilityContext/AccessibilityContext.tsx +60 -36
- package/src/contexts/messageContext/MessageContext.tsx +8 -0
- package/src/contexts/overlayContext/MessageOverlayHostLayer.tsx +5 -1
- package/src/contexts/overlayContext/OverlayProvider.tsx +2 -1
- package/src/i18n/ar.json +26 -8
- package/src/i18n/en.json +23 -5
- package/src/i18n/es.json +23 -5
- package/src/i18n/fr.json +23 -5
- package/src/i18n/he.json +23 -5
- package/src/i18n/hi.json +24 -6
- package/src/i18n/it.json +23 -5
- package/src/i18n/ja.json +23 -5
- package/src/i18n/ko.json +23 -5
- package/src/i18n/nl.json +24 -6
- package/src/i18n/pt-br.json +25 -7
- package/src/i18n/ru.json +23 -5
- package/src/i18n/tr.json +24 -6
- package/src/state-store/__tests__/image-gallery-state-store.test.ts +1 -0
- package/src/state-store/image-gallery-state-store.ts +13 -1
- package/src/utils/i18n/getDateString.ts +57 -0
- package/src/version.json +1 -1
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js +0 -150
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityActions.js.map +0 -1
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js +0 -59
- package/lib/commonjs/components/Poll/hooks/usePollAccessibilityLabel.js.map +0 -1
- package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js +0 -150
- package/lib/module/components/Poll/hooks/usePollAccessibilityActions.js.map +0 -1
- package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js +0 -59
- package/lib/module/components/Poll/hooks/usePollAccessibilityLabel.js.map +0 -1
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts +0 -25
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityActions.d.ts.map +0 -1
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts +0 -8
- package/lib/typescript/components/Poll/hooks/usePollAccessibilityLabel.d.ts.map +0 -1
- package/src/components/Poll/hooks/__tests__/usePollAccessibilityActions.test.tsx +0 -358
- package/src/components/Poll/hooks/__tests__/usePollAccessibilityLabel.test.tsx +0 -142
- package/src/components/Poll/hooks/usePollAccessibilityActions.ts +0 -191
- 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
|
-
};
|