Skip to content

feat(ui): redesign showcase — chat v2, rows v2, SF type, Central icons, trays, swipe-to-send, group profile (draft) - #1159

Draft
aidenjwalker wants to merge 43 commits into
code-payments:mainfrom
aidenjwalker:feat/ui-redesign-showcase
Draft

aidenjwalker wants to merge 43 commits into
code-payments:mainfrom
aidenjwalker:feat/ui-redesign-showcase

Conversation

@aidenjwalker

@aidenjwalker aidenjwalker commented Oct 29, 2026 •

Copy link
Copy Markdown

Draft, not for merging. This is a showcase of the whole redesign so the team can see it in one place, caught up with today's main. I'd love your input on:

  1. How to split it into mergeable PRs. My guess: rows v2 → chat v2 + trays → swipe-to-send → group profile, with type, icons and the background as their own small system PRs. What order and size work for you?
  2. The #121212 background (system-wide, below).
  3. Dynamic Type with SF: the type swap regressed live text scaling (see Known gaps), and fixing it properly is a type-roles decision.

Warning

System-wide change: the app background is now #121212 (was the background asset, #19191A). backgroundMain carries it to 197 references in 148 files, plus the colour asset, the launch screen, the notification extension and the tip-card export. backgroundSecondary (#252526) hasn't been re-stepped from it yet. The Figma token still says #000000.

What's here, screen by screen

Chat (v2)

  • Bubbles: radius 20 (one line is a pill), 17pt regular on a 22pt line, sent bubbles in accent blue with vivid text, received in a neutral grey.
  • Money cards: neutral card, radius 22, token badge and name header. Group payment cards use your group layout (token chip under the amount, "each", recipients), restyled. Your new payment-request card uses the same neutral money-card style.
  • Reactions: 32pt pills, mention capsules. Date separators: day and time set apart.
  • Message lift: backdrop and dim retuned.
  • Composer and media: Central icons throughout, including your new photo-viewer chrome (React, Reply, Save, Forward).
  • Jump-to-bottom: rides the bar, 24pt above it (twice the field gap).

Rows v2 and lists

  • New shared ListRow (60pt minimum height, 20pt margins, 30pt leading slot, a hairline that starts at the text).
  • Settings and the currency picker draw through it.
  • Chat list row: 52pt avatar, two-line preview, short weekday dates, the unread dot (no count pill), a large "Chat" title drawn as content on iOS 26.

Type and icons

  • App face moves from Avenir to SF in FontBook, plus system nav titles.
  • About 110 Central icons (Icon, Image.icon) replace SF Symbols and the old asset set across the tab bar, wallet, currency info, settings, composer, camera and back arrow.

Trays

  • A new tray system: an invisible system sheet gives drag and dim, and the card is drawn in SwiftUI with its own springs.
  • Every DialogItem now shows as a tray through the existing .dialog(item:) seam (48 call sites, no call-site changes).
  • Mute, the E2EE explainer and the encryption info are trays too.
  • There's an amount-entry tray and a red-fade error style.

Swipe-to-send (Lens)

  • The rebuilt SwipeControl: a capsule track, and a Liquid Glass thumb over a Metal lens shader. iOS 18 gets a material thumb.
  • On amount entry it sits in the Next button's slot, dims the screen with travel, and locks the keypad while off rest.
  • Commit thresholds are unchanged (70%, or 50% with a fling) and now pinned by tests.

Public group profile

  • The page is coloured from its cover by the Bleed colour engine (FlipcashUI Theme/Bleed).
  • Requirement and "chatting recently" cards. Requirement amounts restate in the display currency through your GroupBalanceRequirements.formatted(…in:).
  • Tapping the face pile opens your GroupChattingGrid in a tray and then pushes the profile as before.
  • Leave Chat as a calm capsule, the Central back arrow.
  • Private groups and user profiles are unchanged in code.

Caught up with main

I merged upstream/main (86 commits, protocol 0.23.0) instead of rebasing. On every conflict your behaviour, data, navigation and money handling won, and the redesign supplied the look. The redesign doesn't use any contract type the 0.23.0 bump changed.

