feat(wallet): expand token cards into the currency info screen - #587
Open
bmc08gt wants to merge 1 commit into
Open
feat(wallet): expand token cards into the currency info screen#587bmc08gt wants to merge 1 commit into
bmc08gt wants to merge 1 commit into
Conversation
Tapping a bill card in the wallet now pulls it out of the deck and into the currency info screen, Apple Wallet style, and closing puts it back where it came from. The deck is driven by a single `expansionProgress` scalar that the card's travel animates in lockstep with: the cards above gather onto the slot it rises to and fade underneath it, the ones below run off the bottom, and the balance header fades with them. The opened card keeps its natural place in the deck's z-order throughout, which is what lets it slide back *under* its neighbours on the way home rather than landing on top of them. Opening does not hand the card between two views. The card that travels is the detail screen's own hero card, displaced down to the deck slot it came from and animated back to zero while the rest of the screen fades in behind it. It therefore belongs to the screen's scroll view from the first frame and scrolls with the content immediately — an overlaid copy handed over on completion left a window where the page was scrollable but the card was not yet part of it, and the content slid out from underneath it. Closing is the mirror: the deck takes the card back before anything moves, so it returns inside the stack with its neighbours drawn over it. Notes on the parts that are less obvious than they look: - The reorganisation has to be a value, not a branch. `visualEffect` interpolates a changing offset, but swapping which formula applies (by toggling the opened mint) resolves in one frame and reads as a snap. - Work that blocks the main thread — hiding the tab bar, which relayouts the whole `TabView`, and building the page — happens in an un-animated step before the animation is committed. SwiftUI's springs are driven on the main thread, so anything deferred until after the commit interrupts the motion instead of running alongside it. The tab bar is restored the same way, at the top of the close, so it does not arrive late. - Both transitions finish their work in callbacks, so each is tagged and every callback checks it is still current — otherwise a close settling in the background tears down the open that interrupted it. The screen itself arrives in one pass. Nothing below the action tiles is gated on loading: the activity read runs off the main thread, and the market cap section builds its view model up front so it holds its full height around a placeholder plot. Only the chart's points, and so the expensive populated Swift Charts draw, wait for the transition to finish. Hosted as an overlay the screen has no navigation bar, so it draws its own chrome and its own top fade — the system's soft scroll edge is rendered by the bar's background, and without it the page scrolled up to meet the status bar at full strength.
bmc08gt
force-pushed
the
feat-wallet-zoom-transition
branch
from
August 17, 2026 03:19
5be8d79 to
9104e78
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Supersedes #586, which GitHub closed rather than retargeted when #585 merged and its base branch was deleted. Same commit, rebased onto
main.Tapping a bill card pulls it out of the deck and into the currency info screen, Apple Wallet style. Closing puts it back in its slot, sliding under the cards stacked on top of it.
How it works
The deck is driven by one
expansionProgressscalar that the card's flight animates in lockstep with — the cards above gather onto the slot it rises to and fade underneath it, the ones below run off the bottom, and the balance header fades with them. The opened card keeps its natural place in the deck's z-order the whole way, which is what makes closing read as reinserting rather than dropping it on top.Things worth knowing before changing it
Most of these were bugs first, and are easy to reintroduce:
visualEffectinterpolates a changing offset, but swapping which formula applies (by toggling the opened mint) resolves in a single frame and reads as a snap.TabView, and building the page runs a synchronous metadata read. Both happen in the un-animated seed step. SwiftUI's springs are driven on the main thread, so work deferred until afterwithAnimationinterrupts the motion rather than running alongside it — measured as worse, not better. The tab bar is restored the same way at the top of the close, or it arrives visibly late.Testing
Driven with Maestro and verified from frame-by-frame analysis of screen recordings rather than by eye: