taler-ios

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

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