From df1a471c563a7ffa556a12bc1e4f95915e2038e4 Mon Sep 17 00:00:00 2001 From: Diogo Date: Fri, 6 Dec 2024 15:55:15 +0000 Subject: [PATCH] ios: remove all unsafe warnings in group preferences save (#5340) --- apps/ios/Shared/Views/Chat/ChatView.swift | 3 +- .../Chat/Group/AddGroupMembersView.swift | 10 +- .../Views/Chat/Group/GroupChatInfoView.swift | 93 ++++++++++++------- .../Chat/Group/GroupPreferencesView.swift | 33 ++----- .../Shared/Views/NewChat/AddGroupView.swift | 1 - 5 files changed, 76 insertions(+), 64 deletions(-) diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index df5fde9e7a..0c5a458930 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -253,8 +253,7 @@ struct ChatView: View { chat.created = Date.now } ), - onSearch: { focusSearch() }, - preferences: groupInfo.fullGroupPreferences + onSearch: { focusSearch() } ) } } else if case .local = cInfo { diff --git a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift index 0d03b21ca0..bdef8d0a62 100644 --- a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift +++ b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift @@ -15,7 +15,7 @@ struct AddGroupMembersView: View { var groupInfo: GroupInfo var body: some View { - AddGroupMembersViewCommon(chat: chat, groupInfo: groupInfo, preferences: groupInfo.fullGroupPreferences, addedMembersCb: { _ in dismiss() }) + AddGroupMembersViewCommon(chat: chat, groupInfo: groupInfo, addedMembersCb: { _ in dismiss() }) } } @@ -24,7 +24,6 @@ struct AddGroupMembersViewCommon: View { @EnvironmentObject var theme: AppTheme var chat: Chat @State var groupInfo: GroupInfo - @State var preferences: FullGroupPreferences var creatingGroup: Bool = false var showFooterCounter: Bool = true var addedMembersCb: ((Set) -> Void) @@ -79,7 +78,12 @@ struct AddGroupMembersViewCommon: View { let count = selectedContacts.count Section { if creatingGroup { - groupPreferencesButton($groupInfo, $preferences, true) + GroupPreferencesButton( + groupInfo: $groupInfo, + preferences: groupInfo.fullGroupPreferences, + currentPreferences: groupInfo.fullGroupPreferences, + creatingGroup: true + ) } rolePicker() inviteMembersButton() diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index 7dc57f9642..c4df91bb8b 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -19,7 +19,6 @@ struct GroupChatInfoView: View { @Binding var groupInfo: GroupInfo var onSearch: () -> Void @State private var alert: GroupChatInfoViewAlert? = nil - @State var preferences: FullGroupPreferences @State private var groupLink: String? @State private var groupLinkMemberRole: GroupMemberRole = .member @State private var groupLinkNavLinkActive: Bool = false @@ -88,7 +87,7 @@ struct GroupChatInfoView: View { if groupInfo.groupProfile.description != nil || (groupInfo.isOwner && groupInfo.businessChat == nil) { addOrEditWelcomeMessage() } - groupPreferencesButton($groupInfo, $preferences) + GroupPreferencesButton(groupInfo: $groupInfo, preferences: groupInfo.fullGroupPreferences, currentPreferences: groupInfo.fullGroupPreferences) if members.filter({ $0.wrapped.memberCurrent }).count <= SMALL_GROUPS_RCPS_MEM_LIMIT { sendReceiptsOption() } else { @@ -655,41 +654,72 @@ func deleteGroupAlertMessage(_ groupInfo: GroupInfo) -> Text { ) } -func groupPreferencesButton(_ groupInfo: Binding, _ preferences: Binding, _ creatingGroup: Bool = false) -> some View { - let label: LocalizedStringKey = groupInfo.wrappedValue.businessChat == nil ? "Group preferences" : "Chat preferences" - return NavigationLink { - GroupPreferencesView( - groupInfo: groupInfo, - preferences: preferences, - currentPreferences: groupInfo.fullGroupPreferences, - creatingGroup: creatingGroup - ) - .navigationBarTitle(label) - .modifier(ThemedBackground(grouped: true)) - .navigationBarTitleDisplayMode(.large) - .onDisappear { - let saveText = NSLocalizedString(creatingGroup ? "Save" : "Save and notify group members", comment: "alert button") - - if groupInfo.fullGroupPreferences.wrappedValue != preferences.wrappedValue { - showAlert( - title: NSLocalizedString("Save preferences?", comment: "alert title"), - buttonTitle: saveText, - buttonAction: { - savePreferences(groupInfo: groupInfo, preferences: preferences, currentPreferences: groupInfo.fullGroupPreferences) - }, - cancelButton: true +struct GroupPreferencesButton: View { + @Binding var groupInfo: GroupInfo + @State var preferences: FullGroupPreferences + @State var currentPreferences: FullGroupPreferences + var creatingGroup: Bool = false + + private var label: LocalizedStringKey { + groupInfo.businessChat == nil ? "Group preferences" : "Chat preferences" + } + + var body: some View { + NavigationLink { + GroupPreferencesView( + groupInfo: $groupInfo, + preferences: $preferences, + currentPreferences: currentPreferences, + creatingGroup: creatingGroup, + savePreferences: savePreferences + ) + .navigationBarTitle(label) + .modifier(ThemedBackground(grouped: true)) + .navigationBarTitleDisplayMode(.large) + .onDisappear { + let saveText = NSLocalizedString( + creatingGroup ? "Save" : "Save and notify group members", + comment: "alert button" ) + + if groupInfo.fullGroupPreferences != preferences { + showAlert( + title: NSLocalizedString("Save preferences?", comment: "alert title"), + buttonTitle: saveText, + buttonAction: { savePreferences() }, + cancelButton: true + ) + } + } + } label: { + if creatingGroup { + Text("Set group preferences") + } else { + Label(label, systemImage: "switch.2") } } - } label: { - if creatingGroup { - Text("Set group preferences") - } else { - Label(label, systemImage: "switch.2") + } + + private func savePreferences() { + Task { + do { + var gp = groupInfo.groupProfile + gp.groupPreferences = toGroupPreferences(preferences) + let gInfo = try await apiUpdateGroup(groupInfo.groupId, gp) + await MainActor.run { + groupInfo = gInfo + ChatModel.shared.updateGroup(gInfo) + currentPreferences = preferences + } + } catch { + logger.error("GroupPreferencesView apiUpdateGroup error: \(responseError(error))") + } } } + } + func cantInviteIncognitoAlert() -> Alert { Alert( title: Text("Can't invite contacts!"), @@ -709,8 +739,7 @@ struct GroupChatInfoView_Previews: PreviewProvider { GroupChatInfoView( chat: Chat(chatInfo: ChatInfo.sampleData.group, chatItems: []), groupInfo: Binding.constant(GroupInfo.sampleData), - onSearch: {}, - preferences: GroupInfo.sampleData.fullGroupPreferences + onSearch: {} ) } } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift index b27ff37d95..9ef53258aa 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift @@ -21,8 +21,9 @@ struct GroupPreferencesView: View { @EnvironmentObject var theme: AppTheme @Binding var groupInfo: GroupInfo @Binding var preferences: FullGroupPreferences - @Binding var currentPreferences: FullGroupPreferences + var currentPreferences: FullGroupPreferences let creatingGroup: Bool + let savePreferences: () -> Void @State private var showSaveDialogue = false var body: some View { @@ -41,7 +42,7 @@ struct GroupPreferencesView: View { if groupInfo.isOwner { Section { Button("Reset") { preferences = currentPreferences } - Button(saveText) { savePreferences(groupInfo: $groupInfo, preferences: $preferences, currentPreferences: $currentPreferences) } + Button(saveText) { savePreferences() } } .disabled(currentPreferences == preferences) } @@ -65,7 +66,7 @@ struct GroupPreferencesView: View { }) .confirmationDialog("Save preferences?", isPresented: $showSaveDialogue) { Button(saveText) { - savePreferences(groupInfo: $groupInfo, preferences: $preferences, currentPreferences: $currentPreferences) + savePreferences() dismiss() } Button("Exit without saving") { @@ -137,34 +138,14 @@ struct GroupPreferencesView: View { } } -func savePreferences( - groupInfo: Binding, - preferences: Binding, - currentPreferences: Binding -) { - Task { - do { - var gp = groupInfo.groupProfile.wrappedValue - gp.groupPreferences = toGroupPreferences(preferences.wrappedValue) - let gInfo = try await apiUpdateGroup(groupInfo.groupId.wrappedValue, gp) - await MainActor.run { - groupInfo.wrappedValue = gInfo - ChatModel.shared.updateGroup(gInfo) - currentPreferences.wrappedValue = preferences.wrappedValue - } - } catch { - logger.error("GroupPreferencesView apiUpdateGroup error: \(responseError(error))") - } - } -} - struct GroupPreferencesView_Previews: PreviewProvider { static var previews: some View { GroupPreferencesView( groupInfo: Binding.constant(GroupInfo.sampleData), preferences: Binding.constant(FullGroupPreferences.sampleData), - currentPreferences: Binding.constant(FullGroupPreferences.sampleData), - creatingGroup: false + currentPreferences: FullGroupPreferences.sampleData, + creatingGroup: false, + savePreferences: {} ) } } diff --git a/apps/ios/Shared/Views/NewChat/AddGroupView.swift b/apps/ios/Shared/Views/NewChat/AddGroupView.swift index 5207c3a472..0c7f6136ff 100644 --- a/apps/ios/Shared/Views/NewChat/AddGroupView.swift +++ b/apps/ios/Shared/Views/NewChat/AddGroupView.swift @@ -32,7 +32,6 @@ struct AddGroupView: View { AddGroupMembersViewCommon( chat: chat, groupInfo: groupInfo, - preferences: groupInfo.fullGroupPreferences, creatingGroup: true, showFooterCounter: false ) { _ in