From c38c87e26a43ee1095ef898c4f24aff68bc767ee Mon Sep 17 00:00:00 2001 From: Narasimha-sc <166327228+Narasimha-sc@users.noreply.github.com> Date: Thu, 30 Jul 2026 16:34:22 +0000 Subject: [PATCH] android, desktop: don't switch profile when prepared chat reassignment fails changeActiveUser_ was called outside the guards that check whether apiChangePreparedContactUser / apiChangePreparedGroupUser actually succeeded. When the reassignment failed the app still switched to the other profile, leaving the invitation behind in the original one - and keepingChatId then held a chat belonging to a different user. Reachable today: open a link, expand the profile picker, and have the connection start in the window before tapping. profileChangeProhibited flips to true, the API returns null, and the switch happened anyway. The sibling picker in NewChatView already guards this correctly. iOS is unaffected: there apiChangePreparedContactUser throws, so a failure skips the switch by control flow. --- .../chat/ComposeContextProfilePickerView.kt | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextProfilePickerView.kt b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextProfilePickerView.kt index b7be49055e..875021df68 100644 --- a/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextProfilePickerView.kt +++ b/apps/multiplatform/common/src/commonMain/kotlin/chat/simplex/common/views/chat/ComposeContextProfilePickerView.kt @@ -79,6 +79,7 @@ fun ComposeContextProfilePickerView( fun changeProfile(newUser: User) { withApi { + var chatMoved = false if (chat.chatInfo is ChatInfo.Direct) { val updatedContact = chatModel.controller.apiChangePreparedContactUser(rhId, chat.chatInfo.contact.contactId, newUser.userId) if (updatedContact != null) { @@ -86,6 +87,7 @@ fun ComposeContextProfilePickerView( chatModel.controller.appPrefs.incognito.set(false) listExpanded.value = false chatModel.chatsContext.updateContact(rhId, updatedContact) + chatMoved = true } } else if (chat.chatInfo is ChatInfo.Group) { val updatedGroup = chatModel.controller.apiChangePreparedGroupUser(rhId, chat.chatInfo.groupInfo.groupId, newUser.userId) @@ -94,19 +96,24 @@ fun ComposeContextProfilePickerView( chatModel.controller.appPrefs.incognito.set(false) listExpanded.value = false chatModel.chatsContext.updateGroup(rhId, updatedGroup) + chatMoved = true } } - chatModel.controller.changeActiveUser_( - rhId = newUser.remoteHostId, - toUserId = newUser.userId, - viewPwd = null, - keepingChatId = chat.id - ) - if (chatModel.currentUser.value?.userId != newUser.userId) { - AlertManager.shared.showAlertMsg( - generalGetString(MR.strings.switching_profile_error_title), - String.format(generalGetString(MR.strings.switching_profile_error_message), newUser.chatViewName) + // Only switch profile if the chat was actually moved to it, otherwise the user + // would end up in another profile with the invitation left behind in this one. + if (chatMoved) { + chatModel.controller.changeActiveUser_( + rhId = newUser.remoteHostId, + toUserId = newUser.userId, + viewPwd = null, + keepingChatId = chat.id ) + if (chatModel.currentUser.value?.userId != newUser.userId) { + AlertManager.shared.showAlertMsg( + generalGetString(MR.strings.switching_profile_error_title), + String.format(generalGetString(MR.strings.switching_profile_error_message), newUser.chatViewName) + ) + } } } }