Skip to content

fix: Android Chrome mobile — workspace panel close + profile dropdown visibility - #256

Closed
nesquena-hermes wants to merge 2 commits into
masterfrom
fix/android-chrome-mobile-ux
Closed

fix: Android Chrome mobile — workspace panel close + profile dropdown visibility#256
nesquena-hermes wants to merge 2 commits into
masterfrom
fix/android-chrome-mobile-ux

Conversation

@nesquena-hermes

Copy link
Copy Markdown
Collaborator

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() in boot.js now also shows/hides the mobile overlay when toggling the right panel (sharing the overlay with the left sidebar, correctly tracking which panel is open)
  • New closeMobileFiles() helper closes the right panel and hides the overlay only if the left sidebar is also closed
  • mobileOverlay onclick updated to call both closeMobileSidebar() and closeMobileFiles()
  • A .mobile-close-btn button added to the workspace panel header, visible only on mobile (display:none on desktop, display:inline-flex at max-width:900px)

Fix 2 — Issue #246: profile dropdown clipped by overflow-x:auto on mobile

Problem: On mobile, .topbar-chips has overflow-x:auto which creates a stacking context that clips the absolutely-positioned .profile-dropdown even with z-index:200. The dropdown opened but was invisible.

Fix: At max-width:900px, the .profile-dropdown switches to position: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

…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.
@nesquena

Copy link
Copy Markdown
Owner

Full Review: PR #256 — Android Chrome mobile fixes

Security Audit

Clean. Frontend-only changes: mobile overlay logic, close button, and CSS. No new endpoints, no user data handling.

Code Review

Mobile overlay coordination (boot.js):
toggleMobileFiles() now properly shows/hides the mobile overlay in sync with the right panel. The "only hide overlay if left sidebar is also closed" guard is correct — prevents the overlay from disappearing when closing the files panel while the sidebar is still open.

closeMobileFiles() is a dedicated close helper for the overlay tap-to-close handler. The overlay's onclick now calls both closeMobileSidebar();closeMobileFiles() — ensures both panels close on overlay tap.

Mobile close button (index.html):
New <button class="panel-icon-btn mobile-close-btn">×</button> in the workspace panel header. CSS: display:none by default, display:inline-flex at @media(max-width:640px). Clean progressive enhancement.

Profile dropdown fix (style.css):

.profile-dropdown{position:fixed;top:56px;right:8px;left:auto;max-width:calc(100vw - 16px);}

This is the correct fix for the overflow-x:auto clipping issue — position:fixed escapes the stacking context entirely. The top:56px aligns it below the topbar. max-width:calc(100vw - 16px) prevents overflow on narrow screens.

Stacked Branch

This includes PR #255's changes (config.py + test_model_resolver.py). After #255 merges, this will need a rebase.

Tests

574 passed, 0 failed.

Verdict

Approved. Both fixes are correct and well-scoped. Ready to merge after #255.

@nesquena-hermes

Copy link
Copy Markdown
Collaborator Author

Agent review — APPROVED WITH FIX ✅ (merged to stage)

Both Android Chrome fixes verified present:

  • closeMobileFiles() closes the right panel and correctly tracks overlay state
  • toggleMobileFiles() shows/hides the mobile overlay when opening/closing the workspace panel
  • mobileOverlay onclick calls both closeMobileSidebar() and closeMobileFiles()
  • Mobile-only close button (×) added to workspace panel header
  • .profile-dropdown uses position:fixed; top:56px; right:8px at max-width:900px, escaping the overflow-x:auto clipping context

Fix applied during review: closeMobileSidebar() originally removed the overlay unconditionally, which would hide it even if the right panel was still open. Fixed to check if the right panel is also closed before hiding the overlay — symmetric behavior with closeMobileFiles().

Browser tested (mobile simulation): closeMobileFiles() closes panel + hides overlay; closeMobileSidebar() with right panel open preserves overlay; all behaviors correct.

Tests: 625 passed on review branch. Stage total: 645 passed, 0 failed.
Merged to stage branch.

nesquena-hermes pushed a commit that referenced this pull request Apr 11, 2026
…#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
nesquena-hermes added a commit that referenced this pull request Apr 11, 2026
* 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>
@nesquena-hermes

Copy link
Copy Markdown
Collaborator Author

Merged to master via stage branch in PR #258 (v0.47.0).

@nesquena-hermes
nesquena-hermes deleted the fix/android-chrome-mobile-ux branch April 12, 2026 03:14
JKJameson pushed a commit to JKJameson/hermes-webui that referenced this pull request Apr 25, 2026
* 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>
SysAdminDoc pushed a commit to SysAdminDoc/hermes-webui that referenced this pull request Jun 26, 2026
* 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>
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.

Android Chrome: Files/Workspace sidebar opens but cannot be closed via X Android Chrome: Profile dropdown does not open / not selectable

2 participants