stream-chat-react-native-core 10.0.0-rc.2 → 10.0.0-rc.4
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/ai-components/README.md +50 -2
- package/lib/commonjs/ai-components/index.js +24 -0
- package/lib/commonjs/ai-components/index.js.map +1 -1
- package/lib/commonjs/ai-components/message-composer/ComposerView.js +4 -2
- package/lib/commonjs/ai-components/message-composer/ComposerView.js.map +1 -1
- package/lib/commonjs/ai-components/message-composer/SpeechToTextButton.js +4 -1
- package/lib/commonjs/ai-components/message-composer/SpeechToTextButton.js.map +1 -1
- package/lib/commonjs/ai-components/native/AIDictation.js +6 -0
- package/lib/commonjs/ai-components/native/AIDictation.js.map +1 -1
- package/lib/commonjs/ai-components/store/dictation/store.js +4 -2
- package/lib/commonjs/ai-components/store/dictation/store.js.map +1 -1
- package/lib/commonjs/ai-components/store/dictation/useDictationState.js +4 -2
- package/lib/commonjs/ai-components/store/dictation/useDictationState.js.map +1 -1
- package/lib/commonjs/ai-components/store/index.js +22 -0
- package/lib/commonjs/ai-components/store/index.js.map +1 -1
- package/lib/commonjs/ai-components/theme.js +3 -0
- package/lib/commonjs/ai-components/theme.js.map +1 -1
- package/lib/commonjs/ai-components/transcription/useDictation.js +7 -3
- package/lib/commonjs/ai-components/transcription/useDictation.js.map +1 -1
- package/lib/commonjs/ai-components/transcription/useDictationAudioLevel.js +32 -0
- package/lib/commonjs/ai-components/transcription/useDictationAudioLevel.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceGlow.js +79 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceGlow.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceVisualizationView.js +147 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceVisualizationView.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceWave.js +58 -0
- package/lib/commonjs/ai-components/voice-visualization/VoiceWave.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/bounce.js +60 -0
- package/lib/commonjs/ai-components/voice-visualization/bounce.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/driver.js +208 -0
- package/lib/commonjs/ai-components/voice-visualization/driver.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/glowShader.js +218 -0
- package/lib/commonjs/ai-components/voice-visualization/glowShader.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/index.js +18 -0
- package/lib/commonjs/ai-components/voice-visualization/index.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/math.js +70 -0
- package/lib/commonjs/ai-components/voice-visualization/math.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/palette.js +47 -0
- package/lib/commonjs/ai-components/voice-visualization/palette.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/simplex.js +77 -0
- package/lib/commonjs/ai-components/voice-visualization/simplex.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/styles.js +33 -0
- package/lib/commonjs/ai-components/voice-visualization/styles.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/types.js +4 -0
- package/lib/commonjs/ai-components/voice-visualization/types.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/useReduceMotion.js +28 -0
- package/lib/commonjs/ai-components/voice-visualization/useReduceMotion.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/useVoiceVisualization.js +129 -0
- package/lib/commonjs/ai-components/voice-visualization/useVoiceVisualization.js.map +1 -0
- package/lib/commonjs/ai-components/voice-visualization/waveGeometry.js +124 -0
- package/lib/commonjs/ai-components/voice-visualization/waveGeometry.js.map +1 -0
- package/lib/commonjs/components/Channel/Channel.js +1 -0
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/ChannelShell.js +8 -1
- package/lib/commonjs/components/Channel/ChannelShell.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useChannelLifecycle.js +2 -1
- package/lib/commonjs/components/Channel/hooks/useChannelLifecycle.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useJumpToLatestOnOpen.js +26 -0
- package/lib/commonjs/components/Channel/hooks/useJumpToLatestOnOpen.js.map +1 -0
- package/lib/commonjs/components/ChannelDetails/components/members/ChannelMemberItem.js +1 -1
- package/lib/commonjs/components/ChannelDetails/components/members/ChannelMemberItem.js.map +1 -1
- package/lib/commonjs/components/ChannelDetails/hooks/useChannelDetailsMemberStatusText.js +1 -1
- package/lib/commonjs/components/ChannelDetails/hooks/useChannelDetailsMemberStatusText.js.map +1 -1
- package/lib/commonjs/components/ChannelList/ChannelListView.js +0 -2
- package/lib/commonjs/components/ChannelList/ChannelListView.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +2 -2
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelLastMessagePreview.js +1 -0
- package/lib/commonjs/components/ChannelPreview/ChannelLastMessagePreview.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +2 -0
- package/lib/commonjs/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewTitle.js +1 -0
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewTitle.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js +5 -5
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewDisplayName.js +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewDisplayName.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.js +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewPollLabel.js +4 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewPollLabel.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useConnectionLifecycle.js +6 -2
- package/lib/commonjs/components/Chat/hooks/useConnectionLifecycle.js.map +1 -1
- package/lib/commonjs/components/Indicators/LoadingErrorIndicator.js +5 -0
- package/lib/commonjs/components/Indicators/LoadingErrorIndicator.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +1 -1
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js +4 -0
- package/lib/commonjs/components/Message/MessageItemView/MessageStatus.js.map +1 -1
- package/lib/commonjs/components/Message/MessageItemView/MessageWrapper.js +7 -4
- package/lib/commonjs/components/Message/MessageItemView/MessageWrapper.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageActionHandlers.js +3 -3
- package/lib/commonjs/components/Message/hooks/useCreateMessageActionHandlers.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js +2 -2
- package/lib/commonjs/components/Message/hooks/useProcessReactions.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useUserMuteActive.js +1 -1
- package/lib/commonjs/components/Message/hooks/useUserMuteActive.js.map +1 -1
- package/lib/commonjs/components/MessageInput/MessageComposer.js +2 -1
- package/lib/commonjs/components/MessageInput/MessageComposer.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageFlashList.js +2 -2
- package/lib/commonjs/components/MessageList/MessageFlashList.js.map +1 -1
- package/lib/commonjs/components/MessageList/MessageList.js +2 -2
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/MessageList/hooks/useOwnUnreadCount.js +1 -1
- package/lib/commonjs/components/MessageList/hooks/useOwnUnreadCount.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/hooks/useMessageOwnReactions.js +2 -2
- package/lib/commonjs/components/MessageMenu/hooks/useMessageOwnReactions.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollAnswersList.js +1 -1
- package/lib/commonjs/components/Poll/components/PollAnswersList.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollButtons.js +1 -1
- package/lib/commonjs/components/Poll/components/PollButtons.js.map +1 -1
- package/lib/commonjs/components/Poll/hook/useIsPollCreatedByCurrentUser.js +1 -1
- package/lib/commonjs/components/Poll/hook/useIsPollCreatedByCurrentUser.js.map +1 -1
- package/lib/commonjs/components/Thread/Thread.js +1 -1
- package/lib/commonjs/components/Thread/Thread.js.map +1 -1
- package/lib/commonjs/components/ThreadList/ThreadListItem.js +1 -1
- package/lib/commonjs/components/ThreadList/ThreadListItem.js.map +1 -1
- package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js +9 -2
- package/lib/commonjs/components/ThreadList/ThreadListUnreadBanner.js.map +1 -1
- package/lib/commonjs/components/index.js +36 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/componentsContext/defaultComponents.js +0 -2
- package/lib/commonjs/contexts/componentsContext/defaultComponents.js.map +1 -1
- package/lib/commonjs/contexts/liveLocationManagerContext/LiveLocationManagerContext.js +1 -1
- package/lib/commonjs/contexts/liveLocationManagerContext/LiveLocationManagerContext.js.map +1 -1
- package/lib/commonjs/hooks/actions/useChannelActionItems.js +1 -1
- package/lib/commonjs/hooks/actions/useChannelActionItems.js.map +1 -1
- package/lib/commonjs/hooks/actions/useChannelActions.js +2 -2
- package/lib/commonjs/hooks/actions/useChannelActions.js.map +1 -1
- package/lib/commonjs/hooks/actions/useChannelMemberActionItems.js +1 -1
- package/lib/commonjs/hooks/actions/useChannelMemberActionItems.js.map +1 -1
- package/lib/commonjs/hooks/index.js +11 -0
- package/lib/commonjs/hooks/index.js.map +1 -1
- package/lib/commonjs/hooks/messagePreview/useMessageDeliveryStatus.js +6 -6
- package/lib/commonjs/hooks/messagePreview/useMessageDeliveryStatus.js.map +1 -1
- package/lib/commonjs/hooks/useIsDirectChat.js +1 -1
- package/lib/commonjs/hooks/useIsDirectChat.js.map +1 -1
- package/lib/commonjs/i18n/runtimeDefaults.js +1 -0
- package/lib/commonjs/i18n/runtimeDefaults.js.map +1 -1
- package/lib/commonjs/store/apis/getChannelMessages.js +5 -3
- package/lib/commonjs/store/apis/getChannelMessages.js.map +1 -1
- package/lib/commonjs/store/apis/getChannels.js +6 -3
- package/lib/commonjs/store/apis/getChannels.js.map +1 -1
- package/lib/commonjs/store/apis/getChannelsForFilterSort.js +2 -1
- package/lib/commonjs/store/apis/getChannelsForFilterSort.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js +7 -5
- package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/commonjs/utils/installNativeMultipartAdapter.js.map +1 -1
- package/lib/commonjs/utils/setupCommandUIMiddlewares.js +6 -3
- package/lib/commonjs/utils/setupCommandUIMiddlewares.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/ai-components/README.md +50 -2
- package/lib/module/ai-components/index.js +24 -0
- package/lib/module/ai-components/index.js.map +1 -1
- package/lib/module/ai-components/message-composer/ComposerView.js +4 -2
- package/lib/module/ai-components/message-composer/ComposerView.js.map +1 -1
- package/lib/module/ai-components/message-composer/SpeechToTextButton.js +4 -1
- package/lib/module/ai-components/message-composer/SpeechToTextButton.js.map +1 -1
- package/lib/module/ai-components/native/AIDictation.js +6 -0
- package/lib/module/ai-components/native/AIDictation.js.map +1 -1
- package/lib/module/ai-components/store/dictation/store.js +4 -2
- package/lib/module/ai-components/store/dictation/store.js.map +1 -1
- package/lib/module/ai-components/store/dictation/useDictationState.js +4 -2
- package/lib/module/ai-components/store/dictation/useDictationState.js.map +1 -1
- package/lib/module/ai-components/store/index.js +22 -0
- package/lib/module/ai-components/store/index.js.map +1 -1
- package/lib/module/ai-components/theme.js +3 -0
- package/lib/module/ai-components/theme.js.map +1 -1
- package/lib/module/ai-components/transcription/useDictation.js +7 -3
- package/lib/module/ai-components/transcription/useDictation.js.map +1 -1
- package/lib/module/ai-components/transcription/useDictationAudioLevel.js +32 -0
- package/lib/module/ai-components/transcription/useDictationAudioLevel.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/VoiceGlow.js +79 -0
- package/lib/module/ai-components/voice-visualization/VoiceGlow.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/VoiceVisualizationView.js +147 -0
- package/lib/module/ai-components/voice-visualization/VoiceVisualizationView.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/VoiceWave.js +58 -0
- package/lib/module/ai-components/voice-visualization/VoiceWave.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/bounce.js +60 -0
- package/lib/module/ai-components/voice-visualization/bounce.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/driver.js +208 -0
- package/lib/module/ai-components/voice-visualization/driver.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/glowShader.js +218 -0
- package/lib/module/ai-components/voice-visualization/glowShader.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/index.js +18 -0
- package/lib/module/ai-components/voice-visualization/index.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/math.js +70 -0
- package/lib/module/ai-components/voice-visualization/math.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/palette.js +47 -0
- package/lib/module/ai-components/voice-visualization/palette.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/simplex.js +77 -0
- package/lib/module/ai-components/voice-visualization/simplex.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/styles.js +33 -0
- package/lib/module/ai-components/voice-visualization/styles.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/types.js +4 -0
- package/lib/module/ai-components/voice-visualization/types.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/useReduceMotion.js +28 -0
- package/lib/module/ai-components/voice-visualization/useReduceMotion.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/useVoiceVisualization.js +129 -0
- package/lib/module/ai-components/voice-visualization/useVoiceVisualization.js.map +1 -0
- package/lib/module/ai-components/voice-visualization/waveGeometry.js +124 -0
- package/lib/module/ai-components/voice-visualization/waveGeometry.js.map +1 -0
- package/lib/module/components/Channel/Channel.js +1 -0
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/ChannelShell.js +8 -1
- package/lib/module/components/Channel/ChannelShell.js.map +1 -1
- package/lib/module/components/Channel/hooks/useChannelLifecycle.js +2 -1
- package/lib/module/components/Channel/hooks/useChannelLifecycle.js.map +1 -1
- package/lib/module/components/Channel/hooks/useJumpToLatestOnOpen.js +26 -0
- package/lib/module/components/Channel/hooks/useJumpToLatestOnOpen.js.map +1 -0
- package/lib/module/components/ChannelDetails/components/members/ChannelMemberItem.js +1 -1
- package/lib/module/components/ChannelDetails/components/members/ChannelMemberItem.js.map +1 -1
- package/lib/module/components/ChannelDetails/hooks/useChannelDetailsMemberStatusText.js +1 -1
- package/lib/module/components/ChannelDetails/hooks/useChannelDetailsMemberStatusText.js.map +1 -1
- package/lib/module/components/ChannelList/ChannelListView.js +0 -2
- package/lib/module/components/ChannelList/ChannelListView.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +2 -2
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js +1 -1
- package/lib/module/components/ChannelPreview/ChannelDetailsBottomSheet.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelLastMessagePreview.js +1 -0
- package/lib/module/components/ChannelPreview/ChannelLastMessagePreview.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js +2 -0
- package/lib/module/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewTitle.js +1 -0
- package/lib/module/components/ChannelPreview/ChannelPreviewTitle.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewView.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js +5 -5
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewDisplayName.js +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewDisplayName.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.js +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewPollLabel.js +4 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewPollLabel.js.map +1 -1
- package/lib/module/components/Chat/hooks/useConnectionLifecycle.js +6 -2
- package/lib/module/components/Chat/hooks/useConnectionLifecycle.js.map +1 -1
- package/lib/module/components/Indicators/LoadingErrorIndicator.js +5 -0
- package/lib/module/components/Indicators/LoadingErrorIndicator.js.map +1 -1
- package/lib/module/components/Message/Message.js +1 -1
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageStatus.js +4 -0
- package/lib/module/components/Message/MessageItemView/MessageStatus.js.map +1 -1
- package/lib/module/components/Message/MessageItemView/MessageWrapper.js +7 -4
- package/lib/module/components/Message/MessageItemView/MessageWrapper.js.map +1 -1
- package/lib/module/components/Message/hooks/useCreateMessageActionHandlers.js +3 -3
- package/lib/module/components/Message/hooks/useCreateMessageActionHandlers.js.map +1 -1
- package/lib/module/components/Message/hooks/useProcessReactions.js +2 -2
- package/lib/module/components/Message/hooks/useProcessReactions.js.map +1 -1
- package/lib/module/components/Message/hooks/useUserMuteActive.js +1 -1
- package/lib/module/components/Message/hooks/useUserMuteActive.js.map +1 -1
- package/lib/module/components/MessageInput/MessageComposer.js +2 -1
- package/lib/module/components/MessageInput/MessageComposer.js.map +1 -1
- package/lib/module/components/MessageList/MessageFlashList.js +2 -2
- package/lib/module/components/MessageList/MessageFlashList.js.map +1 -1
- package/lib/module/components/MessageList/MessageList.js +2 -2
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/MessageList/hooks/useOwnUnreadCount.js +1 -1
- package/lib/module/components/MessageList/hooks/useOwnUnreadCount.js.map +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactionsItem.js +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
- package/lib/module/components/MessageMenu/hooks/useMessageOwnReactions.js +2 -2
- package/lib/module/components/MessageMenu/hooks/useMessageOwnReactions.js.map +1 -1
- package/lib/module/components/Poll/components/PollAnswersList.js +1 -1
- package/lib/module/components/Poll/components/PollAnswersList.js.map +1 -1
- package/lib/module/components/Poll/components/PollButtons.js +1 -1
- package/lib/module/components/Poll/components/PollButtons.js.map +1 -1
- package/lib/module/components/Poll/hook/useIsPollCreatedByCurrentUser.js +1 -1
- package/lib/module/components/Poll/hook/useIsPollCreatedByCurrentUser.js.map +1 -1
- package/lib/module/components/Thread/Thread.js +1 -1
- package/lib/module/components/Thread/Thread.js.map +1 -1
- package/lib/module/components/ThreadList/ThreadListItem.js +1 -1
- package/lib/module/components/ThreadList/ThreadListItem.js.map +1 -1
- package/lib/module/components/ThreadList/ThreadListUnreadBanner.js +9 -2
- package/lib/module/components/ThreadList/ThreadListUnreadBanner.js.map +1 -1
- package/lib/module/components/index.js +36 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/componentsContext/defaultComponents.js +0 -2
- package/lib/module/contexts/componentsContext/defaultComponents.js.map +1 -1
- package/lib/module/contexts/liveLocationManagerContext/LiveLocationManagerContext.js +1 -1
- package/lib/module/contexts/liveLocationManagerContext/LiveLocationManagerContext.js.map +1 -1
- package/lib/module/hooks/actions/useChannelActionItems.js +1 -1
- package/lib/module/hooks/actions/useChannelActionItems.js.map +1 -1
- package/lib/module/hooks/actions/useChannelActions.js +2 -2
- package/lib/module/hooks/actions/useChannelActions.js.map +1 -1
- package/lib/module/hooks/actions/useChannelMemberActionItems.js +1 -1
- package/lib/module/hooks/actions/useChannelMemberActionItems.js.map +1 -1
- package/lib/module/hooks/index.js +11 -0
- package/lib/module/hooks/index.js.map +1 -1
- package/lib/module/hooks/messagePreview/useMessageDeliveryStatus.js +6 -6
- package/lib/module/hooks/messagePreview/useMessageDeliveryStatus.js.map +1 -1
- package/lib/module/hooks/useIsDirectChat.js +1 -1
- package/lib/module/hooks/useIsDirectChat.js.map +1 -1
- package/lib/module/i18n/runtimeDefaults.js +1 -0
- package/lib/module/i18n/runtimeDefaults.js.map +1 -1
- package/lib/module/store/apis/getChannelMessages.js +5 -3
- package/lib/module/store/apis/getChannelMessages.js.map +1 -1
- package/lib/module/store/apis/getChannels.js +6 -3
- package/lib/module/store/apis/getChannels.js.map +1 -1
- package/lib/module/store/apis/getChannelsForFilterSort.js +2 -1
- package/lib/module/store/apis/getChannelsForFilterSort.js.map +1 -1
- package/lib/module/store/apis/queries/selectMessagesForChannels.js +7 -5
- package/lib/module/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/module/utils/installNativeMultipartAdapter.js.map +1 -1
- package/lib/module/utils/setupCommandUIMiddlewares.js +6 -3
- package/lib/module/utils/setupCommandUIMiddlewares.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/ai-components/index.d.ts +3 -1
- package/lib/typescript/ai-components/index.d.ts.map +1 -1
- package/lib/typescript/ai-components/message-composer/ComposerView.d.ts.map +1 -1
- package/lib/typescript/ai-components/native/AIDictation.d.ts +6 -0
- package/lib/typescript/ai-components/native/AIDictation.d.ts.map +1 -1
- package/lib/typescript/ai-components/store/dictation/store.d.ts +7 -0
- package/lib/typescript/ai-components/store/dictation/store.d.ts.map +1 -1
- package/lib/typescript/ai-components/store/dictation/useDictationState.d.ts +1 -0
- package/lib/typescript/ai-components/store/dictation/useDictationState.d.ts.map +1 -1
- package/lib/typescript/ai-components/store/index.d.ts +2 -0
- package/lib/typescript/ai-components/store/index.d.ts.map +1 -1
- package/lib/typescript/ai-components/theme.d.ts +13 -0
- package/lib/typescript/ai-components/theme.d.ts.map +1 -1
- package/lib/typescript/ai-components/transcription/useDictation.d.ts +9 -1
- package/lib/typescript/ai-components/transcription/useDictation.d.ts.map +1 -1
- package/lib/typescript/ai-components/transcription/useDictationAudioLevel.d.ts +11 -0
- package/lib/typescript/ai-components/transcription/useDictationAudioLevel.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceGlow.d.ts +13 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceGlow.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceVisualizationView.d.ts +26 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceVisualizationView.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceWave.d.ts +13 -0
- package/lib/typescript/ai-components/voice-visualization/VoiceWave.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/bounce.d.ts +20 -0
- package/lib/typescript/ai-components/voice-visualization/bounce.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/driver.d.ts +96 -0
- package/lib/typescript/ai-components/voice-visualization/driver.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/glowShader.d.ts +7 -0
- package/lib/typescript/ai-components/voice-visualization/glowShader.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/index.d.ts +4 -0
- package/lib/typescript/ai-components/voice-visualization/index.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/math.d.ts +26 -0
- package/lib/typescript/ai-components/voice-visualization/math.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/palette.d.ts +18 -0
- package/lib/typescript/ai-components/voice-visualization/palette.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/simplex.d.ts +11 -0
- package/lib/typescript/ai-components/voice-visualization/simplex.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/styles.d.ts +24 -0
- package/lib/typescript/ai-components/voice-visualization/styles.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/types.d.ts +45 -0
- package/lib/typescript/ai-components/voice-visualization/types.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/useReduceMotion.d.ts +10 -0
- package/lib/typescript/ai-components/voice-visualization/useReduceMotion.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/useVoiceVisualization.d.ts +18 -0
- package/lib/typescript/ai-components/voice-visualization/useVoiceVisualization.d.ts.map +1 -0
- package/lib/typescript/ai-components/voice-visualization/waveGeometry.d.ts +25 -0
- package/lib/typescript/ai-components/voice-visualization/waveGeometry.d.ts.map +1 -0
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/ChannelShell.d.ts +2 -0
- package/lib/typescript/components/Channel/ChannelShell.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useChannelLifecycle.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useJumpToLatestOnOpen.d.ts +15 -0
- package/lib/typescript/components/Channel/hooks/useJumpToLatestOnOpen.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/ChannelListView.d.ts +1 -1
- package/lib/typescript/components/ChannelList/ChannelListView.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts.map +1 -1
- package/lib/typescript/components/Chat/hooks/useConnectionLifecycle.d.ts +5 -4
- package/lib/typescript/components/Chat/hooks/useConnectionLifecycle.d.ts.map +1 -1
- package/lib/typescript/components/Indicators/LoadingErrorIndicator.d.ts +1 -1
- package/lib/typescript/components/Indicators/LoadingErrorIndicator.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageStatus.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageItemView/MessageWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/MessageComposer.d.ts.map +1 -1
- package/lib/typescript/components/ThreadList/ThreadListUnreadBanner.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +3 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts +0 -1
- package/lib/typescript/contexts/componentsContext/defaultComponents.d.ts.map +1 -1
- package/lib/typescript/hooks/index.d.ts +1 -0
- package/lib/typescript/hooks/index.d.ts.map +1 -1
- package/lib/typescript/hooks/messagePreview/useMessageDeliveryStatus.d.ts +3 -0
- package/lib/typescript/hooks/messagePreview/useMessageDeliveryStatus.d.ts.map +1 -1
- package/lib/typescript/i18n/keys.d.ts +3 -1
- package/lib/typescript/i18n/keys.d.ts.map +1 -1
- package/lib/typescript/i18n/runtimeDefaults.d.ts +1 -0
- package/lib/typescript/i18n/runtimeDefaults.d.ts.map +1 -1
- package/lib/typescript/store/apis/getChannelMessages.d.ts +2 -1
- package/lib/typescript/store/apis/getChannelMessages.d.ts.map +1 -1
- package/lib/typescript/store/apis/getChannels.d.ts +3 -1
- package/lib/typescript/store/apis/getChannels.d.ts.map +1 -1
- package/lib/typescript/store/apis/getChannelsForFilterSort.d.ts.map +1 -1
- package/lib/typescript/store/apis/queries/selectMessagesForChannels.d.ts +3 -1
- package/lib/typescript/store/apis/queries/selectMessagesForChannels.d.ts.map +1 -1
- package/lib/typescript/utils/installNativeMultipartAdapter.d.ts +5 -3
- package/lib/typescript/utils/installNativeMultipartAdapter.d.ts.map +1 -1
- package/lib/typescript/utils/setupCommandUIMiddlewares.d.ts.map +1 -1
- package/package.json +4 -4
- package/src/__tests__/offline-support/offline-feature.tsx +7 -7
- package/src/__tests__/offline-support/optimistic-update.tsx +5 -5
- package/src/ai-components/README.md +50 -2
- package/src/ai-components/__tests__/VoiceVisualization.test.tsx +208 -0
- package/src/ai-components/__tests__/dictation.test.tsx +58 -1
- package/src/ai-components/__tests__/voiceDriver.test.ts +317 -0
- package/src/ai-components/__tests__/voicePalette.test.ts +124 -0
- package/src/ai-components/index.ts +3 -1
- package/src/ai-components/message-composer/ComposerView.tsx +6 -3
- package/src/ai-components/message-composer/SpeechToTextButton.tsx +5 -2
- package/src/ai-components/native/AIDictation.ts +11 -0
- package/src/ai-components/store/dictation/store.ts +9 -0
- package/src/ai-components/store/dictation/useDictationState.ts +2 -1
- package/src/ai-components/store/index.ts +2 -0
- package/src/ai-components/theme.ts +16 -0
- package/src/ai-components/transcription/useDictation.ts +16 -3
- package/src/ai-components/transcription/useDictationAudioLevel.ts +38 -0
- package/src/ai-components/voice-visualization/VoiceGlow.tsx +79 -0
- package/src/ai-components/voice-visualization/VoiceVisualizationView.tsx +179 -0
- package/src/ai-components/voice-visualization/VoiceWave.tsx +67 -0
- package/src/ai-components/voice-visualization/bounce.ts +61 -0
- package/src/ai-components/voice-visualization/driver.ts +240 -0
- package/src/ai-components/voice-visualization/glowShader.ts +227 -0
- package/src/ai-components/voice-visualization/index.ts +3 -0
- package/src/ai-components/voice-visualization/math.ts +73 -0
- package/src/ai-components/voice-visualization/palette.ts +59 -0
- package/src/ai-components/voice-visualization/simplex.ts +92 -0
- package/src/ai-components/voice-visualization/styles.ts +42 -0
- package/src/ai-components/voice-visualization/types.ts +44 -0
- package/src/ai-components/voice-visualization/useReduceMotion.ts +34 -0
- package/src/ai-components/voice-visualization/useVoiceVisualization.ts +153 -0
- package/src/ai-components/voice-visualization/waveGeometry.ts +137 -0
- package/src/components/Channel/Channel.tsx +1 -0
- package/src/components/Channel/ChannelShell.tsx +12 -0
- package/src/components/Channel/__tests__/Channel.test.tsx +146 -5
- package/src/components/Channel/hooks/useChannelLifecycle.ts +4 -1
- package/src/components/Channel/hooks/useJumpToLatestOnOpen.ts +42 -0
- package/src/components/ChannelDetails/__tests__/ChannelDetails.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelDetailsActionsSection.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelDetailsEditButton.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelDetailsMemberSection.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelDetailsNavHeader.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelDetailsProfile.test.tsx +2 -2
- package/src/components/ChannelDetails/__tests__/ChannelEditDetailsForm.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/ChannelEditDetailsFormContent.test.tsx +2 -2
- package/src/components/ChannelDetails/__tests__/ChannelEditName.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/members/ChannelAddMembersForm.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/members/ChannelMemberActionsSheet.test.tsx +2 -2
- package/src/components/ChannelDetails/__tests__/members/ChannelMemberItem.test.tsx +1 -1
- package/src/components/ChannelDetails/__tests__/useChannelDetailsMemberStatusText.test.tsx +1 -1
- package/src/components/ChannelDetails/components/members/ChannelMemberItem.tsx +1 -1
- package/src/components/ChannelDetails/hooks/useChannelDetailsMemberStatusText.ts +1 -1
- package/src/components/ChannelList/ChannelListView.tsx +1 -3
- package/src/components/ChannelList/__tests__/ChannelList.test.tsx +72 -0
- package/src/components/ChannelList/hooks/usePaginatedChannels.ts +2 -2
- package/src/components/ChannelPreview/ChannelDetailsBottomSheet.tsx +1 -1
- package/src/components/ChannelPreview/ChannelLastMessagePreview.tsx +1 -1
- package/src/components/ChannelPreview/ChannelMessagePreviewDeliveryStatus.tsx +8 -2
- package/src/components/ChannelPreview/ChannelPreviewTitle.tsx +1 -1
- package/src/components/ChannelPreview/ChannelPreviewView.tsx +1 -1
- package/src/components/ChannelPreview/__tests__/ChannelPreview.test.tsx +4 -4
- package/src/components/ChannelPreview/__tests__/ChannelPreviewView.test.tsx +40 -0
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewData.test.tsx +51 -0
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +1 -1
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayPresence.test.tsx +1 -1
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewPollLabel.test.tsx +87 -0
- package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts +3 -4
- package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayName.ts +1 -1
- package/src/components/ChannelPreview/hooks/useChannelPreviewDisplayPresence.ts +1 -1
- package/src/components/ChannelPreview/hooks/useChannelPreviewPollLabel.ts +1 -1
- package/src/components/Chat/__tests__/Chat.test.tsx +31 -1
- package/src/components/Chat/hooks/useConnectionLifecycle.ts +12 -6
- package/src/components/Indicators/LoadingErrorIndicator.tsx +8 -1
- package/src/components/Message/Message.tsx +1 -1
- package/src/components/Message/MessageItemView/MessageStatus.tsx +16 -2
- package/src/components/Message/MessageItemView/MessageWrapper.tsx +14 -4
- package/src/components/Message/MessageItemView/__tests__/MessageStatus.test.tsx +21 -0
- package/src/components/Message/hooks/__tests__/useCreateMessageActionHandlers.test.tsx +1 -1
- package/src/components/Message/hooks/__tests__/useUserMuteActive.test.tsx +1 -1
- package/src/components/Message/hooks/useCreateMessageActionHandlers.ts +3 -3
- package/src/components/Message/hooks/useProcessReactions.ts +2 -2
- package/src/components/Message/hooks/useUserMuteActive.ts +1 -1
- package/src/components/MessageInput/MessageComposer.tsx +4 -2
- package/src/components/MessageList/MessageFlashList.tsx +2 -2
- package/src/components/MessageList/MessageList.tsx +2 -2
- package/src/components/MessageList/__tests__/MessageList.test.tsx +115 -14
- package/src/components/MessageList/__tests__/ScrollToBottomButton.test.tsx +3 -3
- package/src/components/MessageList/hooks/useOwnUnreadCount.ts +1 -1
- package/src/components/MessageMenu/MessageUserReactionsItem.tsx +1 -1
- package/src/components/MessageMenu/hooks/useMessageOwnReactions.ts +2 -2
- package/src/components/Poll/components/PollAnswersList.tsx +1 -1
- package/src/components/Poll/components/PollButtons.tsx +1 -1
- package/src/components/Poll/hook/useIsPollCreatedByCurrentUser.ts +1 -1
- package/src/components/Thread/Thread.tsx +1 -1
- package/src/components/Thread/__tests__/Thread.test.tsx +89 -2
- package/src/components/ThreadList/ThreadListItem.tsx +1 -1
- package/src/components/ThreadList/ThreadListUnreadBanner.tsx +6 -2
- package/src/components/ThreadList/__tests__/ThreadList.test.tsx +21 -0
- package/src/components/index.ts +3 -0
- package/src/contexts/componentsContext/defaultComponents.ts +0 -2
- package/src/contexts/liveLocationManagerContext/LiveLocationManagerContext.tsx +1 -1
- package/src/hooks/__tests__/useChannelMuteActive.test.tsx +1 -1
- package/src/hooks/__tests__/useIsDirectChat.test.tsx +1 -1
- package/src/hooks/actions/__tests__/useChannelActionItems.test.tsx +1 -1
- package/src/hooks/actions/__tests__/useChannelActions.test.tsx +1 -1
- package/src/hooks/actions/__tests__/useChannelMemberActionItems.test.tsx +6 -6
- package/src/hooks/actions/useChannelActionItems.tsx +1 -1
- package/src/hooks/actions/useChannelActions.ts +2 -2
- package/src/hooks/actions/useChannelMemberActionItems.tsx +1 -1
- package/src/hooks/index.ts +1 -0
- package/src/hooks/messagePreview/__tests__/useMessageDeliveryStatus.test.tsx +57 -32
- package/src/hooks/messagePreview/useMessageDeliveryStatus.ts +13 -7
- package/src/hooks/useIsDirectChat.ts +1 -1
- package/src/i18n/__tests__/catalog.fixture.json +2 -0
- package/src/i18n/keys.ts +3 -0
- package/src/i18n/runtimeDefaults.ts +1 -0
- package/src/store/__tests__/selectMessagesForChannels.test.ts +34 -12
- package/src/store/apis/getChannelMessages.ts +4 -1
- package/src/store/apis/getChannels.ts +5 -1
- package/src/store/apis/getChannelsForFilterSort.ts +1 -0
- package/src/store/apis/queries/selectMessagesForChannels.ts +7 -2
- package/src/utils/__tests__/setupCommandUIMiddlewares.test.ts +49 -0
- package/src/utils/installNativeMultipartAdapter.ts +5 -3
- package/src/utils/setupCommandUIMiddlewares.ts +3 -0
- package/src/version.json +1 -1
|
@@ -328,6 +328,8 @@ describe('Thread', () => {
|
|
|
328
328
|
await waitFor(() => {
|
|
329
329
|
expect(screen.getByTestId('loading-error')).toBeTruthy();
|
|
330
330
|
});
|
|
331
|
+
// The thread's own copy, not the channel's "Error loading messages for this channel...".
|
|
332
|
+
expect(screen.getByTestId('loading-error')).toHaveTextContent('Error loading replies...');
|
|
331
333
|
});
|
|
332
334
|
|
|
333
335
|
it('retries the reply query — and only the reply query — from the indicator', async () => {
|
|
@@ -511,10 +513,10 @@ describe('Thread lifecycle', () => {
|
|
|
511
513
|
generateMessage({ reply_count: 3, user }),
|
|
512
514
|
);
|
|
513
515
|
const readState = (unreadMessageCount: number) => ({
|
|
514
|
-
[chatClient.
|
|
516
|
+
[chatClient.userId as string]: {
|
|
515
517
|
lastReadAt: 1,
|
|
516
518
|
unreadMessageCount,
|
|
517
|
-
user: { id: chatClient.
|
|
519
|
+
user: { id: chatClient.userId as string },
|
|
518
520
|
},
|
|
519
521
|
});
|
|
520
522
|
return { markRead, parentMessage, readState, testChannel };
|
|
@@ -584,4 +586,89 @@ describe('Thread lifecycle', () => {
|
|
|
584
586
|
expect(markRead.mock.calls.every(([options]) => options?.thread_id)).toBe(true);
|
|
585
587
|
});
|
|
586
588
|
});
|
|
589
|
+
|
|
590
|
+
describe('reopening a thread left on an older page', () => {
|
|
591
|
+
const OLDER_PAGE_START = new Date('2020-01-01T00:00:00.000Z').getTime();
|
|
592
|
+
|
|
593
|
+
// A thread whose newest replies are loaded, but whose list shows an older page, as it does
|
|
594
|
+
// after a jump to a quoted or searched reply.
|
|
595
|
+
const setUpThreadOnOlderPage = async () => {
|
|
596
|
+
const testChannel = await watchChannel();
|
|
597
|
+
const parentMessage = testChannel.state.formatMessage(generateMessage({ user }));
|
|
598
|
+
const threadInstance = new ThreadClass({
|
|
599
|
+
channel: testChannel,
|
|
600
|
+
client: chatClient,
|
|
601
|
+
parentMessage,
|
|
602
|
+
});
|
|
603
|
+
jest.spyOn(threadInstance, 'reload').mockResolvedValue(undefined);
|
|
604
|
+
jest.spyOn(threadInstance.messagePaginator, 'toTail').mockResolvedValue(undefined);
|
|
605
|
+
|
|
606
|
+
threadInstance.messagePaginator.setItems({
|
|
607
|
+
valueOrFactory: Array.from({ length: 10 }, (_, i) =>
|
|
608
|
+
generateMessage({ id: `newest-${i}`, parent_id: parentMessage.id }),
|
|
609
|
+
),
|
|
610
|
+
isFirstPage: true,
|
|
611
|
+
isLastPage: true,
|
|
612
|
+
});
|
|
613
|
+
threadInstance.messagePaginator.ingestPage({
|
|
614
|
+
page: Array.from({ length: 5 }, (_, i) =>
|
|
615
|
+
generateMessage({
|
|
616
|
+
id: `older-${i}`,
|
|
617
|
+
parent_id: parentMessage.id,
|
|
618
|
+
timestamp: OLDER_PAGE_START + i * 1000,
|
|
619
|
+
}),
|
|
620
|
+
),
|
|
621
|
+
policy: 'strict-overlap-only',
|
|
622
|
+
setActive: true,
|
|
623
|
+
});
|
|
624
|
+
expect(threadInstance.messagePaginator.isActiveIntervalAtHead).toBe(false);
|
|
625
|
+
|
|
626
|
+
return threadInstance;
|
|
627
|
+
};
|
|
628
|
+
|
|
629
|
+
it('shows the newest replies again', async () => {
|
|
630
|
+
const threadInstance = await setUpThreadOnOlderPage();
|
|
631
|
+
|
|
632
|
+
openThread(threadInstance);
|
|
633
|
+
|
|
634
|
+
await waitFor(() =>
|
|
635
|
+
expect(threadInstance.messagePaginator.isActiveIntervalAtHead).toBe(true),
|
|
636
|
+
);
|
|
637
|
+
expect(threadInstance.messagePaginator.items?.map((reply) => reply.id)).toContain('newest-9');
|
|
638
|
+
});
|
|
639
|
+
|
|
640
|
+
it('keeps a jump the integrator already made to a loaded reply', async () => {
|
|
641
|
+
const threadInstance = await setUpThreadOnOlderPage();
|
|
642
|
+
// A deep link from the screen: the target is loaded, so the jump lands at once.
|
|
643
|
+
await threadInstance.messagePaginator.jumpToMessage('older-2', {
|
|
644
|
+
focusReason: 'jump-to-message',
|
|
645
|
+
});
|
|
646
|
+
const jumpToTheLatestMessageSpy = jest.spyOn(
|
|
647
|
+
threadInstance.messagePaginator,
|
|
648
|
+
'jumpToTheLatestMessage',
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
openThread(threadInstance);
|
|
652
|
+
|
|
653
|
+
expect(jumpToTheLatestMessageSpy).not.toHaveBeenCalled();
|
|
654
|
+
expect(threadInstance.messagePaginator.isActiveIntervalAtHead).toBe(false);
|
|
655
|
+
expect(
|
|
656
|
+
threadInstance.messagePaginator.messageFocusSignal.getLatestValue().signal?.messageId,
|
|
657
|
+
).toBe('older-2');
|
|
658
|
+
});
|
|
659
|
+
|
|
660
|
+
it('leaves a jump that is still in flight alone', async () => {
|
|
661
|
+
const threadInstance = await setUpThreadOnOlderPage();
|
|
662
|
+
// A deep link to a reply that is not loaded: its query is in flight.
|
|
663
|
+
jest.spyOn(threadInstance.messagePaginator, 'isLoading', 'get').mockReturnValue(true);
|
|
664
|
+
const jumpToTheLatestMessageSpy = jest.spyOn(
|
|
665
|
+
threadInstance.messagePaginator,
|
|
666
|
+
'jumpToTheLatestMessage',
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
openThread(threadInstance);
|
|
670
|
+
|
|
671
|
+
expect(jumpToTheLatestMessageSpy).not.toHaveBeenCalled();
|
|
672
|
+
});
|
|
673
|
+
});
|
|
587
674
|
});
|
|
@@ -158,7 +158,7 @@ export const ThreadListItem = (props: ThreadListItemProps) => {
|
|
|
158
158
|
channel: nextValue.channel,
|
|
159
159
|
deletedAt: nextValue.deletedAt,
|
|
160
160
|
ownUnreadMessageCount:
|
|
161
|
-
(client.
|
|
161
|
+
(client.userId && nextValue.read[client.userId]?.unreadMessageCount) || 0,
|
|
162
162
|
parentMessage: nextValue.parentMessage,
|
|
163
163
|
}) as const,
|
|
164
164
|
[client],
|
|
@@ -11,13 +11,15 @@ import { primitives } from '../../theme';
|
|
|
11
11
|
const selector = (nextValue: ThreadManagerState) =>
|
|
12
12
|
({ unseenThreadIds: nextValue.unseenThreadIds }) as const;
|
|
13
13
|
|
|
14
|
-
// The paginator records a failed
|
|
14
|
+
// The paginator records a failed query and clears it on the next successful one.
|
|
15
15
|
const lastQueryErrorSelector = (nextValue: { lastQueryError?: Error }) => ({
|
|
16
16
|
lastQueryError: nextValue.lastQueryError,
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
export const ThreadListUnreadBanner = () => {
|
|
20
|
+
// we need the two extra states so we can tell the client's states apart
|
|
20
21
|
const [loading, setLoading] = useState(false);
|
|
22
|
+
const [reloadFailed, setReloadFailed] = useState(false);
|
|
21
23
|
const { client } = useChatContext();
|
|
22
24
|
const { icons } = useComponentsContext();
|
|
23
25
|
const { t } = useTranslationContext();
|
|
@@ -48,8 +50,10 @@ export const ThreadListUnreadBanner = () => {
|
|
|
48
50
|
setLoading(true);
|
|
49
51
|
try {
|
|
50
52
|
await client.threads.reload();
|
|
53
|
+
setReloadFailed(!!client.threads.paginator.lastQueryError);
|
|
51
54
|
} catch {
|
|
52
55
|
// Only with the paginator's `throwErrors`; the error is already in its state.
|
|
56
|
+
setReloadFailed(true);
|
|
53
57
|
} finally {
|
|
54
58
|
setLoading(false);
|
|
55
59
|
}
|
|
@@ -64,7 +68,7 @@ export const ThreadListUnreadBanner = () => {
|
|
|
64
68
|
);
|
|
65
69
|
}
|
|
66
70
|
|
|
67
|
-
if (lastQueryError) {
|
|
71
|
+
if (reloadFailed && lastQueryError) {
|
|
68
72
|
return (
|
|
69
73
|
<Pressable onPress={handlePress} style={pressableStyle}>
|
|
70
74
|
<icons.ExclamationCircle stroke={semantics.textSecondary} height={20} width={20} />
|
|
@@ -179,4 +179,25 @@ describe('ThreadList loading states', () => {
|
|
|
179
179
|
await waitFor(() => expect(rows()).toHaveLength(2));
|
|
180
180
|
expect(screen.queryByText("Couldn't load new threads. Tap to retry")).toBeNull();
|
|
181
181
|
});
|
|
182
|
+
|
|
183
|
+
it('keeps the new threads count when a different thread query failed', async () => {
|
|
184
|
+
jest
|
|
185
|
+
.spyOn(chatClient, 'queryThreadsAndHydrate')
|
|
186
|
+
.mockResolvedValueOnce({ next: undefined, threads: [makeThread()] });
|
|
187
|
+
render(
|
|
188
|
+
<Chat client={chatClient}>
|
|
189
|
+
<ThreadList isFocused />
|
|
190
|
+
</Chat>,
|
|
191
|
+
);
|
|
192
|
+
await waitFor(() => expect(rows()).toHaveLength(1));
|
|
193
|
+
|
|
194
|
+
// A failed next page, for example: the paginator records it the same way as a failed reload.
|
|
195
|
+
act(() => {
|
|
196
|
+
chatClient.threads.paginator.state.partialNext({ lastQueryError: new Error('offline') });
|
|
197
|
+
chatClient.threads.state.partialNext({ unseenThreadIds: ['a'] });
|
|
198
|
+
});
|
|
199
|
+
|
|
200
|
+
await waitFor(() => expect(screen.getByText('1 new thread')).toBeTruthy());
|
|
201
|
+
expect(screen.queryByText("Couldn't load new threads. Tap to retry")).toBeNull();
|
|
202
|
+
});
|
|
182
203
|
});
|
package/src/components/index.ts
CHANGED
|
@@ -34,6 +34,7 @@ export * from './Channel/hooks/useCreateChannelContext';
|
|
|
34
34
|
export * from './Channel/hooks/useCreateInputMessageInputContext';
|
|
35
35
|
export * from './Channel/hooks/useCreateMessagesContext';
|
|
36
36
|
export * from './Channel/hooks/useCreateThreadContext';
|
|
37
|
+
export * from './Channel/hooks/useJumpToLatestOnOpen';
|
|
37
38
|
|
|
38
39
|
export * from './ChannelList/ChannelList';
|
|
39
40
|
export * from './ChannelList/ChannelListFooterLoadingIndicator';
|
|
@@ -150,7 +151,9 @@ export * from './MessageList/hooks/useMarkRead';
|
|
|
150
151
|
// Only the constant, for integrators running their own `jumpToMessage`.
|
|
151
152
|
export { DEFAULT_HIGHLIGHT_DURATION } from './MessageList/hooks/useMessageListFocus';
|
|
152
153
|
export * from './MessageList/hooks/useMessageList';
|
|
154
|
+
export * from './MessageList/hooks/useOwnUnreadCount';
|
|
153
155
|
export * from './MessageList/hooks/useTypingString';
|
|
156
|
+
export * from './MessageList/hooks/useTypingUsers';
|
|
154
157
|
export * from './MessageList/InlineDateSeparator';
|
|
155
158
|
export * from './MessageList/InlineLoadingMoreIndicator';
|
|
156
159
|
export * from './MessageList/InlineLoadingMoreRecentIndicator';
|
|
@@ -149,7 +149,6 @@ import { StopMessageStreamingButton } from '../../components/MessageInput/StopMe
|
|
|
149
149
|
import { DateHeader } from '../../components/MessageList/DateHeader';
|
|
150
150
|
import { InlineDateSeparator } from '../../components/MessageList/InlineDateSeparator';
|
|
151
151
|
import { InlineUnreadIndicator } from '../../components/MessageList/InlineUnreadIndicator';
|
|
152
|
-
import { MessageList } from '../../components/MessageList/MessageList';
|
|
153
152
|
import { MessageSystem } from '../../components/MessageList/MessageSystem';
|
|
154
153
|
import { NetworkDownIndicator } from '../../components/MessageList/NetworkDownIndicator';
|
|
155
154
|
import { ScrollToBottomButton } from '../../components/MessageList/ScrollToBottomButton';
|
|
@@ -448,7 +447,6 @@ const components = {
|
|
|
448
447
|
MessageInputLeadingView,
|
|
449
448
|
MessageInputTrailingView,
|
|
450
449
|
MessageItemView,
|
|
451
|
-
MessageList,
|
|
452
450
|
MessagePinnedHeader,
|
|
453
451
|
MessageReactionPicker,
|
|
454
452
|
MessageReminderHeader,
|
|
@@ -35,7 +35,7 @@ export const LiveLocationManagerProvider = (
|
|
|
35
35
|
}
|
|
36
36
|
return new LiveLocationManager({
|
|
37
37
|
client,
|
|
38
|
-
getDeviceId: getDeviceId ?? (() => `react-native-${Platform.OS}-${client.
|
|
38
|
+
getDeviceId: getDeviceId ?? (() => `react-native-${Platform.OS}-${client.userId}`),
|
|
39
39
|
watchLocation,
|
|
40
40
|
});
|
|
41
41
|
}, [client, getDeviceId, watchLocation]);
|
|
@@ -21,7 +21,7 @@ const createClient = ({
|
|
|
21
21
|
// muted USERS stay client-global — useMutedUsers reads them reactively from mutedUsersStore.
|
|
22
22
|
mutedUsersStore: new StateStore({ mutedUsers }),
|
|
23
23
|
on: jest.fn(() => ({ unsubscribe: jest.fn() })),
|
|
24
|
-
|
|
24
|
+
userId: CURRENT_USER_ID,
|
|
25
25
|
}) as never;
|
|
26
26
|
|
|
27
27
|
// Back the mock channel with a real StateStore (so `useStateStore` can subscribe to `members` and
|
|
@@ -23,7 +23,7 @@ describe('useIsDirectChat', () => {
|
|
|
23
23
|
jest
|
|
24
24
|
.spyOn(ChatContext, 'useChatContext')
|
|
25
25
|
.mockImplementation(
|
|
26
|
-
() => ({ client: {
|
|
26
|
+
() => ({ client: { userId: OWN_USER_ID } }) as unknown as ChatContextValue,
|
|
27
27
|
);
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -58,7 +58,7 @@ const createClient = () => ({
|
|
|
58
58
|
unblockUser: jest.fn(),
|
|
59
59
|
unmuteUser: jest.fn(),
|
|
60
60
|
uploadImage: jest.fn().mockResolvedValue({ file: 'https://cdn.example.com/uploaded.png' }),
|
|
61
|
-
|
|
61
|
+
userId: 'current-user-id',
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
const createChannel = (client: ReturnType<typeof createClient>) =>
|
|
@@ -35,15 +35,15 @@ const createMemberMock = (userId = 'target-user-id'): ChannelMemberResponse =>
|
|
|
35
35
|
user_id: userId,
|
|
36
36
|
}) as ChannelMemberResponse;
|
|
37
37
|
|
|
38
|
-
const createChannelMock = (params?: { blockedUserIds?: string[];
|
|
39
|
-
const { blockedUserIds = [],
|
|
38
|
+
const createChannelMock = (params?: { blockedUserIds?: string[]; userId?: string }): Channel => {
|
|
39
|
+
const { blockedUserIds = [], userId = 'current-user-id' } = params ?? {};
|
|
40
40
|
return {
|
|
41
41
|
getClient: () => ({
|
|
42
42
|
blockedUsers: {
|
|
43
43
|
getLatestValue: () => ({ userIds: blockedUserIds }),
|
|
44
44
|
subscribeWithSelector: () => () => {},
|
|
45
45
|
},
|
|
46
|
-
|
|
46
|
+
userId,
|
|
47
47
|
}),
|
|
48
48
|
} as unknown as Channel;
|
|
49
49
|
};
|
|
@@ -84,7 +84,7 @@ describe('useChannelMemberActionItems', () => {
|
|
|
84
84
|
});
|
|
85
85
|
|
|
86
86
|
it('returns no action items when the member is the current user', () => {
|
|
87
|
-
const currentUserChannel = createChannelMock({
|
|
87
|
+
const currentUserChannel = createChannelMock({ userId: 'target-user-id' });
|
|
88
88
|
|
|
89
89
|
const { result } = renderHook(() =>
|
|
90
90
|
useChannelMemberActionItems({ channel: currentUserChannel, member }),
|
|
@@ -101,7 +101,7 @@ describe('useChannelMemberActionItems', () => {
|
|
|
101
101
|
});
|
|
102
102
|
|
|
103
103
|
const wrapper = ({ children }: PropsWithChildren) => (
|
|
104
|
-
<ChatProvider value={{ client: { mutedUsersStore,
|
|
104
|
+
<ChatProvider value={{ client: { mutedUsersStore, userId: 'current-user-id' } } as never}>
|
|
105
105
|
{children}
|
|
106
106
|
</ChatProvider>
|
|
107
107
|
);
|
|
@@ -166,7 +166,7 @@ describe('useChannelMemberActionItems', () => {
|
|
|
166
166
|
jest
|
|
167
167
|
.spyOn(useChannelOwnCapabilitiesModule, 'useChannelOwnCapabilities')
|
|
168
168
|
.mockReturnValue(['update-channel-members']);
|
|
169
|
-
const currentUserChannel = createChannelMock({
|
|
169
|
+
const currentUserChannel = createChannelMock({ userId: 'target-user-id' });
|
|
170
170
|
|
|
171
171
|
const { result } = renderHook(() =>
|
|
172
172
|
useChannelMemberActionItems({ channel: currentUserChannel, member }),
|
|
@@ -112,7 +112,7 @@ export const buildDefaultChannelActionItems: BuildDefaultChannelActionItems = (
|
|
|
112
112
|
t,
|
|
113
113
|
channel,
|
|
114
114
|
} = channelActionItemsParams;
|
|
115
|
-
const ownUserId = channel.getClient().
|
|
115
|
+
const ownUserId = channel.getClient().userId;
|
|
116
116
|
|
|
117
117
|
const actionItems: ChannelActionItem[] = [
|
|
118
118
|
{
|
|
@@ -39,7 +39,7 @@ export type ChannelActions = {
|
|
|
39
39
|
export const getOtherUserInDirectChannel = (channel: Channel) => {
|
|
40
40
|
const members = Object.values(channel.state.members);
|
|
41
41
|
return members.length === 2
|
|
42
|
-
? members.find((member) => member.user?.id !== channel.getClient().
|
|
42
|
+
? members.find((member) => member.user?.id !== channel.getClient().userId)
|
|
43
43
|
: undefined;
|
|
44
44
|
};
|
|
45
45
|
|
|
@@ -62,7 +62,7 @@ export const useChannelActions = (channel: Channel) => {
|
|
|
62
62
|
const { client } = useChatContext();
|
|
63
63
|
const { addNotification } = useNotificationApi();
|
|
64
64
|
const { t } = useTranslationContext();
|
|
65
|
-
const ownUserId = client.
|
|
65
|
+
const ownUserId = client.userId;
|
|
66
66
|
|
|
67
67
|
const pin = useStableCallback(async (options?: ChannelActionOptions) => {
|
|
68
68
|
try {
|
|
@@ -211,7 +211,7 @@ export const useChannelMemberActionItems = ({
|
|
|
211
211
|
|
|
212
212
|
const isBlocked = blockedUserIds.includes(member.user?.id ?? '');
|
|
213
213
|
|
|
214
|
-
const isCurrentUser = member.user?.id === channel.getClient().
|
|
214
|
+
const isCurrentUser = member.user?.id === channel.getClient().userId;
|
|
215
215
|
|
|
216
216
|
const channelMemberActionItemsParams = useMemo<ChannelMemberActionItemsParams>(
|
|
217
217
|
() => ({
|
package/src/hooks/index.ts
CHANGED
|
@@ -13,6 +13,7 @@ export * from './useChannelMuteActive';
|
|
|
13
13
|
export * from './useIsDirectChat';
|
|
14
14
|
export * from './useIsChannelMember';
|
|
15
15
|
export * from './useStreami18n';
|
|
16
|
+
export * from './useTranslatedMessage';
|
|
16
17
|
export * from './useViewport';
|
|
17
18
|
export * from './useScreenDimensions';
|
|
18
19
|
export * from './useScreenOrientation';
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
|
|
3
3
|
import { act, renderHook } from '@testing-library/react-native';
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
import type { Channel, UserResponse } from 'stream-chat';
|
|
4
|
+
import { asTimestampNS } from 'stream-chat';
|
|
5
|
+
import type { Channel, MsgRef } from 'stream-chat';
|
|
7
6
|
|
|
8
7
|
import { Chat } from '../../../components/Chat/Chat';
|
|
9
8
|
import { initiateClientWithChannels } from '../../../mock-builders/api/initiateClientWithChannels';
|
|
@@ -12,7 +11,16 @@ import { generateUser } from '../../../mock-builders/generator/user';
|
|
|
12
11
|
import { MessageDeliveryStatus, useMessageDeliveryStatus } from '../useMessageDeliveryStatus';
|
|
13
12
|
|
|
14
13
|
describe('useMessageDeliveryStatus', () => {
|
|
15
|
-
const ownMessage = generateMessage({
|
|
14
|
+
const ownMessage = generateMessage({
|
|
15
|
+
timestamp: new Date('2026-01-01T10:00:00Z'),
|
|
16
|
+
user: generateUser({ id: 'me' }),
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// A cursor `offsetNs` after (or, negative, before) `ownMessage`, on a message of its own.
|
|
20
|
+
const cursorAt = (offsetNs: number, msgId = `cursor-${offsetNs}`): MsgRef => ({
|
|
21
|
+
msgId,
|
|
22
|
+
timestamp: asTimestampNS(ownMessage.created_at + offsetNs),
|
|
23
|
+
});
|
|
16
24
|
|
|
17
25
|
const setup = async ({
|
|
18
26
|
isReadEventsEnabled = true,
|
|
@@ -32,14 +40,11 @@ describe('useMessageDeliveryStatus', () => {
|
|
|
32
40
|
|
|
33
41
|
const setReceipts = (
|
|
34
42
|
channel: Channel,
|
|
35
|
-
{
|
|
36
|
-
delivered = {},
|
|
37
|
-
readers = {},
|
|
38
|
-
}: { delivered?: Record<string, UserResponse[]>; readers?: Record<string, UserResponse[]> },
|
|
43
|
+
{ delivered = null, read = null }: { delivered?: MsgRef | null; read?: MsgRef | null },
|
|
39
44
|
) =>
|
|
40
45
|
channel.messageReceiptsTracker.snapshotStore.partialNext({
|
|
41
|
-
|
|
42
|
-
|
|
46
|
+
lastDeliveredRefByOthers: delivered,
|
|
47
|
+
lastReadRefByOthers: read,
|
|
43
48
|
});
|
|
44
49
|
|
|
45
50
|
it('returns NOT_SENT_BY_CURRENT_USER when read events are disabled', async () => {
|
|
@@ -58,22 +63,55 @@ describe('useMessageDeliveryStatus', () => {
|
|
|
58
63
|
const { channel, result } = await setup();
|
|
59
64
|
expect(result.current.status).toBe(MessageDeliveryStatus.SENT);
|
|
60
65
|
|
|
61
|
-
act(() =>
|
|
62
|
-
setReceipts(channel, {
|
|
63
|
-
delivered: { [ownMessage.id]: [fromPartial<UserResponse>({ id: 'other' })] },
|
|
64
|
-
}),
|
|
65
|
-
);
|
|
66
|
+
act(() => setReceipts(channel, { delivered: cursorAt(0, ownMessage.id) }));
|
|
66
67
|
expect(result.current.status).toBe(MessageDeliveryStatus.DELIVERED);
|
|
67
68
|
|
|
68
69
|
act(() =>
|
|
69
70
|
setReceipts(channel, {
|
|
70
|
-
delivered:
|
|
71
|
-
|
|
71
|
+
delivered: cursorAt(0, ownMessage.id),
|
|
72
|
+
read: cursorAt(0, ownMessage.id),
|
|
72
73
|
}),
|
|
73
74
|
);
|
|
74
75
|
expect(result.current.status).toBe(MessageDeliveryStatus.READ);
|
|
75
76
|
});
|
|
76
77
|
|
|
78
|
+
it('returns READ when another member read past the message', async () => {
|
|
79
|
+
const { channel, result } = await setup();
|
|
80
|
+
|
|
81
|
+
act(() => setReceipts(channel, { delivered: cursorAt(1000), read: cursorAt(1000) }));
|
|
82
|
+
|
|
83
|
+
expect(result.current.status).toBe(MessageDeliveryStatus.READ);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
it('returns DELIVERED when the message was delivered past it but not read', async () => {
|
|
87
|
+
const { channel, result } = await setup();
|
|
88
|
+
|
|
89
|
+
act(() => setReceipts(channel, { delivered: cursorAt(1000), read: cursorAt(-1000) }));
|
|
90
|
+
|
|
91
|
+
expect(result.current.status).toBe(MessageDeliveryStatus.DELIVERED);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('returns SENT when every cursor is before the message', async () => {
|
|
95
|
+
const { channel, result } = await setup();
|
|
96
|
+
|
|
97
|
+
act(() => setReceipts(channel, { delivered: cursorAt(-1000), read: cursorAt(-1000) }));
|
|
98
|
+
|
|
99
|
+
expect(result.current.status).toBe(MessageDeliveryStatus.SENT);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
it('returns READ for a thread reply read past by another member', async () => {
|
|
103
|
+
const reply = generateMessage({
|
|
104
|
+
parent_id: 'parent',
|
|
105
|
+
timestamp: new Date('2026-01-01T10:00:00Z'),
|
|
106
|
+
user: generateUser({ id: 'me' }),
|
|
107
|
+
});
|
|
108
|
+
const { channel, result } = await setup({ lastMessage: reply });
|
|
109
|
+
|
|
110
|
+
act(() => setReceipts(channel, { delivered: cursorAt(1000), read: cursorAt(1000) }));
|
|
111
|
+
|
|
112
|
+
expect(result.current.status).toBe(MessageDeliveryStatus.READ);
|
|
113
|
+
});
|
|
114
|
+
|
|
77
115
|
// The receipts tracker rebuilds its reader arrays on every snapshot, presence and user updates
|
|
78
116
|
// included, so a preview row must only re-render when the status itself changes.
|
|
79
117
|
it('does not re-render when the receipts change without changing the status', async () => {
|
|
@@ -95,24 +133,11 @@ describe('useMessageDeliveryStatus', () => {
|
|
|
95
133
|
{ wrapper },
|
|
96
134
|
);
|
|
97
135
|
|
|
98
|
-
act(() =>
|
|
99
|
-
setReceipts(channel, {
|
|
100
|
-
delivered: { [ownMessage.id]: [fromPartial<UserResponse>({ id: 'other' })] },
|
|
101
|
-
}),
|
|
102
|
-
);
|
|
136
|
+
act(() => setReceipts(channel, { delivered: cursorAt(0, ownMessage.id) }));
|
|
103
137
|
expect(result.current.status).toBe(MessageDeliveryStatus.DELIVERED);
|
|
104
138
|
const rendersWhenDelivered = renders;
|
|
105
139
|
|
|
106
|
-
act(() =>
|
|
107
|
-
setReceipts(channel, {
|
|
108
|
-
delivered: {
|
|
109
|
-
[ownMessage.id]: [
|
|
110
|
-
fromPartial<UserResponse>({ id: 'other' }),
|
|
111
|
-
fromPartial<UserResponse>({ id: 'third' }),
|
|
112
|
-
],
|
|
113
|
-
},
|
|
114
|
-
}),
|
|
115
|
-
);
|
|
140
|
+
act(() => setReceipts(channel, { delivered: cursorAt(1000) }));
|
|
116
141
|
expect(result.current.status).toBe(MessageDeliveryStatus.DELIVERED);
|
|
117
142
|
expect(renders).toBe(rendersWhenDelivered);
|
|
118
143
|
});
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
LocalMessage,
|
|
6
6
|
MessageReceiptsSnapshot,
|
|
7
7
|
MessageResponse,
|
|
8
|
-
|
|
8
|
+
MsgRef,
|
|
9
9
|
} from 'stream-chat';
|
|
10
10
|
|
|
11
11
|
import { useChatContext } from '../../contexts/chatContext/ChatContext';
|
|
@@ -25,13 +25,19 @@ type MessageDeliveryStatusProps = {
|
|
|
25
25
|
isReadEventsEnabled: boolean;
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
/** Whether a cursor has reached a message created at `createdAt`, even from a later message. */
|
|
29
|
+
const hasCursorReached = (createdAt: number | undefined, cursor: MsgRef | null) =>
|
|
30
|
+
!!cursor && typeof createdAt === 'number' && Number.isFinite(createdAt)
|
|
31
|
+
? createdAt <= cursor.timestamp
|
|
32
|
+
: false;
|
|
30
33
|
|
|
31
34
|
/**
|
|
32
35
|
* Delivery and read status of the last message when it is the current user's, derived from the
|
|
33
36
|
* channel's `messageReceiptsTracker.snapshotStore`, the same store the in-list receipt hooks use.
|
|
34
37
|
*
|
|
38
|
+
* It compares the message against `lastReadRefByOthers` and `lastDeliveredRefByOthers`, the furthest
|
|
39
|
+
* points anyone else has reached, so a message stays read once another member reads past it.
|
|
40
|
+
*
|
|
35
41
|
* @param params.channel The channel the message belongs to.
|
|
36
42
|
* @param params.lastMessage The channel's last message.
|
|
37
43
|
* @param params.isReadEventsEnabled When false, the status is `NOT_SENT_BY_CURRENT_USER`. Defaults
|
|
@@ -44,15 +50,15 @@ export const useMessageDeliveryStatus = ({
|
|
|
44
50
|
isReadEventsEnabled = true,
|
|
45
51
|
}: MessageDeliveryStatusProps) => {
|
|
46
52
|
const { client } = useChatContext();
|
|
47
|
-
const messageId = lastMessage?.id ?? '';
|
|
48
53
|
const currentUserId = client.user?.id;
|
|
54
|
+
const createdAt = lastMessage?.created_at;
|
|
49
55
|
|
|
50
56
|
const selector = useCallback(
|
|
51
57
|
(snapshot: MessageReceiptsSnapshot) => ({
|
|
52
|
-
isDelivered:
|
|
53
|
-
isRead:
|
|
58
|
+
isDelivered: hasCursorReached(createdAt, snapshot.lastDeliveredRefByOthers),
|
|
59
|
+
isRead: hasCursorReached(createdAt, snapshot.lastReadRefByOthers),
|
|
54
60
|
}),
|
|
55
|
-
[
|
|
61
|
+
[createdAt],
|
|
56
62
|
);
|
|
57
63
|
|
|
58
64
|
const { isDelivered, isRead } = useStateStore(
|
|
@@ -9,7 +9,7 @@ const pickId = (member: ChannelMemberResponse) => ({ id: member.user?.id });
|
|
|
9
9
|
|
|
10
10
|
export const useIsDirectChat = (channel?: Channel) => {
|
|
11
11
|
const { client } = useChatContext();
|
|
12
|
-
const ownUserId = client.
|
|
12
|
+
const ownUserId = client.userId;
|
|
13
13
|
const members = useChannelMembersState(channel, pickId);
|
|
14
14
|
|
|
15
15
|
const otherMembers = useMemo(
|
|
@@ -158,6 +158,7 @@
|
|
|
158
158
|
"channelPreview.deliveryStatus.read.accessibilityLabel": "Read, sent by you",
|
|
159
159
|
"channelPreview.deliveryStatus.sent.accessibilityLabel": "Sent by you",
|
|
160
160
|
"channelPreview.displayName.others.label": "and {{ count }} others",
|
|
161
|
+
"channelPreview.doubleTapToOpen.accessibilityLabel": "Double tap to open",
|
|
161
162
|
"channelPreview.lastMessage.accessibilityLabel": "Last message {{date}}",
|
|
162
163
|
"channelPreview.messageFailed.error": "Message failed to send",
|
|
163
164
|
"channelPreview.muted.accessibilityLabel": "Muted",
|
|
@@ -208,6 +209,7 @@
|
|
|
208
209
|
"indicators.loading.error": "Error loading",
|
|
209
210
|
"indicators.loading.messages.error": "Error loading messages for this channel...",
|
|
210
211
|
"indicators.loading.messages.text": "Loading messages...",
|
|
212
|
+
"indicators.loading.replies.error": "Error loading replies...",
|
|
211
213
|
"message.banUser.label": "Ban User",
|
|
212
214
|
"message.blockUser.label": "Block User",
|
|
213
215
|
"message.blockUserConfirm.label": "Block",
|
package/src/i18n/keys.ts
CHANGED
|
@@ -169,6 +169,7 @@ export type TranslationCatalog = {
|
|
|
169
169
|
'channelPreview.deliveryStatus.read.accessibilityLabel': 'Read, sent by you';
|
|
170
170
|
'channelPreview.deliveryStatus.sent.accessibilityLabel': 'Sent by you';
|
|
171
171
|
'channelPreview.displayName.others.label': 'and {{ count }} others';
|
|
172
|
+
'channelPreview.doubleTapToOpen.accessibilityLabel': 'Double tap to open';
|
|
172
173
|
'channelPreview.lastMessage.accessibilityLabel': 'Last message {{date}}';
|
|
173
174
|
'channelPreview.messageFailed.error': 'Message failed to send';
|
|
174
175
|
'channelPreview.muted.accessibilityLabel': 'Muted';
|
|
@@ -219,6 +220,7 @@ export type TranslationCatalog = {
|
|
|
219
220
|
'indicators.loading.error': 'Error loading';
|
|
220
221
|
'indicators.loading.messages.error': 'Error loading messages for this channel...';
|
|
221
222
|
'indicators.loading.messages.text': 'Loading messages...';
|
|
223
|
+
'indicators.loading.replies.error': 'Error loading replies...';
|
|
222
224
|
'message.banUser.label': 'Ban User';
|
|
223
225
|
'message.blockUser.label': 'Block User';
|
|
224
226
|
'message.blockUserConfirm.label': 'Block';
|
|
@@ -468,6 +470,7 @@ export type BundledTranslationKey =
|
|
|
468
470
|
| 'channelPreview.deliveryStatus.delivered.accessibilityLabel'
|
|
469
471
|
| 'channelPreview.deliveryStatus.read.accessibilityLabel'
|
|
470
472
|
| 'channelPreview.deliveryStatus.sent.accessibilityLabel'
|
|
473
|
+
| 'channelPreview.doubleTapToOpen.accessibilityLabel'
|
|
471
474
|
| 'channelPreview.lastMessage.accessibilityLabel'
|
|
472
475
|
| 'channelPreview.muted.accessibilityLabel'
|
|
473
476
|
| 'channelPreview.pinned.accessibilityLabel'
|
|
@@ -82,6 +82,7 @@ export const runtimeDefaults = {
|
|
|
82
82
|
'channelPreview.deliveryStatus.delivered.accessibilityLabel': 'Delivered, sent by you',
|
|
83
83
|
'channelPreview.deliveryStatus.read.accessibilityLabel': 'Read, sent by you',
|
|
84
84
|
'channelPreview.deliveryStatus.sent.accessibilityLabel': 'Sent by you',
|
|
85
|
+
'channelPreview.doubleTapToOpen.accessibilityLabel': 'Double tap to open',
|
|
85
86
|
'channelPreview.lastMessage.accessibilityLabel': 'Last message {{date}}',
|
|
86
87
|
'channelPreview.muted.accessibilityLabel': 'Muted',
|
|
87
88
|
'channelPreview.pinned.accessibilityLabel': 'Pinned',
|