Your screens the redesign never touched are not restyled yet and still look v1:

  • Chats Search
  • Payment Requests
  • Invite Links (Manage Invites, Invite People, invite preview)
  • Group Card
  • Group and Currency Send
  • Paid Reactions and Reactors
  • Alert Pill
  • Community Chats and the Currency More sheet
  • New Public Group
  • Add Money / Phantom
  • Join Requests
  • Notification transcript bubbles

Anything built on restyled tokens or components picks up the new look partly.

Behaviour changes for you to confirm

  • Mute tray: select a duration, then Mute applies it. main mutes on tap. Aiden prefers the two-step.
  • Amount entry: the keypad locks while the swipe thumb is off rest, so the amount can't change mid-send.
  • Dialogs as trays: UI tests that find dialogs by title, error analytics, dismiss-before-action and non-dismissable dialogs all need your eye.
  • Swipe failure look: it only plays if the send view models return a distinct result when the payment call itself fails. Today production sends reset silently.

Known gaps

  • Dynamic Type: SF tokens don't follow the text-size setting live the way Avenir's .custom(_:size:) did. Fixing it touches about 550 call sites or needs type roles.
  • Trays: the invisible-sheet approach is tuned for iOS 26.1+. The iOS 18 fallback has had light testing only.
  • Light mode: dark only; light values exist only as Figma proposals.
  • Not yet in the redesign's style:
    • Invite People is still a plain sheet next to trays.
    • Notification bubbles still read v1 values.
    • The amount screen has its own private 54pt capsule style.
  • UI tests: FlipcashUITests wasn't run.

Mid-flight

  • Private group and user profiles (Direction D) exist only in Figma.
  • Chat v2 pass 2: the mentions pill, lift backdrop and typing indicator.
  • Tray phase 3: partial sheets and multi-step flows.
  • 27 open taste calls on Aiden's list from the design critique: bubble runs, transcript greys, 17pt tokens, red dialog buttons, press feel, the large title, digit widths, backgroundSecondary, and how far the profile cover melts (shortened from 214pt to about 94pt so the group name stays readable over light covers). The values in the build are the current defaults.
Open questions for you, by area

Group profile pages

  • Currencies a user holds aren't in the profile data. Is a field planned, and would it be public?
  • Can we map the linked X profile into the app's profile model (verified handle, link flow)?
  • Public groups: can we show the member count and "Held by N people"? What does the server's holder minimum mean?
  • Met/unmet requirement status needs the gate's verdict on the profile (see parked items).
  • Should the public profile ever say "Join" instead of "Open Chat"?
  • Created date isn't in the data. Wanted?
  • There's no loading or error state from the fetch. Is a design-only skeleton OK? (A neutral page now shows while loading.)
  • Your own handle opens the tip card, not your profile. Is "the You tab becomes your profile" in scope?
  • Content scrolls only about 180pt, so the collapsing title never appears. Add content, or change the inset?
  • Joining and chatting collapse into one tile when they're equal (same currency and amount). Is that comparison right?
  • "N chatting this week" counts a server sample of at most 100 over a 7-day window computed on device. Are those semantics OK?
  • The group bio isn't stored locally, so it arrives late after a cold start. Store it, or accept the late arrival (it animates in)?

Trays

  • The dialog seam: is "a tray is a local presentation, never a router destination" the rule?
  • An optional icon field on DialogItem?
  • Wiring the amount tray into Send, Buy and Withdraw.
  • The shared keypad gained a rest-fill setting for trays. Is that OK?
  • CADisableMinimumFrameDurationOnPhone is unset, which may cap custom animation at 60 Hz.

Chat v2

  • Is it OK to add chat-only colour tokens for Apple's greys?
  • When does code follow the system light/dark setting?
  • Close buttons still draw the SF xmark in places; the large title uses Bold outside the font map.

Rows v2

  • Which rows should move onto ListRow? The visible changes: settings icon slot 45 → 30, currency coin 24 → 30, region flag 30 → 28 with a check instead of a disc.
  • The currency discovery rank number isn't modelled in the row.
  • There's no row footer in code yet.
  • Trailing value text is 16 semibold in code vs 17 regular in Figma.

Swipe-to-send

  • The Lens look adds a Metal shader to FlipcashUI. Is that OK?
  • Please confirm the swipe's slot, dim and keypad lock don't change what a send triggers or when.
  • The parked "token slides to the recipient" idea needs recipient data passed into the control.

