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 }