Skip to content

feat(mobile): choose chat views from the Host drawer - #2531

Merged
DoodleBears merged 5 commits into
mainfrom
t3/mobile-drawer-views
Oct 21, 2026
Merged

DoodleBears merged 5 commits into
mainfrom
t3/mobile-drawer-views

Conversation

@DoodleBears

@DoodleBears DoodleBears commented Oct 21, 2026 •

Copy link
Copy Markdown
Contributor

Requested by Vain.

Why the change

Phone Chats should choose All or one Host from the drawer using one conversation list, with the latest Host choice matching the actual and persisted Host owner.

Refs #2500, Refs #2517, Refs #2518. Implementation claim, R2 follow-up claim, parent claim. Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050.

Special things to note

  • Draft; not merge-ready. Reversible mobile-only UI/ordering change, no migration or native inputs. Review drawer switch serialization through the existing HostSession save/adopt, latest-view guard, Android accent scope and iOS edge gesture. A later Host choice waits for earlier persistence to settle; All changes the view immediately without cancelling an already requested Host switch. HostSession/T4 notification interfaces are unchanged. Track B follows A; coordinator owns independent review and merge.
  • Checks at 4b0c1b7e79c4f4a7d60126b1b803c1494ec85ee3: 45 related tests across three files passed with one worker; typecheck/lint/format passed with process-local GOMAXPROCS=2 after rebase. Full build passed with GOMAXPROCS=2, exit 0; its exclusive slot has been released. Rebased onto main e0bbe34 (feat(client): show remote Bot and group avatars #2535) without conflicts, then reran typecheck/lint/format, 45 mobile tests, 7 StyleX tests and the full build. Rebuilt browser/computer bundles and maps exactly match main; the redundant hash-only artifact commit was dropped. Both JS files passed syntax checks. The earlier 25b8 build is prior-base evidence only. New real-HostSession tests reproduced two owner failures before the fix and now assert current Host, persisted Host and filter together. Prior ca06871e7 had 13 passing CI checks and Standards 0 per parent; those results belong only to that SHA and did not resolve its remaining Spec P2. Full mobile was not rerun for this follow-up: earlier 1036 pass / 12 fail / 9 skip, with all 12 locale failures reproduced on main. Final-head CI/independent review and native iOS/Android remain pending. No live model invoked.
  • CI plan: full, because deleting environment-pager prevents tracing its old importers; no new rule needed. No packages/client source changes. JS only: existing compatible Expo SDK 58.0.16 / React Native 0.88 dev client can load the change through the queue owner's Metro. Previous web export and isolated Host pairing/header smoke remain prior-head evidence; they do not qualify native usability or complete conversation rendering.

Change outline

Before: environment tabs / swipe pager → conversation list
After:  drawer All → filter=all → one list of current Host + enabled cloud
        drawer Host → queued switchTo → saveHosts → adopt
                    → latest successful selection sets Host filter
  • Serial execution prevents A→pending B→A from returning early for old A and later adopting B. B/C writes cannot finish out of invocation order. A rejected switch does not block the next choice. Regression uses actual HostSession/saveHosts/loadSavedHosts/adopt with delayed SecureStore writes; native/transport adapters and unrelated conversation services are substituted.
  • Header title/icon follows the view. Its localized accessible label contains the full name and existing cloud disambiguation. New title/All icons scale from their label role × fontScale. All has a clipped Android foreground ripple even when selected.
  • Android accent applies only when the current Host filter is selected and has a colour; All/cloud/mismatched Host/no colour/iOS keep default accent. Preserve iOS EDGE_WIDTH, feat(mobile): pair by account or Tailscale from a choice sheet; hide cloud Channels behind a flag #2512 empty home/cloud flag, and account rows opening /pair/account?account=....
  • Native screenshot blocker: iOS is unrun for the coordinator's combined external Mac handoff; Android is Next batch with no lease/runner assigned. No native matched before/after screenshots yet. The exact-head acceptance journey covers three neutral paired Hosts, default/intermediate/maximum OS text × light/dark per platform, rapid A/B/A and B/C with persisted owner checks, All, accent reset, screen-reader names, icon scaling, ripple, edge gestures and account routing. Deterministic delayed storage is automated-test evidence; rapid native taps cannot prove that timing case.

All covers the current Host plus cloud, not every paired Host. Host looks remain device-local by design. Known broader gaps: remote chat text and attachment names only (images/cards missing); DSH Desktop unqualified; no physical two-machine tailnet test.

@DoodleBears DoodleBears self-assigned this Oct 21, 2026
@coderabbitai

coderabbitai Bot commented Oct 21, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Note

Currently processing new changes in this PR. This may take a few minutes, please wait...

⚙️ Run configuration
  • Configuration used: defaults
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 2f1b427c-299b-4350-b6bd-f26878b5a2a5
📥 Commits

Reviewing files that changed from the base of the PR and between e0bbe34 and 4b0c1b7.

📒 Files selected for processing: 15
  • .agents/skills/verify-deepseekbot/features/README.md
  • .agents/skills/verify-deepseekbot/features/phone-drawer-views.md
  • apps/mobile/DESIGN.md
  • apps/mobile/app/(tabs)/(home)/index.tsx
  • apps/mobile/app/_layout.tsx
  • apps/mobile/src/ui/shell/environment-pager.tsx
  • apps/mobile/src/ui/shell/home-header.tsx
  • apps/mobile/src/ui/shell/host-accent-provider.tsx
  • apps/mobile/src/ui/shell/host-drawer-model.ts
  • apps/mobile/src/ui/shell/host-drawer.tsx
  • apps/mobile/test/home-search.test.tsx
  • apps/mobile/test/host-drawer.test.ts
  • apps/mobile/test/host-session-unpair.test.ts
  • changes/2518-mobile-drawer-views.md
  • scripts/verification-inventory.json
+------------------------------------------------------------------+
| Ah yes, the classic pattern: 'parse first, ask questions never'. |
+------------------------------------------------------------------+
  \
   \     /)/)
        ( '')
        /  |
      o(___)
