taler-ios

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

P2pPayURIView.swift (5439B)


      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 // Called either when scanning a QR code or tapping the provided link
     13 // from another user's Request(Invoice). We show the P2P details.
     14 struct P2pPayURIView: View {
     15     private let symLog = SymLogV(0)
     16     let stack: CallStack
     17 
     18     // the scanned URL
     19     let url: URL
     20 
     21     @EnvironmentObject private var model: WalletModel
     22     @EnvironmentObject private var controller: Controller
     23     @AppStorage("myListStyle") var myListStyle: MyListStyle = .automatic
     24 
     25     @State private var peerPullDebitResponse: PreparePeerPullDebitResponse?
     26 
     27     let navTitle = String(localized: "Pay Request", comment: "Nav Title")
     28 
     29     @MainActor
     30     private func viewDidLoad() async {
     31         do {
     32             symLog.log(".task")
     33             let response = try? await model.preparePeerPullDebit(url.absoluteString)
     34             if let response {
     35                 controller.removeURL(url)       // tx is now saved by wallet-core
     36             }
     37             peerPullDebitResponse = response
     38         }
     39     }
     40 
     41     var body: some View {
     42         VStack {
     43             if let peerPullDebitResponse {
     44                 List {
     45                     PeerPullDebitView(stack: stack.push(),
     46                                         raw: peerPullDebitResponse.amountRaw,
     47                                   effective: peerPullDebitResponse.amountEffective,
     48                                       scope: peerPullDebitResponse.scopeInfo,
     49                                     summary: peerPullDebitResponse.contractTerms.summary)
     50                     let expiration = peerPullDebitResponse.contractTerms.purse_expiration
     51                     ExpiresView(expiration: expiration)
     52                 }
     53                 .listStyle(myListStyle.style).anyView
     54                 .navigationTitle(navTitle)
     55 //                .task(id: controller.currencyTicker) {
     56 //                    let currency = peerPullDebitResponse.amountRaw.currencyStr
     57 //                    currencyInfo = controller.info2(for: currency, controller.currencyTicker)
     58 //                }
     59                 .safeAreaInset(edge: .bottom) {
     60                     if peerPullDebitResponse.txState.isConfirmed {
     61                         Button("Done") { dismissTop(stack.push()) }
     62                             .buttonStyle(TalerButtonStyle(type: .prominent))
     63                             .padding(.horizontal)
     64                     } else {
     65                         PeerPullDebitConfirm(stack: stack.push(), url: url,
     66                                      transactionId: peerPullDebitResponse.transactionId)
     67                     }
     68                 }
     69             } else {
     70 #if DEBUG
     71                 let message = url.host
     72 #else
     73                 let message: String? = nil
     74 #endif
     75                 LoadingView(stack: stack.push(), scopeInfo: nil, message: message)
     76                     .task { await viewDidLoad() }
     77             }
     78         }
     79         .onAppear() {
     80             symLog.log("onAppear")
     81             DebugViewC.shared.setSheetID(SHEET_PAY_P2P)
     82         }
     83     }
     84 }
     85 // MARK: -
     86 //#Preview {
     87 //    P2pPayURIView(url: <#T##URL#>, model: <#T##WalletModel#>)
     88 //}
     89 // MARK: -
     90 struct PeerPullDebitConfirm: View  {
     91     let stack: CallStack
     92     let url: URL?
     93     let transactionId: String
     94 
     95     var body: some View {
     96         let destination = P2pAcceptDone(stack: stack.push(),
     97                                           url: url,
     98                                 transactionId: transactionId,
     99                                      incoming: false)
    100         NavigationLink(destination: destination) {
    101             Text("Confirm Payment", comment:"pay P2P request/invoice")      // SHEET_PAY_P2P
    102         }
    103         .buttonStyle(TalerButtonStyle(type: .prominent))
    104         .padding(.horizontal)
    105     }
    106 }
    107 // MARK: -
    108 struct PeerPullDebitView: View  {
    109     let stack: CallStack
    110 //    let peerPullDebitResponse: PreparePeerPullDebitResponse
    111     let raw: Amount
    112     let effective: Amount
    113     let scope: ScopeInfo?
    114     let summary: String
    115 
    116     @Environment(\.colorScheme) private var colorScheme
    117     @Environment(\.colorSchemeContrast) private var colorSchemeContrast
    118     @AppStorage("minimalistic") var minimalistic: Bool = false
    119     var body: some View {
    120 //        let raw = peerPullDebitResponse.amountRaw
    121 //        let effective = peerPullDebitResponse.amountEffective
    122 //        let scope = peerPullDebitResponse.scopeInfo
    123         let currency = raw.currencyStr
    124         let fee = try! Amount.diff(raw, effective)
    125         ThreeAmountsSection(stack: stack.push(),
    126                             scope: scope,
    127                          topTitle: String(localized: "Amount to pay:"),
    128                         topAbbrev: String(localized: "Pay:", comment: "mini"),
    129                         topAmount: raw,
    130                            noFees: nil,        // TODO: check baseURL for fees
    131                               fee: fee,
    132                       bottomTitle: String(localized: "Amount to be spent:"),
    133                      bottomAbbrev: String(localized: "Effective:", comment: "mini"),
    134                      bottomAmount: effective,
    135                             large: false, pending: false, incoming: false,
    136                           baseURL: nil,
    137                        txStateLcl: nil,
    138                           summary: summary,
    139                          merchant: nil,
    140                          products: nil)
    141     }
    142 }