notedeck · crates/notedeck_headway/src/lib.rs · 89aac407aca4
When you click a Headway card from inside Dave, the global history should grow by exactly one entry, and one back press should return you to Dave. This commit gives Headway the half that makes that possible: it can now say, up front, which route an open should land on.
App::open_note_route(ctx, note_id) -> Option<Rc<dyn Any>> is a question the chrome asks the app that owns a clicked note: “what route should this open land on?” The app does whatever state setup the route depends on but doesn't carry (for Headway, which board is active) and hands back its own route token. The chrome then pushes one entry, tagged with the owning app's slot, which the app itself never learns. Commit 1 added the defaulted hook. This commit is Headway's implementation of it.
Headway turns UI movement into nav requests by diffing the view position before and after each render (reconcile_nav(before, after)). The old path started that diff from an untyped () token, which reads as Board. The pending open then selected a card, the diff read Board → Card, and Headway pushed a second entry. Now the token already is the card, so both ends of the diff agree.
The card can be on a board that isn't the active one. activate_open_target switches active straight away, but that board's view folds in on a later frame. Until it does, find_card misses. Before commit 2, that miss cleared the selection. The diff then read Card → Board and popped the entry that had just been pushed. The headline test uses a card from a second roadmap board for this reason: it walks through the gap between the open and the fold.
A board note mints HeadwayRoute::Board. Switching the board was the whole job, so nothing is left pending. open_note_route_for_a_board_note_returns_the_board_route draws that token and waits for the roadmap board's only card to appear, which proves the switch happened. It also checks that no detail opened.
Mutation check, run before committing: make open_note_route return HeadwayRoute::Board for a card, which is the untyped shape the chrome pushes today. The headline test fails on its first assertion:
assertion `left == right` failed: a cross-app open is one history entry left: 3 right: 2
Three entries: [Source/(), Headway/Board, Headway/Card]. That is the stack users get today, where the first back lands on the Headway board instead of the app they came from.
Nothing in the real app calls this yet. The chrome's AppAction::Note arm still does switch_to_headway() followed by open(). The fix users will see is commit 5 (headway:notedeck/duck-echo-chronic). Until then, clicking a card chip from Dave still takes two back presses. Everything on this page was checked in the chrome-less test harness, which copies what apply_nav_requests does. It does not run the real chrome.
Only one render pass per frame. During an animated transition, egui_nav also draws the background route, so render_nav runs twice on those frames. The harness never animates. The plan lists this as an out-of-scope card.
Title is a snapshot. The title comes from the issue event's original subject, so it can lag a rename. That is true of every other Headway history label as well.
Board switches don't go into history. The switch in activate_open_target isn't recorded in any entry. So if a later back or forward lands on an older Headway Card entry from a different board, that card is resolved against whichever board is active then. This is also listed as out of scope.