Skip to content

fix(mobile): responsive dialogs + safe-area + workspace events + X-Frame fallback + https auto-prefix (Phase 7 fixes)#37

Merged
JohnMcLear merged 3 commits into
mainfrom
feat/mobile-phase7-responsive-android-fixes
May 12, 2026
Merged

fix(mobile): responsive dialogs + safe-area + workspace events + X-Frame fallback + https auto-prefix (Phase 7 fixes)#37
JohnMcLear merged 3 commits into
mainfrom
feat/mobile-phase7-responsive-android-fixes

Conversation

@JohnMcLear
Copy link
Copy Markdown
Member

Summary

Six device-test issues surfaced on a real Android run; all fixed in one PR.

# Issue Fix
1 AddWorkspace dialog wider than phone viewport DialogShell width → min(${width}px, calc(100vw - 16px))
2 Bare hostnames rejected as UrlValidationError AddWorkspaceDialog auto-prefixes https:// when no scheme
3 OpenPad dialog huge on phone Same DialogShell fix
4 Black screen on pad open (X-Frame-Options likely) 6s onLoad timeout → opaque "Open in browser" overlay calling @capacitor/browser
5 Status bar overlaps the rail env(safe-area-inset-*) padding on shell-root-wrapper (no-op on desktop)
6 New workspace doesn't show in rail until restart workspace-store fires onChanged; CapacitorPlatform wires it to events.onWorkspacesChanged

Mobile-specific surface (no desktop behaviour change)

  • shell-root-wrapper safe-area padding uses env(...) which resolves to 0 on Electron/desktop browsers.
  • min(...) width cap also produces the same 420px on desktop viewports.
  • All other changes are inside packages/mobile/.

Test plan

  • Local pnpm test clean (203 shell + 281 desktop + 6 mobile)
  • APK installed + launched on a physical device (Nokia C62)
  • CI green on pnpm typecheck / test / test:e2e
  • User confirms each of the 6 fixes on the device

🤖 Generated with Claude Code

@qodo-code-review
Copy link
Copy Markdown

ⓘ You've reached your Qodo monthly free-tier limit. Reviews pause until next month — upgrade your plan to continue now, or link your paid account if you already have one.

JohnMcLear and others added 3 commits May 12, 2026 09:04
… + X-Frame fallback + https:// auto-prefix

Six device-test issues from real-hardware run:

1. Dialogs (AddWorkspace / OpenPad / etc.) overflowed phone viewports —
   DialogShell width now `min(${width}px, calc(100vw - 16px))` so a 420
   panel caps at viewport-16 on phones. Tighter padding under 480px.
2. Bare hostname URLs were rejected — AddWorkspaceDialog auto-prefixes
   `https://` when the input has no `://` scheme.
3. (Same as #1 — OpenPadDialog uses DialogShell.)
4. "Black screen" on pad open — likely X-Frame-Options DENY/SAMEORIGIN
   from the server. PadIframeStack now starts a 6s timeout per iframe;
   if no onLoad fires, an opaque overlay surfaces with an "Open in
   browser" button that hands the URL off to @capacitor/browser.
5. Status bar overlapped the rail — shell-root-wrapper now applies
   `env(safe-area-inset-*)` padding. Zero visual change on desktop;
   stops mobile WebView from drawing under the status bar / notch.
6. Newly added workspaces didn't appear in the rail — mobile platform's
   `events.onWorkspacesChanged` was a noop. workspace-store now owns
   a tiny listener Set; CapacitorPlatform wires it through so the
   shell's `onWorkspacesChanged` handler in App.tsx receives the new
   `{workspaces, order}` after every add / update / remove / reorder.

DialogShell width-test dropped (jsdom can't parse CSS `min()`; behaviour
is exercised in Playwright on real Chromium).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-history + Ctrl-K hint + tests

Round 2 of device feedback:

- App icons: regenerated all five mipmap densities + adaptive foregrounds
  from packages/desktop/build/icons/icon-512.png. The Capacitor default
  icon is gone; Etherpad branding everywhere.
- Removed the always-visible PadActionsOverlay (share is redundant with
  Etherpad's own UI; the "open in browser" button forced over content).
- Collapse handle now flush to left edge, 14px wide (was 22 + 3px gap),
  right-flat border so it reads as a tab sticking out.
- Tab.open auto-collapses the workspace rail (mobile UX) — fires only on
  the open event, doesn't fight subsequent manual expands.
- Tab.open upserts pad-history so QuickSwitcher's name search finds the
  pad. Wired events.onPadHistoryChanged through.
- Settings.userName threads into the iframe src as `&userName=` so the
  user's name applies to existing + new pads (Etherpad reads the query
  param at join time).
- "Tip: Ctrl+K opens this from anywhere" hidden via `@media (pointer:
  coarse)` — touch devices can't issue keyboard shortcuts anyway.
- Tests: 8 mobile Playwright cases now (added 3 — auto-collapse,
  pad-history populate, userName in src). X-Frame detection removed
  (Chromium fires onLoad even for blocked iframes; needs the native
  WebChromeClient hook in Phase 6b).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ging

- Edge-swipe right from left edge expands the rail; swipe left from
  inside collapses it. Touch-only — doesn't fire when a dialog is open
  (dialogs handle their own gestures).
- Android hardware/gesture back: dismiss open dialog first, else collapse
  rail, else minimise the app. Mirrors stock Android navigation expectations.
- padHistory.upsert errors now log to console.warn instead of being
  swallowed by `void`. Earlier logcat confirmed upsert is firing and
  writing 'Jehejej' to SharedPreferences as expected.
@JohnMcLear JohnMcLear force-pushed the feat/mobile-phase7-responsive-android-fixes branch from 2be8bbb to fa0dd22 Compare May 12, 2026 08:05
@JohnMcLear JohnMcLear merged commit 374f598 into main May 12, 2026
6 of 7 checks passed
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