✨ Finishing Touches
📝 Generate docstrings
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@DoodleBears

Copy link
Copy Markdown
Contributor Author

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
State: handed-off to coordinator.

Requested by Vain. Draft PR #2531, branch t3/mobile-drawer-views, head 70ca072863d6d5acb30f2690429b7f1fc864e554. Independent implementation supersedes the missing-patch handoff. Typecheck, lint, format and build passed; changed tests 31 passed. Full mobile: 1036 passed / 12 failed / 9 skipped; all 12 failures independently reproduced on main. client-observer passed; workspace-grant-roundtrip timeout reproduced on main. No node:sqlite bundling failure observed this run.

No native inputs changed. Android submitted to Windows Next batch without a lease; iOS deferred to coordinator combined external Mac acceptance per Vain. No native before/after screenshots or native acceptance yet; not merge-ready, no merge performed. Track B follows A. Known limits remain: device-local looks by design; remote text/attachment names only, images/cards missing; Desktop and physical-machine tailnet unqualified.

Exact-head HTML generated locally via repository answer-me-with-html; no approved reviewer-accessible HTML publication was made, so accessibility remains a handoff gap. Runnable native matrix is in the committed phone-drawer-views guide and PR description. Local detailed handoff: .humanlayer/tasks/2518/handoff.md.

@DoodleBears

Copy link
Copy Markdown
Contributor Author

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050

State: handed-off for coordinator review; PR #2531 remains Draft, not merge-ready. Requested by Vain. Refs #2500 / #2518.

Final pushed head: ca06871e7c99025dcbe5a8c44a88de57b5c6be33; rebased base: a6704fd8555f04a9f82b6f753154ca5fc243cf76. Same branch t3/mobile-drawer-views; no unpushed tracked changes.

All five reviewed findings are addressed:

  1. Android accent is injected only with the current Host filter selected and a configured colour. All/cloud/mismatched Host/no colour/iOS use the default theme. Regression covers Host→All, current/noncurrent filters, scheme and colour changes, no Host and iOS.
  2. A selection generation prevents older switch completions from committing the view after a newer All or Host choice. Existing HostSession authority is unchanged. Deferred Host→All and both Host-completion orders are covered.
  3. The localized header accessibility label includes the complete selected view name and existing cloud disambiguation. All, long Host and cloud labels are covered.
  4. New title icons and drawer All icon use their label role × live fontScale. Header regressions cover three font scales; the All wiring and glyph scaling semantics were inspected.
  5. All uses token-derived Android foreground ripple with clipping, including over its selected background. Static wiring is checked; actual native press feedback is still untested.

Final-head typecheck, lint, format and 37 related tests (two files, one worker) passed. An earlier parallel worker-start timeout is retained separately and is not counted as a pass. Build passed before the final rebase, which brought in CI-only main changes. Full mobile was not rerun for this follow-up: prior results were 1036 pass / 12 fail / 9 skip, with all 12 locale failures independently reproduced on main. The 12 passing CI checks reported for 6fefff4 belong to that older head; final-head CI was not awaited.

