diff --git a/shared/constants/platform-specific/push.native.tsx b/shared/constants/platform-specific/push.native.tsx index 716e27d4257b..ab16b4610e4e 100644 --- a/shared/constants/platform-specific/push.native.tsx +++ b/shared/constants/platform-specific/push.native.tsx @@ -29,12 +29,14 @@ type DataNewMessage = DataCommon & { convID?: string t: string | number m: string + username?: string } type DataNewMessageSilent2 = DataCommon & { type: 'chat.newmessageSilent_2' t: string | number c?: string m: string + username?: string } type DataFollow = DataCommon & { type: 'follow' @@ -43,6 +45,7 @@ type DataFollow = DataCommon & { type DataChatExtension = DataCommon & { type: 'chat.extension' convID?: string + username?: string } type Data = DataReadMessage | DataNewMessage | DataNewMessageSilent2 | DataFollow | DataChatExtension @@ -94,6 +97,7 @@ const normalizePush = (_n?: object): T.Push.PushNotification | undefined => { ? { conversationIDKey: T.Chat.stringToConversationIDKey(data.convID), membersType: anyToConversationMembersType(data.t), + recipientUsername: data.username, type: 'chat.newmessage', unboxPayload: data.m || '', userInteraction, @@ -106,6 +110,7 @@ const normalizePush = (_n?: object): T.Push.PushNotification | undefined => { return { conversationIDKey: T.Chat.stringToConversationIDKey(data.c), membersType, + recipientUsername: data.username, type: 'chat.newmessageSilent_2', unboxPayload: data.m || '', } @@ -124,6 +129,7 @@ const normalizePush = (_n?: object): T.Push.PushNotification | undefined => { return data.convID ? { conversationIDKey: T.Chat.stringToConversationIDKey(data.convID), + recipientUsername: data.username, type: 'chat.extension', } : undefined diff --git a/shared/constants/push.native.tsx b/shared/constants/push.native.tsx index aeaa9da328a1..625a9f09eb39 100644 --- a/shared/constants/push.native.tsx +++ b/shared/constants/push.native.tsx @@ -146,6 +146,40 @@ export const useState_ = Z.createZustand((set, get) => { try { logger.info('[Push]: ' + notification.type || 'unknown') + const switchToRecipientIfNeeded = async (recipientUsername?: string): Promise => { + if (!recipientUsername) { + return true + } + const currentUsername = C.useCurrentUserState.getState().username + if (recipientUsername === currentUsername) { + return true + } + + logger.info(`[Push] notification is for different user: ${recipientUsername} vs ${currentUsername}`) + + const configuredAccounts = C.useConfigState.getState().configuredAccounts + const targetAccount = configuredAccounts.find(acc => acc.username === recipientUsername) + + if (!targetAccount) { + logger.info(`[Push] recipient account not found in configured accounts`) + return false + } + + if (!targetAccount.hasStoredSecret) { + logger.info(`[Push] recipient account has no stored secrets, cannot auto-login`) + return false + } + + logger.info(`[Push] auto-switching to account ${targetAccount.username}`) + const setUserSwitching = C.useConfigState.getState().dispatch.setUserSwitching + const login = C.useConfigState.getState().dispatch.login + setUserSwitching(true) + login(targetAccount.username, '') + await C.timeoutPromise(1500) + + return true + } + switch (notification.type) { case 'chat.readmessage': logger.info('[Push] read message') @@ -157,7 +191,9 @@ export const useState_ = Z.createZustand((set, get) => { // entirely handled by go on ios and in onNotification on Android break case 'chat.newmessage': - await handleLoudMessage(notification) + if (await switchToRecipientIfNeeded(notification.recipientUsername)) { + await handleLoudMessage(notification) + } break case 'follow': // We only care if the user clicked while in session @@ -169,8 +205,10 @@ export const useState_ = Z.createZustand((set, get) => { break case 'chat.extension': { - const {conversationIDKey} = notification - C.getConvoState(conversationIDKey).dispatch.navigateToThread('extension') + const {conversationIDKey, recipientUsername} = notification + if (await switchToRecipientIfNeeded(recipientUsername)) { + C.getConvoState(conversationIDKey).dispatch.navigateToThread('extension') + } } break case 'settings.contacts': diff --git a/shared/constants/types/push.tsx b/shared/constants/types/push.tsx index 8b35307b1543..680e2d116031 100644 --- a/shared/constants/types/push.tsx +++ b/shared/constants/types/push.tsx @@ -11,12 +11,14 @@ export type PushNotification = | { conversationIDKey: ChatTypes.ConversationIDKey membersType: RPCChatTypes.ConversationMembersType + recipientUsername?: string type: 'chat.newmessageSilent_2' unboxPayload: string } | { conversationIDKey: ChatTypes.ConversationIDKey membersType?: RPCChatTypes.ConversationMembersType + recipientUsername?: string type: 'chat.newmessage' unboxPayload: string userInteraction: boolean @@ -27,8 +29,9 @@ export type PushNotification = username: string } | { - type: 'chat.extension' conversationIDKey: ChatTypes.ConversationIDKey + recipientUsername?: string + type: 'chat.extension' } | { type: 'settings.contacts'