stream-chat-react-native-core 6.0.0-rc.8 → 6.0.0
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/README.md +1 -1
- package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js +53 -0
- package/lib/commonjs/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -0
- package/lib/commonjs/components/AITypingIndicatorView/hooks/useAIState.js +59 -0
- package/lib/commonjs/components/AITypingIndicatorView/hooks/useAIState.js.map +1 -0
- package/lib/commonjs/components/AITypingIndicatorView/index.js +26 -0
- package/lib/commonjs/components/AITypingIndicatorView/index.js.map +1 -0
- package/lib/commonjs/components/Attachment/AudioAttachment.js +27 -22
- package/lib/commonjs/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/commonjs/components/Attachment/Gallery.js +3 -1
- package/lib/commonjs/components/Attachment/Gallery.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js +2 -2
- package/lib/commonjs/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js +37 -133
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js +6 -4
- package/lib/commonjs/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -1
- package/lib/commonjs/components/Channel/Channel.js +483 -1056
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useChannelDataState.js +174 -0
- package/lib/commonjs/components/Channel/hooks/useChannelDataState.js.map +1 -0
- package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js +0 -6
- package/lib/commonjs/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js +4 -0
- package/lib/commonjs/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js +3 -3
- package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
- package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js +324 -0
- package/lib/commonjs/components/Channel/hooks/useMessageListPagination.js.map +1 -0
- package/lib/commonjs/components/ChannelList/Skeleton.js +7 -3
- package/lib/commonjs/components/ChannelList/Skeleton.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +85 -45
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreview.js +17 -91
- package/lib/commonjs/components/ChannelPreview/ChannelPreview.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js +3 -24
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js +2 -2
- package/lib/commonjs/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js +121 -0
- package/lib/commonjs/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -0
- package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js +35 -0
- package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -0
- package/lib/commonjs/components/Chat/Chat.js +5 -1
- package/lib/commonjs/components/Chat/Chat.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js +15 -9
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js +2 -0
- package/lib/commonjs/components/Chat/hooks/useCreateChatContext.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useIsOnline.js +0 -4
- package/lib/commonjs/components/Chat/hooks/useIsOnline.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js +46 -46
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js +3 -4
- package/lib/commonjs/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
- package/lib/commonjs/components/ImageGallery/hooks/useAnimatedGalleryStyle.js +2 -2
- package/lib/commonjs/components/ImageGallery/hooks/useAnimatedGalleryStyle.js.map +1 -1
- package/lib/commonjs/components/Message/Message.js +7 -0
- package/lib/commonjs/components/Message/Message.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/MessageContent.js +17 -4
- package/lib/commonjs/components/Message/MessageSimple/MessageContent.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js +15 -6
- package/lib/commonjs/components/Message/MessageSimple/MessageFooter.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/StreamingMessageView.js +36 -0
- package/lib/commonjs/components/Message/MessageSimple/StreamingMessageView.js.map +1 -0
- package/lib/commonjs/components/Message/MessageSimple/utils/generateMarkdownText.js +9 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/generateMarkdownText.js.map +1 -1
- package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js +209 -23
- package/lib/commonjs/components/Message/MessageSimple/utils/renderText.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js +2 -0
- package/lib/commonjs/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/commonjs/components/Message/hooks/useStreamingMessage.js +43 -0
- package/lib/commonjs/components/Message/hooks/useStreamingMessage.js.map +1 -0
- package/lib/commonjs/components/MessageInput/MessageInput.js +41 -21
- package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/commonjs/components/MessageInput/StopMessageStreamingButton.js +39 -0
- package/lib/commonjs/components/MessageInput/StopMessageStreamingButton.js.map +1 -0
- package/lib/commonjs/components/MessageList/MessageList.js +74 -73
- package/lib/commonjs/components/MessageList/MessageList.js.map +1 -1
- package/lib/commonjs/components/MessageList/ScrollToBottomButton.js +1 -1
- package/lib/commonjs/components/MessageList/ScrollToBottomButton.js.map +1 -1
- package/lib/commonjs/components/MessageList/hooks/useMessageList.js.map +1 -1
- package/lib/commonjs/components/MessageList/utils/getReadStates.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js +4 -2
- package/lib/commonjs/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js +3 -2
- package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
- package/lib/commonjs/components/Poll/CreatePollContent.js +14 -9
- package/lib/commonjs/components/Poll/CreatePollContent.js.map +1 -1
- package/lib/commonjs/components/Poll/Poll.js +2 -8
- package/lib/commonjs/components/Poll/Poll.js.map +1 -1
- package/lib/commonjs/components/Poll/components/Button.js +9 -474
- package/lib/commonjs/components/Poll/components/Button.js.map +1 -1
- package/lib/commonjs/components/Poll/components/CreatePollIcon.js +2 -2
- package/lib/commonjs/components/Poll/components/CreatePollIcon.js.map +1 -1
- package/lib/commonjs/components/Poll/components/CreatePollOptions.js +9 -4
- package/lib/commonjs/components/Poll/components/CreatePollOptions.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollAnswersList.js +99 -26
- package/lib/commonjs/components/Poll/components/PollAnswersList.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollButtons.js +291 -0
- package/lib/commonjs/components/Poll/components/PollButtons.js.map +1 -0
- package/lib/commonjs/components/Poll/components/PollInputDialog.js +14 -4
- package/lib/commonjs/components/Poll/components/PollInputDialog.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollModalHeader.js +7 -1
- package/lib/commonjs/components/Poll/components/PollModalHeader.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollOption.js +88 -6
- package/lib/commonjs/components/Poll/components/PollOption.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollResults/PollOptionFullResults.js +2 -2
- package/lib/commonjs/components/Poll/components/PollResults/PollOptionFullResults.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js +62 -67
- package/lib/commonjs/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
- package/lib/commonjs/components/Poll/components/PollResults/PollVote.js +89 -0
- package/lib/commonjs/components/Poll/components/PollResults/PollVote.js.map +1 -0
- package/lib/commonjs/components/Poll/components/index.js +11 -0
- package/lib/commonjs/components/Poll/components/index.js.map +1 -1
- package/lib/commonjs/components/ThreadList/ThreadList.js +0 -3
- package/lib/commonjs/components/ThreadList/ThreadList.js.map +1 -1
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js +11 -5
- package/lib/commonjs/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/commonjs/components/index.js +66 -0
- package/lib/commonjs/components/index.js.map +1 -1
- package/lib/commonjs/contexts/channelContext/ChannelContext.js.map +1 -1
- package/lib/commonjs/contexts/channelsStateContext/ChannelsStateContext.js +0 -35
- package/lib/commonjs/contexts/channelsStateContext/ChannelsStateContext.js.map +1 -1
- package/lib/commonjs/contexts/channelsStateContext/useChannelState.js +7 -84
- package/lib/commonjs/contexts/channelsStateContext/useChannelState.js.map +1 -1
- package/lib/commonjs/contexts/chatContext/ChatContext.js.map +1 -1
- package/lib/commonjs/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +4 -2
- package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
- package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/commonjs/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/commonjs/contexts/paginatedMessageListContext/PaginatedMessageListContext.js.map +1 -1
- package/lib/commonjs/contexts/themeContext/utils/theme.js +15 -0
- package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/commonjs/i18n/en.json +2 -0
- package/lib/commonjs/i18n/es.json +2 -0
- package/lib/commonjs/i18n/fr.json +2 -0
- package/lib/commonjs/i18n/he.json +2 -0
- package/lib/commonjs/i18n/hi.json +2 -0
- package/lib/commonjs/i18n/it.json +2 -0
- package/lib/commonjs/i18n/ja.json +2 -0
- package/lib/commonjs/i18n/ko.json +2 -0
- package/lib/commonjs/i18n/nl.json +2 -0
- package/lib/commonjs/i18n/pt-br.json +2 -0
- package/lib/commonjs/i18n/ru.json +2 -0
- package/lib/commonjs/i18n/tr.json +2 -0
- package/lib/commonjs/mock-builders/event/notificationChannelMutesUpdated.js +14 -0
- package/lib/commonjs/mock-builders/event/notificationChannelMutesUpdated.js.map +1 -0
- package/lib/commonjs/mock-builders/event/notificationMarkRead.js +14 -0
- package/lib/commonjs/mock-builders/event/notificationMarkRead.js.map +1 -0
- package/lib/commonjs/mock-builders/event/notificationMarkUnread.js +17 -0
- package/lib/commonjs/mock-builders/event/notificationMarkUnread.js.map +1 -0
- package/lib/commonjs/mock-builders/generator/channel.js +1 -0
- package/lib/commonjs/mock-builders/generator/channel.js.map +1 -1
- package/lib/commonjs/store/SqliteClient.js +11 -2
- package/lib/commonjs/store/SqliteClient.js.map +1 -1
- package/lib/commonjs/utils/getTrimmedAttachmentTitle.js +8 -2
- package/lib/commonjs/utils/getTrimmedAttachmentTitle.js.map +1 -1
- package/lib/commonjs/utils/utils.js +3 -2
- package/lib/commonjs/utils/utils.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js +53 -0
- package/lib/module/components/AITypingIndicatorView/AITypingIndicatorView.js.map +1 -0
- package/lib/module/components/AITypingIndicatorView/hooks/useAIState.js +59 -0
- package/lib/module/components/AITypingIndicatorView/hooks/useAIState.js.map +1 -0
- package/lib/module/components/AITypingIndicatorView/index.js +26 -0
- package/lib/module/components/AITypingIndicatorView/index.js.map +1 -0
- package/lib/module/components/Attachment/AudioAttachment.js +27 -22
- package/lib/module/components/Attachment/AudioAttachment.js.map +1 -1
- package/lib/module/components/Attachment/Gallery.js +3 -1
- package/lib/module/components/Attachment/Gallery.js.map +1 -1
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js +2 -2
- package/lib/module/components/AttachmentPicker/AttachmentPicker.js.map +1 -1
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js +37 -133
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerItem.js.map +1 -1
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js +6 -4
- package/lib/module/components/AttachmentPicker/components/AttachmentPickerSelectionBar.js.map +1 -1
- package/lib/module/components/Channel/Channel.js +483 -1056
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/Channel/hooks/useChannelDataState.js +174 -0
- package/lib/module/components/Channel/hooks/useChannelDataState.js.map +1 -0
- package/lib/module/components/Channel/hooks/useCreateChannelContext.js +0 -6
- package/lib/module/components/Channel/hooks/useCreateChannelContext.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +2 -0
- package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreateMessagesContext.js +4 -0
- package/lib/module/components/Channel/hooks/useCreateMessagesContext.js.map +1 -1
- package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js +3 -3
- package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
- package/lib/module/components/Channel/hooks/useMessageListPagination.js +324 -0
- package/lib/module/components/Channel/hooks/useMessageListPagination.js.map +1 -0
- package/lib/module/components/ChannelList/Skeleton.js +7 -3
- package/lib/module/components/ChannelList/Skeleton.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +85 -45
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreview.js +17 -91
- package/lib/module/components/ChannelPreview/ChannelPreview.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js +3 -24
- package/lib/module/components/ChannelPreview/ChannelPreviewMessenger.js.map +1 -1
- package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js +2 -2
- package/lib/module/components/ChannelPreview/ChannelPreviewMutedStatus.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js +121 -0
- package/lib/module/components/ChannelPreview/hooks/useChannelPreviewData.js.map +1 -0
- package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js +35 -0
- package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -0
- package/lib/module/components/Chat/Chat.js +5 -1
- package/lib/module/components/Chat/Chat.js.map +1 -1
- package/lib/module/components/Chat/hooks/useAppSettings.js +15 -9
- package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/module/components/Chat/hooks/useCreateChatContext.js +2 -0
- package/lib/module/components/Chat/hooks/useCreateChatContext.js.map +1 -1
- package/lib/module/components/Chat/hooks/useIsOnline.js +0 -4
- package/lib/module/components/Chat/hooks/useIsOnline.js.map +1 -1
- package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js +46 -46
- package/lib/module/components/ImageGallery/components/ImageGalleryFooter.js.map +1 -1
- package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js +3 -4
- package/lib/module/components/ImageGallery/components/ImageGalleryHeader.js.map +1 -1
- package/lib/module/components/ImageGallery/hooks/useAnimatedGalleryStyle.js +2 -2
- package/lib/module/components/ImageGallery/hooks/useAnimatedGalleryStyle.js.map +1 -1
- package/lib/module/components/Message/Message.js +7 -0
- package/lib/module/components/Message/Message.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/MessageContent.js +17 -4
- package/lib/module/components/Message/MessageSimple/MessageContent.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/MessageFooter.js +15 -6
- package/lib/module/components/Message/MessageSimple/MessageFooter.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/StreamingMessageView.js +36 -0
- package/lib/module/components/Message/MessageSimple/StreamingMessageView.js.map +1 -0
- package/lib/module/components/Message/MessageSimple/utils/generateMarkdownText.js +9 -1
- package/lib/module/components/Message/MessageSimple/utils/generateMarkdownText.js.map +1 -1
- package/lib/module/components/Message/MessageSimple/utils/renderText.js +209 -23
- package/lib/module/components/Message/MessageSimple/utils/renderText.js.map +1 -1
- package/lib/module/components/Message/hooks/useCreateMessageContext.js +2 -0
- package/lib/module/components/Message/hooks/useCreateMessageContext.js.map +1 -1
- package/lib/module/components/Message/hooks/useStreamingMessage.js +43 -0
- package/lib/module/components/Message/hooks/useStreamingMessage.js.map +1 -0
- package/lib/module/components/MessageInput/MessageInput.js +41 -21
- package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
- package/lib/module/components/MessageInput/StopMessageStreamingButton.js +39 -0
- package/lib/module/components/MessageInput/StopMessageStreamingButton.js.map +1 -0
- package/lib/module/components/MessageList/MessageList.js +74 -73
- package/lib/module/components/MessageList/MessageList.js.map +1 -1
- package/lib/module/components/MessageList/ScrollToBottomButton.js +1 -1
- package/lib/module/components/MessageList/ScrollToBottomButton.js.map +1 -1
- package/lib/module/components/MessageList/hooks/useMessageList.js.map +1 -1
- package/lib/module/components/MessageList/utils/getReadStates.js.map +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactions.js +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactionsItem.js +4 -2
- package/lib/module/components/MessageMenu/MessageUserReactionsItem.js.map +1 -1
- package/lib/module/components/MessageMenu/hooks/useFetchReactions.js +3 -2
- package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
- package/lib/module/components/Poll/CreatePollContent.js +14 -9
- package/lib/module/components/Poll/CreatePollContent.js.map +1 -1
- package/lib/module/components/Poll/Poll.js +2 -8
- package/lib/module/components/Poll/Poll.js.map +1 -1
- package/lib/module/components/Poll/components/Button.js +9 -474
- package/lib/module/components/Poll/components/Button.js.map +1 -1
- package/lib/module/components/Poll/components/CreatePollIcon.js +2 -2
- package/lib/module/components/Poll/components/CreatePollIcon.js.map +1 -1
- package/lib/module/components/Poll/components/CreatePollOptions.js +9 -4
- package/lib/module/components/Poll/components/CreatePollOptions.js.map +1 -1
- package/lib/module/components/Poll/components/PollAnswersList.js +99 -26
- package/lib/module/components/Poll/components/PollAnswersList.js.map +1 -1
- package/lib/module/components/Poll/components/PollButtons.js +291 -0
- package/lib/module/components/Poll/components/PollButtons.js.map +1 -0
- package/lib/module/components/Poll/components/PollInputDialog.js +14 -4
- package/lib/module/components/Poll/components/PollInputDialog.js.map +1 -1
- package/lib/module/components/Poll/components/PollModalHeader.js +7 -1
- package/lib/module/components/Poll/components/PollModalHeader.js.map +1 -1
- package/lib/module/components/Poll/components/PollOption.js +88 -6
- package/lib/module/components/Poll/components/PollOption.js.map +1 -1
- package/lib/module/components/Poll/components/PollResults/PollOptionFullResults.js +2 -2
- package/lib/module/components/Poll/components/PollResults/PollOptionFullResults.js.map +1 -1
- package/lib/module/components/Poll/components/PollResults/PollResultItem.js +62 -67
- package/lib/module/components/Poll/components/PollResults/PollResultItem.js.map +1 -1
- package/lib/module/components/Poll/components/PollResults/PollVote.js +89 -0
- package/lib/module/components/Poll/components/PollResults/PollVote.js.map +1 -0
- package/lib/module/components/Poll/components/index.js +11 -0
- package/lib/module/components/Poll/components/index.js.map +1 -1
- package/lib/module/components/ThreadList/ThreadList.js +0 -3
- package/lib/module/components/ThreadList/ThreadList.js.map +1 -1
- package/lib/module/components/UIComponents/BottomSheetModal.js +11 -5
- package/lib/module/components/UIComponents/BottomSheetModal.js.map +1 -1
- package/lib/module/components/index.js +66 -0
- package/lib/module/components/index.js.map +1 -1
- package/lib/module/contexts/channelContext/ChannelContext.js.map +1 -1
- package/lib/module/contexts/channelsStateContext/ChannelsStateContext.js +0 -35
- package/lib/module/contexts/channelsStateContext/ChannelsStateContext.js.map +1 -1
- package/lib/module/contexts/channelsStateContext/useChannelState.js +7 -84
- package/lib/module/contexts/channelsStateContext/useChannelState.js.map +1 -1
- package/lib/module/contexts/chatContext/ChatContext.js.map +1 -1
- package/lib/module/contexts/messageContext/MessageContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/MessageInputContext.js +4 -2
- package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +2 -0
- package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
- package/lib/module/contexts/messagesContext/MessagesContext.js.map +1 -1
- package/lib/module/contexts/paginatedMessageListContext/PaginatedMessageListContext.js.map +1 -1
- package/lib/module/contexts/themeContext/utils/theme.js +15 -0
- package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
- package/lib/module/i18n/en.json +2 -0
- package/lib/module/i18n/es.json +2 -0
- package/lib/module/i18n/fr.json +2 -0
- package/lib/module/i18n/he.json +2 -0
- package/lib/module/i18n/hi.json +2 -0
- package/lib/module/i18n/it.json +2 -0
- package/lib/module/i18n/ja.json +2 -0
- package/lib/module/i18n/ko.json +2 -0
- package/lib/module/i18n/nl.json +2 -0
- package/lib/module/i18n/pt-br.json +2 -0
- package/lib/module/i18n/ru.json +2 -0
- package/lib/module/i18n/tr.json +2 -0
- package/lib/module/mock-builders/event/notificationChannelMutesUpdated.js +14 -0
- package/lib/module/mock-builders/event/notificationChannelMutesUpdated.js.map +1 -0
- package/lib/module/mock-builders/event/notificationMarkRead.js +14 -0
- package/lib/module/mock-builders/event/notificationMarkRead.js.map +1 -0
- package/lib/module/mock-builders/event/notificationMarkUnread.js +17 -0
- package/lib/module/mock-builders/event/notificationMarkUnread.js.map +1 -0
- package/lib/module/mock-builders/generator/channel.js +1 -0
- package/lib/module/mock-builders/generator/channel.js.map +1 -1
- package/lib/module/store/SqliteClient.js +11 -2
- package/lib/module/store/SqliteClient.js.map +1 -1
- package/lib/module/utils/getTrimmedAttachmentTitle.js +8 -2
- package/lib/module/utils/getTrimmedAttachmentTitle.js.map +1 -1
- package/lib/module/utils/utils.js +3 -2
- package/lib/module/utils/utils.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/AITypingIndicatorView/AITypingIndicatorView.d.ts +11 -0
- package/lib/typescript/components/AITypingIndicatorView/AITypingIndicatorView.d.ts.map +1 -0
- package/lib/typescript/components/AITypingIndicatorView/hooks/useAIState.d.ts +18 -0
- package/lib/typescript/components/AITypingIndicatorView/hooks/useAIState.d.ts.map +1 -0
- package/lib/typescript/components/AITypingIndicatorView/index.d.ts +3 -0
- package/lib/typescript/components/AITypingIndicatorView/index.d.ts.map +1 -0
- package/lib/typescript/components/Attachment/AudioAttachment.d.ts.map +1 -1
- package/lib/typescript/components/AttachmentPicker/AttachmentPicker.d.ts.map +1 -1
- package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerItem.d.ts.map +1 -1
- package/lib/typescript/components/AttachmentPicker/components/AttachmentPickerSelectionBar.d.ts.map +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts +7 -6
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts +75 -0
- package/lib/typescript/components/Channel/hooks/useChannelDataState.d.ts.map +1 -0
- package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateChannelContext.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts +128 -1
- package/lib/typescript/components/Channel/hooks/useCreateMessagesContext.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreatePaginatedMessageListContext.d.ts +1 -1
- package/lib/typescript/components/Channel/hooks/useCreatePaginatedMessageListContext.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts +28 -0
- package/lib/typescript/components/Channel/hooks/useMessageListPagination.d.ts.map +1 -0
- package/lib/typescript/components/ChannelList/Skeleton.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreview.d.ts +1 -2
- package/lib/typescript/components/ChannelPreview/ChannelPreview.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewMessenger.d.ts +2 -0
- package/lib/typescript/components/ChannelPreview/ChannelPreviewMessenger.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/ChannelPreviewMutedStatus.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts +8 -0
- package/lib/typescript/components/ChannelPreview/hooks/useChannelPreviewData.d.ts.map +1 -0
- package/lib/typescript/components/ChannelPreview/hooks/useIsChannelMuted.d.ts +8 -0
- package/lib/typescript/components/ChannelPreview/hooks/useIsChannelMuted.d.ts.map +1 -0
- package/lib/typescript/components/Chat/Chat.d.ts +7 -1
- package/lib/typescript/components/Chat/Chat.d.ts.map +1 -1
- package/lib/typescript/components/Chat/hooks/useAppSettings.d.ts.map +1 -1
- package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts +1 -1
- package/lib/typescript/components/Chat/hooks/useCreateChatContext.d.ts.map +1 -1
- package/lib/typescript/components/Chat/hooks/useIsOnline.d.ts.map +1 -1
- package/lib/typescript/components/ImageGallery/ImageGallery.d.ts.map +1 -1
- package/lib/typescript/components/Message/Message.d.ts +1 -1
- package/lib/typescript/components/Message/Message.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts +1 -1
- package/lib/typescript/components/Message/MessageSimple/MessageContent.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageSimple/MessageFooter.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageSimple/StreamingMessageView.d.ts +12 -0
- package/lib/typescript/components/Message/MessageSimple/StreamingMessageView.d.ts.map +1 -0
- package/lib/typescript/components/Message/MessageSimple/utils/generateMarkdownText.d.ts.map +1 -1
- package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts +16 -1
- package/lib/typescript/components/Message/MessageSimple/utils/renderText.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts +1 -1
- package/lib/typescript/components/Message/hooks/useCreateMessageContext.d.ts.map +1 -1
- package/lib/typescript/components/Message/hooks/useStreamingMessage.d.ts +17 -0
- package/lib/typescript/components/Message/hooks/useStreamingMessage.d.ts.map +1 -0
- package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
- package/lib/typescript/components/MessageInput/MessageInput.d.ts.map +1 -1
- package/lib/typescript/components/MessageInput/StopMessageStreamingButton.d.ts +10 -0
- package/lib/typescript/components/MessageInput/StopMessageStreamingButton.d.ts.map +1 -0
- package/lib/typescript/components/MessageList/MessageList.d.ts +1 -1
- package/lib/typescript/components/MessageList/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/hooks/useMessageList.d.ts.map +1 -1
- package/lib/typescript/components/MessageList/utils/getReadStates.d.ts +1 -1
- package/lib/typescript/components/MessageList/utils/getReadStates.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/MessageUserReactionsItem.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts +3 -2
- package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
- package/lib/typescript/components/Poll/Poll.d.ts +0 -1
- package/lib/typescript/components/Poll/Poll.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/Button.d.ts +0 -17
- package/lib/typescript/components/Poll/components/Button.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/CreatePollOptions.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollAnswersList.d.ts +2 -0
- package/lib/typescript/components/Poll/components/PollAnswersList.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollButtons.d.ts +10 -0
- package/lib/typescript/components/Poll/components/PollButtons.d.ts.map +1 -0
- package/lib/typescript/components/Poll/components/PollInputDialog.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollOption.d.ts +2 -0
- package/lib/typescript/components/Poll/components/PollOption.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts +11 -4
- package/lib/typescript/components/Poll/components/PollResults/PollResultItem.d.ts.map +1 -1
- package/lib/typescript/components/Poll/components/PollResults/PollVote.d.ts +6 -0
- package/lib/typescript/components/Poll/components/PollResults/PollVote.d.ts.map +1 -0
- package/lib/typescript/components/Poll/components/index.d.ts +1 -0
- package/lib/typescript/components/Poll/components/index.d.ts.map +1 -1
- package/lib/typescript/components/ThreadList/ThreadList.d.ts.map +1 -1
- package/lib/typescript/components/UIComponents/BottomSheetModal.d.ts.map +1 -1
- package/lib/typescript/components/index.d.ts +6 -0
- package/lib/typescript/components/index.d.ts.map +1 -1
- package/lib/typescript/contexts/channelContext/ChannelContext.d.ts +27 -37
- package/lib/typescript/contexts/channelContext/ChannelContext.d.ts.map +1 -1
- package/lib/typescript/contexts/channelsStateContext/ChannelsStateContext.d.ts +0 -16
- package/lib/typescript/contexts/channelsStateContext/ChannelsStateContext.d.ts.map +1 -1
- package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts +7 -13
- package/lib/typescript/contexts/channelsStateContext/useChannelState.d.ts.map +1 -1
- package/lib/typescript/contexts/chatContext/ChatContext.d.ts +2 -1
- package/lib/typescript/contexts/chatContext/ChatContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts +4 -0
- package/lib/typescript/contexts/messageContext/MessageContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +2 -1
- package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
- package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts.map +1 -1
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +8 -4
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
- package/lib/typescript/contexts/paginatedMessageListContext/PaginatedMessageListContext.d.ts +17 -16
- package/lib/typescript/contexts/paginatedMessageListContext/PaginatedMessageListContext.d.ts.map +1 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts +16 -1
- package/lib/typescript/contexts/themeContext/utils/theme.d.ts.map +1 -1
- package/lib/typescript/i18n/en.json +2 -0
- package/lib/typescript/i18n/es.json +2 -0
- package/lib/typescript/i18n/fr.json +2 -0
- package/lib/typescript/i18n/he.json +2 -0
- package/lib/typescript/i18n/hi.json +2 -0
- package/lib/typescript/i18n/it.json +2 -0
- package/lib/typescript/i18n/ja.json +2 -0
- package/lib/typescript/i18n/ko.json +2 -0
- package/lib/typescript/i18n/nl.json +2 -0
- package/lib/typescript/i18n/pt-br.json +2 -0
- package/lib/typescript/i18n/ru.json +2 -0
- package/lib/typescript/i18n/tr.json +2 -0
- package/lib/typescript/store/SqliteClient.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +3 -0
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/utils/getTrimmedAttachmentTitle.d.ts.map +1 -1
- package/lib/typescript/utils/i18n/Streami18n.d.ts +2 -0
- package/lib/typescript/utils/i18n/Streami18n.d.ts.map +1 -1
- package/lib/typescript/utils/utils.d.ts.map +1 -1
- package/package.json +5 -5
- package/src/components/AITypingIndicatorView/AITypingIndicatorView.tsx +50 -0
- package/src/components/AITypingIndicatorView/hooks/useAIState.ts +68 -0
- package/src/components/AITypingIndicatorView/index.ts +2 -0
- package/src/components/Attachment/AudioAttachment.tsx +20 -19
- package/src/components/Attachment/Gallery.tsx +1 -1
- package/src/components/AttachmentPicker/AttachmentPicker.tsx +7 -2
- package/src/components/AttachmentPicker/components/AttachmentPickerItem.tsx +16 -32
- package/src/components/AttachmentPicker/components/AttachmentPickerSelectionBar.tsx +3 -5
- package/src/components/Channel/Channel.tsx +262 -835
- package/src/components/Channel/__tests__/Channel.test.js +244 -13
- package/src/components/Channel/__tests__/useMessageListPagination.test.js +419 -0
- package/src/components/Channel/hooks/useChannelDataState.ts +235 -0
- package/src/components/Channel/hooks/useCreateChannelContext.ts +0 -6
- package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +2 -0
- package/src/components/Channel/hooks/useCreateMessagesContext.ts +4 -0
- package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +3 -10
- package/src/components/Channel/hooks/useMessageListPagination.tsx +246 -0
- package/src/components/ChannelList/Skeleton.tsx +9 -1
- package/src/components/ChannelList/hooks/usePaginatedChannels.ts +37 -30
- package/src/components/ChannelPreview/ChannelPreview.tsx +28 -107
- package/src/components/ChannelPreview/ChannelPreviewMessenger.tsx +5 -15
- package/src/components/ChannelPreview/ChannelPreviewMutedStatus.tsx +2 -7
- package/src/components/ChannelPreview/__tests__/ChannelPreview.test.tsx +226 -10
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewDisplayName.test.tsx +1 -1
- package/src/components/ChannelPreview/hooks/__tests__/useChannelPreviewMuted.test.tsx +62 -0
- package/src/components/ChannelPreview/hooks/useChannelPreviewData.ts +138 -0
- package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +29 -0
- package/src/components/Chat/Chat.tsx +11 -2
- package/src/components/Chat/hooks/__tests__/useAppSettings.test.tsx +1 -0
- package/src/components/Chat/hooks/useAppSettings.ts +2 -0
- package/src/components/Chat/hooks/useCreateChatContext.ts +2 -0
- package/src/components/Chat/hooks/useIsOnline.ts +0 -5
- package/src/components/ImageGallery/ImageGallery.tsx +1 -0
- package/src/components/ImageGallery/components/ImageGalleryFooter.tsx +32 -32
- package/src/components/ImageGallery/components/ImageGalleryHeader.tsx +5 -6
- package/src/components/ImageGallery/hooks/useAnimatedGalleryStyle.tsx +2 -2
- package/src/components/Message/Message.tsx +16 -2
- package/src/components/Message/MessageSimple/MessageContent.tsx +22 -2
- package/src/components/Message/MessageSimple/MessageFooter.tsx +16 -5
- package/src/components/Message/MessageSimple/StreamingMessageView.tsx +34 -0
- package/src/components/Message/MessageSimple/utils/generateMarkdownText.ts +15 -1
- package/src/components/Message/MessageSimple/utils/renderText.tsx +207 -3
- package/src/components/Message/hooks/useCreateMessageContext.ts +2 -0
- package/src/components/Message/hooks/useStreamingMessage.ts +54 -0
- package/src/components/MessageInput/MessageInput.tsx +38 -20
- package/src/components/MessageInput/StopMessageStreamingButton.tsx +34 -0
- package/src/components/MessageInput/__tests__/MessageInput.test.js +116 -2
- package/src/components/MessageList/MessageList.tsx +53 -85
- package/src/components/MessageList/ScrollToBottomButton.tsx +1 -1
- package/src/components/MessageList/__tests__/MessageList.test.js +174 -2
- package/src/components/MessageList/__tests__/ScrollToBottomButton.test.js +3 -3
- package/src/components/MessageList/__tests__/__snapshots__/ScrollToBottomButton.test.js.snap +1 -1
- package/src/components/MessageList/hooks/useMessageList.ts +2 -5
- package/src/components/MessageList/utils/getReadStates.ts +3 -2
- package/src/components/MessageMenu/MessageUserReactions.tsx +1 -1
- package/src/components/MessageMenu/MessageUserReactionsItem.tsx +4 -2
- package/src/components/MessageMenu/hooks/useFetchReactions.ts +6 -3
- package/src/components/Poll/CreatePollContent.tsx +4 -4
- package/src/components/Poll/Poll.tsx +1 -20
- package/src/components/Poll/components/Button.tsx +8 -420
- package/src/components/Poll/components/CreatePollIcon.tsx +1 -1
- package/src/components/Poll/components/CreatePollOptions.tsx +9 -4
- package/src/components/Poll/components/PollAnswersList.tsx +66 -3
- package/src/components/Poll/components/PollButtons.tsx +241 -0
- package/src/components/Poll/components/PollInputDialog.tsx +9 -6
- package/src/components/Poll/components/PollModalHeader.tsx +3 -3
- package/src/components/Poll/components/PollOption.tsx +74 -4
- package/src/components/Poll/components/PollResults/PollOptionFullResults.tsx +1 -1
- package/src/components/Poll/components/PollResults/PollResultItem.tsx +68 -52
- package/src/components/Poll/components/PollResults/PollVote.tsx +68 -0
- package/src/components/Poll/components/index.ts +1 -0
- package/src/components/Thread/__tests__/__snapshots__/Thread.test.js.snap +37 -4
- package/src/components/ThreadList/ThreadList.tsx +0 -2
- package/src/components/UIComponents/BottomSheetModal.tsx +7 -3
- package/src/components/index.ts +7 -0
- package/src/contexts/channelContext/ChannelContext.tsx +35 -37
- package/src/contexts/channelsStateContext/ChannelsStateContext.tsx +1 -67
- package/src/contexts/channelsStateContext/useChannelState.ts +6 -108
- package/src/contexts/chatContext/ChatContext.tsx +2 -1
- package/src/contexts/messageContext/MessageContext.tsx +4 -0
- package/src/contexts/messageInputContext/MessageInputContext.tsx +5 -1
- package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +2 -0
- package/src/contexts/messagesContext/MessagesContext.tsx +8 -3
- package/src/contexts/paginatedMessageListContext/PaginatedMessageListContext.tsx +17 -16
- package/src/contexts/themeContext/utils/theme.ts +30 -1
- package/src/i18n/en.json +2 -0
- package/src/i18n/es.json +2 -0
- package/src/i18n/fr.json +2 -0
- package/src/i18n/he.json +2 -0
- package/src/i18n/hi.json +2 -0
- package/src/i18n/it.json +2 -0
- package/src/i18n/ja.json +2 -0
- package/src/i18n/ko.json +2 -0
- package/src/i18n/nl.json +2 -0
- package/src/i18n/pt-br.json +2 -0
- package/src/i18n/ru.json +2 -0
- package/src/i18n/tr.json +2 -0
- package/src/mock-builders/event/notificationChannelMutesUpdated.js +7 -0
- package/src/mock-builders/event/notificationMarkRead.js +7 -0
- package/src/mock-builders/event/notificationMarkUnread.js +9 -0
- package/src/mock-builders/generator/channel.ts +1 -0
- package/src/store/SqliteClient.ts +5 -1
- package/src/types/types.ts +3 -0
- package/src/utils/getTrimmedAttachmentTitle.ts +10 -2
- package/src/utils/utils.ts +5 -2
- package/src/version.json +1 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { PropsWithChildren, useCallback, useEffect,
|
|
1
|
+
import React, { PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
|
|
2
2
|
import { KeyboardAvoidingViewProps, StyleSheet, Text, View } from 'react-native';
|
|
3
3
|
|
|
4
4
|
import debounce from 'lodash/debounce';
|
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
ChannelState,
|
|
12
12
|
Channel as ChannelType,
|
|
13
13
|
EventHandler,
|
|
14
|
+
FormatMessageResponse,
|
|
14
15
|
logChatPromiseExecution,
|
|
15
16
|
MessageResponse,
|
|
16
17
|
Reaction,
|
|
@@ -21,6 +22,7 @@ import {
|
|
|
21
22
|
Thread,
|
|
22
23
|
} from 'stream-chat';
|
|
23
24
|
|
|
25
|
+
import { useChannelDataState } from './hooks/useChannelDataState';
|
|
24
26
|
import { useCreateChannelContext } from './hooks/useCreateChannelContext';
|
|
25
27
|
|
|
26
28
|
import { useCreateInputMessageInputContext } from './hooks/useCreateInputMessageInputContext';
|
|
@@ -34,8 +36,10 @@ import { useCreateThreadContext } from './hooks/useCreateThreadContext';
|
|
|
34
36
|
|
|
35
37
|
import { useCreateTypingContext } from './hooks/useCreateTypingContext';
|
|
36
38
|
|
|
39
|
+
import { useMessageListPagination } from './hooks/useMessageListPagination';
|
|
37
40
|
import { useTargetedMessage } from './hooks/useTargetedMessage';
|
|
38
41
|
|
|
42
|
+
import { MessageContextValue } from '../../contexts';
|
|
39
43
|
import { ChannelContextValue, ChannelProvider } from '../../contexts/channelContext/ChannelContext';
|
|
40
44
|
import type { UseChannelStateValue } from '../../contexts/channelsStateContext/useChannelState';
|
|
41
45
|
import { useChannelState } from '../../contexts/channelsStateContext/useChannelState';
|
|
@@ -142,6 +146,7 @@ import { MessageStatus as MessageStatusDefault } from '../Message/MessageSimple/
|
|
|
142
146
|
import { MessageTimestamp as MessageTimestampDefault } from '../Message/MessageSimple/MessageTimestamp';
|
|
143
147
|
import { ReactionListBottom as ReactionListBottomDefault } from '../Message/MessageSimple/ReactionList/ReactionListBottom';
|
|
144
148
|
import { ReactionListTop as ReactionListTopDefault } from '../Message/MessageSimple/ReactionList/ReactionListTop';
|
|
149
|
+
import { StreamingMessageView as DefaultStreamingMessageView } from '../Message/MessageSimple/StreamingMessageView';
|
|
145
150
|
import { AttachButton as AttachButtonDefault } from '../MessageInput/AttachButton';
|
|
146
151
|
import { CommandsButton as CommandsButtonDefault } from '../MessageInput/CommandsButton';
|
|
147
152
|
import { AudioRecorder as AudioRecorderDefault } from '../MessageInput/components/AudioRecorder/AudioRecorder';
|
|
@@ -161,6 +166,7 @@ import { MoreOptionsButton as MoreOptionsButtonDefault } from '../MessageInput/M
|
|
|
161
166
|
import { SendButton as SendButtonDefault } from '../MessageInput/SendButton';
|
|
162
167
|
import { SendMessageDisallowedIndicator as SendMessageDisallowedIndicatorDefault } from '../MessageInput/SendMessageDisallowedIndicator';
|
|
163
168
|
import { ShowThreadMessageInChannelButton as ShowThreadMessageInChannelButtonDefault } from '../MessageInput/ShowThreadMessageInChannelButton';
|
|
169
|
+
import { StopMessageStreamingButton as DefaultStopMessageStreamingButton } from '../MessageInput/StopMessageStreamingButton';
|
|
164
170
|
import { UploadProgressIndicator as UploadProgressIndicatorDefault } from '../MessageInput/UploadProgressIndicator';
|
|
165
171
|
import { DateHeader as DateHeaderDefault } from '../MessageList/DateHeader';
|
|
166
172
|
import type { MessageType } from '../MessageList/hooks/useMessageList';
|
|
@@ -265,7 +271,7 @@ export type ChannelPropsWithContext<
|
|
|
265
271
|
'messages' | 'loadingMore' | 'loadingMoreRecent'
|
|
266
272
|
>
|
|
267
273
|
> &
|
|
268
|
-
UseChannelStateValue<StreamChatGenerics> &
|
|
274
|
+
Pick<UseChannelStateValue<StreamChatGenerics>, 'threadMessages' | 'setThreadMessages'> &
|
|
269
275
|
Partial<
|
|
270
276
|
Pick<
|
|
271
277
|
MessagesContextValue<StreamChatGenerics>,
|
|
@@ -354,8 +360,10 @@ export type ChannelPropsWithContext<
|
|
|
354
360
|
| 'VideoThumbnail'
|
|
355
361
|
| 'PollContent'
|
|
356
362
|
| 'hasCreatePoll'
|
|
363
|
+
| 'StreamingMessageView'
|
|
357
364
|
>
|
|
358
365
|
> &
|
|
366
|
+
Partial<Pick<MessageContextValue<StreamChatGenerics>, 'isMessageAIGenerated'>> &
|
|
359
367
|
Partial<Pick<ThreadContextValue<StreamChatGenerics>, 'allowThreadMessagesInChannel'>> & {
|
|
360
368
|
shouldSyncChannel: boolean;
|
|
361
369
|
thread: ThreadType<StreamChatGenerics>;
|
|
@@ -363,10 +371,6 @@ export type ChannelPropsWithContext<
|
|
|
363
371
|
* Additional props passed to keyboard avoiding view
|
|
364
372
|
*/
|
|
365
373
|
additionalKeyboardAvoidingViewProps?: Partial<KeyboardAvoidingViewProps>;
|
|
366
|
-
/**
|
|
367
|
-
* Disables the channel UI if the channel is frozen
|
|
368
|
-
*/
|
|
369
|
-
disableIfFrozenChannel?: boolean;
|
|
370
374
|
/**
|
|
371
375
|
* When true, disables the KeyboardCompatibleView wrapper
|
|
372
376
|
*
|
|
@@ -434,6 +438,10 @@ export type ChannelPropsWithContext<
|
|
|
434
438
|
* Load the channel at a specified message instead of the most recent message.
|
|
435
439
|
*/
|
|
436
440
|
messageId?: string;
|
|
441
|
+
/**
|
|
442
|
+
* @deprecated
|
|
443
|
+
* The time interval for throttling while updating the message state
|
|
444
|
+
*/
|
|
437
445
|
newMessageStateUpdateThrottleInterval?: number;
|
|
438
446
|
overrideOwnCapabilities?: Partial<OwnCapabilitiesContextValue>;
|
|
439
447
|
stateUpdateThrottleInterval?: number;
|
|
@@ -441,7 +449,12 @@ export type ChannelPropsWithContext<
|
|
|
441
449
|
* Tells if channel is rendering a thread list
|
|
442
450
|
*/
|
|
443
451
|
threadList?: boolean;
|
|
444
|
-
} & Partial<
|
|
452
|
+
} & Partial<
|
|
453
|
+
Pick<
|
|
454
|
+
InputMessageInputContextValue,
|
|
455
|
+
'openPollCreationDialog' | 'CreatePollContent' | 'StopMessageStreamingButton'
|
|
456
|
+
>
|
|
457
|
+
>;
|
|
445
458
|
|
|
446
459
|
const ChannelWithContext = <
|
|
447
460
|
StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
|
|
@@ -486,7 +499,6 @@ const ChannelWithContext = <
|
|
|
486
499
|
CreatePollContent,
|
|
487
500
|
DateHeader = DateHeaderDefault,
|
|
488
501
|
deletedMessagesVisibilityType = 'always',
|
|
489
|
-
disableIfFrozenChannel = true,
|
|
490
502
|
disableKeyboardCompatibleView = false,
|
|
491
503
|
disableTypingIndicator,
|
|
492
504
|
dismissKeyboardOnMessageTouch = true,
|
|
@@ -544,6 +556,7 @@ const ChannelWithContext = <
|
|
|
544
556
|
InputGiphySearch = InputGiphyCommandInputDefault,
|
|
545
557
|
InputReplyStateHeader = InputReplyStateHeaderDefault,
|
|
546
558
|
isAttachmentEqual,
|
|
559
|
+
isMessageAIGenerated = () => false,
|
|
547
560
|
keyboardBehavior,
|
|
548
561
|
KeyboardCompatibleView = KeyboardCompatibleViewDefault,
|
|
549
562
|
keyboardVerticalOffset,
|
|
@@ -556,7 +569,6 @@ const ChannelWithContext = <
|
|
|
556
569
|
maxMessageLength: maxMessageLengthProp,
|
|
557
570
|
maxNumberOfFiles = 10,
|
|
558
571
|
maxTimeBetweenGroupedMessages,
|
|
559
|
-
members,
|
|
560
572
|
mentionAllAppUsersEnabled = false,
|
|
561
573
|
mentionAllAppUsersQuery,
|
|
562
574
|
Message = MessageDefault,
|
|
@@ -566,7 +578,15 @@ const ChannelWithContext = <
|
|
|
566
578
|
MessageAvatar = MessageAvatarDefault,
|
|
567
579
|
MessageBounce = MessageBounceDefault,
|
|
568
580
|
MessageContent = MessageContentDefault,
|
|
569
|
-
messageContentOrder = [
|
|
581
|
+
messageContentOrder = [
|
|
582
|
+
'quoted_reply',
|
|
583
|
+
'gallery',
|
|
584
|
+
'files',
|
|
585
|
+
'poll',
|
|
586
|
+
'ai_text',
|
|
587
|
+
'text',
|
|
588
|
+
'attachments',
|
|
589
|
+
],
|
|
570
590
|
MessageDeleted = MessageDeletedDefault,
|
|
571
591
|
MessageEditedTimestamp = MessageEditedTimestampDefault,
|
|
572
592
|
MessageError = MessageErrorDefault,
|
|
@@ -579,12 +599,11 @@ const ChannelWithContext = <
|
|
|
579
599
|
MessageReactionPicker = MessageReactionPickerDefault,
|
|
580
600
|
MessageReplies = MessageRepliesDefault,
|
|
581
601
|
MessageRepliesAvatars = MessageRepliesAvatarsDefault,
|
|
582
|
-
messages,
|
|
583
602
|
MessageSimple = MessageSimpleDefault,
|
|
584
603
|
MessageStatus = MessageStatusDefault,
|
|
585
604
|
MessageSystem = MessageSystemDefault,
|
|
586
605
|
MessageText,
|
|
587
|
-
messageTextNumberOfLines
|
|
606
|
+
messageTextNumberOfLines,
|
|
588
607
|
MessageTimestamp = MessageTimestampDefault,
|
|
589
608
|
MessageUserReactions = MessageUserReactionsDefault,
|
|
590
609
|
MessageUserReactionsAvatar = MessageUserReactionsAvatarDefault,
|
|
@@ -592,6 +611,7 @@ const ChannelWithContext = <
|
|
|
592
611
|
MoreOptionsButton = MoreOptionsButtonDefault,
|
|
593
612
|
myMessageTheme,
|
|
594
613
|
NetworkDownIndicator = NetworkDownIndicatorDefault,
|
|
614
|
+
// TODO: Think about this one
|
|
595
615
|
newMessageStateUpdateThrottleInterval = defaultThrottleInterval,
|
|
596
616
|
numberOfLines = 5,
|
|
597
617
|
onChangeText,
|
|
@@ -604,7 +624,6 @@ const ChannelWithContext = <
|
|
|
604
624
|
ReactionListBottom = ReactionListBottomDefault,
|
|
605
625
|
reactionListPosition = 'top',
|
|
606
626
|
ReactionListTop = ReactionListTopDefault,
|
|
607
|
-
read,
|
|
608
627
|
Reply = ReplyDefault,
|
|
609
628
|
ScrollToBottomButton = ScrollToBottomButtonDefault,
|
|
610
629
|
selectReaction,
|
|
@@ -612,35 +631,32 @@ const ChannelWithContext = <
|
|
|
612
631
|
sendImageAsync = false,
|
|
613
632
|
SendMessageDisallowedIndicator = SendMessageDisallowedIndicatorDefault,
|
|
614
633
|
setInputRef,
|
|
615
|
-
setMembers,
|
|
616
|
-
setMessages,
|
|
617
|
-
setRead,
|
|
618
634
|
setThreadMessages,
|
|
619
|
-
setTyping,
|
|
620
|
-
setWatcherCount,
|
|
621
|
-
setWatchers,
|
|
622
635
|
shouldShowUnreadUnderlay = true,
|
|
623
636
|
shouldSyncChannel,
|
|
624
637
|
ShowThreadMessageInChannelButton = ShowThreadMessageInChannelButtonDefault,
|
|
625
638
|
StartAudioRecordingButton = AudioRecordingButtonDefault,
|
|
626
639
|
stateUpdateThrottleInterval = defaultThrottleInterval,
|
|
627
640
|
StickyHeader = StickyHeaderDefault,
|
|
641
|
+
StopMessageStreamingButton: StopMessageStreamingButtonOverride,
|
|
642
|
+
StreamingMessageView = DefaultStreamingMessageView,
|
|
628
643
|
supportedReactions = reactionData,
|
|
629
644
|
t,
|
|
630
645
|
thread: threadFromProps,
|
|
631
646
|
threadList,
|
|
632
647
|
threadMessages,
|
|
633
|
-
typing,
|
|
634
648
|
TypingIndicator = TypingIndicatorDefault,
|
|
635
649
|
TypingIndicatorContainer = TypingIndicatorContainerDefault,
|
|
636
650
|
UploadProgressIndicator = UploadProgressIndicatorDefault,
|
|
637
651
|
UrlPreview = CardDefault,
|
|
638
652
|
VideoThumbnail = VideoThumbnailDefault,
|
|
639
|
-
watcherCount,
|
|
640
|
-
watchers,
|
|
641
653
|
} = props;
|
|
642
654
|
|
|
643
655
|
const { thread: threadProps, threadInstance } = threadFromProps;
|
|
656
|
+
const StopMessageStreamingButton =
|
|
657
|
+
StopMessageStreamingButtonOverride === undefined
|
|
658
|
+
? DefaultStopMessageStreamingButton
|
|
659
|
+
: StopMessageStreamingButtonOverride;
|
|
644
660
|
|
|
645
661
|
const {
|
|
646
662
|
theme: {
|
|
@@ -648,15 +664,10 @@ const ChannelWithContext = <
|
|
|
648
664
|
colors: { black },
|
|
649
665
|
},
|
|
650
666
|
} = useTheme();
|
|
651
|
-
const [deleted, setDeleted] = useState(false);
|
|
667
|
+
const [deleted, setDeleted] = useState<boolean>(false);
|
|
652
668
|
const [editing, setEditing] = useState<MessageType<StreamChatGenerics> | undefined>(undefined);
|
|
653
669
|
const [error, setError] = useState<Error | boolean>(false);
|
|
654
|
-
const [hasMore, setHasMore] = useState(true);
|
|
655
670
|
const [lastRead, setLastRead] = useState<ChannelContextValue<StreamChatGenerics>['lastRead']>();
|
|
656
|
-
const [loading, setLoading] = useState(false);
|
|
657
|
-
const [loadingMore, setLoadingMore] = useState(false);
|
|
658
|
-
|
|
659
|
-
const [loadingMoreRecent, setLoadingMoreRecent] = useState(false);
|
|
660
671
|
const [quotedMessage, setQuotedMessage] = useState<MessageType<StreamChatGenerics> | undefined>(
|
|
661
672
|
undefined,
|
|
662
673
|
);
|
|
@@ -666,19 +677,7 @@ const ChannelWithContext = <
|
|
|
666
677
|
|
|
667
678
|
const syncingChannelRef = useRef(false);
|
|
668
679
|
|
|
669
|
-
|
|
670
|
-
* Flag to track if we know for sure that there are no more recent messages to load.
|
|
671
|
-
* This is necessary to avoid unnecessary api calls to load recent messages on pagination.
|
|
672
|
-
*/
|
|
673
|
-
const [hasNoMoreRecentMessagesToLoad, setHasNoMoreRecentMessagesToLoad] = useState(true);
|
|
674
|
-
|
|
675
|
-
const { prevTargetedMessage, setTargetedMessage, targetedMessage } = useTargetedMessage();
|
|
676
|
-
|
|
677
|
-
/**
|
|
678
|
-
* If we loaded a channel around message
|
|
679
|
-
* We may have moved latest message to a new message set in that case mark this ref to avoid fetching
|
|
680
|
-
*/
|
|
681
|
-
const hasOverlappingRecentMessagesRef = useRef(false);
|
|
680
|
+
const { setTargetedMessage, targetedMessage } = useTargetedMessage();
|
|
682
681
|
|
|
683
682
|
/**
|
|
684
683
|
* This ref will hold the abort controllers for
|
|
@@ -690,50 +689,142 @@ const ChannelWithContext = <
|
|
|
690
689
|
const channelId = channel?.id || '';
|
|
691
690
|
const pollCreationEnabled = !channel.disconnected && !!channel?.id && channel?.getConfig()?.polls;
|
|
692
691
|
|
|
692
|
+
const {
|
|
693
|
+
copyStateFromChannel,
|
|
694
|
+
initStateFromChannel,
|
|
695
|
+
setTyping,
|
|
696
|
+
state: channelState,
|
|
697
|
+
} = useChannelDataState<StreamChatGenerics>(channel);
|
|
698
|
+
|
|
699
|
+
const {
|
|
700
|
+
copyMessagesStateFromChannel,
|
|
701
|
+
loadChannelAroundMessage: loadChannelAroundMessageFn,
|
|
702
|
+
loadChannelAtFirstUnreadMessage,
|
|
703
|
+
loadInitialMessagesStateFromChannel,
|
|
704
|
+
loadLatestMessages,
|
|
705
|
+
loadMore,
|
|
706
|
+
loadMoreRecent,
|
|
707
|
+
state: channelMessagesState,
|
|
708
|
+
} = useMessageListPagination<StreamChatGenerics>({
|
|
709
|
+
channel,
|
|
710
|
+
});
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Since we copy the current channel state all together, we need to find the greatest time among the below two and apply it as the throttling time for copying the channel state.
|
|
714
|
+
* This is done until we remove the newMessageStateUpdateThrottleInterval prop.
|
|
715
|
+
*/
|
|
716
|
+
const copyChannelStateThrottlingTime =
|
|
717
|
+
newMessageStateUpdateThrottleInterval > stateUpdateThrottleInterval
|
|
718
|
+
? newMessageStateUpdateThrottleInterval
|
|
719
|
+
: stateUpdateThrottleInterval;
|
|
720
|
+
|
|
721
|
+
const copyChannelState = useRef(
|
|
722
|
+
throttle(
|
|
723
|
+
() => {
|
|
724
|
+
if (channel) {
|
|
725
|
+
copyStateFromChannel(channel);
|
|
726
|
+
copyMessagesStateFromChannel(channel);
|
|
727
|
+
}
|
|
728
|
+
},
|
|
729
|
+
copyChannelStateThrottlingTime,
|
|
730
|
+
throttleOptions,
|
|
731
|
+
),
|
|
732
|
+
).current;
|
|
733
|
+
|
|
734
|
+
const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
|
|
735
|
+
if (shouldSyncChannel) {
|
|
736
|
+
// Ignore user.watching.start and user.watching.stop events
|
|
737
|
+
const ignorableEvents = ['user.watching.start', 'user.watching.stop'];
|
|
738
|
+
if (ignorableEvents.includes(event.type)) return;
|
|
739
|
+
|
|
740
|
+
// If the event is typing.start or typing.stop, set the typing state
|
|
741
|
+
const isTypingEvent = event.type === 'typing.start' || event.type === 'typing.stop';
|
|
742
|
+
if (isTypingEvent) {
|
|
743
|
+
setTyping(channel);
|
|
744
|
+
} else {
|
|
745
|
+
if (thread?.id) {
|
|
746
|
+
const updatedThreadMessages =
|
|
747
|
+
(thread.id && channel && channel.state.threads[thread.id]) || threadMessages;
|
|
748
|
+
setThreadMessages(updatedThreadMessages);
|
|
749
|
+
|
|
750
|
+
if (channel && event.message?.id === thread.id && !threadInstance) {
|
|
751
|
+
const updatedThread = channel.state.formatMessage(event.message);
|
|
752
|
+
setThread(updatedThread);
|
|
753
|
+
}
|
|
754
|
+
}
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
// only update channel state if the events are not the previously subscribed useEffect's subscription events
|
|
758
|
+
if (channel && channel.initialized) {
|
|
759
|
+
copyChannelState();
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
};
|
|
763
|
+
|
|
693
764
|
useEffect(() => {
|
|
765
|
+
let listener: ReturnType<typeof channel.on>;
|
|
694
766
|
const initChannel = async () => {
|
|
695
767
|
if (!channel || !shouldSyncChannel || channel.offlineMode) return;
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
768
|
+
let errored = false;
|
|
769
|
+
|
|
770
|
+
if (!channel.initialized || !channel.state.isUpToDate) {
|
|
771
|
+
try {
|
|
772
|
+
await channel?.watch();
|
|
773
|
+
} catch (err) {
|
|
774
|
+
console.warn('Channel watch request failed with error:', err);
|
|
775
|
+
setError(true);
|
|
776
|
+
errored = true;
|
|
777
|
+
}
|
|
704
778
|
}
|
|
705
779
|
|
|
706
|
-
if (
|
|
707
|
-
|
|
780
|
+
if (!errored) {
|
|
781
|
+
initStateFromChannel(channel);
|
|
782
|
+
loadInitialMessagesStateFromChannel(channel, channel.state.messagePagination.hasPrev);
|
|
708
783
|
}
|
|
709
|
-
|
|
710
|
-
|
|
784
|
+
|
|
785
|
+
if (messageId) {
|
|
786
|
+
await loadChannelAroundMessage({ messageId, setTargetedMessage });
|
|
787
|
+
} else if (
|
|
711
788
|
initialScrollToFirstUnreadMessage &&
|
|
712
789
|
channel.countUnread() > scrollToFirstUnreadThreshold
|
|
713
790
|
) {
|
|
714
|
-
loadChannelAtFirstUnreadMessage();
|
|
715
|
-
}
|
|
716
|
-
// If the messageId is undefined and the last message and the current message id do not match we load the channel at the very bottom.
|
|
717
|
-
else if (
|
|
718
|
-
channel.state.messages?.[channel.state.messages.length - 1]?.id !==
|
|
719
|
-
channel.state.latestMessages?.[channel.state.latestMessages.length - 1]?.id &&
|
|
720
|
-
!messageId
|
|
721
|
-
) {
|
|
722
|
-
await loadChannel();
|
|
791
|
+
await loadChannelAtFirstUnreadMessage({ setTargetedMessage });
|
|
723
792
|
}
|
|
793
|
+
listener = channel.on(handleEvent);
|
|
724
794
|
};
|
|
725
795
|
|
|
726
796
|
initChannel();
|
|
727
797
|
|
|
728
798
|
return () => {
|
|
729
799
|
copyChannelState.cancel();
|
|
730
|
-
copyReadState.cancel();
|
|
731
|
-
copyTypingState.cancel();
|
|
732
|
-
loadMoreFinished.cancel();
|
|
733
800
|
loadMoreThreadFinished.cancel();
|
|
801
|
+
listener?.unsubscribe();
|
|
734
802
|
};
|
|
735
803
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
736
|
-
}, [
|
|
804
|
+
}, [channel.cid, messageId, shouldSyncChannel]);
|
|
805
|
+
|
|
806
|
+
// subscribe to channel.deleted event
|
|
807
|
+
useEffect(() => {
|
|
808
|
+
const { unsubscribe } = client.on('channel.deleted', (event) => {
|
|
809
|
+
if (event.cid === channel?.cid) {
|
|
810
|
+
setDeleted(true);
|
|
811
|
+
}
|
|
812
|
+
});
|
|
813
|
+
|
|
814
|
+
return unsubscribe;
|
|
815
|
+
}, [channel?.cid, client]);
|
|
816
|
+
|
|
817
|
+
/**
|
|
818
|
+
* Subscription to the Notification mark_read event.
|
|
819
|
+
*/
|
|
820
|
+
useEffect(() => {
|
|
821
|
+
const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
|
|
822
|
+
if (channel.cid === event.cid) copyChannelState();
|
|
823
|
+
};
|
|
824
|
+
|
|
825
|
+
const { unsubscribe } = client.on('notification.mark_read', handleEvent);
|
|
826
|
+
return unsubscribe;
|
|
827
|
+
}, [channel.cid, client, copyChannelState]);
|
|
737
828
|
|
|
738
829
|
const threadPropsExists = !!threadProps;
|
|
739
830
|
|
|
@@ -764,17 +855,6 @@ const ChannelWithContext = <
|
|
|
764
855
|
|
|
765
856
|
useAppStateListener(undefined, handleAppBackground);
|
|
766
857
|
|
|
767
|
-
/**
|
|
768
|
-
* CHANNEL CONSTANTS
|
|
769
|
-
*/
|
|
770
|
-
const isAdmin = client?.user?.role === 'admin' || channel?.state.membership.role === 'admin';
|
|
771
|
-
|
|
772
|
-
const isModerator =
|
|
773
|
-
channel?.state.membership.role === 'channel_moderator' ||
|
|
774
|
-
channel?.state.membership.role === 'moderator';
|
|
775
|
-
|
|
776
|
-
const isOwner = channel?.state.membership.role === 'owner';
|
|
777
|
-
|
|
778
858
|
/**
|
|
779
859
|
* CHANNEL METHODS
|
|
780
860
|
*/
|
|
@@ -796,441 +876,6 @@ const ChannelWithContext = <
|
|
|
796
876
|
),
|
|
797
877
|
).current;
|
|
798
878
|
|
|
799
|
-
const copyMessagesState = useRef(
|
|
800
|
-
throttle(
|
|
801
|
-
() => {
|
|
802
|
-
if (channel) {
|
|
803
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
804
|
-
setMessages(channel.state.messages);
|
|
805
|
-
restartSetsMergeFuncRef.current();
|
|
806
|
-
}
|
|
807
|
-
},
|
|
808
|
-
newMessageStateUpdateThrottleInterval,
|
|
809
|
-
throttleOptions,
|
|
810
|
-
),
|
|
811
|
-
).current;
|
|
812
|
-
|
|
813
|
-
const copyTypingState = useRef(
|
|
814
|
-
throttle(
|
|
815
|
-
() => {
|
|
816
|
-
if (channel) {
|
|
817
|
-
setTyping({ ...channel.state.typing });
|
|
818
|
-
}
|
|
819
|
-
},
|
|
820
|
-
stateUpdateThrottleInterval,
|
|
821
|
-
throttleOptions,
|
|
822
|
-
),
|
|
823
|
-
).current;
|
|
824
|
-
|
|
825
|
-
const copyReadState = useRef(
|
|
826
|
-
throttle(
|
|
827
|
-
() => {
|
|
828
|
-
if (channel) {
|
|
829
|
-
setRead({ ...channel.state.read });
|
|
830
|
-
}
|
|
831
|
-
},
|
|
832
|
-
stateUpdateThrottleInterval,
|
|
833
|
-
throttleOptions,
|
|
834
|
-
),
|
|
835
|
-
).current;
|
|
836
|
-
|
|
837
|
-
const copyChannelState = useRef(
|
|
838
|
-
throttle(
|
|
839
|
-
() => {
|
|
840
|
-
setLoading(false);
|
|
841
|
-
if (channel) {
|
|
842
|
-
setMembers({ ...channel.state.members });
|
|
843
|
-
setMessages([...channel.state.messages]);
|
|
844
|
-
setRead({ ...channel.state.read });
|
|
845
|
-
setTyping({ ...channel.state.typing });
|
|
846
|
-
setWatcherCount(channel.state.watcher_count);
|
|
847
|
-
setWatchers({ ...channel.state.watchers });
|
|
848
|
-
}
|
|
849
|
-
},
|
|
850
|
-
stateUpdateThrottleInterval,
|
|
851
|
-
throttleOptions,
|
|
852
|
-
),
|
|
853
|
-
).current;
|
|
854
|
-
|
|
855
|
-
// subscribe to specific channel events
|
|
856
|
-
useEffect(() => {
|
|
857
|
-
const channelSubscriptions: Array<ReturnType<ChannelType['on']>> = [];
|
|
858
|
-
if (channel && shouldSyncChannel) {
|
|
859
|
-
channelSubscriptions.push(channel.on('message.new', copyMessagesState));
|
|
860
|
-
channelSubscriptions.push(channel.on('message.read', copyReadState));
|
|
861
|
-
channelSubscriptions.push(channel.on('typing.start', copyTypingState));
|
|
862
|
-
channelSubscriptions.push(channel.on('typing.stop', copyTypingState));
|
|
863
|
-
}
|
|
864
|
-
return () => {
|
|
865
|
-
channelSubscriptions.forEach((s) => s.unsubscribe());
|
|
866
|
-
};
|
|
867
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
868
|
-
}, [channelId, shouldSyncChannel]);
|
|
869
|
-
|
|
870
|
-
// subscribe to the generic all channel event
|
|
871
|
-
useEffect(() => {
|
|
872
|
-
const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
|
|
873
|
-
const ignorableEvents = ['user.watching.start', 'user.watching.stop'];
|
|
874
|
-
if (ignorableEvents.includes(event.type)) return;
|
|
875
|
-
if (shouldSyncChannel) {
|
|
876
|
-
const isTypingEvent = event.type === 'typing.start' || event.type === 'typing.stop';
|
|
877
|
-
if (!isTypingEvent) {
|
|
878
|
-
if (thread?.id) {
|
|
879
|
-
const updatedThreadMessages =
|
|
880
|
-
(thread.id && channel && channel.state.threads[thread.id]) || threadMessages;
|
|
881
|
-
setThreadMessages(updatedThreadMessages);
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
if (channel && thread?.id && event.message?.id === thread.id && !threadInstance) {
|
|
885
|
-
const updatedThread = channel.state.formatMessage(event.message);
|
|
886
|
-
setThread(updatedThread);
|
|
887
|
-
}
|
|
888
|
-
}
|
|
889
|
-
|
|
890
|
-
// only update channel state if the events are not the previously subscribed useEffect's subscription events
|
|
891
|
-
if (
|
|
892
|
-
channel &&
|
|
893
|
-
channel.initialized &&
|
|
894
|
-
event.type !== 'message.new' &&
|
|
895
|
-
event.type !== 'message.read' &&
|
|
896
|
-
event.type !== 'typing.start' &&
|
|
897
|
-
event.type !== 'typing.stop'
|
|
898
|
-
) {
|
|
899
|
-
copyChannelState();
|
|
900
|
-
}
|
|
901
|
-
}
|
|
902
|
-
};
|
|
903
|
-
const { unsubscribe } = channel.on(handleEvent);
|
|
904
|
-
return unsubscribe;
|
|
905
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
906
|
-
}, [channelId, thread?.id, shouldSyncChannel]);
|
|
907
|
-
|
|
908
|
-
// subscribe to channel.deleted event
|
|
909
|
-
useEffect(() => {
|
|
910
|
-
const { unsubscribe } = client.on('channel.deleted', (event) => {
|
|
911
|
-
if (event.cid === channel?.cid) {
|
|
912
|
-
setDeleted(true);
|
|
913
|
-
}
|
|
914
|
-
});
|
|
915
|
-
|
|
916
|
-
return unsubscribe;
|
|
917
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
918
|
-
}, [channelId]);
|
|
919
|
-
|
|
920
|
-
useEffect(() => {
|
|
921
|
-
const handleEvent: EventHandler<StreamChatGenerics> = (event) => {
|
|
922
|
-
if (channel.cid === event.cid) copyChannelState();
|
|
923
|
-
};
|
|
924
|
-
|
|
925
|
-
const { unsubscribe } = client.on('notification.mark_read', handleEvent);
|
|
926
|
-
return unsubscribe;
|
|
927
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
928
|
-
}, []);
|
|
929
|
-
|
|
930
|
-
const channelQueryCallRef = useRef(
|
|
931
|
-
async (
|
|
932
|
-
queryCall: () => Promise<void>,
|
|
933
|
-
onAfterQueryCall: (() => void) | undefined = undefined,
|
|
934
|
-
// if we are scrolling to a message after the query, pass it here
|
|
935
|
-
scrollToMessageId: string | (() => string | undefined) | undefined = undefined,
|
|
936
|
-
) => {
|
|
937
|
-
setError(false);
|
|
938
|
-
try {
|
|
939
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
940
|
-
await queryCall();
|
|
941
|
-
setLastRead(new Date());
|
|
942
|
-
setHasMore(true);
|
|
943
|
-
const currentMessages = channel.state.messages;
|
|
944
|
-
const hadCurrentLatestMessages =
|
|
945
|
-
currentMessages.length > 0 && currentMessages === channel.state.latestMessages;
|
|
946
|
-
if (typeof scrollToMessageId === 'function') {
|
|
947
|
-
scrollToMessageId = scrollToMessageId();
|
|
948
|
-
}
|
|
949
|
-
|
|
950
|
-
const scrollToMessageIndex = scrollToMessageId
|
|
951
|
-
? currentMessages.findIndex(({ id }) => id === scrollToMessageId)
|
|
952
|
-
: -1;
|
|
953
|
-
if (channel && scrollToMessageIndex !== -1) {
|
|
954
|
-
copyChannelState.cancel();
|
|
955
|
-
// We assume that on average user sees 5 messages on screen
|
|
956
|
-
// We dont want new renders to happen while scrolling to the targeted message
|
|
957
|
-
// hence we limit the number of messages to be rendered after the targeted message to 5 - 1 = 4
|
|
958
|
-
// NOTE: we have one drawback here, if there were already a split latest and current message set
|
|
959
|
-
// the previous latest message set will be thrown away as we cannot merge it with the current message set after the target message is set
|
|
960
|
-
const limitAfter = 4;
|
|
961
|
-
const currentLength = currentMessages.length;
|
|
962
|
-
const noOfMessagesAfter = currentLength - scrollToMessageIndex - 1;
|
|
963
|
-
// number of messages are over the limit, limit the length of messages
|
|
964
|
-
if (noOfMessagesAfter > limitAfter) {
|
|
965
|
-
const endIndex = scrollToMessageIndex + limitAfter;
|
|
966
|
-
channel.state.clearMessages();
|
|
967
|
-
channel.state.messages = currentMessages.slice(0, endIndex + 1);
|
|
968
|
-
splitLatestCurrentMessageSetRef.current();
|
|
969
|
-
const restOfMessages = currentMessages.slice(endIndex + 1);
|
|
970
|
-
if (hadCurrentLatestMessages) {
|
|
971
|
-
const latestSet = channel.state.messageSets.find((set) => set.isLatest);
|
|
972
|
-
if (latestSet) {
|
|
973
|
-
latestSet.messages = restOfMessages;
|
|
974
|
-
hasOverlappingRecentMessagesRef.current = true;
|
|
975
|
-
}
|
|
976
|
-
}
|
|
977
|
-
}
|
|
978
|
-
}
|
|
979
|
-
const hasLatestMessages = channel.state.latestMessages.length > 0;
|
|
980
|
-
channel.state.setIsUpToDate(hasLatestMessages);
|
|
981
|
-
setHasNoMoreRecentMessagesToLoad(hasLatestMessages);
|
|
982
|
-
copyChannelState();
|
|
983
|
-
if (scrollToMessageIndex !== -1) {
|
|
984
|
-
// since we need to scroll after immediately do this without throttle
|
|
985
|
-
copyChannelState.flush();
|
|
986
|
-
}
|
|
987
|
-
onAfterQueryCall?.();
|
|
988
|
-
} catch (err) {
|
|
989
|
-
if (err instanceof Error) {
|
|
990
|
-
setError(err);
|
|
991
|
-
} else {
|
|
992
|
-
setError(true);
|
|
993
|
-
}
|
|
994
|
-
setLoading(false);
|
|
995
|
-
setLastRead(new Date());
|
|
996
|
-
}
|
|
997
|
-
},
|
|
998
|
-
);
|
|
999
|
-
|
|
1000
|
-
/**
|
|
1001
|
-
* Loads channel at first unread message.
|
|
1002
|
-
*/
|
|
1003
|
-
const loadChannelAtFirstUnreadMessage = () => {
|
|
1004
|
-
if (!channel) return;
|
|
1005
|
-
let unreadMessageIdToScrollTo: string | undefined;
|
|
1006
|
-
// query for messages around the last read date
|
|
1007
|
-
return channelQueryCallRef.current(
|
|
1008
|
-
async () => {
|
|
1009
|
-
const unreadCount = channel.countUnread();
|
|
1010
|
-
if (unreadCount === 0) return;
|
|
1011
|
-
const isLatestMessageSetShown = !!channel.state.messageSets.find(
|
|
1012
|
-
(set) => set.isCurrent && set.isLatest,
|
|
1013
|
-
);
|
|
1014
|
-
if (isLatestMessageSetShown && unreadCount <= channel.state.messages.length) {
|
|
1015
|
-
unreadMessageIdToScrollTo =
|
|
1016
|
-
channel.state.messages[channel.state.messages.length - unreadCount].id;
|
|
1017
|
-
return;
|
|
1018
|
-
}
|
|
1019
|
-
const lastReadDate = channel.lastRead();
|
|
1020
|
-
|
|
1021
|
-
// if last read date is present we can just fetch messages around that date
|
|
1022
|
-
// last read date not being present is an edge case if somewhere the user of SDK deletes the read state (this will usually never happen)
|
|
1023
|
-
if (lastReadDate) {
|
|
1024
|
-
setLoading(true);
|
|
1025
|
-
// get totally 30 messages... max 15 before last read date and max 15 after last read date
|
|
1026
|
-
// ref: https://github.com/GetStream/chat/pull/2588
|
|
1027
|
-
const res = await channel.query(
|
|
1028
|
-
{
|
|
1029
|
-
messages: {
|
|
1030
|
-
created_at_around: lastReadDate,
|
|
1031
|
-
limit: 30,
|
|
1032
|
-
},
|
|
1033
|
-
watch: true,
|
|
1034
|
-
},
|
|
1035
|
-
'new',
|
|
1036
|
-
);
|
|
1037
|
-
unreadMessageIdToScrollTo = res.messages.find(
|
|
1038
|
-
(m) => lastReadDate < (m.created_at ? new Date(m.created_at) : new Date()),
|
|
1039
|
-
)?.id;
|
|
1040
|
-
if (unreadMessageIdToScrollTo) {
|
|
1041
|
-
channel.state.loadMessageIntoState(unreadMessageIdToScrollTo);
|
|
1042
|
-
}
|
|
1043
|
-
} else {
|
|
1044
|
-
await loadLatestMessagesRef.current();
|
|
1045
|
-
}
|
|
1046
|
-
},
|
|
1047
|
-
() => {
|
|
1048
|
-
if (unreadMessageIdToScrollTo) {
|
|
1049
|
-
restartSetsMergeFuncRef.current();
|
|
1050
|
-
}
|
|
1051
|
-
},
|
|
1052
|
-
() => unreadMessageIdToScrollTo,
|
|
1053
|
-
);
|
|
1054
|
-
};
|
|
1055
|
-
|
|
1056
|
-
/**
|
|
1057
|
-
* Loads channel around a specific message
|
|
1058
|
-
*
|
|
1059
|
-
* @param messageId If undefined, channel will be loaded at most recent message.
|
|
1060
|
-
*/
|
|
1061
|
-
const loadChannelAroundMessage: ChannelContextValue<StreamChatGenerics>['loadChannelAroundMessage'] =
|
|
1062
|
-
async ({ messageId: messageIdToLoadAround }) => {
|
|
1063
|
-
if (thread) {
|
|
1064
|
-
if (messageIdToLoadAround) {
|
|
1065
|
-
setThreadLoadingMore(true);
|
|
1066
|
-
try {
|
|
1067
|
-
await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id);
|
|
1068
|
-
setThreadLoadingMore(false);
|
|
1069
|
-
setThreadMessages(channel.state.threads[thread.id]);
|
|
1070
|
-
setTargetedMessage(messageIdToLoadAround);
|
|
1071
|
-
} catch (err) {
|
|
1072
|
-
if (err instanceof Error) {
|
|
1073
|
-
setError(err);
|
|
1074
|
-
} else {
|
|
1075
|
-
setError(true);
|
|
1076
|
-
}
|
|
1077
|
-
setThreadLoadingMore(false);
|
|
1078
|
-
}
|
|
1079
|
-
}
|
|
1080
|
-
} else {
|
|
1081
|
-
await channelQueryCallRef.current(
|
|
1082
|
-
async () => {
|
|
1083
|
-
setLoading(true);
|
|
1084
|
-
if (messageIdToLoadAround) {
|
|
1085
|
-
setMessages([]);
|
|
1086
|
-
await channel.state.loadMessageIntoState(messageIdToLoadAround);
|
|
1087
|
-
const currentMessageSet = channel.state.messageSets.find((set) => set.isCurrent);
|
|
1088
|
-
if (currentMessageSet && !currentMessageSet?.isLatest) {
|
|
1089
|
-
// if the current message set is not the latest, we will throw away the latest messages
|
|
1090
|
-
// in order to attempt to not throw away, will attempt to merge it by loading 25 more messages
|
|
1091
|
-
const recentCurrentSetMsgId =
|
|
1092
|
-
currentMessageSet.messages[currentMessageSet.messages.length - 1].id;
|
|
1093
|
-
await channel.query(
|
|
1094
|
-
{
|
|
1095
|
-
messages: {
|
|
1096
|
-
id_gte: recentCurrentSetMsgId,
|
|
1097
|
-
limit: 25,
|
|
1098
|
-
},
|
|
1099
|
-
},
|
|
1100
|
-
'current',
|
|
1101
|
-
);
|
|
1102
|
-
// if the gap is more than 25, we will unfortunately have to throw away the latest messages
|
|
1103
|
-
}
|
|
1104
|
-
}
|
|
1105
|
-
},
|
|
1106
|
-
() => {
|
|
1107
|
-
if (messageIdToLoadAround) {
|
|
1108
|
-
clearInterval(mergeSetsIntervalRef.current); // do not merge sets as we will scroll/highlight to the message
|
|
1109
|
-
setTargetedMessage(messageIdToLoadAround);
|
|
1110
|
-
}
|
|
1111
|
-
},
|
|
1112
|
-
messageIdToLoadAround,
|
|
1113
|
-
);
|
|
1114
|
-
}
|
|
1115
|
-
};
|
|
1116
|
-
|
|
1117
|
-
useEffect(() => {
|
|
1118
|
-
if (!targetedMessage && prevTargetedMessage) {
|
|
1119
|
-
// we cleared the merge sets interval to wait for the targeted message to be set
|
|
1120
|
-
// now restart it since its done
|
|
1121
|
-
restartSetsMergeFuncRef.current();
|
|
1122
|
-
}
|
|
1123
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1124
|
-
}, [targetedMessage]);
|
|
1125
|
-
|
|
1126
|
-
/**
|
|
1127
|
-
* Utility method to mark that current set if latest into two.
|
|
1128
|
-
* With an empty latest set
|
|
1129
|
-
* This is useful when we know that we dont know the latest messages anymore
|
|
1130
|
-
* Or if we are loading a channel around a message
|
|
1131
|
-
*/
|
|
1132
|
-
const splitLatestCurrentMessageSetRef = useRef(() => {
|
|
1133
|
-
const currentLatestSet = channel.state.messageSets.find((set) => set.isCurrent && set.isLatest);
|
|
1134
|
-
if (!currentLatestSet) return;
|
|
1135
|
-
// unmark the current latest set
|
|
1136
|
-
currentLatestSet.isLatest = false;
|
|
1137
|
-
// create a new set with empty latest messages
|
|
1138
|
-
channel.state.messageSets.push({
|
|
1139
|
-
isCurrent: false,
|
|
1140
|
-
isLatest: true,
|
|
1141
|
-
messages: [],
|
|
1142
|
-
pagination: {
|
|
1143
|
-
hasNext: true,
|
|
1144
|
-
hasPrev: true,
|
|
1145
|
-
},
|
|
1146
|
-
});
|
|
1147
|
-
});
|
|
1148
|
-
|
|
1149
|
-
/**
|
|
1150
|
-
* Utility method to merge current and latest message set.
|
|
1151
|
-
* Returns true if merge was successful, false otherwise.
|
|
1152
|
-
*/
|
|
1153
|
-
const mergeOverlappingMessageSetsRef = useRef((limitToMaxRenderPerBatch = false) => {
|
|
1154
|
-
if (hasOverlappingRecentMessagesRef.current) {
|
|
1155
|
-
const limit = 5; // 5 is the load to recent limit, a larger value seems to cause jumpiness in some devices..
|
|
1156
|
-
// merge current and latest sets
|
|
1157
|
-
const latestMessageSet = channel.state.messageSets.find((set) => set.isLatest);
|
|
1158
|
-
const currentMessageSet = channel.state.messageSets.find((set) => set.isCurrent);
|
|
1159
|
-
if (latestMessageSet && currentMessageSet && latestMessageSet !== currentMessageSet) {
|
|
1160
|
-
if (limitToMaxRenderPerBatch && latestMessageSet.messages.length > limit) {
|
|
1161
|
-
currentMessageSet.messages = currentMessageSet.messages.concat(
|
|
1162
|
-
latestMessageSet.messages.slice(0, limit),
|
|
1163
|
-
);
|
|
1164
|
-
latestMessageSet.messages = latestMessageSet.messages.slice(limit);
|
|
1165
|
-
} else {
|
|
1166
|
-
channel.state.messageSets = channel.state.messageSets.filter((set) => !set.isLatest);
|
|
1167
|
-
currentMessageSet.messages = currentMessageSet.messages.concat(latestMessageSet.messages);
|
|
1168
|
-
currentMessageSet.isLatest = true;
|
|
1169
|
-
hasOverlappingRecentMessagesRef.current = false;
|
|
1170
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
1171
|
-
}
|
|
1172
|
-
return true;
|
|
1173
|
-
}
|
|
1174
|
-
}
|
|
1175
|
-
return false;
|
|
1176
|
-
});
|
|
1177
|
-
|
|
1178
|
-
const mergeSetsIntervalRef = useRef<NodeJS.Timeout>();
|
|
1179
|
-
|
|
1180
|
-
// clear the interval on unmount
|
|
1181
|
-
useEffect(
|
|
1182
|
-
() => () => {
|
|
1183
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
1184
|
-
},
|
|
1185
|
-
[],
|
|
1186
|
-
);
|
|
1187
|
-
|
|
1188
|
-
// if we had split the latest and current message set, we try to merge them back
|
|
1189
|
-
// temporarily commented out the interval as it was causing issues with jankiness during scrolling
|
|
1190
|
-
const restartSetsMergeFuncRef = useRef(() => {
|
|
1191
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
1192
|
-
if (!hasOverlappingRecentMessagesRef.current) return;
|
|
1193
|
-
// mergeSetsIntervalRef.current = setInterval(() => {
|
|
1194
|
-
// const currentLength = channel.state.messages.length || 0;
|
|
1195
|
-
// const didMerge = mergeOverlappingMessageSetsRef.current(true);
|
|
1196
|
-
// if (didMerge && channel.state.messages.length !== currentLength) {
|
|
1197
|
-
// setMessages(channel.state.messages);
|
|
1198
|
-
// }
|
|
1199
|
-
// }, 1000);
|
|
1200
|
-
});
|
|
1201
|
-
|
|
1202
|
-
/**
|
|
1203
|
-
* Shows the latest messages from the channel state
|
|
1204
|
-
* If recent messages are empty, fetches new
|
|
1205
|
-
* @param clearLatest If true, clears the latest messages before loading (useful for complete refresh)
|
|
1206
|
-
*/
|
|
1207
|
-
const loadLatestMessagesRef = useRef(async (clearLatest = false) => {
|
|
1208
|
-
mergeOverlappingMessageSetsRef.current();
|
|
1209
|
-
if (clearLatest) {
|
|
1210
|
-
const latestSet = channel.state.messageSets.find((set) => set.isLatest);
|
|
1211
|
-
if (latestSet) latestSet.messages = [];
|
|
1212
|
-
}
|
|
1213
|
-
if (channel.state.latestMessages.length === 0) {
|
|
1214
|
-
await channel.query({}, 'latest');
|
|
1215
|
-
}
|
|
1216
|
-
await channel.state.loadMessageIntoState('latest');
|
|
1217
|
-
});
|
|
1218
|
-
|
|
1219
|
-
const loadChannel = () =>
|
|
1220
|
-
channelQueryCallRef.current(
|
|
1221
|
-
async () => {
|
|
1222
|
-
if (!channel?.initialized || !channel.state.isUpToDate) {
|
|
1223
|
-
await channel?.watch();
|
|
1224
|
-
} else {
|
|
1225
|
-
await channel.state.loadMessageIntoState('latest');
|
|
1226
|
-
}
|
|
1227
|
-
},
|
|
1228
|
-
() => {
|
|
1229
|
-
channel?.state.setIsUpToDate(true);
|
|
1230
|
-
setHasNoMoreRecentMessagesToLoad(true);
|
|
1231
|
-
},
|
|
1232
|
-
);
|
|
1233
|
-
|
|
1234
879
|
const reloadThread = async () => {
|
|
1235
880
|
if (!channel || !thread?.id) return;
|
|
1236
881
|
setThreadLoadingMore(true);
|
|
@@ -1266,105 +911,39 @@ const ChannelWithContext = <
|
|
|
1266
911
|
|
|
1267
912
|
const resyncChannel = async () => {
|
|
1268
913
|
if (!channel || syncingChannelRef.current) return;
|
|
1269
|
-
hasOverlappingRecentMessagesRef.current = false;
|
|
1270
|
-
clearInterval(mergeSetsIntervalRef.current);
|
|
1271
914
|
syncingChannelRef.current = true;
|
|
1272
|
-
|
|
1273
915
|
setError(false);
|
|
1274
|
-
try {
|
|
1275
|
-
/**
|
|
1276
|
-
* Allow a buffer of 30 new messages, so that MessageList won't move its scroll position,
|
|
1277
|
-
* giving smooth user experience.
|
|
1278
|
-
*/
|
|
1279
|
-
const state = await channel.watch({
|
|
1280
|
-
messages: {
|
|
1281
|
-
limit: messages.length + 30,
|
|
1282
|
-
},
|
|
1283
|
-
});
|
|
1284
|
-
|
|
1285
|
-
const oldListTopMessage = messages[0];
|
|
1286
|
-
const oldListTopMessageId = messages[0]?.id;
|
|
1287
|
-
const oldListBottomMessage = messages[messages.length - 1];
|
|
1288
|
-
|
|
1289
|
-
const newListTopMessage = state.messages[0];
|
|
1290
|
-
const newListBottomMessage = state.messages[state.messages.length - 1];
|
|
1291
916
|
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
channel.state.clearMessages();
|
|
1300
|
-
channel.state.setIsUpToDate(true);
|
|
1301
|
-
channel.state.addMessagesSorted(state.messages);
|
|
1302
|
-
channel.state.addPinnedMessages(state.pinned_messages);
|
|
917
|
+
const parseMessage = (message: FormatMessageResponse<StreamChatGenerics>) =>
|
|
918
|
+
({
|
|
919
|
+
...message,
|
|
920
|
+
created_at: message.created_at.toString(),
|
|
921
|
+
pinned_at: message.pinned_at?.toString(),
|
|
922
|
+
updated_at: message.updated_at?.toString(),
|
|
923
|
+
} as unknown as MessageResponse<StreamChatGenerics>);
|
|
1303
924
|
|
|
925
|
+
try {
|
|
926
|
+
if (!thread) {
|
|
1304
927
|
copyChannelState();
|
|
1305
|
-
return;
|
|
1306
|
-
}
|
|
1307
928
|
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
} as unknown as MessageResponse<StreamChatGenerics>);
|
|
1315
|
-
|
|
1316
|
-
const failedMessages = messages
|
|
1317
|
-
.filter((message) => message.status === MessageStatusTypes.FAILED)
|
|
1318
|
-
.map(parseMessage);
|
|
1319
|
-
|
|
1320
|
-
const failedThreadMessages = thread
|
|
1321
|
-
? threadMessages
|
|
1322
|
-
.filter((message) => message.status === MessageStatusTypes.FAILED)
|
|
1323
|
-
.map(parseMessage)
|
|
1324
|
-
: [];
|
|
1325
|
-
|
|
1326
|
-
const oldListTopMessageCreatedAt = oldListTopMessage.created_at;
|
|
1327
|
-
const oldListBottomMessageCreatedAt = oldListBottomMessage.created_at;
|
|
1328
|
-
const newListTopMessageCreatedAt = newListTopMessage.created_at
|
|
1329
|
-
? new Date(newListTopMessage.created_at)
|
|
1330
|
-
: new Date();
|
|
1331
|
-
const newListBottomMessageCreatedAt = newListBottomMessage?.created_at
|
|
1332
|
-
? new Date(newListBottomMessage.created_at)
|
|
1333
|
-
: new Date();
|
|
1334
|
-
|
|
1335
|
-
let finalMessages = [];
|
|
1336
|
-
|
|
1337
|
-
if (
|
|
1338
|
-
oldListTopMessage &&
|
|
1339
|
-
oldListTopMessageCreatedAt &&
|
|
1340
|
-
oldListBottomMessageCreatedAt &&
|
|
1341
|
-
newListTopMessageCreatedAt < oldListTopMessageCreatedAt &&
|
|
1342
|
-
newListBottomMessageCreatedAt >= oldListBottomMessageCreatedAt
|
|
1343
|
-
) {
|
|
1344
|
-
const index = state.messages.findIndex((message) => message.id === oldListTopMessageId);
|
|
1345
|
-
finalMessages = state.messages.slice(index);
|
|
929
|
+
const failedMessages = channelMessagesState.messages
|
|
930
|
+
?.filter((message) => message.status === MessageStatusTypes.FAILED)
|
|
931
|
+
.map(parseMessage);
|
|
932
|
+
if (failedMessages?.length) {
|
|
933
|
+
channel.state.addMessagesSorted(failedMessages);
|
|
934
|
+
}
|
|
1346
935
|
} else {
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
if (failedMessages.length) {
|
|
1359
|
-
channel.state.addMessagesSorted(failedMessages);
|
|
1360
|
-
copyChannelState();
|
|
1361
|
-
}
|
|
1362
|
-
|
|
1363
|
-
await reloadThread();
|
|
1364
|
-
|
|
1365
|
-
if (thread && failedThreadMessages.length) {
|
|
1366
|
-
channel.state.addMessagesSorted(failedThreadMessages);
|
|
1367
|
-
setThreadMessages([...channel.state.threads[thread.id]]);
|
|
936
|
+
await reloadThread();
|
|
937
|
+
|
|
938
|
+
const failedThreadMessages = thread
|
|
939
|
+
? threadMessages
|
|
940
|
+
.filter((message) => message.status === MessageStatusTypes.FAILED)
|
|
941
|
+
.map(parseMessage)
|
|
942
|
+
: [];
|
|
943
|
+
if (failedThreadMessages.length) {
|
|
944
|
+
channel.state.addMessagesSorted(failedThreadMessages);
|
|
945
|
+
setThreadMessages([...channel.state.threads[thread.id]]);
|
|
946
|
+
}
|
|
1368
947
|
}
|
|
1369
948
|
} catch (err) {
|
|
1370
949
|
if (err instanceof Error) {
|
|
@@ -1372,7 +951,6 @@ const ChannelWithContext = <
|
|
|
1372
951
|
} else {
|
|
1373
952
|
setError(true);
|
|
1374
953
|
}
|
|
1375
|
-
setLoading(false);
|
|
1376
954
|
}
|
|
1377
955
|
|
|
1378
956
|
syncingChannelRef.current = false;
|
|
@@ -1393,7 +971,7 @@ const ChannelWithContext = <
|
|
|
1393
971
|
if (enableOfflineSupport) {
|
|
1394
972
|
connectionChangedSubscription = DBSyncManager.onSyncStatusChange((statusChanged) => {
|
|
1395
973
|
if (statusChanged) {
|
|
1396
|
-
|
|
974
|
+
copyChannelState();
|
|
1397
975
|
}
|
|
1398
976
|
});
|
|
1399
977
|
} else {
|
|
@@ -1409,15 +987,6 @@ const ChannelWithContext = <
|
|
|
1409
987
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1410
988
|
}, [enableOfflineSupport, shouldSyncChannel]);
|
|
1411
989
|
|
|
1412
|
-
const reloadChannel = () =>
|
|
1413
|
-
channelQueryCallRef.current(async () => {
|
|
1414
|
-
setLoading(true);
|
|
1415
|
-
await loadLatestMessagesRef.current(true);
|
|
1416
|
-
setLoading(false);
|
|
1417
|
-
channel?.state.setIsUpToDate(true);
|
|
1418
|
-
setHasNoMoreRecentMessagesToLoad(true);
|
|
1419
|
-
});
|
|
1420
|
-
|
|
1421
990
|
// In case the channel is disconnected which may happen when channel is deleted,
|
|
1422
991
|
// underlying js client throws an error. Following function ensures that Channel component
|
|
1423
992
|
// won't result in error in such a case.
|
|
@@ -1436,22 +1005,61 @@ const ChannelWithContext = <
|
|
|
1436
1005
|
*/
|
|
1437
1006
|
const clientChannelConfig = getChannelConfigSafely();
|
|
1438
1007
|
|
|
1008
|
+
const reloadChannel = async () => {
|
|
1009
|
+
try {
|
|
1010
|
+
await loadLatestMessages();
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
console.warn('Reloading channel failed with error:', err);
|
|
1013
|
+
}
|
|
1014
|
+
};
|
|
1015
|
+
|
|
1016
|
+
const loadChannelAroundMessage: ChannelContextValue<StreamChatGenerics>['loadChannelAroundMessage'] =
|
|
1017
|
+
async ({ messageId: messageIdToLoadAround }): Promise<void> => {
|
|
1018
|
+
if (!messageIdToLoadAround) return;
|
|
1019
|
+
try {
|
|
1020
|
+
if (thread) {
|
|
1021
|
+
setThreadLoadingMore(true);
|
|
1022
|
+
try {
|
|
1023
|
+
await channel.state.loadMessageIntoState(messageIdToLoadAround, thread.id);
|
|
1024
|
+
setThreadLoadingMore(false);
|
|
1025
|
+
setThreadMessages(channel.state.threads[thread.id]);
|
|
1026
|
+
if (setTargetedMessage) {
|
|
1027
|
+
setTargetedMessage(messageIdToLoadAround);
|
|
1028
|
+
}
|
|
1029
|
+
} catch (err) {
|
|
1030
|
+
if (err instanceof Error) {
|
|
1031
|
+
setError(err);
|
|
1032
|
+
} else {
|
|
1033
|
+
setError(true);
|
|
1034
|
+
}
|
|
1035
|
+
setThreadLoadingMore(false);
|
|
1036
|
+
}
|
|
1037
|
+
} else {
|
|
1038
|
+
await loadChannelAroundMessageFn({
|
|
1039
|
+
messageId: messageIdToLoadAround,
|
|
1040
|
+
setTargetedMessage,
|
|
1041
|
+
});
|
|
1042
|
+
}
|
|
1043
|
+
} catch (err) {
|
|
1044
|
+
console.warn('Loading channel around message failed with error:', err);
|
|
1045
|
+
}
|
|
1046
|
+
};
|
|
1047
|
+
|
|
1439
1048
|
/**
|
|
1440
1049
|
* MESSAGE METHODS
|
|
1441
1050
|
*/
|
|
1442
|
-
|
|
1443
1051
|
const updateMessage: MessagesContextValue<StreamChatGenerics>['updateMessage'] = (
|
|
1444
1052
|
updatedMessage,
|
|
1445
1053
|
extraState = {},
|
|
1446
1054
|
) => {
|
|
1447
|
-
if (channel)
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
setThreadMessages(extraState.threadMessages);
|
|
1452
|
-
}
|
|
1055
|
+
if (!channel) return;
|
|
1056
|
+
|
|
1057
|
+
channel.state.addMessageSorted(updatedMessage, true);
|
|
1058
|
+
copyMessagesStateFromChannel(channel);
|
|
1453
1059
|
|
|
1454
|
-
|
|
1060
|
+
if (thread && updatedMessage.parent_id) {
|
|
1061
|
+
extraState.threadMessages = channel.state.threads[updatedMessage.parent_id] || [];
|
|
1062
|
+
setThreadMessages(extraState.threadMessages);
|
|
1455
1063
|
}
|
|
1456
1064
|
};
|
|
1457
1065
|
|
|
@@ -1462,11 +1070,12 @@ const ChannelWithContext = <
|
|
|
1462
1070
|
if (channel) {
|
|
1463
1071
|
channel.state.removeMessage(oldMessage);
|
|
1464
1072
|
channel.state.addMessageSorted(newMessage, true);
|
|
1073
|
+
copyMessagesStateFromChannel(channel);
|
|
1074
|
+
|
|
1465
1075
|
if (thread && newMessage.parent_id) {
|
|
1466
1076
|
const threadMessages = channel.state.threads[newMessage.parent_id] || [];
|
|
1467
1077
|
setThreadMessages(threadMessages);
|
|
1468
1078
|
}
|
|
1469
|
-
setMessages(channel.state.messages);
|
|
1470
1079
|
}
|
|
1471
1080
|
};
|
|
1472
1081
|
|
|
@@ -1516,7 +1125,9 @@ const ChannelWithContext = <
|
|
|
1516
1125
|
* as quoted_message is a reserved field.
|
|
1517
1126
|
*/
|
|
1518
1127
|
if (preview.quoted_message_id) {
|
|
1519
|
-
const quotedMessage = messages
|
|
1128
|
+
const quotedMessage = channelMessagesState.messages?.find(
|
|
1129
|
+
(message) => message.id === preview.quoted_message_id,
|
|
1130
|
+
);
|
|
1520
1131
|
|
|
1521
1132
|
preview.quoted_message =
|
|
1522
1133
|
quotedMessage as MessageResponse<StreamChatGenerics>['quoted_message'];
|
|
@@ -1685,8 +1296,6 @@ const ChannelWithContext = <
|
|
|
1685
1296
|
attachments: message.attachments || [],
|
|
1686
1297
|
});
|
|
1687
1298
|
|
|
1688
|
-
mergeOverlappingMessageSetsRef.current();
|
|
1689
|
-
|
|
1690
1299
|
updateMessage(messagePreview, {
|
|
1691
1300
|
commands: [],
|
|
1692
1301
|
messageInput: '',
|
|
@@ -1727,159 +1336,6 @@ const ChannelWithContext = <
|
|
|
1727
1336
|
);
|
|
1728
1337
|
};
|
|
1729
1338
|
|
|
1730
|
-
// hard limit to prevent you from scrolling faster than 1 page per 2 seconds
|
|
1731
|
-
const loadMoreFinished = useRef(
|
|
1732
|
-
debounce(
|
|
1733
|
-
(updatedHasMore: boolean, newMessages: ChannelState<StreamChatGenerics>['messages']) => {
|
|
1734
|
-
setLoading(false);
|
|
1735
|
-
setLoadingMore(false);
|
|
1736
|
-
setError(false);
|
|
1737
|
-
setHasMore(updatedHasMore);
|
|
1738
|
-
setMessages(newMessages);
|
|
1739
|
-
},
|
|
1740
|
-
defaultDebounceInterval,
|
|
1741
|
-
debounceOptions,
|
|
1742
|
-
),
|
|
1743
|
-
).current;
|
|
1744
|
-
|
|
1745
|
-
/**
|
|
1746
|
-
* This function loads more messages before the first message in current channel state.
|
|
1747
|
-
*/
|
|
1748
|
-
const loadMore = useCallback<PaginatedMessageListContextValue<StreamChatGenerics>['loadMore']>(
|
|
1749
|
-
async (limit = 20) => {
|
|
1750
|
-
if (loadingMore || hasMore === false) {
|
|
1751
|
-
return;
|
|
1752
|
-
}
|
|
1753
|
-
|
|
1754
|
-
const currentMessages = channel.state.messages;
|
|
1755
|
-
|
|
1756
|
-
if (!currentMessages.length) {
|
|
1757
|
-
return setLoadingMore(false);
|
|
1758
|
-
}
|
|
1759
|
-
|
|
1760
|
-
const oldestMessage = currentMessages && currentMessages[0];
|
|
1761
|
-
|
|
1762
|
-
if (oldestMessage && oldestMessage.status !== MessageStatusTypes.RECEIVED) {
|
|
1763
|
-
return setLoadingMore(false);
|
|
1764
|
-
}
|
|
1765
|
-
|
|
1766
|
-
setLoadingMore(true);
|
|
1767
|
-
|
|
1768
|
-
const oldestID = oldestMessage && oldestMessage.id;
|
|
1769
|
-
|
|
1770
|
-
try {
|
|
1771
|
-
if (channel) {
|
|
1772
|
-
const queryResponse = await channel.query({
|
|
1773
|
-
messages: { id_lt: oldestID, limit },
|
|
1774
|
-
});
|
|
1775
|
-
|
|
1776
|
-
const updatedHasMore = queryResponse.messages.length === limit;
|
|
1777
|
-
loadMoreFinished(updatedHasMore, channel.state.messages);
|
|
1778
|
-
}
|
|
1779
|
-
} catch (err) {
|
|
1780
|
-
if (err instanceof Error) {
|
|
1781
|
-
setError(err);
|
|
1782
|
-
} else {
|
|
1783
|
-
setError(true);
|
|
1784
|
-
}
|
|
1785
|
-
setLoadingMore(false);
|
|
1786
|
-
throw err;
|
|
1787
|
-
}
|
|
1788
|
-
},
|
|
1789
|
-
/*
|
|
1790
|
-
* This function is passed to useCreatePaginatedMessageListContext
|
|
1791
|
-
* Where the deps are [channelId, hasMore, loadingMoreRecent, loadingMore]
|
|
1792
|
-
* and only those deps should be used here because of that
|
|
1793
|
-
*/
|
|
1794
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1795
|
-
[channelId, hasMore, loadingMore],
|
|
1796
|
-
);
|
|
1797
|
-
|
|
1798
|
-
/**
|
|
1799
|
-
* This function loads more messages after the most recent message in current channel state.
|
|
1800
|
-
*/
|
|
1801
|
-
const loadMoreRecent = useCallback<
|
|
1802
|
-
PaginatedMessageListContextValue<StreamChatGenerics>['loadMoreRecent']
|
|
1803
|
-
>(
|
|
1804
|
-
async (limit = 5) => {
|
|
1805
|
-
const latestMessageSet = channel.state.messageSets.find((set) => set.isLatest);
|
|
1806
|
-
const latestLengthBeforeMerge = latestMessageSet?.messages.length || 0;
|
|
1807
|
-
const didMerge = mergeOverlappingMessageSetsRef.current(true);
|
|
1808
|
-
if (didMerge) {
|
|
1809
|
-
if (latestMessageSet && latestLengthBeforeMerge >= limit) {
|
|
1810
|
-
setLoadingMoreRecent(true);
|
|
1811
|
-
channel.state.setIsUpToDate(true);
|
|
1812
|
-
setHasNoMoreRecentMessagesToLoad(true);
|
|
1813
|
-
loadMoreRecentFinished(channel.state.messages);
|
|
1814
|
-
restartSetsMergeFuncRef.current();
|
|
1815
|
-
return;
|
|
1816
|
-
}
|
|
1817
|
-
}
|
|
1818
|
-
if (channel.state.isUpToDate) {
|
|
1819
|
-
setLoadingMoreRecent(false);
|
|
1820
|
-
return;
|
|
1821
|
-
}
|
|
1822
|
-
const currentMessages = channel.state.messages;
|
|
1823
|
-
const recentMessage = currentMessages[currentMessages.length - 1];
|
|
1824
|
-
|
|
1825
|
-
if (recentMessage?.status !== MessageStatusTypes.RECEIVED) {
|
|
1826
|
-
setLoadingMoreRecent(false);
|
|
1827
|
-
return;
|
|
1828
|
-
}
|
|
1829
|
-
setLoadingMoreRecent(true);
|
|
1830
|
-
try {
|
|
1831
|
-
if (channel) {
|
|
1832
|
-
const queryResponse = await channel.query({
|
|
1833
|
-
messages: {
|
|
1834
|
-
id_gte: recentMessage.id,
|
|
1835
|
-
limit,
|
|
1836
|
-
},
|
|
1837
|
-
watch: true,
|
|
1838
|
-
});
|
|
1839
|
-
const gotAllRecentMessages = queryResponse.messages.length < limit;
|
|
1840
|
-
const currentSet = channel.state.messageSets.find((set) => set.isCurrent);
|
|
1841
|
-
if (gotAllRecentMessages && currentSet && !currentSet.isLatest) {
|
|
1842
|
-
channel.state.messageSets = channel.state.messageSets.filter((set) => !set.isLatest);
|
|
1843
|
-
// make current set as the latest
|
|
1844
|
-
currentSet.isLatest = true;
|
|
1845
|
-
}
|
|
1846
|
-
channel.state.setIsUpToDate(gotAllRecentMessages);
|
|
1847
|
-
setHasNoMoreRecentMessagesToLoad(gotAllRecentMessages);
|
|
1848
|
-
loadMoreRecentFinished(channel.state.messages);
|
|
1849
|
-
}
|
|
1850
|
-
} catch (err) {
|
|
1851
|
-
console.warn('Message pagination request failed with error', err);
|
|
1852
|
-
if (err instanceof Error) {
|
|
1853
|
-
setError(err);
|
|
1854
|
-
} else {
|
|
1855
|
-
setError(true);
|
|
1856
|
-
}
|
|
1857
|
-
setLoadingMoreRecent(false);
|
|
1858
|
-
throw err;
|
|
1859
|
-
}
|
|
1860
|
-
},
|
|
1861
|
-
/*
|
|
1862
|
-
* This function is passed to useCreatePaginatedMessageListContext
|
|
1863
|
-
* Where the deps are [channelId, hasMore, loadingMoreRecent, loadingMore, hasNoMoreRecentMessagesToLoad]
|
|
1864
|
-
* and and only those deps should be used here because of that
|
|
1865
|
-
*/
|
|
1866
|
-
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
1867
|
-
[channelId, hasNoMoreRecentMessagesToLoad],
|
|
1868
|
-
);
|
|
1869
|
-
|
|
1870
|
-
// hard limit to prevent you from scrolling faster than 1 page per 2 seconds
|
|
1871
|
-
const loadMoreRecentFinished = useRef(
|
|
1872
|
-
debounce(
|
|
1873
|
-
(newMessages: ChannelState<StreamChatGenerics>['messages']) => {
|
|
1874
|
-
setLoadingMoreRecent(false);
|
|
1875
|
-
setMessages(newMessages);
|
|
1876
|
-
setError(false);
|
|
1877
|
-
},
|
|
1878
|
-
defaultDebounceInterval,
|
|
1879
|
-
debounceOptions,
|
|
1880
|
-
),
|
|
1881
|
-
).current;
|
|
1882
|
-
|
|
1883
1339
|
const editMessage: InputMessageInputContextValue<StreamChatGenerics>['editMessage'] = (
|
|
1884
1340
|
updatedMessage,
|
|
1885
1341
|
) =>
|
|
@@ -1914,7 +1370,8 @@ const ChannelWithContext = <
|
|
|
1914
1370
|
) => {
|
|
1915
1371
|
if (channel) {
|
|
1916
1372
|
channel.state.removeMessage(message);
|
|
1917
|
-
|
|
1373
|
+
copyMessagesStateFromChannel(channel);
|
|
1374
|
+
|
|
1918
1375
|
if (thread) {
|
|
1919
1376
|
setThreadMessages(channel.state.threads[thread.id] || []);
|
|
1920
1377
|
}
|
|
@@ -1953,7 +1410,7 @@ const ChannelWithContext = <
|
|
|
1953
1410
|
user: client.user,
|
|
1954
1411
|
});
|
|
1955
1412
|
|
|
1956
|
-
|
|
1413
|
+
copyMessagesStateFromChannel(channel);
|
|
1957
1414
|
|
|
1958
1415
|
const sendReactionResponse = await DBSyncManager.queueTask<StreamChatGenerics>({
|
|
1959
1416
|
client,
|
|
@@ -2039,7 +1496,7 @@ const ChannelWithContext = <
|
|
|
2039
1496
|
user: client.user,
|
|
2040
1497
|
});
|
|
2041
1498
|
|
|
2042
|
-
|
|
1499
|
+
copyMessagesStateFromChannel(channel);
|
|
2043
1500
|
|
|
2044
1501
|
await DBSyncManager.queueTask<StreamChatGenerics>({
|
|
2045
1502
|
client,
|
|
@@ -2134,11 +1591,6 @@ const ChannelWithContext = <
|
|
|
2134
1591
|
}
|
|
2135
1592
|
};
|
|
2136
1593
|
|
|
2137
|
-
const disabledValue = useMemo(
|
|
2138
|
-
() => !!channel?.data?.frozen && disableIfFrozenChannel,
|
|
2139
|
-
[channel.data?.frozen, disableIfFrozenChannel],
|
|
2140
|
-
);
|
|
2141
|
-
|
|
2142
1594
|
const ownCapabilitiesContext = useCreateOwnCapabilitiesContext({
|
|
2143
1595
|
channel,
|
|
2144
1596
|
overrideCapabilities: overrideOwnCapabilities,
|
|
@@ -2146,7 +1598,7 @@ const ChannelWithContext = <
|
|
|
2146
1598
|
|
|
2147
1599
|
const channelContext = useCreateChannelContext({
|
|
2148
1600
|
channel,
|
|
2149
|
-
disabled:
|
|
1601
|
+
disabled: !!channel?.data?.frozen,
|
|
2150
1602
|
EmptyStateIndicator,
|
|
2151
1603
|
enableMessageGroupingByUser,
|
|
2152
1604
|
enforceUniqueReaction,
|
|
@@ -2156,19 +1608,16 @@ const ChannelWithContext = <
|
|
|
2156
1608
|
!!(clientChannelConfig?.commands || [])?.some((command) => command.name === 'giphy'),
|
|
2157
1609
|
hideDateSeparators,
|
|
2158
1610
|
hideStickyDateHeader,
|
|
2159
|
-
isAdmin,
|
|
2160
1611
|
isChannelActive: shouldSyncChannel,
|
|
2161
|
-
isModerator,
|
|
2162
|
-
isOwner,
|
|
2163
1612
|
lastRead,
|
|
2164
1613
|
loadChannelAroundMessage,
|
|
2165
|
-
loading,
|
|
1614
|
+
loading: channelMessagesState.loading,
|
|
2166
1615
|
LoadingIndicator,
|
|
2167
1616
|
markRead,
|
|
2168
1617
|
maxTimeBetweenGroupedMessages,
|
|
2169
|
-
members,
|
|
1618
|
+
members: channelState.members ?? {},
|
|
2170
1619
|
NetworkDownIndicator,
|
|
2171
|
-
read,
|
|
1620
|
+
read: channelState.read ?? {},
|
|
2172
1621
|
reloadChannel,
|
|
2173
1622
|
scrollToFirstUnreadThreshold,
|
|
2174
1623
|
setLastRead,
|
|
@@ -2177,8 +1626,8 @@ const ChannelWithContext = <
|
|
|
2177
1626
|
targetedMessage,
|
|
2178
1627
|
threadList,
|
|
2179
1628
|
uploadAbortControllerRef,
|
|
2180
|
-
watcherCount,
|
|
2181
|
-
watchers,
|
|
1629
|
+
watcherCount: channelState.watcherCount,
|
|
1630
|
+
watchers: channelState.watchers,
|
|
2182
1631
|
});
|
|
2183
1632
|
|
|
2184
1633
|
// This is mainly a hack to get around an issue with sendMessage not being passed correctly as a
|
|
@@ -2250,21 +1699,22 @@ const ChannelWithContext = <
|
|
|
2250
1699
|
setQuotedMessageState,
|
|
2251
1700
|
ShowThreadMessageInChannelButton,
|
|
2252
1701
|
StartAudioRecordingButton,
|
|
1702
|
+
StopMessageStreamingButton,
|
|
2253
1703
|
UploadProgressIndicator,
|
|
2254
1704
|
});
|
|
2255
1705
|
|
|
2256
1706
|
const messageListContext = useCreatePaginatedMessageListContext({
|
|
2257
1707
|
channelId,
|
|
2258
|
-
hasMore,
|
|
2259
|
-
|
|
2260
|
-
loadingMore: loadingMoreProp !== undefined ? loadingMoreProp : loadingMore,
|
|
1708
|
+
hasMore: channelMessagesState.hasMore,
|
|
1709
|
+
loadingMore: loadingMoreProp !== undefined ? loadingMoreProp : channelMessagesState.loadingMore,
|
|
2261
1710
|
loadingMoreRecent:
|
|
2262
|
-
loadingMoreRecentProp !== undefined
|
|
1711
|
+
loadingMoreRecentProp !== undefined
|
|
1712
|
+
? loadingMoreRecentProp
|
|
1713
|
+
: channelMessagesState.loadingMoreRecent,
|
|
1714
|
+
loadLatestMessages,
|
|
2263
1715
|
loadMore,
|
|
2264
1716
|
loadMoreRecent,
|
|
2265
|
-
messages,
|
|
2266
|
-
setLoadingMore,
|
|
2267
|
-
setLoadingMoreRecent,
|
|
1717
|
+
messages: channelMessagesState.messages ?? [],
|
|
2268
1718
|
});
|
|
2269
1719
|
|
|
2270
1720
|
const messagesContext = useCreateMessagesContext({
|
|
@@ -2312,6 +1762,7 @@ const ChannelWithContext = <
|
|
|
2312
1762
|
InlineDateSeparator,
|
|
2313
1763
|
InlineUnreadIndicator,
|
|
2314
1764
|
isAttachmentEqual,
|
|
1765
|
+
isMessageAIGenerated,
|
|
2315
1766
|
legacyImageViewerSwipeBehaviour,
|
|
2316
1767
|
markdownRules,
|
|
2317
1768
|
Message,
|
|
@@ -2359,6 +1810,7 @@ const ChannelWithContext = <
|
|
|
2359
1810
|
setEditingState,
|
|
2360
1811
|
setQuotedMessageState,
|
|
2361
1812
|
shouldShowUnreadUnderlay,
|
|
1813
|
+
StreamingMessageView,
|
|
2362
1814
|
supportedReactions,
|
|
2363
1815
|
targetedMessage,
|
|
2364
1816
|
TypingIndicator,
|
|
@@ -2389,13 +1841,13 @@ const ChannelWithContext = <
|
|
|
2389
1841
|
});
|
|
2390
1842
|
|
|
2391
1843
|
const typingContext = useCreateTypingContext({
|
|
2392
|
-
typing,
|
|
1844
|
+
typing: channelState.typing ?? {},
|
|
2393
1845
|
});
|
|
2394
1846
|
|
|
2395
1847
|
// TODO: replace the null view with appropriate message. Currently this is waiting a design decision.
|
|
2396
1848
|
if (deleted) return null;
|
|
2397
1849
|
|
|
2398
|
-
if (!channel || (error && messages
|
|
1850
|
+
if (!channel || (error && channelMessagesState.messages?.length === 0)) {
|
|
2399
1851
|
return <LoadingErrorIndicator error={error} listType='message' retry={reloadChannel} />;
|
|
2400
1852
|
}
|
|
2401
1853
|
|
|
@@ -2455,7 +1907,8 @@ export const Channel = <
|
|
|
2455
1907
|
>(
|
|
2456
1908
|
props: PropsWithChildren<ChannelProps<StreamChatGenerics>>,
|
|
2457
1909
|
) => {
|
|
2458
|
-
const { client, enableOfflineSupport } =
|
|
1910
|
+
const { client, enableOfflineSupport, isMessageAIGenerated } =
|
|
1911
|
+
useChatContext<StreamChatGenerics>();
|
|
2459
1912
|
const { t } = useTranslationContext();
|
|
2460
1913
|
|
|
2461
1914
|
const threadFromProps = props?.thread;
|
|
@@ -2471,22 +1924,7 @@ export const Channel = <
|
|
|
2471
1924
|
|
|
2472
1925
|
const shouldSyncChannel = threadMessage?.id ? !!props.threadList : true;
|
|
2473
1926
|
|
|
2474
|
-
const {
|
|
2475
|
-
members,
|
|
2476
|
-
messages,
|
|
2477
|
-
read,
|
|
2478
|
-
setMembers,
|
|
2479
|
-
setMessages,
|
|
2480
|
-
setRead,
|
|
2481
|
-
setThreadMessages,
|
|
2482
|
-
setTyping,
|
|
2483
|
-
setWatcherCount,
|
|
2484
|
-
setWatchers,
|
|
2485
|
-
threadMessages,
|
|
2486
|
-
typing,
|
|
2487
|
-
watcherCount,
|
|
2488
|
-
watchers,
|
|
2489
|
-
} = useChannelState<StreamChatGenerics>(
|
|
1927
|
+
const { setThreadMessages, threadMessages } = useChannelState<StreamChatGenerics>(
|
|
2490
1928
|
props.channel,
|
|
2491
1929
|
props.threadList ? threadMessage?.id : undefined,
|
|
2492
1930
|
);
|
|
@@ -2501,21 +1939,10 @@ export const Channel = <
|
|
|
2501
1939
|
{...props}
|
|
2502
1940
|
shouldSyncChannel={shouldSyncChannel}
|
|
2503
1941
|
{...{
|
|
2504
|
-
|
|
2505
|
-
messages: props.messages || messages,
|
|
2506
|
-
read,
|
|
2507
|
-
setMembers,
|
|
2508
|
-
setMessages,
|
|
2509
|
-
setRead,
|
|
1942
|
+
isMessageAIGenerated,
|
|
2510
1943
|
setThreadMessages,
|
|
2511
|
-
setTyping,
|
|
2512
|
-
setWatcherCount,
|
|
2513
|
-
setWatchers,
|
|
2514
1944
|
thread,
|
|
2515
1945
|
threadMessages,
|
|
2516
|
-
typing,
|
|
2517
|
-
watcherCount,
|
|
2518
|
-
watchers,
|
|
2519
1946
|
}}
|
|
2520
1947
|
/>
|
|
2521
1948
|
);
|