diff --git a/apps/ios/Shared/Model/SimpleXAPI.swift b/apps/ios/Shared/Model/SimpleXAPI.swift index 3efc9f102c..59524c2c39 100644 --- a/apps/ios/Shared/Model/SimpleXAPI.swift +++ b/apps/ios/Shared/Model/SimpleXAPI.swift @@ -691,12 +691,12 @@ func apiListContacts() throws -> [Contact] { throw r } -func apiUpdateProfile(profile: Profile) async throws -> Profile? { +func apiUpdateProfile(profile: Profile) async throws -> (Profile, [Contact])? { let userId = try currentUserId("apiUpdateProfile") let r = await chatSendCmd(.apiUpdateProfile(userId: userId, profile: profile)) switch r { case .userProfileNoChange: return nil - case let .userProfileUpdated(_, _, toProfile): return toProfile + case let .userProfileUpdated(_, _, toProfile, updateSummary): return (toProfile, updateSummary.changedContacts) default: throw r } } @@ -706,7 +706,7 @@ func apiSetProfileAddress(on: Bool) async throws -> User? { let r = await chatSendCmd(.apiSetProfileAddress(userId: userId, on: on)) switch r { case .userProfileNoChange: return nil - case let .userProfileUpdated(user, _, _): return user + case let .userProfileUpdated(user, _, _, _): return user default: throw r } } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift b/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift index 32adf861f3..729556e739 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupProfileView.swift @@ -130,7 +130,7 @@ struct GroupProfileView: View { let err = responseError(error) saveGroupError = err showSaveErrorAlert = true - logger.error("UserProfile apiUpdateProfile error: \(err)") + logger.error("GroupProfile apiUpdateGroup error: \(err)") } } } diff --git a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift index cf8978498b..960afb6d38 100644 --- a/apps/ios/Shared/Views/UserSettings/PreferencesView.swift +++ b/apps/ios/Shared/Views/UserSettings/PreferencesView.swift @@ -71,9 +71,10 @@ struct PreferencesView: View { do { var p = fromLocalProfile(profile) p.preferences = fullPreferencesToPreferences(preferences) - if let newProfile = try await apiUpdateProfile(profile: p) { + if let (newProfile, updatedContacts) = try await apiUpdateProfile(profile: p) { await MainActor.run { chatModel.updateCurrentUser(newProfile, preferences) + updatedContacts.forEach(chatModel.updateContact) currentPreferences = preferences } } diff --git a/apps/ios/Shared/Views/UserSettings/UserProfile.swift b/apps/ios/Shared/Views/UserSettings/UserProfile.swift index 9ea6fe2a7f..f38dc593a6 100644 --- a/apps/ios/Shared/Views/UserSettings/UserProfile.swift +++ b/apps/ios/Shared/Views/UserSettings/UserProfile.swift @@ -144,7 +144,7 @@ struct UserProfile: View { func saveProfile() { Task { do { - if let newProfile = try await apiUpdateProfile(profile: profile) { + if let (newProfile, _) = try await apiUpdateProfile(profile: profile) { DispatchQueue.main.async { chatModel.updateCurrentUser(newProfile) profile = newProfile diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index ae92930669..d80626d6f1 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -457,7 +457,7 @@ public enum ChatResponse: Decodable, Error { case contactDeleted(user: UserRef, contact: Contact) case chatCleared(user: UserRef, chatInfo: ChatInfo) case userProfileNoChange(user: User) - case userProfileUpdated(user: User, fromProfile: Profile, toProfile: Profile) + case userProfileUpdated(user: User, fromProfile: Profile, toProfile: Profile, updateSummary: UserProfileUpdateSummary) case userPrivacy(user: User, updatedUser: User) case contactAliasUpdated(user: UserRef, toContact: Contact) case connectionAliasUpdated(user: UserRef, toConnection: PendingContactConnection) @@ -724,7 +724,7 @@ public enum ChatResponse: Decodable, Error { case let .contactDeleted(u, contact): return withUser(u, String(describing: contact)) case let .chatCleared(u, chatInfo): return withUser(u, String(describing: chatInfo)) case .userProfileNoChange: return noDetails - case let .userProfileUpdated(u, _, toProfile): return withUser(u, String(describing: toProfile)) + case let .userProfileUpdated(u, _, toProfile, _): return withUser(u, String(describing: toProfile)) case let .userPrivacy(u, updatedUser): return withUser(u, String(describing: updatedUser)) case let .contactAliasUpdated(u, toContact): return withUser(u, String(describing: toContact)) case let .connectionAliasUpdated(u, toConnection): return withUser(u, String(describing: toConnection)) diff --git a/apps/ios/SimpleXChat/ChatTypes.swift b/apps/ios/SimpleXChat/ChatTypes.swift index ef85978350..48996abb78 100644 --- a/apps/ios/SimpleXChat/ChatTypes.swift +++ b/apps/ios/SimpleXChat/ChatTypes.swift @@ -171,6 +171,13 @@ public func fromLocalProfile (_ profile: LocalProfile) -> Profile { Profile(displayName: profile.displayName, fullName: profile.fullName, image: profile.image, contactLink: profile.contactLink, preferences: profile.preferences) } +public struct UserProfileUpdateSummary: Decodable { + public var notChanged: Int + public var updateSuccesses: Int + public var updateFailures: Int + public var changedContacts: [Contact] +} + public enum ChatType: String { case direct = "@" case group = "#"