DESIGN, the bilingual fragment, feature guide, PR body, native handoff and exact-head HTML have been refreshed. The HTML was generated with the repository CLI and inspected at desktop/narrow widths; it remains a local/T3 handoff, without a reviewer-accessible public attachment. It is not runtime evidence.

Native inputs: none, JS only; existing compatible Expo SDK 58.0.16 / React Native 0.88 client. iOS remains unrun for coordinator-led external Mac acceptance. Android remains Next batch with no lease and no native result. No shared Host/device was restarted. The exact-head native journey specifies two neutral paired Hosts, three OS font sizes × light/dark per platform, full screen-reader names, icon scaling, All ripple, Host→All accent reset, delayed switching, iOS EDGE_WIDTH and account routing. Native before/after screenshots are still missing.

Track B still follows A; coordinator owns merge and the next independent reviews. Known wider limits remain: remote chat text/attachment names only (images/cards missing), device-local Host looks by design, DSH Desktop unqualified, no physical two-machine tailnet test.

@DoodleBears
DoodleBears force-pushed the t3/mobile-drawer-views branch from ca06871 to bd1c8ec Compare October 21, 2026 17:29
@DoodleBears

Copy link
Copy Markdown
Contributor Author

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050

State: handed-off for coordinator R3 independent review. Requested by Vain. Same Draft PR #2531, not merged and not merge-ready. Refs #2500 / #2518.

Final pushed head: bd1c8ec171d31728a1ef4006696c766b9e325f30.
Base: b1cf50ed22c65fe0292c236b07d9b11d1d7afbb3.
Same branch t3/mobile-drawer-views; clean working tree, no unpushed tracked changes. Fetch/rebase before push found no newer base changes; explicit expected-head lease protected the push.

The remaining R2 Spec P2 is addressed by serializing drawer-triggered switchTo calls. A later choice waits until the preceding real saveHosts/adopt settles before checking the current Host. This prevents A→pending B→A from returning early for old A, and prevents B/C persistence/adoption from completing out of invocation order. The existing generation still gates showView. All sets its filter immediately and does not cancel an already requested Host switch. Rejection is propagated to its caller but does not block the next queued choice.

No HostSession/T4 interface changes: host-session.ts is untouched. No rewrite of pairing, unpairing, push or client lifecycle. Only host-drawer-model.ts has new production logic in this follow-up; the preceding accessibility/scaling/ripple/accent fixes remain intact.

Regression evidence uses real HostSession, saveHosts, loadSavedHosts and adopt, with deferred SecureStore writes and native/transport test adapters:

  • A→pending B→A: final current Host, persisted Host and filter all A.
  • B→C with either storage gate released first: all three facts end on C.
  • pending B→All: current/persisted Host B and filter All.
  • Rejected earlier switch: later Host choice still completes.

Two owner assertions failed before the fix (B instead of A, B instead of C); 45 tests across three files passed after it, with one worker. An earlier native-import timeout is retained separately and is not the red reproduction. Typecheck, lint and format passed after the latest-main rebase with process-local GOMAXPROCS=2. Full pnpm build passed, exit 0; A immediately released its exclusive heavy-build slot to the coordinator. Source checks/build ran on 25b8ae9fc; the final commit records the two generated browser/computer client bundles, only StyleX hashes changed, maps unchanged, and both JS syntax checks passed. Oxfmt excludes those generated files under repository rules; they were not hand-formatted.

Parent-reported 13 CI checks passed / Standards 0 at ca06871 remains evidence for that prior SHA only. It did not resolve the remaining P2 at that SHA. New-head CI was not awaited; R3 independent review is pending. Full mobile was not rerun; earlier 12 locale failures were independently reproduced on main.

PR description, bilingual fragment, DESIGN, feature guide, exact-head HTML and native handoff are updated. HTML remains local/T3 without a public reviewer attachment; it is not runtime evidence. The exact-head native journey includes A/B/C, owner/persistence after restart, default/intermediate/maximum OS text × light/dark, iOS EDGE_WIDTH, Android accent/ripple, screen-reader names and account routing.

Native inputs are unchanged (JS only; compatible SDK58.0.16/RN0.88 development client). iOS/Android native checks and matched before/after screenshots remain unrun. No shared device, Metro or Host was started or restarted. Track B still follows A; coordinator owns review and merge. Known limits remain remote chat text/attachment names only (images/cards missing), device-local Host looks by design, DSH Desktop unqualified, and no physical two-machine tailnet test.

Issue: #2518

Issue: #2500

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
Issue: #2518

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
Limit Android Host tint to the selected current Host and ignore superseded switch completions.

Issue: #2518

Issue: #2500

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
Issue: #2518

Issue: #2500

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
Issue: #2518

Issue: #2500

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050
@DoodleBears
DoodleBears force-pushed the t3/mobile-drawer-views branch from bd1c8ec to 4b0c1b7 Compare October 21, 2026 17:37
@DoodleBears

Copy link
Copy Markdown
Contributor Author

Agent-Task: codex/local/01a15f0c-71f0-7202-8a08-f2e8aacb6050

State: handed-off for coordinator R3 independent review. Requested by Vain. Same Draft PR #2531, not merged and not merge-ready. Refs #2500 / #2518.

Final pushed head: 4b0c1b7e79c4f4a7d60126b1b803c1494ec85ee3.
Base: e0bbe34a4d4fcb36973fde9f1fa907102736640c.
Same branch t3/mobile-drawer-views; clean working tree, no unpushed tracked changes. Fetch/rebase integrated main e0bbe34 / T1 #2535 without conflicts; explicit expected-head lease protected the push. Mobile source is unchanged by the rebase.

The remaining R2 Spec P2 is addressed by serializing drawer-triggered switchTo calls. A later choice waits until the preceding real saveHosts/adopt settles before checking the current Host. This prevents A→pending B→A from returning early for old A, and prevents B/C persistence/adoption from completing out of invocation order. The existing generation still gates showView. All sets its filter immediately and does not cancel an already requested Host switch. Rejection is propagated to its caller but does not block the next queued choice.

No HostSession/T4 interface changes: host-session.ts is untouched. No rewrite of pairing, unpairing, push or client lifecycle. Only host-drawer-model.ts has new production logic in this follow-up; the preceding accessibility/scaling/ripple/accent fixes remain intact.

Regression evidence uses real HostSession, saveHosts, loadSavedHosts and adopt, with deferred SecureStore writes and native/transport test adapters:

  • A→pending B→A: final current Host, persisted Host and filter all A.
  • B→C with either storage gate released first: all three facts end on C.
  • pending B→All: current/persisted Host B and filter All.
  • Rejected earlier switch: later Host choice still completes.

Two owner assertions failed before the fix (B instead of A, B instead of C); 45 tests across three files passed after it, with one worker. An earlier native-import timeout is retained separately and is not the red reproduction. Typecheck, lint and format passed after the latest-main rebase with process-local GOMAXPROCS=2. Full pnpm build passed, exit 0; A immediately released its exclusive heavy-build slot to the coordinator. All required integration checks and the full build were rerun on e0bbe34, with 7 additional StyleX tests passing. Rebuilt browser/computer bundles and maps exactly match main, so the redundant hash-only artifact commit was dropped. Both JS syntax checks passed. The earlier 25b8 build is prior-base evidence only; the new build log is separate. An initial node --test invocation of the Vitest StyleX file failed to initialize the runner; the correct Vitest invocation passed all 7 tests.

Parent-reported 13 CI checks passed / Standards 0 at ca06871 remains evidence for that prior SHA only. It did not resolve the remaining P2 at that SHA. New-head CI was not awaited; R3 independent review is pending. Full mobile was not rerun; earlier 12 locale failures were independently reproduced on main.

PR description, bilingual fragment, DESIGN, feature guide, exact-head HTML and native handoff are updated. HTML remains local/T3 without a public reviewer attachment; it is not runtime evidence. The exact-head native journey includes A/B/C, owner/persistence after restart, default/intermediate/maximum OS text × light/dark, iOS EDGE_WIDTH, Android accent/ripple, screen-reader names and account routing.

Native inputs are unchanged (JS only; compatible SDK58.0.16/RN0.88 development client). iOS/Android native checks and matched before/after screenshots remain unrun. No shared device, Metro or Host was started or restarted. Track B still follows A; coordinator owns review and merge. Known limits remain remote chat text/attachment names only (images/cards missing), device-local Host looks by design, DSH Desktop unqualified, and no physical two-machine tailnet test.

@DoodleBears
DoodleBears marked this pull request as ready for review October 21, 2026 20:47
@DoodleBears
DoodleBears merged commit 94abbe8 into main Oct 21, 2026
12 of 13 checks passed
@DoodleBears
DoodleBears deleted the t3/mobile-drawer-views branch October 28, 2026 04:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant