stream-chat-react-native-core 9.4.0-beta.10 → 9.4.0-beta.11
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/components/AutoCompleteInput/AutoCompleteInput.js +7 -0
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionHeader.js +2 -0
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionHeader.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +41 -55
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionList.js +27 -7
- package/lib/commonjs/components/AutoCompleteInput/AutoCompleteSuggestionList.js.map +1 -1
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.js +55 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.js +47 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.js +39 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionItem.js +45 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionItem.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionRoleItem.js +33 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionRoleItem.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.js +26 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionUserItem.js +53 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/MentionUserItem.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.js +38 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.js.map +1 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/index.js +60 -0
- package/lib/commonjs/components/AutoCompleteInput/mentionItems/index.js.map +1 -0
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js +14 -0
- package/lib/commonjs/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/utils/renderText.js +69 -11
- package/lib/commonjs/components/Message/MessageItemView/utils/renderText.js.map +1 -1
- package/lib/commonjs/components/MessageInput/MessageComposer.js +5 -12
- package/lib/commonjs/components/MessageInput/MessageComposer.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageFlashList.js +22 -3
- package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageList.js +23 -4
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js +4 -17
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/commonjs/components/UIComponents/ClippingFadeBottom.js +56 -0
- package/lib/commonjs/components/UIComponents/ClippingFadeBottom.js.map +1 -0
- package/lib/commonjs/components/UIComponents/PortalWhileClosingView.js +0 -3
- package/lib/commonjs/components/UIComponents/PortalWhileClosingView.js.map +1 -1
- package/lib/commonjs/components/UIComponents/index.js +11 -0
- package/lib/commonjs/components/UIComponents/index.js.map +1 -1
- package/lib/commonjs/components/index.js +11 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/componentsContext/defaultComponents.js +1 -0
- package/lib/commonjs/contexts/componentsContext/defaultComponents.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +6 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/i18n/ar.json +6 -0
- package/lib/commonjs/i18n/en.json +7 -1
- package/lib/commonjs/i18n/es.json +6 -0
- package/lib/commonjs/i18n/fr.json +6 -0
- package/lib/commonjs/i18n/he.json +6 -0
- package/lib/commonjs/i18n/hi.json +6 -0
- package/lib/commonjs/i18n/it.json +6 -0
- package/lib/commonjs/i18n/ja.json +6 -0
- package/lib/commonjs/i18n/ko.json +6 -0
- package/lib/commonjs/i18n/nl.json +6 -0
- package/lib/commonjs/i18n/pt-br.json +6 -0
- package/lib/commonjs/i18n/ru.json +6 -0
- package/lib/commonjs/i18n/tr.json +6 -0
- package/lib/commonjs/icons/megaphone.js +36 -0
- package/lib/commonjs/icons/megaphone.js.map +1 -0
- package/lib/commonjs/icons/shield.js +36 -0
- package/lib/commonjs/icons/shield.js.map +1 -0
- package/lib/commonjs/store/SqliteClient.js +1 -1
- package/lib/commonjs/store/mappers/mapDraftMessageToStorable.js +8 -0
- package/lib/commonjs/store/mappers/mapDraftMessageToStorable.js.map +1 -1
- package/lib/commonjs/store/mappers/mapStorableToDraftMessage.js +8 -0
- package/lib/commonjs/store/mappers/mapStorableToDraftMessage.js.map +1 -1
- package/lib/commonjs/store/schema.js +4 -0
- package/lib/commonjs/store/schema.js.map +1 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.android.js +10 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.android.js.map +1 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js +10 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.ios.js.map +1 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.web.js +10 -1
- package/lib/commonjs/theme/generated/dark/StreamTokens.web.js.map +1 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.android.js +10 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.android.js.map +1 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.ios.js +10 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.ios.js.map +1 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.web.js +10 -1
- package/lib/commonjs/theme/generated/light/StreamTokens.web.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js +7 -0
- package/lib/module/components/AutoCompleteInput/AutoCompleteInput.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionHeader.js +2 -0
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionHeader.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js +41 -55
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionItem.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionList.js +27 -7
- package/lib/module/components/AutoCompleteInput/AutoCompleteSuggestionList.js.map +1 -1
- package/lib/module/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.js +55 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.js +47 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.js +39 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionItem.js +45 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionItem.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionRoleItem.js +33 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionRoleItem.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.js +26 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionUserItem.js +53 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/MentionUserItem.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.js +38 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.js.map +1 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/index.js +60 -0
- package/lib/module/components/AutoCompleteInput/mentionItems/index.js.map +1 -0
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageTextContainer.js +14 -0
- package/lib/module/components/Message/MessageItemView/MessageTextContainer.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/utils/renderText.js +69 -11
- package/lib/module/components/Message/MessageItemView/utils/renderText.js.map +1 -1
- package/lib/module/components/MessageInput/MessageComposer.js +5 -12
- package/lib/module/components/MessageInput/MessageComposer.js.map +1 -1
- package/lib/module/components/MessageList/MessageFlashList.js +22 -3
- package/lib/module/components/MessageList/MessageFlashList.js.map +1 -1
- package/lib/module/components/MessageList/MessageList.js +23 -4
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/UIComponents/BottomSheetModal.js +4 -17
- package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/module/components/UIComponents/ClippingFadeBottom.js +56 -0
- package/lib/module/components/UIComponents/ClippingFadeBottom.js.map +1 -0
- package/lib/module/components/UIComponents/PortalWhileClosingView.js +0 -3
- package/lib/module/components/UIComponents/PortalWhileClosingView.js.map +1 -1
- package/lib/module/components/UIComponents/index.js +11 -0
- package/lib/module/components/UIComponents/index.js.map +1 -1
- package/lib/module/components/index.js +11 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/componentsContext/defaultComponents.js +1 -0
- package/lib/module/contexts/componentsContext/defaultComponents.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +6 -1
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/i18n/ar.json +6 -0
- package/lib/module/i18n/en.json +7 -1
- package/lib/module/i18n/es.json +6 -0
- package/lib/module/i18n/fr.json +6 -0
- package/lib/module/i18n/he.json +6 -0
- package/lib/module/i18n/hi.json +6 -0
- package/lib/module/i18n/it.json +6 -0
- package/lib/module/i18n/ja.json +6 -0
- package/lib/module/i18n/ko.json +6 -0
- package/lib/module/i18n/nl.json +6 -0
- package/lib/module/i18n/pt-br.json +6 -0
- package/lib/module/i18n/ru.json +6 -0
- package/lib/module/i18n/tr.json +6 -0
- package/lib/module/icons/megaphone.js +36 -0
- package/lib/module/icons/megaphone.js.map +1 -0
- package/lib/module/icons/shield.js +36 -0
- package/lib/module/icons/shield.js.map +1 -0
- package/lib/module/store/SqliteClient.js +1 -1
- package/lib/module/store/mappers/mapDraftMessageToStorable.js +8 -0
- package/lib/module/store/mappers/mapDraftMessageToStorable.js.map +1 -1
- package/lib/module/store/mappers/mapStorableToDraftMessage.js +8 -0
- package/lib/module/store/mappers/mapStorableToDraftMessage.js.map +1 -1
- package/lib/module/store/schema.js +4 -0
- package/lib/module/store/schema.js.map +1 -1
- package/lib/module/theme/generated/dark/StreamTokens.android.js +10 -1
- package/lib/module/theme/generated/dark/StreamTokens.android.js.map +1 -1
- package/lib/module/theme/generated/dark/StreamTokens.ios.js +10 -1
- package/lib/module/theme/generated/dark/StreamTokens.ios.js.map +1 -1
- package/lib/module/theme/generated/dark/StreamTokens.web.js +10 -1
- package/lib/module/theme/generated/dark/StreamTokens.web.js.map +1 -1
- package/lib/module/theme/generated/light/StreamTokens.android.js +10 -1
- package/lib/module/theme/generated/light/StreamTokens.android.js.map +1 -1
- package/lib/module/theme/generated/light/StreamTokens.ios.js +10 -1
- package/lib/module/theme/generated/light/StreamTokens.ios.js.map +1 -1
- package/lib/module/theme/generated/light/StreamTokens.web.js +10 -1
- package/lib/module/theme/generated/light/StreamTokens.web.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteInput.d.ts.map +1 -1
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionHeader.d.ts.map +1 -1
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionItem.d.ts +8 -2
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionItem.d.ts.map +1 -1
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionList.d.ts +1 -1
- package/lib/typescript/components/AutoCompleteInput/AutoCompleteSuggestionList.d.ts.map +1 -1
- package/lib/typescript/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.d.ts +13 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.d.ts +26 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.d.ts +7 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionItem.d.ts +17 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionItem.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionRoleItem.d.ts +7 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionRoleItem.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.d.ts +7 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionUserItem.d.ts +7 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/MentionUserItem.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.d.ts +21 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.d.ts.map +1 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/index.d.ts +17 -0
- package/lib/typescript/components/AutoCompleteInput/mentionItems/index.d.ts.map +1 -0
- package/lib/typescript/components/Message/Message.d.ts +11 -1
- package/lib/typescript/components/Message/Message.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageTextContainer.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/utils/renderText.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/MessageComposer.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/MessageFlashList.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/ClippingFadeBottom.d.ts +18 -0
- package/lib/typescript/components/UIComponents/ClippingFadeBottom.d.ts.map +1 -0
- package/lib/typescript/components/UIComponents/index.d.ts +1 -0
- package/lib/typescript/components/UIComponents/index.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +1 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts +1 -0
- package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts.map +1 -1
- package/lib/typescript/contexts/themeContext/ThemeContext.d.ts +5 -0
- package/lib/typescript/contexts/themeContext/ThemeContext.d.ts.map +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +5 -0
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/i18n/ar.json +6 -0
- package/lib/typescript/i18n/en.json +7 -1
- package/lib/typescript/i18n/es.json +6 -0
- package/lib/typescript/i18n/fr.json +6 -0
- package/lib/typescript/i18n/he.json +6 -0
- package/lib/typescript/i18n/hi.json +6 -0
- package/lib/typescript/i18n/it.json +6 -0
- package/lib/typescript/i18n/ja.json +6 -0
- package/lib/typescript/i18n/ko.json +6 -0
- package/lib/typescript/i18n/nl.json +6 -0
- package/lib/typescript/i18n/pt-br.json +6 -0
- package/lib/typescript/i18n/ru.json +6 -0
- package/lib/typescript/i18n/tr.json +6 -0
- package/lib/typescript/icons/megaphone.d.ts +4 -0
- package/lib/typescript/icons/megaphone.d.ts.map +1 -0
- package/lib/typescript/icons/shield.d.ts +4 -0
- package/lib/typescript/icons/shield.d.ts.map +1 -0
- package/lib/typescript/store/mappers/mapDraftMessageToStorable.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapStorableToDraftMessage.d.ts.map +1 -1
- package/lib/typescript/store/schema.d.ts +4 -0
- package/lib/typescript/store/schema.d.ts.map +1 -1
- package/lib/typescript/theme/generated/StreamTokens.types.d.ts +9 -0
- package/lib/typescript/theme/generated/StreamTokens.types.d.ts.map +1 -1
- package/lib/typescript/theme/generated/dark/StreamTokens.android.d.ts.map +1 -1
- package/lib/typescript/theme/generated/dark/StreamTokens.ios.d.ts.map +1 -1
- package/lib/typescript/theme/generated/dark/StreamTokens.web.d.ts.map +1 -1
- package/lib/typescript/theme/generated/light/StreamTokens.android.d.ts.map +1 -1
- package/lib/typescript/theme/generated/light/StreamTokens.ios.d.ts.map +1 -1
- package/lib/typescript/theme/generated/light/StreamTokens.web.d.ts.map +1 -1
- package/lib/typescript/utils/i18n/Streami18n.d.ts +6 -0
- package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/AutoCompleteInput/AutoCompleteInput.tsx +13 -0
- package/src/components/AutoCompleteInput/AutoCompleteSuggestionHeader.tsx +2 -1
- package/src/components/AutoCompleteInput/AutoCompleteSuggestionItem.tsx +35 -43
- package/src/components/AutoCompleteInput/AutoCompleteSuggestionList.tsx +28 -3
- package/src/components/AutoCompleteInput/mentionItems/EnhancedMentionContent.tsx +71 -0
- package/src/components/AutoCompleteInput/mentionItems/EnhancedMentionIcon.tsx +71 -0
- package/src/components/AutoCompleteInput/mentionItems/MentionBroadcastItem.tsx +36 -0
- package/src/components/AutoCompleteInput/mentionItems/MentionItem.tsx +59 -0
- package/src/components/AutoCompleteInput/mentionItems/MentionRoleItem.tsx +27 -0
- package/src/components/AutoCompleteInput/mentionItems/MentionUserGroupItem.tsx +23 -0
- package/src/components/AutoCompleteInput/mentionItems/MentionUserItem.tsx +55 -0
- package/src/components/AutoCompleteInput/mentionItems/TokenizedSuggestionParts.tsx +56 -0
- package/src/components/AutoCompleteInput/mentionItems/__tests__/MentionItems.test.tsx +129 -0
- package/src/components/AutoCompleteInput/mentionItems/__tests__/TokenizedSuggestionParts.test.tsx +63 -0
- package/src/components/AutoCompleteInput/mentionItems/index.ts +16 -0
- package/src/components/Message/Message.tsx +14 -2
- package/src/components/Message/MessageItemView/MessageTextContainer.tsx +25 -0
- package/src/components/Message/MessageItemView/utils/renderText.tsx +97 -18
- package/src/components/MessageInput/MessageComposer.tsx +7 -9
- package/src/components/MessageList/MessageFlashList.tsx +28 -0
- package/src/components/MessageList/MessageList.tsx +28 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.tsx.snap +24 -15
- package/src/components/UIComponents/BottomSheetModal.tsx +2 -17
- package/src/components/UIComponents/ClippingFadeBottom.tsx +47 -0
- package/src/components/UIComponents/PortalWhileClosingView.tsx +0 -4
- package/src/components/UIComponents/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/contexts/componentsContext/defaultComponents.ts +5 -1
- package/src/contexts/themeContext/utils/theme.ts +10 -0
- package/src/i18n/ar.json +6 -0
- package/src/i18n/en.json +7 -1
- package/src/i18n/es.json +6 -0
- package/src/i18n/fr.json +6 -0
- package/src/i18n/he.json +6 -0
- package/src/i18n/hi.json +6 -0
- package/src/i18n/it.json +6 -0
- package/src/i18n/ja.json +6 -0
- package/src/i18n/ko.json +6 -0
- package/src/i18n/nl.json +6 -0
- package/src/i18n/pt-br.json +6 -0
- package/src/i18n/ru.json +6 -0
- package/src/i18n/tr.json +6 -0
- package/src/icons/megaphone.tsx +21 -0
- package/src/icons/shield.tsx +21 -0
- package/src/store/SqliteClient.ts +1 -1
- package/src/store/mappers/mapDraftMessageToStorable.ts +8 -0
- package/src/store/mappers/mapStorableToDraftMessage.ts +8 -0
- package/src/store/schema.ts +8 -0
- package/src/theme/generated/StreamTokens.types.ts +9 -0
- package/src/theme/generated/dark/StreamTokens.android.ts +10 -1
- package/src/theme/generated/dark/StreamTokens.ios.ts +10 -1
- package/src/theme/generated/dark/StreamTokens.web.ts +10 -1
- package/src/theme/generated/light/StreamTokens.android.ts +10 -1
- package/src/theme/generated/light/StreamTokens.ios.ts +10 -1
- package/src/theme/generated/light/StreamTokens.web.ts +10 -1
- package/src/version.json +1 -1
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ChannelMentionSuggestion, HereMentionSuggestion } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { EnhancedMentionContent } from './EnhancedMentionContent';
|
|
6
|
+
import { EnhancedMentionIcon } from './EnhancedMentionIcon';
|
|
7
|
+
import { MentionItem } from './MentionItem';
|
|
8
|
+
|
|
9
|
+
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
|
|
10
|
+
import { Megaphone } from '../../../icons/megaphone';
|
|
11
|
+
|
|
12
|
+
export type MentionBroadcastItemProps = {
|
|
13
|
+
entity: ChannelMentionSuggestion | HereMentionSuggestion;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
// @channel and @here are literal SDK command keywords (matching mentioned_channel
|
|
17
|
+
// and mentioned_here on the wire). The title is not localized; only the
|
|
18
|
+
// description below it is.
|
|
19
|
+
const TITLE = { channel: '@channel', here: '@here' } as const;
|
|
20
|
+
const SUBTITLE_KEY = {
|
|
21
|
+
channel: 'mention/Channel Description',
|
|
22
|
+
here: 'mention/Here Description',
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
export const MentionBroadcastItem = ({ entity }: MentionBroadcastItemProps) => {
|
|
26
|
+
const { t } = useTranslationContext();
|
|
27
|
+
return (
|
|
28
|
+
<MentionItem leading={<EnhancedMentionIcon Icon={Megaphone} />}>
|
|
29
|
+
<EnhancedMentionContent
|
|
30
|
+
subtitle={t(SUBTITLE_KEY[entity.mentionType])}
|
|
31
|
+
testID='mentions-item-name'
|
|
32
|
+
title={TITLE[entity.mentionType]}
|
|
33
|
+
/>
|
|
34
|
+
</MentionItem>
|
|
35
|
+
);
|
|
36
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { PropsWithChildren, ReactNode, useMemo } from 'react';
|
|
2
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import { useTheme } from '../../../contexts/themeContext/ThemeContext';
|
|
5
|
+
import { primitives } from '../../../theme';
|
|
6
|
+
|
|
7
|
+
export type MentionItemProps = PropsWithChildren<{
|
|
8
|
+
/**
|
|
9
|
+
* Leading visual rendered to the left of the row. UserAvatar for user
|
|
10
|
+
* mentions, an `EnhancedMentionIcon` for the rest.
|
|
11
|
+
*/
|
|
12
|
+
leading?: ReactNode;
|
|
13
|
+
testID?: string;
|
|
14
|
+
}>;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Layout primitive for every mention-suggestion row: `[leading | content]`.
|
|
18
|
+
* The per-type content (tokenized user name, or `EnhancedMentionContent` for
|
|
19
|
+
* channel/here/role/user_group) is passed as children. Container and column
|
|
20
|
+
* styles come from `theme.messageComposer.suggestions.mention`.
|
|
21
|
+
*/
|
|
22
|
+
export const MentionItem = ({ children, leading, testID }: MentionItemProps) => {
|
|
23
|
+
const {
|
|
24
|
+
theme: {
|
|
25
|
+
messageComposer: {
|
|
26
|
+
suggestions: {
|
|
27
|
+
mention: { column, container },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
},
|
|
31
|
+
} = useTheme();
|
|
32
|
+
const styles = useStyles();
|
|
33
|
+
|
|
34
|
+
return (
|
|
35
|
+
<View style={[styles.container, container]} testID={testID}>
|
|
36
|
+
{leading}
|
|
37
|
+
<View style={[styles.column, column]}>{children}</View>
|
|
38
|
+
</View>
|
|
39
|
+
);
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const useStyles = () =>
|
|
43
|
+
useMemo(
|
|
44
|
+
() =>
|
|
45
|
+
StyleSheet.create({
|
|
46
|
+
column: {
|
|
47
|
+
flex: 1,
|
|
48
|
+
justifyContent: 'space-evenly',
|
|
49
|
+
},
|
|
50
|
+
container: {
|
|
51
|
+
alignItems: 'center',
|
|
52
|
+
flexDirection: 'row',
|
|
53
|
+
paddingHorizontal: primitives.spacingXs,
|
|
54
|
+
paddingVertical: primitives.spacingXs,
|
|
55
|
+
gap: primitives.spacingSm,
|
|
56
|
+
},
|
|
57
|
+
}),
|
|
58
|
+
[],
|
|
59
|
+
);
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { RoleMentionSuggestion } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { EnhancedMentionContent } from './EnhancedMentionContent';
|
|
6
|
+
import { EnhancedMentionIcon } from './EnhancedMentionIcon';
|
|
7
|
+
import { MentionItem } from './MentionItem';
|
|
8
|
+
|
|
9
|
+
import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
|
|
10
|
+
import { Shield } from '../../../icons/shield';
|
|
11
|
+
|
|
12
|
+
export type MentionRoleItemProps = {
|
|
13
|
+
entity: RoleMentionSuggestion;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const MentionRoleItem = ({ entity }: MentionRoleItemProps) => {
|
|
17
|
+
const { t } = useTranslationContext();
|
|
18
|
+
return (
|
|
19
|
+
<MentionItem leading={<EnhancedMentionIcon Icon={Shield} />}>
|
|
20
|
+
<EnhancedMentionContent
|
|
21
|
+
subtitle={t('Notify all {{ role }} members', { role: entity.name })}
|
|
22
|
+
testID='mentions-item-name'
|
|
23
|
+
title={`@${entity.name}`}
|
|
24
|
+
/>
|
|
25
|
+
</MentionItem>
|
|
26
|
+
);
|
|
27
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { UserGroupMentionSuggestion } from 'stream-chat';
|
|
4
|
+
|
|
5
|
+
import { EnhancedMentionContent } from './EnhancedMentionContent';
|
|
6
|
+
import { EnhancedMentionIcon } from './EnhancedMentionIcon';
|
|
7
|
+
import { MentionItem } from './MentionItem';
|
|
8
|
+
|
|
9
|
+
import { PeopleIcon } from '../../../icons/users';
|
|
10
|
+
|
|
11
|
+
export type MentionUserGroupItemProps = {
|
|
12
|
+
entity: UserGroupMentionSuggestion;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
export const MentionUserGroupItem = ({ entity }: MentionUserGroupItemProps) => (
|
|
16
|
+
<MentionItem leading={<EnhancedMentionIcon Icon={PeopleIcon} />}>
|
|
17
|
+
<EnhancedMentionContent
|
|
18
|
+
subtitle={entity.description}
|
|
19
|
+
testID='mentions-item-name'
|
|
20
|
+
title={`@${entity.name}`}
|
|
21
|
+
/>
|
|
22
|
+
</MentionItem>
|
|
23
|
+
);
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import React, { useMemo } from 'react';
|
|
2
|
+
import { View } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { UserSuggestion } from 'stream-chat';
|
|
5
|
+
|
|
6
|
+
import { MentionItem } from './MentionItem';
|
|
7
|
+
import { TokenizedSuggestionParts } from './TokenizedSuggestionParts';
|
|
8
|
+
|
|
9
|
+
import { useTheme } from '../../../contexts/themeContext/ThemeContext';
|
|
10
|
+
import { primitives } from '../../../theme';
|
|
11
|
+
import { UserAvatar } from '../../ui/Avatar/UserAvatar';
|
|
12
|
+
|
|
13
|
+
export type MentionUserItemProps = {
|
|
14
|
+
entity: UserSuggestion;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const MentionUserItem = ({ entity }: MentionUserItemProps) => {
|
|
18
|
+
const styles = useStyles();
|
|
19
|
+
|
|
20
|
+
return (
|
|
21
|
+
<MentionItem
|
|
22
|
+
leading={
|
|
23
|
+
<View importantForAccessibility='no-hide-descendants'>
|
|
24
|
+
<UserAvatar showOnlineIndicator={!!entity.online} size='md' user={entity} />
|
|
25
|
+
</View>
|
|
26
|
+
}
|
|
27
|
+
>
|
|
28
|
+
<TokenizedSuggestionParts
|
|
29
|
+
fallback={entity.name || entity.id}
|
|
30
|
+
matchStyle={styles.match}
|
|
31
|
+
style={styles.name}
|
|
32
|
+
testID='mentions-item-name'
|
|
33
|
+
tokenizedDisplayName={entity.tokenizedDisplayName}
|
|
34
|
+
/>
|
|
35
|
+
</MentionItem>
|
|
36
|
+
);
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const useStyles = () => {
|
|
40
|
+
const {
|
|
41
|
+
theme: { semantics },
|
|
42
|
+
} = useTheme();
|
|
43
|
+
return useMemo(
|
|
44
|
+
() => ({
|
|
45
|
+
match: { fontWeight: primitives.typographyFontWeightBold },
|
|
46
|
+
name: {
|
|
47
|
+
color: semantics.textPrimary,
|
|
48
|
+
fontSize: primitives.typographyFontSizeMd,
|
|
49
|
+
lineHeight: primitives.typographyLineHeightNormal,
|
|
50
|
+
paddingBottom: 2,
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
[semantics.textPrimary],
|
|
54
|
+
);
|
|
55
|
+
};
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { StyleProp, Text, TextStyle } from 'react-native';
|
|
3
|
+
|
|
4
|
+
import type { TokenizationPayload } from 'stream-chat';
|
|
5
|
+
|
|
6
|
+
export type TokenizedSuggestionPartsProps = {
|
|
7
|
+
/**
|
|
8
|
+
* Token + parts payload produced by the stream-chat-js text composer search
|
|
9
|
+
* source. When the consumer matches against a display name the source splits
|
|
10
|
+
* the name into substrings around the matched token; we render each part and
|
|
11
|
+
* bold whichever part case-insensitively equals the token.
|
|
12
|
+
*/
|
|
13
|
+
tokenizedDisplayName?: TokenizationPayload['tokenizedDisplayName'];
|
|
14
|
+
/**
|
|
15
|
+
* Fallback string rendered when the tokenized payload is absent (or empty).
|
|
16
|
+
*/
|
|
17
|
+
fallback?: string;
|
|
18
|
+
style?: StyleProp<TextStyle>;
|
|
19
|
+
matchStyle?: StyleProp<TextStyle>;
|
|
20
|
+
testID?: string;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const partMatchesToken = (part: string, token: string) =>
|
|
24
|
+
token.length > 0 && part.toLowerCase() === token.toLowerCase();
|
|
25
|
+
|
|
26
|
+
export const TokenizedSuggestionParts = ({
|
|
27
|
+
fallback,
|
|
28
|
+
matchStyle,
|
|
29
|
+
style,
|
|
30
|
+
tokenizedDisplayName,
|
|
31
|
+
testID,
|
|
32
|
+
}: TokenizedSuggestionPartsProps) => {
|
|
33
|
+
if (!tokenizedDisplayName || tokenizedDisplayName.parts.length === 0) {
|
|
34
|
+
if (!fallback) return null;
|
|
35
|
+
return (
|
|
36
|
+
<Text style={style} testID={testID}>
|
|
37
|
+
{fallback}
|
|
38
|
+
</Text>
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const { parts, token } = tokenizedDisplayName;
|
|
43
|
+
return (
|
|
44
|
+
<Text style={style} testID={testID}>
|
|
45
|
+
{parts.map((part, index) =>
|
|
46
|
+
partMatchesToken(part, token) ? (
|
|
47
|
+
<Text key={index} style={matchStyle}>
|
|
48
|
+
{part}
|
|
49
|
+
</Text>
|
|
50
|
+
) : (
|
|
51
|
+
part
|
|
52
|
+
),
|
|
53
|
+
)}
|
|
54
|
+
</Text>
|
|
55
|
+
);
|
|
56
|
+
};
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cleanup, render } from '@testing-library/react-native';
|
|
4
|
+
|
|
5
|
+
// UserAvatar pulls in ComponentsContext defaults which transitively load
|
|
6
|
+
// stream-chat-js's CJS dist; that fails to resolve @babel/runtime when the
|
|
7
|
+
// SDK is consumed from a workspace symlink during tests. The avatar itself
|
|
8
|
+
// isn't what we assert on here, so substitute a no-op.
|
|
9
|
+
jest.mock('../../../ui/Avatar/UserAvatar', () => ({
|
|
10
|
+
UserAvatar: () => null,
|
|
11
|
+
}));
|
|
12
|
+
|
|
13
|
+
// Same reason — useMessageComposer (used by AutoCompleteSuggestionItem) pulls
|
|
14
|
+
// stream-chat-js's CJS dist at module load. The dispatcher we're testing
|
|
15
|
+
// doesn't use these hooks itself, so stub them.
|
|
16
|
+
jest.mock('../../../../contexts/messageInputContext/hooks/useMessageComposer', () => ({
|
|
17
|
+
useMessageComposer: () => ({ textComposer: { handleSelect: () => {} } }),
|
|
18
|
+
}));
|
|
19
|
+
jest.mock('../../../../contexts/messageInputContext/hooks/useIsCommandDisabled', () => ({
|
|
20
|
+
useIsCommandDisabled: () => false,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
import type {
|
|
24
|
+
ChannelMentionSuggestion,
|
|
25
|
+
HereMentionSuggestion,
|
|
26
|
+
RoleMentionSuggestion,
|
|
27
|
+
UserGroupMentionSuggestion,
|
|
28
|
+
UserSuggestion,
|
|
29
|
+
} from 'stream-chat';
|
|
30
|
+
|
|
31
|
+
import { ThemeProvider } from '../../../../contexts/themeContext/ThemeContext';
|
|
32
|
+
import { defaultTheme } from '../../../../contexts/themeContext/utils/theme';
|
|
33
|
+
import { MentionSuggestionItem } from '../../AutoCompleteSuggestionItem';
|
|
34
|
+
|
|
35
|
+
const wrap = (ui: React.ReactElement) =>
|
|
36
|
+
render(<ThemeProvider theme={defaultTheme}>{ui}</ThemeProvider>);
|
|
37
|
+
|
|
38
|
+
const userEntity: UserSuggestion = {
|
|
39
|
+
id: 'u1',
|
|
40
|
+
mentionType: 'user',
|
|
41
|
+
name: 'Alice',
|
|
42
|
+
tokenizedDisplayName: { parts: ['Alice'], token: '' },
|
|
43
|
+
} as unknown as UserSuggestion;
|
|
44
|
+
|
|
45
|
+
const channelEntity: ChannelMentionSuggestion = {
|
|
46
|
+
id: 'channel',
|
|
47
|
+
mentionType: 'channel',
|
|
48
|
+
name: 'channel',
|
|
49
|
+
tokenizedDisplayName: { parts: ['channel'], token: '' },
|
|
50
|
+
} as unknown as ChannelMentionSuggestion;
|
|
51
|
+
|
|
52
|
+
const hereEntity: HereMentionSuggestion = {
|
|
53
|
+
id: 'here',
|
|
54
|
+
mentionType: 'here',
|
|
55
|
+
name: 'here',
|
|
56
|
+
tokenizedDisplayName: { parts: ['here'], token: '' },
|
|
57
|
+
} as unknown as HereMentionSuggestion;
|
|
58
|
+
|
|
59
|
+
const roleEntity: RoleMentionSuggestion = {
|
|
60
|
+
id: 'admin',
|
|
61
|
+
mentionType: 'role',
|
|
62
|
+
name: 'admin',
|
|
63
|
+
tokenizedDisplayName: { parts: ['admin'], token: '' },
|
|
64
|
+
} as unknown as RoleMentionSuggestion;
|
|
65
|
+
|
|
66
|
+
const groupEntity: UserGroupMentionSuggestion = {
|
|
67
|
+
description: 'Engineering org',
|
|
68
|
+
id: 'eng',
|
|
69
|
+
memberCount: 42,
|
|
70
|
+
mentionType: 'user_group',
|
|
71
|
+
name: 'engineering',
|
|
72
|
+
tokenizedDisplayName: { parts: ['engineering'], token: '' },
|
|
73
|
+
} as unknown as UserGroupMentionSuggestion;
|
|
74
|
+
|
|
75
|
+
describe('MentionSuggestionItem', () => {
|
|
76
|
+
afterEach(() => {
|
|
77
|
+
cleanup();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
it('renders a user row with the display name', () => {
|
|
81
|
+
const { getByText } = wrap(<MentionSuggestionItem {...userEntity} />);
|
|
82
|
+
expect(getByText('Alice')).toBeTruthy();
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('renders a broadcast row for @channel with description subtitle', () => {
|
|
86
|
+
const { getByText } = wrap(<MentionSuggestionItem {...channelEntity} />);
|
|
87
|
+
expect(getByText('@channel')).toBeTruthy();
|
|
88
|
+
expect(getByText('mention/Channel Description')).toBeTruthy();
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
it('renders a broadcast row for @here with description subtitle', () => {
|
|
92
|
+
const { getByText } = wrap(<MentionSuggestionItem {...hereEntity} />);
|
|
93
|
+
expect(getByText('@here')).toBeTruthy();
|
|
94
|
+
expect(getByText('mention/Here Description')).toBeTruthy();
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
it('renders a role row with the role name and the notify subtitle', () => {
|
|
98
|
+
const { getByText } = wrap(<MentionSuggestionItem {...roleEntity} />);
|
|
99
|
+
expect(getByText('@admin')).toBeTruthy();
|
|
100
|
+
// The test translation context echoes the i18n key; the {{ role }}
|
|
101
|
+
// interpolation is left as-is, which is enough to assert the right key
|
|
102
|
+
// was selected with the right argument.
|
|
103
|
+
expect(getByText(/Notify all .* members/)).toBeTruthy();
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('renders a user group row with name + description', () => {
|
|
107
|
+
const { getByText } = wrap(<MentionSuggestionItem {...groupEntity} />);
|
|
108
|
+
expect(getByText('@engineering')).toBeTruthy();
|
|
109
|
+
expect(getByText('Engineering org')).toBeTruthy();
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
it('omits the subtitle slot when a user group has no description', () => {
|
|
113
|
+
const { queryByText } = wrap(
|
|
114
|
+
<MentionSuggestionItem
|
|
115
|
+
{...({ ...groupEntity, description: undefined } as UserGroupMentionSuggestion)}
|
|
116
|
+
/>,
|
|
117
|
+
);
|
|
118
|
+
expect(queryByText('Engineering org')).toBeNull();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
it('renders nothing for an unknown mention type', () => {
|
|
122
|
+
const { toJSON } = wrap(
|
|
123
|
+
<MentionSuggestionItem
|
|
124
|
+
{...({ id: 'x', mentionType: 'unknown' } as unknown as ChannelMentionSuggestion)}
|
|
125
|
+
/>,
|
|
126
|
+
);
|
|
127
|
+
expect(toJSON()).toBeNull();
|
|
128
|
+
});
|
|
129
|
+
});
|
package/src/components/AutoCompleteInput/mentionItems/__tests__/TokenizedSuggestionParts.test.tsx
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
|
|
3
|
+
import { cleanup, render } from '@testing-library/react-native';
|
|
4
|
+
|
|
5
|
+
import { TokenizedSuggestionParts } from '../TokenizedSuggestionParts';
|
|
6
|
+
|
|
7
|
+
describe('TokenizedSuggestionParts', () => {
|
|
8
|
+
afterEach(() => {
|
|
9
|
+
cleanup();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('renders the fallback when no tokenized payload is provided', () => {
|
|
13
|
+
const { getByText } = render(<TokenizedSuggestionParts fallback='Jane Doe' />);
|
|
14
|
+
expect(getByText('Jane Doe')).toBeTruthy();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders nothing when neither tokenized payload nor fallback is provided', () => {
|
|
18
|
+
const { toJSON } = render(<TokenizedSuggestionParts />);
|
|
19
|
+
expect(toJSON()).toBeNull();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('renders all parts when the tokenized payload is present', () => {
|
|
23
|
+
const { queryByText } = render(
|
|
24
|
+
<TokenizedSuggestionParts tokenizedDisplayName={{ parts: ['Al', 'i', 'ce'], token: 'i' }} />,
|
|
25
|
+
);
|
|
26
|
+
// The full name still reads through because RN concatenates nested Text children.
|
|
27
|
+
expect(queryByText('Alice')).toBeTruthy();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('wraps the matched part in a separate Text node so it can be styled', () => {
|
|
31
|
+
const matchStyle = { fontWeight: 'bold' as const };
|
|
32
|
+
const { UNSAFE_root } = render(
|
|
33
|
+
<TokenizedSuggestionParts
|
|
34
|
+
matchStyle={matchStyle}
|
|
35
|
+
tokenizedDisplayName={{ parts: ['Al', 'ice', 'son'], token: 'ice' }}
|
|
36
|
+
/>,
|
|
37
|
+
);
|
|
38
|
+
// The matched substring is rendered inside a nested Text — the only one
|
|
39
|
+
// carrying our matchStyle — so the count of styled descendants equals the
|
|
40
|
+
// number of matching parts (case-insensitive).
|
|
41
|
+
const matchedNodes = UNSAFE_root.findAll(
|
|
42
|
+
(node) =>
|
|
43
|
+
typeof node.type !== 'string' &&
|
|
44
|
+
Array.isArray(node.props?.style) === false &&
|
|
45
|
+
node.props?.style === matchStyle,
|
|
46
|
+
);
|
|
47
|
+
expect(matchedNodes.length).toBe(1);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('matches case-insensitively', () => {
|
|
51
|
+
const matchStyle = { fontWeight: 'bold' as const };
|
|
52
|
+
const { UNSAFE_root } = render(
|
|
53
|
+
<TokenizedSuggestionParts
|
|
54
|
+
matchStyle={matchStyle}
|
|
55
|
+
tokenizedDisplayName={{ parts: ['Channel'], token: 'channel' }}
|
|
56
|
+
/>,
|
|
57
|
+
);
|
|
58
|
+
const matchedNodes = UNSAFE_root.findAll(
|
|
59
|
+
(node) => typeof node.type !== 'string' && node.props?.style === matchStyle,
|
|
60
|
+
);
|
|
61
|
+
expect(matchedNodes.length).toBe(1);
|
|
62
|
+
});
|
|
63
|
+
});
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export { EnhancedMentionContent } from './EnhancedMentionContent';
|
|
2
|
+
export type { EnhancedMentionContentProps } from './EnhancedMentionContent';
|
|
3
|
+
export { EnhancedMentionIcon } from './EnhancedMentionIcon';
|
|
4
|
+
export type { EnhancedMentionIconProps } from './EnhancedMentionIcon';
|
|
5
|
+
export { MentionBroadcastItem } from './MentionBroadcastItem';
|
|
6
|
+
export type { MentionBroadcastItemProps } from './MentionBroadcastItem';
|
|
7
|
+
export { MentionItem } from './MentionItem';
|
|
8
|
+
export type { MentionItemProps } from './MentionItem';
|
|
9
|
+
export { MentionRoleItem } from './MentionRoleItem';
|
|
10
|
+
export type { MentionRoleItemProps } from './MentionRoleItem';
|
|
11
|
+
export { MentionUserGroupItem } from './MentionUserGroupItem';
|
|
12
|
+
export type { MentionUserGroupItemProps } from './MentionUserGroupItem';
|
|
13
|
+
export { MentionUserItem } from './MentionUserItem';
|
|
14
|
+
export type { MentionUserItemProps } from './MentionUserItem';
|
|
15
|
+
export { TokenizedSuggestionParts } from './TokenizedSuggestionParts';
|
|
16
|
+
export type { TokenizedSuggestionPartsProps } from './TokenizedSuggestionParts';
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
12
12
|
import { Portal } from 'react-native-teleport';
|
|
13
13
|
|
|
14
|
-
import type { Attachment, LocalMessage, UserResponse } from 'stream-chat';
|
|
14
|
+
import type { Attachment, LocalMessage, MentionEntity, UserResponse } from 'stream-chat';
|
|
15
15
|
|
|
16
16
|
import { useCreateMessageContext } from './hooks/useCreateMessageContext';
|
|
17
17
|
import { useMessageActionHandlers } from './hooks/useMessageActionHandlers';
|
|
@@ -94,7 +94,19 @@ export type TouchableEmitter =
|
|
|
94
94
|
| 'messageReplies'
|
|
95
95
|
| 'reactionList';
|
|
96
96
|
|
|
97
|
-
export type TextMentionTouchableHandlerAdditionalInfo = {
|
|
97
|
+
export type TextMentionTouchableHandlerAdditionalInfo = {
|
|
98
|
+
/**
|
|
99
|
+
* The typed mention entity for the pressed mention (user / channel / here /
|
|
100
|
+
* role / user_group). Always populated by the default renderText pipeline;
|
|
101
|
+
* undefined only when a custom renderer doesn't resolve a match.
|
|
102
|
+
*/
|
|
103
|
+
mentionedEntity?: MentionEntity;
|
|
104
|
+
/**
|
|
105
|
+
* Back-compat: still populated when the mention is a user, so existing
|
|
106
|
+
* integrators reading `additionalInfo.user` keep working.
|
|
107
|
+
*/
|
|
108
|
+
user?: UserResponse;
|
|
109
|
+
};
|
|
98
110
|
|
|
99
111
|
export type TextMentionTouchableHandlerPayload = {
|
|
100
112
|
emitter: 'textMention';
|
|
@@ -166,6 +166,31 @@ const areEqual = (
|
|
|
166
166
|
return false;
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
+
// Enhanced mention sources (channel/here/roles/groups) — without these the
|
|
170
|
+
// renderText cache would refresh on a new entity but this comparator would
|
|
171
|
+
// short-circuit it away and the highlight would not appear until something
|
|
172
|
+
// else re-rendered the row.
|
|
173
|
+
const mentionedBroadcastEqual =
|
|
174
|
+
prevMessage.mentioned_channel === nextMessage.mentioned_channel &&
|
|
175
|
+
prevMessage.mentioned_here === nextMessage.mentioned_here;
|
|
176
|
+
if (!mentionedBroadcastEqual) {
|
|
177
|
+
return false;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const joinIds = (values?: string[]) => (values ?? []).join('|');
|
|
181
|
+
const mentionedRolesEqual =
|
|
182
|
+
joinIds(prevMessage.mentioned_roles) === joinIds(nextMessage.mentioned_roles);
|
|
183
|
+
if (!mentionedRolesEqual) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const groupIds = (m: typeof prevMessage) =>
|
|
188
|
+
joinIds(m.mentioned_groups?.map((g) => g.id) ?? m.mentioned_group_ids);
|
|
189
|
+
const mentionedGroupsEqual = groupIds(prevMessage) === groupIds(nextMessage);
|
|
190
|
+
if (!mentionedGroupsEqual) {
|
|
191
|
+
return false;
|
|
192
|
+
}
|
|
193
|
+
|
|
169
194
|
// stringify could be an expensive operation, so lets rule out the obvious
|
|
170
195
|
// possibilities first such as different object reference or empty objects etc.
|
|
171
196
|
// Also keeping markdown equality check at the last to make sure other less
|