Skip to content

feat(you): rebuild the You tab around the tip card - #1291

Merged
bmc08gt merged 9 commits into
code/cashfrom
feat/you-tab-redesign
Aug 21, 2026
Merged

feat(you): rebuild the You tab around the tip card#1291
bmc08gt merged 9 commits into
code/cashfrom
feat/you-tab-redesign

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 20, 2026

Copy link
Copy Markdown
Collaborator

Implements the "Tip Card You Page" design (node 9216:656).

You tab

The You tab — the Menu feature under the v2 tab bar — drops its app bar and money tiles and leads with the viewer's own tip card.

  • The card renders opaque at the design's flattened fill (rgb(16,16,17)) rather than the translucent frosted fill, since nothing is behind it here.
  • A link row shows the abbreviated tip link and copies the full URL to the clipboard. The trailing icon flips to a filled checkmark for 1.5s and fades back, matching iOS.
  • Share and Download tiles sit below. Download opens a "Download As" sheet offering PNG or SVG, renders the chosen format via TipCodeExporter, and hands the file to the Sharesheet — Android has no permissionless save-to-Photos, and the chooser already surfaces Files/Drive/Photos.
  • TipCardMaxWidth is raised from 270dp to 305dp so a phone-width canvas gets the full 0.82 width fraction the design specifies (302 on a 402 frame). This also enlarges scanned tip cards slightly.

Full Screen is an in-place expansion

Tapping the card or "Full Screen" no longer navigates anywhere — it expands the card that's already on screen, matching iOS.

  • The card keeps its slot in the LazyColumn; an inner layer translates it to the display centre while the slot grows to the 302dp expanded width (node 9277:121410). Effectively a shared-element morph without a shared-element API, mirroring iOS's clear-slot + offset approach.
  • Everything else on the page fades and slides down 60dp under it; the tab bar hides through a new counted TabBarVisibilityController so overlapping callers can't uncover it.
  • Close (bottom of screen) and system back collapse it.
  • The spring is iOS's .spring(response: 0.45, dampingFraction: 0.85) converted to Compose: dampingRatio = 0.85f, stiffness = 195f.

This replaces TipCardScreen (and its content/view model) and the session-presented own-tip-card path, both of which are removed.

MenuList gained an itemModifier that wraps each row together with its sibling divider — ListItem emits the divider outside the row, so fading the list out otherwise left hairlines floating over the expanded card.

Settings

Rows are restyled to match the design — 17sp Demi headline, 24dp icon, and the trailing chevron extracted to ListItemDefaults.Chevron() so callers driving their own endSlot can reuse it. The version footer sits 44dp below the last row, matching iOS's 69dp gap.

They are also rearranged:

Screen Rows
My Account Require Biometrics (switch), Blocked, User Profile (staff)
Advanced Access Key, Beta Features, Application Logs, Switch Accounts, Log Out, Delete Account

Access Key, Log Out and Delete Account are recovery/destructive actions rather than account details, so they move to Advanced along with their confirmation prompts and auth wiring.

Change Display Name is deferred to its own change — promoting the User Profile screen from a staff-gated row to an always-visible one is a separate concern. User Profile stays where it was, behind the staff/beta gate, and the My Account view model regains the beta-unlock wiring it needs for that.

Switch Accounts lives in Advanced next to the other beta tool. It keeps both of its gates — staff/beta unlock and FeatureFlag.CredentialManager, which PassphraseCredentialManager.selectCredential() hard-refuses without — and the Advanced view model now applies the staff/flag filtering it had been missing, so flag-gated rows don't flash before their flag resolves.

App Settings screen removed

The standalone App Settings screen held two toggles. Require Biometrics folded into My Account (still gated on biometric hardware, still disabled when nothing is enrolled, still prompting before the flip). Auto Start Camera is dropped outright — the camera now always auto-starts — which also removes SessionState.autoStartCamera and the now-dead CameraDisabledView branch in ScannableContainer.

The :apps:flipcash:features:appsettings module, AppRoute.Menu.AppSettings, and AppSettingValue.CameraStartByDefault are gone.

Implements the "Tip Card You Page" design (node 9216:656).

The You tab (the Menu feature under the v2 tab bar) drops its app bar and
money tiles and leads with the viewer's own tip card:

- the card renders opaque at the design's flattened fill, sits under a
  "Full Screen" affordance that presents it over the camera, and the
  status-bar clearance moves to the list's content padding so the card's
  own inset isn't paid twice
- a copy row shows the abbreviated tip link and copies the full URL
- Share and Download tiles sit below it. Download opens a "Download As"
  sheet (PNG / SVG) and hands the rendered file to the Sharesheet —
  Android has no permissionless save-to-Photos, and the chooser already
  offers Files/Drive/Photos
- the full-screen presentation of your own card gets a Close affordance
  instead of the Send-a-Tip modal, via a new SelfTipCardDecorator
- TipCardMaxWidth is raised so a phone-width canvas gets the full 0.82
  fraction the design specifies

Settings rows are restyled (17sp headline, 24dp icon, chevron extracted to
ListItemDefaults) and rearranged:

- My Account keeps the account-shaped rows — Change Display Name, Require
  Biometrics, Blocked
- Access Key, Log Out and Delete Account move to Advanced, alongside Beta
  Features and Application Logs
- the standalone App Settings screen is removed; its only surviving toggle
  moved into My Account, and Auto Start Camera is dropped (the camera now
  always auto-starts)
