fix: Android Chrome mobile — workspace panel close + profile dropdown visibility - #256
fix: Android Chrome mobile — workspace panel close + profile dropdown visibility#256nesquena-hermes wants to merge 2 commits into
Conversation
…Router When base_url is configured, resolve_model_provider() now trusts the configured provider/base_url and skips the slash-based OpenRouter heuristic. Fixes the case where model: google/gemma-4-26b-a4b with provider: custom would be silently routed to OpenRouter, resulting in 401 errors. Fixes #230
…own visibility Fixes #247: toggleMobileFiles() now shows/hides the mobile overlay and a new closeMobileFiles() helper closes the right panel. The overlay's onclick now calls both closeMobileSidebar() and closeMobileFiles(). A mobile-only close button is added to the workspace panel header. Fixes #246: profile dropdown no longer clipped by overflow-x:auto on mobile. At max-width:900px the dropdown uses position:fixed below the topbar (top:56px, right:8px), escaping the overflow stacking context.
Full Review: PR #256 — Android Chrome mobile fixesSecurity AuditClean. Frontend-only changes: mobile overlay logic, close button, and CSS. No new endpoints, no user data handling. Code ReviewMobile overlay coordination (
Mobile close button ( Profile dropdown fix ( .profile-dropdown{position:fixed;top:56px;right:8px;left:auto;max-width:calc(100vw - 16px);}This is the correct fix for the Stacked BranchThis includes PR #255's changes (config.py + test_model_resolver.py). After #255 merges, this will need a rebase. Tests574 passed, 0 failed. VerdictApproved. Both fixes are correct and well-scoped. Ready to merge after #255. |
|
Agent review — APPROVED WITH FIX ✅ (merged to stage) Both Android Chrome fixes verified present:
Fix applied during review: Browser tested (mobile simulation): Tests: 625 passed on review branch. Stage total: 645 passed, 0 failed. |
…#256) Fix #247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix #246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes #247 Fixes #246
* fix: custom provider with slash model name no longer rerouted to OpenRouter (#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes #230 * test: mobile layout regression suite — 14 tests for every QA run (#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes #248 * feat: shared app dialogs replace native confirm()/prompt() calls (#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR #242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (#256) Fix #247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix #246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes #247 Fixes #246 * feat: session ⋯ action dropdown replaces per-row buttons (#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR #242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
|
Merged to master via stage branch in PR #258 (v0.47.0). |
* fix: custom provider with slash model name no longer rerouted to OpenRouter (nesquena#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes nesquena#230 * test: mobile layout regression suite — 14 tests for every QA run (nesquena#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (nesquena#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes nesquena#248 * feat: shared app dialogs replace native confirm()/prompt() calls (nesquena#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR nesquena#242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (nesquena#256) Fix nesquena#247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix nesquena#246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes nesquena#247 Fixes nesquena#246 * feat: session ⋯ action dropdown replaces per-row buttons (nesquena#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR nesquena#242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
* fix: custom provider with slash model name no longer rerouted to OpenRouter (nesquena#255) When base_url is configured in config.yaml, resolve_model_provider() now trusts the configured provider/base_url entirely and skips the slash-based OpenRouter heuristic. Fixes google/gemma-4-26b-a4b with provider:custom being silently routed to OpenRouter, resulting in 401 errors. Fixes nesquena#230 * test: mobile layout regression suite — 14 tests for every QA run (nesquena#254) Adds tests/test_mobile_layout.py with 14 static regression tests that run on every QA pass to catch mobile layout breakage before it reaches prod. Covers: breakpoints at 900px/640px, right panel slide-over CSS, mobile overlay, bottom nav, files button, profile dropdown z-index, chip overflow, workspace close, 100dvh, 44px touch targets, 16px font-size on textarea. * feat: /skills slash command lists and filters available Hermes skills (nesquena#257) Adds /skills [query] command to commands.js. Fetches from /api/skills, groups by category (alphabetically sorted), displays as a formatted assistant message. Optional query filters by name, description, or category. i18n keys added for en, de, zh, zh-Hant. 1 regression test added. Fixes nesquena#248 * feat: shared app dialogs replace native confirm()/prompt() calls (nesquena#251) Adds showConfirmDialog() and showPromptDialog() helpers to ui.js, backed by a themed #appDialogOverlay. Replaces all 11 native browser confirm/prompt call sites across panels.js, sessions.js, ui.js, workspace.js. Supports: danger mode, keyboard focus trap (Tab/Escape/Enter), focus restore, ARIA roles, mobile-responsive stacked buttons at 640px. i18n for en/de/zh/zh-Hant. 5 new tests in test_sprint33.py verify markup, CSS, helpers, and absence of native dialog calls. Extracted from PR nesquena#242. * fix: Android Chrome mobile — workspace panel close + profile dropdown (nesquena#256) Fix nesquena#247: toggleMobileFiles() now shows/hides the mobile overlay when toggling the right workspace panel. New closeMobileFiles() helper closes the panel with correct overlay state tracking. Overlay onclick calls both closeMobileSidebar() and closeMobileFiles(). Mobile-only close button (x) added to workspace panel header. Fix nesquena#246: profile dropdown uses position:fixed;top:56px;right:8px at max-width:900px, escaping the overflow-x:auto stacking context that was clipping it on Android Chrome. Fix applied during review: closeMobileSidebar() now checks if the right panel is still open before hiding the overlay, preventing the overlay from disappearing when only the sidebar is closed. Fixes nesquena#247 Fixes nesquena#246 * feat: session ⋯ action dropdown replaces per-row buttons (nesquena#252) Replaces the 5 per-row hover action buttons (pin/move/archive/duplicate/trash) with a single ⋯ trigger that opens a positioned dropdown menu. Menu has full keyboard (Escape), click-outside, scroll, and resize-reposition handling. Position:fixed prevents sidebar clipping. 5 actions: Pin/Unpin, Move to project, Archive/Unarchive, Duplicate, Delete (danger style). Each with icon and descriptive subtitle. Updated test_sprint16.py: test_sessions_js_uses_action_menu_not_per_row_buttons asserts the new trigger and menu functions exist, old per-row classes are gone. Extracted from PR nesquena#242. * docs: v0.47.0 release notes, bump version, update test counts (645) --------- Co-authored-by: Nathan Esquenazi <nesquena@gmail.com>
Summary
Two Android Chrome mobile fixes bundled together.
Fix 1 — Issue #247: workspace panel cannot be closed on Android Chrome
Problem: Tapping the folder button opens the right workspace panel via
toggleMobileFiles(), but there was no way to close it. The X button (btnClearPreview) only closes the file preview, not the panel. The mobile overlay only closed the left sidebar.Fix:
toggleMobileFiles()inboot.jsnow also shows/hides the mobile overlay when toggling the right panel (sharing the overlay with the left sidebar, correctly tracking which panel is open)closeMobileFiles()helper closes the right panel and hides the overlay only if the left sidebar is also closedmobileOverlayonclick updated to call bothcloseMobileSidebar()andcloseMobileFiles().mobile-close-btnbutton added to the workspace panel header, visible only on mobile (display:noneon desktop,display:inline-flexatmax-width:900px)Fix 2 — Issue #246: profile dropdown clipped by overflow-x:auto on mobile
Problem: On mobile,
.topbar-chipshasoverflow-x:autowhich creates a stacking context that clips the absolutely-positioned.profile-dropdowneven withz-index:200. The dropdown opened but was invisible.Fix: At
max-width:900px, the.profile-dropdownswitches toposition:fixed; top:56px; right:8px— this escapes the overflow clip entirely and positions the dropdown below the topbar, fully visible regardless of the overflow on its ancestor.Tests
624 passed, 0 failed, 0 skipped (CSS/JS changes, existing mobile regression tests pass)
Fixes #247
Fixes #246