stream-chat-react-native-core 7.0.1 → 7.1.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/Channel/Channel.js +214 -237
- package/lib/commonjs/components/Channel/Channel.js.map +1 -1
- package/lib/commonjs/components/ChannelList/ChannelList.js +2 -19
- package/lib/commonjs/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js +48 -176
- package/lib/commonjs/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js +13 -2
- package/lib/commonjs/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -1
- package/lib/commonjs/components/Chat/Chat.js +33 -46
- package/lib/commonjs/components/Chat/Chat.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js +47 -120
- package/lib/commonjs/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/commonjs/components/Chat/hooks/useSyncDatabase.js +0 -15
- package/lib/commonjs/components/Chat/hooks/useSyncDatabase.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js +5 -0
- package/lib/commonjs/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js +92 -108
- package/lib/commonjs/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
- package/lib/commonjs/index.js +8 -0
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/mock-builders/event/channelVisible.js +13 -0
- package/lib/commonjs/mock-builders/event/channelVisible.js.map +1 -0
- package/lib/commonjs/mock-builders/event/memberAdded.js +4 -2
- package/lib/commonjs/mock-builders/event/memberAdded.js.map +1 -1
- package/lib/commonjs/mock-builders/event/memberRemoved.js +2 -1
- package/lib/commonjs/mock-builders/event/memberRemoved.js.map +1 -1
- package/lib/commonjs/mock-builders/event/memberUpdated.js +2 -1
- package/lib/commonjs/mock-builders/event/memberUpdated.js.map +1 -1
- package/lib/commonjs/mock-builders/event/messageNew.js +4 -2
- package/lib/commonjs/mock-builders/event/messageNew.js.map +1 -1
- package/lib/commonjs/mock-builders/event/messageRead.js +6 -3
- package/lib/commonjs/mock-builders/event/messageRead.js.map +1 -1
- package/lib/commonjs/mock-builders/event/notificationMarkUnread.js +3 -0
- package/lib/commonjs/mock-builders/event/notificationMarkUnread.js.map +1 -1
- package/lib/commonjs/mock-builders/generator/channel.js +10 -3
- package/lib/commonjs/mock-builders/generator/channel.js.map +1 -1
- package/lib/commonjs/store/OfflineDB.js +108 -0
- package/lib/commonjs/store/OfflineDB.js.map +1 -0
- package/lib/commonjs/store/SqliteClient.js +11 -10
- package/lib/commonjs/store/SqliteClient.js.map +1 -1
- package/lib/commonjs/store/apis/addPendingTask.js.map +1 -1
- package/lib/commonjs/store/apis/channelExists.js +34 -0
- package/lib/commonjs/store/apis/channelExists.js.map +1 -0
- package/lib/commonjs/store/apis/deleteChannel.js +4 -4
- package/lib/commonjs/store/apis/deleteChannel.js.map +1 -1
- package/lib/commonjs/store/apis/deleteMember.js +4 -4
- package/lib/commonjs/store/apis/deleteMember.js.map +1 -1
- package/lib/commonjs/store/apis/deleteMessage.js +16 -12
- package/lib/commonjs/store/apis/deleteMessage.js.map +1 -1
- package/lib/commonjs/store/apis/deleteMessagesForChannel.js +11 -12
- package/lib/commonjs/store/apis/deleteMessagesForChannel.js.map +1 -1
- package/lib/commonjs/store/apis/deleteReaction.js +29 -17
- package/lib/commonjs/store/apis/deleteReaction.js.map +1 -1
- package/lib/commonjs/store/apis/deleteReactions.js +4 -4
- package/lib/commonjs/store/apis/deleteReactions.js.map +1 -1
- package/lib/commonjs/store/apis/dropPendingTasks.js +41 -0
- package/lib/commonjs/store/apis/dropPendingTasks.js.map +1 -0
- package/lib/commonjs/store/apis/getChannelMessages.js +1 -1
- package/lib/commonjs/store/apis/getChannelMessages.js.map +1 -1
- package/lib/commonjs/store/apis/getChannels.js +18 -21
- package/lib/commonjs/store/apis/getChannels.js.map +1 -1
- package/lib/commonjs/store/apis/getLastSyncedAt.js +3 -9
- package/lib/commonjs/store/apis/getLastSyncedAt.js.map +1 -1
- package/lib/commonjs/store/apis/getReactionsforFilterSort.js +5 -8
- package/lib/commonjs/store/apis/getReactionsforFilterSort.js.map +1 -1
- package/lib/commonjs/store/apis/index.js +103 -4
- package/lib/commonjs/store/apis/index.js.map +1 -1
- package/lib/commonjs/store/apis/insertReaction.js +4 -4
- package/lib/commonjs/store/apis/insertReaction.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js +1 -1
- package/lib/commonjs/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js +25 -5
- package/lib/commonjs/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/commonjs/store/apis/softDeleteMessage.js +45 -0
- package/lib/commonjs/store/apis/softDeleteMessage.js.map +1 -0
- package/lib/commonjs/store/apis/updateMessage.js +7 -11
- package/lib/commonjs/store/apis/updateMessage.js.map +1 -1
- package/lib/commonjs/store/apis/updateReaction.js +11 -9
- package/lib/commonjs/store/apis/updateReaction.js.map +1 -1
- package/lib/commonjs/store/apis/upsertAppSettings.js +9 -7
- package/lib/commonjs/store/apis/upsertAppSettings.js.map +1 -1
- package/lib/commonjs/store/apis/upsertChannelData.js +4 -4
- package/lib/commonjs/store/apis/upsertChannelData.js.map +1 -1
- package/lib/commonjs/store/apis/upsertChannelDataFromChannel.js +3 -3
- package/lib/commonjs/store/apis/upsertChannelDataFromChannel.js.map +1 -1
- package/lib/commonjs/store/apis/upsertChannels.js +86 -83
- package/lib/commonjs/store/apis/upsertChannels.js.map +1 -1
- package/lib/commonjs/store/apis/upsertCidsForQuery.js +4 -4
- package/lib/commonjs/store/apis/upsertCidsForQuery.js.map +1 -1
- package/lib/commonjs/store/apis/upsertMembers.js +4 -4
- package/lib/commonjs/store/apis/upsertMembers.js.map +1 -1
- package/lib/commonjs/store/apis/upsertMessages.js +4 -4
- package/lib/commonjs/store/apis/upsertMessages.js.map +1 -1
- package/lib/commonjs/store/apis/upsertPoll.js +42 -0
- package/lib/commonjs/store/apis/upsertPoll.js.map +1 -0
- package/lib/commonjs/store/apis/upsertReads.js +4 -4
- package/lib/commonjs/store/apis/upsertReads.js.map +1 -1
- package/lib/commonjs/store/apis/upsertUserSyncStatus.js +13 -7
- package/lib/commonjs/store/apis/upsertUserSyncStatus.js.map +1 -1
- package/lib/commonjs/store/mappers/mapMemberToStorable.js +6 -2
- package/lib/commonjs/store/mappers/mapMemberToStorable.js.map +1 -1
- package/lib/commonjs/store/mappers/mapReadToStorable.js +3 -1
- package/lib/commonjs/store/mappers/mapReadToStorable.js.map +1 -1
- package/lib/commonjs/store/mappers/mapStorableToMember.js +5 -1
- package/lib/commonjs/store/mappers/mapStorableToMember.js.map +1 -1
- package/lib/commonjs/store/mappers/mapStorableToRead.js +3 -1
- package/lib/commonjs/store/mappers/mapStorableToRead.js.map +1 -1
- package/lib/commonjs/store/mappers/mapStorableToTask.js.map +1 -1
- package/lib/commonjs/store/schema.js +2 -0
- package/lib/commonjs/store/schema.js.map +1 -1
- package/lib/commonjs/utils/addReactionToLocalState.js +62 -81
- package/lib/commonjs/utils/addReactionToLocalState.js.map +1 -1
- package/lib/commonjs/utils/removeReactionFromLocalState.js +0 -6
- package/lib/commonjs/utils/removeReactionFromLocalState.js.map +1 -1
- package/lib/commonjs/version.json +1 -1
- package/lib/module/components/Channel/Channel.js +214 -237
- package/lib/module/components/Channel/Channel.js.map +1 -1
- package/lib/module/components/ChannelList/ChannelList.js +2 -19
- package/lib/module/components/ChannelList/ChannelList.js.map +1 -1
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js +48 -176
- package/lib/module/components/ChannelList/hooks/usePaginatedChannels.js.map +1 -1
- package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js +13 -2
- package/lib/module/components/ChannelPreview/hooks/useIsChannelMuted.js.map +1 -1
- package/lib/module/components/Chat/Chat.js +33 -46
- package/lib/module/components/Chat/Chat.js.map +1 -1
- package/lib/module/components/Chat/hooks/useAppSettings.js +47 -120
- package/lib/module/components/Chat/hooks/useAppSettings.js.map +1 -1
- package/lib/module/components/Chat/hooks/useSyncDatabase.js +0 -15
- package/lib/module/components/Chat/hooks/useSyncDatabase.js.map +1 -1
- package/lib/module/components/MessageMenu/MessageUserReactions.js +5 -0
- package/lib/module/components/MessageMenu/MessageUserReactions.js.map +1 -1
- package/lib/module/components/MessageMenu/hooks/useFetchReactions.js +92 -108
- package/lib/module/components/MessageMenu/hooks/useFetchReactions.js.map +1 -1
- package/lib/module/index.js +8 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/mock-builders/event/channelVisible.js +13 -0
- package/lib/module/mock-builders/event/channelVisible.js.map +1 -0
- package/lib/module/mock-builders/event/memberAdded.js +4 -2
- package/lib/module/mock-builders/event/memberAdded.js.map +1 -1
- package/lib/module/mock-builders/event/memberRemoved.js +2 -1
- package/lib/module/mock-builders/event/memberRemoved.js.map +1 -1
- package/lib/module/mock-builders/event/memberUpdated.js +2 -1
- package/lib/module/mock-builders/event/memberUpdated.js.map +1 -1
- package/lib/module/mock-builders/event/messageNew.js +4 -2
- package/lib/module/mock-builders/event/messageNew.js.map +1 -1
- package/lib/module/mock-builders/event/messageRead.js +6 -3
- package/lib/module/mock-builders/event/messageRead.js.map +1 -1
- package/lib/module/mock-builders/event/notificationMarkUnread.js +3 -0
- package/lib/module/mock-builders/event/notificationMarkUnread.js.map +1 -1
- package/lib/module/mock-builders/generator/channel.js +10 -3
- package/lib/module/mock-builders/generator/channel.js.map +1 -1
- package/lib/module/store/OfflineDB.js +108 -0
- package/lib/module/store/OfflineDB.js.map +1 -0
- package/lib/module/store/SqliteClient.js +11 -10
- package/lib/module/store/SqliteClient.js.map +1 -1
- package/lib/module/store/apis/addPendingTask.js.map +1 -1
- package/lib/module/store/apis/channelExists.js +34 -0
- package/lib/module/store/apis/channelExists.js.map +1 -0
- package/lib/module/store/apis/deleteChannel.js +4 -4
- package/lib/module/store/apis/deleteChannel.js.map +1 -1
- package/lib/module/store/apis/deleteMember.js +4 -4
- package/lib/module/store/apis/deleteMember.js.map +1 -1
- package/lib/module/store/apis/deleteMessage.js +16 -12
- package/lib/module/store/apis/deleteMessage.js.map +1 -1
- package/lib/module/store/apis/deleteMessagesForChannel.js +11 -12
- package/lib/module/store/apis/deleteMessagesForChannel.js.map +1 -1
- package/lib/module/store/apis/deleteReaction.js +29 -17
- package/lib/module/store/apis/deleteReaction.js.map +1 -1
- package/lib/module/store/apis/deleteReactions.js +4 -4
- package/lib/module/store/apis/deleteReactions.js.map +1 -1
- package/lib/module/store/apis/dropPendingTasks.js +41 -0
- package/lib/module/store/apis/dropPendingTasks.js.map +1 -0
- package/lib/module/store/apis/getChannelMessages.js +1 -1
- package/lib/module/store/apis/getChannelMessages.js.map +1 -1
- package/lib/module/store/apis/getChannels.js +18 -21
- package/lib/module/store/apis/getChannels.js.map +1 -1
- package/lib/module/store/apis/getLastSyncedAt.js +3 -9
- package/lib/module/store/apis/getLastSyncedAt.js.map +1 -1
- package/lib/module/store/apis/getReactionsforFilterSort.js +5 -8
- package/lib/module/store/apis/getReactionsforFilterSort.js.map +1 -1
- package/lib/module/store/apis/index.js +103 -4
- package/lib/module/store/apis/index.js.map +1 -1
- package/lib/module/store/apis/insertReaction.js +4 -4
- package/lib/module/store/apis/insertReaction.js.map +1 -1
- package/lib/module/store/apis/queries/selectMessagesForChannels.js +1 -1
- package/lib/module/store/apis/queries/selectMessagesForChannels.js.map +1 -1
- package/lib/module/store/apis/queries/selectReactionsForMessages.js +25 -5
- package/lib/module/store/apis/queries/selectReactionsForMessages.js.map +1 -1
- package/lib/module/store/apis/softDeleteMessage.js +45 -0
- package/lib/module/store/apis/softDeleteMessage.js.map +1 -0
- package/lib/module/store/apis/updateMessage.js +7 -11
- package/lib/module/store/apis/updateMessage.js.map +1 -1
- package/lib/module/store/apis/updateReaction.js +11 -9
- package/lib/module/store/apis/updateReaction.js.map +1 -1
- package/lib/module/store/apis/upsertAppSettings.js +9 -7
- package/lib/module/store/apis/upsertAppSettings.js.map +1 -1
- package/lib/module/store/apis/upsertChannelData.js +4 -4
- package/lib/module/store/apis/upsertChannelData.js.map +1 -1
- package/lib/module/store/apis/upsertChannelDataFromChannel.js +3 -3
- package/lib/module/store/apis/upsertChannelDataFromChannel.js.map +1 -1
- package/lib/module/store/apis/upsertChannels.js +86 -83
- package/lib/module/store/apis/upsertChannels.js.map +1 -1
- package/lib/module/store/apis/upsertCidsForQuery.js +4 -4
- package/lib/module/store/apis/upsertCidsForQuery.js.map +1 -1
- package/lib/module/store/apis/upsertMembers.js +4 -4
- package/lib/module/store/apis/upsertMembers.js.map +1 -1
- package/lib/module/store/apis/upsertMessages.js +4 -4
- package/lib/module/store/apis/upsertMessages.js.map +1 -1
- package/lib/module/store/apis/upsertPoll.js +42 -0
- package/lib/module/store/apis/upsertPoll.js.map +1 -0
- package/lib/module/store/apis/upsertReads.js +4 -4
- package/lib/module/store/apis/upsertReads.js.map +1 -1
- package/lib/module/store/apis/upsertUserSyncStatus.js +13 -7
- package/lib/module/store/apis/upsertUserSyncStatus.js.map +1 -1
- package/lib/module/store/mappers/mapMemberToStorable.js +6 -2
- package/lib/module/store/mappers/mapMemberToStorable.js.map +1 -1
- package/lib/module/store/mappers/mapReadToStorable.js +3 -1
- package/lib/module/store/mappers/mapReadToStorable.js.map +1 -1
- package/lib/module/store/mappers/mapStorableToMember.js +5 -1
- package/lib/module/store/mappers/mapStorableToMember.js.map +1 -1
- package/lib/module/store/mappers/mapStorableToRead.js +3 -1
- package/lib/module/store/mappers/mapStorableToRead.js.map +1 -1
- package/lib/module/store/mappers/mapStorableToTask.js.map +1 -1
- package/lib/module/store/schema.js +2 -0
- package/lib/module/store/schema.js.map +1 -1
- package/lib/module/utils/addReactionToLocalState.js +62 -81
- package/lib/module/utils/addReactionToLocalState.js.map +1 -1
- package/lib/module/utils/removeReactionFromLocalState.js +0 -6
- package/lib/module/utils/removeReactionFromLocalState.js.map +1 -1
- package/lib/module/version.json +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts +1 -1
- package/lib/typescript/components/Channel/Channel.d.ts.map +1 -1
- package/lib/typescript/components/Channel/hooks/useCreateThreadContext.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/ChannelList.d.ts.map +1 -1
- package/lib/typescript/components/ChannelList/hooks/usePaginatedChannels.d.ts +1 -1
- package/lib/typescript/components/ChannelList/hooks/usePaginatedChannels.d.ts.map +1 -1
- package/lib/typescript/components/ChannelPreview/hooks/useIsChannelMuted.d.ts.map +1 -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/useSyncDatabase.d.ts +9 -1
- package/lib/typescript/components/Chat/hooks/useSyncDatabase.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/MessageUserReactions.d.ts.map +1 -1
- package/lib/typescript/components/MessageMenu/hooks/useFetchReactions.d.ts.map +1 -1
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts +1 -1
- package/lib/typescript/contexts/messagesContext/MessagesContext.d.ts.map +1 -1
- package/lib/typescript/hooks/useTranslatedMessage.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +1 -0
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/store/OfflineDB.d.ts +112 -0
- package/lib/typescript/store/OfflineDB.d.ts.map +1 -0
- package/lib/typescript/store/SqliteClient.d.ts +1 -1
- package/lib/typescript/store/SqliteClient.d.ts.map +1 -1
- package/lib/typescript/store/apis/addPendingTask.d.ts +1 -1
- package/lib/typescript/store/apis/addPendingTask.d.ts.map +1 -1
- package/lib/typescript/store/apis/channelExists.d.ts +4 -0
- package/lib/typescript/store/apis/channelExists.d.ts.map +1 -0
- package/lib/typescript/store/apis/deleteChannel.d.ts +2 -2
- package/lib/typescript/store/apis/deleteChannel.d.ts.map +1 -1
- package/lib/typescript/store/apis/deleteMember.d.ts +2 -2
- package/lib/typescript/store/apis/deleteMember.d.ts.map +1 -1
- package/lib/typescript/store/apis/deleteMessage.d.ts +3 -3
- package/lib/typescript/store/apis/deleteMessage.d.ts.map +1 -1
- package/lib/typescript/store/apis/deleteMessagesForChannel.d.ts +4 -3
- package/lib/typescript/store/apis/deleteMessagesForChannel.d.ts.map +1 -1
- package/lib/typescript/store/apis/deleteReaction.d.ts +7 -6
- package/lib/typescript/store/apis/deleteReaction.d.ts.map +1 -1
- package/lib/typescript/store/apis/deleteReactions.d.ts +2 -2
- package/lib/typescript/store/apis/deleteReactions.d.ts.map +1 -1
- package/lib/typescript/store/apis/dropPendingTasks.d.ts +16 -0
- package/lib/typescript/store/apis/dropPendingTasks.d.ts.map +1 -0
- package/lib/typescript/store/apis/getChannels.d.ts.map +1 -1
- package/lib/typescript/store/apis/getLastSyncedAt.d.ts +1 -1
- package/lib/typescript/store/apis/getLastSyncedAt.d.ts.map +1 -1
- package/lib/typescript/store/apis/getPendingTasks.d.ts +1 -1
- package/lib/typescript/store/apis/getPendingTasks.d.ts.map +1 -1
- package/lib/typescript/store/apis/getReactionsforFilterSort.d.ts +5 -3
- package/lib/typescript/store/apis/getReactionsforFilterSort.d.ts.map +1 -1
- package/lib/typescript/store/apis/index.d.ts +10 -1
- package/lib/typescript/store/apis/index.d.ts.map +1 -1
- package/lib/typescript/store/apis/insertReaction.d.ts +2 -2
- package/lib/typescript/store/apis/insertReaction.d.ts.map +1 -1
- package/lib/typescript/store/apis/queries/selectReactionsForMessages.d.ts +5 -1
- package/lib/typescript/store/apis/queries/selectReactionsForMessages.d.ts.map +1 -1
- package/lib/typescript/store/apis/softDeleteMessage.d.ts +5 -0
- package/lib/typescript/store/apis/softDeleteMessage.d.ts.map +1 -0
- package/lib/typescript/store/apis/updateMessage.d.ts +2 -2
- package/lib/typescript/store/apis/updateMessage.d.ts.map +1 -1
- package/lib/typescript/store/apis/updateReaction.d.ts +2 -2
- package/lib/typescript/store/apis/updateReaction.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertAppSettings.d.ts +3 -3
- package/lib/typescript/store/apis/upsertAppSettings.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertChannelData.d.ts +2 -2
- package/lib/typescript/store/apis/upsertChannelData.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertChannelDataFromChannel.d.ts +2 -2
- package/lib/typescript/store/apis/upsertChannelDataFromChannel.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertChannels.d.ts +3 -5
- package/lib/typescript/store/apis/upsertChannels.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertCidsForQuery.d.ts +2 -2
- package/lib/typescript/store/apis/upsertCidsForQuery.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertMembers.d.ts +2 -2
- package/lib/typescript/store/apis/upsertMembers.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertMessages.d.ts +2 -2
- package/lib/typescript/store/apis/upsertMessages.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertPoll.d.ts +7 -0
- package/lib/typescript/store/apis/upsertPoll.d.ts.map +1 -0
- package/lib/typescript/store/apis/upsertReads.d.ts +2 -2
- package/lib/typescript/store/apis/upsertReads.d.ts.map +1 -1
- package/lib/typescript/store/apis/upsertUserSyncStatus.d.ts +3 -2
- package/lib/typescript/store/apis/upsertUserSyncStatus.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapMemberToStorable.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapReadToStorable.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapStorableToMember.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapStorableToRead.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapStorableToTask.d.ts +2 -1
- package/lib/typescript/store/mappers/mapStorableToTask.d.ts.map +1 -1
- package/lib/typescript/store/mappers/mapTaskToStorable.d.ts +18 -10
- package/lib/typescript/store/mappers/mapTaskToStorable.d.ts.map +1 -1
- package/lib/typescript/store/schema.d.ts +3 -2
- package/lib/typescript/store/schema.d.ts.map +1 -1
- package/lib/typescript/utils/addReactionToLocalState.d.ts +1 -1
- package/lib/typescript/utils/addReactionToLocalState.d.ts.map +1 -1
- package/lib/typescript/utils/removeReactionFromLocalState.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/__tests__/offline-support/offline-feature.js +894 -21
- package/src/__tests__/offline-support/optimistic-update.js +154 -44
- package/src/components/Channel/Channel.tsx +95 -118
- package/src/components/ChannelList/ChannelList.tsx +1 -23
- package/src/components/ChannelList/hooks/usePaginatedChannels.ts +9 -93
- package/src/components/ChannelPreview/hooks/useIsChannelMuted.ts +20 -2
- package/src/components/Chat/Chat.tsx +21 -45
- package/src/components/Chat/__tests__/Chat.test.js +21 -13
- package/src/components/Chat/hooks/useAppSettings.ts +17 -54
- package/src/components/Chat/hooks/useSyncDatabase.ts +11 -17
- package/src/components/MessageMenu/MessageUserReactions.tsx +7 -1
- package/src/components/MessageMenu/hooks/useFetchReactions.ts +68 -35
- package/src/contexts/messagesContext/MessagesContext.tsx +1 -1
- package/src/index.ts +1 -0
- package/src/mock-builders/event/channelVisible.js +7 -0
- package/src/mock-builders/event/memberAdded.js +3 -1
- package/src/mock-builders/event/memberRemoved.js +1 -0
- package/src/mock-builders/event/memberUpdated.js +1 -0
- package/src/mock-builders/event/messageNew.js +1 -0
- package/src/mock-builders/event/messageRead.js +5 -2
- package/src/mock-builders/event/notificationMarkUnread.js +3 -0
- package/src/mock-builders/generator/channel.ts +15 -3
- package/src/store/OfflineDB.ts +93 -0
- package/src/store/SqliteClient.ts +7 -1
- package/src/store/apis/addPendingTask.ts +2 -1
- package/src/store/apis/channelExists.ts +14 -0
- package/src/store/apis/deleteChannel.ts +9 -3
- package/src/store/apis/deleteMember.ts +4 -4
- package/src/store/apis/deleteMessage.ts +18 -8
- package/src/store/apis/deleteMessagesForChannel.ts +12 -8
- package/src/store/apis/deleteReaction.ts +39 -19
- package/src/store/apis/deleteReactions.ts +4 -4
- package/src/store/apis/dropPendingTasks.ts +32 -0
- package/src/store/apis/getChannelMessages.ts +1 -1
- package/src/store/apis/getChannels.ts +10 -7
- package/src/store/apis/getLastSyncedAt.ts +2 -5
- package/src/store/apis/getReactionsforFilterSort.ts +8 -7
- package/src/store/apis/index.ts +10 -1
- package/src/store/apis/insertReaction.ts +4 -4
- package/src/store/apis/queries/selectMessagesForChannels.ts +2 -2
- package/src/store/apis/queries/selectReactionsForMessages.ts +21 -2
- package/src/store/apis/softDeleteMessage.ts +32 -0
- package/src/store/apis/updateMessage.ts +3 -10
- package/src/store/apis/updateReaction.ts +7 -5
- package/src/store/apis/upsertAppSettings.ts +13 -9
- package/src/store/apis/upsertChannelData.ts +4 -4
- package/src/store/apis/upsertChannelDataFromChannel.ts +3 -3
- package/src/store/apis/upsertChannels.ts +14 -24
- package/src/store/apis/upsertCidsForQuery.ts +4 -4
- package/src/store/apis/upsertMembers.ts +4 -4
- package/src/store/apis/upsertMessages.ts +4 -4
- package/src/store/apis/upsertPoll.ts +29 -0
- package/src/store/apis/upsertReads.ts +4 -4
- package/src/store/apis/upsertUserSyncStatus.ts +13 -5
- package/src/store/mappers/mapMemberToStorable.ts +4 -0
- package/src/store/mappers/mapReadToStorable.ts +2 -1
- package/src/store/mappers/mapStorableToMember.ts +4 -0
- package/src/store/mappers/mapStorableToRead.ts +2 -1
- package/src/store/mappers/mapStorableToTask.ts +3 -1
- package/src/store/mappers/mapTaskToStorable.ts +1 -1
- package/src/store/schema.ts +5 -3
- package/src/utils/addReactionToLocalState.ts +9 -63
- package/src/utils/removeReactionFromLocalState.ts +0 -8
- package/src/version.json +1 -1
- package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js +0 -406
- package/lib/commonjs/components/Chat/hooks/handleEventToSyncDB.js.map +0 -1
- package/lib/commonjs/store/apis/updatePollMessage.js +0 -84
- package/lib/commonjs/store/apis/updatePollMessage.js.map +0 -1
- package/lib/commonjs/utils/DBSyncManager.js +0 -470
- package/lib/commonjs/utils/DBSyncManager.js.map +0 -1
- package/lib/module/components/Chat/hooks/handleEventToSyncDB.js +0 -406
- package/lib/module/components/Chat/hooks/handleEventToSyncDB.js.map +0 -1
- package/lib/module/store/apis/updatePollMessage.js +0 -84
- package/lib/module/store/apis/updatePollMessage.js.map +0 -1
- package/lib/module/utils/DBSyncManager.js +0 -470
- package/lib/module/utils/DBSyncManager.js.map +0 -1
- package/lib/typescript/components/Chat/hooks/handleEventToSyncDB.d.ts +0 -4
- package/lib/typescript/components/Chat/hooks/handleEventToSyncDB.d.ts.map +0 -1
- package/lib/typescript/store/apis/updatePollMessage.d.ts +0 -10
- package/lib/typescript/store/apis/updatePollMessage.d.ts.map +0 -1
- package/lib/typescript/utils/DBSyncManager.d.ts +0 -50
- package/lib/typescript/utils/DBSyncManager.d.ts.map +0 -1
- package/src/components/Chat/hooks/handleEventToSyncDB.ts +0 -290
- package/src/store/apis/updatePollMessage.ts +0 -71
- package/src/utils/DBSyncManager.ts +0 -242
|
@@ -13,8 +13,11 @@ import { useChannelsContext } from '../../contexts/channelsContext/ChannelsConte
|
|
|
13
13
|
import { getOrCreateChannelApi } from '../../mock-builders/api/getOrCreateChannel';
|
|
14
14
|
import { queryChannelsApi } from '../../mock-builders/api/queryChannels';
|
|
15
15
|
import { useMockedApis } from '../../mock-builders/api/useMockedApis';
|
|
16
|
+
import dispatchChannelDeletedEvent from '../../mock-builders/event/channelDeleted';
|
|
17
|
+
import dispatchChannelHiddenEvent from '../../mock-builders/event/channelHidden';
|
|
16
18
|
import dispatchChannelTruncatedEvent from '../../mock-builders/event/channelTruncated';
|
|
17
19
|
import dispatchChannelUpdatedEvent from '../../mock-builders/event/channelUpdated';
|
|
20
|
+
import dispatchChannelVisibleEvent from '../../mock-builders/event/channelVisible';
|
|
18
21
|
import dispatchConnectionChangedEvent from '../../mock-builders/event/connectionChanged';
|
|
19
22
|
import dispatchMemberAddedEvent from '../../mock-builders/event/memberAdded';
|
|
20
23
|
import dispatchMemberRemovedEvent from '../../mock-builders/event/memberRemoved';
|
|
@@ -23,6 +26,7 @@ import dispatchMessageNewEvent from '../../mock-builders/event/messageNew';
|
|
|
23
26
|
import dispatchMessageReadEvent from '../../mock-builders/event/messageRead';
|
|
24
27
|
import dispatchMessageUpdatedEvent from '../../mock-builders/event/messageUpdated';
|
|
25
28
|
import dispatchNotificationAddedToChannel from '../../mock-builders/event/notificationAddedToChannel';
|
|
29
|
+
import dispatchNotificationMarkUnread from '../../mock-builders/event/notificationMarkUnread';
|
|
26
30
|
import dispatchNotificationMessageNewEvent from '../../mock-builders/event/notificationMessageNew';
|
|
27
31
|
import dispatchNotificationRemovedFromChannel from '../../mock-builders/event/notificationRemovedFromChannel';
|
|
28
32
|
import dispatchReactionDeletedEvent from '../../mock-builders/event/reactionDeleted';
|
|
@@ -124,8 +128,10 @@ export const Generic = () => {
|
|
|
124
128
|
const createChannel = (messagesOverride) => {
|
|
125
129
|
const id = uuidv4();
|
|
126
130
|
const cid = `messaging:${id}`;
|
|
127
|
-
|
|
128
|
-
|
|
131
|
+
// always guarantee at least 2 members for ease of use; cases that need to test specific behaviour
|
|
132
|
+
// for 1 or 0 member channels should explicitly generate them.
|
|
133
|
+
const begin = getRandomInt(0, allUsers.length - 3); // begin shouldn't be the end of users.length
|
|
134
|
+
const end = getRandomInt(begin + 2, allUsers.length - 1);
|
|
129
135
|
const usersForMembers = allUsers.slice(begin, end);
|
|
130
136
|
const members = usersForMembers.map((user) =>
|
|
131
137
|
generateMember({
|
|
@@ -133,6 +139,8 @@ export const Generic = () => {
|
|
|
133
139
|
user,
|
|
134
140
|
}),
|
|
135
141
|
);
|
|
142
|
+
members.push(generateMember({ cid, user: chatClient.user }));
|
|
143
|
+
|
|
136
144
|
const messages =
|
|
137
145
|
messagesOverride ||
|
|
138
146
|
Array(10)
|
|
@@ -162,8 +170,9 @@ export const Generic = () => {
|
|
|
162
170
|
});
|
|
163
171
|
|
|
164
172
|
const reads = members.map((member) => ({
|
|
173
|
+
cid,
|
|
165
174
|
last_read: new Date(new Date().setDate(new Date().getDate() - getRandomInt(0, 20))),
|
|
166
|
-
unread_messages:
|
|
175
|
+
unread_messages: 0,
|
|
167
176
|
user: member.user,
|
|
168
177
|
}));
|
|
169
178
|
|
|
@@ -176,21 +185,23 @@ export const Generic = () => {
|
|
|
176
185
|
id,
|
|
177
186
|
members,
|
|
178
187
|
messages,
|
|
188
|
+
read: reads,
|
|
179
189
|
});
|
|
180
190
|
};
|
|
181
191
|
|
|
182
192
|
beforeEach(async () => {
|
|
183
193
|
jest.clearAllMocks();
|
|
194
|
+
chatClient = await getTestClientWithUser({ id: 'dan' });
|
|
184
195
|
allUsers = Array(20).fill(1).map(generateUser);
|
|
196
|
+
allUsers.push(chatClient.user);
|
|
185
197
|
allMessages = [];
|
|
186
198
|
allMembers = [];
|
|
187
199
|
allReactions = [];
|
|
188
200
|
allReads = [];
|
|
201
|
+
|
|
189
202
|
channels = Array(10)
|
|
190
203
|
.fill(1)
|
|
191
204
|
.map(() => createChannel());
|
|
192
|
-
|
|
193
|
-
chatClient = await getTestClientWithUser({ id: 'dan' });
|
|
194
205
|
await BetterSqlite.openDB();
|
|
195
206
|
BetterSqlite.dropAllTables();
|
|
196
207
|
});
|
|
@@ -282,12 +293,7 @@ export const Generic = () => {
|
|
|
282
293
|
);
|
|
283
294
|
readsRows.forEach((row) =>
|
|
284
295
|
expect(
|
|
285
|
-
allReads.filter(
|
|
286
|
-
(r) =>
|
|
287
|
-
r.last_read === row.lastRead &&
|
|
288
|
-
r.user.id === row.userId &&
|
|
289
|
-
r.unread_messages === row.unreadMessages,
|
|
290
|
-
),
|
|
296
|
+
allReads.filter((r) => r.user.id === row.userId && r.cid === row.cid),
|
|
291
297
|
).toHaveLength(1),
|
|
292
298
|
);
|
|
293
299
|
});
|
|
@@ -316,6 +322,7 @@ export const Generic = () => {
|
|
|
316
322
|
await act(() => dispatchConnectionChangedEvent(chatClient, false));
|
|
317
323
|
// await waiter();
|
|
318
324
|
await act(() => dispatchConnectionChangedEvent(chatClient));
|
|
325
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
319
326
|
|
|
320
327
|
await waitFor(async () => {
|
|
321
328
|
expect(screen.getByTestId('channel-list')).toBeTruthy();
|
|
@@ -328,8 +335,10 @@ export const Generic = () => {
|
|
|
328
335
|
|
|
329
336
|
renderComponent();
|
|
330
337
|
|
|
338
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
339
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
340
|
+
|
|
331
341
|
await waitFor(async () => {
|
|
332
|
-
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
333
342
|
expect(screen.getByTestId('channel-list')).toBeTruthy();
|
|
334
343
|
await expectAllChannelsWithStateToBeInDB(screen.queryAllByLabelText);
|
|
335
344
|
});
|
|
@@ -342,8 +351,11 @@ export const Generic = () => {
|
|
|
342
351
|
|
|
343
352
|
renderComponent();
|
|
344
353
|
|
|
345
|
-
await waitFor(() => {
|
|
354
|
+
await waitFor(async () => {
|
|
346
355
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
356
|
+
await act(
|
|
357
|
+
async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true),
|
|
358
|
+
);
|
|
347
359
|
expect(screen.getByTestId('channel-list')).toBeTruthy();
|
|
348
360
|
expect(screen.getByTestId(emptyChannel.cid)).toBeTruthy();
|
|
349
361
|
expect(chatClient.hydrateActiveChannels).toHaveBeenCalled();
|
|
@@ -356,18 +368,151 @@ export const Generic = () => {
|
|
|
356
368
|
|
|
357
369
|
renderComponent();
|
|
358
370
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
371
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
359
372
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
373
|
+
const targetChannel = channels[0].channel;
|
|
360
374
|
const newMessage = generateMessage({
|
|
361
|
-
cid:
|
|
375
|
+
cid: targetChannel.cid,
|
|
362
376
|
user: generateUser(),
|
|
363
377
|
});
|
|
364
|
-
act(() => dispatchMessageNewEvent(chatClient, newMessage,
|
|
378
|
+
act(() => dispatchMessageNewEvent(chatClient, newMessage, targetChannel));
|
|
365
379
|
|
|
366
380
|
await waitFor(async () => {
|
|
367
381
|
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
368
|
-
const
|
|
369
|
-
|
|
370
|
-
|
|
382
|
+
const readRows = await BetterSqlite.selectFromTable('reads');
|
|
383
|
+
const matchingMessageRows = messagesRows.filter((m) => m.id === newMessage.id);
|
|
384
|
+
const matchingReadRows = readRows.filter(
|
|
385
|
+
(r) => targetChannel.cid === r.cid && chatClient.userID === r.userId,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
expect(matchingMessageRows.length).toBe(1);
|
|
389
|
+
expect(matchingMessageRows[0].id).toBe(newMessage.id);
|
|
390
|
+
expect(matchingReadRows.length).toBe(1);
|
|
391
|
+
expect(matchingReadRows[0].unreadMessages).toBe(1);
|
|
392
|
+
});
|
|
393
|
+
});
|
|
394
|
+
|
|
395
|
+
it('should correctly handle multiple new messages and add them to the database', async () => {
|
|
396
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
397
|
+
|
|
398
|
+
renderComponent();
|
|
399
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
400
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
401
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
402
|
+
const targetChannel = channels[0].channel;
|
|
403
|
+
|
|
404
|
+
// check if the reads state is correct first
|
|
405
|
+
await waitFor(async () => {
|
|
406
|
+
const readRows = await BetterSqlite.selectFromTable('reads');
|
|
407
|
+
const matchingReadRows = readRows.filter(
|
|
408
|
+
(r) => targetChannel.cid === r.cid && chatClient.userID === r.userId,
|
|
409
|
+
);
|
|
410
|
+
|
|
411
|
+
expect(matchingReadRows.length).toBe(1);
|
|
412
|
+
expect(matchingReadRows[0].unreadMessages).toBe(0);
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
const newMessages = [
|
|
416
|
+
generateMessage({
|
|
417
|
+
cid: targetChannel.cid,
|
|
418
|
+
user: generateUser(),
|
|
419
|
+
}),
|
|
420
|
+
generateMessage({
|
|
421
|
+
cid: targetChannel.cid,
|
|
422
|
+
user: generateUser(),
|
|
423
|
+
}),
|
|
424
|
+
generateMessage({
|
|
425
|
+
cid: targetChannel.cid,
|
|
426
|
+
user: generateUser(),
|
|
427
|
+
}),
|
|
428
|
+
];
|
|
429
|
+
|
|
430
|
+
newMessages.forEach((newMessage) => {
|
|
431
|
+
act(() => dispatchMessageNewEvent(chatClient, newMessage, targetChannel));
|
|
432
|
+
});
|
|
433
|
+
|
|
434
|
+
await waitFor(async () => {
|
|
435
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
436
|
+
const readRows = await BetterSqlite.selectFromTable('reads');
|
|
437
|
+
const matchingMessageRows = messagesRows.filter((m) =>
|
|
438
|
+
newMessages.some((newMessage) => newMessage.id === m.id),
|
|
439
|
+
);
|
|
440
|
+
const matchingReadRows = readRows.filter(
|
|
441
|
+
(r) => targetChannel.cid === r.cid && chatClient.userID === r.userId,
|
|
442
|
+
);
|
|
443
|
+
|
|
444
|
+
expect(matchingMessageRows.length).toBe(3);
|
|
445
|
+
newMessages.forEach((newMessage) => {
|
|
446
|
+
expect(
|
|
447
|
+
matchingMessageRows.some(
|
|
448
|
+
(matchingMessageRow) => matchingMessageRow.id === newMessage.id,
|
|
449
|
+
),
|
|
450
|
+
).toBe(true);
|
|
451
|
+
});
|
|
452
|
+
expect(matchingReadRows.length).toBe(1);
|
|
453
|
+
expect(matchingReadRows[0].unreadMessages).toBe(3);
|
|
454
|
+
});
|
|
455
|
+
});
|
|
456
|
+
|
|
457
|
+
it('should correctly handle multiple new messages from our own user', async () => {
|
|
458
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
459
|
+
|
|
460
|
+
renderComponent();
|
|
461
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
462
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
463
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
464
|
+
const targetChannel = channels[0].channel;
|
|
465
|
+
|
|
466
|
+
// check if the reads state is correct first
|
|
467
|
+
await waitFor(async () => {
|
|
468
|
+
const readRows = await BetterSqlite.selectFromTable('reads');
|
|
469
|
+
const matchingReadRows = readRows.filter(
|
|
470
|
+
(r) => targetChannel.cid === r.cid && chatClient.userID === r.userId,
|
|
471
|
+
);
|
|
472
|
+
|
|
473
|
+
expect(matchingReadRows.length).toBe(1);
|
|
474
|
+
expect(matchingReadRows[0].unreadMessages).toBe(0);
|
|
475
|
+
});
|
|
476
|
+
|
|
477
|
+
const newMessages = [
|
|
478
|
+
generateMessage({
|
|
479
|
+
cid: targetChannel.cid,
|
|
480
|
+
user: chatClient.user,
|
|
481
|
+
}),
|
|
482
|
+
generateMessage({
|
|
483
|
+
cid: targetChannel.cid,
|
|
484
|
+
user: chatClient.user,
|
|
485
|
+
}),
|
|
486
|
+
generateMessage({
|
|
487
|
+
cid: targetChannel.cid,
|
|
488
|
+
user: chatClient.user,
|
|
489
|
+
}),
|
|
490
|
+
];
|
|
491
|
+
|
|
492
|
+
newMessages.forEach((newMessage) => {
|
|
493
|
+
act(() => dispatchMessageNewEvent(chatClient, newMessage, targetChannel));
|
|
494
|
+
});
|
|
495
|
+
|
|
496
|
+
await waitFor(async () => {
|
|
497
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
498
|
+
const readRows = await BetterSqlite.selectFromTable('reads');
|
|
499
|
+
const matchingMessageRows = messagesRows.filter((m) =>
|
|
500
|
+
newMessages.some((newMessage) => newMessage.id === m.id),
|
|
501
|
+
);
|
|
502
|
+
const matchingReadRows = readRows.filter(
|
|
503
|
+
(r) => targetChannel.cid === r.cid && chatClient.userID === r.userId,
|
|
504
|
+
);
|
|
505
|
+
|
|
506
|
+
expect(matchingMessageRows.length).toBe(3);
|
|
507
|
+
newMessages.forEach((newMessage) => {
|
|
508
|
+
expect(
|
|
509
|
+
matchingMessageRows.some(
|
|
510
|
+
(matchingMessageRow) => matchingMessageRow.id === newMessage.id,
|
|
511
|
+
),
|
|
512
|
+
).toBe(true);
|
|
513
|
+
});
|
|
514
|
+
expect(matchingReadRows.length).toBe(1);
|
|
515
|
+
expect(matchingReadRows[0].unreadMessages).toBe(0);
|
|
371
516
|
});
|
|
372
517
|
});
|
|
373
518
|
|
|
@@ -375,8 +520,11 @@ export const Generic = () => {
|
|
|
375
520
|
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
376
521
|
|
|
377
522
|
renderComponent();
|
|
378
|
-
await waitFor(() => {
|
|
523
|
+
await waitFor(async () => {
|
|
379
524
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
525
|
+
await act(
|
|
526
|
+
async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true),
|
|
527
|
+
);
|
|
380
528
|
expect(screen.getByTestId('channel-list')).toBeTruthy();
|
|
381
529
|
});
|
|
382
530
|
|
|
@@ -399,6 +547,7 @@ export const Generic = () => {
|
|
|
399
547
|
|
|
400
548
|
renderComponent();
|
|
401
549
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
550
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
402
551
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
403
552
|
|
|
404
553
|
const updatedMessage = { ...channels[0].messages[0] };
|
|
@@ -420,6 +569,7 @@ export const Generic = () => {
|
|
|
420
569
|
|
|
421
570
|
renderComponent();
|
|
422
571
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
572
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
423
573
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
424
574
|
const removedChannel = channels[getRandomInt(0, channels.length - 1)].channel;
|
|
425
575
|
act(() => dispatchNotificationRemovedFromChannel(chatClient, removedChannel));
|
|
@@ -441,11 +591,122 @@ export const Generic = () => {
|
|
|
441
591
|
});
|
|
442
592
|
});
|
|
443
593
|
|
|
594
|
+
it('should remove the channel from DB if the channel is deleted', async () => {
|
|
595
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
596
|
+
|
|
597
|
+
renderComponent();
|
|
598
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
599
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
600
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
601
|
+
const removedChannel = channels[getRandomInt(0, channels.length - 1)].channel;
|
|
602
|
+
act(() => dispatchChannelDeletedEvent(chatClient, removedChannel));
|
|
603
|
+
await waitFor(async () => {
|
|
604
|
+
const channelIdsOnUI = screen
|
|
605
|
+
.queryAllByLabelText('list-item')
|
|
606
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
607
|
+
expect(channelIdsOnUI.includes(removedChannel.cid)).toBeFalsy();
|
|
608
|
+
await expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
609
|
+
|
|
610
|
+
const channelsRows = await BetterSqlite.selectFromTable('channels');
|
|
611
|
+
const matchingRows = channelsRows.filter((c) => c.id === removedChannel.id);
|
|
612
|
+
|
|
613
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
614
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === removedChannel.cid);
|
|
615
|
+
|
|
616
|
+
expect(matchingRows.length).toBe(0);
|
|
617
|
+
expect(matchingMessagesRows.length).toBe(0);
|
|
618
|
+
});
|
|
619
|
+
});
|
|
620
|
+
|
|
621
|
+
it('should correctly mark the channel as hidden in the db', async () => {
|
|
622
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
623
|
+
|
|
624
|
+
renderComponent();
|
|
625
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
626
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
627
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
628
|
+
const hiddenChannel = channels[getRandomInt(0, channels.length - 1)].channel;
|
|
629
|
+
act(() => dispatchChannelHiddenEvent(chatClient, hiddenChannel));
|
|
630
|
+
await waitFor(async () => {
|
|
631
|
+
const channelIdsOnUI = screen
|
|
632
|
+
.queryAllByLabelText('list-item')
|
|
633
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
634
|
+
expect(channelIdsOnUI.includes(hiddenChannel.cid)).toBeFalsy();
|
|
635
|
+
await expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
636
|
+
|
|
637
|
+
const channelsRows = await BetterSqlite.selectFromTable('channels');
|
|
638
|
+
const matchingRows = channelsRows.filter((c) => c.id === hiddenChannel.id);
|
|
639
|
+
|
|
640
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
641
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === hiddenChannel.cid);
|
|
642
|
+
|
|
643
|
+
expect(matchingRows.length).toBe(1);
|
|
644
|
+
expect(matchingRows[0].hidden).toBeTruthy();
|
|
645
|
+
expect(matchingMessagesRows.length).toBe(
|
|
646
|
+
chatClient.activeChannels[hiddenChannel.cid].state.messages.length,
|
|
647
|
+
);
|
|
648
|
+
});
|
|
649
|
+
});
|
|
650
|
+
|
|
651
|
+
it('should correctly mark the channel as visible if it was hidden before in the db', async () => {
|
|
652
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
653
|
+
|
|
654
|
+
renderComponent();
|
|
655
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
656
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
657
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
658
|
+
const hiddenChannel = channels[getRandomInt(0, channels.length - 1)].channel;
|
|
659
|
+
// first, we mark it as hidden
|
|
660
|
+
act(() => dispatchChannelHiddenEvent(chatClient, hiddenChannel));
|
|
661
|
+
await waitFor(async () => {
|
|
662
|
+
const channelIdsOnUI = screen
|
|
663
|
+
.queryAllByLabelText('list-item')
|
|
664
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
665
|
+
expect(channelIdsOnUI.includes(hiddenChannel.cid)).toBeFalsy();
|
|
666
|
+
await expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
667
|
+
|
|
668
|
+
const channelsRows = await BetterSqlite.selectFromTable('channels');
|
|
669
|
+
const matchingRows = channelsRows.filter((c) => c.id === hiddenChannel.id);
|
|
670
|
+
|
|
671
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
672
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === hiddenChannel.cid);
|
|
673
|
+
|
|
674
|
+
expect(matchingRows.length).toBe(1);
|
|
675
|
+
expect(matchingRows[0].hidden).toBeTruthy();
|
|
676
|
+
expect(matchingMessagesRows.length).toBe(
|
|
677
|
+
chatClient.activeChannels[hiddenChannel.cid].state.messages.length,
|
|
678
|
+
);
|
|
679
|
+
});
|
|
680
|
+
|
|
681
|
+
// then, we make it visible after waiting for everything to finish
|
|
682
|
+
act(() => dispatchChannelVisibleEvent(chatClient, hiddenChannel));
|
|
683
|
+
await waitFor(async () => {
|
|
684
|
+
const channelIdsOnUI = screen
|
|
685
|
+
.queryAllByLabelText('list-item')
|
|
686
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
687
|
+
expect(channelIdsOnUI.includes(hiddenChannel.cid)).toBeFalsy();
|
|
688
|
+
await expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
689
|
+
|
|
690
|
+
const channelsRows = await BetterSqlite.selectFromTable('channels');
|
|
691
|
+
const matchingRows = channelsRows.filter((c) => c.id === hiddenChannel.id);
|
|
692
|
+
|
|
693
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
694
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === hiddenChannel.cid);
|
|
695
|
+
|
|
696
|
+
expect(matchingRows.length).toBe(1);
|
|
697
|
+
expect(matchingRows[0].hidden).toBeFalsy();
|
|
698
|
+
expect(matchingMessagesRows.length).toBe(
|
|
699
|
+
chatClient.activeChannels[hiddenChannel.cid].state.messages.length,
|
|
700
|
+
);
|
|
701
|
+
});
|
|
702
|
+
});
|
|
703
|
+
|
|
444
704
|
it('should add the channel to DB when user is added as member', async () => {
|
|
445
705
|
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
446
706
|
|
|
447
707
|
renderComponent();
|
|
448
708
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
709
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
449
710
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
450
711
|
|
|
451
712
|
const newChannel = createChannel();
|
|
@@ -476,11 +737,130 @@ export const Generic = () => {
|
|
|
476
737
|
|
|
477
738
|
renderComponent();
|
|
478
739
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
740
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
479
741
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
480
742
|
|
|
481
743
|
const channelToTruncate = channels[getRandomInt(0, channels.length - 1)].channel;
|
|
482
744
|
act(() => dispatchChannelTruncatedEvent(chatClient, channelToTruncate));
|
|
483
745
|
|
|
746
|
+
await waitFor(async () => {
|
|
747
|
+
const channelIdsOnUI = screen
|
|
748
|
+
.queryAllByLabelText('list-item')
|
|
749
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
750
|
+
expect(channelIdsOnUI.includes(channelToTruncate.cid)).toBeTruthy();
|
|
751
|
+
expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
752
|
+
|
|
753
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
754
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === channelToTruncate.cid);
|
|
755
|
+
|
|
756
|
+
const readsRows = await BetterSqlite.selectFromTable('reads');
|
|
757
|
+
const matchingReadRows = readsRows.filter(
|
|
758
|
+
(r) => r.userId === chatClient.userID && r.cid === channelToTruncate.cid,
|
|
759
|
+
);
|
|
760
|
+
|
|
761
|
+
expect(matchingMessagesRows.length).toBe(0);
|
|
762
|
+
expect(matchingReadRows.length).toBe(1);
|
|
763
|
+
expect(matchingReadRows[0].unreadMessages).toBe(0);
|
|
764
|
+
});
|
|
765
|
+
});
|
|
766
|
+
|
|
767
|
+
it('should truncate the correct messages if channel.truncated arrives with truncated_at', async () => {
|
|
768
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
769
|
+
|
|
770
|
+
renderComponent();
|
|
771
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
772
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
773
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
774
|
+
|
|
775
|
+
const channelResponse = channels[getRandomInt(0, channels.length - 1)];
|
|
776
|
+
const channelToTruncate = channelResponse.channel;
|
|
777
|
+
const messages = channelResponse.messages;
|
|
778
|
+
messages.sort((a, b) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime());
|
|
779
|
+
// truncate at the middle
|
|
780
|
+
const truncatedAt = messages[Number(messages.length / 2)].created_at;
|
|
781
|
+
act(() =>
|
|
782
|
+
dispatchChannelTruncatedEvent(chatClient, {
|
|
783
|
+
...channelToTruncate,
|
|
784
|
+
truncated_at: truncatedAt,
|
|
785
|
+
}),
|
|
786
|
+
);
|
|
787
|
+
|
|
788
|
+
await waitFor(async () => {
|
|
789
|
+
const channelIdsOnUI = screen
|
|
790
|
+
.queryAllByLabelText('list-item')
|
|
791
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
792
|
+
expect(channelIdsOnUI.includes(channelToTruncate.cid)).toBeTruthy();
|
|
793
|
+
expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
794
|
+
|
|
795
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
796
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === channelToTruncate.cid);
|
|
797
|
+
|
|
798
|
+
const readsRows = await BetterSqlite.selectFromTable('reads');
|
|
799
|
+
const matchingReadRows = readsRows.filter(
|
|
800
|
+
(r) => r.userId === chatClient.userID && r.cid === channelToTruncate.cid,
|
|
801
|
+
);
|
|
802
|
+
|
|
803
|
+
const messagesLeft = messages.length / 2 - 1;
|
|
804
|
+
|
|
805
|
+
expect(matchingMessagesRows.length).toBe(messagesLeft);
|
|
806
|
+
expect(matchingReadRows.length).toBe(1);
|
|
807
|
+
expect(matchingReadRows[0].unreadMessages).toBe(messagesLeft);
|
|
808
|
+
});
|
|
809
|
+
});
|
|
810
|
+
|
|
811
|
+
it('should gracefully handle a truncated_at date before each message', async () => {
|
|
812
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
813
|
+
|
|
814
|
+
renderComponent();
|
|
815
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
816
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
817
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
818
|
+
|
|
819
|
+
const channelResponse = channels[getRandomInt(0, channels.length - 1)];
|
|
820
|
+
const channelToTruncate = channelResponse.channel;
|
|
821
|
+
const truncatedAt = new Date(0).toISOString();
|
|
822
|
+
act(() =>
|
|
823
|
+
dispatchChannelTruncatedEvent(chatClient, {
|
|
824
|
+
...channelToTruncate,
|
|
825
|
+
truncated_at: truncatedAt,
|
|
826
|
+
}),
|
|
827
|
+
);
|
|
828
|
+
|
|
829
|
+
await waitFor(async () => {
|
|
830
|
+
const channelIdsOnUI = screen
|
|
831
|
+
.queryAllByLabelText('list-item')
|
|
832
|
+
.map((node) => node._fiber.pendingProps.testID);
|
|
833
|
+
expect(channelIdsOnUI.includes(channelToTruncate.cid)).toBeTruthy();
|
|
834
|
+
expectCIDsOnUIToBeInDB(screen.queryAllByLabelText);
|
|
835
|
+
|
|
836
|
+
const messagesRows = await BetterSqlite.selectFromTable('messages');
|
|
837
|
+
const matchingMessagesRows = messagesRows.filter((m) => m.cid === channelToTruncate.cid);
|
|
838
|
+
|
|
839
|
+
expect(matchingMessagesRows.length).toBe(channelResponse.messages.length);
|
|
840
|
+
});
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
it('should gracefully handle a truncated_at date after each message', async () => {
|
|
844
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
845
|
+
|
|
846
|
+
renderComponent();
|
|
847
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
848
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
849
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
850
|
+
|
|
851
|
+
const channelResponse = channels[getRandomInt(0, channels.length - 1)];
|
|
852
|
+
const channelToTruncate = channelResponse.channel;
|
|
853
|
+
const messages = channelResponse.messages;
|
|
854
|
+
const latestTimestamp = Math.max(...messages.map((m) => new Date(m.created_at).getTime()));
|
|
855
|
+
// truncate at the middle
|
|
856
|
+
const truncatedAt = new Date(latestTimestamp + 1).toISOString();
|
|
857
|
+
act(() =>
|
|
858
|
+
dispatchChannelTruncatedEvent(chatClient, {
|
|
859
|
+
...channelToTruncate,
|
|
860
|
+
truncated_at: truncatedAt,
|
|
861
|
+
}),
|
|
862
|
+
);
|
|
863
|
+
|
|
484
864
|
await waitFor(async () => {
|
|
485
865
|
const channelIdsOnUI = screen
|
|
486
866
|
.queryAllByLabelText('list-item')
|
|
@@ -499,6 +879,7 @@ export const Generic = () => {
|
|
|
499
879
|
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
500
880
|
renderComponent();
|
|
501
881
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
882
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
502
883
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
503
884
|
|
|
504
885
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
@@ -539,11 +920,161 @@ export const Generic = () => {
|
|
|
539
920
|
});
|
|
540
921
|
});
|
|
541
922
|
|
|
923
|
+
it('should correctly add multiple reactions to the DB', async () => {
|
|
924
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
925
|
+
renderComponent();
|
|
926
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
927
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
928
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
929
|
+
|
|
930
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
931
|
+
const targetMessage =
|
|
932
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
933
|
+
const reactionMember =
|
|
934
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
935
|
+
const someOtherMember = targetChannel.members.filter(
|
|
936
|
+
(member) => reactionMember.user.id !== member.user.id,
|
|
937
|
+
)[getRandomInt(0, targetChannel.members.length - 2)];
|
|
938
|
+
|
|
939
|
+
const newReactions = [
|
|
940
|
+
generateReaction({
|
|
941
|
+
message_id: targetMessage.id,
|
|
942
|
+
type: 'wow',
|
|
943
|
+
user: reactionMember.user,
|
|
944
|
+
}),
|
|
945
|
+
generateReaction({
|
|
946
|
+
message_id: targetMessage.id,
|
|
947
|
+
type: 'wow',
|
|
948
|
+
user: someOtherMember.user,
|
|
949
|
+
}),
|
|
950
|
+
generateReaction({
|
|
951
|
+
message_id: targetMessage.id,
|
|
952
|
+
type: 'love',
|
|
953
|
+
user: reactionMember.user,
|
|
954
|
+
}),
|
|
955
|
+
];
|
|
956
|
+
const messageWithNewReactionBase = {
|
|
957
|
+
...targetMessage,
|
|
958
|
+
latest_reactions: [...targetMessage.latest_reactions],
|
|
959
|
+
};
|
|
960
|
+
const newLatestReactions = [];
|
|
961
|
+
|
|
962
|
+
newReactions.forEach((newReaction) => {
|
|
963
|
+
newLatestReactions.push(newReaction);
|
|
964
|
+
const messageWithNewReaction = {
|
|
965
|
+
...messageWithNewReactionBase,
|
|
966
|
+
latest_reactions: [...messageWithNewReactionBase.latest_reactions, ...newLatestReactions],
|
|
967
|
+
};
|
|
968
|
+
act(() =>
|
|
969
|
+
dispatchReactionNewEvent(
|
|
970
|
+
chatClient,
|
|
971
|
+
newReaction,
|
|
972
|
+
messageWithNewReaction,
|
|
973
|
+
targetChannel.channel,
|
|
974
|
+
),
|
|
975
|
+
);
|
|
976
|
+
});
|
|
977
|
+
|
|
978
|
+
const finalReactionCount =
|
|
979
|
+
messageWithNewReactionBase.latest_reactions.length +
|
|
980
|
+
newReactions.filter(
|
|
981
|
+
(newReaction) =>
|
|
982
|
+
!messageWithNewReactionBase.latest_reactions.some(
|
|
983
|
+
(initialReaction) =>
|
|
984
|
+
initialReaction.type === newReaction.type &&
|
|
985
|
+
initialReaction.user.id === newReaction.user.id,
|
|
986
|
+
),
|
|
987
|
+
).length;
|
|
988
|
+
|
|
989
|
+
await waitFor(async () => {
|
|
990
|
+
const reactionsRows = await BetterSqlite.selectFromTable('reactions');
|
|
991
|
+
const matchingReactionsRows = reactionsRows.filter(
|
|
992
|
+
(r) => r.messageId === messageWithNewReactionBase.id,
|
|
993
|
+
);
|
|
994
|
+
|
|
995
|
+
expect(matchingReactionsRows.length).toBe(finalReactionCount);
|
|
996
|
+
newReactions.forEach((newReaction) => {
|
|
997
|
+
expect(
|
|
998
|
+
matchingReactionsRows.filter(
|
|
999
|
+
(reaction) =>
|
|
1000
|
+
reaction.type === newReaction.type && reaction.userId === newReaction.user.id,
|
|
1001
|
+
).length,
|
|
1002
|
+
).toBe(1);
|
|
1003
|
+
});
|
|
1004
|
+
});
|
|
1005
|
+
});
|
|
1006
|
+
|
|
1007
|
+
it('should gracefully handle multiple reaction.new events of the same type for the same user', async () => {
|
|
1008
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1009
|
+
renderComponent();
|
|
1010
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1011
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1012
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
1013
|
+
|
|
1014
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1015
|
+
const targetMessage =
|
|
1016
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
1017
|
+
const reactionMember =
|
|
1018
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1019
|
+
|
|
1020
|
+
const newReactions = [
|
|
1021
|
+
generateReaction({
|
|
1022
|
+
message_id: targetMessage.id,
|
|
1023
|
+
type: 'wow',
|
|
1024
|
+
user: reactionMember.user,
|
|
1025
|
+
}),
|
|
1026
|
+
generateReaction({
|
|
1027
|
+
message_id: targetMessage.id,
|
|
1028
|
+
type: 'wow',
|
|
1029
|
+
user: reactionMember.user,
|
|
1030
|
+
}),
|
|
1031
|
+
generateReaction({
|
|
1032
|
+
message_id: targetMessage.id,
|
|
1033
|
+
type: 'wow',
|
|
1034
|
+
user: reactionMember.user,
|
|
1035
|
+
}),
|
|
1036
|
+
];
|
|
1037
|
+
const messageWithNewReactionBase = {
|
|
1038
|
+
...targetMessage,
|
|
1039
|
+
latest_reactions: [...targetMessage.latest_reactions],
|
|
1040
|
+
};
|
|
1041
|
+
const newLatestReactions = [];
|
|
1042
|
+
|
|
1043
|
+
newReactions.forEach((newReaction) => {
|
|
1044
|
+
newLatestReactions.push(newReaction);
|
|
1045
|
+
const messageWithNewReaction = {
|
|
1046
|
+
...messageWithNewReactionBase,
|
|
1047
|
+
latest_reactions: [...messageWithNewReactionBase.latest_reactions, ...newLatestReactions],
|
|
1048
|
+
};
|
|
1049
|
+
act(() =>
|
|
1050
|
+
dispatchReactionNewEvent(
|
|
1051
|
+
chatClient,
|
|
1052
|
+
newReaction,
|
|
1053
|
+
messageWithNewReaction,
|
|
1054
|
+
targetChannel.channel,
|
|
1055
|
+
),
|
|
1056
|
+
);
|
|
1057
|
+
});
|
|
1058
|
+
|
|
1059
|
+
await waitFor(async () => {
|
|
1060
|
+
const reactionsRows = await BetterSqlite.selectFromTable('reactions');
|
|
1061
|
+
const matchingReactionsRows = reactionsRows.filter(
|
|
1062
|
+
(r) =>
|
|
1063
|
+
r.type === 'wow' &&
|
|
1064
|
+
r.userId === reactionMember.user.id &&
|
|
1065
|
+
r.messageId === messageWithNewReactionBase.id,
|
|
1066
|
+
);
|
|
1067
|
+
|
|
1068
|
+
expect(matchingReactionsRows.length).toBe(1);
|
|
1069
|
+
});
|
|
1070
|
+
});
|
|
1071
|
+
|
|
542
1072
|
it('should remove a reaction from DB when reaction is deleted', async () => {
|
|
543
1073
|
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
544
1074
|
|
|
545
1075
|
renderComponent();
|
|
546
1076
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1077
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
547
1078
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
548
1079
|
|
|
549
1080
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
@@ -597,6 +1128,7 @@ export const Generic = () => {
|
|
|
597
1128
|
|
|
598
1129
|
renderComponent();
|
|
599
1130
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1131
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
600
1132
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
601
1133
|
|
|
602
1134
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
@@ -629,24 +1161,301 @@ export const Generic = () => {
|
|
|
629
1161
|
});
|
|
630
1162
|
});
|
|
631
1163
|
|
|
632
|
-
it('should
|
|
1164
|
+
it('should correctly upsert reactions when enforce_unique is true', async () => {
|
|
633
1165
|
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1166
|
+
renderComponent();
|
|
1167
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1168
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1169
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
634
1170
|
|
|
1171
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1172
|
+
const targetMessage =
|
|
1173
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
1174
|
+
const reactionMember =
|
|
1175
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1176
|
+
|
|
1177
|
+
const newReactions = [
|
|
1178
|
+
generateReaction({
|
|
1179
|
+
message_id: targetMessage.id,
|
|
1180
|
+
type: 'wow',
|
|
1181
|
+
user: reactionMember.user,
|
|
1182
|
+
}),
|
|
1183
|
+
generateReaction({
|
|
1184
|
+
message_id: targetMessage.id,
|
|
1185
|
+
type: 'love',
|
|
1186
|
+
user: reactionMember.user,
|
|
1187
|
+
}),
|
|
1188
|
+
];
|
|
1189
|
+
const messageWithNewReactionBase = {
|
|
1190
|
+
...targetMessage,
|
|
1191
|
+
latest_reactions: [...targetMessage.latest_reactions],
|
|
1192
|
+
};
|
|
1193
|
+
const newLatestReactions = [];
|
|
1194
|
+
|
|
1195
|
+
newReactions.forEach((newReaction) => {
|
|
1196
|
+
newLatestReactions.push(newReaction);
|
|
1197
|
+
const messageWithNewReaction = {
|
|
1198
|
+
...messageWithNewReactionBase,
|
|
1199
|
+
latest_reactions: [...messageWithNewReactionBase.latest_reactions, ...newLatestReactions],
|
|
1200
|
+
};
|
|
1201
|
+
act(() =>
|
|
1202
|
+
dispatchReactionNewEvent(
|
|
1203
|
+
chatClient,
|
|
1204
|
+
newReaction,
|
|
1205
|
+
messageWithNewReaction,
|
|
1206
|
+
targetChannel.channel,
|
|
1207
|
+
),
|
|
1208
|
+
);
|
|
1209
|
+
});
|
|
1210
|
+
|
|
1211
|
+
await waitFor(async () => {
|
|
1212
|
+
const reactionsRows = await BetterSqlite.selectFromTable('reactions');
|
|
1213
|
+
const matchingReactionsRows = reactionsRows.filter(
|
|
1214
|
+
(r) =>
|
|
1215
|
+
r.messageId === messageWithNewReactionBase.id && r.userId === reactionMember.user.id,
|
|
1216
|
+
);
|
|
1217
|
+
|
|
1218
|
+
expect(matchingReactionsRows.length).toBe(2);
|
|
1219
|
+
newReactions.forEach((newReaction) => {
|
|
1220
|
+
expect(
|
|
1221
|
+
matchingReactionsRows.filter(
|
|
1222
|
+
(reaction) =>
|
|
1223
|
+
reaction.type === newReaction.type && reaction.userId === newReaction.user.id,
|
|
1224
|
+
).length,
|
|
1225
|
+
).toBe(1);
|
|
1226
|
+
});
|
|
1227
|
+
});
|
|
1228
|
+
|
|
1229
|
+
const uniqueReaction = generateReaction({
|
|
1230
|
+
message_id: targetMessage.id,
|
|
1231
|
+
type: 'like',
|
|
1232
|
+
user: reactionMember.user,
|
|
1233
|
+
});
|
|
1234
|
+
const messageWithNewReaction = {
|
|
1235
|
+
...targetMessage,
|
|
1236
|
+
latest_reactions: [...targetMessage.latest_reactions, uniqueReaction],
|
|
1237
|
+
};
|
|
1238
|
+
|
|
1239
|
+
act(() =>
|
|
1240
|
+
dispatchReactionUpdatedEvent(
|
|
1241
|
+
chatClient,
|
|
1242
|
+
uniqueReaction,
|
|
1243
|
+
messageWithNewReaction,
|
|
1244
|
+
targetChannel.channel,
|
|
1245
|
+
),
|
|
1246
|
+
);
|
|
1247
|
+
|
|
1248
|
+
await waitFor(async () => {
|
|
1249
|
+
const reactionsRows = await BetterSqlite.selectFromTable('reactions');
|
|
1250
|
+
const matchingReactionsRows = reactionsRows.filter(
|
|
1251
|
+
(r) =>
|
|
1252
|
+
r.type === uniqueReaction.type &&
|
|
1253
|
+
r.userId === reactionMember.user.id &&
|
|
1254
|
+
r.messageId === messageWithNewReaction.id,
|
|
1255
|
+
);
|
|
1256
|
+
|
|
1257
|
+
expect(matchingReactionsRows.length).toBe(1);
|
|
1258
|
+
});
|
|
1259
|
+
});
|
|
1260
|
+
|
|
1261
|
+
it('should also update the corresponding message.reaction_groups with reaction.new', async () => {
|
|
1262
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
635
1263
|
renderComponent();
|
|
636
1264
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1265
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
637
1266
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
638
1267
|
|
|
639
1268
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1269
|
+
const targetMessage =
|
|
1270
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
1271
|
+
const reactionMember =
|
|
1272
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1273
|
+
|
|
1274
|
+
const newReaction = generateReaction({
|
|
1275
|
+
message_id: targetMessage.id,
|
|
1276
|
+
type: 'wow',
|
|
1277
|
+
user: reactionMember.user,
|
|
1278
|
+
});
|
|
1279
|
+
const newDate = new Date().toISOString();
|
|
1280
|
+
// the actual content of the reaction_groups does not matter, as we just want to know if it updates to it
|
|
1281
|
+
// anything impossible given the scenarios is fine
|
|
1282
|
+
const messageWithNewReaction = {
|
|
1283
|
+
...targetMessage,
|
|
1284
|
+
latest_reactions: [...targetMessage.latest_reactions, newReaction],
|
|
1285
|
+
reaction_groups: {
|
|
1286
|
+
...targetMessage.reaction_groups,
|
|
1287
|
+
[newReaction.type]: {
|
|
1288
|
+
count: 999,
|
|
1289
|
+
first_reaction_at: newDate,
|
|
1290
|
+
last_reaction_at: newDate,
|
|
1291
|
+
sum_scores: 999,
|
|
1292
|
+
},
|
|
1293
|
+
},
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
act(() =>
|
|
1297
|
+
dispatchReactionNewEvent(
|
|
1298
|
+
chatClient,
|
|
1299
|
+
newReaction,
|
|
1300
|
+
messageWithNewReaction,
|
|
1301
|
+
targetChannel.channel,
|
|
1302
|
+
),
|
|
1303
|
+
);
|
|
1304
|
+
|
|
1305
|
+
await waitFor(async () => {
|
|
1306
|
+
const messageRows = await BetterSqlite.selectFromTable('messages');
|
|
1307
|
+
const messageWithReactionRow = messageRows.filter(
|
|
1308
|
+
(m) => m.id === messageWithNewReaction.id,
|
|
1309
|
+
)[0];
|
|
1310
|
+
|
|
1311
|
+
const reactionGroups = JSON.parse(messageWithReactionRow.reactionGroups);
|
|
1312
|
+
|
|
1313
|
+
expect(reactionGroups[newReaction.type]?.count).toBe(999);
|
|
1314
|
+
expect(reactionGroups[newReaction.type]?.sum_scores).toBe(999);
|
|
1315
|
+
expect(reactionGroups[newReaction.type]?.first_reaction_at).toBe(newDate);
|
|
1316
|
+
expect(reactionGroups[newReaction.type]?.last_reaction_at).toBe(newDate);
|
|
1317
|
+
});
|
|
1318
|
+
});
|
|
1319
|
+
|
|
1320
|
+
it('should also update the corresponding message.reaction_groups with reaction.updated', async () => {
|
|
1321
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1322
|
+
renderComponent();
|
|
1323
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1324
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1325
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
1326
|
+
|
|
1327
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1328
|
+
const targetMessage =
|
|
1329
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
1330
|
+
const reactionMember =
|
|
1331
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1332
|
+
|
|
1333
|
+
const newReaction = generateReaction({
|
|
1334
|
+
message_id: targetMessage.id,
|
|
1335
|
+
type: 'wow',
|
|
1336
|
+
user: reactionMember.user,
|
|
1337
|
+
});
|
|
1338
|
+
const newDate = new Date().toISOString();
|
|
1339
|
+
const messageWithNewReaction = {
|
|
1340
|
+
...targetMessage,
|
|
1341
|
+
latest_reactions: [...targetMessage.latest_reactions, newReaction],
|
|
1342
|
+
reaction_groups: {
|
|
1343
|
+
...targetMessage.reaction_groups,
|
|
1344
|
+
[newReaction.type]: {
|
|
1345
|
+
count: 999,
|
|
1346
|
+
first_reaction_at: newDate,
|
|
1347
|
+
last_reaction_at: newDate,
|
|
1348
|
+
sum_scores: 999,
|
|
1349
|
+
},
|
|
1350
|
+
},
|
|
1351
|
+
};
|
|
1352
|
+
|
|
1353
|
+
act(() =>
|
|
1354
|
+
dispatchReactionUpdatedEvent(
|
|
1355
|
+
chatClient,
|
|
1356
|
+
newReaction,
|
|
1357
|
+
messageWithNewReaction,
|
|
1358
|
+
targetChannel.channel,
|
|
1359
|
+
),
|
|
1360
|
+
);
|
|
1361
|
+
|
|
1362
|
+
await waitFor(async () => {
|
|
1363
|
+
const messageRows = await BetterSqlite.selectFromTable('messages');
|
|
1364
|
+
const messageWithReactionRow = messageRows.filter(
|
|
1365
|
+
(m) => m.id === messageWithNewReaction.id,
|
|
1366
|
+
)[0];
|
|
1367
|
+
|
|
1368
|
+
const reactionGroups = JSON.parse(messageWithReactionRow.reactionGroups);
|
|
1369
|
+
|
|
1370
|
+
expect(reactionGroups[newReaction.type]?.count).toBe(999);
|
|
1371
|
+
expect(reactionGroups[newReaction.type]?.sum_scores).toBe(999);
|
|
1372
|
+
expect(reactionGroups[newReaction.type]?.first_reaction_at).toBe(newDate);
|
|
1373
|
+
expect(reactionGroups[newReaction.type]?.last_reaction_at).toBe(newDate);
|
|
1374
|
+
});
|
|
1375
|
+
});
|
|
1376
|
+
|
|
1377
|
+
it('should also update the corresponding message.reaction_groups with reaction.deleted', async () => {
|
|
1378
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1379
|
+
renderComponent();
|
|
1380
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1381
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1382
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
1383
|
+
|
|
1384
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1385
|
+
const targetMessage =
|
|
1386
|
+
targetChannel.messages[getRandomInt(0, targetChannel.messages.length - 1)];
|
|
1387
|
+
const reactionMember =
|
|
1388
|
+
targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1389
|
+
|
|
1390
|
+
const newReaction = generateReaction({
|
|
1391
|
+
message_id: targetMessage.id,
|
|
1392
|
+
type: 'wow',
|
|
1393
|
+
user: reactionMember.user,
|
|
1394
|
+
});
|
|
1395
|
+
const newDate = new Date().toISOString();
|
|
1396
|
+
const messageWithNewReaction = {
|
|
1397
|
+
...targetMessage,
|
|
1398
|
+
latest_reactions: [...targetMessage.latest_reactions, newReaction],
|
|
1399
|
+
reaction_groups: {
|
|
1400
|
+
...targetMessage.reaction_groups,
|
|
1401
|
+
[newReaction.type]: {
|
|
1402
|
+
count: 999,
|
|
1403
|
+
first_reaction_at: newDate,
|
|
1404
|
+
last_reaction_at: newDate,
|
|
1405
|
+
sum_scores: 999,
|
|
1406
|
+
},
|
|
1407
|
+
},
|
|
1408
|
+
};
|
|
1409
|
+
|
|
1410
|
+
act(() =>
|
|
1411
|
+
dispatchReactionDeletedEvent(
|
|
1412
|
+
chatClient,
|
|
1413
|
+
newReaction,
|
|
1414
|
+
messageWithNewReaction,
|
|
1415
|
+
targetChannel.channel,
|
|
1416
|
+
),
|
|
1417
|
+
);
|
|
1418
|
+
|
|
1419
|
+
await waitFor(async () => {
|
|
1420
|
+
const messageRows = await BetterSqlite.selectFromTable('messages');
|
|
1421
|
+
const messageWithReactionRow = messageRows.filter(
|
|
1422
|
+
(m) => m.id === messageWithNewReaction.id,
|
|
1423
|
+
)[0];
|
|
1424
|
+
|
|
1425
|
+
const reactionGroups = JSON.parse(messageWithReactionRow.reactionGroups);
|
|
1426
|
+
|
|
1427
|
+
expect(reactionGroups[newReaction.type]?.count).toBe(999);
|
|
1428
|
+
expect(reactionGroups[newReaction.type]?.sum_scores).toBe(999);
|
|
1429
|
+
expect(reactionGroups[newReaction.type]?.first_reaction_at).toBe(newDate);
|
|
1430
|
+
expect(reactionGroups[newReaction.type]?.last_reaction_at).toBe(newDate);
|
|
1431
|
+
});
|
|
1432
|
+
});
|
|
1433
|
+
|
|
1434
|
+
it('should add a member to DB when a new member is added to channel', async () => {
|
|
1435
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1436
|
+
renderComponent();
|
|
1437
|
+
|
|
1438
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1439
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1440
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
1441
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1442
|
+
|
|
1443
|
+
const oldMemberCount = targetChannel.channel.member_count;
|
|
640
1444
|
const newMember = generateMember();
|
|
641
1445
|
act(() => dispatchMemberAddedEvent(chatClient, newMember, targetChannel.channel));
|
|
642
1446
|
|
|
643
1447
|
await waitFor(async () => {
|
|
644
1448
|
const membersRows = await BetterSqlite.selectFromTable('members');
|
|
1449
|
+
const channelRows = await BetterSqlite.selectFromTable('channels');
|
|
645
1450
|
const matchingMembersRows = membersRows.filter(
|
|
646
1451
|
(m) => m.cid === targetChannel.channel.cid && m.userId === newMember.user_id,
|
|
647
1452
|
);
|
|
1453
|
+
const targetChannelFromDb = channelRows.filter(
|
|
1454
|
+
(c) => c.cid === targetChannel.channel.cid,
|
|
1455
|
+
)[0];
|
|
648
1456
|
|
|
649
1457
|
expect(matchingMembersRows.length).toBe(1);
|
|
1458
|
+
expect(targetChannelFromDb.memberCount).toBe(oldMemberCount + 1);
|
|
650
1459
|
});
|
|
651
1460
|
});
|
|
652
1461
|
|
|
@@ -655,19 +1464,26 @@ export const Generic = () => {
|
|
|
655
1464
|
|
|
656
1465
|
renderComponent();
|
|
657
1466
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1467
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
658
1468
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
659
1469
|
|
|
660
1470
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
661
1471
|
const targetMember = targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1472
|
+
const oldMemberCount = targetChannel.channel.member_count;
|
|
662
1473
|
act(() => dispatchMemberRemovedEvent(chatClient, targetMember, targetChannel.channel));
|
|
663
1474
|
|
|
664
1475
|
await waitFor(async () => {
|
|
665
1476
|
const membersRows = await BetterSqlite.selectFromTable('members');
|
|
1477
|
+
const channelRows = await BetterSqlite.selectFromTable('channels');
|
|
666
1478
|
const matchingMembersRows = membersRows.filter(
|
|
667
1479
|
(m) => m.cid === targetChannel.channel.cid && m.userId === targetMember.user_id,
|
|
668
1480
|
);
|
|
1481
|
+
const targetChannelFromDb = channelRows.filter(
|
|
1482
|
+
(c) => c.cid === targetChannel.channel.cid,
|
|
1483
|
+
)[0];
|
|
669
1484
|
|
|
670
1485
|
expect(matchingMembersRows.length).toBe(0);
|
|
1486
|
+
expect(targetChannelFromDb.memberCount).toBe(oldMemberCount - 1);
|
|
671
1487
|
});
|
|
672
1488
|
});
|
|
673
1489
|
|
|
@@ -676,6 +1492,7 @@ export const Generic = () => {
|
|
|
676
1492
|
|
|
677
1493
|
renderComponent();
|
|
678
1494
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1495
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
679
1496
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
680
1497
|
|
|
681
1498
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
@@ -702,6 +1519,7 @@ export const Generic = () => {
|
|
|
702
1519
|
|
|
703
1520
|
renderComponent();
|
|
704
1521
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1522
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
705
1523
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
706
1524
|
|
|
707
1525
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
@@ -727,12 +1545,19 @@ export const Generic = () => {
|
|
|
727
1545
|
|
|
728
1546
|
renderComponent();
|
|
729
1547
|
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1548
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
730
1549
|
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
731
1550
|
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
732
1551
|
const targetMember = targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
733
1552
|
|
|
1553
|
+
const readTimestamp = new Date().toISOString();
|
|
1554
|
+
|
|
734
1555
|
act(() => {
|
|
735
|
-
dispatchMessageReadEvent(chatClient, targetMember.user, targetChannel.channel
|
|
1556
|
+
dispatchMessageReadEvent(chatClient, targetMember.user, targetChannel.channel, {
|
|
1557
|
+
first_unread_message_id: '123',
|
|
1558
|
+
last_read: readTimestamp,
|
|
1559
|
+
last_read_message_id: '321',
|
|
1560
|
+
});
|
|
736
1561
|
});
|
|
737
1562
|
|
|
738
1563
|
await waitFor(async () => {
|
|
@@ -743,6 +1568,54 @@ export const Generic = () => {
|
|
|
743
1568
|
|
|
744
1569
|
expect(matchingReadRows.length).toBe(1);
|
|
745
1570
|
expect(matchingReadRows[0].unreadMessages).toBe(0);
|
|
1571
|
+
expect(matchingReadRows[0].lastReadMessageId).toBe('321');
|
|
1572
|
+
// FIXME: Currently missing from the DB, uncomment when added.
|
|
1573
|
+
// expect(matchingReadRows[0].firstUnreadMessageId).toBe('123');
|
|
1574
|
+
expect(matchingReadRows[0].lastRead).toBe(readTimestamp);
|
|
1575
|
+
});
|
|
1576
|
+
});
|
|
1577
|
+
|
|
1578
|
+
it('should update reads in DB when a channel is marked as unread', async () => {
|
|
1579
|
+
useMockedApis(chatClient, [queryChannelsApi(channels)]);
|
|
1580
|
+
|
|
1581
|
+
renderComponent();
|
|
1582
|
+
act(() => dispatchConnectionChangedEvent(chatClient));
|
|
1583
|
+
await act(async () => await chatClient.offlineDb.syncManager.invokeSyncStatusListeners(true));
|
|
1584
|
+
await waitFor(() => expect(screen.getByTestId('channel-list')).toBeTruthy());
|
|
1585
|
+
const targetChannel = channels[getRandomInt(0, channels.length - 1)];
|
|
1586
|
+
const targetMember = targetChannel.members[getRandomInt(0, targetChannel.members.length - 1)];
|
|
1587
|
+
|
|
1588
|
+
chatClient.userID = targetMember.user.id;
|
|
1589
|
+
chatClient.user = targetMember.user;
|
|
1590
|
+
|
|
1591
|
+
const readTimestamp = new Date().toISOString();
|
|
1592
|
+
|
|
1593
|
+
act(() => {
|
|
1594
|
+
dispatchNotificationMarkUnread(
|
|
1595
|
+
chatClient,
|
|
1596
|
+
targetChannel.channel,
|
|
1597
|
+
{
|
|
1598
|
+
first_unread_message_id: '123',
|
|
1599
|
+
last_read: readTimestamp,
|
|
1600
|
+
last_read_message_id: '321',
|
|
1601
|
+
unread_messages: 5,
|
|
1602
|
+
},
|
|
1603
|
+
targetMember.user,
|
|
1604
|
+
);
|
|
1605
|
+
});
|
|
1606
|
+
|
|
1607
|
+
await waitFor(async () => {
|
|
1608
|
+
const readsRows = await BetterSqlite.selectFromTable('reads');
|
|
1609
|
+
const matchingReadRows = readsRows.filter(
|
|
1610
|
+
(r) => r.userId === targetMember.user_id && r.cid === targetChannel.cid,
|
|
1611
|
+
);
|
|
1612
|
+
|
|
1613
|
+
expect(matchingReadRows.length).toBe(1);
|
|
1614
|
+
expect(matchingReadRows[0].unreadMessages).toBe(5);
|
|
1615
|
+
expect(matchingReadRows[0].lastReadMessageId).toBe('321');
|
|
1616
|
+
// FIXME: Currently missing from the DB, uncomment when added.
|
|
1617
|
+
// expect(matchingReadRows[0].firstUnreadMessageId).toBe('123');
|
|
1618
|
+
expect(matchingReadRows[0].lastRead).toBe(readTimestamp);
|
|
746
1619
|
});
|
|
747
1620
|
});
|
|
748
1621
|
});
|