feat(notifications): a Rust notification on a phone (module-rust phase 11) #50

Merged
whitlocktech merged 1 commits from feat/rust-phase-11-notifications into edge 2026-09-23 20:49:30 +00:00
Member

What & why

module-rust phase 11, R10's leg C (M16). The inbox and preferences screen already render every Rust trigger from the wire, and /rust/servers/<id> already opens natively. This PR fixes the three places where the app still assumed its site was a UO shard. Design of record: docs/modules/rust/PLAN.md §26 (D69–D72), in docs#266.

  • D69: the link check asks the site's own module. NotificationSettingsViewModel decided "linked" by calling module-uo's /player/shard/accounts. On a Rust site that failed, so the whole raid alert row was disabled, in every channel: it could not be switched on or off. The new LinkedAccountRepository asks /player/rust/links or /player/shard/accounts depending on capability. pushNeedsLink/canSetMode replace itemSelectable: the link holds back only switching push on, and turning anything off is never refused.
  • D70: a tickle is titled from the inbox row it points at. PushContentResolver pulls the first inbox page (five-second timeout) and titles the notification with the row the notification:<id> ref names. The row's trigger must match the tickle's stream. Any failure falls back to the per-stream title, which is also the lock-screen public version (VISIBILITY_PRIVATE). PushService now launches each tickle in its own job, because inside collectLatest the next tickle would cancel a pull.
  • D71: two links open natively. /player/rust goes to My Rust account, and /rust/servers/<id>?tab=<tab> opens on that tab, only for exactly tab= and a tab the app has. ?tab=clans still hands off to the browser.

How it was tested

  • testDebugUnitTest: 672 tests, 0 failures (657 on edge). New: LinkedAccountRepositoryTest, PushContentTest, and D71 cases in RustNavigationTest. The gating tests are rewritten for the new rule. lintDebug and assembleDebug are green.
  • Emulator walk (s22_ultra) against real core on main, with module-rust installed, the protocol-7 sidecar in the Oxide rig's container, and the relay on public ntfy.sh (D72):
    • Linked player: raid push switched on and registered https://ntfy.sh/<topic>. A rig raid reached the phone 19 s later as "Your base is being raided — A door was destroyed in P16 on Oxide rig." (vis=PRIVATE plus a public version). The tap opened the inbox, and the row opened the server natively.
    • Push switched off in the app: the next raid enqueued in-app only. The row arrived and no system notification was posted.
    • No link (walkadmin): push held with the hint, email and in-app live, and in-app switched off then on.
    • ?tab=leaderboard opened on Leaderboard, /player/rust opened My Rust account, and ?tab=clans opened a Custom Tab.
  • Not walked: a UO site (no UO core running; a unit test pins that branch), and the lock screen as seen (no screen lock on the emulator; the public version was read back from dumpsys).

Checklist

  • I have read CONTRIBUTING.md.
  • The change builds and existing tests/checks pass locally.
  • I have added or updated tests/docs where it makes sense.
  • My commits are reasonably scoped with clear messages.

AI-assisted contributions (required)

  • No AI tools were used to produce this contribution.
  • AI tools were used. Tool(s): Claude Code (Claude Opus 5.5). I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a Co-Authored-By / Assisted-By trailer.

License

  • I agree that my contribution is licensed under this project's license (GNU GPL v3.0 or later), and I have the right to contribute it.

🤖 Generated with Claude Code

https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY

