diff --git a/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift b/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift index 3d5afb4879..63aa4b50c3 100644 --- a/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/ContactPreferencesView.swift @@ -10,10 +10,12 @@ import SwiftUI import SimpleXChat struct ContactPreferencesView: View { + @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject var chatModel: ChatModel @Binding var contact: Contact @State var featuresAllowed: ContactFeaturesAllowed @State var currentFeaturesAllowed: ContactFeaturesAllowed + @State private var showSaveDialogue = false var body: some View { let user: User = chatModel.currentUser! @@ -25,11 +27,25 @@ struct ContactPreferencesView: View { Section { Button("Reset") { featuresAllowed = currentFeaturesAllowed } - Button("Save (and notify contact)") { savePreferences() } + Button("Save and notify contact") { savePreferences() } } .disabled(currentFeaturesAllowed == featuresAllowed) } } + .modifier(BackButton { + if currentFeaturesAllowed == featuresAllowed { + dismiss() + } else { + showSaveDialogue = true + } + }) + .confirmationDialog("Save preferences?", isPresented: $showSaveDialogue) { + Button("Save and notify contact") { + savePreferences() + dismiss() + } + Button("Exit without saving") { dismiss() } + } } private func featureSection(_ feature: ChatFeature, _ userDefault: FeatureAllowed, _ pref: ContactUserPreference, _ allowFeature: Binding) -> some View { diff --git a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift index 5e68e13672..2f5456731c 100644 --- a/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift +++ b/apps/ios/Shared/Views/Chat/Group/AddGroupMembersView.swift @@ -13,8 +13,8 @@ struct AddGroupMembersView: View { @EnvironmentObject var chatModel: ChatModel @Environment(\.dismiss) var dismiss: DismissAction var chat: Chat - var groupInfo: GroupInfo - var showSkip: Bool = false + @State var groupInfo: GroupInfo + var creatingGroup: Bool = false var showFooterCounter: Bool = true var addedMembersCb: ((Set) -> Void)? = nil @State private var selectedContacts = Set() @@ -52,6 +52,9 @@ struct AddGroupMembersView: View { } else { let count = selectedContacts.count Section { + if creatingGroup { + groupPreferencesButton($groupInfo, true) + } rolePicker() inviteMembersButton() .disabled(count < 1) @@ -78,14 +81,10 @@ struct AddGroupMembersView: View { } } - if (showSkip) { + if creatingGroup { v.toolbar { ToolbarItem(placement: .navigationBarTrailing) { - if showSkip { - Button ("Skip") { - if let cb = addedMembersCb { cb(selectedContacts) } - } - } + Button ("Skip") { addedMembersCb?(selectedContacts) } } } } else { @@ -142,6 +141,7 @@ struct AddGroupMembersView: View { } } } + .frame(height: 36) } private func contactCheckView(_ contact: Contact) -> some View { diff --git a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift index 1d155dd42d..d7adf0a380 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupChatInfoView.swift @@ -45,7 +45,7 @@ struct GroupChatInfoView: View { if groupInfo.canEdit { editGroupButton() } - groupPreferencesButton() + groupPreferencesButton($groupInfo) } header: { Text("") } footer: { @@ -200,20 +200,6 @@ struct GroupChatInfoView: View { } } - func groupPreferencesButton() -> some View { - NavigationLink { - GroupPreferencesView( - groupInfo: $groupInfo, - preferences: groupInfo.fullGroupPreferences, - currentPreferences: groupInfo.fullGroupPreferences - ) - .navigationBarTitle("Group preferences") - .navigationBarTitleDisplayMode(.large) - } label: { - Label("Group preferences", systemImage: "switch.2") - } - } - func editGroupButton() -> some View { NavigationLink { GroupProfileView( @@ -310,6 +296,25 @@ struct GroupChatInfoView: View { } } +func groupPreferencesButton(_ groupInfo: Binding, _ creatingGroup: Bool = false) -> some View { + NavigationLink { + GroupPreferencesView( + groupInfo: groupInfo, + preferences: groupInfo.wrappedValue.fullGroupPreferences, + currentPreferences: groupInfo.wrappedValue.fullGroupPreferences, + creatingGroup: creatingGroup + ) + .navigationBarTitle("Group preferences") + .navigationBarTitleDisplayMode(.large) + } label: { + if creatingGroup { + Text("Set group preferences") + } else { + Label("Group preferences", systemImage: "switch.2") + } + } +} + func cantInviteIncognitoAlert() -> Alert { Alert( title: Text("Can't invite contacts!"), diff --git a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift index 842faad9dc..c416223431 100644 --- a/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift +++ b/apps/ios/Shared/Views/Chat/Group/GroupPreferencesView.swift @@ -10,12 +10,16 @@ import SwiftUI import SimpleXChat struct GroupPreferencesView: View { + @Environment(\.dismiss) var dismiss: DismissAction @EnvironmentObject var chatModel: ChatModel @Binding var groupInfo: GroupInfo @State var preferences: FullGroupPreferences @State var currentPreferences: FullGroupPreferences + let creatingGroup: Bool + @State private var showSaveDialogue = false var body: some View { + let saveText: LocalizedStringKey = creatingGroup ? "Save" : "Save and notify group members" VStack { List { featureSection(.fullDelete, $preferences.fullDelete.enable) @@ -25,18 +29,34 @@ struct GroupPreferencesView: View { if groupInfo.canEdit { Section { Button("Reset") { preferences = currentPreferences } - Button("Save (and notify group members)") { savePreferences() } + Button(saveText) { savePreferences() } } .disabled(currentPreferences == preferences) } } } + .modifier(BackButton { + if currentPreferences == preferences { + dismiss() + } else { + showSaveDialogue = true + } + }) + .confirmationDialog("Save preferences?", isPresented: $showSaveDialogue) { + Button(saveText) { + savePreferences() + dismiss() + } + Button("Exit without saving") { dismiss() } + } } private func featureSection(_ feature: GroupFeature, _ enableFeature: Binding) -> some View { Section { + let color: Color = enableFeature.wrappedValue == .on ? .green : .secondary + let icon = enableFeature.wrappedValue == .on ? feature.iconFilled : feature.icon if (groupInfo.canEdit) { - settingsRow(feature.icon) { + settingsRow(icon, color: color) { Picker(feature.text, selection: enableFeature) { ForEach(GroupFeatureEnabled.values) { enable in Text(enable.text) @@ -46,7 +66,7 @@ struct GroupPreferencesView: View { } } else { - settingsRow(feature.icon) { + settingsRow(icon, color: color) { infoRow(feature.text, enableFeature.wrappedValue.text) } } @@ -79,7 +99,8 @@ struct GroupPreferencesView_Previews: PreviewProvider { GroupPreferencesView( groupInfo: Binding.constant(GroupInfo.sampleData), preferences: FullGroupPreferences.sampleData, - currentPreferences: FullGroupPreferences.sampleData + currentPreferences: FullGroupPreferences.sampleData, + creatingGroup: false ) } } diff --git a/apps/ios/Shared/Views/NewChat/AddGroupView.swift b/apps/ios/Shared/Views/NewChat/AddGroupView.swift index ed4e82c0e0..998ae395bb 100644 --- a/apps/ios/Shared/Views/NewChat/AddGroupView.swift +++ b/apps/ios/Shared/Views/NewChat/AddGroupView.swift @@ -27,7 +27,7 @@ struct AddGroupView: View { AddGroupMembersView( chat: chat, groupInfo: groupInfo, - showSkip: true, + creatingGroup: true, showFooterCounter: false ) { _ in dismiss() diff --git a/apps/ios/Shared/Views/UserSettings/SMPServerView.swift b/apps/ios/Shared/Views/UserSettings/SMPServerView.swift index 8aa2e92909..454e1e7186 100644 --- a/apps/ios/Shared/Views/UserSettings/SMPServerView.swift +++ b/apps/ios/Shared/Views/UserSettings/SMPServerView.swift @@ -28,20 +28,10 @@ struct SMPServerView: View { ProgressView().scaleEffect(2) } } - .navigationBarBackButtonHidden(true) - .toolbar { - ToolbarItem(placement: .navigationBarLeading) { - Button { - server = serverToEdit - dismiss() - } label: { - HStack { - Image(systemName: "chevron.left") - Text("Your SMP servers") - } - } - } - } + .modifier(BackButton(label: "Your SMP servers") { + server = serverToEdit + dismiss() + }) .alert(isPresented: $showTestFailure) { Alert( title: Text("Server test failed!"), @@ -121,6 +111,26 @@ struct SMPServerView: View { } } +struct BackButton: ViewModifier { + var label: LocalizedStringKey = "Back" + var action: () -> Void + + func body(content: Content) -> some View { + content + .navigationBarBackButtonHidden(true) + .toolbar { + ToolbarItem(placement: .navigationBarLeading) { + Button(action: action) { + HStack { + Image(systemName: "chevron.left") + Text(label) + } + } + } + } + } +} + @ViewBuilder func showTestStatus(server: ServerCfg) -> some View { switch server.tested { case .some(true):