diff --git a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift index a140d95769..b7ada05208 100644 --- a/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift +++ b/apps/ios/Shared/Views/Chat/ComposeMessage/ContextProfilePickerView.swift @@ -295,14 +295,16 @@ struct ContextProfilePickerView: View { users.append(newUser) } } + let updatedUsers = try? await listUsersAsync() // changeProfile resolves the prepared chat under whatever is active when it runs, - // and a notification action can have switched it while we were creating. + // and a notification action can have switched it while we were creating. After the + // await above, not before it: checked first, that await reopens the very window + // this closes. Kotlin orders it the same way. guard await MainActor.run({ chatModel.currentUser?.userId }) == ownerUserId else { await MainActor.run { showAddProfile = false } alertAfterDismissal(NSLocalizedString("Error changing chat profile", comment: "alert title")) return } - let updatedUsers = try? await listUsersAsync() await MainActor.run { if let updatedUsers = updatedUsers { chatModel.users = updatedUsers @@ -361,13 +363,13 @@ struct ContextProfilePickerView: View { private func incognitoOption() -> some View { Button { - // As in profilerPickerUserOption: a failed changeProfile would leave the - // incognito default on while the picker still shows the chat profile. - if busy { return } if !chat.chatInfo.profileChangeProhibited { if incognitoDefault { listExpanded.toggle() - } else { + } else if !busy { + // As in profilerPickerUserOption: a failed changeProfile would leave the + // incognito default on while the picker still shows the chat profile. + // Only this branch - expanding and collapsing is local, as on Kotlin. incognitoDefault = true listExpanded = false } diff --git a/apps/ios/Shared/Views/NewChat/NewChatView.swift b/apps/ios/Shared/Views/NewChat/NewChatView.swift index 44c8a1f131..887aba7e62 100644 --- a/apps/ios/Shared/Views/NewChat/NewChatView.swift +++ b/apps/ios/Shared/Views/NewChat/NewChatView.swift @@ -559,7 +559,9 @@ private struct ActiveProfilePicker: View { private func profilerPickerUserOption(_ user: User) -> some View { Button { - if selectedProfile == user && incognitoEnabled { + // contactConnection as in incognitoOption: with nothing to change the handler + // does nothing and the backstop writes the app-wide default straight back. + if selectedProfile == user && incognitoEnabled && contactConnection != nil { incognitoEnabled = false profileSwitchStatus = .switchingIncognito } else if selectedProfile != user { @@ -634,6 +636,10 @@ private struct ActiveProfilePicker: View { // previous profile if it threw. Not newUser unconditionally, or a failed // switch leaves the checkmark on a profile that is not active. selectedProfile = chatModel.currentUser ?? selectedProfile + // The resync refreshed chatModel.users but not this snapshot, which is + // otherwise only filled in onAppear: without it the picker lists the old + // profiles, none matches the active one, and no row shows a checkmark. + profiles = chatModel.users.map { $0.user } } alertAfterDismissal(NSLocalizedString("Error changing chat profile", comment: "alert title")) return @@ -649,14 +655,16 @@ private struct ActiveProfilePicker: View { } profiles = chatModel.users.map { $0.user } } + let updatedUsers = try? await listUsersAsync() // apiChangeConnectionUser resolves pccConnId under whatever is active when the // selectedProfile handler runs, and a notification action can have switched it. + // After the await above, not before it: checked first, that await reopens the very + // window this closes. Kotlin orders it the same way. guard await MainActor.run({ chatModel.currentUser?.userId }) == ownerUserId else { await MainActor.run { showAddProfile = false } alertAfterDismissal(NSLocalizedString("Error changing chat profile", comment: "alert title")) return } - let updatedUsers = try? await listUsersAsync() await MainActor.run { if let updatedUsers = updatedUsers { chatModel.users = updatedUsers } // Derived from chatModel.users, which already holds the new profile - without