@ethora/chat-component-rn 26.5.21 → 26.6.10
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 +80 -0
- package/README.md +3 -3
- package/index.js +1 -1
- package/lib/commonjs/components/MainComponents/ChatHeader.js +20 -8
- package/lib/commonjs/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/commonjs/components/MainComponents/ChatWrapper.js +17 -0
- package/lib/commonjs/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js +62 -0
- package/lib/commonjs/components/MainComponents/LanguageSelectorButton.js.map +1 -0
- package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js +253 -0
- package/lib/commonjs/components/MainComponents/LanguageSelectorModal.js.map +1 -0
- package/lib/commonjs/components/MainComponents/RoomList.js +23 -9
- package/lib/commonjs/components/MainComponents/RoomList.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/Message.js +72 -11
- package/lib/commonjs/components/MessageBubble/Message.js.map +1 -1
- package/lib/commonjs/components/MessageBubble/MessageTranslate.js +160 -0
- package/lib/commonjs/components/MessageBubble/MessageTranslate.js.map +1 -0
- package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js +59 -0
- package/lib/commonjs/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
- package/lib/commonjs/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
- package/lib/commonjs/components/UsersList/UsersList.js +3 -1
- package/lib/commonjs/components/UsersList/UsersList.js.map +1 -1
- package/lib/commonjs/components/VideoCalls/CallButtons.js +159 -0
- package/lib/commonjs/components/VideoCalls/CallButtons.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/CallIcons.js +328 -0
- package/lib/commonjs/components/VideoCalls/CallIcons.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js +550 -0
- package/lib/commonjs/components/VideoCalls/VideoCallOverlay.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js +636 -0
- package/lib/commonjs/components/VideoCalls/VideoCallSession.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/livekitRuntime.js +91 -0
- package/lib/commonjs/components/VideoCalls/livekitRuntime.js.map +1 -0
- package/lib/commonjs/components/VideoCalls/useCallKeep.js +215 -0
- package/lib/commonjs/components/VideoCalls/useCallKeep.js.map +1 -0
- package/lib/commonjs/components/styled/AudioMessage.js +91 -33
- package/lib/commonjs/components/styled/AudioMessage.js.map +1 -1
- package/lib/commonjs/components/styled/RoomListComponents/index.js +13 -1
- package/lib/commonjs/components/styled/RoomListComponents/index.js.map +1 -1
- package/lib/commonjs/components/styled/SendInput.js +83 -49
- package/lib/commonjs/components/styled/SendInput.js.map +1 -1
- package/lib/commonjs/components/styled/StyledComponents.js +9 -4
- package/lib/commonjs/components/styled/StyledComponents.js.map +1 -1
- package/lib/commonjs/components/styled/StyledInputComponents/Composing.js +2 -0
- package/lib/commonjs/components/styled/StyledInputComponents/Composing.js.map +1 -1
- package/lib/commonjs/context/xmppProvider.js +10 -3
- package/lib/commonjs/context/xmppProvider.js.map +1 -1
- package/lib/commonjs/helpers/callLogMessage.js +162 -0
- package/lib/commonjs/helpers/callLogMessage.js.map +1 -0
- package/lib/commonjs/helpers/callPush.js +61 -0
- package/lib/commonjs/helpers/callPush.js.map +1 -0
- package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
- package/lib/commonjs/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
- package/lib/commonjs/helpers/createUserNameFromSetUser.js +51 -2
- package/lib/commonjs/helpers/createUserNameFromSetUser.js.map +1 -1
- package/lib/commonjs/helpers/getDataFromXml.js +19 -1
- package/lib/commonjs/helpers/getDataFromXml.js.map +1 -1
- package/lib/commonjs/helpers/incomingCallFromPush.js +74 -0
- package/lib/commonjs/helpers/incomingCallFromPush.js.map +1 -0
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js +13 -1
- package/lib/commonjs/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/commonjs/helpers/isUnresolvedSenderId.js +32 -0
- package/lib/commonjs/helpers/isUnresolvedSenderId.js.map +1 -0
- package/lib/commonjs/hooks/useChatSettingState.js +2 -0
- package/lib/commonjs/hooks/useChatSettingState.js.map +1 -1
- package/lib/commonjs/hooks/useMessageTranslation.js +51 -0
- package/lib/commonjs/hooks/useMessageTranslation.js.map +1 -0
- package/lib/commonjs/hooks/usePushNotifications.js +13 -3
- package/lib/commonjs/hooks/usePushNotifications.js.map +1 -1
- package/lib/commonjs/hooks/useSendMessage.js +12 -2
- package/lib/commonjs/hooks/useSendMessage.js.map +1 -1
- package/lib/commonjs/i18n/strings.js +1308 -0
- package/lib/commonjs/i18n/strings.js.map +1 -0
- package/lib/commonjs/i18n/useT.js +60 -0
- package/lib/commonjs/i18n/useT.js.map +1 -0
- package/lib/commonjs/main.js +44 -0
- package/lib/commonjs/main.js.map +1 -1
- package/lib/commonjs/networking/api-requests/push.api.js +34 -5
- package/lib/commonjs/networking/api-requests/push.api.js.map +1 -1
- package/lib/commonjs/networking/api-requests/rooms.api.js +108 -0
- package/lib/commonjs/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/commonjs/networking/callTokenStanza.js +531 -0
- package/lib/commonjs/networking/callTokenStanza.js.map +1 -0
- package/lib/commonjs/networking/outboundQueue.js.map +1 -1
- package/lib/commonjs/networking/stanzaHandlers.js +75 -8
- package/lib/commonjs/networking/stanzaHandlers.js.map +1 -1
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js +47 -11
- package/lib/commonjs/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js +2 -1
- package/lib/commonjs/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +42 -5
- package/lib/commonjs/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/commonjs/networking/xmppClient.js +78 -16
- package/lib/commonjs/networking/xmppClient.js.map +1 -1
- package/lib/commonjs/roomStore/callSlice.js +144 -0
- package/lib/commonjs/roomStore/callSlice.js.map +1 -0
- package/lib/commonjs/roomStore/chatSettingsSlice.js +8 -2
- package/lib/commonjs/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/commonjs/roomStore/index.js +7 -1
- package/lib/commonjs/roomStore/index.js.map +1 -1
- package/lib/commonjs/roomStore/persistence.js +69 -5
- package/lib/commonjs/roomStore/persistence.js.map +1 -1
- package/lib/commonjs/roomStore/roomsSlice.js +136 -6
- package/lib/commonjs/roomStore/roomsSlice.js.map +1 -1
- package/lib/commonjs/utils/translateModePolicy.js +33 -0
- package/lib/commonjs/utils/translateModePolicy.js.map +1 -0
- package/lib/module/components/MainComponents/ChatHeader.js +20 -8
- package/lib/module/components/MainComponents/ChatHeader.js.map +1 -1
- package/lib/module/components/MainComponents/ChatWrapper.js +17 -0
- package/lib/module/components/MainComponents/ChatWrapper.js.map +1 -1
- package/lib/module/components/MainComponents/LanguageSelectorButton.js +57 -0
- package/lib/module/components/MainComponents/LanguageSelectorButton.js.map +1 -0
- package/lib/module/components/MainComponents/LanguageSelectorModal.js +246 -0
- package/lib/module/components/MainComponents/LanguageSelectorModal.js.map +1 -0
- package/lib/module/components/MainComponents/RoomList.js +23 -9
- package/lib/module/components/MainComponents/RoomList.js.map +1 -1
- package/lib/module/components/MessageBubble/Message.js +73 -12
- package/lib/module/components/MessageBubble/Message.js.map +1 -1
- package/lib/module/components/MessageBubble/MessageTranslate.js +155 -0
- package/lib/module/components/MessageBubble/MessageTranslate.js.map +1 -0
- package/lib/module/components/MessageBubble/TranslatedMessageBody.js +53 -0
- package/lib/module/components/MessageBubble/TranslatedMessageBody.js.map +1 -0
- package/lib/module/components/Modals/FilePreviewModal/FilePreviewModal.js +3 -3
- package/lib/module/components/UsersList/UsersList.js +3 -1
- package/lib/module/components/UsersList/UsersList.js.map +1 -1
- package/lib/module/components/VideoCalls/CallButtons.js +154 -0
- package/lib/module/components/VideoCalls/CallButtons.js.map +1 -0
- package/lib/module/components/VideoCalls/CallIcons.js +309 -0
- package/lib/module/components/VideoCalls/CallIcons.js.map +1 -0
- package/lib/module/components/VideoCalls/VideoCallOverlay.js +544 -0
- package/lib/module/components/VideoCalls/VideoCallOverlay.js.map +1 -0
- package/lib/module/components/VideoCalls/VideoCallSession.js +630 -0
- package/lib/module/components/VideoCalls/VideoCallSession.js.map +1 -0
- package/lib/module/components/VideoCalls/livekitRuntime.js +83 -0
- package/lib/module/components/VideoCalls/livekitRuntime.js.map +1 -0
- package/lib/module/components/VideoCalls/useCallKeep.js +210 -0
- package/lib/module/components/VideoCalls/useCallKeep.js.map +1 -0
- package/lib/module/components/styled/AudioMessage.js +91 -33
- package/lib/module/components/styled/AudioMessage.js.map +1 -1
- package/lib/module/components/styled/RoomListComponents/index.js +13 -1
- package/lib/module/components/styled/RoomListComponents/index.js.map +1 -1
- package/lib/module/components/styled/SendInput.js +83 -49
- package/lib/module/components/styled/SendInput.js.map +1 -1
- package/lib/module/components/styled/StyledComponents.js +9 -4
- package/lib/module/components/styled/StyledComponents.js.map +1 -1
- package/lib/module/components/styled/StyledInputComponents/Composing.js +2 -0
- package/lib/module/components/styled/StyledInputComponents/Composing.js.map +1 -1
- package/lib/module/context/xmppProvider.js +11 -4
- package/lib/module/context/xmppProvider.js.map +1 -1
- package/lib/module/helpers/callLogMessage.js +152 -0
- package/lib/module/helpers/callLogMessage.js.map +1 -0
- package/lib/module/helpers/callPush.js +55 -0
- package/lib/module/helpers/callPush.js.map +1 -0
- package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js +24 -12
- package/lib/module/helpers/constants/LANGUAGE_OPTIONS.js.map +1 -1
- package/lib/module/helpers/createUserNameFromSetUser.js +49 -1
- package/lib/module/helpers/createUserNameFromSetUser.js.map +1 -1
- package/lib/module/helpers/getDataFromXml.js +20 -1
- package/lib/module/helpers/getDataFromXml.js.map +1 -1
- package/lib/module/helpers/incomingCallFromPush.js +70 -0
- package/lib/module/helpers/incomingCallFromPush.js.map +1 -0
- package/lib/module/helpers/insertMessageWithDelimiter.js +13 -1
- package/lib/module/helpers/insertMessageWithDelimiter.js.map +1 -1
- package/lib/module/helpers/isUnresolvedSenderId.js +27 -0
- package/lib/module/helpers/isUnresolvedSenderId.js.map +1 -0
- package/lib/module/hooks/useChatSettingState.js +2 -0
- package/lib/module/hooks/useChatSettingState.js.map +1 -1
- package/lib/module/hooks/useMessageTranslation.js +46 -0
- package/lib/module/hooks/useMessageTranslation.js.map +1 -0
- package/lib/module/hooks/usePushNotifications.js +13 -3
- package/lib/module/hooks/usePushNotifications.js.map +1 -1
- package/lib/module/hooks/useSendMessage.js +12 -2
- package/lib/module/hooks/useSendMessage.js.map +1 -1
- package/lib/module/i18n/strings.js +1300 -0
- package/lib/module/i18n/strings.js.map +1 -0
- package/lib/module/i18n/useT.js +55 -0
- package/lib/module/i18n/useT.js.map +1 -0
- package/lib/module/main.js +7 -1
- package/lib/module/main.js.map +1 -1
- package/lib/module/networking/api-requests/push.api.js +35 -5
- package/lib/module/networking/api-requests/push.api.js.map +1 -1
- package/lib/module/networking/api-requests/rooms.api.js +109 -1
- package/lib/module/networking/api-requests/rooms.api.js.map +1 -1
- package/lib/module/networking/callTokenStanza.js +526 -0
- package/lib/module/networking/callTokenStanza.js.map +1 -0
- package/lib/module/networking/outboundQueue.js.map +1 -1
- package/lib/module/networking/stanzaHandlers.js +76 -9
- package/lib/module/networking/stanzaHandlers.js.map +1 -1
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js +48 -11
- package/lib/module/networking/xmpp/handleStanzas.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js +1 -1
- package/lib/module/networking/xmpp/sendTextMessage.xmpp.js.map +1 -1
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js +43 -5
- package/lib/module/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.js.map +1 -1
- package/lib/module/networking/xmppClient.js +78 -16
- package/lib/module/networking/xmppClient.js.map +1 -1
- package/lib/module/roomStore/callSlice.js +130 -0
- package/lib/module/roomStore/callSlice.js.map +1 -0
- package/lib/module/roomStore/chatSettingsSlice.js +6 -1
- package/lib/module/roomStore/chatSettingsSlice.js.map +1 -1
- package/lib/module/roomStore/index.js +6 -1
- package/lib/module/roomStore/index.js.map +1 -1
- package/lib/module/roomStore/persistence.js +69 -5
- package/lib/module/roomStore/persistence.js.map +1 -1
- package/lib/module/roomStore/roomsSlice.js +134 -5
- package/lib/module/roomStore/roomsSlice.js.map +1 -1
- package/lib/module/utils/translateModePolicy.js +27 -0
- package/lib/module/utils/translateModePolicy.js.map +1 -0
- package/lib/typescript/components/MainComponents/ChatHeader.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/ChatWrapper.d.ts.map +1 -1
- package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts +12 -0
- package/lib/typescript/components/MainComponents/LanguageSelectorButton.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts +31 -0
- package/lib/typescript/components/MainComponents/LanguageSelectorModal.d.ts.map +1 -0
- package/lib/typescript/components/MainComponents/RoomList.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/Message.d.ts.map +1 -1
- package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts +44 -0
- package/lib/typescript/components/MessageBubble/MessageTranslate.d.ts.map +1 -0
- package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts +24 -0
- package/lib/typescript/components/MessageBubble/TranslatedMessageBody.d.ts.map +1 -0
- package/lib/typescript/components/UsersList/UsersList.d.ts.map +1 -1
- package/lib/typescript/components/VideoCalls/CallButtons.d.ts +16 -0
- package/lib/typescript/components/VideoCalls/CallButtons.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/CallIcons.d.ts +30 -0
- package/lib/typescript/components/VideoCalls/CallIcons.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts +10 -0
- package/lib/typescript/components/VideoCalls/VideoCallOverlay.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts +38 -0
- package/lib/typescript/components/VideoCalls/VideoCallSession.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts +52 -0
- package/lib/typescript/components/VideoCalls/livekitRuntime.d.ts.map +1 -0
- package/lib/typescript/components/VideoCalls/useCallKeep.d.ts +32 -0
- package/lib/typescript/components/VideoCalls/useCallKeep.d.ts.map +1 -0
- package/lib/typescript/components/styled/AudioMessage.d.ts.map +1 -1
- package/lib/typescript/components/styled/RoomListComponents/index.d.ts.map +1 -1
- package/lib/typescript/components/styled/SendInput.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledComponents.d.ts.map +1 -1
- package/lib/typescript/components/styled/StyledInputComponents/Composing.d.ts.map +1 -1
- package/lib/typescript/context/xmppProvider.d.ts.map +1 -1
- package/lib/typescript/helpers/callLogMessage.d.ts +34 -0
- package/lib/typescript/helpers/callLogMessage.d.ts.map +1 -0
- package/lib/typescript/helpers/callPush.d.ts +23 -0
- package/lib/typescript/helpers/callPush.d.ts.map +1 -0
- package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts +14 -0
- package/lib/typescript/helpers/constants/LANGUAGE_OPTIONS.d.ts.map +1 -1
- package/lib/typescript/helpers/createUserNameFromSetUser.d.ts +33 -1
- package/lib/typescript/helpers/createUserNameFromSetUser.d.ts.map +1 -1
- package/lib/typescript/helpers/getDataFromXml.d.ts.map +1 -1
- package/lib/typescript/helpers/incomingCallFromPush.d.ts +14 -0
- package/lib/typescript/helpers/incomingCallFromPush.d.ts.map +1 -0
- package/lib/typescript/helpers/insertMessageWithDelimiter.d.ts.map +1 -1
- package/lib/typescript/helpers/isUnresolvedSenderId.d.ts +2 -0
- package/lib/typescript/helpers/isUnresolvedSenderId.d.ts.map +1 -0
- package/lib/typescript/hooks/useChatSettingState.d.ts +2 -1
- package/lib/typescript/hooks/useChatSettingState.d.ts.map +1 -1
- package/lib/typescript/hooks/useMessageTranslation.d.ts +25 -0
- package/lib/typescript/hooks/useMessageTranslation.d.ts.map +1 -0
- package/lib/typescript/hooks/usePushNotifications.d.ts.map +1 -1
- package/lib/typescript/hooks/useSendMessage.d.ts.map +1 -1
- package/lib/typescript/i18n/strings.d.ts +16 -0
- package/lib/typescript/i18n/strings.d.ts.map +1 -0
- package/lib/typescript/i18n/useT.d.ts +34 -0
- package/lib/typescript/i18n/useT.d.ts.map +1 -0
- package/lib/typescript/main.d.ts +6 -1
- package/lib/typescript/main.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/push.api.d.ts.map +1 -1
- package/lib/typescript/networking/api-requests/rooms.api.d.ts +3 -0
- package/lib/typescript/networking/api-requests/rooms.api.d.ts.map +1 -1
- package/lib/typescript/networking/callTokenStanza.d.ts +14 -0
- package/lib/typescript/networking/callTokenStanza.d.ts.map +1 -0
- package/lib/typescript/networking/outboundQueue.d.ts +1 -0
- package/lib/typescript/networking/outboundQueue.d.ts.map +1 -1
- package/lib/typescript/networking/stanzaHandlers.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/handleStanzas.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts +10 -0
- package/lib/typescript/networking/xmpp/sendTextMessage.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts +16 -1
- package/lib/typescript/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.d.ts.map +1 -1
- package/lib/typescript/networking/xmppClient.d.ts +1 -1
- package/lib/typescript/networking/xmppClient.d.ts.map +1 -1
- package/lib/typescript/roomStore/callSlice.d.ts +39 -0
- package/lib/typescript/roomStore/callSlice.d.ts.map +1 -0
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts +10 -1
- package/lib/typescript/roomStore/chatSettingsSlice.d.ts.map +1 -1
- package/lib/typescript/roomStore/index.d.ts +4 -0
- package/lib/typescript/roomStore/index.d.ts.map +1 -1
- package/lib/typescript/roomStore/persistence.d.ts.map +1 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts +6 -1
- package/lib/typescript/roomStore/roomsSlice.d.ts.map +1 -1
- package/lib/typescript/types/models/language.model.d.ts +1 -1
- package/lib/typescript/types/models/language.model.d.ts.map +1 -1
- package/lib/typescript/types/models/message.model.d.ts +7 -0
- package/lib/typescript/types/models/message.model.d.ts.map +1 -1
- package/lib/typescript/types/types.d.ts +135 -1
- package/lib/typescript/types/types.d.ts.map +1 -1
- package/lib/typescript/utils/translateModePolicy.d.ts +20 -0
- package/lib/typescript/utils/translateModePolicy.d.ts.map +1 -0
- package/package.json +20 -4
- package/src/components/MainComponents/ChatHeader.tsx +30 -9
- package/src/components/MainComponents/ChatWrapper.tsx +15 -0
- package/src/components/MainComponents/LanguageSelectorButton.tsx +53 -0
- package/src/components/MainComponents/LanguageSelectorModal.tsx +276 -0
- package/src/components/MainComponents/RoomList.tsx +27 -9
- package/src/components/MessageBubble/Message.tsx +109 -17
- package/src/components/MessageBubble/MessageTranslate.tsx +182 -0
- package/src/components/MessageBubble/TranslatedMessageBody.tsx +59 -0
- package/src/components/Modals/FilePreviewModal/FilePreviewModal.tsx +3 -3
- package/src/components/UsersList/UsersList.tsx +3 -1
- package/src/components/VideoCalls/CallButtons.tsx +171 -0
- package/src/components/VideoCalls/CallIcons.tsx +246 -0
- package/src/components/VideoCalls/VideoCallOverlay.tsx +627 -0
- package/src/components/VideoCalls/VideoCallSession.tsx +675 -0
- package/src/components/VideoCalls/livekitRuntime.ts +100 -0
- package/src/components/VideoCalls/useCallKeep.ts +252 -0
- package/src/components/styled/AudioMessage.tsx +97 -37
- package/src/components/styled/RoomListComponents/index.tsx +15 -3
- package/src/components/styled/SendInput.tsx +94 -51
- package/src/components/styled/StyledComponents.ts +9 -6
- package/src/components/styled/StyledInputComponents/Composing.tsx +7 -1
- package/src/context/xmppProvider.tsx +14 -1
- package/src/helpers/callLogMessage.ts +174 -0
- package/src/helpers/callPush.ts +90 -0
- package/src/helpers/constants/LANGUAGE_OPTIONS.ts +20 -5
- package/src/helpers/createUserNameFromSetUser.ts +68 -2
- package/src/helpers/getDataFromXml.ts +40 -4
- package/src/helpers/incomingCallFromPush.ts +83 -0
- package/src/helpers/insertMessageWithDelimiter.ts +27 -9
- package/src/helpers/isUnresolvedSenderId.ts +25 -0
- package/src/hooks/useChatSettingState.tsx +4 -0
- package/src/hooks/useMessageTranslation.ts +70 -0
- package/src/hooks/usePushNotifications.ts +15 -3
- package/src/hooks/useSendMessage.tsx +15 -2
- package/src/i18n/strings.ts +1322 -0
- package/src/i18n/useT.ts +56 -0
- package/src/main.ts +18 -1
- package/src/networking/api-requests/push.api.ts +39 -8
- package/src/networking/api-requests/rooms.api.ts +109 -1
- package/src/networking/callTokenStanza.ts +636 -0
- package/src/networking/outboundQueue.ts +1 -0
- package/src/networking/stanzaHandlers.ts +74 -15
- package/src/networking/xmpp/handleStanzas.xmpp.ts +52 -11
- package/src/networking/xmpp/sendTextMessage.xmpp.ts +1 -1
- package/src/networking/xmpp/sendTextMessageWithTranslateTag.xmpp.ts +41 -5
- package/src/networking/xmppClient.ts +97 -28
- package/src/roomStore/callSlice.ts +190 -0
- package/src/roomStore/chatSettingsSlice.ts +16 -0
- package/src/roomStore/index.ts +5 -0
- package/src/roomStore/persistence.ts +103 -3
- package/src/roomStore/roomsSlice.ts +149 -4
- package/src/types/models/language.model.ts +17 -1
- package/src/types/models/message.model.ts +9 -0
- package/src/types/types.ts +142 -2
- package/src/utils/translateModePolicy.ts +31 -0
|
@@ -1,5 +1,11 @@
|
|
|
1
|
-
import { RoomMember } from '../types/types';
|
|
1
|
+
import { IMessage, RoomMember } from '../types/types';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Cache-only lookup. Returns the literal "Deleted User" as a MISS sentinel
|
|
5
|
+
* when `usersSet` has no entry for `userId` yet, callers that want a
|
|
6
|
+
* better fallback (e.g. resolveSenderDisplayName below) check for that
|
|
7
|
+
* exact string rather than treating it as a real name.
|
|
8
|
+
*/
|
|
3
9
|
export const createUserNameFromSetUser = (
|
|
4
10
|
usersSet: Record<string, RoomMember>,
|
|
5
11
|
userId: string
|
|
@@ -10,6 +16,66 @@ export const createUserNameFromSetUser = (
|
|
|
10
16
|
|
|
11
17
|
const firstName = user.firstName?.trim() || '';
|
|
12
18
|
const lastName = user.lastName?.trim() || '';
|
|
19
|
+
// REST-loaded members carry firstName/lastName; XMPP-roster-only
|
|
20
|
+
// members (no REST match yet) carry just the roster `name` attr —
|
|
21
|
+
// fall back to that before giving up and returning the raw id.
|
|
22
|
+
const bareName = user.name?.trim() || '';
|
|
13
23
|
|
|
14
|
-
return `${firstName} ${lastName}`.trim() || userId;
|
|
24
|
+
return `${firstName} ${lastName}`.trim() || bareName || userId;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* The sender's display name, resolved WITHOUT depending on `usersSet`
|
|
29
|
+
* having already been hydrated.
|
|
30
|
+
*
|
|
31
|
+
* `usersSet` is populated by a separate fetch (member list / presence) that
|
|
32
|
+
* can still be in flight when a message arrives, most reliably right after
|
|
33
|
+
* reconnect, when a burst of catch-up messages can land before that fetch
|
|
34
|
+
* resolves. A cache-only lookup shows the literal "Deleted User" for every
|
|
35
|
+
* one of those messages, even though the sender is very much not deleted.
|
|
36
|
+
* On mobile this is the common case, not the rare one: every return from
|
|
37
|
+
* background reconnects.
|
|
38
|
+
*
|
|
39
|
+
* The message itself already carries the sender's name on the wire: every
|
|
40
|
+
* client that sends through this SDK stamps `senderFirstName` /
|
|
41
|
+
* `senderLastName` / `fullName` onto the outgoing stanza's `<data>` element
|
|
42
|
+
* (see sendTextMessage.xmpp.ts / sendTextMessageWithTranslateTag.xmpp.ts),
|
|
43
|
+
* and createMessageFromXml spreads those onto the top-level message object.
|
|
44
|
+
* Preferring that over the cache removes the timing dependency entirely for
|
|
45
|
+
* the common case, and "Deleted User" becomes what it should have always
|
|
46
|
+
* been: a rare last resort, not "usersSet hasn't loaded yet".
|
|
47
|
+
*/
|
|
48
|
+
export const resolveSenderDisplayName = (
|
|
49
|
+
message: Pick<IMessage, 'user'> & {
|
|
50
|
+
fullName?: string;
|
|
51
|
+
senderFirstName?: string;
|
|
52
|
+
senderLastName?: string;
|
|
53
|
+
},
|
|
54
|
+
usersSet: Record<string, RoomMember>
|
|
55
|
+
): string => {
|
|
56
|
+
const rawUserId = String(message?.user?.id || '');
|
|
57
|
+
const localUserId = rawUserId.split('@')[0];
|
|
58
|
+
const currentNameRaw = String(message?.user?.name || '').trim();
|
|
59
|
+
// A previously-resolved "Deleted User" is itself a miss sentinel, not a
|
|
60
|
+
// real name, don't let it short-circuit the fallback chain below.
|
|
61
|
+
const currentName = currentNameRaw === 'Deleted User' ? '' : currentNameRaw;
|
|
62
|
+
|
|
63
|
+
const dataFullName = String(message?.fullName || '').trim();
|
|
64
|
+
const dataFirst = String(message?.senderFirstName || '').trim();
|
|
65
|
+
const dataLast = String(message?.senderLastName || '').trim();
|
|
66
|
+
const composedFromData = dataFullName || `${dataFirst} ${dataLast}`.trim();
|
|
67
|
+
|
|
68
|
+
const usersSetName = createUserNameFromSetUser(usersSet, localUserId);
|
|
69
|
+
const usersSetNameAlt = createUserNameFromSetUser(usersSet, rawUserId);
|
|
70
|
+
const isUsersSetUseful = (name: string) => !!name && name !== 'Deleted User';
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
currentName ||
|
|
74
|
+
(isUsersSetUseful(usersSetName) && usersSetName) ||
|
|
75
|
+
(isUsersSetUseful(usersSetNameAlt) && usersSetNameAlt) ||
|
|
76
|
+
composedFromData ||
|
|
77
|
+
localUserId ||
|
|
78
|
+
rawUserId ||
|
|
79
|
+
'Deleted User'
|
|
80
|
+
);
|
|
15
81
|
};
|
|
@@ -2,6 +2,38 @@ import { Element } from 'ltx';
|
|
|
2
2
|
import { Iso639_1Codes, IUser } from '../types/types';
|
|
3
3
|
import { transformArrayToObject } from './transformTranslatations';
|
|
4
4
|
|
|
5
|
+
// Tolerant JSON parse: a malformed `translations` attr must not reject the
|
|
6
|
+
// whole stanza (which would silently drop the message). Mirrors the web
|
|
7
|
+
// SDK's safeJsonParse.
|
|
8
|
+
const safeJsonParse = <T,>(value: unknown, fallback: T): T => {
|
|
9
|
+
if (typeof value !== 'string' || !value) {return fallback;}
|
|
10
|
+
try {
|
|
11
|
+
return JSON.parse(value) as T;
|
|
12
|
+
} catch {
|
|
13
|
+
return fallback;
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
// Keep only well-formed translation entries (drops partial/garbage items),
|
|
18
|
+
// same shape guard the web SDK applies before transformArrayToObject.
|
|
19
|
+
const normalizeTranslations = (value: unknown) =>
|
|
20
|
+
Array.isArray(value)
|
|
21
|
+
? value.filter(
|
|
22
|
+
(
|
|
23
|
+
item
|
|
24
|
+
): item is {
|
|
25
|
+
translatedText: string;
|
|
26
|
+
language: string;
|
|
27
|
+
languageName: string;
|
|
28
|
+
} =>
|
|
29
|
+
!!item &&
|
|
30
|
+
typeof item === 'object' &&
|
|
31
|
+
typeof (item as any).translatedText === 'string' &&
|
|
32
|
+
typeof (item as any).language === 'string' &&
|
|
33
|
+
typeof (item as any).languageName === 'string'
|
|
34
|
+
)
|
|
35
|
+
: [];
|
|
36
|
+
|
|
5
37
|
const extractTimestamp = (str: string, stanza?: any): string | null => {
|
|
6
38
|
if (!str) {return null;}
|
|
7
39
|
if (typeof str !== 'string') {
|
|
@@ -43,12 +75,16 @@ export const getDataFromXml = async (stanza: Element): Promise<DataXml | undefin
|
|
|
43
75
|
|
|
44
76
|
const body = fullData?.getChild('body')?.getText() || undefined;
|
|
45
77
|
const deleted = !!fullData?.getChild('deleted');
|
|
78
|
+
const translationPayload = safeJsonParse<{ translates?: unknown[] }>(
|
|
79
|
+
fullData?.getChild('translations')?.attrs?.value,
|
|
80
|
+
{}
|
|
81
|
+
);
|
|
46
82
|
const translations = fullData?.getChild('translations')?.attrs?.value
|
|
47
|
-
? transformArrayToObject(
|
|
48
|
-
JSON.parse(fullData.getChild('translations')!.attrs.value).translates
|
|
49
|
-
)
|
|
83
|
+
? transformArrayToObject(normalizeTranslations(translationPayload.translates))
|
|
50
84
|
: undefined;
|
|
51
|
-
const langSource = fullData?.getChild('translate')?.attrs?.source
|
|
85
|
+
const langSource = fullData?.getChild('translate')?.attrs?.source as
|
|
86
|
+
| Iso639_1Codes
|
|
87
|
+
| undefined;
|
|
52
88
|
const numericPart = /\d{13,}/.exec(id || '')?.[0];
|
|
53
89
|
const date = numericPart
|
|
54
90
|
? new Date(+numericPart.slice(0, 13)).toISOString()
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { store } from '../roomStore';
|
|
2
|
+
import { setIncomingCallToken } from '../roomStore/callSlice';
|
|
3
|
+
import { isCallPush, parseCallPush } from './callPush';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Turn an incoming-call push into a ringing call.
|
|
7
|
+
*
|
|
8
|
+
* On mobile the XMPP socket dies whenever the OS backgrounds or kills the
|
|
9
|
+
* app, and the `call-token` stanza that normally opens the ring screen is
|
|
10
|
+
* lost with it. The backend also delivers the call as a data push, so this
|
|
11
|
+
* is the path every call takes when the app was not in the foreground.
|
|
12
|
+
*
|
|
13
|
+
* Returns true when the payload WAS a call push (whether or not it could
|
|
14
|
+
* be rung), so the caller knows to stop and not also show it as a chat
|
|
15
|
+
* notification. A user should never get a "new message: call-state" toast.
|
|
16
|
+
*/
|
|
17
|
+
export const handleCallPush = (
|
|
18
|
+
data: Record<string, any> | null | undefined
|
|
19
|
+
): boolean => {
|
|
20
|
+
if (!isCallPush(data)) {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const parsed = parseCallPush(data);
|
|
25
|
+
const state = store.getState();
|
|
26
|
+
|
|
27
|
+
// Calls off in this deployment: swallow the push rather than ringing a
|
|
28
|
+
// screen the host never opted into.
|
|
29
|
+
if (state.chatSettingStore.config?.videoCalls?.enabled !== true) {
|
|
30
|
+
return true;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Already ringing or in this exact call (the push raced the stanza, or
|
|
34
|
+
// two pushes arrived). Re-dispatching would reset startedAt and restart
|
|
35
|
+
// the ring, so leave the existing call alone.
|
|
36
|
+
const current = state.call;
|
|
37
|
+
if (current.phase !== 'idle') {
|
|
38
|
+
const sameCall =
|
|
39
|
+
(!!parsed.callId && parsed.callId === current.callId) ||
|
|
40
|
+
(!!parsed.roomBareName && parsed.roomBareName === current.roomBareName);
|
|
41
|
+
if (sameCall || current.phase === 'in-call') {
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Without a LiveKit token there is nothing to accept: the push is only
|
|
47
|
+
// an alert. Ringing anyway would give the user an Accept button that
|
|
48
|
+
// cannot work, so treat it as handled and let the stanza (once the
|
|
49
|
+
// socket is back up) open the real ring screen.
|
|
50
|
+
if (!parsed.token) {
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Resolve the full room JID from the local room map. The push carries
|
|
55
|
+
// the bare name; callSlice and the hangup signal both want the JID.
|
|
56
|
+
const rooms = state.rooms.rooms || {};
|
|
57
|
+
const resolved = Object.values(rooms).find(
|
|
58
|
+
(room: any) =>
|
|
59
|
+
(room?.jid || '').split('@')[0] === parsed.roomBareName ||
|
|
60
|
+
room?.jid === parsed.roomRef
|
|
61
|
+
) as { jid?: string; name?: string } | undefined;
|
|
62
|
+
|
|
63
|
+
const roomJid =
|
|
64
|
+
resolved?.jid ||
|
|
65
|
+
(parsed.roomRef && parsed.roomRef.includes('@') ? parsed.roomRef : '');
|
|
66
|
+
if (!roomJid) {
|
|
67
|
+
return true;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
store.dispatch(
|
|
71
|
+
setIncomingCallToken({
|
|
72
|
+
roomJid,
|
|
73
|
+
roomName: parsed.callerName || resolved?.name || null,
|
|
74
|
+
roomBareName: parsed.roomBareName,
|
|
75
|
+
token: parsed.token,
|
|
76
|
+
kind: parsed.kind,
|
|
77
|
+
callId: parsed.callId,
|
|
78
|
+
peerXmppUsername: parsed.callerXmppUsername,
|
|
79
|
+
})
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
return true;
|
|
83
|
+
};
|
|
@@ -71,20 +71,38 @@ export function insertMessageWithDelimiter(
|
|
|
71
71
|
isDateAfter(msg.date?.toString() ?? '', lastViewedTimestamp.toString())
|
|
72
72
|
);
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
if (delimiterIndex !== -1) {
|
|
75
|
+
// The divider's date is what ORDERS it: roomsSlice re-sorts every
|
|
76
|
+
// merged page by timestamp (see `byMs`), so a divider stamped with
|
|
77
|
+
// `new Date()` — i.e. now — sorted past every real message and
|
|
78
|
+
// rendered at the very bottom, BELOW the new messages it is
|
|
79
|
+
// supposed to introduce. Anchor it a hair before the first unread
|
|
80
|
+
// instead, which is where it belongs and where any later sort keeps
|
|
81
|
+
// it. Derived from that message rather than from
|
|
82
|
+
// lastViewedTimestamp so it works whatever format the caller passes.
|
|
83
|
+
const firstUnreadMs = Date.parse(
|
|
84
|
+
String(roomMessages[delimiterIndex]?.date ?? '')
|
|
85
|
+
);
|
|
86
|
+
const rawLastViewed = lastViewedTimestamp.toString();
|
|
87
|
+
const lastViewedMs =
|
|
88
|
+
Date.parse(rawLastViewed) || Number(rawLastViewed) || Date.now();
|
|
89
|
+
const anchorMs = Number.isFinite(firstUnreadMs)
|
|
90
|
+
? firstUnreadMs - 1
|
|
91
|
+
: lastViewedMs;
|
|
92
|
+
|
|
93
|
+
roomMessages.splice(delimiterIndex, 0, {
|
|
94
|
+
id: 'delimiter-new',
|
|
95
|
+
user: {
|
|
78
96
|
id: 'system',
|
|
79
97
|
name: undefined,
|
|
80
98
|
token: '',
|
|
81
99
|
refreshToken: '',
|
|
82
100
|
},
|
|
83
|
-
date: new Date().
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
101
|
+
date: new Date(anchorMs).toISOString(),
|
|
102
|
+
body: 'New Messages',
|
|
103
|
+
roomJid: '',
|
|
104
|
+
});
|
|
105
|
+
}
|
|
88
106
|
}
|
|
89
107
|
} else if (
|
|
90
108
|
isDateBefore(newMessageDate.toString(), firstMessage?.date?.toString() ?? '')
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Whether a resolved sender "name" is really just an unresolved id.
|
|
3
|
+
*
|
|
4
|
+
* The name chain ends at the sender's JID localpart when `usersSet` has no
|
|
5
|
+
* entry and the wire carried no name. For a real member that never happens
|
|
6
|
+
* for long — the REST roster fills the cache in. But some senders are not
|
|
7
|
+
* members at all: a broadcast posted by the app itself arrives with the
|
|
8
|
+
* ROOM's own id as its occupant resource (e.g.
|
|
9
|
+
* `646cc8dc96d4a4dc8f7b2f2d_67f6823cf5995841ba431f06`), so no roster will
|
|
10
|
+
* ever resolve it and the bubble ends up captioned with 50 characters of
|
|
11
|
+
* hex.
|
|
12
|
+
*
|
|
13
|
+
* Ethora ids are `<24-hex appId>_<24-hex objectId>`, which is what this
|
|
14
|
+
* matches. A raw objectId on its own is matched too, since some senders
|
|
15
|
+
* carry only that half.
|
|
16
|
+
*/
|
|
17
|
+
const ETHORA_ID = /^[0-9a-f]{24}(_[0-9a-f]{24})?$/i;
|
|
18
|
+
|
|
19
|
+
export const isUnresolvedSenderId = (name?: string): boolean => {
|
|
20
|
+
const trimmed = String(name || '').trim();
|
|
21
|
+
if (!trimmed) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
return ETHORA_ID.test(trimmed);
|
|
25
|
+
};
|
|
@@ -24,6 +24,9 @@ export const useChatSettingState = () => {
|
|
|
24
24
|
const client = useSelector(
|
|
25
25
|
(state: RootState) => state.chatSettingStore.client
|
|
26
26
|
);
|
|
27
|
+
const translateMode = useSelector(
|
|
28
|
+
(state: RootState) => state.chatSettingStore.translateMode
|
|
29
|
+
);
|
|
27
30
|
|
|
28
31
|
return {
|
|
29
32
|
user,
|
|
@@ -33,6 +36,7 @@ export const useChatSettingState = () => {
|
|
|
33
36
|
deleteModal,
|
|
34
37
|
selectedUser,
|
|
35
38
|
langSource,
|
|
39
|
+
translateMode,
|
|
36
40
|
client,
|
|
37
41
|
};
|
|
38
42
|
};
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { IMessage } from '../types/types';
|
|
2
|
+
import { toBaseLanguage } from '../i18n/strings';
|
|
3
|
+
|
|
4
|
+
export interface MessageTranslationState {
|
|
5
|
+
/** False when the message is already in the reader's language, or no
|
|
6
|
+
* translation is available — render the plain body, no quote. */
|
|
7
|
+
hasTranslation: boolean;
|
|
8
|
+
originalText: string;
|
|
9
|
+
/** Translation when hasTranslation, else the original — always safe to
|
|
10
|
+
* render directly. */
|
|
11
|
+
displayText: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// "42", "+1 (555) 123-4567", "3.14159" — text with no actual letters has
|
|
15
|
+
// nothing to translate.
|
|
16
|
+
const hasNoLetters = (text: string): boolean => !/\p{L}/u.test(text);
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Translation for ONE message, into the reader's language only. Ported
|
|
20
|
+
* verbatim from the web SDK (src/hooks/useMessageTranslation.ts).
|
|
21
|
+
*
|
|
22
|
+
* Pure and synchronous — no HTTP call. Every translation this client ever
|
|
23
|
+
* shows arrives over XMPP already: the sender tags outgoing messages with
|
|
24
|
+
* `<translate source="xx"/>` (see sendTextMessageWithTranslateTag) and
|
|
25
|
+
* whatever process attaches actual translations does so server-side,
|
|
26
|
+
* landing on `message.translations` when the stanza is parsed (see
|
|
27
|
+
* getDataFromXml). This function only ever reads that — it never calls a
|
|
28
|
+
* translation service itself, so there's nothing to fail when one isn't
|
|
29
|
+
* reachable, and nothing to await.
|
|
30
|
+
*/
|
|
31
|
+
export const useMessageTranslation = (
|
|
32
|
+
message: Pick<IMessage, 'body' | 'langSource' | 'translations'>,
|
|
33
|
+
readerLocale?: string,
|
|
34
|
+
enabled = true
|
|
35
|
+
): MessageTranslationState => {
|
|
36
|
+
const originalText = message?.body || '';
|
|
37
|
+
const source = message?.langSource;
|
|
38
|
+
const targetBase = toBaseLanguage(readerLocale || 'en');
|
|
39
|
+
const sourceBase = toBaseLanguage(source);
|
|
40
|
+
|
|
41
|
+
// Nothing to do when we don't know the source language, the message is
|
|
42
|
+
// already in the reader's language (region ignored: en-US vs en-CA is the
|
|
43
|
+
// same language, not a translation job), or there's no actual text to
|
|
44
|
+
// translate (a bare number, a phone number, an emoji-only reaction).
|
|
45
|
+
const trimmedText = originalText.trim();
|
|
46
|
+
const needsTranslation =
|
|
47
|
+
enabled &&
|
|
48
|
+
!!trimmedText &&
|
|
49
|
+
!!source &&
|
|
50
|
+
sourceBase !== targetBase &&
|
|
51
|
+
!hasNoLetters(trimmedText);
|
|
52
|
+
|
|
53
|
+
const result = needsTranslation
|
|
54
|
+
? message?.translations?.[readerLocale || '']?.translatedText ||
|
|
55
|
+
message?.translations?.[targetBase]?.translatedText
|
|
56
|
+
: undefined;
|
|
57
|
+
|
|
58
|
+
// A "translation" that's byte-identical to the original (mistagged
|
|
59
|
+
// langSource, a no-op from the source, matching proper nouns/numbers in
|
|
60
|
+
// otherwise-different text) is worse than nothing: it renders the same
|
|
61
|
+
// sentence twice. Treat identical-after-trim as "nothing to show".
|
|
62
|
+
const isRealTranslation =
|
|
63
|
+
!!result && result.trim() !== originalText.trim();
|
|
64
|
+
|
|
65
|
+
return {
|
|
66
|
+
hasTranslation: isRealTranslation,
|
|
67
|
+
originalText,
|
|
68
|
+
displayText: isRealTranslation ? (result as string) : originalText,
|
|
69
|
+
};
|
|
70
|
+
};
|
|
@@ -10,7 +10,8 @@ import { pushSubscriptionService } from '../services/pushSubscriptionService';
|
|
|
10
10
|
import { useSelector, useDispatch } from 'react-redux';
|
|
11
11
|
import { RootState } from '../roomStore';
|
|
12
12
|
import { useLocalStorage } from './useLocalStorage';
|
|
13
|
-
import {
|
|
13
|
+
import { setPendingNotificationJid } from '../roomStore/roomsSlice';
|
|
14
|
+
import { handleCallPush } from '../helpers/incomingCallFromPush';
|
|
14
15
|
|
|
15
16
|
export function usePushNotifications() {
|
|
16
17
|
const [fcmToken, setFcmToken] = useState<string | null>(null);
|
|
@@ -22,7 +23,11 @@ export function usePushNotifications() {
|
|
|
22
23
|
const { set, get } = useLocalStorage('fcmToken');
|
|
23
24
|
|
|
24
25
|
const handleNotificationPress = (remoteMessage: any) => {
|
|
25
|
-
|
|
26
|
+
// Tapping a call notification (or launching the app from one) should
|
|
27
|
+
// land on the ring screen, not on the chat room.
|
|
28
|
+
if (handleCallPush(remoteMessage?.data)) {
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
26
31
|
|
|
27
32
|
const jid = remoteMessage?.data?.jid || remoteMessage?.data?.chatJid || remoteMessage?.jid;
|
|
28
33
|
|
|
@@ -60,9 +65,16 @@ export function usePushNotifications() {
|
|
|
60
65
|
);
|
|
61
66
|
|
|
62
67
|
const unsubscribeForeground = onForegroundMessage((message) => {
|
|
68
|
+
// Calls first: a call push must open the ring screen, never an
|
|
69
|
+
// "OK / Open" alert. handleCallPush returns true for anything
|
|
70
|
+
// call-shaped, so we bail before the chat-notification path.
|
|
71
|
+
if (handleCallPush(message?.data)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
63
75
|
setNotification(message);
|
|
64
76
|
|
|
65
|
-
const { notification: notif
|
|
77
|
+
const { notification: notif } = message;
|
|
66
78
|
if (notif) {
|
|
67
79
|
Alert.alert(
|
|
68
80
|
notif.title || 'Notification',
|
|
@@ -70,6 +70,14 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
70
70
|
const config = useSelector(
|
|
71
71
|
(state: RootState) => state.chatSettingStore.config
|
|
72
72
|
);
|
|
73
|
+
// The sender's own language, driven by the header globe picker (or the
|
|
74
|
+
// host via config.translates.readerLocale). Declared on every outgoing
|
|
75
|
+
// message as `<translate source>` so the backend can translate it for
|
|
76
|
+
// readers in other languages (see sendTextMessageWithTranslateTagStanza).
|
|
77
|
+
// Mirrors the web SDK, which always sends through the translate-tag path.
|
|
78
|
+
const langSource = useSelector(
|
|
79
|
+
(state: RootState) => state.chatSettingStore.langSource
|
|
80
|
+
);
|
|
73
81
|
const editAction = useSelector((state: RootState) => state.rooms.editAction);
|
|
74
82
|
const rooms = useSelector((state: RootState) => state.rooms.rooms);
|
|
75
83
|
|
|
@@ -150,6 +158,10 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
150
158
|
date: optimisticDate,
|
|
151
159
|
pending: true,
|
|
152
160
|
isDeleted: false,
|
|
161
|
+
// Declare the sender's language on their own optimistic bubble so
|
|
162
|
+
// manual-mode readers see the Translate link on it too (parity with
|
|
163
|
+
// the web SDK, which stamps langSource on the optimistic message).
|
|
164
|
+
langSource: (langSource as any) || 'en',
|
|
153
165
|
user: {
|
|
154
166
|
...(user as any),
|
|
155
167
|
id: selfId,
|
|
@@ -208,7 +220,7 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
208
220
|
// reducer's dedupe matches and the bubble flips pending → delivered
|
|
209
221
|
// in-place (rather than rendering a second copy).
|
|
210
222
|
const replaySend = (c: any) =>
|
|
211
|
-
c.
|
|
223
|
+
c.sendTextMessageWithTranslateTagStanza(
|
|
212
224
|
activeRoomJID,
|
|
213
225
|
user.firstName,
|
|
214
226
|
user.lastName,
|
|
@@ -219,6 +231,7 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
219
231
|
isReply || false,
|
|
220
232
|
isChecked || false,
|
|
221
233
|
mainMessage || '',
|
|
234
|
+
(langSource as any) || 'en',
|
|
222
235
|
optimisticId
|
|
223
236
|
);
|
|
224
237
|
|
|
@@ -291,7 +304,7 @@ export const useSendMessage = (_configOverride?: IConfig) => {
|
|
|
291
304
|
});
|
|
292
305
|
}
|
|
293
306
|
},
|
|
294
|
-
[editAction, client, user, dispatch, handleMessageSent, handleMessageEdited, handleMessageFailed, reduxStore]
|
|
307
|
+
[editAction, client, user, langSource, dispatch, handleMessageSent, handleMessageEdited, handleMessageFailed, reduxStore]
|
|
295
308
|
);
|
|
296
309
|
|
|
297
310
|
const sendMedia = useCallback(
|