From 29b54ec5b296926c56882f3db5c2f12774efbfc8 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 20 Nov 2024 17:58:13 +0400 Subject: [PATCH 1/2] ios: rework saving settings (#5219) * ios: rework saving settings * fix * shorter names --------- Co-authored-by: Evgeny Poberezkin --- .../Shared/Views/ChatList/ChatListView.swift | 31 ++++++---- .../Views/ChatList/ServersSummaryView.swift | 57 +------------------ .../NetworkAndServers/NetworkAndServers.swift | 52 ++++++++--------- .../Views/UserSettings/SettingsView.swift | 22 ++----- 4 files changed, 50 insertions(+), 112 deletions(-) diff --git a/apps/ios/Shared/Views/ChatList/ChatListView.swift b/apps/ios/Shared/Views/ChatList/ChatListView.swift index 8e7aec581b..6da17fb312 100644 --- a/apps/ios/Shared/Views/ChatList/ChatListView.swift +++ b/apps/ios/Shared/Views/ChatList/ChatListView.swift @@ -31,14 +31,22 @@ enum UserPickerSheet: Identifiable { } } +class SaveableSettings: ObservableObject { + @Published var servers: ServerSettings = ServerSettings(currUserServers: [], userServers: [], serverErrors: []) +} + +struct ServerSettings { + public var currUserServers: [UserOperatorServers] + public var userServers: [UserOperatorServers] + public var serverErrors: [UserServersError] +} + struct UserPickerSheetView: View { let sheet: UserPickerSheet @EnvironmentObject var chatModel: ChatModel - @State private var loaded = false + @StateObject private var ss = SaveableSettings() - @State private var currUserServers: [UserOperatorServers] = [] - @State private var userServers: [UserOperatorServers] = [] - @State private var serverErrors: [UserServersError] = [] + @State private var loaded = false var body: some View { NavigationView { @@ -60,11 +68,7 @@ struct UserPickerSheetView: View { case .useFromDesktop: ConnectDesktopView() case .settings: - SettingsView( - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors - ) + SettingsView() } } Color.clear // Required for list background to be rendered during loading @@ -85,15 +89,20 @@ struct UserPickerSheetView: View { ) } .onDisappear { - if serversCanBeSaved(currUserServers, userServers, serverErrors) { + if serversCanBeSaved( + ss.servers.currUserServers, + ss.servers.userServers, + ss.servers.serverErrors + ) { showAlert( title: NSLocalizedString("Save servers?", comment: "alert title"), buttonTitle: NSLocalizedString("Save", comment: "alert button"), - buttonAction: { saveServers($currUserServers, $userServers) }, + buttonAction: { saveServers($ss.servers.currUserServers, $ss.servers.userServers) }, cancelButton: true ) } } + .environmentObject(ss) } } diff --git a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift index a13a159a45..b87b84ebc0 100644 --- a/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift +++ b/apps/ios/Shared/Views/ChatList/ServersSummaryView.swift @@ -20,10 +20,6 @@ struct ServersSummaryView: View { @State private var timer: Timer? = nil @State private var alert: SomeAlert? - @State private var currUserServers: [UserOperatorServers] = [] - @State private var userServers: [UserOperatorServers] = [] - @State private var serverErrors: [UserServersError] = [] - @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false enum PresentedUserCategory { @@ -57,15 +53,6 @@ struct ServersSummaryView: View { } .onDisappear { stopTimer() - - if serversCanBeSaved(currUserServers, userServers, serverErrors) { - showAlert( - title: NSLocalizedString("Save servers?", comment: "alert title"), - buttonTitle: NSLocalizedString("Save", comment: "alert button"), - buttonAction: { saveServers($currUserServers, $userServers) }, - cancelButton: true - ) - } } .alert(item: $alert) { $0.alert } } @@ -288,10 +275,7 @@ struct ServersSummaryView: View { NavigationLink(tag: srvSumm.id, selection: $selectedSMPServer) { SMPServerSummaryView( summary: srvSumm, - statsStartedAt: statsStartedAt, - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors + statsStartedAt: statsStartedAt ) .navigationBarTitle("SMP server") .navigationBarTitleDisplayMode(.large) @@ -360,10 +344,7 @@ struct ServersSummaryView: View { NavigationLink(tag: srvSumm.id, selection: $selectedXFTPServer) { XFTPServerSummaryView( summary: srvSumm, - statsStartedAt: statsStartedAt, - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors + statsStartedAt: statsStartedAt ) .navigationBarTitle("XFTP server") .navigationBarTitleDisplayMode(.large) @@ -505,28 +486,11 @@ struct SMPServerSummaryView: View { @AppStorage(DEFAULT_SHOW_SUBSCRIPTION_PERCENTAGE) private var showSubscriptionPercentage = false - @Binding var currUserServers: [UserOperatorServers] - @Binding var userServers: [UserOperatorServers] - @Binding var serverErrors: [UserServersError] - var body: some View { List { Section("Server address") { Text(summary.smpServer) .textSelection(.enabled) - if summary.known == true { - NavigationLink { - NetworkAndServers( - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors - ) - .navigationTitle("Network & servers") - .modifier(ThemedBackground(grouped: true)) - } label: { - Text("Open server settings") - } - } } if let stats = summary.stats { @@ -701,28 +665,11 @@ struct XFTPServerSummaryView: View { var summary: XFTPServerSummary var statsStartedAt: Date - @Binding var currUserServers: [UserOperatorServers] - @Binding var userServers: [UserOperatorServers] - @Binding var serverErrors: [UserServersError] - var body: some View { List { Section("Server address") { Text(summary.xftpServer) .textSelection(.enabled) - if summary.known == true { - NavigationLink { - NetworkAndServers( - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors - ) - .navigationTitle("Network & servers") - .modifier(ThemedBackground(grouped: true)) - } label: { - Text("Open server settings") - } - } } if let stats = summary.stats { diff --git a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift index c668ad3858..8b07c9a519 100644 --- a/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift +++ b/apps/ios/Shared/Views/UserSettings/NetworkAndServers/NetworkAndServers.swift @@ -34,9 +34,7 @@ struct NetworkAndServers: View { @EnvironmentObject var m: ChatModel @Environment(\.colorScheme) var colorScheme: ColorScheme @EnvironmentObject var theme: AppTheme - @Binding var currUserServers: [UserOperatorServers] - @Binding var userServers: [UserOperatorServers] - @Binding var serverErrors: [UserServersError] + @EnvironmentObject var ss: SaveableSettings @State private var sheetItem: NetworkAndServersSheet? = nil @State private var justOpened = true @State private var showSaveDialog = false @@ -45,9 +43,9 @@ struct NetworkAndServers: View { VStack { List { let conditionsAction = m.conditions.conditionsAction - let anyOperatorEnabled = userServers.contains(where: { $0.operator?.enabled ?? false }) + let anyOperatorEnabled = ss.servers.userServers.contains(where: { $0.operator?.enabled ?? false }) Section { - ForEach(userServers.enumerated().map { $0 }, id: \.element.id) { idx, userOperatorServers in + ForEach(ss.servers.userServers.enumerated().map { $0 }, id: \.element.id) { idx, userOperatorServers in if let serverOperator = userOperatorServers.operator { serverOperatorView(idx, serverOperator) } else { @@ -74,11 +72,11 @@ struct NetworkAndServers: View { } Section { - if let idx = userServers.firstIndex(where: { $0.operator == nil }) { + if let idx = ss.servers.userServers.firstIndex(where: { $0.operator == nil }) { NavigationLink { YourServersView( - userServers: $userServers, - serverErrors: $serverErrors, + userServers: $ss.servers.userServers, + serverErrors: $ss.servers.serverErrors, operatorIndex: idx ) .navigationTitle("Your servers") @@ -87,7 +85,7 @@ struct NetworkAndServers: View { HStack { Text("Your servers") - if userServers[idx] != currUserServers[idx] { + if ss.servers.userServers[idx] != ss.servers.currUserServers[idx] { Spacer() unsavedChangesIndicator() } @@ -108,12 +106,12 @@ struct NetworkAndServers: View { } Section { - Button("Save servers", action: { saveServers($currUserServers, $userServers) }) - .disabled(!serversCanBeSaved(currUserServers, userServers, serverErrors)) + Button("Save servers", action: { saveServers($ss.servers.currUserServers, $ss.servers.userServers) }) + .disabled(!serversCanBeSaved(ss.servers.currUserServers, ss.servers.userServers, ss.servers.serverErrors)) } footer: { - if let errStr = globalServersError(serverErrors) { + if let errStr = globalServersError(ss.servers.serverErrors) { ServersErrorView(errStr: errStr) - } else if !serverErrors.isEmpty { + } else if !ss.servers.serverErrors.isEmpty { ServersErrorView(errStr: NSLocalizedString("Errors in servers configuration.", comment: "servers error")) } } @@ -141,9 +139,9 @@ struct NetworkAndServers: View { // this condition is needed to prevent re-setting the servers when exiting single server view if justOpened { do { - currUserServers = try await getUserServers() - userServers = currUserServers - serverErrors = [] + ss.servers.currUserServers = try await getUserServers() + ss.servers.userServers = ss.servers.currUserServers + ss.servers.serverErrors = [] } catch let error { await MainActor.run { showAlert( @@ -156,7 +154,7 @@ struct NetworkAndServers: View { } } .modifier(BackButton(disabled: Binding.constant(false)) { - if serversCanBeSaved(currUserServers, userServers, serverErrors) { + if serversCanBeSaved(ss.servers.currUserServers, ss.servers.userServers, ss.servers.serverErrors) { showSaveDialog = true } else { dismiss() @@ -164,7 +162,7 @@ struct NetworkAndServers: View { }) .confirmationDialog("Save servers?", isPresented: $showSaveDialog, titleVisibility: .visible) { Button("Save") { - saveServers($currUserServers, $userServers) + saveServers($ss.servers.currUserServers, $ss.servers.userServers) dismiss() } Button("Exit without saving") { dismiss() } @@ -173,8 +171,8 @@ struct NetworkAndServers: View { switch item { case .showConditions: UsageConditionsView( - currUserServers: $currUserServers, - userServers: $userServers + currUserServers: $ss.servers.currUserServers, + userServers: $ss.servers.userServers ) .modifier(ThemedBackground(grouped: true)) } @@ -184,9 +182,9 @@ struct NetworkAndServers: View { private func serverOperatorView(_ operatorIndex: Int, _ serverOperator: ServerOperator) -> some View { NavigationLink() { OperatorView( - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors, + currUserServers: $ss.servers.currUserServers, + userServers: $ss.servers.userServers, + serverErrors: $ss.servers.serverErrors, operatorIndex: operatorIndex, useOperator: serverOperator.enabled ) @@ -203,7 +201,7 @@ struct NetworkAndServers: View { Text(serverOperator.tradeName) .foregroundColor(serverOperator.enabled ? theme.colors.onBackground : theme.colors.secondary) - if userServers[operatorIndex] != currUserServers[operatorIndex] { + if ss.servers.userServers[operatorIndex] != ss.servers.currUserServers[operatorIndex] { Spacer() unsavedChangesIndicator() } @@ -427,10 +425,6 @@ func updateOperatorsConditionsAcceptance(_ usvs: Binding<[UserOperatorServers]>, struct NetworkServersView_Previews: PreviewProvider { static var previews: some View { - NetworkAndServers( - currUserServers: Binding.constant([UserOperatorServers.sampleData1, UserOperatorServers.sampleDataNilOperator]), - userServers: Binding.constant([UserOperatorServers.sampleData1, UserOperatorServers.sampleDataNilOperator]), - serverErrors: Binding.constant([]) - ) + NetworkAndServers() } } diff --git a/apps/ios/Shared/Views/UserSettings/SettingsView.swift b/apps/ios/Shared/Views/UserSettings/SettingsView.swift index f2a1a56d01..95bf327f1b 100644 --- a/apps/ios/Shared/Views/UserSettings/SettingsView.swift +++ b/apps/ios/Shared/Views/UserSettings/SettingsView.swift @@ -266,10 +266,6 @@ struct SettingsView: View { @EnvironmentObject var theme: AppTheme @State private var showProgress: Bool = false - @Binding var currUserServers: [UserOperatorServers] - @Binding var userServers: [UserOperatorServers] - @Binding var serverErrors: [UserServersError] - var body: some View { ZStack { settingsView() @@ -296,13 +292,9 @@ struct SettingsView: View { .disabled(chatModel.chatRunning != true) NavigationLink { - NetworkAndServers( - currUserServers: $currUserServers, - userServers: $userServers, - serverErrors: $serverErrors - ) - .navigationTitle("Network & servers") - .modifier(ThemedBackground(grouped: true)) + NetworkAndServers() + .navigationTitle("Network & servers") + .modifier(ThemedBackground(grouped: true)) } label: { settingsRow("externaldrive.connected.to.line.below", color: theme.colors.secondary) { Text("Network & servers") } } @@ -536,11 +528,7 @@ struct SettingsView_Previews: PreviewProvider { static var previews: some View { let chatModel = ChatModel() chatModel.currentUser = User.sampleData - return SettingsView( - currUserServers: Binding.constant([UserOperatorServers.sampleData1, UserOperatorServers.sampleDataNilOperator]), - userServers: Binding.constant([UserOperatorServers.sampleData1, UserOperatorServers.sampleDataNilOperator]), - serverErrors: Binding.constant([]) - ) - .environmentObject(chatModel) + return SettingsView() + .environmentObject(chatModel) } } From f3cef7ce12ef76c4e2d9dd7329593ce6d5c86815 Mon Sep 17 00:00:00 2001 From: spaced4ndy <8711996+spaced4ndy@users.noreply.github.com> Date: Wed, 20 Nov 2024 18:23:51 +0400 Subject: [PATCH 2/2] ios: remove unused type --- apps/ios/SimpleXChat/APITypes.swift | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/ios/SimpleXChat/APITypes.swift b/apps/ios/SimpleXChat/APITypes.swift index 016a8213c3..8014600d47 100644 --- a/apps/ios/SimpleXChat/APITypes.swift +++ b/apps/ios/SimpleXChat/APITypes.swift @@ -1456,7 +1456,6 @@ public enum UserServersError: Decodable { case noServers(protocol: ServerProtocol, user: UserRef?) case storageMissing(protocol: ServerProtocol, user: UserRef?) case proxyMissing(protocol: ServerProtocol, user: UserRef?) - case invalidServer(protocol: ServerProtocol, invalidServer: String) case duplicateServer(protocol: ServerProtocol, duplicateServer: String, duplicateHost: String) public var globalError: String? {