commit 131b14e6a66deb66662e5b8583a176b9d0475112
parent 3384b0f0db6e5b69f9ba4cfe8762d8daa1430e64
Author: Marc Stibane <marc@taler.net>
Date: Mon, 28 Apr 2025 06:54:19 +0200
selectedIndex (savings box selection)
Diffstat:
5 files changed, 104 insertions(+), 12 deletions(-)
diff --git a/TalerWallet1/Views/Actions/Peer2peer/RequestPayment.swift b/TalerWallet1/Views/Actions/Peer2peer/RequestPayment.swift
@@ -20,13 +20,32 @@ struct RequestPayment: View {
@EnvironmentObject private var controller: Controller
#if OIM
- @StateObject private var cash = OIMcash()
+ @StateObject private var cash: OIMcash
#endif
@State private var balanceIndex = 0
@State private var balance: Balance? = nil // nil only when balances == []
@State private var currencyInfo: CurrencyInfo = CurrencyInfo.zero(UNKNOWN)
@State private var amountToTransfer = Amount.zero(currency: EMPTYSTRING) // Update currency when used
+ init(stack: CallStack,
+ selectedBalance: Balance?,
+ selectedIndex: Int?,
+ amountLastUsed: Binding<Amount>,
+ summary: Binding<String>
+ ) {
+ // SwiftUI ensures that the initialization uses the
+ // closure only once during the lifetime of the view, so
+ // later changes to the currency have no effect.
+ self.stack = stack
+ self.selectedBalance = selectedBalance
+ self._amountLastUsed = amountLastUsed
+ self._summary = summary
+#if OIM
+ let currency = selectedIndex == 1 ? OIMleones : OIMeuros
+ self._cash = StateObject(wrappedValue: { OIMcash(currency) }())
+#endif
+ }
+
@MainActor
private func viewDidLoad() async {
if let selectedBalance {
diff --git a/TalerWallet1/Views/Actions/Peer2peer/SendAmountV.swift b/TalerWallet1/Views/Actions/Peer2peer/SendAmountV.swift
@@ -21,7 +21,7 @@ struct SendAmountV: View {
@EnvironmentObject private var model: WalletModel
#if OIM
- @StateObject private var cash = OIMcash()
+ @StateObject private var cash: OIMcash
#endif
@State private var balanceIndex = 0
@State private var balance: Balance? = nil // nil only when balances == []
@@ -31,6 +31,25 @@ struct SendAmountV: View {
@State private var buttonSelected = false
@Namespace var namespace
+ init(stack: CallStack,
+ selectedBalance: Balance?,
+ selectedIndex: Int?,
+ amountLastUsed: Binding<Amount>,
+ summary: Binding<String>
+ ) {
+ // SwiftUI ensures that the initialization uses the
+ // closure only once during the lifetime of the view, so
+ // later changes to the currency have no effect.
+ self.stack = stack
+ self.selectedBalance = selectedBalance
+ self._amountLastUsed = amountLastUsed
+ self._summary = summary
+#if OIM
+ let currency = selectedIndex == 1 ? OIMleones : OIMeuros
+ self._cash = StateObject(wrappedValue: { OIMcash(currency) }())
+#endif
+ }
+
@MainActor
private func viewDidLoad() async {
let balances = controller.balances
@@ -159,6 +178,7 @@ fileprivate struct Preview_Content: View {
flags: [])
SendAmountV(stack: CallStack("Preview"),
selectedBalance: noBalance,
+ selectedIndex: nil,
amountLastUsed: $amountToPreview,
summary: $summary)
}
diff --git a/TalerWallet1/Views/Balances/BalancesListView.swift b/TalerWallet1/Views/Balances/BalancesListView.swift
@@ -15,6 +15,7 @@ struct BalancesListView: View {
private let symLog = SymLogV(0)
let stack: CallStack
@Binding var selectedBalance: Balance? // pass down to TransactionsListView
+ @Binding var selectedIndex: Int?
@Binding var reloadTransactions: Int
@Binding var qrButtonTapped: Bool
@@ -75,6 +76,7 @@ struct BalancesListView: View {
if controller.oimModeActive {
OIMView(stack: stack.push(),
selectedBalance: $selectedBalance, // set to user choice
+ selectedIndex: $selectedIndex,
qrButtonTapped: $qrButtonTapped)
.environmentObject(NamespaceWrapper(namespace)) // keep OIMviews apart
}
diff --git a/TalerWallet1/Views/Main/MainView.swift b/TalerWallet1/Views/Main/MainView.swift
@@ -32,6 +32,7 @@ struct MainView: View {
@StateObject var tabBarModel = TabBarModel()
@State private var selectedBalance: Balance? = nil // gets set in TransactionsListView
+ @State private var selectedIndex: Int? = nil // user selects savings box in OIMview
@State private var urlToOpen: URL? = nil
@State private var showUrlSheet = false
@State private var showActionSheet = false
@@ -62,6 +63,7 @@ struct MainView: View {
let mainContent = ZStack {
MainContent(logger: logger, stack: stack.push("Content"),
selectedBalance: $selectedBalance,
+ selectedIndex: $selectedIndex, // user selects savings box in OIMview
talerFontIndex: $talerFontIndex,
showActionSheet: $showActionSheet,
showScanner: $showScanner,
@@ -244,6 +246,7 @@ extension MainView {
let logger: Logger
let stack: CallStack
@Binding var selectedBalance: Balance?
+ @Binding var selectedIndex: Int? // user selects savings box in OIMview
@Binding var talerFontIndex: Int
@Binding var showActionSheet: Bool
@Binding var showScanner: Bool
@@ -327,10 +330,12 @@ extension MainView {
/// Destinations for the 4 actions
let sendDest = SendAmountV(stack: stack.push(Self.name),
selectedBalance: selectedBalance, // if nil shows currency picker
+ selectedIndex: selectedIndex, // selected savings box from OIMview
amountLastUsed: $amountLastUsed, // currency needs to be updated!
summary: $summary)
let requestDest = RequestPayment(stack: stack.push(Self.name),
selectedBalance: selectedBalance,
+ selectedIndex: selectedIndex, // selected savings box from OIMview
amountLastUsed: $amountLastUsed, // currency needs to be updated!
summary: $summary)
let depositDest = DepositSelectV(stack: stack.push(Self.name),
@@ -369,6 +374,7 @@ extension MainView {
let balancesStack = NavigationView {
BalancesListView(stack: stack.push(balancesTitle),
selectedBalance: $selectedBalance, // <= gets set in TransactionsListView
+ selectedIndex: $selectedIndex, // user selects savings box in OIMview
// shouldReloadPending: $shouldReloadPending,
reloadTransactions: $shouldReloadTransactions,
qrButtonTapped: $qrButtonTapped)
diff --git a/TalerWallet1/Views/OIM/OIMView.swift b/TalerWallet1/Views/OIM/OIMView.swift
@@ -66,8 +66,10 @@ struct OIMView: View {
let stack: CallStack
// let decimal: Int // 0 for ¥,HUF; 2 for $,€,£; 3 for ﷼,₯ (arabic)
@Binding var selectedBalance: Balance? // return user's choice
+ @Binding var selectedIndex: Int?
@Binding var qrButtonTapped: Bool
+ @EnvironmentObject private var controller: Controller
@EnvironmentObject private var wrapper: NamespaceWrapper
@StateObject private var cash = OIMcash()
@@ -75,6 +77,7 @@ struct OIMView: View {
@State private var tappedVal: UInt64 = 0
@State private var sending = false
@State private var available: Amount? = nil
+ @State private var isOpen: Int? = nil
func sendAction() {
let delay = cash.moveDown()
@@ -127,16 +130,41 @@ struct OIMView: View {
actions
VStack {
Spacer()
- OIMcurrencyScroller(stack: stack.push(),
- cash: cash,
- availableVal: $availableVal,
- tappedVal: $tappedVal,
- canEdit: false)
- .zIndex(1) // make notes fly from topZ
- .clipped(antialiased: true)
- .padding(.horizontal, 5)
- .ignoresSafeArea(edges: .horizontal)
- .opacity(sending ? 1.0 : 0.01)
+ HStack(spacing: 30) {
+// ForEach(controller.balances, id: \.self) { balance in
+// OIMbalanceButton(isOpen: selectedBalance == balance) {
+
+ let balance = controller.balances[0]
+ ForEach(0...1, id: \.self) { index in
+ let itsMe = isOpen == index
+ let isClosed = isOpen == nil
+ let size = isClosed ? 120.0 : 66.0
+ OIMbalanceButton(isOpen: itsMe, tint: index > 0) {
+ withAnimation(.basic1) {
+ if itsMe {
+ isOpen = nil
+ selectedBalance = nil
+ selectedIndex = nil
+ available = nil
+ } else {
+ isOpen = index
+ selectedIndex = index
+ cash.currency = index == 0 ? OIMeuros : OIMleones
+ selectedBalance = balance
+ available = balance.available
+ }
+ }
+ }
+ .frame(width: size, height: size)
+ .zIndex(itsMe ? 3 : 0)
+ .opacity((isClosed || itsMe) ? 1.0 : 0.01)
+ .matchedGeometryEffect(id: itsMe ? (sending ? "OIMback" : "OIMnumber")
+ : String(index),
+ in: wrapper.namespace,isSource: false)
+ .frame(width: size, height: size)
+ }
+ }
+ Spacer()
}
VStack {
Spacer()
@@ -152,6 +180,23 @@ struct OIMView: View {
#if DEBUG
// .border(.red)
#endif
+ VStack {
+ Spacer()
+ OIMcurrencyScroller(stack: stack.push(),
+ cash: cash,
+ availableVal: $availableVal,
+ tappedVal: $tappedVal,
+ canEdit: false)
+ .clipped(antialiased: true)
+ .padding(.horizontal, 5)
+ .ignoresSafeArea(edges: .horizontal)
+ .scrollDisabled(true)
+#if DEBUG
+ .opacity(sending ? 1.0 : 0.3)
+#else
+ .opacity(sending ? 1.0 : 0.01)
+#endif
+ }
}
}
.task {