taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

commit 8d5f7ea6700e4f99d897eff109af72d8a71d2943
parent bca1afc489fba3a03800f347fb514b47d135037b
Author: Marc Stibane <marc@taler.net>
Date:   Sun,  1 Mar 2026 21:40:20 +0100

Update Settings

Diffstat:
MTalerWallet1/Views/Actions/Banking/DepositSelectV.swift | 2+-
MTalerWallet1/Views/Settings/AboutView.swift | 4++--
MTalerWallet1/Views/Settings/DebugSettingsView.swift | 61++++++++++++++++++++++++++++++++++++-------------------------
MTalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift | 14++++++++------
ATalerWallet1/Views/Settings/MoreSettingsView.swift | 115+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
MTalerWallet1/Views/Settings/SettingsItem.swift | 203+++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------
MTalerWallet1/Views/Settings/SettingsView.swift | 117+++++++++++++++++++++++++++++---------------------------------------------------
7 files changed, 336 insertions(+), 180 deletions(-)

diff --git a/TalerWallet1/Views/Actions/Banking/DepositSelectV.swift b/TalerWallet1/Views/Actions/Banking/DepositSelectV.swift @@ -72,7 +72,7 @@ struct DepositSelectV: View { bankAccountsDest } label: { SettingsItem(name: bankAccountsTitle, id1: "bankAccounts", - description: minimalistic ? nil : String(localized: "Your accounts for deposit...")) {} + description: String(localized: "Your accounts for deposit...")) {} } } } else { diff --git a/TalerWallet1/Views/Settings/AboutView.swift b/TalerWallet1/Views/Settings/AboutView.swift @@ -56,7 +56,7 @@ struct AboutView: View { SettingsItem(name: String(localized: "Visit the taler.net website"), id1: "web", imageName: "link", - description: minimalistic ? nil : String(localized: "More info about GNU Taler in general...")) { } + description: String(localized: "More info about GNU Taler in general...")) { } .accessibilityAddTraits(.isLink) .accessibilityRemoveTraits(.isStaticText) .onTapGesture() { @@ -93,7 +93,7 @@ struct AboutView: View { } }), id1: "onboarding", - description: minimalistic ? nil : String(localized: "Explain the Actions button")) + description: String(localized: "Explain the Actions button")) #if DEBUG Text(verbatim: "Tapped: \(tapped), dragged: \(dragged)") #endif diff --git a/TalerWallet1/Views/Settings/DebugSettingsView.swift b/TalerWallet1/Views/Settings/DebugSettingsView.swift @@ -62,29 +62,33 @@ struct DebugSettingsView: View { let walletCore = WalletCore.shared Group { List { - SettingsToggle(name: String("Developer Mode"), value: $developerMode, id1: "devMode", - description: minimalistic ? nil : String("More information intended for debugging")) { + SettingsToggle(name: String("Developer Mode"), value: $developerMode, + id1: "devMode", + description: String("More information intended for debugging")) { newVal in withAnimation(Animation.linear.delay(0.8)) { showDevelopItems = developerMode } } if showDevelopItems { #if DEBUG SettingsToggle(name: String("Log Transactions"), value: $logTransactions.onChange({ isLogging in - walletCore.logTransactions = isLogging}), id1: "logTransactions", - description: minimalistic ? nil : String("full log with all tx")) {} + walletCore.logTransactions = isLogging}), + id1: "logTransactions", + description: String("full log with all tx")) #endif let localConsStr = String("on LocalConsole") let observability = String("Observe walletCore") SettingsTriState(name: observability, value: $localConsoleO.onChange({ isObserving in walletCore.isObserving = isObserving}), - description: minimalistic ? nil : localConsStr) { isObserving in + id1: "observe", + description: localConsStr) { isObserving in let consoleManager = LCManager.shared consoleManager.isVisible = localConsoleO != 0 || localConsoleL consoleManager.clear() } let showLogs = String("Show logs") SettingsToggle(name: showLogs, value: $localConsoleL.onChange({ isLogging in - walletCore.isLogging = isLogging}), id1: "localConsoleL", - description: minimalistic ? nil : localConsStr) { + walletCore.isLogging = isLogging}), + id1: "localConsoleL", + description: localConsStr) { _ in let consoleManager = LCManager.shared consoleManager.isVisible = localConsoleO != 0 || localConsoleL consoleManager.clear() @@ -100,7 +104,7 @@ struct DebugSettingsView: View { #endif } // showDevelopItems SettingsItem(name: String("DEMO"), id1: "demo1with", - description: minimalistic ? nil : String("Get money for testing")) { + description: String("Get money for testing")) { let title = "Withdraw" Button(title) { withDrawDisabled = true // don't run twice @@ -114,7 +118,7 @@ struct DebugSettingsView: View { .disabled(withDrawDisabled) }.id("demo1withdraw") SettingsItem(name: String("TEST"), id1: "test1with", - description: minimalistic ? nil : String("Get money for testing")) { + description: String("Get money for testing")) { let title = "Withdraw" Button(title) { withDrawDisabled = true // don't run twice @@ -130,7 +134,7 @@ struct DebugSettingsView: View { }.id("test1withdraw") if showDevelopItems { SettingsItem(name: String("HEAD"), id1: "head1with", - description: minimalistic ? nil : String("Get money for testing")) { + description: String("Get money for testing")) { let title = "Withdraw" Button(title) { withDrawDisabled = true // don't run twice @@ -147,11 +151,12 @@ struct DebugSettingsView: View { value: $developDelay.onChange({ delay in walletCore.developDelay = delay}), id1: "delay", - description: minimalistic ? nil : String("After each wallet-core action")) + description: String("After each wallet-core action")) .id("delay") #if DEBUG - SettingsItem(name: String("Run Dev Experiment Refresh"), id1: "applyDevExperiment", - description: minimalistic ? nil : "dev-experiment/insert-pending-refresh") { + SettingsItem(name: String("Run Dev Experiment Refresh"), + id1: "applyDevExperiment", + description: "dev-experiment/insert-pending-refresh") { let title = "Refresh" Button(title) { Task { // runs on MainActor @@ -164,8 +169,9 @@ struct DebugSettingsView: View { .buttonStyle(.bordered) }.id("Refresh") #endif - SettingsItem(name: String("Run Integration Test"), id1: "demo1test", - description: minimalistic ? nil : String("Perform basic test transactions")) { + SettingsItem(name: String("Run Integration Test"), + id1: "demo1test", + description: String("Perform basic test transactions")) { let title = "Demo 1" Button(title) { checkDisabled = true // don't run twice @@ -177,8 +183,9 @@ struct DebugSettingsView: View { .buttonStyle(.bordered) .disabled(checkDisabled) }.id("demo1runTest") - SettingsItem(name: String("Run Integration Test"), id1: "test1test", - description: minimalistic ? nil : "Perform basic test transactions") { + SettingsItem(name: String("Run Integration Test"), + id1: "test1test", + description: "Perform basic test transactions") { let title = "Test 1" Button(title) { checkDisabled = true // don't run twice @@ -190,8 +197,9 @@ struct DebugSettingsView: View { .buttonStyle(.bordered) .disabled(checkDisabled) }.id("test1runTest") - SettingsItem(name: String("Run Integration Test V2"), id1: "demo2test", - description: minimalistic ? nil : String("Perform more test transactions")) { + SettingsItem(name: String("Run Integration Test V2"), + id1: "demo2test", + description: String("Perform more test transactions")) { let title = "Demo 2" Button(title) { checkDisabled = true // don't run twice @@ -203,8 +211,9 @@ struct DebugSettingsView: View { .buttonStyle(.bordered) .disabled(checkDisabled) }.id("demo2runTest") - SettingsItem(name: String("Run Integration Test V2"), id1: "test2test", - description: minimalistic ? nil : String("Perform more test transactions")) { + SettingsItem(name: String("Run Integration Test V2"), + id1: "test2test", + description: String("Perform more test transactions")) { let title = "Test 2" Button(title) { checkDisabled = true // don't run twice @@ -216,8 +225,9 @@ struct DebugSettingsView: View { .buttonStyle(.bordered) .disabled(checkDisabled) }.id("test2runTest") - SettingsItem(name: String("Run Infinite Transaction Loop"), id1: "runInfinite", - description: minimalistic ? nil : String("Check DB in background")) { + SettingsItem(name: String("Run Infinite Transaction Loop"), + id1: "runInfinite", + description: String("Check DB in background")) { let title = "Loop" Button(title) { checkDisabled = true // don't run twice @@ -230,7 +240,7 @@ struct DebugSettingsView: View { .disabled(checkDisabled) }.id("runInfiniteLoop") SettingsItem(name: String("Save Logfile"), id1: "save", - description: minimalistic ? nil : String("Help debugging wallet-core")) { + description: String("Help debugging wallet-core")) { Button("Save") { symLog.log("Saving Log") // FIXME: Save Logfile @@ -239,7 +249,7 @@ struct DebugSettingsView: View { .disabled(true) }.id("saveLog") SettingsItem(name: String("Reset Wallet"), id1: "reset", - description: minimalistic ? nil : String("Throw away all your money")) { + description: String("Throw away all your money")) { Button("Reset") { showResetAlert = true } @@ -248,6 +258,7 @@ struct DebugSettingsView: View { }.id("resetWallet") } } + .padding(.bottom) .id(listID) .listStyle(myListStyle.style).anyView } diff --git a/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift b/TalerWallet1/Views/Settings/Exchange/ExchangeSectionView.swift @@ -1,5 +1,5 @@ /* - * This file is part of GNU Taler, ©2022-25 Taler Systems S.A. + * This file is part of GNU Taler, ©2022-26 Taler Systems S.A. * See LICENSE.md */ /** @@ -111,14 +111,16 @@ struct ExchangeSectionView: View { SettingsToggle(name: String("Global"), value: $global.onChange({ isGlobal in setGlobal() }), id1: "global", - description: minimalistic ? nil : String("Treat this as a global exchange")) + description: String("Treat this as a global exchange")) .listRowSeparator(.hidden) - SettingsToggle(name: String("Fake no fees"), value: $fakeNoFees, id1: "fakeNoFees", - description: minimalistic ? nil : String("Remove fee and gros from details")) + SettingsToggle(name: String("Fake no fees"), value: $fakeNoFees, + id1: "fakeNoFees", + description: String("Remove fee and gros from details")) } if DEMOCURRENCY == currency { - SettingsToggle(name: String(localized: "Demo Hints"), value: $demoHints, id1: "demoHints", - description: minimalistic ? nil : String(localized: "Show hints for demo money")) + SettingsToggle(name: String(localized: "Demo Hints"), value: $demoHints, + id1: "demoHints", + description: String(localized: "Show hints for demo money")) .listRowSeparator(.hidden) let bankingHint = String(localized: "Since the demo bank supports the Taler integration, you can start a withdrawal directly on the") let linkTitle = String(localized: "LinkTitle_DEMOBANK", defaultValue: "Demo Bank Website") diff --git a/TalerWallet1/Views/Settings/MoreSettingsView.swift b/TalerWallet1/Views/Settings/MoreSettingsView.swift @@ -0,0 +1,115 @@ +/* + * This file is part of GNU Taler, ©2022-26 Taler Systems S.A. + * See LICENSE.md + */ +/** + * @author Marc Stibane + */ +import SwiftUI +import taler_swift +import SymLog + +struct MoreSettingsView: View { + private let symLog = SymLogV(0) + let stack: CallStack + let navTitle: String + + @EnvironmentObject private var controller: Controller + @EnvironmentObject private var model: WalletModel +// @Environment(\.colorSchemeContrast) private var colorSchemeContrast +#if DEBUG + @AppStorage("developerMode") var developerMode: Bool = true +#else + @AppStorage("developerMode") var developerMode: Bool = false +#endif + @AppStorage("useHaptics") var useHaptics: Bool = true + @AppStorage("playSoundsI") var playSoundsI: Int = 1 + @AppStorage("playSoundsB") var playSoundsB: Bool = false + @AppStorage("talerFontIndex") var talerFontIndex: Int = 0 + @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic + @AppStorage("minimalistic") var minimalistic: Bool = false + @AppStorage("showQRauto16") var showQRauto16: Bool = true + @AppStorage("showQRauto17") var showQRauto17: Bool = false + @AppStorage("oimEuro") var oimEuro: Bool = false + @AppStorage("oimChart") var oimChart: Bool = false + + @State private var listID = UUID() + + func redraw(_ newFont: Int) -> Void { + if newFont != talerFontIndex { + talerFontIndex = newFont + withAnimation { listID = UUID() } + } + } + + var body: some View { +#if PRINT_CHANGES + let _ = Self._printChanges() + let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear +#endif + let walletCore = WalletCore.shared + Group { + List { + let showQRstring = String(localized: "Show QR codes") + let showQRhint = String(localized: "Automatically for P2P transactions") + if #available(iOS 17.7, *) { + SettingsToggle(name: showQRstring, value: $showQRauto17, id1: "showQRautomatic", + description: showQRhint) + } else { + SettingsToggle(name: showQRstring, value: $showQRauto16, id1: "showQRautomatic", + description: showQRhint) + } + + if controller.hapticCapability.supportsHaptics { + SettingsToggle(name: String(localized: "Haptics"), value: $useHaptics, + id1: "haptics", + description: String(localized: "Vibration Feedback")) + } + + SettingsToggle(name: String(localized: "Play Payment Sounds"), value: $playSoundsB, + id1: "playSounds", + description: String(localized: "When a transaction finished")) {_ in} + + /// Backup + let backupTitle = String(localized: "TitleBackup", defaultValue: "Backup / Restore") + let backupDest = BackupView(stack: stack.push(backupTitle), + navTitle: backupTitle) + NavigationLink { + backupDest + } label: { + SettingsItem(name: backupTitle, id1: "backup", + description: String(localized: "Backup your money")) {} + } + +#if OIM + SettingsToggle(name: String(localized: "OIM: Euro"), value: $oimEuro, + id1: "oimEuro", + description: String(localized: "OIM currency for KUDOS")) +#endif +#if OIM + SettingsToggle(name: String(localized: "OIM: Chart"), value: $oimChart, + id1: "oimChart", + description: String(localized: "OIM history as chart")) +#endif + +// SettingsFont(title: String(localized: "Font:"), value: talerFontIndex, action: redraw) +// .id("font") + } + .padding(.bottom) + .id(listID) + .listStyle(myListStyle.style).anyView + } + .navigationTitle(navTitle) + .onAppear() { + DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push()) + } + } // body +} +// MARK: - +#if DEBUG +//struct SettingsView_Previews: PreviewProvider { +// static var previews: some View { +// SettingsView(stack: CallStack("Preview"), balances: <#Binding<[Balance]>#>, navTitle: "Settings") +// } +//} +#endif diff --git a/TalerWallet1/Views/Settings/SettingsItem.swift b/TalerWallet1/Views/Settings/SettingsItem.swift @@ -1,5 +1,5 @@ /* - * This file is part of GNU Taler, ©2022-25 Taler Systems S.A. + * This file is part of GNU Taler, ©2022-26 Taler Systems S.A. * See LICENSE.md */ /** @@ -7,53 +7,110 @@ */ import SwiftUI -struct SettingsItem<Content: View>: View { - var name: String - var id1: String? - var imageName: String? - var description: String? - var content: () -> Content - - init(name: String, id1: String, imageName: String, description: String? = nil, @ViewBuilder content: @escaping () -> Content) { - self.name = name +struct SettingsImage: View { + let imageName: String? + + var hasImage: Bool { + if let imageName { + return UIImage(named: imageName) != nil + } + return false + } + + var hasSysImage: Bool { + if let imageName { + return UIImage(systemName: imageName) != nil + } + return false + } + + var body: some View { + if hasImage { + Image(imageName!) + .resizable() + .scaledToFit() + .frame(width: 44, height: 44) + } else if hasSysImage { + Image(systemName: imageName!) + .resizable() + .scaledToFit() + .frame(width: 36, height: 36) + .padding(.horizontal, 2) + } else { + EmptyView() + } + } +} + +struct SettingsDescription: View { + let id1: String? + let description: String? + + @AppStorage("minimalistic") var minimalistic: Bool = false + + var body: some View { + if !minimalistic { + if let desc = description { + Text(desc) + .id(id1 == nil ? nil : id1! + "_T") + .frame(maxWidth: .infinity, alignment: .leading) + .talerFont(.caption) + } + } + } +} +// MARK: - +struct SettingsBase<Content: View>: View { + let id1: String? + let description: String? + let content: () -> Content + + init(id1: String?, description: String? = nil, @ViewBuilder content: @escaping () -> Content) { self.id1 = id1 - self.imageName = imageName self.description = description self.content = content } - - init(name: String, id1: String, description: String? = nil, @ViewBuilder content: @escaping () -> Content) { + + var body: some View { + let isWeb = id1?.hasPrefix("web") ?? false + let foreColor = isWeb ? Color.accentColor + : .primary + VStack { + content() + .id(id1) + .frame(maxWidth: .infinity, alignment: .leading) + .foregroundColor(foreColor) + .talerFont(.title2) + .padding([.bottom], 0.01) + SettingsDescription(id1: id1, description: description) + }.id(id1 == nil ? nil : id1! + "_V") + } +} +// MARK: - +struct SettingsItem<Content: View>: View { + let name: String + let id1: String? + let imageName: String? + let description: String? + let content: () -> Content + + init(name: String, id1: String, imageName: String? = nil, description: String? = nil, + @ViewBuilder content: @escaping () -> Content + ) { self.name = name self.id1 = id1 - self.imageName = nil + self.imageName = imageName self.description = description self.content = content } - + var body: some View { HStack { - VStack { - let isWeb = id1?.hasPrefix("web") ?? false - let foreColor = isWeb ? Color.accentColor - : .primary - HStack(spacing: 8.0) { - if let imageName { - Image(systemName: imageName) - } - Text(name) - .id(id1) - } - .frame(maxWidth: .infinity, alignment: .leading) - .foregroundColor(foreColor) - .talerFont(.title2) - .padding([.bottom], 0.01) - if let desc = description { - Text(desc) - .id(id1 == nil ? nil : id1! + "_T") - .frame(maxWidth: .infinity, alignment: .leading) - .talerFont(.caption) - } - }.id(id1 == nil ? nil : id1! + "_V") + SettingsImage(imageName: imageName) + + SettingsBase(id1: id1, description: description) { + Text(name) + } content() .talerFont(.body) }.id(id1 == nil ? nil : id1! + "_H") @@ -63,11 +120,25 @@ struct SettingsItem<Content: View>: View { } // MARK: - struct SettingsToggle: View { - var name: String + let name: String @Binding var value: Bool - var id1: String? = nil - var description: String? - var action: () -> Void = {} + let id1: String? + let imageName: String? + let description: String? + let action: (_ newValue: Bool) -> Void + + init(name: String, value: Binding<Bool>, id1: String? = nil, + imageName: String? = nil, + description: String? = nil, + action: @escaping (_ newValue: Bool) -> Void = {_ in} + ) { + self.name = name + self._value = value + self.id1 = id1 + self.imageName = imageName + self.description = description + self.action = action + } var body: some View { let accLabel: String = if let description { @@ -75,28 +146,20 @@ struct SettingsToggle: View { } else { name } - VStack { - Toggle(name, isOn: $value.animation()) - .id(id1) -// .accessibilityLabel(name) - .accessibility(sortPriority: 1) - .talerFont(.title2) - .onChange(of: value) { value in - action() - } + HStack { + SettingsImage(imageName: imageName) - if let desc = description { - Text(desc) - .id(id1 == nil ? nil : id1! + "_T") - .frame(maxWidth: .infinity, alignment: .leading) - .accessibility(sortPriority: 0) - .talerFont(.caption) + SettingsBase(id1: id1, description: description) { + Toggle(name, isOn: $value.animation()) + .accessibility(sortPriority: 1) + .onChange(of: value) { value in + action(value) + } } - } + }.id(id1 == nil ? nil : id1! + "_H") .accessibilityElement(children: .combine) .accessibilityLabel(accLabel) .padding([.bottom], 4) - .id(id1 == nil ? nil : id1! + "_V") } } // MARK: - @@ -151,6 +214,7 @@ struct SettingsStyle: View { struct SettingsTriState: View { var name: String @Binding var value: Int + let id1: String? var description: String? var action: (_ value: Int) -> Void = {value in } @@ -185,11 +249,7 @@ struct SettingsTriState: View { } } - if let desc = description { - Text(desc) - .frame(maxWidth: .infinity, alignment: .leading) - .talerFont(.caption) - } + SettingsDescription(id1: id1, description: description) } .accessibilityElement(children: .combine) .accessibilityLabel(name) @@ -209,8 +269,8 @@ struct SettingsItemPreview : View { SettingsToggle(name: "Developer Preview", value: $developerMode, id1: "dev1", description: "More information intended for debugging") SettingsTriState(name: "Observe walletCore", value: $observe, - description: "on LocalConsole") - + id1: "observe", + description: "on LocalConsole") } } } @@ -218,13 +278,14 @@ struct SettingsItemPreview : View { struct SettingsItem_Previews: PreviewProvider { static var previews: some View { List { - SettingsItem (name: "Exchanges", id1: "list", description: "Manage list of exchanges known to this wallet") {} + SettingsItem(name: "Exchanges", id1: "list", + description: "Manage list of exchanges known to this wallet") {} SettingsItemPreview() - SettingsItem(name: "Save Logfile", id1: "save", description: "Help debugging wallet-core") { - Button("Save") { - } - .buttonStyle(.bordered) - .disabled(true) + SettingsItem(name: "Save Logfile", id1: "save", + description: "Help debugging wallet-core") { + Button("Save") { } + .buttonStyle(.bordered) + .disabled(true) } } } diff --git a/TalerWallet1/Views/Settings/SettingsView.swift b/TalerWallet1/Views/Settings/SettingsView.swift @@ -8,7 +8,6 @@ import SwiftUI import taler_swift import SymLog -import LocalConsole struct SettingsView: View { private let symLog = SymLogV(0) @@ -24,29 +23,13 @@ struct SettingsView: View { #else @AppStorage("developerMode") var developerMode: Bool = false #endif - @AppStorage("useHaptics") var useHaptics: Bool = true - @AppStorage("playSoundsI") var playSoundsI: Int = 1 - @AppStorage("playSoundsB") var playSoundsB: Bool = false @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true -// @AppStorage("increaseContrast") var increaseContrast: Bool = false - @AppStorage("talerFontIndex") var talerFontIndex: Int = 0 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic @AppStorage("minimalistic") var minimalistic: Bool = false @AppStorage("useAuthentication") var useAuthentication: Bool = false - @AppStorage("showQRauto16") var showQRauto16: Bool = true - @AppStorage("showQRauto17") var showQRauto17: Bool = false - @AppStorage("oimEuro") var oimEuro: Bool = false - @AppStorage("oimChart") var oimChart: Bool = false - @State private var hideDescriptions = false @State private var listID = UUID() - func redraw(_ newFont: Int) -> Void { - if newFont != talerFontIndex { - talerFontIndex = newFont - withAnimation { listID = UUID() } - } - } var body: some View { #if PRINT_CHANGES let _ = Self._printChanges() @@ -67,8 +50,7 @@ struct SettingsView: View { NavigationLink { // whole row like in a tableView AboutView(stack: stack.push(), navTitle: aboutStr) } label: { - SettingsItem(name: aboutStr, id1: "about", - description: hideDescriptions ? nil : String(localized: "More info about this app...")) {} + SettingsItem(name: aboutStr, id1: "about", imageName: TALER_LOGO) {} } let exchangesTitle = String(localized: "TitleExchanges", defaultValue: "Payment Services") @@ -77,8 +59,8 @@ struct SettingsView: View { NavigationLink { // whole row like in a tableView exchangesDest } label: { - SettingsItem(name: exchangesTitle, id1: "exchanges", - description: hideDescriptions ? nil : String(localized: "Manage payment services...")) {} + SettingsItem(name: exchangesTitle, id1: "exchanges", imageName: EXCHANGE_LOGO, + description: String(localized: "Manage payment services")) {} } let bankAccountsTitle = String(localized: "TitleBankAccounts", defaultValue: "Bank Accounts") let bankAccountsDest = BankListView(stack: stack.push(bankAccountsTitle), @@ -87,76 +69,48 @@ struct SettingsView: View { bankAccountsDest } label: { SettingsItem(name: bankAccountsTitle, id1: "bankAccounts", - description: hideDescriptions ? nil : String(localized: "Your accounts for deposit...")) {} + imageName: "building.columns", + description: String(localized: "Your accounts for deposit")) {} } - let showQRstring = String(localized: "Show QR codes") - let showQRhint = String(localized: "Automatically for P2P transactions") - if #available(iOS 17.7, *) { - SettingsToggle(name: showQRstring, value: $showQRauto17, id1: "showQRautomatic", - description: minimalistic ? nil : showQRhint) {} - } else { - SettingsToggle(name: showQRstring, value: $showQRauto16, id1: "showQRautomatic", - description: minimalistic ? nil : showQRhint) {} - } let biometryType = biometricService.biometryType() - let biometryString = biometryType == .faceID ? String(localized: "Use FaceID") - : biometryType == .touchID ? String(localized: "Use TouchID") + let hasFaceID = biometryType == .faceID + let hasTouchID = biometryType == .touchID + let biometryString = hasFaceID ? String(localized: "Use FaceID") + : hasTouchID ? String(localized: "Use TouchID") : EMPTYSTRING if !biometryString.isEmpty { - SettingsToggle(name: biometryString, value: $useAuthentication, id1: "useFaceID", - description: minimalistic ? nil : String(localized: "Protect your money")) { + SettingsToggle(name: biometryString, + value: $useAuthentication, + id1: "useFaceID", + imageName: hasFaceID ? "faceid" : "touchid", // 􀎽 􀟒 + description: String(localized: "Protect your money")) { _ in biometricService.isAuthenticated = false } // } else { // biometricService.isAuthenticated = false } - /// Backup - let backupTitle = String(localized: "TitleBackup", defaultValue: "Backup / Restore") - let backupDest = BackupView(stack: stack.push(backupTitle), - navTitle: backupTitle) - NavigationLink { // whole row like in a tableView - backupDest - } label: { - SettingsItem(name: backupTitle, id1: "backup", - description: hideDescriptions ? nil : String(localized: "Backup your money...")) {} - } + SettingsToggle(name: String(localized: "Minimalistic"), value: $minimalistic, id1: "minimal", + imageName: "heart", // 􀊴 + description: String(localized: "Omit text where possible")) + + SettingsToggle(name: String(localized: "Show Warnings"), value: $shouldShowWarning, + id1: "warnings", + imageName: "exclamationmark.triangle", // 􀇾 + description: String(localized: "For Delete, Abandon & Abort buttons")) - /// Report + /// Report let reportTitle = String(localized: "TitleReport", defaultValue: "Report diagnostics") let reportDest = ReportView(stack: stack.push(reportTitle), navTitle: reportTitle) - NavigationLink { // whole row like in a tableView + NavigationLink { reportDest } label: { SettingsItem(name: reportTitle, id1: "report", - description: hideDescriptions ? nil : String(localized: "Help improve this app...")) {} - } - -#if OIM - SettingsToggle(name: String(localized: "OIM: Euro"), value: $oimEuro, id1: "oimEuro", - description: minimalistic ? nil : String(localized: "OIM currency for KUDOS")) -#endif -#if OIM - SettingsToggle(name: String(localized: "OIM: Chart"), value: $oimChart, id1: "oimChart", - description: minimalistic ? nil : String(localized: "OIM history as chart")) -#endif - - SettingsToggle(name: String(localized: "Minimalistic"), value: $minimalistic, id1: "minimal", - description: hideDescriptions ? nil : String(localized: "Omit text where possible")) { - hideDescriptions = minimalistic //withAnimation { hideDescriptions = minimalistic } + imageName: "arrow.up.message", // 􀜃 + description: String(localized: "Help improve \(localizedAppName)")) {} } - if controller.hapticCapability.supportsHaptics { - SettingsToggle(name: String(localized: "Haptics"), value: $useHaptics, id1: "haptics", - description: hideDescriptions ? nil : String(localized: "Vibration Feedback")) - } - SettingsToggle(name: String(localized: "Play Payment Sounds"), value: $playSoundsB, id1: "playSounds", - description: hideDescriptions ? nil : String(localized: "When a transaction finished")) - SettingsToggle(name: String(localized: "Show Warnings"), value: $shouldShowWarning, id1: "warnings", - description: hideDescriptions ? nil : String(localized: "For Delete, Abandon & Abort buttons")) -// SettingsFont(title: String(localized: "Font:"), value: talerFontIndex, action: redraw) -// .id("font") #if DEBUG let showDiagnostic = true @@ -167,20 +121,33 @@ struct SettingsView: View { let devTitle = String(localized: "TitleDeveloper", defaultValue: "Developer") let devDest = DebugSettingsView(stack: stack.push(devTitle), navTitle: devTitle) - NavigationLink { // whole row like in a tableView + NavigationLink { devDest } label: { SettingsItem(name: devTitle, id1: "developer", - description: hideDescriptions ? nil : String(localized: "Help debug this app...")) {} + imageName: "hammer", // 􀙄 + description: String(localized: "Help debug \(localizedAppName)")) {} } } + + let moreItem = String(localized: "TitleMore", defaultValue: "More") + let moreTitle = String(localized: "TitleMoreSettings", defaultValue: "More Settings") + let moreDest = MoreSettingsView(stack: stack.push(moreTitle), + navTitle: moreTitle) + NavigationLink { + moreDest + } label: { + SettingsItem(name: moreItem, id1: "more", + imageName: "ellipsis", // 􀍠 + description: nil) {} + } } + .padding(.bottom) .id(listID) .listStyle(myListStyle.style).anyView } .navigationTitle(navTitle) .onAppear() { - hideDescriptions = minimalistic DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push()) } } // body