Parked dev items

  • Met/unmet requirement status: two designs exist (a status line or a holdings meter; met / short / split / checking). Short is "$N more" in warning yellow, never red. The verdict and shortfall must come from the existing chat gate, never compared in the view. Until then the footer shows "Your Balance".
  • Shared capsule button style: CodeButton (60pt, radius 6) is deprecated. Trays, the amount screen and the profile each use a 54pt capsule. We need one shared style and a decision on screen-level button height.
  • Bleed derived palette: the colour is derived on device, so no backend change is needed. Still open: seeding the first paint from the blurhash, and a Bleed row in the design standard.
  • Social links need backend: the data has X only (at most one linked profile). Instagram and TikTok need backend fields and link flows.
  • Poster photo resolution: is the uploaded profile photo big enough for a full-screen user poster? What's the fallback without one?

Decided by Aiden

  • Group payment cards: your layout, restyled.
  • Chat list: the dot, not a count.
  • Currency Info tiles: 28pt icons, Buy as arrow-down.
  • Payment-request card: neutral.
  • The face pile opens the full chatter list.
  • Mute: select then confirm.
  • Keypad: locks during a swipe.
  • Jump button: rides the bar.
  • Read-receipt fade: 0.065s, so it clears before the next bubble arrives over the 4pt run gap.

How to see it

  • Build the branch (Debug).
  • Beta Features has Tray Showcase and Swipe Showcase. The launch arguments --motion-sandbox and --swipe-sandbox open sandboxes that need no sign-in.
  • The public group profile opens from any public group's chat header.

Checks

  • Scripts/build.sh passes unsigned; there are no new warnings on the lines this branch changed.
  • FlipcashCoreTests: 1,583 tests pass.
  • FlipcashTests: all 3,323 tests pass. The chat bubble, quote, media, run-gap and tab-badge tests now read the redesign's values from ChatStyle and its metrics.
  • FlipcashUITests not run.
  • Running on a Dev iPhone (Debug).
  • Reviewed against the design standard. Blocking and should-fix findings are folded in; taste calls are listed above.

… a failure look

Same gesture, thresholds, nudge and commit order as before; the commit rule moves
into SwipeControl.shouldCommit unchanged.
Callers' throws reset silently as before. One press feedback (interactive glass off by
default), 0.4 s snap-back, Reduce Motion crossfades, shared glass helper, token colours.
… the label shimmer

The swipe gets its own 64 pt height; trays keep 54.
Same side and bottom insets as the amount-entry button; layout only.
…unt screen with swipe travel

Progress reaches EnterAmountView through SwipeControlProgressKey; visual only.
Final values as constants, tuner removed from the control; glass thumb and fill looks
removed; release haptic only on a non-committing release.
Derives a deep page colour and a text palette from an image, dark only, with the Recipes prototype's tuned defaults baked in.
The public branch of ChatProfileScreen draws the cover melting into its own colour, an identity block with outline Share/Edit pills, requirement tiles, a chatting-recently pulse card and a capsule Open Chat. The private branch is unchanged.
Every LOCAL-TUNER value is baked to its default in the call site's original
form; tuner wiring, floating panels and the profile playground entry are gone.
FlipcashUI is back on the iOS 18 floor with no TunerKit dependency.
Catches the redesign up with 86 upstream commits (protocol 0.23.0, invite
links, payment requests, group send, paid reactions, chats search, display
currency). Conflicts keep upstream's behaviour, data, navigation and money
handling with the redesign's look. Group payment cards use upstream's layout
in the redesign's style; the payment-request card is a neutral money card;
public profile requirement tiles now restate amounts in the display currency.
Jump-to-bottom rides the bar; the profile's chatter pile opens the full
chatter list; accessibility labels, hit areas, Dynamic Type wrapping,
iOS 18 fallbacks, tray button stacking and the SE amount inset.
…receipt exit fade

Chat bubble, quote, media, run-gap and tab-badge tests read the redesign's
values from ChatStyle and its metrics. The 4pt run gap brings the next
bubble over the receipt line sooner, so its exit fade drops to 0.065 s.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant