mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-14 06:33:09 -06:00
2a8b322ebf
* feat(ui): add mobile desktop document mode Add a shell-free mobile desktop route that reuses the dock panel controller and lazy noVNC client, with source preselection, touch controls, keyboard input, and retryable inventory failures. * feat(ios): add desktop viewer entry points * feat(android): add desktop viewer * fix(android): keep System Back inside the desktop viewer The per-session viewer replaces SessionDashboardScreen in place instead of pushing a shell tab, so System Back fell through to the shell-level handler and popped the whole Dashboard tab, stranding the operator on Chat. Claim Back while the viewer is showing. Also carry over TerminalSettingsScreen's imePadding: the viewer's own touch toolbar hosts the keyboard affordance, so the soft keyboard would cover it. Proof (emulator, Medium_Phone_API_36.0, stub control UI on 18789): pre-fix Back from the viewer lands on Chat; post-fix it returns to Dashboard. No Robolectric regression test — no existing screen test constructs MainViewModel, and BackHandler under Robolectric would need new scaffolding for weaker evidence than the live repro. * test(ui): stop the pairing views leaking dialogs into the shared document `ui/vitest.config.ts` runs the unit project with `isolate: false`, so test files share one jsdom document inside a worker. `view.pairing.test.ts` appends a container to `document.body` for every case and never tears down, unlike its sibling `channels-page.test.ts`, so whichever suite the worker scheduled next inherited a mounted pairing dialog. That surfaced on this PR's first CI run as ten failures in the untouched `input-dialog.test.ts`, which found "Approve DM access" where it expected "Rename session". A rerun went green, so the ordering is scheduler-dependent rather than deterministic; this removes the contamination source rather than leaving the next suite to lose the race. Not a proven fix for that specific run — the leak reproduces only under CI's file scheduling, and the full suite passes locally either way — but the missing teardown is a real violation of the shared-environment contract. * test(ui): stop the background-tasks rail asserting on a ticking clock The rail e2e captured the main transcript's text before opening a task detail and required it to be byte-identical afterwards. A running task renders a live elapsed label, so the assertion failed whenever a second ticked over between the two reads — twice while landing this PR, both times "12s" against "13s" with no other difference. Normalize elapsed labels on both sides instead of weakening the assertion. The invariant it protects, that opening a detail leaves the main transcript alone, still holds: a real content change is still caught, and only complete duration tokens collapse, so diffstat figures like +14/-3 and phrases like "5 messages" are untouched.