QRCodeDetailView.swift (4739B)
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 AVFoundation 11 12 struct QRCodeDetailView: View { 13 let talerURI: String 14 let talerCopyShare: String 15 let incoming: Bool 16 let amount: Amount 17 let scope: ScopeInfo? 18 19 @EnvironmentObject private var controller: Controller 20 @AppStorage("minimalistic") var minimalistic: Bool = false 21 @AppStorage("showQRauto16") var showQRauto16: Bool = true 22 @AppStorage("showQRauto17") var showQRauto17: Bool = false 23 24 @State private var showQRcode = false 25 @State private var currencyInfo: CurrencyInfo? 26 @State private var qrImage: UIImage? = nil 27 28 private func currencyTickerChanged() async { 29 if let scope { 30 currencyInfo = controller.info(for: scope) 31 } 32 } 33 34 private func amountStr(_ currencyInfo : CurrencyInfo?) -> (String, String) { 35 let amountFormatted: (String, String) 36 let readable = amount.readableDescription 37 let myCurrencyInfo = currencyInfo ?? (scope != nil ? controller.info(for: scope!) : nil) 38 if let myCurrencyInfo { 39 amountFormatted = amount.formatted(myCurrencyInfo, isNegative: false, 40 useISO: false, a11yDecSep: nil) 41 } else { 42 amountFormatted = (readable, readable) 43 } 44 return amountFormatted 45 } 46 47 private func requesting(_ amountS: String) -> String { 48 minimalistic ? String(localized: "(payer) 1 mini", 49 defaultValue: "Requesting \(amountS)", 50 comment: "e.g. '5,3 €'") 51 : String(localized: "(payer) 1", 52 defaultValue: "Scan this to pay \(amountS)", 53 comment: "e.g. '5,3 €'") 54 } 55 private func sending(_ amountS: String) -> String { 56 minimalistic ? String(localized: "(payee) 1 mini", 57 defaultValue: "Sending \(amountS)", 58 comment: "e.g. '$ 7.41'") 59 : String(localized: "(payee) 1", 60 defaultValue: "Scan this to receive \(amountS)", 61 comment: "e.g. '$ 7.41'") 62 } 63 64 var body: some View { 65 if talerURI.count > 10 { 66 Section { 67 let amountStr = amountStr(currencyInfo) 68 let scanLong = incoming ? (requesting(amountStr.0), requesting(amountStr.1)) 69 : (sending(amountStr.0), sending(amountStr.1)) 70 let size = 240.0 71 let qrView = QRGeneratorView(text: talerURI, size: size, image: $qrImage) 72 .frame(maxWidth: .infinity, alignment: .center) 73 .accessibilityLabel(Text("QR Code", comment: "a11y")) 74 if #available(iOS 17.7, *) { 75 BorderWithHCE(talerURI: talerURI, nfcHint: true, size: size, scanHints: scanLong) { 76 qrView 77 } 78 } else if showQRcode { 79 qrView 80 } else { 81 let qrCode = Image(systemName: QRCODE) // "qrcode" 82 Button(minimalistic ? "\(qrCode)" : "\(qrCode) Show QR code") { 83 withAnimation { showQRcode = true } 84 }.buttonStyle(TalerButtonStyle(type: .prominent)) 85 } 86 CopyShare(textToCopy: talerCopyShare, image: qrImage) 87 .disabled(false) 88 // .padding(.bottom) 89 .listRowSeparator(.hidden) 90 91 } 92 .task(id: controller.currencyTicker) { await currencyTickerChanged() } 93 .task { 94 withAnimation { 95 if #available(iOS 17.7, *) { 96 showQRcode = showQRauto17 97 } else { 98 showQRcode = showQRauto16 99 } 100 } 101 } 102 } 103 } 104 } 105 // MARK: - 106 #if DEBUG 107 //fileprivate struct ContentView: View { 108 // @State var previewURI: String = "taler://pay-push/exchange.demo.taler.net/95ZG4D1AGFGZQ7CNQ1V49D3FT18HXKA6HQT4X3XME9YSJQVFQ520" 109 // 110 // var body: some View { 111 // let amount = Amount(currency: LONGCURRENCY, cent: 123) 112 // List { 113 // QRCodeDetailView(talerURI: previewURI, talerCopyShare: previewURI, incoming: false, amount: amount) 114 // } 115 // } 116 //} 117 //struct QRCodeDetailView_Previews: PreviewProvider { 118 // 119 // static var previews: some View { 120 // ContentView() 121 // } 122 //} 123 #endif