@github-actions github-actions Bot added type: feature New functionality area: payments Payments, transfers, intents, billing area: ui Compose UI, theme, components, resources area: scanner QR/Kikcode scanning, camera area: build-system Gradle, convention plugins, build-logic area: session and removed type: feature New functionality labels Aug 20, 2026
Three fixes found on device:

* The Share / Download tiles paid 20dp of vertical padding inside a tile
  whose height is already fixed at 88dp, leaving the label a 14dp box for a
  16dp line and clipping its descenders. The centred arrangement was already
  doing the spacing, so the padding just goes.

* "Require Biometrics" sat ~24dp taller than its neighbours: Material applies
  its 48dp minimum touch target to a Switch only when onCheckedChange is
  non-null, and 48dp beats the 24dp icon that sets every other row's height.
  Adds ListItemDefaults.Toggle — a display-only switch pinned to the icon size
  — and uses it there; the row's own onClick already ran the toggle, and it
  still does when you tap the switch itself.

* The full-screen tip card is now a route (AppRoute.Menu.TipCard) instead of a
  bill presented into the session's overlay. The card is a static thing to
  hold up to a camera, so it gets the whole screen: the page drops away
  downward on push (and the tab bar leaves with it, since this isn't a tab
  route), the card sits centred at the design's 302/402 of the screen width,
  and Close sits just above the navigation bar. Node 9277:121410.

That last one retires the whole own-card-as-bill path:
presentOwnTipCard, Scannable.TipCard.isSelf, and SelfTipCardDecorator.
@github-actions github-actions Bot added the type: feature New functionality label Aug 21, 2026
Full Screen now morphs the card that's already on the You tab rather than
navigating to a dedicated TipCardScreen. The card keeps its slot in the list
while an inner layer translates it to the display centre and grows it to the
302dp expanded width (node 9277:121410); the rest of the page fades and slides
out under it, the tab bar hides via a counted TabBarVisibilityController, and
Close/back collapse it. Spring matches iOS's
.spring(response: 0.45, dampingFraction: 0.85) — dampingRatio 0.85, stiffness 195.

Also:
- Copy link now flips to a filled checkmark.circle.fill-style glyph for 1.5s
  before fading back to the copy icon, matching iOS.
- Version footer sits 44dp below the last row to match iOS's 69dp gap.
- Switch Accounts moves into Advanced Features next to Beta Features, and the
  Advanced view model gained the staff/feature-flag filtering it was missing.
- MenuList takes an itemModifier that wraps the row *and* its sibling divider,
  so fading the list out no longer leaves divider hairlines behind.
- Clamp the animated tab-bar inset: the underdamped spring undershoots below
  zero, PaddingValues throws on a negative, and the exception was killing the
  Recomposer and freezing the whole UI mid-expansion.

Removes TipCardScreen, its content and view model, and the session-presented
tip card path.
The empty state was a Box wrapping its content, so `align(Center)` centered it
against itself and it rendered flush at the top-left of the list. It now fills
the viewport and centers there when it's the only thing in the list, and centers
within padding when the override sections are present so it can't push them off
screen. Text is centered and inset for narrow screens.
…splay Name

The row is literally called Beta Features — the badge next to it was redundant.

Change Display Name comes out of My Account for now; promoting the UserProfile
screen from a staff row to an always-visible one is its own change. The events
and navigation that open it stay wired, so re-adding the row is a one-liner.
The row went away with Change Display Name, which left the User Profile screen
unreachable — on code/cash staff could still get to it. It comes back as the
staff-gated row it was, last in the list so the production list is unchanged,
and the view model regains the beta-unlock wiring (feature-flag override or
isStaff) that My Account lost in the redesign. Staff rows stay out of the
default state so they can't flash in before the flag resolves.
…w's unavailable state

Two regressions from the settings restyle, both in the slot-driven MenuList
overload that My Account uses for its toggle row:

- the overload never forwarded MenuItem.showBetaIndicator, so User Profile —
  a StaffMenuItem, gated behind the same `override || isStaff` unlock it
  always had — rendered without its Beta badge. The badge is now emitted by
  the overload itself, ahead of whatever trailing content the caller supplies.

- the old SettingsSwitchRow dimmed its content and explained itself when a
  toggle wasn't offerable. Require Biometrics on hardware with nothing
  enrolled had been rendering as a live row that silently did nothing.
  ListItem takes `enabled` and `supportingText` again, and the mapper's
  existing "No biometrics currently enrolled" description is plumbed through
  MyAccountScreenViewModel.State.
The setting itself, its mapper entry and its session-controller consumer went
with the standalone App Settings screen; its title string and icon outlived it
with no references left.
…esign

* origin/code/cash:
  fix(core): add \ to escape ' in What's (#1298)
  feat(shared-core): wrap the framework in a Swift target (#1297)
  chore: update display name entry title/hint (#1296)
  ci(shared-core): write a placeholder local.properties before publishing (#1295)
  build(shared-core): publish the XCFramework to flipcash-shared-core-spm (#1294)
  refactor(build-logic): extract the KMP test-fixture generator into a convention plugin (#1293)
  build(base58): declare the base58 lint tasks' dependency on generated fixtures (#1292)
  test(base58): run the vector gate on Kotlin/Native, not just the JVM (#1289)
  build(codes): declare the kikcode lint tasks' dependency on generated fixtures (#1288)

# Conflicts:
#	apps/flipcash/core/src/main/res/values/strings.xml
@bmc08gt
bmc08gt merged commit 3324c4b into code/cash Aug 21, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: build-system Gradle, convention plugins, build-logic area: payments Payments, transfers, intents, billing area: scanner QR/Kikcode scanning, camera area: session area: ui Compose UI, theme, components, resources type: feature New functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant