mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-08-27 09:19:49 +00:00
fix the incognito preference ordering, and register new profiles earlier on iOS
Move appPreferences.incognito.set(true) inside the success branch: written before the call that can fail, it left the app-wide default on so the next connection silently used a random profile. Mirror of the profile-path bug fixed two blocks above; iOS does not have it. Register the created profile in chatModel.users right after creation rather than after the ownership guard, so a user switch mid-create cannot leave a profile that exists in the database but in no list the app shows. Replaces the later fallbacks, which this subsumes. Also correct the plan on simplex-chat-client/typescript: it does import the regenerated types package, and is insulated by a ^0.3.0 pin, not by having its own types - adding the field there would break it.
This commit is contained in:
@@ -259,6 +259,14 @@ struct ContextProfilePickerView: View {
|
||||
let ownerUserId = await MainActor.run { chatModel.currentUser?.userId }
|
||||
let profile = Profile(displayName: displayName, fullName: "", shortDescr: shortDescr, image: image)
|
||||
let newUser = try apiCreateActiveUser(profile, keepActiveUser: true)
|
||||
// Before any early return below, as Kotlin does: nothing else on iOS refreshes
|
||||
// chatModel.users, so a profile left out of it exists in the database but in no
|
||||
// list the app shows - and creating it again fails on the duplicate name.
|
||||
await MainActor.run {
|
||||
if !chatModel.users.contains(where: { $0.user.userId == newUser.userId }) {
|
||||
chatModel.users.append(UserInfo(user: newUser, unreadCount: 0))
|
||||
}
|
||||
}
|
||||
// Checked before refreshing the lists below: on this path the core has already
|
||||
// activated the new profile, so they would disagree with chatModel.currentUser
|
||||
// until the resync lands - and changeActiveUserAsync_ refreshes them anyway.
|
||||
@@ -295,17 +303,10 @@ struct ContextProfilePickerView: View {
|
||||
chatModel.users = updatedUsers
|
||||
// Only filled in onAppear otherwise, so the new profile is missing here
|
||||
users = updatedUsers.map { $0.user }.filter { u in u.activeUser || !u.hidden }
|
||||
} else {
|
||||
} else if !users.contains(where: { $0.userId == newUser.userId }) {
|
||||
// changeProfile sets selectedUser to it, and otherUsers filters on that -
|
||||
// absent from users, nothing is filtered out and a row is clipped.
|
||||
if !users.contains(where: { $0.userId == newUser.userId }) {
|
||||
users.append(newUser)
|
||||
}
|
||||
// App-wide too, or the profile exists in the database but in no list the
|
||||
// app shows, and creating it again fails on the duplicate name.
|
||||
if !chatModel.users.contains(where: { $0.user.userId == newUser.userId }) {
|
||||
chatModel.users.append(UserInfo(user: newUser, unreadCount: 0))
|
||||
}
|
||||
users.append(newUser)
|
||||
}
|
||||
// changingProfile here too: the defer clears creatingProfile as soon as this returns
|
||||
showAddProfile = false
|
||||
|
||||
@@ -605,6 +605,14 @@ private struct ActiveProfilePicker: View {
|
||||
let ownerUserId = await MainActor.run { chatModel.currentUser?.userId }
|
||||
let profile = Profile(displayName: displayName, fullName: "", shortDescr: shortDescr, image: image)
|
||||
let newUser = try apiCreateActiveUser(profile, keepActiveUser: true)
|
||||
// Before any early return below, as Kotlin does: nothing else on iOS refreshes
|
||||
// chatModel.users, so a profile left out of it exists in the database but in no
|
||||
// list the app shows - and creating it again fails on the duplicate name.
|
||||
await MainActor.run {
|
||||
if !chatModel.users.contains(where: { $0.user.userId == newUser.userId }) {
|
||||
chatModel.users.append(UserInfo(user: newUser, unreadCount: 0))
|
||||
}
|
||||
}
|
||||
// Checked before refreshing the lists below: on this path the core has already
|
||||
// activated the new profile, so they would disagree with chatModel.currentUser
|
||||
// until the resync lands - and changeActiveUserAsync_ refreshes them anyway.
|
||||
@@ -638,13 +646,8 @@ private struct ActiveProfilePicker: View {
|
||||
let updatedUsers = try? await listUsersAsync()
|
||||
await MainActor.run {
|
||||
if let updatedUsers = updatedUsers { chatModel.users = updatedUsers }
|
||||
// listUsersAsync failed, so chatModel.users predates the creation. Add it there
|
||||
// as well as to profiles below, or the profile exists in the database but in no
|
||||
// list the app shows, and creating it again fails on the duplicate name.
|
||||
if !chatModel.users.contains(where: { $0.user.userId == newUser.userId }) {
|
||||
chatModel.users.append(UserInfo(user: newUser, unreadCount: 0))
|
||||
}
|
||||
// Without this selectedProfile below points at a profile that has no row.
|
||||
// Derived from chatModel.users, which already holds the new profile - without
|
||||
// it selectedProfile below points at a profile that has no row in the picker.
|
||||
profiles = chatModel.users.map { $0.user }
|
||||
showAddProfile = false
|
||||
selectedProfile = newUser
|
||||
|
||||
+4
-1
@@ -413,9 +413,12 @@ fun ActiveProfilePicker(
|
||||
switchingProfile.value = true
|
||||
withApi {
|
||||
try {
|
||||
appPreferences.incognito.set(true)
|
||||
val conn = controller.apiSetConnectionIncognito(rhId, contactConnection.pccConnId, true)
|
||||
if (conn != null) {
|
||||
// Only once the connection is actually incognito, as on the profile path
|
||||
// above: set before the call, a failure leaves the app-wide default on and
|
||||
// the next connection silently uses a random profile.
|
||||
appPreferences.incognito.set(true)
|
||||
withContext(Dispatchers.Main) {
|
||||
chatModel.chatsContext.updateContactConnection(rhId, conn)
|
||||
updateShownConnection(conn)
|
||||
|
||||
Reference in New Issue
Block a user