diff --git a/apps/ios/Shared/Views/Chat/ChatView.swift b/apps/ios/Shared/Views/Chat/ChatView.swift index cfbbfe6080..f2f25ff272 100644 --- a/apps/ios/Shared/Views/Chat/ChatView.swift +++ b/apps/ios/Shared/Views/Chat/ChatView.swift @@ -246,7 +246,8 @@ struct ChatView: View { chat.created = Date.now } ), - onSearch: { focusSearch() } + onSearch: { focusSearch() }, + preferences: groupInfo.fullGroupPreferences ) } } 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 925f4120bc..0d03b21ca0 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, addedMembersCb: { _ in dismiss() }) + AddGroupMembersViewCommon(chat: chat, groupInfo: groupInfo, preferences: groupInfo.fullGroupPreferences, addedMembersCb: { _ in dismiss() }) } } @@ -24,6 +24,7 @@ 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) @@ -78,7 +79,7 @@ struct AddGroupMembersViewCommon: View { let count = selectedContacts.count Section { if creatingGroup { - groupPreferencesButton($groupInfo, true) + groupPreferencesButton($groupInfo, $preferences, true) } rolePicker() inviteMembersButton() diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index 27aa0edb5b..640b8c6b1d 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -19,6 +19,7 @@ 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 @@ -87,7 +88,7 @@ struct GroupChatInfoView: View { if groupInfo.groupProfile.description != nil || (groupInfo.isOwner && groupInfo.businessChat == nil) { addOrEditWelcomeMessage() } - groupPreferencesButton($groupInfo) + groupPreferencesButton($groupInfo, $preferences) if members.filter({ $0.wrapped.memberCurrent }).count <= SMALL_GROUPS_RCPS_MEM_LIMIT { sendReceiptsOption() } else { @@ -654,18 +655,32 @@ func deleteGroupAlertMessage(_ groupInfo: GroupInfo) -> Text { ) } -func groupPreferencesButton(_ groupInfo: Binding, _ creatingGroup: Bool = false) -> some View { +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: groupInfo.wrappedValue.fullGroupPreferences, - currentPreferences: groupInfo.wrappedValue.fullGroupPreferences, + 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 + ) + } + } } label: { if creatingGroup { Text("Set group preferences") @@ -694,7 +709,8 @@ struct GroupChatInfoView_Previews: PreviewProvider { GroupChatInfoView( chat: Chat(chatInfo: ChatInfo.sampleData.group, chatItems: []), groupInfo: Binding.constant(GroupInfo.sampleData), - onSearch: {} + onSearch: {}, + preferences: GroupInfo.sampleData.fullGroupPreferences ) } } diff --git a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift index bbbbe4d4c3..b27ff37d95 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift @@ -20,8 +20,8 @@ struct GroupPreferencesView: View { @EnvironmentObject var chatModel: ChatModel @EnvironmentObject var theme: AppTheme @Binding var groupInfo: GroupInfo - @State var preferences: FullGroupPreferences - @State var currentPreferences: FullGroupPreferences + @Binding var preferences: FullGroupPreferences + @Binding var currentPreferences: FullGroupPreferences let creatingGroup: Bool @State private var showSaveDialogue = false @@ -41,7 +41,7 @@ struct GroupPreferencesView: View { if groupInfo.isOwner { Section { Button("Reset") { preferences = currentPreferences } - Button(saveText) { savePreferences() } + Button(saveText) { savePreferences(groupInfo: $groupInfo, preferences: $preferences, currentPreferences: $currentPreferences) } } .disabled(currentPreferences == preferences) } @@ -65,10 +65,13 @@ struct GroupPreferencesView: View { }) .confirmationDialog("Save preferences?", isPresented: $showSaveDialogue) { Button(saveText) { - savePreferences() + savePreferences(groupInfo: $groupInfo, preferences: $preferences, currentPreferences: $currentPreferences) + dismiss() + } + Button("Exit without saving") { + preferences = currentPreferences dismiss() } - Button("Exit without saving") { dismiss() } } } @@ -132,21 +135,25 @@ struct GroupPreferencesView: View { } } } +} - 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.updateGroup(gInfo) - currentPreferences = preferences - } - } catch { - logger.error("GroupPreferencesView apiUpdateGroup error: \(responseError(error))") +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))") } } } @@ -155,8 +162,8 @@ struct GroupPreferencesView_Previews: PreviewProvider { static var previews: some View { GroupPreferencesView( groupInfo: Binding.constant(GroupInfo.sampleData), - preferences: FullGroupPreferences.sampleData, - currentPreferences: FullGroupPreferences.sampleData, + preferences: Binding.constant(FullGroupPreferences.sampleData), + currentPreferences: Binding.constant(FullGroupPreferences.sampleData), creatingGroup: false ) } diff --git a/apps/ios/Shared/Views/NewChat/AddGroupView.swift b/apps/ios/Shared/Views/NewChat/AddGroupView.swift index 0c7f6136ff..5207c3a472 100644 --- a/apps/ios/Shared/Views/NewChat/AddGroupView.swift +++ b/apps/ios/Shared/Views/NewChat/AddGroupView.swift @@ -32,6 +32,7 @@ struct AddGroupView: View { AddGroupMembersViewCommon( chat: chat, groupInfo: groupInfo, + preferences: groupInfo.fullGroupPreferences, creatingGroup: true, showFooterCounter: false ) { _ in