taler-ios

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

commit 8a2d0eafc93749974d419c66fa9c999ddd1cd7b1
parent 3270843c61095f5fc6043c30d087956295767bd8
Author: Marc Stibane <marc@taler.net>
Date:   Tue,  8 Jul 2025 23:30:59 +0200

Back to chest

Diffstat:
MTalerWallet1/Views/OIM/OIMView.swift | 22++++++++++++++++------
MTalerWallet1/Views/OIM/OIMcash.swift | 47++++++++++++++++++++++++++++++++++++++++++-----
MTalerWallet1/Views/OIM/OIMcurrencyButton.swift | 2+-
MTalerWallet1/Views/OIM/OIMlayout.swift | 9+++++----
4 files changed, 64 insertions(+), 16 deletions(-)

diff --git a/TalerWallet1/Views/OIM/OIMView.swift b/TalerWallet1/Views/OIM/OIMView.swift @@ -114,6 +114,7 @@ struct OIMView: View { @State private var chestOpen: Int? = nil @State private var showingActions = false // set true after user opened a chest, set false when choosing an action @State private var sending = false // after user tapped on Send or on the money + @State private var closing = false // after user tapped on the open chest func noAction() { } @@ -139,12 +140,21 @@ struct OIMView: View { } func closeAnimated() { - withAnimation(.basic1) { - chestOpen = nil - selectedBalance = nil - selectedIndex = nil - available = nil - showingActions = false + if !closing { + closing = true + let duration = fastAnimations ? 0.6 : 1.1 + let delay = cash.backToChest(duration) + DispatchQueue.main.asyncAfter(deadline: .now() + delay) { + print("closeAnimated", delay) + withAnimation(.basic1) { + chestOpen = nil + selectedBalance = nil + selectedIndex = nil + available = nil + showingActions = false + } + closing = false + } } } diff --git a/TalerWallet1/Views/OIM/OIMcash.swift b/TalerWallet1/Views/OIM/OIMcash.swift @@ -407,7 +407,45 @@ final class OIMcash: ObservableObject, Sendable { } } - func interval(count: UInt64, + func flyToChest(_ index: Int, after delay: TimeInterval) { + let interval = fastAnimations ? 0.2 : 0.4 + DispatchQueue.main.asyncAfter(deadline: .now() + delay) { + var fund = self.funds[index] + withAnimation(.move1) { + fund.state = .curve + self.updateFund(fund) + } + print("backToChest", fund.id, fund.value, delay) + DispatchQueue.main.asyncAfter(deadline: .now() + interval) { + withAnimation(.move1) { + fund.state = .reveal + self.updateFund(fund) + } + DispatchQueue.main.asyncAfter(deadline: .now() + interval) { + withAnimation(.move1) { + do { + self.funds.remove(at: index) + } catch {} + } + } + } + } + } + + func backToChest(_ duration: TimeInterval) -> TimeInterval { + var count = funds.count + var initial: TimeInterval = 0.01 + let interval = interval(count: count, duration: duration, initial: initial) + + while count > 0 { + count -= 1 + flyToChest(count, after: initial) + initial += interval + } + return initial - interval + (fastAnimations ? 0.1 : 0.2) + } + + func interval(count: Int, duration: TimeInterval, initial: TimeInterval = 0 ) -> TimeInterval { @@ -421,17 +459,16 @@ final class OIMcash: ObservableObject, Sendable { _ initial: TimeInterval = 0) { // optimize/rebuild funds let dosh = currency.notesCoins(intVal) - let count = countDosh(dosh.0) + countDosh(dosh.1) + let count = Int(countDosh(dosh.0) + countDosh(dosh.1)) let interval = interval(count: count, duration: duration, initial: initial) - let delay = update1(dosh.0, denominations: currency.bankNotes, state: state, count, interval, initial) - update1(dosh.1, denominations: currency.bankCoins, state: state, count, interval, delay) + let delay = update1(dosh.0, denominations: currency.bankNotes, state: state, interval, initial) + update1(dosh.1, denominations: currency.bankCoins, state: state, interval, delay) } @discardableResult func update1(_ notesCoins: OIMdenominations, denominations: OIMdenominations, state: FundState = .idle, - _ count: UInt64, _ interval: TimeInterval = 0, _ initial: TimeInterval = 0) -> TimeInterval { var array = funds diff --git a/TalerWallet1/Views/OIM/OIMcurrencyButton.swift b/TalerWallet1/Views/OIM/OIMcurrencyButton.swift @@ -164,7 +164,7 @@ struct OIMcurrencyButton: View { flipBack: mutating, disabled: disabled, unavailable: unavailable, - invisible: state.hiding, + invisible: state.hiding || state.chestOpening, pct: pct, action: action)) .accessibilityLabel(Text("\(value)", comment: "VoiceOver")) // TODO: currency name diff --git a/TalerWallet1/Views/OIM/OIMlayout.swift b/TalerWallet1/Views/OIM/OIMlayout.swift @@ -153,11 +153,12 @@ struct OIMlayoutView: View { .oimFundState(fundState) .matchedGeometryEffect(id: fund.targetID, in: wrapper.namespace, isSource: false) .onAppear { - if shouldFly { - startFlying(fundID: fundID) - } else if fundState.chestOpening { + if fundState.chestOpening { startFlying(fundID: fundID, fromChest: true) -// print(" ->OIMlayout ForEach fund.onAppear ignore \(value), \(fundID)") + } else if fundState.shouldFly { + startFlying(fundID: fundID) + } else { +// print(" ->OIMlayout ForEach fund.onAppear ignore \(value), \(fundID)") } } }