ChoicesView.swift (3462B)
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 struct ChoicesView: View, Sendable { 12 let stack: CallStack 13 let choiceTriple: [ChoiceTriple] 14 let showHeader: Bool 15 let automaticIndex: Int? 16 @Binding var selectedChoice: Int? 17 18 @ViewBuilder 19 func selectedBackground(_ useColor: Bool) -> some View { 20 let is26: Bool = if #available(iOS 26.0, *) { true } else { false } 21 let color: Color = useColor ? WalletColors().primaryAccent 22 : .secondary 23 if #available(iOS 17.0, *) { 24 RoundedRectangle(cornerRadius: is26 ? 26 : 10) 25 .fill(.background) 26 .strokeBorder(color, lineWidth: 2.4) 27 } else { 28 RoundedRectangle(cornerRadius: 10) 29 .strokeBorder(color, lineWidth: 2.4) 30 .foregroundColor(Color.clear) 31 } 32 } 33 34 var body: some View { 35 ForEach(choiceTriple, id: \.1) { choice in 36 let selectionDetail: ChoiceSelectionDetail = choice.0 37 let contractChoice: ContractChoice = choice.1 38 let index: Int = choice.2 39 let isPaymentPossible = selectionDetail.status == .paymentPossible 40 let payAutomatic = automaticIndex == index 41 let scopeInfo = selectionDetail.scopeInfo 42 let amount = selectionDetail.amountRaw 43 /// 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. 44 /// 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. 45 /// Tokens only, paymentPossible. If automaticIndex, then also hide it (and auto-pay it). Otherwise show it, so the user can select it. 46 if (!amount.isZero || isPaymentPossible) && !payAutomatic { 47 Section { 48 let amountV = HStack { 49 Spacer() 50 AmountV(stack: stack.push(), 51 scope: scopeInfo, 52 amount: contractChoice.amount) 53 .foregroundColor(isPaymentPossible ? .primary : .secondary ) 54 } .overlay { 55 Color.primary.opacity(INVISIBLE) // Color.clear doesn't accept taps! 56 .contentShape(.rect) 57 .onTapGesture { 58 if isPaymentPossible { 59 selectedChoice = index 60 } 61 } 62 } 63 if index == selectedChoice { 64 amountV.listRowBackground ( 65 selectedBackground(isPaymentPossible) 66 // .padding(.top, n == 1 ? 0 : -15) 67 // .padding(.bottom, n == 10 ? 0 : -15) 68 ) 69 } else { 70 amountV 71 } 72 } header: { 73 if showHeader { 74 if let description = contractChoice.descI18n { 75 Text(description) 76 } } } 77 } 78 } 79 } 80 }