feat(rust): the map on a phone (module-rust phase 15, M17) #51

Merged
whitlocktech merged 1 commits from feat/rust-phase-15-map into edge 2026-09-25 17:43:22 +00:00
Member

Android leg D of module-rust: the live map as a fifth tab on the Rust server screen, and site-event markers linking to the app's own event pages. Design of record: docs/modules/rust/PLAN.md §31 (D121–D125, merged in docs#273). As-built and walk: docs#274 (§31.5–§31.7).

What it does

  • The tab (D122). RustTab.MAP sits between Online and Wipes. It's shown when the site's module declares map, under the app's one three-state capability rule. ?tab=map opens it, and on a site without a map it opens the feed.
  • The canvas (D121). Coil loads the picture once per map (the URL carries its hash) as RGB_565, with hardware bitmaps off. A Compose Canvas draws the grid and the markers, with pinch, pan and double tap. No new dependency.
    • The frame is §30.3's transform, ported from the web's mapGeometry.js with its fifteen probed grid cases.
    • Markers keep their size on screen. A zone is drawn on the ground, in metres.
  • No gate of its own. map/live is projected per viewer on the server. The app draws what it is sent, and lists each layer it wasn't sent with who can see it (the D113 line included).
  • The tap card shows what a marker is, its grid square, and what its layer carried.
  • The event link (D123/D125). A site-event marker whose run is on core's public calendar gets Open event, which goes to Routes.event(slug, runId).
    • The calendar is read once, and re-read at most once a minute, only for a run id it doesn't know.
    • Run ids are matched as text: the plugin sends "41", core sends 41.
    • A rehearsal's or unlisted event's marker says "Site event" and has no button.
  • The poll (D124). map/live every pollMs (10 s) while RESUMED on the Map tab. There is no poll at all for a viewer who is sent nothing that moves. A new mapKey re-reads /map, so a new seed's picture follows in place.
  • Per account. On a change of signed-in account the map's state is dropped and re-asked. An answer asked for the previous account is discarded when it lands.

Walked on an emulator against real core (D125 branch) and the Oxide rig's protocol-11 sidecar, with probe stand-ins. All seven §31.3 steps pass; details are in §31.5. The walk found two defects, both fixed here:

  • The reader's zoom was lost on the way back from the event page. It is now rememberSaveable.
  • The zoom was also lost whenever the status line under the map changed length. A resize now keeps the view's centre (MapTransform.resized, tested).

Depends on website#208 for the event link. Against an older core the field is absent, and every event marker stays unlinked.

Checks: testDebugUnitTest 732/732 (72 new or changed in ui/rust), lintDebug clean, assembleDebug.

  • AI-assisted: Claude Code (Claude Opus 5.5)

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

Android leg D of module-rust: the live map as a fifth tab on the Rust server screen, and site-event markers linking to the app's own event pages. Design of record: `docs/modules/rust/PLAN.md` §31 (D121–D125, merged in docs#273). As-built and walk: docs#274 (§31.5–§31.7). **What it does** - **The tab (D122).** `RustTab.MAP` sits between Online and Wipes. It's shown when the site's module declares `map`, under the app's one three-state capability rule. `?tab=map` opens it, and on a site without a map it opens the feed. - **The canvas (D121).** Coil loads the picture once per map (the URL carries its hash) as RGB_565, with hardware bitmaps off. A Compose `Canvas` draws the grid and the markers, with pinch, pan and double tap. No new dependency. - The frame is §30.3's transform, ported from the web's `mapGeometry.js` with its fifteen probed grid cases. - Markers keep their size on screen. A zone is drawn on the ground, in metres. - **No gate of its own.** `map/live` is projected per viewer on the server. The app draws what it is sent, and lists each layer it wasn't sent with who can see it (the D113 line included). - **The tap card** shows what a marker is, its grid square, and what its layer carried. - **The event link (D123/D125).** A site-event marker whose run is on core's public calendar gets **Open event**, which goes to `Routes.event(slug, runId)`. - The calendar is read once, and re-read at most once a minute, only for a run id it doesn't know. - Run ids are matched as text: the plugin sends `"41"`, core sends `41`. - A rehearsal's or unlisted event's marker says "Site event" and has no button. - **The poll (D124).** `map/live` every `pollMs` (10 s) while RESUMED on the Map tab. There is no poll at all for a viewer who is sent nothing that moves. A new `mapKey` re-reads `/map`, so a new seed's picture follows in place. - **Per account.** On a change of signed-in account the map's state is dropped and re-asked. An answer asked for the previous account is discarded when it lands. **Walked on an emulator** against real core (D125 branch) and the Oxide rig's protocol-11 sidecar, with probe stand-ins. All seven §31.3 steps pass; details are in §31.5. The walk found two defects, both fixed here: - The reader's zoom was lost on the way back from the event page. It is now `rememberSaveable`. - The zoom was also lost whenever the status line under the map changed length. A resize now keeps the view's centre (`MapTransform.resized`, tested). **Depends on** website#208 for the event link. Against an older core the field is absent, and every event marker stays unlinked. **Checks:** `testDebugUnitTest` 732/732 (72 new or changed in `ui/rust`), `lintDebug` clean, `assembleDebug`. - [x] AI-assisted: Claude Code (Claude Opus 5.5) 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-25 17:31:18 +00:00
feat(rust): the map on a phone (module-rust phase 15, M17)
All checks were successful
PR Checks / android-build (pull_request) Successful in 9m53s
09eb101c52
A fifth tab on the Rust server screen, between Online and Wipes, shown
when the site's module declares `map` under the app's one capability
rule (D122). `?tab=map` opens it; on a site without a map it opens the
feed.

The phone draws the map itself (D121): Coil loads the picture once per
map as RGB_565, and a Compose Canvas draws the grid and the markers,
with pinch, pan and double tap. The frame is §30.3's transform, ported
from the web's mapGeometry.js with its test cases. Markers keep their
size on screen; a zone is drawn on the ground. Nothing here gates a
layer: map/live is projected per viewer on the server, and the app
draws what it is sent.

- The legend: a switch per layer the viewer was sent, and who can see
  each one they were not (with the D113 line). The mates row offers
  the Steam link to a signed-in, unlinked viewer.
- The tap card: what a marker is, its grid square, and what its layer
  carried. A site-event marker whose run core's public calendar lists
  (D125) has Open event, which opens the app's own event page on that
  run (D123). A rehearsal's or unlisted event's marker says only
  "Site event".
- The poll: map/live every pollMs (10 s) while RESUMED on the Map tab
  (D124), and not at all for a viewer sent nothing that moves. A new
  mapKey re-reads the map, so a new seed's picture follows in place.
- Per account: the map's state is dropped and re-asked on a change of
  signed-in account, and an answer asked for the previous account is
  discarded when it lands.

Found on the emulator walk and fixed here: the reader's zoom was lost
on the way back from the event page, and again whenever the status line
under the map changed length (a resize was treated as a rotation).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit edcbc0727b into edge 2026-09-25 17:43:22 +00:00
whitlocktech deleted branch feat/rust-phase-15-map 2026-09-25 17:43:23 +00:00
Sign in to join this conversation.
No description provided.