taler-ios

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

ChoicesView.swift (3927B)


      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 showHeader: Bool
     17     let automaticIndex: Int?
     18     @Binding var selectedChoice: Int
     19 
     20     @ViewBuilder
     21     func selectedBackground(_ useColor: Bool) -> some View {
     22         let is26: Bool = if #available(iOS 26.0, *) { true } else { false }
     23         let color: Color = useColor ? WalletColors().talerColor
     24                                     : .secondary
     25         if #available(iOS 17.0, *) {
     26             RoundedRectangle(cornerRadius: is26 ? 26 : 10)
     27                 .fill(.background)
     28                 .strokeBorder(color, lineWidth: 2.4)
     29         } else {
     30             RoundedRectangle(cornerRadius: 10)
     31                 .strokeBorder(color, lineWidth: 2.4)
     32                 .foregroundColor(Color.clear)
     33         }
     34     }
     35     func description(_ contractChoice: ContractChoice) -> String? {
     36         if let i18nDict = contractChoice.descriptionI18n {
     37             if !i18nDict.isEmpty {
     38                 for code in Locale.preferredLanguageCodes {
     39                     if let descI18n = i18nDict[code] {
     40                         return descI18n
     41                     }
     42                 }
     43             }
     44         }
     45         if let desc = contractChoice.description {
     46             return desc
     47         }
     48         return nil
     49     }
     50 
     51     var body: some View {
     52         ForEach(choiceTriple, id: \.1) { choice in
     53             let selectionDetail: ChoiceSelectionDetail = choice.0
     54             let contractChoice: ContractChoice = choice.1
     55             let index: Int = choice.2
     56             let isPaymentPossible = selectionDetail.status == .paymentPossible
     57             let payAutomatic = automaticIndex == index
     58             let scopeInfo = selectionDetail.scopeInfo
     59             let amount = selectionDetail.amountRaw
     60             /// 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.
     61             /// 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.
     62             /// Tokens only, paymentPossible. If automaticIndex, then also hide it (and auto-pay it). Otherwise show it, so the user can select it.
     63             if (!amount.isZero || isPaymentPossible) && !payAutomatic {
     64                 Section {
     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                 } header: {
     88                     if showHeader {
     89                         if let description = description(contractChoice) {
     90                             Text(description)
     91                 }   }   }
     92             }
     93         }
     94     }
     95 }