taler-ios

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

ChoicesView.swift (3868B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-26 Taler Systems S.A.
      3  * See LICENSE.md
      4  */
      5 /**
      6  * @author Marc Stibane
      7  */
      8 import SwiftUI
      9 import taler_swift
     10 
     11 typealias ChoiceTriple = (ChoiceSelectionDetail, ContractChoice, Int)
     12 
     13 struct ChoicesView: View, Sendable {
     14     let stack: CallStack
     15     let choiceTriple: [ChoiceTriple]
     16     let automaticIndex: Int?
     17     @Binding var selectedChoice: Int
     18 
     19     @ViewBuilder
     20     func selectedBackground(_ useColor: Bool) -> some View {
     21         let is26: Bool = if #available(iOS 26.0, *) { true } else { false }
     22         let color: Color = useColor ? WalletColors().talerColor
     23                                     : .secondary
     24         if #available(iOS 17.0, *) {
     25             RoundedRectangle(cornerRadius: is26 ? 26 : 10)
     26                 .fill(.background)
     27                 .strokeBorder(color, lineWidth: 2.4)
     28         } else {
     29             RoundedRectangle(cornerRadius: 10)
     30                 .strokeBorder(color, lineWidth: 2.4)
     31                 .foregroundColor(Color.clear)
     32         }
     33     }
     34     func description(_ contractChoice: ContractChoice) -> String {
     35         if let i18nDict = contractChoice.descriptionI18n {
     36             if !i18nDict.isEmpty {
     37                 for code in Locale.preferredLanguageCodes {
     38                     if let descI18n = i18nDict[code] {
     39                         return descI18n
     40                     }
     41                 }
     42             }
     43         }
     44         if let desc = contractChoice.description {
     45             return desc
     46         }
     47         return String(localized: "No description", comment: "contractChoice.description")
     48     }
     49 
     50     var body: some View {
     51         ForEach(choiceTriple, id: \.1) { choice in
     52             let selectionDetail: ChoiceSelectionDetail = choice.0
     53             let contractChoice: ContractChoice = choice.1
     54             let index: Int = choice.2
     55             let isPaymentPossible = selectionDetail.status == .paymentPossible
     56             let payAutomatic = automaticIndex == index
     57             let scopeInfo = selectionDetail.scopeInfo
     58             let amount = selectionDetail.amountRaw
     59             /// If it contains money, always show it. Disable but don’t hide it if insufficient - that serves as advertisement what you could buy if you had more money / tokens.
     60             /// If it only contains tokens, and insufficient, then hide it. Most probably there is a money payment option to acquire those tokens, which is advertisement enough.
     61             /// Tokens only, paymentPossible. If automaticIndex, then also hide it (and auto-pay it). Otherwise show it, so the user can select it.
     62             if (!amount.isZero || isPaymentPossible) && !payAutomatic {
     63                 let description = description(contractChoice)
     64                 Section(header: Text(description)) {
     65                     let amountV = HStack {
     66                         Spacer()
     67                         AmountV(stack: stack.push(),
     68                                 scope: scopeInfo,
     69                                amount: contractChoice.amount)
     70                             .foregroundColor(isPaymentPossible ? .primary : .secondary  )
     71                     } .overlay {
     72                         Color.primary.opacity(0.001)        // Color.clear doesn't accept taps!
     73                             .contentShape(.rect)
     74                             .onTapGesture {
     75                                 selectedChoice = index
     76                             }
     77                     }
     78                     if index == selectedChoice {
     79                         amountV.listRowBackground (
     80                             selectedBackground(isPaymentPossible)
     81 //                          .padding(.top, n == 1 ? 0 : -15)
     82 //                          .padding(.bottom, n == 10 ? 0 : -15)
     83                         )
     84                     } else {
     85                         amountV
     86                     }
     87                 }
     88             }
     89         }
     90     }
     91 }