AboutView.swift (6880B)
1 /* 2 * This file is part of GNU Taler, ©2022-25 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 AboutView: View { 13 private let symLog = SymLogV(0) 14 let stack: CallStack 15 let localizedAppName: String 16 let navTitle: String 17 18 @EnvironmentObject private var controller: Controller 19 #if DEBUG 20 @AppStorage("developerMode") var developerMode: Bool = true 21 #else 22 @AppStorage("developerMode") var developerMode: Bool = false 23 #endif 24 @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic 25 @AppStorage("minimalistic") var minimalistic: Bool = false 26 @AppStorage("tapped") var tapped: Int = 0 27 @AppStorage("dragged") var dragged: Int = 0 28 29 @State private var rotationEnabled = false 30 @State private var showGitHash = false 31 @State private var listID = UUID() 32 @State private var onboarding = false 33 34 var body: some View { 35 #if PRINT_CHANGES 36 let _ = Self._printChanges() 37 let _ = symLog.vlog() // just to get the # to compare it with .onAppear & onDisappear 38 #endif 39 let walletCore = WalletCore.shared 40 let size = 100.0 41 let rotatingTaler = RotatingTaler(size: size, 42 progress: false, 43 once: true, 44 rotationEnabled: $rotationEnabled) 45 .accessibilityHidden(true) // has its own accessibilityLabel 46 .frame(maxWidth: .infinity, alignment: .center) 47 .onTapGesture(count: 1) { rotationEnabled.toggle() } 48 Group { 49 List { 50 if #available(iOS 17.7, *) { 51 let talerURI = TALER_NET 52 BorderWithHCE(talerURI: talerURI, nfcHint: false, size: size, scanHints: nil) { 53 rotatingTaler 54 } 55 } else { 56 rotatingTaler 57 } 58 SettingsItem(name: String(localized: "Visit the taler.net website"), 59 id1: "webTaler", 60 imageName: LINK, 61 description: String(localized: "More info about GNU Taler in general")) { } 62 .accessibilityAddTraits(.isLink) 63 .accessibilityRemoveTraits(.isStaticText) 64 .onTapGesture() { 65 UIApplication.shared.open(URL(string:TALER_NET)!, options: [:]) 66 } 67 68 SettingsItem(name: String(localized: "Open \(localizedAppName) settings"), 69 id1: "webSettings", 70 imageName: SETTINGS, 71 description: String(localized: "System settings -> Apps")) { } 72 .accessibilityAddTraits(.isLink) 73 .accessibilityRemoveTraits(.isStaticText) 74 .onTapGesture() { 75 UIApplication.shared.open(URL(string: UIApplication.openSettingsURLString)!, options: [:]) 76 } 77 78 SettingsItem(name: String(localized: "App Version"), id1: "app") { 79 Text(verbatim: "\(Bundle.main.releaseVersionNumberPretty)") 80 } 81 Group { 82 if showGitHash { 83 SettingsItem(name: "Wallet-Core Git", id1: "wallet-coreG") { 84 if let gitHash = walletCore.versionInfo?.implementationGitHash { 85 let index = gitHash.index(gitHash.startIndex, offsetBy: 7) 86 Text(gitHash[..<index]) 87 } else { 88 Text(verbatim: "unknown") 89 } 90 } 91 } else { 92 SettingsItem(name: String(localized: "Wallet-Core Version"), id1: "wallet-coreV") { 93 Text(verbatim: "\(walletCore.versionInfo?.implementationSemver ?? "unknown")") 94 } 95 } 96 }.onTapGesture(count: 1) { showGitHash.toggle() } 97 98 SettingsToggle(name: String(localized: "Onboarding"), 99 value: $onboarding.onChange({ shouldOnboard in 100 if shouldOnboard { 101 tapped = 0 102 dragged = 0 103 } else { 104 tapped = TAPPED 105 dragged = DRAGGED 106 } 107 }), 108 id1: "onboarding", 109 description: String(localized: "Explain the Actions button")) 110 #if DEBUG 111 Text(verbatim: "Tapped: \(tapped), dragged: \(dragged)") 112 .onTapGesture { 113 tapped = 0 114 } 115 #endif 116 117 // SettingsItem(name: "Supported Exchange Versions", id1: "exchange") { 118 // Text(verbatim: "\(walletCore.versionInfo?.exchange ?? "unknown")") 119 // } 120 // SettingsItem(name: "Supported Merchant Versions", id1: "merchant") { 121 // Text(verbatim: "\(walletCore.versionInfo?.merchant ?? "unknown")") 122 // } 123 // SettingsItem(name: "Used Bank", id1: "bank") { 124 // Text(verbatim: "\(walletCore.versionInfo?.bank ?? "unknown")") 125 // } 126 } 127 .id(listID) 128 .listStyle(myListStyle.style).anyView 129 } 130 .navigationTitle(navTitle) 131 .task { 132 onboarding = (tapped < TAPPED || dragged < DRAGGED) 133 // try? await Task.sleep(nanoseconds: 1_000_000_000 * UInt64(5)) 134 // rotationEnabled.toggle() 135 } 136 .onAppear() { 137 DebugViewC.shared.setViewID(VIEW_ABOUT, stack: stack.push()) 138 } 139 } 140 } 141 extension Bundle { 142 var bundleName: String? { 143 return infoDictionary?["CFBundleDisplayName"] as? String 144 } 145 var releaseVersionNumber: String? { 146 return infoDictionary?["CFBundleShortVersionString"] as? String 147 } 148 var buildVersionNumber: String { 149 let build = infoDictionary?["CFBundleVersion"] 150 let zero = "0" 151 if let build { 152 return build as? String ?? zero 153 } 154 return zero 155 } 156 var releaseVersionNumberPretty: String { 157 let release = releaseVersionNumber ?? "1.0.0" 158 return release // "v\(release) (\(buildVersionNumber))" 159 } 160 } 161 // MARK: - 162 #if DEBUG 163 struct AboutView_Previews: PreviewProvider { 164 static var previews: some View { 165 AboutView(stack: CallStack("Preview"), localizedAppName: "GNU Taler", navTitle: "About") 166 } 167 } 168 #endif