taler-ios

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

OIMEditView.swift (7137B)


      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 
     11 // MARK: -
     12 // called by SendAmountV
     13 @available(iOS 16.4, *)
     14 struct OIMEditView: View {
     15     let stack: CallStack
     16     let cash: OIMcash
     17     @Binding var amountToTransfer: Amount
     18     let available: Amount
     19     let useAvailable : Bool         // if false then we're requesting money and don't use available
     20 //    let decimal: Int            // 0 for ¥,HUF;   2 for $,€,£;   3 for ﷼,₯ (arabic)
     21     @Binding var fwdButtonTapped: Bool      // user tapped "Send" TODO: "Request"
     22 
     23     @EnvironmentObject private var wrapper: NamespaceWrapper
     24 
     25 //    @State private var amount2: Amount?
     26     @State private var amountVal: UInt64 = 0
     27     @State private var sending = false              // user tapped on Send
     28     @State private var availableVal: UInt64 = 0
     29     @State private var availRest: Amount
     30     @State private var tappedVal: UInt64 = 0
     31 
     32     init(stack: CallStack,
     33                      cash: OIMcash,
     34          amountToTransfer: Binding<Amount>,
     35                 available: Amount,
     36              useAvailable: Bool,
     37           fwdButtonTapped: Binding<Bool>
     38     ) {
     39         self.stack = stack
     40         self.cash = cash
     41         self._amountToTransfer = amountToTransfer
     42         self.available = available
     43         self.useAvailable = useAvailable
     44         self._fwdButtonTapped = fwdButtonTapped
     45         self._availRest = State(wrappedValue: { available }())
     46     }
     47 
     48 
     49     // available minus amountVal - what's still available from the balance when amount is on the table
     50     var isAvailable: UInt64 {
     51         if useAvailable {
     52             let have = available.centValue                                      // TODO: centValue factor
     53             let want = amountToTransfer.centValue                               // TODO: centValue factor
     54             if have > want {
     55                 return have - want
     56             }
     57             return 0
     58         }
     59         return 999_999_999
     60     }
     61 
     62     func sendAction() {
     63 //        DispatchQueue.main.asyncAfter(deadline: .now() + 0.6) {
     64 //          withAnimation(.basic1.delay(delay + 0.5)) {
     65             withAnimation(.basic1) {
     66                 sending = true                // hide scroller
     67             }
     68 //          DispatchQueue.main.asyncAfter(deadline: .now() + delay + 1) {       // cash.delay
     69             DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) {
     70                 var transaction = Transaction()
     71                 transaction.disablesAnimations = true
     72                 withTransaction(transaction) {
     73                     fwdButtonTapped = true          // ==> go to purpose/goal
     74                 }
     75             }
     76 //        }
     77     }
     78 
     79     var body: some View {
     80 //        let _ = Self._printChanges()
     81 //        let _ = print(">>> OIMEditView", available, amount, stack.peek()?.file)
     82 
     83         OIMnavBack(stack: stack.push(),
     84                    chest: cash.currency.chest,
     85                     type: .sendP2P,
     86                  isFinal: false,
     87                isSending: sending,
     88                   action: sendAction,
     89              actDisabled: amountToTransfer.isZero
     90         ) {
     91             ZStack(alignment: .top) {
     92                 VStack {
     93                     OIMtitleView(cash: cash,
     94                                amount: available,
     95                               history: false,
     96                          secondAmount: amountToTransfer)
     97                     Spacer()
     98                     OIMlineView(stack: stack.push(),
     99                                  cash: cash,
    100                             amountVal: $amountVal,
    101                               canEdit: true)
    102                         .matchedGeometryEffect(id: OIMLINE, in: wrapper.namespace, isSource: true)
    103                         .zIndex(1)  // make notes fly from topZ
    104                         .scaleEffect(sending ? 0.6 : 1.0)
    105                         .onChange(of: amountVal) { newVal in
    106 //                            if let amountOld = amount2 {
    107 //                                let currencyStr = amountOld.currencyStr
    108                             let currencyStr = amountToTransfer.currencyStr
    109 //                                amount2 = Amount(currency: currencyStr, cent: UInt64(newVal))
    110                             amountToTransfer = Amount(currency: currencyStr, cent: UInt64(newVal))
    111                                 availableVal = isAvailable
    112                                 availRest = Amount(currency: currencyStr, cent: UInt64(availableVal))
    113 //                            }
    114                         }
    115                         .onChange(of: tappedVal) { newVal in
    116                             if newVal > 0 {
    117 //                                symLog.log(">>tapped \(newVal)")
    118                                 tappedVal = 0
    119 
    120                                 DispatchQueue.main.async {                      // next layout cycle
    121                                     withAnimation(.move1) {
    122 //                                        symLog.log(">>addCash \(newVal)")
    123                                         cash.addCash(value: newVal)
    124                                         amountVal += newVal                     // update directly
    125                                     }
    126                                 }
    127                             }
    128                         }
    129                     if !sending {       // need space for currency scroller
    130                         Spacer()
    131                         Spacer()
    132                     }
    133                 }
    134                 VStack {
    135                     Spacer()
    136                     let availableCent = available.centValue                     // TODO: centValue factor
    137                     let maxAvailable = useAvailable ? cash.max(available: availableCent) : 0
    138                     OIMcurrencyDrawer(stack: stack.push(),
    139                                        cash: cash,
    140                                availableVal: $availableVal,           // ==> available - amount
    141                                   tappedVal: $tappedVal,
    142                              scrollPosition: maxAvailable,            // max note or coin (available)
    143                                     canEdit: true)
    144                         .zIndex(2)  // make notes fly from topZ
    145                         .clipped(antialiased: true)
    146                         .padding(.horizontal, 5)
    147                         .ignoresSafeArea(edges: .horizontal)
    148                         .opacity(sending ? INVISIBLE : 1)
    149                 }
    150 //              .border(.red)
    151             } // ZStack
    152         }
    153         .task {     // re-set cash to amount (once)
    154 //            amount2 = amountToTransfer
    155             amountVal = amountToTransfer.centValue                              // TODO: centValue factor
    156             availableVal = isAvailable
    157 //          print("OIMEditView.task", availableVal, amountVal)
    158             cash.update2(amountVal, state: .idle)
    159         }
    160         .onAppear {
    161 //            print("OIMEditView.onAppear", availableVal, amountVal)
    162             withAnimation(.basic1) {
    163                 sending = false                              // move back up when coming back
    164             }
    165         }
    166     }
    167 }