From d6a925cf1121cd3ec253afdec906b703fcb01c61 Mon Sep 17 00:00:00 2001 From: nesquena-hermes Date: Sun, 12 Apr 2026 00:41:52 -0700 Subject: [PATCH] feat(mobile): add Profiles button to mobile bottom navigation (#265) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds a Profiles button as the last item in the mobile bottom nav bar, making the Profiles panel reachable on mobile without opening the sidebar. Fixes from original PR: - Uses mobileSwitchPanel('profiles') not the broken two-call approach - data-panel='profiles' attribute present for active-highlight state - SVG 20x20 stroke-width 1.5 matching all other mobile nav icons - Placed last (Chat → Tasks → Skills → Memory → Spaces → Profiles) - 3 new tests in test_mobile_layout.py covering presence, handler, and order Tests: 700 passed (up from 697) Co-authored-by: @gabogabucho Co-authored-by: Nathan Esquenazi --- static/index.html | 4 ++++ tests/test_mobile_layout.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/static/index.html b/static/index.html index ea14cd7..b39963e 100644 --- a/static/index.html +++ b/static/index.html @@ -481,6 +481,10 @@ Spaces +
diff --git a/tests/test_mobile_layout.py b/tests/test_mobile_layout.py index 2d41ba6..952c138 100644 --- a/tests/test_mobile_layout.py +++ b/tests/test_mobile_layout.py @@ -175,3 +175,34 @@ def test_composer_textarea_font_size_mobile(): # Check for 16px font-size on the textarea in a mobile breakpoint assert re.search(r'font-size:16px', CSS), \ "Composer textarea must have font-size:16px at mobile widths to prevent iOS zoom-on-focus" + + + +# ── Profiles button in mobile bottom nav ───────────────────────────────────── + +def test_mobile_profiles_button_present(): + """Mobile bottom nav must include a Profiles button (PR #265).""" + assert 'data-panel="profiles"' in HTML and 'mobileSwitchPanel' in HTML, \ + "Mobile nav must have a Profiles button with data-panel='profiles' and mobileSwitchPanel" + + +def test_mobile_profiles_button_uses_mobileSwitchPanel(): + """Profiles mobile nav button must use mobileSwitchPanel, not raw switchPanel.""" + import re + match = re.search( + r']*mobile-nav-btn[^>]*data-panel="profiles"[^>]*>|' + r']*data-panel="profiles"[^>]*mobile-nav-btn[^>]*>', + HTML + ) + assert match, "Could not find mobile-nav-btn with data-panel='profiles'" + btn_html = HTML[match.start():match.start()+300] + assert "mobileSwitchPanel('profiles')" in btn_html, \ + "Profiles mobile nav button must call mobileSwitchPanel('profiles')" + + +def test_mobile_profiles_button_is_last_in_nav(): + """Profiles button must appear after Spaces in the mobile bottom nav.""" + spaces_pos = HTML.find('data-panel="workspaces"') + profiles_pos = HTML.rfind('data-panel="profiles"') + assert spaces_pos > 0 and profiles_pos > spaces_pos, \ + "Profiles button must appear after Spaces button in the mobile nav"