@ethora/chat-component-rn 26.9.1 → 26.10.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/CHANGELOG.md +30 -0
- package/README.md +19 -0
- package/lib/commonjs/assets/icons.js +2 -2
- package/lib/commonjs/assets/icons.js.map +1 -1
- package/lib/commonjs/components/Header/HeaderRoomList.js +22 -6
- package/lib/commonjs/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/commonjs/components/InputComponents/Search.js +38 -1
- package/lib/commonjs/components/InputComponents/Search.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ArchivedMessageCard.js +166 -0
- package/lib/commonjs/components/MainComponents/ArchivedMessageCard.js.map +1 -0
- package/lib/commonjs/components/MainComponents/ChatHeader.js +22 -5
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatRoom.js +56 -25
- package/lib/commonjs/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +31 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MediaMessage.js +18 -3
- package/lib/commonjs/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageList.js +739 -42
- package/lib/commonjs/components/MainComponents/MessageList.js.map +1 -1
- package/lib/commonjs/components/MainComponents/MessageSearchButton.js +58 -0
- package/lib/commonjs/components/MainComponents/MessageSearchButton.js.map +1 -0
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js +15 -6
- package/lib/commonjs/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/RoomList.js +110 -1
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js +14 -3
- package/lib/commonjs/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/BubbleHighlight.js +112 -0
- package/lib/commonjs/components/MessageBubble/BubbleHighlight.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/Message.js +169 -125
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js +98 -78
- package/lib/commonjs/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/messageMenuLayout.js +50 -0
- package/lib/commonjs/components/MessageBubble/messageMenuLayout.js.map +1 -0
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js +73 -37
- package/lib/commonjs/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/commonjs/components/Modals/MessageSearchModal/MessageHitResults.js +253 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/MessageHitResults.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/MessageSearchModal.js +488 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/MessageSearchModal.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/openHit.js +51 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/openHit.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/resolveSender.js +47 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/resolveSender.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/searchFilters.js +83 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/searchFilters.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/snippet.js +61 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/snippet.js.map +1 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/useMessageSearch.js +136 -0
- package/lib/commonjs/components/Modals/MessageSearchModal/useMessageSearch.js.map +1 -0
- package/lib/commonjs/components/Modals/PublicChatsModal/PublicChatsModal.js +306 -0
- package/lib/commonjs/components/Modals/PublicChatsModal/PublicChatsModal.js.map +1 -0
- package/lib/commonjs/components/Modals/PublicChatsModal/publicChatsLogic.js +36 -0
- package/lib/commonjs/components/Modals/PublicChatsModal/publicChatsLogic.js.map +1 -0
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js +8 -1
- package/lib/commonjs/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js +13 -2
- package/lib/commonjs/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js +38 -6
- package/lib/commonjs/components/RoomComponents/SwipeableRoomRow.js.map +1 -1
- package/lib/commonjs/components/Thread/ThreadHeader.js +3 -1
- package/lib/commonjs/components/Thread/ThreadHeader.js.map +1 -1
- package/lib/commonjs/components/Thread/ThreadWrapper.js +90 -10
- package/lib/commonjs/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/commonjs/components/styled/AudioDecoderHost.js +338 -0
- package/lib/commonjs/components/styled/AudioDecoderHost.js.map +1 -0
- package/lib/commonjs/components/styled/AudioMessage.js +493 -420
- package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +31 -5
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/context/MessageNotificationContext.js +14 -4
- package/lib/commonjs/context/MessageNotificationContext.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +41 -77
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/audioWaveform.js +165 -0
- package/lib/commonjs/helpers/audioWaveform.js.map +1 -0
- package/lib/commonjs/helpers/backgroundJoinSweep.js +36 -0
- package/lib/commonjs/helpers/backgroundJoinSweep.js.map +1 -0
- package/lib/commonjs/helpers/bubbleHighlight.js +44 -0
- package/lib/commonjs/helpers/bubbleHighlight.js.map +1 -0
- package/lib/commonjs/helpers/checkUniqueUsers.js +14 -12
- package/lib/commonjs/helpers/checkUniqueUsers.js.map +1 -1
- package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js +5 -1
- package/lib/commonjs/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
- package/lib/commonjs/helpers/constants/MODAL_TYPES.js +3 -1
- package/lib/commonjs/helpers/constants/MODAL_TYPES.js.map +1 -1
- package/lib/commonjs/helpers/createRoomFromApi.js +40 -3
- package/lib/commonjs/helpers/createRoomFromApi.js.map +1 -1
- package/lib/commonjs/helpers/dedupeMembers.js +34 -0
- package/lib/commonjs/helpers/dedupeMembers.js.map +1 -0
- package/lib/commonjs/helpers/ethoraLogger.js +56 -0
- package/lib/commonjs/helpers/ethoraLogger.js.map +1 -0
- package/lib/commonjs/helpers/getUnnamedUsers.js +9 -4
- package/lib/commonjs/helpers/getUnnamedUsers.js.map +1 -1
- package/lib/commonjs/helpers/historyPreloadConfig.js +44 -0
- package/lib/commonjs/helpers/historyPreloadConfig.js.map +1 -0
- package/lib/commonjs/helpers/historyPreloadScheduler.js +372 -137
- package/lib/commonjs/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/commonjs/helpers/initRoomsPresence.js +17 -5
- package/lib/commonjs/helpers/initRoomsPresence.js.map +1 -1
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js +5 -0
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/commonjs/helpers/isLikelyMucJid.js +67 -0
- package/lib/commonjs/helpers/isLikelyMucJid.js.map +1 -0
- package/lib/commonjs/helpers/isMessageSearchEnabled.js +18 -0
- package/lib/commonjs/helpers/isMessageSearchEnabled.js.map +1 -0
- package/lib/commonjs/helpers/joiningRoom.js +14 -0
- package/lib/commonjs/helpers/joiningRoom.js.map +1 -0
- package/lib/commonjs/helpers/jumpThread.js +100 -0
- package/lib/commonjs/helpers/jumpThread.js.map +1 -0
- package/lib/commonjs/helpers/jumpToMessage.js +58 -0
- package/lib/commonjs/helpers/jumpToMessage.js.map +1 -0
- package/lib/commonjs/helpers/jumpWindow.js +187 -0
- package/lib/commonjs/helpers/jumpWindow.js.map +1 -0
- package/lib/commonjs/helpers/loadRoomHistory.js +75 -0
- package/lib/commonjs/helpers/loadRoomHistory.js.map +1 -0
- package/lib/commonjs/helpers/notificationPolicy.js +77 -0
- package/lib/commonjs/helpers/notificationPolicy.js.map +1 -0
- package/lib/commonjs/helpers/openRoomAtMessage.js +47 -0
- package/lib/commonjs/helpers/openRoomAtMessage.js.map +1 -0
- package/lib/commonjs/helpers/openThreadForJump.js +72 -0
- package/lib/commonjs/helpers/openThreadForJump.js.map +1 -0
- package/lib/commonjs/helpers/parseMessageReference.js +27 -8
- package/lib/commonjs/helpers/parseMessageReference.js.map +1 -1
- package/lib/commonjs/helpers/publicChatsEntry.js +17 -0
- package/lib/commonjs/helpers/publicChatsEntry.js.map +1 -0
- package/lib/commonjs/helpers/roomActivityScore.js +37 -0
- package/lib/commonjs/helpers/roomActivityScore.js.map +1 -0
- package/lib/commonjs/helpers/roomUserCount.js +36 -0
- package/lib/commonjs/helpers/roomUserCount.js.map +1 -0
- package/lib/commonjs/helpers/runConfiguredHistoryPreload.js +68 -0
- package/lib/commonjs/helpers/runConfiguredHistoryPreload.js.map +1 -0
- package/lib/commonjs/helpers/sessionAppId.js +24 -0
- package/lib/commonjs/helpers/sessionAppId.js.map +1 -0
- package/lib/commonjs/helpers/timestamp.js +43 -0
- package/lib/commonjs/helpers/timestamp.js.map +1 -0
- package/lib/commonjs/helpers/userResolver.js +517 -0
- package/lib/commonjs/helpers/userResolver.js.map +1 -0
- package/lib/commonjs/helpers/xmppIdShape.js +52 -0
- package/lib/commonjs/helpers/xmppIdShape.js.map +1 -0
- package/lib/commonjs/hooks/useChatWrapperInit.js +27 -5
- package/lib/commonjs/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/commonjs/hooks/useHeapSender.js +54 -3
- package/lib/commonjs/hooks/useHeapSender.js.map +1 -1
- package/lib/commonjs/hooks/useJumpToMessage.js +411 -0
- package/lib/commonjs/hooks/useJumpToMessage.js.map +1 -0
- package/lib/commonjs/hooks/useMessageLoaderQueue.js +32 -5
- package/lib/commonjs/hooks/useMessageLoaderQueue.js.map +1 -1
- package/lib/commonjs/hooks/useMessageQueue.js +13 -5
- package/lib/commonjs/hooks/useMessageQueue.js.map +1 -1
- package/lib/commonjs/hooks/useRoomDirectory.js +29 -0
- package/lib/commonjs/hooks/useRoomDirectory.js.map +1 -0
- package/lib/commonjs/hooks/useRoomInitialization.js +27 -5
- package/lib/commonjs/hooks/useRoomInitialization.js.map +1 -1
- package/lib/commonjs/hooks/useRoomMute.js +62 -0
- package/lib/commonjs/hooks/useRoomMute.js.map +1 -0
- package/lib/commonjs/hooks/useRoomState.js +3 -1
- package/lib/commonjs/hooks/useRoomState.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +13 -3
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/i18n/strings.js +288 -6
- package/lib/commonjs/i18n/strings.js.map +1 -1
- package/lib/commonjs/networking/api-requests/messageSearch.api.js +87 -0
- package/lib/commonjs/networking/api-requests/messageSearch.api.js.map +1 -0
- package/lib/commonjs/networking/api-requests/publicChats.api.js +48 -0
- package/lib/commonjs/networking/api-requests/publicChats.api.js.map +1 -0
- package/lib/commonjs/networking/api-requests/roomMembers.api.js +253 -4
- package/lib/commonjs/networking/api-requests/roomMembers.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/rooms.api.js +48 -12
- package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/xmppToken.api.js +71 -0
- package/lib/commonjs/networking/api-requests/xmppToken.api.js.map +1 -0
- package/lib/commonjs/networking/ethoraEvents.js +227 -0
- package/lib/commonjs/networking/ethoraEvents.js.map +1 -0
- package/lib/commonjs/networking/stanzaHandlers.js +153 -16
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmpp/allRoomPresences.xmpp.js +124 -3
- package/lib/commonjs/networking/xmpp/allRoomPresences.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/getHistory.xmpp.js +319 -35
- package/lib/commonjs/networking/xmpp/getHistory.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +7 -0
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/historyCursor.js +101 -0
- package/lib/commonjs/networking/xmpp/historyCursor.js.map +1 -0
- package/lib/commonjs/networking/xmpp/mamQueryIds.js +17 -0
- package/lib/commonjs/networking/xmpp/mamQueryIds.js.map +1 -0
- package/lib/commonjs/networking/xmpp/mamRouter.js +24 -9
- package/lib/commonjs/networking/xmpp/mamRouter.js.map +1 -1
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js +70 -65
- package/lib/commonjs/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/roomJoinSweep.js +389 -0
- package/lib/commonjs/networking/xmpp/roomJoinSweep.js.map +1 -0
- package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js +0 -1
- package/lib/commonjs/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +0 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +0 -1
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +269 -41
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/networking/xmppCredentials.js +80 -0
- package/lib/commonjs/networking/xmppCredentials.js.map +1 -0
- package/lib/commonjs/roomStore/Middleware/jumpThreadMiddleware.js +158 -0
- package/lib/commonjs/roomStore/Middleware/jumpThreadMiddleware.js.map +1 -0
- package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js +6 -0
- package/lib/commonjs/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js +45 -7
- package/lib/commonjs/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js +15 -1
- package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/commonjs/roomStore/index.js +13 -3
- package/lib/commonjs/roomStore/index.js.map +1 -1
- package/lib/commonjs/roomStore/persistence.js +48 -1
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +474 -60
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/roomStore/safeKey.js +44 -0
- package/lib/commonjs/roomStore/safeKey.js.map +1 -0
- package/lib/commonjs/roomStore/usersSetCap.js +37 -0
- package/lib/commonjs/roomStore/usersSetCap.js.map +1 -0
- package/lib/commonjs/version.js +1 -1
- package/lib/commonjs/version.js.map +1 -1
- package/lib/module/assets/icons.js +1 -1
- package/lib/module/assets/icons.js.map +1 -1
- package/lib/module/components/Header/HeaderRoomList.js +23 -7
- package/lib/module/components/Header/HeaderRoomList.js.map +1 -1
- package/lib/module/components/InputComponents/Search.js +39 -2
- package/lib/module/components/InputComponents/Search.js.map +1 -1
- package/lib/module/components/MainComponents/ArchivedMessageCard.js +161 -0
- package/lib/module/components/MainComponents/ArchivedMessageCard.js.map +1 -0
- package/lib/module/components/MainComponents/ChatHeader.js +22 -5
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatRoom.js +57 -26
- package/lib/module/components/MainComponents/ChatRoom.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +31 -1
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/MediaMessage.js +18 -3
- package/lib/module/components/MainComponents/MediaMessage.js.map +1 -1
- package/lib/module/components/MainComponents/MessageList.js +740 -42
- package/lib/module/components/MainComponents/MessageList.js.map +1 -1
- package/lib/module/components/MainComponents/MessageSearchButton.js +48 -0
- package/lib/module/components/MainComponents/MessageSearchButton.js.map +1 -0
- package/lib/module/components/MainComponents/ReduxWrapper.js +15 -7
- package/lib/module/components/MainComponents/ReduxWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/RoomList.js +111 -2
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/Menu/HeaderRoomListMenu.js +15 -4
- package/lib/module/components/Menu/HeaderRoomListMenu.js.map +1 -1
- package/lib/module/components/MessageBubble/BubbleHighlight.js +106 -0
- package/lib/module/components/MessageBubble/BubbleHighlight.js.map +1 -0
- package/lib/module/components/MessageBubble/Message.js +172 -127
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageInteractions.js +98 -78
- package/lib/module/components/MessageBubble/MessageInteractions.js.map +1 -1
- package/lib/module/components/MessageBubble/messageMenuLayout.js +45 -0
- package/lib/module/components/MessageBubble/messageMenuLayout.js.map +1 -0
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js +74 -38
- package/lib/module/components/Modals/ChatProfileModal/ChatProfileModal.js.map +1 -1
- package/lib/module/components/Modals/MessageSearchModal/MessageHitResults.js +243 -0
- package/lib/module/components/Modals/MessageSearchModal/MessageHitResults.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/MessageSearchModal.js +482 -0
- package/lib/module/components/Modals/MessageSearchModal/MessageSearchModal.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/openHit.js +45 -0
- package/lib/module/components/Modals/MessageSearchModal/openHit.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/resolveSender.js +41 -0
- package/lib/module/components/Modals/MessageSearchModal/resolveSender.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/searchFilters.js +74 -0
- package/lib/module/components/Modals/MessageSearchModal/searchFilters.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/snippet.js +57 -0
- package/lib/module/components/Modals/MessageSearchModal/snippet.js.map +1 -0
- package/lib/module/components/Modals/MessageSearchModal/useMessageSearch.js +131 -0
- package/lib/module/components/Modals/MessageSearchModal/useMessageSearch.js.map +1 -0
- package/lib/module/components/Modals/PublicChatsModal/PublicChatsModal.js +300 -0
- package/lib/module/components/Modals/PublicChatsModal/PublicChatsModal.js.map +1 -0
- package/lib/module/components/Modals/PublicChatsModal/publicChatsLogic.js +30 -0
- package/lib/module/components/Modals/PublicChatsModal/publicChatsLogic.js.map +1 -0
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js +8 -1
- package/lib/module/components/Modals/SelectUsersModal/SelectUsersModal.js.map +1 -1
- package/lib/module/components/RoomComponents/ChatRoomItem.js +14 -3
- package/lib/module/components/RoomComponents/ChatRoomItem.js.map +1 -1
- package/lib/module/components/RoomComponents/SwipeableRoomRow.js +39 -7
- package/lib/module/components/RoomComponents/SwipeableRoomRow.js.map +1 -1
- package/lib/module/components/Thread/ThreadHeader.js +3 -1
- package/lib/module/components/Thread/ThreadHeader.js.map +1 -1
- package/lib/module/components/Thread/ThreadWrapper.js +89 -9
- package/lib/module/components/Thread/ThreadWrapper.js.map +1 -1
- package/lib/module/components/styled/AudioDecoderHost.js +332 -0
- package/lib/module/components/styled/AudioDecoderHost.js.map +1 -0
- package/lib/module/components/styled/AudioMessage.js +495 -422
- package/lib/module/components/styled/AudioMessage.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +32 -6
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/context/MessageNotificationContext.js +15 -5
- package/lib/module/context/MessageNotificationContext.js.map +1 -1
- package/lib/module/context/xmppProvider.js +42 -78
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/audioWaveform.js +153 -0
- package/lib/module/helpers/audioWaveform.js.map +1 -0
- package/lib/module/helpers/backgroundJoinSweep.js +30 -0
- package/lib/module/helpers/backgroundJoinSweep.js.map +1 -0
- package/lib/module/helpers/bubbleHighlight.js +38 -0
- package/lib/module/helpers/bubbleHighlight.js.map +1 -0
- package/lib/module/helpers/checkUniqueUsers.js +15 -13
- package/lib/module/helpers/checkUniqueUsers.js.map +1 -1
- package/lib/module/helpers/constants/MODAL_COMPONENTS.js +5 -1
- package/lib/module/helpers/constants/MODAL_COMPONENTS.js.map +1 -1
- package/lib/module/helpers/constants/MODAL_TYPES.js +3 -1
- package/lib/module/helpers/constants/MODAL_TYPES.js.map +1 -1
- package/lib/module/helpers/createRoomFromApi.js +37 -3
- package/lib/module/helpers/createRoomFromApi.js.map +1 -1
- package/lib/module/helpers/dedupeMembers.js +28 -0
- package/lib/module/helpers/dedupeMembers.js.map +1 -0
- package/lib/module/helpers/ethoraLogger.js +52 -0
- package/lib/module/helpers/ethoraLogger.js.map +1 -0
- package/lib/module/helpers/getUnnamedUsers.js +9 -4
- package/lib/module/helpers/getUnnamedUsers.js.map +1 -1
- package/lib/module/helpers/historyPreloadConfig.js +39 -0
- package/lib/module/helpers/historyPreloadConfig.js.map +1 -0
- package/lib/module/helpers/historyPreloadScheduler.js +368 -134
- package/lib/module/helpers/historyPreloadScheduler.js.map +1 -1
- package/lib/module/helpers/initRoomsPresence.js +18 -5
- package/lib/module/helpers/initRoomsPresence.js.map +1 -1
- package/lib/module/helpers/insertMessageWithDelimiter.js +5 -0
- package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/module/helpers/isLikelyMucJid.js +60 -0
- package/lib/module/helpers/isLikelyMucJid.js.map +1 -0
- package/lib/module/helpers/isMessageSearchEnabled.js +13 -0
- package/lib/module/helpers/isMessageSearchEnabled.js.map +1 -0
- package/lib/module/helpers/joiningRoom.js +9 -0
- package/lib/module/helpers/joiningRoom.js.map +1 -0
- package/lib/module/helpers/jumpThread.js +83 -0
- package/lib/module/helpers/jumpThread.js.map +1 -0
- package/lib/module/helpers/jumpToMessage.js +52 -0
- package/lib/module/helpers/jumpToMessage.js.map +1 -0
- package/lib/module/helpers/jumpWindow.js +177 -0
- package/lib/module/helpers/jumpWindow.js.map +1 -0
- package/lib/module/helpers/loadRoomHistory.js +69 -0
- package/lib/module/helpers/loadRoomHistory.js.map +1 -0
- package/lib/module/helpers/notificationPolicy.js +70 -0
- package/lib/module/helpers/notificationPolicy.js.map +1 -0
- package/lib/module/helpers/openRoomAtMessage.js +41 -0
- package/lib/module/helpers/openRoomAtMessage.js.map +1 -0
- package/lib/module/helpers/openThreadForJump.js +68 -0
- package/lib/module/helpers/openThreadForJump.js.map +1 -0
- package/lib/module/helpers/parseMessageReference.js +26 -6
- package/lib/module/helpers/parseMessageReference.js.map +1 -1
- package/lib/module/helpers/publicChatsEntry.js +12 -0
- package/lib/module/helpers/publicChatsEntry.js.map +1 -0
- package/lib/module/helpers/roomActivityScore.js +30 -0
- package/lib/module/helpers/roomActivityScore.js.map +1 -0
- package/lib/module/helpers/roomUserCount.js +29 -0
- package/lib/module/helpers/roomUserCount.js.map +1 -0
- package/lib/module/helpers/runConfiguredHistoryPreload.js +63 -0
- package/lib/module/helpers/runConfiguredHistoryPreload.js.map +1 -0
- package/lib/module/helpers/sessionAppId.js +20 -0
- package/lib/module/helpers/sessionAppId.js.map +1 -0
- package/lib/module/helpers/timestamp.js +37 -0
- package/lib/module/helpers/timestamp.js.map +1 -0
- package/lib/module/helpers/userResolver.js +503 -0
- package/lib/module/helpers/userResolver.js.map +1 -0
- package/lib/module/helpers/xmppIdShape.js +46 -0
- package/lib/module/helpers/xmppIdShape.js.map +1 -0
- package/lib/module/hooks/useChatWrapperInit.js +16 -5
- package/lib/module/hooks/useChatWrapperInit.js.map +1 -1
- package/lib/module/hooks/useHeapSender.js +54 -3
- package/lib/module/hooks/useHeapSender.js.map +1 -1
- package/lib/module/hooks/useJumpToMessage.js +389 -0
- package/lib/module/hooks/useJumpToMessage.js.map +1 -0
- package/lib/module/hooks/useMessageLoaderQueue.js +32 -5
- package/lib/module/hooks/useMessageLoaderQueue.js.map +1 -1
- package/lib/module/hooks/useMessageQueue.js +13 -5
- package/lib/module/hooks/useMessageQueue.js.map +1 -1
- package/lib/module/hooks/useRoomDirectory.js +24 -0
- package/lib/module/hooks/useRoomDirectory.js.map +1 -0
- package/lib/module/hooks/useRoomInitialization.js +29 -7
- package/lib/module/hooks/useRoomInitialization.js.map +1 -1
- package/lib/module/hooks/useRoomMute.js +58 -0
- package/lib/module/hooks/useRoomMute.js.map +1 -0
- package/lib/module/hooks/useRoomState.js +3 -1
- package/lib/module/hooks/useRoomState.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +13 -3
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/i18n/strings.js +288 -6
- package/lib/module/i18n/strings.js.map +1 -1
- package/lib/module/networking/api-requests/messageSearch.api.js +81 -0
- package/lib/module/networking/api-requests/messageSearch.api.js.map +1 -0
- package/lib/module/networking/api-requests/publicChats.api.js +43 -0
- package/lib/module/networking/api-requests/publicChats.api.js.map +1 -0
- package/lib/module/networking/api-requests/roomMembers.api.js +248 -4
- package/lib/module/networking/api-requests/roomMembers.api.js.map +1 -1
- package/lib/module/networking/api-requests/rooms.api.js +48 -12
- package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/module/networking/api-requests/xmppToken.api.js +66 -0
- package/lib/module/networking/api-requests/xmppToken.api.js.map +1 -0
- package/lib/module/networking/ethoraEvents.js +220 -0
- package/lib/module/networking/ethoraEvents.js.map +1 -0
- package/lib/module/networking/stanzaHandlers.js +155 -18
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmpp/allRoomPresences.xmpp.js +125 -3
- package/lib/module/networking/xmpp/allRoomPresences.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/getHistory.xmpp.js +318 -35
- package/lib/module/networking/xmpp/getHistory.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js +7 -0
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/historyCursor.js +95 -0
- package/lib/module/networking/xmpp/historyCursor.js.map +1 -0
- package/lib/module/networking/xmpp/mamQueryIds.js +12 -0
- package/lib/module/networking/xmpp/mamQueryIds.js.map +1 -0
- package/lib/module/networking/xmpp/mamRouter.js +22 -8
- package/lib/module/networking/xmpp/mamRouter.js.map +1 -1
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js +68 -62
- package/lib/module/networking/xmpp/presenceInRoom.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/roomJoinSweep.js +385 -0
- package/lib/module/networking/xmpp/roomJoinSweep.js.map +1 -0
- package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js +0 -1
- package/lib/module/networking/xmpp/sendMediaMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +0 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +0 -1
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +269 -41
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/networking/xmppCredentials.js +76 -0
- package/lib/module/networking/xmppCredentials.js.map +1 -0
- package/lib/module/roomStore/Middleware/jumpThreadMiddleware.js +153 -0
- package/lib/module/roomStore/Middleware/jumpThreadMiddleware.js.map +1 -0
- package/lib/module/roomStore/Middleware/reactionsMiddleware.js +6 -0
- package/lib/module/roomStore/Middleware/reactionsMiddleware.js.map +1 -1
- package/lib/module/roomStore/Middleware/unreadMidlleware.js +46 -7
- package/lib/module/roomStore/Middleware/unreadMidlleware.js.map +1 -1
- package/lib/module/roomStore/chatSettingsSlice.js +13 -0
- package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/module/roomStore/index.js +7 -3
- package/lib/module/roomStore/index.js.map +1 -1
- package/lib/module/roomStore/persistence.js +46 -1
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +459 -58
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/roomStore/safeKey.js +37 -0
- package/lib/module/roomStore/safeKey.js.map +1 -0
- package/lib/module/roomStore/usersSetCap.js +32 -0
- package/lib/module/roomStore/usersSetCap.js.map +1 -0
- package/lib/module/version.js +1 -1
- package/lib/module/version.js.map +1 -1
- package/lib/typescript/assets/icons.d.ts +4 -0
- package/lib/typescript/assets/icons.d.ts.map +1 -1
- package/lib/typescript/components/Header/HeaderRoomList.d.ts.map +1 -1
- package/lib/typescript/components/InputComponents/Search.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ArchivedMessageCard.d.ts +12 -0
- package/lib/typescript/components/MainComponents/ArchivedMessageCard.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatRoom.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MediaMessage.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts +22 -1
- package/lib/typescript/components/MainComponents/MessageList.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/MessageSearchButton.d.ts +7 -0
- package/lib/typescript/components/MainComponents/MessageSearchButton.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/ReduxWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/Menu/HeaderRoomListMenu.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/BubbleHighlight.d.ts +12 -0
- package/lib/typescript/components/MessageBubble/BubbleHighlight.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts +5 -0
- package/lib/typescript/components/MessageBubble/MessageInteractions.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/messageMenuLayout.d.ts +29 -0
- package/lib/typescript/components/MessageBubble/messageMenuLayout.d.ts.map +1 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts +2 -0
- package/lib/typescript/components/Modals/ChatProfileModal/ChatProfileModal.d.ts.map +1 -1
- package/lib/typescript/components/Modals/MessageSearchModal/MessageHitResults.d.ts +44 -0
- package/lib/typescript/components/Modals/MessageSearchModal/MessageHitResults.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/MessageSearchModal.d.ts +12 -0
- package/lib/typescript/components/Modals/MessageSearchModal/MessageSearchModal.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/openHit.d.ts +15 -0
- package/lib/typescript/components/Modals/MessageSearchModal/openHit.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/resolveSender.d.ts +34 -0
- package/lib/typescript/components/Modals/MessageSearchModal/resolveSender.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/searchFilters.d.ts +41 -0
- package/lib/typescript/components/Modals/MessageSearchModal/searchFilters.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/snippet.d.ts +15 -0
- package/lib/typescript/components/Modals/MessageSearchModal/snippet.d.ts.map +1 -0
- package/lib/typescript/components/Modals/MessageSearchModal/useMessageSearch.d.ts +23 -0
- package/lib/typescript/components/Modals/MessageSearchModal/useMessageSearch.d.ts.map +1 -0
- package/lib/typescript/components/Modals/PublicChatsModal/PublicChatsModal.d.ts +16 -0
- package/lib/typescript/components/Modals/PublicChatsModal/PublicChatsModal.d.ts.map +1 -0
- package/lib/typescript/components/Modals/PublicChatsModal/publicChatsLogic.d.ts +14 -0
- package/lib/typescript/components/Modals/PublicChatsModal/publicChatsLogic.d.ts.map +1 -0
- package/lib/typescript/components/Modals/SelectUsersModal/SelectUsersModal.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/ChatRoomItem.d.ts.map +1 -1
- package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts +5 -1
- package/lib/typescript/components/RoomComponents/SwipeableRoomRow.d.ts.map +1 -1
- package/lib/typescript/components/Thread/ThreadHeader.d.ts.map +1 -1
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts +1 -0
- package/lib/typescript/components/Thread/ThreadWrapper.d.ts.map +1 -1
- package/lib/typescript/components/styled/AudioDecoderHost.d.ts +39 -0
- package/lib/typescript/components/styled/AudioDecoderHost.d.ts.map +1 -0
- package/lib/typescript/components/styled/AudioMessage.d.ts +14 -1
- package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/context/MessageNotificationContext.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/audioWaveform.d.ts +54 -0
- package/lib/typescript/helpers/audioWaveform.d.ts.map +1 -0
- package/lib/typescript/helpers/backgroundJoinSweep.d.ts +14 -0
- package/lib/typescript/helpers/backgroundJoinSweep.d.ts.map +1 -0
- package/lib/typescript/helpers/bubbleHighlight.d.ts +17 -0
- package/lib/typescript/helpers/bubbleHighlight.d.ts.map +1 -0
- package/lib/typescript/helpers/checkUniqueUsers.d.ts +2 -2
- package/lib/typescript/helpers/checkUniqueUsers.d.ts.map +1 -1
- package/lib/typescript/helpers/constants/MODAL_COMPONENTS.d.ts.map +1 -1
- package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts +2 -0
- package/lib/typescript/helpers/constants/MODAL_TYPES.d.ts.map +1 -1
- package/lib/typescript/helpers/createRoomFromApi.d.ts +25 -0
- package/lib/typescript/helpers/createRoomFromApi.d.ts.map +1 -1
- package/lib/typescript/helpers/dedupeMembers.d.ts +11 -0
- package/lib/typescript/helpers/dedupeMembers.d.ts.map +1 -0
- package/lib/typescript/helpers/ethoraLogger.d.ts +13 -0
- package/lib/typescript/helpers/ethoraLogger.d.ts.map +1 -0
- package/lib/typescript/helpers/getUnnamedUsers.d.ts.map +1 -1
- package/lib/typescript/helpers/historyPreloadConfig.d.ts +26 -0
- package/lib/typescript/helpers/historyPreloadConfig.d.ts.map +1 -0
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts +8 -4
- package/lib/typescript/helpers/historyPreloadScheduler.d.ts.map +1 -1
- package/lib/typescript/helpers/initRoomsPresence.d.ts +7 -0
- package/lib/typescript/helpers/initRoomsPresence.d.ts.map +1 -1
- package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
- package/lib/typescript/helpers/isLikelyMucJid.d.ts +19 -0
- package/lib/typescript/helpers/isLikelyMucJid.d.ts.map +1 -0
- package/lib/typescript/helpers/isMessageSearchEnabled.d.ts +12 -0
- package/lib/typescript/helpers/isMessageSearchEnabled.d.ts.map +1 -0
- package/lib/typescript/helpers/joiningRoom.d.ts +7 -0
- package/lib/typescript/helpers/joiningRoom.d.ts.map +1 -0
- package/lib/typescript/helpers/jumpThread.d.ts +48 -0
- package/lib/typescript/helpers/jumpThread.d.ts.map +1 -0
- package/lib/typescript/helpers/jumpToMessage.d.ts +26 -0
- package/lib/typescript/helpers/jumpToMessage.d.ts.map +1 -0
- package/lib/typescript/helpers/jumpWindow.d.ts +74 -0
- package/lib/typescript/helpers/jumpWindow.d.ts.map +1 -0
- package/lib/typescript/helpers/loadRoomHistory.d.ts +34 -0
- package/lib/typescript/helpers/loadRoomHistory.d.ts.map +1 -0
- package/lib/typescript/helpers/notificationPolicy.d.ts +42 -0
- package/lib/typescript/helpers/notificationPolicy.d.ts.map +1 -0
- package/lib/typescript/helpers/openRoomAtMessage.d.ts +17 -0
- package/lib/typescript/helpers/openRoomAtMessage.d.ts.map +1 -0
- package/lib/typescript/helpers/openThreadForJump.d.ts +27 -0
- package/lib/typescript/helpers/openThreadForJump.d.ts.map +1 -0
- package/lib/typescript/helpers/parseMessageReference.d.ts +18 -5
- package/lib/typescript/helpers/parseMessageReference.d.ts.map +1 -1
- package/lib/typescript/helpers/publicChatsEntry.d.ts +11 -0
- package/lib/typescript/helpers/publicChatsEntry.d.ts.map +1 -0
- package/lib/typescript/helpers/roomActivityScore.d.ts +5 -0
- package/lib/typescript/helpers/roomActivityScore.d.ts.map +1 -0
- package/lib/typescript/helpers/roomUserCount.d.ts +20 -0
- package/lib/typescript/helpers/roomUserCount.d.ts.map +1 -0
- package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts +21 -0
- package/lib/typescript/helpers/runConfiguredHistoryPreload.d.ts.map +1 -0
- package/lib/typescript/helpers/sessionAppId.d.ts +8 -0
- package/lib/typescript/helpers/sessionAppId.d.ts.map +1 -0
- package/lib/typescript/helpers/timestamp.d.ts +3 -0
- package/lib/typescript/helpers/timestamp.d.ts.map +1 -0
- package/lib/typescript/helpers/userResolver.d.ts +58 -0
- package/lib/typescript/helpers/userResolver.d.ts.map +1 -0
- package/lib/typescript/helpers/xmppIdShape.d.ts +10 -0
- package/lib/typescript/helpers/xmppIdShape.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatWrapperInit.d.ts +2 -0
- package/lib/typescript/hooks/useChatWrapperInit.d.ts.map +1 -1
- package/lib/typescript/hooks/useHeapSender.d.ts.map +1 -1
- package/lib/typescript/hooks/useJumpToMessage.d.ts +116 -0
- package/lib/typescript/hooks/useJumpToMessage.d.ts.map +1 -0
- package/lib/typescript/hooks/useMessageLoaderQueue.d.ts.map +1 -1
- package/lib/typescript/hooks/useMessageQueue.d.ts.map +1 -1
- package/lib/typescript/hooks/useRoomDirectory.d.ts +12 -0
- package/lib/typescript/hooks/useRoomDirectory.d.ts.map +1 -0
- package/lib/typescript/hooks/useRoomInitialization.d.ts.map +1 -1
- package/lib/typescript/hooks/useRoomMute.d.ts +8 -0
- package/lib/typescript/hooks/useRoomMute.d.ts.map +1 -0
- package/lib/typescript/hooks/useRoomState.d.ts +1 -0
- package/lib/typescript/hooks/useRoomState.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/i18n/strings.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/messageSearch.api.d.ts +57 -0
- package/lib/typescript/networking/api-requests/messageSearch.api.d.ts.map +1 -0
- package/lib/typescript/networking/api-requests/publicChats.api.d.ts +24 -0
- package/lib/typescript/networking/api-requests/publicChats.api.d.ts.map +1 -0
- package/lib/typescript/networking/api-requests/roomMembers.api.d.ts +19 -1
- package/lib/typescript/networking/api-requests/roomMembers.api.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/xmppToken.api.d.ts +2 -0
- package/lib/typescript/networking/api-requests/xmppToken.api.d.ts.map +1 -0
- package/lib/typescript/networking/ethoraEvents.d.ts +45 -0
- package/lib/typescript/networking/ethoraEvents.d.ts.map +1 -0
- package/lib/typescript/networking/stanzaHandlers.d.ts +1 -1
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts +32 -1
- package/lib/typescript/networking/xmpp/allRoomPresences.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts +64 -0
- package/lib/typescript/networking/xmpp/getHistory.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/historyCursor.d.ts +35 -0
- package/lib/typescript/networking/xmpp/historyCursor.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/mamQueryIds.d.ts +10 -0
- package/lib/typescript/networking/xmpp/mamQueryIds.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/mamRouter.d.ts +7 -0
- package/lib/typescript/networking/xmpp/mamRouter.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts +13 -2
- package/lib/typescript/networking/xmpp/presenceInRoom.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts +82 -0
- package/lib/typescript/networking/xmpp/roomJoinSweep.d.ts.map +1 -0
- package/lib/typescript/networking/xmpp/sendMediaMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +90 -4
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/networking/xmppCredentials.d.ts +12 -0
- package/lib/typescript/networking/xmppCredentials.d.ts.map +1 -0
- package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts +3 -0
- package/lib/typescript/roomStore/Middleware/jumpThreadMiddleware.d.ts.map +1 -0
- package/lib/typescript/roomStore/Middleware/reactionsMiddleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/Middleware/unreadMidlleware.d.ts.map +1 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts +8 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/index.d.ts +2 -1
- package/lib/typescript/roomStore/index.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistence.d.ts +8 -0
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +138 -2
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/safeKey.d.ts +13 -0
- package/lib/typescript/roomStore/safeKey.d.ts.map +1 -0
- package/lib/typescript/roomStore/usersSetCap.d.ts +16 -0
- package/lib/typescript/roomStore/usersSetCap.d.ts.map +1 -0
- package/lib/typescript/types/models/media.model.d.ts +2 -0
- package/lib/typescript/types/models/media.model.d.ts.map +1 -1
- package/lib/typescript/types/models/room.model.d.ts +18 -5
- package/lib/typescript/types/models/room.model.d.ts.map +1 -1
- package/lib/typescript/types/models/xmpp.model.d.ts +8 -1
- package/lib/typescript/types/models/xmpp.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +88 -5
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/version.d.ts +1 -1
- package/lib/typescript/version.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/assets/icons.tsx +13 -0
- package/src/components/Header/HeaderRoomList.tsx +21 -4
- package/src/components/InputComponents/Search.tsx +33 -0
- package/src/components/MainComponents/ArchivedMessageCard.tsx +139 -0
- package/src/components/MainComponents/ChatHeader.tsx +19 -3
- package/src/components/MainComponents/ChatRoom.tsx +60 -23
- package/src/components/MainComponents/ChatWrapper.tsx +23 -4
- package/src/components/MainComponents/MediaMessage.tsx +17 -0
- package/src/components/MainComponents/MessageList.tsx +823 -84
- package/src/components/MainComponents/MessageSearchButton.tsx +48 -0
- package/src/components/MainComponents/ReduxWrapper.tsx +16 -5
- package/src/components/MainComponents/RoomList.tsx +125 -0
- package/src/components/Menu/HeaderRoomListMenu.tsx +26 -2
- package/src/components/MessageBubble/BubbleHighlight.tsx +106 -0
- package/src/components/MessageBubble/Message.tsx +265 -177
- package/src/components/MessageBubble/MessageInteractions.tsx +109 -86
- package/src/components/MessageBubble/messageMenuLayout.ts +59 -0
- package/src/components/Modals/ChatProfileModal/ChatProfileModal.tsx +92 -21
- package/src/components/Modals/MessageSearchModal/MessageHitResults.tsx +271 -0
- package/src/components/Modals/MessageSearchModal/MessageSearchModal.tsx +487 -0
- package/src/components/Modals/MessageSearchModal/openHit.ts +50 -0
- package/src/components/Modals/MessageSearchModal/resolveSender.ts +57 -0
- package/src/components/Modals/MessageSearchModal/searchFilters.ts +109 -0
- package/src/components/Modals/MessageSearchModal/snippet.ts +58 -0
- package/src/components/Modals/MessageSearchModal/useMessageSearch.ts +151 -0
- package/src/components/Modals/PublicChatsModal/PublicChatsModal.tsx +288 -0
- package/src/components/Modals/PublicChatsModal/publicChatsLogic.ts +36 -0
- package/src/components/Modals/SelectUsersModal/SelectUsersModal.tsx +8 -1
- package/src/components/RoomComponents/ChatRoomItem.tsx +16 -3
- package/src/components/RoomComponents/SwipeableRoomRow.tsx +39 -6
- package/src/components/Thread/ThreadHeader.tsx +3 -1
- package/src/components/Thread/ThreadWrapper.tsx +96 -10
- package/src/components/styled/AudioDecoderHost.tsx +351 -0
- package/src/components/styled/AudioMessage.tsx +482 -425
- package/src/components/styled/SendInput.tsx +42 -4
- package/src/context/MessageNotificationContext.tsx +19 -5
- package/src/context/xmppProvider.tsx +44 -91
- package/src/helpers/audioWaveform.ts +142 -0
- package/src/helpers/backgroundJoinSweep.ts +35 -0
- package/src/helpers/bubbleHighlight.ts +47 -0
- package/src/helpers/checkUniqueUsers.tsx +15 -17
- package/src/helpers/constants/MODAL_COMPONENTS.tsx +4 -0
- package/src/helpers/constants/MODAL_TYPES.ts +3 -0
- package/src/helpers/createRoomFromApi.tsx +45 -4
- package/src/helpers/dedupeMembers.ts +29 -0
- package/src/helpers/ethoraLogger.ts +50 -0
- package/src/helpers/getUnnamedUsers.ts +7 -4
- package/src/helpers/historyPreloadConfig.ts +68 -0
- package/src/helpers/historyPreloadScheduler.ts +437 -199
- package/src/helpers/initRoomsPresence.ts +20 -7
- package/src/helpers/insertMessageWithDelimiter.ts +3 -0
- package/src/helpers/isLikelyMucJid.ts +72 -0
- package/src/helpers/isMessageSearchEnabled.ts +18 -0
- package/src/helpers/joiningRoom.ts +13 -0
- package/src/helpers/jumpThread.ts +102 -0
- package/src/helpers/jumpToMessage.ts +57 -0
- package/src/helpers/jumpWindow.ts +212 -0
- package/src/helpers/loadRoomHistory.ts +83 -0
- package/src/helpers/notificationPolicy.ts +82 -0
- package/src/helpers/openRoomAtMessage.ts +38 -0
- package/src/helpers/openThreadForJump.ts +96 -0
- package/src/helpers/parseMessageReference.ts +37 -8
- package/src/helpers/publicChatsEntry.ts +15 -0
- package/src/helpers/roomActivityScore.ts +45 -0
- package/src/helpers/roomUserCount.ts +44 -0
- package/src/helpers/runConfiguredHistoryPreload.ts +76 -0
- package/src/helpers/sessionAppId.ts +17 -0
- package/src/helpers/timestamp.ts +44 -0
- package/src/helpers/userResolver.ts +542 -0
- package/src/helpers/xmppIdShape.ts +46 -0
- package/src/hooks/useChatWrapperInit.ts +22 -4
- package/src/hooks/useHeapSender.tsx +54 -3
- package/src/hooks/useJumpToMessage.ts +538 -0
- package/src/hooks/useMessageLoaderQueue.tsx +40 -4
- package/src/hooks/useMessageQueue.ts +9 -5
- package/src/hooks/useRoomDirectory.ts +39 -0
- package/src/hooks/useRoomInitialization.tsx +33 -7
- package/src/hooks/useRoomMute.ts +42 -0
- package/src/hooks/useRoomState.tsx +6 -0
- package/src/hooks/useSendMessage.tsx +14 -2
- package/src/i18n/strings.ts +282 -0
- package/src/networking/api-requests/messageSearch.api.ts +130 -0
- package/src/networking/api-requests/publicChats.api.ts +71 -0
- package/src/networking/api-requests/roomMembers.api.ts +263 -11
- package/src/networking/api-requests/rooms.api.ts +52 -12
- package/src/networking/api-requests/xmppToken.api.ts +62 -0
- package/src/networking/ethoraEvents.ts +262 -0
- package/src/networking/stanzaHandlers.ts +145 -19
- package/src/networking/xmpp/allRoomPresences.xmpp.ts +155 -5
- package/src/networking/xmpp/getHistory.xmpp.ts +433 -47
- package/src/networking/xmpp/handleStanzas.xmpp.ts +8 -0
- package/src/networking/xmpp/historyCursor.ts +124 -0
- package/src/networking/xmpp/mamQueryIds.ts +11 -0
- package/src/networking/xmpp/mamRouter.ts +24 -10
- package/src/networking/xmpp/presenceInRoom.xmpp.ts +91 -68
- package/src/networking/xmpp/roomJoinSweep.ts +412 -0
- package/src/networking/xmpp/sendMediaMessage.xmpp.ts +0 -1
- package/src/networking/xmpp/sendTextMessage.xmpp.ts +0 -1
- package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +0 -1
- package/src/networking/xmppClient.ts +323 -47
- package/src/networking/xmppCredentials.ts +87 -0
- package/src/roomStore/Middleware/jumpThreadMiddleware.ts +163 -0
- package/src/roomStore/Middleware/reactionsMiddleware.tsx +4 -0
- package/src/roomStore/Middleware/unreadMidlleware.tsx +59 -11
- package/src/roomStore/chatSettingsSlice.ts +11 -0
- package/src/roomStore/index.ts +10 -3
- package/src/roomStore/persistence.ts +54 -0
- package/src/roomStore/roomsSlice.ts +547 -65
- package/src/roomStore/safeKey.ts +49 -0
- package/src/roomStore/usersSetCap.ts +37 -0
- package/src/types/models/media.model.ts +4 -0
- package/src/types/models/room.model.ts +18 -5
- package/src/types/models/xmpp.model.ts +15 -1
- package/src/types/types.ts +93 -5
- package/src/version.ts +1 -1
|
@@ -4,6 +4,10 @@ import { EditAction, HistoryPreloadState, IMessage, IRoom } from '../types/types
|
|
|
4
4
|
import { insertMessageWithDelimiter } from '../helpers/insertMessageWithDelimiter';
|
|
5
5
|
import { msgSortableMs } from '../helpers/msgSortableMs';
|
|
6
6
|
import type XmppClient from '../networking/xmppClient';
|
|
7
|
+
import type { TranslationObject } from '../helpers/transformTranslatations';
|
|
8
|
+
import { isSafeKey } from './safeKey';
|
|
9
|
+
import { mergeUsersSet as mergeIntoUsersSet } from './usersSetCap';
|
|
10
|
+
import { getRoomUserCount } from '../helpers/roomUserCount';
|
|
7
11
|
import { subscribeRoomForPush } from '../services/pushSubscriptionService';
|
|
8
12
|
|
|
9
13
|
// Per-room runtime message cap. Mirrors the persistence layer's
|
|
@@ -175,6 +179,64 @@ const insertRoomMessage = (
|
|
|
175
179
|
return { grew, atHead };
|
|
176
180
|
};
|
|
177
181
|
|
|
182
|
+
/**
|
|
183
|
+
* Keeps the jump window's separate copy of a message in step with the live
|
|
184
|
+
* list: an echo of a message the reader sees flips it from "sending" to
|
|
185
|
+
* delivered there too, call-log entries collapse per callId, and (only for a
|
|
186
|
+
* live single-message add, `allowAppend`) a reader parked at the LIVE END of
|
|
187
|
+
* a window (hasNewer false) sees what arrives next. While hasNewer is true
|
|
188
|
+
* the window is not adjacent to the tail and the message waits in
|
|
189
|
+
* room.messages until the reader returns to live.
|
|
190
|
+
*/
|
|
191
|
+
const syncJumpWindowWithMessage = (
|
|
192
|
+
state: WritableDraft<RoomMessagesState>,
|
|
193
|
+
roomJID: string,
|
|
194
|
+
message: IMessage,
|
|
195
|
+
start: boolean | undefined,
|
|
196
|
+
allowAppend: boolean
|
|
197
|
+
): void => {
|
|
198
|
+
const win = state.jumpWindow;
|
|
199
|
+
if (!win || win.roomJID !== roomJID || isCallSignalMessage(message)) {return;}
|
|
200
|
+
const incomingCallLog = message.callLog;
|
|
201
|
+
if (incomingCallLog?.callId) {
|
|
202
|
+
const wi = win.messages.findIndex(
|
|
203
|
+
(msg) => msg.callLog?.callId === incomingCallLog.callId
|
|
204
|
+
);
|
|
205
|
+
if (wi !== -1) {
|
|
206
|
+
const wExisting = win.messages[wi];
|
|
207
|
+
const wMerged = mergeCallLogEntries(wExisting, message);
|
|
208
|
+
if (wMerged !== wExisting) {win.messages[wi] = wMerged;}
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
if (win.messages.length === 0) {return;}
|
|
213
|
+
const isKnownMessage = (msg: IMessage) =>
|
|
214
|
+
msg.id === message.id ||
|
|
215
|
+
(!!message.xmppId && msg.id === message.xmppId) ||
|
|
216
|
+
(!!msg.xmppId && msg.xmppId === message.id);
|
|
217
|
+
const wi = win.messages.findIndex(isKnownMessage);
|
|
218
|
+
if (wi !== -1) {
|
|
219
|
+
const prev = win.messages[wi];
|
|
220
|
+
const next: Record<string, unknown> = { ...prev };
|
|
221
|
+
for (const [key, value] of Object.entries(message)) {
|
|
222
|
+
if (value !== undefined && isSafeKey(key)) {next[key] = value;}
|
|
223
|
+
}
|
|
224
|
+
// The sender identity captured on first insert wins, as in the live
|
|
225
|
+
// list (the echo parses a different id form).
|
|
226
|
+
next.user = prev.user;
|
|
227
|
+
next.pending = false;
|
|
228
|
+
win.messages[wi] = next as unknown as IMessage;
|
|
229
|
+
} else if (allowAppend && !win.hasNewer && !start) {
|
|
230
|
+
win.messages.push({ ...message });
|
|
231
|
+
if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
|
|
232
|
+
win.messages = win.messages.slice(-JUMP_WINDOW_MAX_MESSAGES);
|
|
233
|
+
const oldest = Number(win.messages[0].id);
|
|
234
|
+
win.olderCursor = Number.isFinite(oldest) ? oldest : win.olderCursor;
|
|
235
|
+
win.hasOlder = true;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
178
240
|
const capAfterGrowth = (
|
|
179
241
|
messages: IMessage[],
|
|
180
242
|
lengthBefore: number,
|
|
@@ -208,6 +270,7 @@ const upsertRoom = (
|
|
|
208
270
|
state: WritableDraft<RoomMessagesState>,
|
|
209
271
|
roomData: IRoom
|
|
210
272
|
): void => {
|
|
273
|
+
if (!isSafeKey(roomData?.jid)) {return;}
|
|
211
274
|
const existing = state.rooms[roomData.jid];
|
|
212
275
|
let lastViewed: number;
|
|
213
276
|
const serverMarker = state.privateStoreMarkers?.[roomData.jid] || 0;
|
|
@@ -237,13 +300,23 @@ const upsertRoom = (
|
|
|
237
300
|
: [];
|
|
238
301
|
state.rooms[roomData.jid] = {
|
|
239
302
|
...roomData,
|
|
303
|
+
usersCnt: resolveIncomingUsersCnt(roomData, existing),
|
|
304
|
+
// A seed for the room-list preview: take the freshest API value but
|
|
305
|
+
// never let a payload without one erase what is already there.
|
|
306
|
+
lastMessage: roomData.lastMessage ?? existing?.lastMessage,
|
|
307
|
+
...resolveApiUnread(state, roomData.jid, roomData, existing),
|
|
240
308
|
icon: roomData.icon !== undefined ? roomData.icon : existing?.icon,
|
|
241
309
|
roomBg: roomData.roomBg !== undefined ? roomData.roomBg : existing?.roomBg,
|
|
242
310
|
messages:
|
|
243
311
|
existingMessages.length > 0 ? existingMessages : incomingMessages,
|
|
244
312
|
lastViewedTimestamp: lastViewed,
|
|
313
|
+
// A server-seeded count must not badge a room that is open right now.
|
|
245
314
|
unreadMessages:
|
|
246
|
-
roomData.
|
|
315
|
+
roomData.apiUnreadCount !== undefined &&
|
|
316
|
+
(state.activeRoomJID === roomData.jid ||
|
|
317
|
+
state.visibleRoomJID === roomData.jid)
|
|
318
|
+
? existing?.unreadMessages ?? 0
|
|
319
|
+
: roomData.unreadMessages ?? existing?.unreadMessages ?? 0,
|
|
247
320
|
unreadBaselineTimestamp:
|
|
248
321
|
existing?.unreadBaselineTimestamp ??
|
|
249
322
|
existing?.lastViewedTimestamp ??
|
|
@@ -427,12 +500,91 @@ function mergeHistoryIntoCache(
|
|
|
427
500
|
return [...capTail(merged), ...pending];
|
|
428
501
|
}
|
|
429
502
|
|
|
503
|
+
/** A message found in the archive that the chat cannot show in place. */
|
|
504
|
+
export interface ArchivedMessage {
|
|
505
|
+
roomJID: string;
|
|
506
|
+
sender: string;
|
|
507
|
+
body: string;
|
|
508
|
+
/** ISO timestamp from the archive. */
|
|
509
|
+
createdAt: string;
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
/** A request to scroll a room's transcript to one message. */
|
|
513
|
+
export interface PendingJump {
|
|
514
|
+
roomJID: string;
|
|
515
|
+
/** Any id the message may be known by: message id, stanza id, xmpp id. */
|
|
516
|
+
ids: string[];
|
|
517
|
+
/**
|
|
518
|
+
* For a message that has no usable id (search archive rows often carry
|
|
519
|
+
* none): its timestamp and text, matched against the loaded transcript.
|
|
520
|
+
*/
|
|
521
|
+
createdAt?: string;
|
|
522
|
+
body?: string;
|
|
523
|
+
/**
|
|
524
|
+
* What to show if the message cannot be reached in the transcript: the hit
|
|
525
|
+
* itself, so a tap on a search result always ends with the message on
|
|
526
|
+
* screen rather than an error.
|
|
527
|
+
*/
|
|
528
|
+
preview?: ArchivedMessage;
|
|
529
|
+
/** Epoch ms the request was made, to drop one nobody ever fulfilled. */
|
|
530
|
+
at: number;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/**
|
|
534
|
+
* A short slice of a room's archive around one message, shown INSTEAD of the
|
|
535
|
+
* live list while the reader is away from the tail (a search jump to a message
|
|
536
|
+
* far back). Separate from room.messages on purpose: it is not contiguous with
|
|
537
|
+
* the live history, so it must not touch messageStats or historyComplete.
|
|
538
|
+
* Never persisted.
|
|
539
|
+
*/
|
|
540
|
+
export interface JumpWindow {
|
|
541
|
+
roomJID: string;
|
|
542
|
+
/** Ascending by time, like room.messages. */
|
|
543
|
+
messages: IMessage[];
|
|
544
|
+
/** Id of the message the jump named, as it appears in `messages`. */
|
|
545
|
+
targetId: string;
|
|
546
|
+
/** RSM cursor (microseconds) to continue older paging from. */
|
|
547
|
+
olderCursor: number | null;
|
|
548
|
+
hasOlder: boolean;
|
|
549
|
+
/** RSM cursor (microseconds) to continue newer paging from. */
|
|
550
|
+
newerCursor: number | null;
|
|
551
|
+
hasNewer: boolean;
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
/** The window is trimmed on the far side past this many messages. */
|
|
555
|
+
export const JUMP_WINDOW_MAX_MESSAGES = 300;
|
|
556
|
+
|
|
557
|
+
const mergeWindowMessages = (a: IMessage[], b: IMessage[]): IMessage[] => {
|
|
558
|
+
const seen = new Set<string>();
|
|
559
|
+
const merged: IMessage[] = [];
|
|
560
|
+
for (const message of [...a, ...b]) {
|
|
561
|
+
const key = String(message.id);
|
|
562
|
+
if (seen.has(key)) {continue;}
|
|
563
|
+
seen.add(key);
|
|
564
|
+
merged.push(message);
|
|
565
|
+
}
|
|
566
|
+
const num = (message: IMessage) => {
|
|
567
|
+
const id = Number(message.id);
|
|
568
|
+
return Number.isFinite(id) && id > 0
|
|
569
|
+
? id
|
|
570
|
+
: new Date(message.date).getTime();
|
|
571
|
+
};
|
|
572
|
+
// Archive ids are microsecond stanza ids and ascending in time; fall back to
|
|
573
|
+
// the date when an id is not numeric.
|
|
574
|
+
return merged.sort((x, y) => num(x) - num(y));
|
|
575
|
+
};
|
|
576
|
+
|
|
430
577
|
export interface RoomPreloadPatch {
|
|
431
578
|
jid: string;
|
|
432
579
|
messages?: IMessage[];
|
|
433
580
|
historyPreloadState?: HistoryPreloadState;
|
|
434
581
|
unreadCapped?: boolean;
|
|
435
582
|
historyComplete?: boolean;
|
|
583
|
+
/**
|
|
584
|
+
* RSM bounds of the loaded history (epoch ms or archive microseconds, the
|
|
585
|
+
* same units the room already stores): merged into room.messageStats.
|
|
586
|
+
*/
|
|
587
|
+
messageStats?: { firstMessageTimestamp?: number; lastMessageTimestamp?: number };
|
|
436
588
|
}
|
|
437
589
|
|
|
438
590
|
export interface RoomMessagesState {
|
|
@@ -444,6 +596,10 @@ export interface RoomMessagesState {
|
|
|
444
596
|
loadingText?: string;
|
|
445
597
|
isUnreadSyncing?: boolean;
|
|
446
598
|
usersSet?: Record<string, any>;
|
|
599
|
+
/** See JumpWindow. Never persisted. */
|
|
600
|
+
jumpWindow: JumpWindow | null;
|
|
601
|
+
/** See ArchivedMessage. Never persisted. */
|
|
602
|
+
archivedMessage: ArchivedMessage | null;
|
|
447
603
|
pendingNotificationJid?: string | null;
|
|
448
604
|
// Server-side read markers fetched from the XMPP private store
|
|
449
605
|
// (`{ roomJID: lastViewedMs }`). Kept here so a room that loads AFTER
|
|
@@ -451,6 +607,19 @@ export interface RoomMessagesState {
|
|
|
451
607
|
// — see `applyPrivateStoreMarkers`. Re-fetched every init/reconnect,
|
|
452
608
|
// so it is intentionally NOT persisted.
|
|
453
609
|
privateStoreMarkers: Record<string, number>;
|
|
610
|
+
// A pending "scroll this room's transcript to that message" request (a
|
|
611
|
+
// message search hit, later a notification). Fulfilled by MessageList's
|
|
612
|
+
// useJumpToMessage: scroll if mounted, else page older history until the
|
|
613
|
+
// message shows up. `at` bounds how long a request may stay alive. Never
|
|
614
|
+
// persisted (persistence.ts only picks `rooms`).
|
|
615
|
+
pendingJump: PendingJump | null;
|
|
616
|
+
// The room this session is joining right now (opened from the public chats
|
|
617
|
+
// directory, a link or a QR code) which is not in the room list yet. The
|
|
618
|
+
// server registers the membership a moment after our presence join, so
|
|
619
|
+
// "not in the list" is not yet "unavailable": ChatRoom shows a loader while
|
|
620
|
+
// this names the active room. Set and cleared by useRoomInitialization.
|
|
621
|
+
// Never persisted.
|
|
622
|
+
joiningRoomJID: string | null;
|
|
454
623
|
/** `{ roomJID: { messageId: reactions[] } }` — reactions that arrived
|
|
455
624
|
* before their message (a newer history page), applied on insert. */
|
|
456
625
|
pendingReactions?: Record<string, Record<string, PendingReaction[]>>;
|
|
@@ -497,16 +666,97 @@ const initialState: RoomMessagesState = {
|
|
|
497
666
|
},
|
|
498
667
|
pendingNotificationJid: null,
|
|
499
668
|
privateStoreMarkers: {},
|
|
669
|
+
pendingJump: null,
|
|
670
|
+
joiningRoomJID: null,
|
|
500
671
|
readBoundaries: {},
|
|
672
|
+
usersSet: {},
|
|
673
|
+
jumpWindow: null,
|
|
674
|
+
archivedMessage: null,
|
|
501
675
|
pendingReactions: {},
|
|
502
676
|
};
|
|
503
677
|
|
|
504
678
|
const isValidRoomJid = (jid: unknown): jid is string => {
|
|
505
|
-
if (
|
|
506
|
-
if (!jid.includes('@')) return false;
|
|
679
|
+
if (!isSafeKey(jid)) {return false;}
|
|
680
|
+
if (!jid.includes('@')) {return false;}
|
|
507
681
|
return true;
|
|
508
682
|
};
|
|
509
683
|
|
|
684
|
+
/**
|
|
685
|
+
* Visits every stored copy of one message: the live copy in
|
|
686
|
+
* state.rooms[jid].messages and, when a jump window is open on that room, the
|
|
687
|
+
* window's separate copy. The window is a second list of the same messages, so
|
|
688
|
+
* every reducer that mutates ONE message must go through this or the reader
|
|
689
|
+
* sees stale edits/reactions/delivery state while away from the live tail.
|
|
690
|
+
* `matches` is an id, or a predicate when a reducer also matches on xmppId.
|
|
691
|
+
*/
|
|
692
|
+
const forEachMessageCopy = (
|
|
693
|
+
state: RoomMessagesState,
|
|
694
|
+
jid: string,
|
|
695
|
+
matches: string | ((message: IMessage) => boolean),
|
|
696
|
+
fn: (message: IMessage) => void
|
|
697
|
+
) => {
|
|
698
|
+
const pred =
|
|
699
|
+
typeof matches === 'function'
|
|
700
|
+
? matches
|
|
701
|
+
: (message: IMessage) => message.id === matches;
|
|
702
|
+
const live = state.rooms[jid]?.messages;
|
|
703
|
+
if (Array.isArray(live)) {
|
|
704
|
+
for (const message of live) {if (pred(message)) {fn(message);}}
|
|
705
|
+
}
|
|
706
|
+
const win = state.jumpWindow;
|
|
707
|
+
if (win && win.roomJID === jid && Array.isArray(win.messages)) {
|
|
708
|
+
for (const message of win.messages) {if (pred(message)) {fn(message);}}
|
|
709
|
+
}
|
|
710
|
+
};
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* usersCnt after a /chats/my refresh. The API reports the true total in
|
|
714
|
+
* `usersCnt` but at most 30 `members` for a big room, so the members array
|
|
715
|
+
* length is only a floor; and a count already known (a larger one from an
|
|
716
|
+
* earlier response or a live join) is never lowered by a refresh.
|
|
717
|
+
*/
|
|
718
|
+
const resolveIncomingUsersCnt = (
|
|
719
|
+
incoming: Pick<IRoom, 'members' | 'usersCnt'> & { participants?: number },
|
|
720
|
+
existing: IRoom | undefined
|
|
721
|
+
): number => {
|
|
722
|
+
const apiTotal =
|
|
723
|
+
typeof incoming.usersCnt === 'number' && incoming.usersCnt > 0
|
|
724
|
+
? incoming.usersCnt
|
|
725
|
+
: 0;
|
|
726
|
+
const membersLen = Array.isArray(incoming.members)
|
|
727
|
+
? incoming.members.length
|
|
728
|
+
: 0;
|
|
729
|
+
const next = Math.max(apiTotal, membersLen);
|
|
730
|
+
return Math.max(next, existing ? getRoomUserCount(existing) : 0);
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* The server-reported unread snapshot of a room after an incoming /chats/my
|
|
735
|
+
* item: the freshest API value wins while the user is not looking at the
|
|
736
|
+
* room; one being read right now keeps none. Absent from the response =
|
|
737
|
+
* keep what an earlier, richer response set.
|
|
738
|
+
*/
|
|
739
|
+
const resolveApiUnread = (
|
|
740
|
+
state: RoomMessagesState,
|
|
741
|
+
jid: string,
|
|
742
|
+
incoming: Partial<IRoom>,
|
|
743
|
+
existing: IRoom | undefined
|
|
744
|
+
): Pick<IRoom, 'apiUnreadCount' | 'apiUnreadSeededAt'> => {
|
|
745
|
+
if (state.activeRoomJID === jid || state.visibleRoomJID === jid) {
|
|
746
|
+
return { apiUnreadCount: undefined, apiUnreadSeededAt: undefined };
|
|
747
|
+
}
|
|
748
|
+
if (incoming.apiUnreadCount !== undefined) {
|
|
749
|
+
return {
|
|
750
|
+
apiUnreadCount: incoming.apiUnreadCount,
|
|
751
|
+
apiUnreadSeededAt: incoming.apiUnreadSeededAt ?? Date.now(),
|
|
752
|
+
};
|
|
753
|
+
}
|
|
754
|
+
return {
|
|
755
|
+
apiUnreadCount: existing?.apiUnreadCount,
|
|
756
|
+
apiUnreadSeededAt: existing?.apiUnreadSeededAt,
|
|
757
|
+
};
|
|
758
|
+
};
|
|
759
|
+
|
|
510
760
|
export const addRoomViaApi = createAsyncThunk(
|
|
511
761
|
'roomMessages/addRoomViaApi',
|
|
512
762
|
async (
|
|
@@ -549,6 +799,7 @@ const reducers = {
|
|
|
549
799
|
},
|
|
550
800
|
deleteRoom(state: WritableDraft<RoomMessagesState>, action: PayloadAction<{ jid: string }>) {
|
|
551
801
|
const { jid } = action.payload;
|
|
802
|
+
if (!isSafeKey(jid)) {return;}
|
|
552
803
|
if (state.rooms[jid]) {
|
|
553
804
|
delete state.rooms[jid];
|
|
554
805
|
if (state.visibleRoomJID === jid) {
|
|
@@ -561,20 +812,41 @@ const reducers = {
|
|
|
561
812
|
action: PayloadAction<{ jid: string; updates: Partial<IRoom> }>
|
|
562
813
|
) {
|
|
563
814
|
const { jid, updates } = action.payload;
|
|
815
|
+
if (!isSafeKey(jid)) {return;}
|
|
564
816
|
const existingRoom = state.rooms[jid];
|
|
817
|
+
if (!existingRoom) {return;}
|
|
565
818
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
819
|
+
const merged: IRoom = { ...existingRoom, ...updates };
|
|
820
|
+
|
|
821
|
+
if (typeof updates.usersCnt === 'number') {
|
|
822
|
+
// An explicit count (a live join or leave) is taken as given, with the
|
|
823
|
+
// known members as a floor.
|
|
824
|
+
const newMembers = Array.isArray(updates.members)
|
|
825
|
+
? updates.members
|
|
826
|
+
: existingRoom.members;
|
|
827
|
+
const floor = Array.isArray(newMembers) ? newMembers.length : 0;
|
|
828
|
+
merged.usersCnt = Math.max(updates.usersCnt, floor);
|
|
829
|
+
} else if (Array.isArray(updates.members)) {
|
|
830
|
+
// A members-only refresh of a truncated big room (usersCnt > the
|
|
831
|
+
// first page) must not collapse the true total to the page length.
|
|
832
|
+
const prevMembers = Array.isArray(existingRoom.members)
|
|
833
|
+
? existingRoom.members.length
|
|
834
|
+
: 0;
|
|
835
|
+
const prevCnt =
|
|
836
|
+
typeof existingRoom.usersCnt === 'number' ? existingRoom.usersCnt : 0;
|
|
837
|
+
merged.usersCnt =
|
|
838
|
+
prevCnt > prevMembers
|
|
839
|
+
? Math.max(prevCnt, updates.members.length)
|
|
840
|
+
: updates.members.length;
|
|
571
841
|
}
|
|
842
|
+
state.rooms[jid] = merged;
|
|
572
843
|
},
|
|
573
844
|
setRoomMessages(
|
|
574
845
|
state: WritableDraft<RoomMessagesState>,
|
|
575
846
|
action: PayloadAction<{ roomJID: string; messages: IMessage[] }>
|
|
576
847
|
) {
|
|
577
848
|
const { roomJID, messages } = action.payload;
|
|
849
|
+
if (!isSafeKey(roomJID)) {return;}
|
|
578
850
|
if (state.rooms[roomJID]) {
|
|
579
851
|
// Cap to the runtime limit on replace too — guards against a
|
|
580
852
|
// single MAM page returning more than the limit (would balloon
|
|
@@ -591,6 +863,7 @@ const reducers = {
|
|
|
591
863
|
action: PayloadAction<{ roomJID: string; messageId: string }>
|
|
592
864
|
) {
|
|
593
865
|
const { roomJID, messageId } = action.payload;
|
|
866
|
+
if (!isSafeKey(roomJID)) {return;}
|
|
594
867
|
const room = state.rooms[roomJID];
|
|
595
868
|
if (!room?.messages) {return;}
|
|
596
869
|
// The "New messages" divider is a transient UI marker, not a real
|
|
@@ -603,11 +876,9 @@ const reducers = {
|
|
|
603
876
|
if (idx !== -1) {room.messages.splice(idx, 1);}
|
|
604
877
|
return;
|
|
605
878
|
}
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
message.reaction = undefined;
|
|
610
|
-
}
|
|
879
|
+
forEachMessageCopy(state, roomJID, messageId, (message) => {
|
|
880
|
+
message.isDeleted = true;
|
|
881
|
+
message.reaction = undefined;
|
|
611
882
|
});
|
|
612
883
|
},
|
|
613
884
|
setEditAction: (state: WritableDraft<RoomMessagesState>, action: PayloadAction<EditAction | undefined>) => {
|
|
@@ -631,17 +902,58 @@ const reducers = {
|
|
|
631
902
|
}>
|
|
632
903
|
) {
|
|
633
904
|
const { roomJID, messageId, text } = action.payload;
|
|
634
|
-
if (
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
905
|
+
if (!isSafeKey(roomJID)) {return;}
|
|
906
|
+
// Edited in place on every copy (live list and jump window).
|
|
907
|
+
forEachMessageCopy(state, roomJID, messageId, (message) => {
|
|
908
|
+
message.body = text;
|
|
909
|
+
// Flag the correction so the bubble can render an "edited" marker.
|
|
910
|
+
// Covers both the author's own edit and edits from other users -
|
|
911
|
+
// every <replace> echo flows through here.
|
|
912
|
+
message.isEdited = true;
|
|
913
|
+
});
|
|
914
|
+
},
|
|
915
|
+
/**
|
|
916
|
+
* Hard removal, unlike `deleteRoomMessage`'s tombstone. For optimistic
|
|
917
|
+
* messages that never made it onto the wire.
|
|
918
|
+
*/
|
|
919
|
+
removeRoomMessage(
|
|
920
|
+
state: WritableDraft<RoomMessagesState>,
|
|
921
|
+
action: PayloadAction<{ roomJID: string; messageId: string }>
|
|
922
|
+
) {
|
|
923
|
+
const { roomJID, messageId } = action.payload;
|
|
924
|
+
if (!isSafeKey(roomJID)) {return;}
|
|
925
|
+
if (state.rooms[roomJID]?.messages) {
|
|
926
|
+
state.rooms[roomJID].messages = state.rooms[roomJID].messages.filter(
|
|
927
|
+
(message) => message.id !== messageId
|
|
928
|
+
);
|
|
644
929
|
}
|
|
930
|
+
const win = state.jumpWindow;
|
|
931
|
+
if (win && win.roomJID === roomJID) {
|
|
932
|
+
win.messages = win.messages.filter(
|
|
933
|
+
(message) => message.id !== messageId
|
|
934
|
+
);
|
|
935
|
+
}
|
|
936
|
+
},
|
|
937
|
+
/**
|
|
938
|
+
* Caches one translation onto the message it belongs to, keyed by the
|
|
939
|
+
* locale tag the translate service echoed back. Applied to the live
|
|
940
|
+
* copy and the jump window's copy.
|
|
941
|
+
*/
|
|
942
|
+
setMessageTranslation(
|
|
943
|
+
state: WritableDraft<RoomMessagesState>,
|
|
944
|
+
action: PayloadAction<{
|
|
945
|
+
roomJID: string;
|
|
946
|
+
messageId: string;
|
|
947
|
+
locale: string;
|
|
948
|
+
entry: TranslationObject[string];
|
|
949
|
+
}>
|
|
950
|
+
) {
|
|
951
|
+
const { roomJID, messageId, locale, entry } = action.payload;
|
|
952
|
+
if (!isSafeKey(roomJID) || !isSafeKey(locale)) {return;}
|
|
953
|
+
forEachMessageCopy(state, roomJID, messageId, (message) => {
|
|
954
|
+
if (!message.translations) {message.translations = {};}
|
|
955
|
+
message.translations[locale] = entry;
|
|
956
|
+
});
|
|
645
957
|
},
|
|
646
958
|
addRoomMessage(
|
|
647
959
|
state: WritableDraft<RoomMessagesState>,
|
|
@@ -652,12 +964,15 @@ const reducers = {
|
|
|
652
964
|
}>
|
|
653
965
|
) {
|
|
654
966
|
const { roomJID, message, start } = action.payload;
|
|
967
|
+
if (!isSafeKey(roomJID)) {return;}
|
|
655
968
|
const lengthBefore = state.rooms[roomJID]?.messages?.length || 0;
|
|
656
969
|
const outcome = insertRoomMessage(state, roomJID, message, start);
|
|
657
970
|
if (outcome.grew) {
|
|
658
971
|
capAfterGrowth(state.rooms[roomJID].messages!, lengthBefore, outcome.atHead);
|
|
659
972
|
}
|
|
660
973
|
bumpLastMessageTimestamp(state, roomJID, message);
|
|
974
|
+
// Keep the jump window's copy in step with the live list.
|
|
975
|
+
syncJumpWindowWithMessage(state, roomJID, message, start, true);
|
|
661
976
|
},
|
|
662
977
|
/**
|
|
663
978
|
* A whole page of messages (a MAM history page) in ONE action: the same
|
|
@@ -674,7 +989,7 @@ const reducers = {
|
|
|
674
989
|
}>
|
|
675
990
|
) {
|
|
676
991
|
const { roomJID, messages, start } = action.payload;
|
|
677
|
-
if (!state.rooms[roomJID] || !Array.isArray(messages)) {
|
|
992
|
+
if (!isSafeKey(roomJID) || !state.rooms[roomJID] || !Array.isArray(messages)) {
|
|
678
993
|
return;
|
|
679
994
|
}
|
|
680
995
|
const lengthBefore = state.rooms[roomJID].messages?.length || 0;
|
|
@@ -690,6 +1005,9 @@ const reducers = {
|
|
|
690
1005
|
if (!newest || Number(message?.id) > Number(newest.id)) {
|
|
691
1006
|
newest = message;
|
|
692
1007
|
}
|
|
1008
|
+
// History pages never append to a reader's jump window (they are not
|
|
1009
|
+
// "the newest message"); they only refresh copies it already holds.
|
|
1010
|
+
syncJumpWindowWithMessage(state, roomJID, message, start, false);
|
|
693
1011
|
}
|
|
694
1012
|
if (grew) {
|
|
695
1013
|
// A page that only prepended older history is never trimmed.
|
|
@@ -701,6 +1019,7 @@ const reducers = {
|
|
|
701
1019
|
},
|
|
702
1020
|
deleteAllRooms(state: WritableDraft<RoomMessagesState>) {
|
|
703
1021
|
state.rooms = {};
|
|
1022
|
+
state.jumpWindow = null;
|
|
704
1023
|
state.visibleRoomJID = null;
|
|
705
1024
|
state.privateStoreMarkers = {};
|
|
706
1025
|
state.readBoundaries = {};
|
|
@@ -715,6 +1034,7 @@ const reducers = {
|
|
|
715
1034
|
}>
|
|
716
1035
|
) {
|
|
717
1036
|
const { chatJID, composing, composingList } = action.payload;
|
|
1037
|
+
if (!isSafeKey(chatJID) || !state.rooms[chatJID]) {return;}
|
|
718
1038
|
state.rooms[chatJID].composing = composing;
|
|
719
1039
|
state.rooms[chatJID].composingList = composingList;
|
|
720
1040
|
},
|
|
@@ -723,7 +1043,7 @@ const reducers = {
|
|
|
723
1043
|
action: PayloadAction<{ chatJID?: string; loading: boolean; loadingText?: string }>
|
|
724
1044
|
) => {
|
|
725
1045
|
const { chatJID, loading, loadingText } = action.payload;
|
|
726
|
-
if (chatJID && state.rooms?.[chatJID]) {
|
|
1046
|
+
if (isSafeKey(chatJID) && state.rooms?.[chatJID]) {
|
|
727
1047
|
state.rooms[chatJID].isLoading = loading;
|
|
728
1048
|
}
|
|
729
1049
|
state.isLoading = loading;
|
|
@@ -740,7 +1060,7 @@ const reducers = {
|
|
|
740
1060
|
action: PayloadAction<{ chatJID: string; timestamp: number }>
|
|
741
1061
|
) => {
|
|
742
1062
|
const { chatJID, timestamp } = action.payload;
|
|
743
|
-
if (state.rooms[chatJID]) {
|
|
1063
|
+
if (isSafeKey(chatJID) && state.rooms[chatJID]) {
|
|
744
1064
|
state.rooms[chatJID].lastViewedTimestamp = timestamp;
|
|
745
1065
|
// A non-positive timestamp means "no persisted marker yet" and
|
|
746
1066
|
// must not inflate unread from history that predates the first
|
|
@@ -793,7 +1113,7 @@ const reducers = {
|
|
|
793
1113
|
if (!state.privateStoreMarkers) {state.privateStoreMarkers = {};}
|
|
794
1114
|
for (const jid of Object.keys(markers)) {
|
|
795
1115
|
const ts = Number(markers[jid]);
|
|
796
|
-
if (!jid || !Number.isFinite(ts) || ts <= 0) {continue;}
|
|
1116
|
+
if (!isSafeKey(jid) || !Number.isFinite(ts) || ts <= 0) {continue;}
|
|
797
1117
|
|
|
798
1118
|
const room = state.rooms[jid];
|
|
799
1119
|
const newestKnownMs = room ? newestAckedMessageMs(room.messages) : 0;
|
|
@@ -839,7 +1159,7 @@ const reducers = {
|
|
|
839
1159
|
action: PayloadAction<{ jid: string; ts: number | null }>
|
|
840
1160
|
) => {
|
|
841
1161
|
const { jid, ts } = action.payload;
|
|
842
|
-
if (!jid) {return;}
|
|
1162
|
+
if (!isSafeKey(jid)) {return;}
|
|
843
1163
|
if (!state.readBoundaries) {state.readBoundaries = {};}
|
|
844
1164
|
if (typeof ts === 'number' && Number.isFinite(ts) && ts > 0) {
|
|
845
1165
|
state.readBoundaries[jid] = ts;
|
|
@@ -858,14 +1178,14 @@ const reducers = {
|
|
|
858
1178
|
action: PayloadAction<{ jid: string }>
|
|
859
1179
|
) => {
|
|
860
1180
|
const { jid } = action.payload;
|
|
861
|
-
if (jid && state.readBoundaries) {delete state.readBoundaries[jid];}
|
|
1181
|
+
if (isSafeKey(jid) && state.readBoundaries) {delete state.readBoundaries[jid];}
|
|
862
1182
|
},
|
|
863
1183
|
setRoomRole: (
|
|
864
1184
|
state: WritableDraft<RoomMessagesState>,
|
|
865
1185
|
action: PayloadAction<{ chatJID: string; role: string }>
|
|
866
1186
|
) => {
|
|
867
1187
|
const { chatJID, role } = action.payload;
|
|
868
|
-
if (state.rooms[chatJID]) {
|
|
1188
|
+
if (isSafeKey(chatJID) && state.rooms[chatJID]) {
|
|
869
1189
|
state.rooms[chatJID].role = role;
|
|
870
1190
|
}
|
|
871
1191
|
},
|
|
@@ -874,7 +1194,7 @@ const reducers = {
|
|
|
874
1194
|
action: PayloadAction<{ value: boolean; chatJID?: string }>
|
|
875
1195
|
) => {
|
|
876
1196
|
const { value, chatJID } = action.payload;
|
|
877
|
-
if (chatJID) {
|
|
1197
|
+
if (isSafeKey(chatJID) && state.rooms[chatJID]) {
|
|
878
1198
|
state.rooms[chatJID].noMessages = value;
|
|
879
1199
|
}
|
|
880
1200
|
},
|
|
@@ -884,16 +1204,30 @@ const reducers = {
|
|
|
884
1204
|
) => {
|
|
885
1205
|
// Accept null/empty so callers can clear the active room (e.g.
|
|
886
1206
|
// back button from chat → return to RoomList). Mirrors web.
|
|
887
|
-
|
|
1207
|
+
const { roomJID } = action.payload;
|
|
1208
|
+
if (roomJID && !isSafeKey(roomJID)) {return;}
|
|
1209
|
+
state.activeRoomJID = roomJID || '';
|
|
1210
|
+
// Opening a room reads it: the server's earlier unread count no longer
|
|
1211
|
+
// applies (the unread middleware would otherwise bring it back the
|
|
1212
|
+
// moment the user leaves the room again).
|
|
1213
|
+
if (roomJID && state.rooms[roomJID]?.apiUnreadCount !== undefined) {
|
|
1214
|
+
state.rooms[roomJID].apiUnreadCount = undefined;
|
|
1215
|
+
state.rooms[roomJID].apiUnreadSeededAt = undefined;
|
|
1216
|
+
state.rooms[roomJID].unreadMessages = 0;
|
|
1217
|
+
}
|
|
888
1218
|
},
|
|
889
1219
|
setVisibleRoom: (
|
|
890
1220
|
state: WritableDraft<RoomMessagesState>,
|
|
891
1221
|
action: PayloadAction<{ roomJID: string | null }>
|
|
892
1222
|
) => {
|
|
893
|
-
|
|
1223
|
+
const requested = action.payload.roomJID;
|
|
1224
|
+
if (requested && !isSafeKey(requested)) {return;}
|
|
1225
|
+
state.visibleRoomJID = requested || null;
|
|
894
1226
|
const jid = state.visibleRoomJID;
|
|
895
1227
|
if (jid && state.rooms[jid]) {
|
|
896
1228
|
state.rooms[jid].unreadMessages = 0;
|
|
1229
|
+
state.rooms[jid].apiUnreadCount = undefined;
|
|
1230
|
+
state.rooms[jid].apiUnreadSeededAt = undefined;
|
|
897
1231
|
}
|
|
898
1232
|
},
|
|
899
1233
|
clearVisibleRoom: (state: WritableDraft<RoomMessagesState>) => {
|
|
@@ -920,6 +1254,116 @@ const reducers = {
|
|
|
920
1254
|
clearPendingNotificationJid: (state: WritableDraft<RoomMessagesState>) => {
|
|
921
1255
|
state.pendingNotificationJid = null;
|
|
922
1256
|
},
|
|
1257
|
+
requestJumpToMessage: (
|
|
1258
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1259
|
+
action: PayloadAction<{
|
|
1260
|
+
roomJID: string;
|
|
1261
|
+
ids: string[];
|
|
1262
|
+
createdAt?: string;
|
|
1263
|
+
body?: string;
|
|
1264
|
+
preview?: ArchivedMessage;
|
|
1265
|
+
}>
|
|
1266
|
+
) => {
|
|
1267
|
+
const ids = action.payload.ids.filter(Boolean);
|
|
1268
|
+
const canMatchByContent = Boolean(
|
|
1269
|
+
action.payload.createdAt && action.payload.body
|
|
1270
|
+
);
|
|
1271
|
+
if (!action.payload.roomJID || (ids.length === 0 && !canMatchByContent)) {
|
|
1272
|
+
return;
|
|
1273
|
+
}
|
|
1274
|
+
state.pendingJump = {
|
|
1275
|
+
roomJID: action.payload.roomJID,
|
|
1276
|
+
ids,
|
|
1277
|
+
createdAt: action.payload.createdAt,
|
|
1278
|
+
body: action.payload.body,
|
|
1279
|
+
preview: action.payload.preview,
|
|
1280
|
+
at: Date.now(),
|
|
1281
|
+
};
|
|
1282
|
+
},
|
|
1283
|
+
clearPendingJump: (state: WritableDraft<RoomMessagesState>) => {
|
|
1284
|
+
state.pendingJump = null;
|
|
1285
|
+
},
|
|
1286
|
+
showArchivedMessage: (
|
|
1287
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1288
|
+
action: PayloadAction<ArchivedMessage>
|
|
1289
|
+
) => {
|
|
1290
|
+
state.archivedMessage = action.payload;
|
|
1291
|
+
},
|
|
1292
|
+
clearArchivedMessage: (state: WritableDraft<RoomMessagesState>) => {
|
|
1293
|
+
state.archivedMessage = null;
|
|
1294
|
+
},
|
|
1295
|
+
setJumpWindow: (
|
|
1296
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1297
|
+
action: PayloadAction<JumpWindow>
|
|
1298
|
+
) => {
|
|
1299
|
+
state.jumpWindow = {
|
|
1300
|
+
...action.payload,
|
|
1301
|
+
messages: mergeWindowMessages(action.payload.messages, []),
|
|
1302
|
+
};
|
|
1303
|
+
},
|
|
1304
|
+
prependJumpWindowMessages: (
|
|
1305
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1306
|
+
action: PayloadAction<{
|
|
1307
|
+
roomJID: string;
|
|
1308
|
+
messages: IMessage[];
|
|
1309
|
+
olderCursor: number | null;
|
|
1310
|
+
hasOlder: boolean;
|
|
1311
|
+
}>
|
|
1312
|
+
) => {
|
|
1313
|
+
const win = state.jumpWindow;
|
|
1314
|
+
if (!win || win.roomJID !== action.payload.roomJID) {return;}
|
|
1315
|
+
win.messages = mergeWindowMessages(action.payload.messages, win.messages);
|
|
1316
|
+
win.olderCursor = action.payload.olderCursor;
|
|
1317
|
+
win.hasOlder = action.payload.hasOlder;
|
|
1318
|
+
if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
|
|
1319
|
+
// Reader is going up: drop the far (newest) side and page it again if
|
|
1320
|
+
// they come back down.
|
|
1321
|
+
win.messages = win.messages.slice(0, JUMP_WINDOW_MAX_MESSAGES);
|
|
1322
|
+
const newest = Number(win.messages[win.messages.length - 1].id);
|
|
1323
|
+
win.newerCursor = Number.isFinite(newest) ? newest : win.newerCursor;
|
|
1324
|
+
win.hasNewer = true;
|
|
1325
|
+
}
|
|
1326
|
+
},
|
|
1327
|
+
appendJumpWindowMessages: (
|
|
1328
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1329
|
+
action: PayloadAction<{
|
|
1330
|
+
roomJID: string;
|
|
1331
|
+
messages: IMessage[];
|
|
1332
|
+
newerCursor: number | null;
|
|
1333
|
+
hasNewer: boolean;
|
|
1334
|
+
}>
|
|
1335
|
+
) => {
|
|
1336
|
+
const win = state.jumpWindow;
|
|
1337
|
+
if (!win || win.roomJID !== action.payload.roomJID) {return;}
|
|
1338
|
+
win.messages = mergeWindowMessages(win.messages, action.payload.messages);
|
|
1339
|
+
win.newerCursor = action.payload.newerCursor;
|
|
1340
|
+
win.hasNewer = action.payload.hasNewer;
|
|
1341
|
+
if (win.messages.length > JUMP_WINDOW_MAX_MESSAGES) {
|
|
1342
|
+
win.messages = win.messages.slice(-JUMP_WINDOW_MAX_MESSAGES);
|
|
1343
|
+
const oldest = Number(win.messages[0].id);
|
|
1344
|
+
win.olderCursor = Number.isFinite(oldest) ? oldest : win.olderCursor;
|
|
1345
|
+
win.hasOlder = true;
|
|
1346
|
+
}
|
|
1347
|
+
},
|
|
1348
|
+
clearJumpWindow: (state: WritableDraft<RoomMessagesState>) => {
|
|
1349
|
+
state.jumpWindow = null;
|
|
1350
|
+
},
|
|
1351
|
+
setJoiningRoom: (
|
|
1352
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1353
|
+
action: PayloadAction<string>
|
|
1354
|
+
) => {
|
|
1355
|
+
state.joiningRoomJID = action.payload || null;
|
|
1356
|
+
},
|
|
1357
|
+
// Only clears when it still names that room, so a slow join for a room
|
|
1358
|
+
// the user already left cannot wipe the join of the current one.
|
|
1359
|
+
clearJoiningRoom: (
|
|
1360
|
+
state: WritableDraft<RoomMessagesState>,
|
|
1361
|
+
action: PayloadAction<string>
|
|
1362
|
+
) => {
|
|
1363
|
+
if (state.joiningRoomJID === action.payload) {
|
|
1364
|
+
state.joiningRoomJID = null;
|
|
1365
|
+
}
|
|
1366
|
+
},
|
|
923
1367
|
/**
|
|
924
1368
|
* Stamp a message in `state.rooms[roomJID].messages` with an updated
|
|
925
1369
|
* reactions list. The reactionsMiddleware listens for this action to
|
|
@@ -938,15 +1382,28 @@ const reducers = {
|
|
|
938
1382
|
) => {
|
|
939
1383
|
const { roomJID, messageId, reactions, from, data, latestReactionTimestamp } =
|
|
940
1384
|
action.payload;
|
|
941
|
-
if (!from) {return;}
|
|
942
|
-
|
|
943
|
-
const
|
|
944
|
-
|
|
1385
|
+
if (!isSafeKey(roomJID) || !from) {return;}
|
|
1386
|
+
// `fromId` becomes a property name on the message's reaction map.
|
|
1387
|
+
const fromId = String(from).split('/')[0].split('@')[0];
|
|
1388
|
+
if (!isSafeKey(fromId)) {return;}
|
|
1389
|
+
let found = false;
|
|
1390
|
+
// Applied on every stored copy (live list and jump window).
|
|
1391
|
+
forEachMessageCopy(
|
|
1392
|
+
state,
|
|
1393
|
+
roomJID,
|
|
1394
|
+
(msg) => msg?.id === messageId || msg?.xmppId === messageId,
|
|
1395
|
+
(message) => {
|
|
1396
|
+
found = true;
|
|
1397
|
+
applyReactionToMessage(
|
|
1398
|
+
message as IMessage,
|
|
1399
|
+
from,
|
|
1400
|
+
reactions,
|
|
1401
|
+
data,
|
|
1402
|
+
latestReactionTimestamp
|
|
1403
|
+
);
|
|
1404
|
+
}
|
|
945
1405
|
);
|
|
946
|
-
if (
|
|
947
|
-
applyReactionToMessage(target as IMessage, from, reactions, data, latestReactionTimestamp);
|
|
948
|
-
return;
|
|
949
|
-
}
|
|
1406
|
+
if (found) {return;}
|
|
950
1407
|
// The message is not loaded (yet): keep the reaction for it.
|
|
951
1408
|
if (!state.pendingReactions) {state.pendingReactions = {};}
|
|
952
1409
|
const byMessage = (state.pendingReactions[roomJID] ||= {});
|
|
@@ -964,30 +1421,39 @@ const reducers = {
|
|
|
964
1421
|
state.isUnreadSyncing = false;
|
|
965
1422
|
state.privateStoreMarkers = {};
|
|
966
1423
|
state.readBoundaries = {};
|
|
1424
|
+
state.usersSet = {};
|
|
1425
|
+
state.jumpWindow = null;
|
|
1426
|
+
state.archivedMessage = null;
|
|
1427
|
+
state.pendingJump = null;
|
|
967
1428
|
},
|
|
968
1429
|
setActiveMessage: (
|
|
969
1430
|
state: WritableDraft<RoomMessagesState>,
|
|
970
1431
|
action: PayloadAction<{ id: string; chatJID: string }>
|
|
971
1432
|
) => {
|
|
972
1433
|
const { id, chatJID } = action.payload;
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
}
|
|
1434
|
+
if (!isSafeKey(chatJID) || !state.rooms[chatJID]) {return;}
|
|
1435
|
+
const flag = (message: IMessage) => {
|
|
1436
|
+
message.activeMessage = message.id === id;
|
|
1437
|
+
};
|
|
1438
|
+
state.rooms[chatJID].messages.forEach(flag);
|
|
1439
|
+
if (state.jumpWindow?.roomJID === chatJID) {
|
|
1440
|
+
state.jumpWindow.messages.forEach(flag);
|
|
1441
|
+
}
|
|
981
1442
|
},
|
|
982
1443
|
setCloseActiveMessage: (
|
|
983
1444
|
state: WritableDraft<RoomMessagesState>,
|
|
984
1445
|
action: PayloadAction<{ chatJID: string }>
|
|
985
1446
|
) => {
|
|
986
1447
|
const { chatJID } = action.payload;
|
|
987
|
-
|
|
988
|
-
state.rooms[chatJID].messages.
|
|
1448
|
+
if (!isSafeKey(chatJID) || !state.rooms[chatJID]) {return;}
|
|
1449
|
+
state.rooms[chatJID].messages.forEach((message) => {
|
|
989
1450
|
message.activeMessage = false;
|
|
990
1451
|
});
|
|
1452
|
+
if (state.jumpWindow?.roomJID === chatJID) {
|
|
1453
|
+
state.jumpWindow.messages.forEach((message) => {
|
|
1454
|
+
message.activeMessage = false;
|
|
1455
|
+
});
|
|
1456
|
+
}
|
|
991
1457
|
},
|
|
992
1458
|
/**
|
|
993
1459
|
* Batched update used by the history preload scheduler. Each patch is
|
|
@@ -1008,22 +1474,15 @@ const reducers = {
|
|
|
1008
1474
|
...existing,
|
|
1009
1475
|
...room,
|
|
1010
1476
|
title: room.title || existing?.title || room.title,
|
|
1011
|
-
usersCnt: (
|
|
1012
|
-
const incoming =
|
|
1013
|
-
typeof room.usersCnt === 'number' && room.usersCnt > 0
|
|
1014
|
-
? room.usersCnt
|
|
1015
|
-
: 0;
|
|
1016
|
-
const previous =
|
|
1017
|
-
typeof existing?.usersCnt === 'number' && existing.usersCnt > 0
|
|
1018
|
-
? existing.usersCnt
|
|
1019
|
-
: 0;
|
|
1020
|
-
if (incoming === 0 && previous === 0) return room.usersCnt;
|
|
1021
|
-
return Math.max(incoming, previous);
|
|
1022
|
-
})(),
|
|
1477
|
+
usersCnt: resolveIncomingUsersCnt(room, existing),
|
|
1023
1478
|
icon: room.icon ?? existing?.icon,
|
|
1024
1479
|
messages:
|
|
1025
1480
|
existingMessages.length > 0 ? existingMessages : incomingMessages,
|
|
1481
|
+
// A seed for the room-list preview (the API's `lastMessage`): take the
|
|
1482
|
+
// freshest value, never let a refresh without one erase it.
|
|
1483
|
+
lastMessage: room.lastMessage ?? existing?.lastMessage,
|
|
1026
1484
|
unreadMessages: existing?.unreadMessages ?? room.unreadMessages ?? 0,
|
|
1485
|
+
...resolveApiUnread(state, room.jid, room, existing),
|
|
1027
1486
|
lastViewedTimestamp:
|
|
1028
1487
|
existing?.lastViewedTimestamp ?? room.lastViewedTimestamp ?? 0,
|
|
1029
1488
|
unreadBaselineTimestamp:
|
|
@@ -1047,8 +1506,9 @@ const reducers = {
|
|
|
1047
1506
|
) => {
|
|
1048
1507
|
const { rooms } = action.payload;
|
|
1049
1508
|
for (const patch of rooms) {
|
|
1509
|
+
if (!isSafeKey(patch?.jid)) {continue;}
|
|
1050
1510
|
const room = state.rooms[patch.jid];
|
|
1051
|
-
if (!room) {continue;}
|
|
1511
|
+
if (!room || typeof room !== 'object' || Array.isArray(room)) {continue;}
|
|
1052
1512
|
if (typeof patch.historyPreloadState !== 'undefined') {
|
|
1053
1513
|
room.historyPreloadState = patch.historyPreloadState;
|
|
1054
1514
|
}
|
|
@@ -1058,6 +1518,9 @@ const reducers = {
|
|
|
1058
1518
|
if (typeof patch.historyComplete !== 'undefined') {
|
|
1059
1519
|
room.historyComplete = patch.historyComplete;
|
|
1060
1520
|
}
|
|
1521
|
+
if (patch.messageStats) {
|
|
1522
|
+
room.messageStats = { ...room.messageStats, ...patch.messageStats };
|
|
1523
|
+
}
|
|
1061
1524
|
if (Array.isArray(patch.messages)) {
|
|
1062
1525
|
for (const m of patch.messages) {takePendingReactions(state, patch.jid, m);}
|
|
1063
1526
|
// Merge the fetched page into cache by message id rather than
|
|
@@ -1076,7 +1539,13 @@ const reducers = {
|
|
|
1076
1539
|
state: WritableDraft<RoomMessagesState>,
|
|
1077
1540
|
action: PayloadAction<{ members: Record<string, any> }>
|
|
1078
1541
|
) {
|
|
1079
|
-
|
|
1542
|
+
// A real merge with a cap: fresh entries win (and move to the newest
|
|
1543
|
+
// position), entries fetched lazily earlier stay, the oldest-inserted
|
|
1544
|
+
// are evicted past USERS_SET_CAP. Unsafe keys are skipped.
|
|
1545
|
+
if (!state.usersSet || typeof state.usersSet !== 'object') {
|
|
1546
|
+
state.usersSet = {};
|
|
1547
|
+
}
|
|
1548
|
+
mergeIntoUsersSet(state.usersSet, action.payload?.members || {});
|
|
1080
1549
|
},
|
|
1081
1550
|
};
|
|
1082
1551
|
|
|
@@ -1197,8 +1666,21 @@ export const {
|
|
|
1197
1666
|
setUnreadCounts,
|
|
1198
1667
|
setPendingNotificationJid,
|
|
1199
1668
|
clearPendingNotificationJid,
|
|
1669
|
+
requestJumpToMessage,
|
|
1670
|
+
clearPendingJump,
|
|
1671
|
+
setJoiningRoom,
|
|
1672
|
+
clearJoiningRoom,
|
|
1200
1673
|
setReactions,
|
|
1201
1674
|
mergeUsersSet,
|
|
1675
|
+
removeRoomMessage,
|
|
1676
|
+
addRoomFromApi,
|
|
1677
|
+
setMessageTranslation,
|
|
1678
|
+
showArchivedMessage,
|
|
1679
|
+
clearArchivedMessage,
|
|
1680
|
+
setJumpWindow,
|
|
1681
|
+
prependJumpWindowMessages,
|
|
1682
|
+
appendJumpWindowMessages,
|
|
1683
|
+
clearJumpWindow,
|
|
1202
1684
|
} = roomsStore.actions;
|
|
1203
1685
|
|
|
1204
1686
|
export default roomsStore.reducer;
|