SettingsView.swift (7286B)
1 /* 2 * This file is part of GNU Taler, ©2022-26 Taler Systems S.A. 3 * See LICENSE.md 4 */ 5 /** 6 * @author Marc Stibane 7 */ 8 import SwiftUI 9 import taler_swift 10 import SymLog 11 12 struct SettingsView: View { 13 private let symLog = SymLogV(0) 14 let stack: CallStack 15 let navTitle: String 16 17 @EnvironmentObject private var controller: Controller 18 @EnvironmentObject private var model: WalletModel 19 @EnvironmentObject private var biometricService: BiometricService 20 // @Environment(\.colorSchemeContrast) private var colorSchemeContrast 21 #if DEBUG 22 @AppStorage("developerMode") var developerMode: Bool = true 23 #else 24 @AppStorage("developerMode") var developerMode: Bool = false 25 #endif 26 @AppStorage("shouldShowWarning") var shouldShowWarning: Bool = true 27 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic 28 @AppStorage("minimalistic") var minimalistic: Bool = false 29 @AppStorage("useAuthentication") var useAuthentication: Bool = false 30 31 @State private var listID = UUID() 32 33 var body: some View { 34 #if PRINT_CHANGES 35 let _ = Self._printChanges() 36 let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear 37 #endif 38 let walletCore = WalletCore.shared 39 Group { 40 List { 41 #if TALER_WALLET 42 let appName = "Taler Wallet" 43 #elseif TALER_NIGHTLY 44 let appName = "Taler Nightly" 45 #else 46 let appName = "GNU Taler" 47 #endif 48 let localizedAppName = Bundle.main.bundleName ?? appName 49 let aboutStr = String(localized: "About \(localizedAppName)") 50 NavigationLink { // whole row like in a tableView 51 AboutView(stack: stack.push(), navTitle: aboutStr) 52 } label: { 53 SettingsItem(name: aboutStr, id1: "about", imageName: TALER_LOGO) {} 54 } 55 56 let exchangesTitle = String(localized: "TitleExchanges", defaultValue: "Payment Services") 57 let exchangesDest = ExchangeListView(stack: stack.push(exchangesTitle), 58 navTitle: exchangesTitle) 59 NavigationLink { // whole row like in a tableView 60 exchangesDest 61 } label: { 62 SettingsItem(name: exchangesTitle, id1: "exchanges", imageName: EXCHANGE_LOGO, 63 description: String(localized: "Manage payment services")) {} 64 } 65 let bankAccountsTitle = String(localized: "TitleBankAccounts", defaultValue: "Bank Accounts") 66 let bankAccountsDest = BankListView(stack: stack.push(bankAccountsTitle), 67 navTitle: bankAccountsTitle) 68 NavigationLink { // whole row like in a tableView 69 bankAccountsDest 70 } label: { 71 SettingsItem(name: bankAccountsTitle, id1: "bankAccounts", 72 imageName: "building.columns", 73 description: String(localized: "Your accounts for deposit")) {} 74 } 75 76 let biometryType = biometricService.biometryType() 77 let hasFaceID = biometryType == .faceID 78 let hasTouchID = biometryType == .touchID 79 let biometryString = hasFaceID ? String(localized: "Use FaceID") 80 : hasTouchID ? String(localized: "Use TouchID") 81 : EMPTYSTRING 82 if !biometryString.isEmpty { 83 SettingsToggle(name: biometryString, 84 value: $useAuthentication, 85 id1: "useFaceID", 86 imageName: hasFaceID ? "faceid" : "touchid", // 87 description: String(localized: "Protect your money")) { _ in 88 biometricService.isAuthenticated = false 89 } 90 // } else { 91 // biometricService.isAuthenticated = false 92 } 93 94 SettingsToggle(name: String(localized: "Minimalistic"), value: $minimalistic, id1: "minimal", 95 imageName: "heart", // 96 description: String(localized: "Omit text where possible")) 97 98 SettingsToggle(name: String(localized: "Show Warnings"), value: $shouldShowWarning, 99 id1: "warnings", 100 imageName: "exclamationmark.triangle", // 101 description: String(localized: "For Delete, Abandon & Abort buttons")) 102 103 /// Report 104 let reportTitle = String(localized: "TitleReport", defaultValue: "Report diagnostics") 105 let reportDest = ReportView(stack: stack.push(reportTitle), 106 navTitle: reportTitle) 107 NavigationLink { 108 reportDest 109 } label: { 110 SettingsItem(name: reportTitle, id1: "report", 111 imageName: "arrow.up.message", // 112 description: String(localized: "Help improve \(localizedAppName)")) {} 113 } 114 115 #if DEBUG 116 let showDiagnostic = true 117 #else 118 let showDiagnostic = controller.diagnosticModeEnabled 119 #endif 120 if showDiagnostic { 121 let devTitle = String(localized: "TitleDeveloper", defaultValue: "Developer") 122 let devDest = DebugSettingsView(stack: stack.push(devTitle), 123 navTitle: devTitle) 124 NavigationLink { 125 devDest 126 } label: { 127 SettingsItem(name: devTitle, id1: "developer", 128 imageName: "hammer", // 129 description: String(localized: "Help debug \(localizedAppName)")) {} 130 } 131 } 132 133 let moreItem = String(localized: "TitleMore", defaultValue: "More") 134 let moreTitle = String(localized: "TitleMoreSettings", defaultValue: "More Settings") 135 let moreDest = MoreSettingsView(stack: stack.push(moreTitle), 136 navTitle: moreTitle) 137 NavigationLink { 138 moreDest 139 } label: { 140 SettingsItem(name: moreItem, id1: "more", 141 imageName: "ellipsis", // 142 description: nil) {} 143 } 144 } 145 .padding(.bottom) 146 .id(listID) 147 .listStyle(myListStyle.style).anyView 148 } 149 .navigationTitle(navTitle) 150 .onAppear() { 151 DebugViewC.shared.setViewID(VIEW_SETTINGS, stack: stack.push()) 152 } 153 } // body 154 } 155 // MARK: - 156 #if DEBUG 157 //struct SettingsView_Previews: PreviewProvider { 158 // static var previews: some View { 159 // SettingsView(stack: CallStack("Preview"), balances: <#Binding<[Balance]>#>, navTitle: "Settings") 160 // } 161 //} 162 #endif