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 //}