Skip to content

fix: route your own tip card to the You tab (deeplink + scan) - #1317

Merged
bmc08gt merged 2 commits into
code/cashfrom
fix/tip-card-self-link-nav
Aug 24, 2026
Merged

fix: route your own tip card to the You tab (deeplink + scan)#1317
bmc08gt merged 2 commits into
code/cashfrom
fix/tip-card-self-link-nav

Conversation

@bmc08gt

@bmc08gt bmc08gt commented Aug 24, 2026

Copy link
Copy Markdown
Collaborator

Problem

Hitting your own Tip Card did nothing at all — via a /tip/{self} deeplink, or by scanning your own code.

Tipping yourself is a payment no-op, so the flow was correctly disabled — but it was disabled by a bare return in TipCardDelegate.resolveTipCard, after the deeplink or scan had already been consumed. The user is left on whatever screen they were on with no feedback that anything happened.

Both now land on the You tabAppRoute.Sheets.Menu, the surface that owns your tip card (NavBarRoutes: NavBarButton.TipCard -> Sheets.Menu).

Deeplink

Decided in AppRouter, which gains a currentUserIdProvider wired in RouterModule from the UserManager it already injects. A self-targeted link resolves to DeeplinkAction.Navigate(listOf(AppRoute.Sheets.Menu)) rather than PresentTipCard.

Routing it as a plain Navigate means every existing dispatch site handles it unchanged:

  • Cold start — the Navigate branch in MainRoot, where buildNavGraphForLaunch already replaces the launch home with a tab-home deeplink route (you get [Sheets.Menu], not Menu stacked on Wallet).
  • WarmcodeNavigator.navigateAll(...) in App.kt, which wraps it as a sheet under v1 and swaps the tab under v2.

Sheets.Menu is already emitted by the router for the my-account email-verification link, so both UI versions are known to handle it.

Scan

Two scan shapes reach this: a QR tip link (Scanner hands the id straight to resolveTipCard) and an OpenCode tip payload (CodeScanDelegate raises TipCardScanned, which the shell routes to the same call). Both funnel through the one guard in TipCardDelegate, so that is where it is answered — it raises TipCardEvent.OwnCardScanned on a new UI-facing flow instead of returning silently, and Scanner collects it and navigates.

tipCardEvents is deliberately separate from TipCardDelegate.events: that channel is the shell's single consumer (consumeAsFlow), this one is the UI's. It is replay-less, so an event raised with no scanner on screen is dropped — correct here, since every producer runs while the scanner is composed.

TipCardOperations is only implemented by TipCardDelegate and RealSessionController delegates to it, so the new member propagates without touching the shell.

Tests

  • AppRouterTest — self link resolves to Navigate([Sheets.Menu]); another user to PresentTipCard; a null accountId to PresentTipCard, so a link opened before the account resolves is not swallowed.
  • TipCardDelegateTest (new) — own id raises OwnCardScanned and never calls the coordinator; another id resolves and presents as before.

A `/tip/{self}` deeplink dead-ended: AppRouter always produced
PresentTipCard, and the self-check lived downstream in TipCardDelegate as
a bare `return` — so tapping your own tip card link did nothing at all.

Decide it in the router instead. A self-targeted tip card link now
resolves to Navigate(Sheets.Menu) — the You tab, which owns your tip card
(NavBarRoutes: NavBarButton.TipCard -> Sheets.Menu). Every existing
dispatch site already handles Navigate: cold start goes through
buildNavGraphForLaunch, which replaces the launch home with a tab-home
deeplink route, and the warm path goes through navigateAll, which wraps
it as a sheet under v1 and swaps the tab under v2.

The TipCardDelegate guard stays — scanning your own QR still reaches it —
but its comment no longer claims the self case never comes through.

Scanning your own tip code is unchanged and still no-ops.
@github-actions github-actions Bot added type: fix Bug fix area: deeplinks Deep link handling, URL routing, and link parsing area: session and removed type: fix Bug fix labels Aug 24, 2026
Scanning your own tip card had the same dead end the deeplink did: the
guard in TipCardDelegate.resolveTipCard returned bare, so the scan
produced no visible outcome at all.

Both scan shapes — a QR tip link (Scanner hands the id straight to
resolveTipCard) and an OpenCode tip payload (CodeScanDelegate raises
TipCardScanned, which the shell routes to the same call) — funnel through
that one guard, so it's the place that has to answer for them. It now
raises TipCardEvent.OwnCardScanned on a new UI-facing flow instead of
returning silently, and the scanner collects it and navigates to
Sheets.Menu — the same You tab the deeplink lands on.

tipCardEvents is separate from TipCardDelegate.events: that channel is
the shell's single consumer, this one is the UI's. It's replay-less, so
an event raised with no scanner on screen is dropped, which is right —
every producer runs while the scanner is composed.

TipCardOperations is only implemented by TipCardDelegate, and
RealSessionController delegates to it, so the new member propagates
without touching the shell.
@github-actions github-actions Bot added area: scanner QR/Kikcode scanning, camera type: fix Bug fix labels Aug 24, 2026
@bmc08gt bmc08gt changed the title fix(router): route your own tip card link to the You tab fix: route your own tip card to the You tab (deeplink + scan) Aug 24, 2026
@bmc08gt
bmc08gt merged commit 57c991c into code/cash Aug 24, 2026
3 checks passed
@bmc08gt
bmc08gt deleted the fix/tip-card-self-link-nav branch August 24, 2026 17:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: deeplinks Deep link handling, URL routing, and link parsing area: scanner QR/Kikcode scanning, camera area: session type: fix Bug fix

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant