taler-ios

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

P2pPayURIView.swift (5548B)


      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                                      isDone: false,
     49                                       scope: peerPullDebitResponse.scopeInfo,
     50                                     summary: peerPullDebitResponse.contractTerms.summary)
     51                     let expiration = peerPullDebitResponse.contractTerms.purse_expiration
     52                     ExpiresView(expiration: expiration)
     53                 }
     54                 .listStyle(myListStyle.style).anyView
     55                 .navigationTitle(navTitle)
     56 //                .task(id: controller.currencyTicker) {
     57 //                    let currency = peerPullDebitResponse.amountRaw.currencyStr
     58 //                    currencyInfo = controller.info2(for: currency, controller.currencyTicker)
     59 //                }
     60                 .safeAreaInset(edge: .bottom) {
     61                     if peerPullDebitResponse.txState.isConfirmed {
     62                         Button("Done") { dismissTop(stack.push()) }
     63                             .buttonStyle(TalerButtonStyle(type: .prominent))
     64                             .padding(.horizontal)
     65                     } else {
     66                         PeerPullDebitConfirm(stack: stack.push(), url: url,
     67                                      transactionId: peerPullDebitResponse.transactionId)
     68                     }
     69                 }
     70             } else {
     71 #if DEBUG
     72                 let message = url.host
     73 #else
     74                 let message: String? = nil
     75 #endif
     76                 LoadingView(stack: stack.push(), scopeInfo: nil, message: message)
     77                     .task { await viewDidLoad() }
     78             }
     79         }
     80         .onAppear() {
     81             symLog.log("onAppear")
     82             DebugViewC.shared.setSheetID(SHEET_PAY_P2P, stack: stack.push())
     83         }
     84     }
     85 }
     86 // MARK: -
     87 //#Preview {
     88 //    P2pPayURIView(url: <#T##URL#>, model: <#T##WalletModel#>)
     89 //}
     90 // MARK: -
     91 struct PeerPullDebitConfirm: View  {
     92     let stack: CallStack
     93     let url: URL?
     94     let transactionId: String
     95 
     96     var body: some View {
     97         let destination = P2pAcceptDone(stack: stack.push(),
     98                                           url: url,
     99                                 transactionId: transactionId,
    100                                      incoming: false)
    101         NavigationLink(destination: destination) {
    102             Text("Confirm Payment", comment:"pay P2P request/invoice")      // SHEET_PAY_P2P
    103         }
    104         .buttonStyle(TalerButtonStyle(type: .prominent))
    105         .padding(.horizontal)
    106     }
    107 }
    108 // MARK: -
    109 struct PeerPullDebitView: View  {
    110     let stack: CallStack
    111 //    let peerPullDebitResponse: PreparePeerPullDebitResponse
    112     let raw: Amount
    113     let effective: Amount
    114     let isDone: Bool
    115     let scope: ScopeInfo?
    116     let summary: String
    117 
    118     @Environment(\.colorScheme) private var colorScheme
    119     @Environment(\.colorSchemeContrast) private var colorSchemeContrast
    120     @AppStorage("minimalistic") var minimalistic: Bool = false
    121     var body: some View {
    122 //        let raw = peerPullDebitResponse.amountRaw
    123 //        let effective = peerPullDebitResponse.amountEffective
    124 //        let scope = peerPullDebitResponse.scopeInfo
    125         let fee = try! Amount.diff(raw, effective)
    126         ThreeAmountsSection(stack: stack.push(),
    127                             scope: scope,
    128                          topTitle: String(localized: "Amount to pay:"),
    129                         topAbbrev: String(localized: "Pay:", comment: "mini"),
    130                         topAmount: raw,
    131                            noFees: nil,        // TODO: check baseURL for fees
    132                               fee: fee,
    133                       bottomTitle: String(localized: "Amount to be spent:"),
    134                      bottomAbbrev: String(localized: "Effective:", comment: "mini"),
    135                      bottomAmount: effective,
    136                             large: false,
    137                     pendingDialog: false,
    138                            isDone: isDone,
    139                          incoming: false,
    140                           baseURL: nil,
    141                        txStateLcl: nil,
    142                           summary: summary,
    143                          products: nil)
    144     }
    145 }