taler-ios

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

QuiteSomeCoins.swift (4211B)


      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 struct CoinData {
     13     let numCoins: Int       // 0 == invalid, -1 == unknown
     14     var unknown:   Bool { numCoins < 0 }
     15     var invalid:   Bool { numCoins == 0 }
     16     var manyCoins: Bool { numCoins > 99 }
     17     var quiteSome: Bool { numCoins > 199 }
     18     var tooMany:   Bool { numCoins > 999 }
     19 
     20     let fee: Amount?
     21     func feeLabel(_ scope: ScopeInfo?, feeZero: String?, isNegative: Bool = false) -> (String, String) {
     22         if let fee {
     23             let formatted = fee.formatted(scope, isNegative: false)
     24             let feeLabel = fee.isZero ? feeZero ?? EMPTYSTRING    // String(localized: "No withdrawal fee")
     25                          : isNegative ? String(localized: "- \(formatted.0) fee")
     26                                       : String(localized: "+ \(formatted.0) fee")
     27             let feeA11Y = fee.isZero ? feeZero ?? EMPTYSTRING    // String(localized: "No withdrawal fee")
     28                         : isNegative ? String(localized: "- \(formatted.1) fee")
     29                                      : String(localized: "+ \(formatted.1) fee")
     30             return (feeLabel, feeA11Y)
     31        } else {
     32            return (EMPTYSTRING, EMPTYSTRING)
     33        }
     34     }
     35 }
     36 
     37 extension CoinData {
     38     init(coins numCoins: Int?, fee: Amount?) {
     39         self.init(numCoins: numCoins ?? -1, fee: fee)           // either the number of coins, or unknown
     40     }
     41 
     42     init(details: WithdrawalDetailsForAmount?) {
     43         do {
     44             if let details {
     45                 // Incoming: fee = raw - effective
     46                 let aFee = try details.amountRaw - details.amountEffective
     47                 self.init(numCoins: details.numCoins ?? -1,    // either the number of coins, or unknown
     48                                fee: aFee)
     49                 return
     50             }
     51         } catch {}
     52         self.init(numCoins: 0, fee: nil)      // invalid
     53     }
     54 
     55     init(details: CheckPeerPullCreditResponse?) {
     56         do {
     57             if let details {
     58                 // Incoming: fee = raw - effective
     59                 let aFee = try details.amountRaw - details.amountEffective
     60                 self.init(numCoins: details.numCoins ?? -1,    // either the number of coins, or unknown
     61                                fee: aFee)
     62                 return
     63             }
     64         } catch {}
     65         self.init(numCoins: 0, fee: nil)      // invalid
     66     }
     67 }
     68 // MARK: -
     69 struct QuiteSomeCoins: View {
     70     private let symLog = SymLogV(0)
     71     let scope: ScopeInfo?
     72     let coinData: CoinData
     73     let shouldShowFee: Bool
     74     let feeIsNegative: Bool
     75 
     76     var body: some View {
     77         let isError = coinData.tooMany // || coinData.invalid
     78         let showFee = shouldShowFee && !isError
     79         if showFee {    // TODO: does exchange never have fee?
     80             if let fee = coinData.fee {
     81                 let feeLabel = coinData.feeLabel(scope,
     82                                         feeZero: String(localized: "No fee"),
     83                                      isNegative: feeIsNegative)
     84                 Text(feeLabel.0)
     85                     .accessibilityLabel(feeLabel.1)
     86                     .foregroundColor(.primary)
     87                     .talerFont(.body)
     88             }
     89         }
     90         if isError || coinData.quiteSome || coinData.manyCoins {
     91             Text(coinData.tooMany ? "Amount too big for a single withdrawal!"
     92              : coinData.quiteSome ? "Note: It will take quite some time to prepare this amount! Be more patient..."
     93                                   : "Note: It will take some time to prepare this amount. Be patient...")
     94                 .foregroundColor(isError || coinData.quiteSome ? WalletColors().attention : .primary)
     95                 .talerFont(.body)
     96                 .multilineTextAlignment(.leading)
     97                 .padding(.vertical, 6)
     98         }
     99     }
    100 }
    101 // MARK: -
    102 //struct QuiteSomeCoins_Previews: PreviewProvider {
    103 //    static var previews: some View {
    104 //        QuiteSomeCoins(coinData: CoinData(numCoins: 4, fee: Amount(currency: LONGCURRENCY, cent: 20) ),
    105 //                  shouldShowFee: true,
    106 //                amountEffective: nil)
    107 //    }
    108 //}