## What & why `module-rust` phase 11, R10's leg C (M16). The inbox and preferences screen already render every Rust trigger from the wire, and `/rust/servers/<id>` already opens natively. This PR fixes the three places where the app still assumed its site was a UO shard. Design of record: `docs/modules/rust/PLAN.md` §26 (D69–D72), in docs#266. - **D69: the link check asks the site's own module.** `NotificationSettingsViewModel` decided "linked" by calling `module-uo`'s `/player/shard/accounts`. On a Rust site that failed, so the **whole** raid alert row was disabled, in every channel: it could not be switched on or off. The new `LinkedAccountRepository` asks `/player/rust/links` or `/player/shard/accounts` depending on capability. `pushNeedsLink`/`canSetMode` replace `itemSelectable`: the link holds back only switching **push on**, and turning anything off is never refused. - **D70: a tickle is titled from the inbox row it points at.** `PushContentResolver` pulls the first inbox page (five-second timeout) and titles the notification with the row the `notification:<id>` ref names. The row's trigger must match the tickle's stream. Any failure falls back to the per-stream title, which is also the lock-screen public version (`VISIBILITY_PRIVATE`). `PushService` now launches each tickle in its own job, because inside `collectLatest` the next tickle would cancel a pull. - **D71: two links open natively.** `/player/rust` goes to *My Rust account*, and `/rust/servers/<id>?tab=<tab>` opens on that tab, only for exactly `tab=` and a tab the app has. `?tab=clans` still hands off to the browser. ## How it was tested - `testDebugUnitTest`: **672 tests, 0 failures** (657 on `edge`). New: `LinkedAccountRepositoryTest`, `PushContentTest`, and D71 cases in `RustNavigationTest`. The gating tests are rewritten for the new rule. `lintDebug` and `assembleDebug` are green. - **Emulator walk** (`s22_ultra`) against real core on `main`, with module-rust installed, the protocol-7 sidecar in the Oxide rig's container, and the relay on public `ntfy.sh` (D72): - Linked player: raid push switched on and registered `https://ntfy.sh/<topic>`. A rig raid reached the phone **19 s** later as *"Your base is being raided — A door was destroyed in P16 on Oxide rig."* (`vis=PRIVATE` plus a public version). The tap opened the inbox, and the row opened the server natively. - Push switched off in the app: the next raid enqueued in-app only. The row arrived and no system notification was posted. - No link (walkadmin): push held with the hint, email and in-app live, and in-app switched off then on. - `?tab=leaderboard` opened on Leaderboard, `/player/rust` opened *My Rust account*, and `?tab=clans` opened a Custom Tab. - **Not walked:** a UO site (no UO core running; a unit test pins that branch), and the lock screen as seen (no screen lock on the emulator; the public version was read back from `dumpsys`). ## Checklist - [x] I have read [CONTRIBUTING.md](CONTRIBUTING.md). - [x] The change builds and existing tests/checks pass locally. - [x] I have added or updated tests/docs where it makes sense. - [x] My commits are reasonably scoped with clear messages. ## AI-assisted contributions (required) - [ ] No AI tools were used to produce this contribution. - [x] AI tools were used. Tool(s): `Claude Code (Claude Opus 5.5)`. I have reviewed and understand every change, and take responsibility for it. AI-authored commits are marked with a `Co-Authored-By` / `Assisted-By` trailer. ## License - [x] I agree that my contribution is licensed under this project's license (**GNU GPL v3.0 or later**), and I have the right to contribute it. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
wtclaude added 1 commit 2026-09-23 20:40:39 +00:00
feat(notifications): a Rust notification on a phone (module-rust phase 11)
All checks were successful
PR Checks / android-build (pull_request) Successful in 8m54s
640b423dfa
Three places the app still assumed its site was a UO shard (D69-D71):

- The linked-account check behind personal streams asked module-uo's
  /player/shard/accounts. On a Rust site that failed, and the whole raid
  alert row was disabled in every channel. It now asks the site's own
  module by capability, and the link only holds back switching push ON;
  switching anything off is never refused.
- A tickle whose ref names an inbox row is titled from that row, pulled
  over the authenticated inbox API (wake-and-pull). The lock screen shows
  only the per-stream title. Each tickle runs in its own job, because
  collectLatest would cancel a pull on the next tickle.
- /player/rust and /rust/servers/<id>?tab=<tab> open natively; a tab the
  app does not have (clans) still hands off to the browser.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E14m6SuuY6i1vASFeGDBeY
whitlocktech merged commit adf9547e01 into edge 2026-09-23 20:49:30 +00:00
whitlocktech deleted branch feat/rust-phase-11-notifications 2026-09-23 20:49:31 +00:00
Sign in to join this conversation.
No description provided.