taler-ios

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

ExchangeRowView.swift (5335B)


      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 ExchangeRowView: View {
     13     private let symLog = SymLogV(0)
     14     let stack: CallStack
     15     let exchange: Exchange
     16     let index: Int
     17 
     18     @Environment(\.sizeCategory) var sizeCategory
     19     @EnvironmentObject private var controller: Controller
     20     @EnvironmentObject private var model: WalletModel
     21     @EnvironmentObject private var tabBarModel: TabBarModel
     22 
     23     var body: some View {
     24 #if PRINT_CHANGES
     25         let _ = Self._printChanges()
     26         let _ = symLog.vlog()       // just to get the # to compare it with .onAppear & onDisappear
     27         let delay: UInt = 0     // set to 5 to test delayed currency information
     28 #else
     29         let delay: UInt = 0
     30 #endif
     31         let baseURL = exchange.exchangeBaseUrl
     32         let chevron = Text(Image(systemName: "chevron.right"))
     33                         .talerFont(.table)
     34                         .foregroundColor(.secondary)
     35 
     36         let termsLine = HStack {
     37             Text("Terms of Service")  // VIEW_WITHDRAW_TOS
     38             Spacer()
     39             chevron
     40         }
     41 
     42         let rowView = VStack(alignment: .leading) {
     43             Text(baseURL.trimURL)
     44                 .talerFont(.headline)
     45             ExchangeStatus(exchange: exchange)
     46             termsLine
     47                 .talerFont(.body)
     48                 .background {           // only needed for .onTapGesture
     49                     Color.gray.opacity(INVISIBLE)
     50                 }
     51                 .onTapGesture {
     52                     tabBarModel.tosView = index
     53                 }
     54         }
     55         let showToS = WithdrawTOSView(stack: stack.push(),
     56                             exchangeBaseUrl: baseURL,
     57                                      viewID: VIEW_WITHDRAW_TOS,
     58                                acceptAction: nil)         // pop back to here
     59         let details = ExchangeDetailView(stack: stack.push(),
     60                                       exchange: exchange)
     61         let actions = Group {
     62             NavLink(index, $tabBarModel.tosView) { showToS }
     63         }
     64 
     65         Group {
     66             rowView
     67                 .background(actions)
     68         }.listRowSeparator(.hidden)
     69     }
     70 }
     71 // MARK: -
     72 struct  ExchangeStatus: View {
     73     let exchange: Exchange
     74 
     75     @EnvironmentObject private var controller: Controller
     76     @AppStorage("minimalistic") var minimalistic: Bool = false
     77 
     78     var body: some View {
     79         let status = controller.isConnected ? exchange.exchangeUpdateStatus.localized
     80                                             : ExchangeUpdateStatus.unavailable.localized
     81         VStack(alignment: .leading) {
     82             HStack {
     83                 if !minimalistic {
     84                     Text("Status:")
     85                 }
     86                 Text(status)
     87             }
     88             if let lastUpdateErrorInfo = exchange.lastUpdateErrorInfo {
     89                 Text("Last Error: \(lastUpdateErrorInfo.error.code)")
     90                 if let hint = lastUpdateErrorInfo.error.hint {
     91                     Text(hint)                                                  // TODO: L10N
     92                 }
     93                 if let detail = lastUpdateErrorInfo.error.detail {
     94                     Text(detail)                                                // TODO: L10N
     95                 }
     96             }
     97         }
     98         .padding(.bottom, 4)
     99         .talerFont(.body)
    100     }
    101 }
    102 // MARK: -
    103 #if DEBUG
    104 fileprivate struct ExchangeRow_Previews: PreviewProvider {
    105     @MainActor
    106     struct BindingViewContainer : View {
    107         @State private var amountToPreview = Amount(currency: LONGCURRENCY, cent: 1234)
    108         @State private var depositIBAN = "DE1234567890"
    109         @State private var accountHolder = "Marc Stibane"
    110 //        @State private var previewL: CurrencyInfo = CurrencyInfo.zero(LONGCURRENCY)
    111 
    112 //    let amount = Amount(currency: LONGCURRENCY, cent: 123456)
    113         var body: some View {
    114             let scopeInfo = ScopeInfo(type: .exchange, currency: LONGCURRENCY)
    115             let exchange1 = Exchange(exchangeBaseUrl: ARS_AGE_EXCHANGE,
    116                                            masterPub: "masterPub",
    117                                            scopeInfo: scopeInfo,
    118                                            paytoUris: [],
    119                                            tosStatus: .pending,
    120                                  exchangeEntryStatus: .preset,
    121                                 exchangeUpdateStatus: .initial,
    122                                ageRestrictionOptions: [12,16])
    123             let exchange2 = Exchange(exchangeBaseUrl: ARS_EXP_EXCHANGE,
    124                                            masterPub: "masterPub",
    125                                            scopeInfo: scopeInfo,
    126                                            paytoUris: [],
    127                                            tosStatus: .proposed,
    128                                  exchangeEntryStatus: .ephemeral,
    129                                 exchangeUpdateStatus: .ready,
    130                                ageRestrictionOptions: [])
    131             ExchangeRowView(stack: CallStack("Preview"),
    132                          exchange: exchange1,
    133                             index: 1)
    134         }
    135     }
    136 
    137     @MainActor
    138     static var previews: some View {
    139         List {
    140             BindingViewContainer()
    141         }
    142     }
    143 }
    144 #endif