Skip to content

fix(pwa): Menu button hidden behind Dynamic Island and viewport scrolling not locked on iOS PWA #264

@shuv1337

Description

@shuv1337

Problem/Context

After the latest upstream merge (v1.1.1), the PWA mobile layout has regressed with two critical issues on iOS devices:

Issue 1: Menu Button Hidden Behind Dynamic Island

On the "Recent Projects" home screen, the hamburger menu button is positioned too high and is hidden behind the iPhone Dynamic Island safe area. This makes it impossible to access the sidebar menu on mobile PWA.

Location: packages/app/src/pages/home.tsx:35-41

<div class="xl:hidden absolute top-0 left-0 p-2">
  <IconButton
    icon="menu"
    variant="ghost"
    onClick={layout.mobileSidebar.toggle}
  />
</div>

The top-0 positioning doesn't account for safe-area-inset-top in PWA standalone mode.

Issue 2: Viewport Not Locked in Session View

When inside a session, the viewport is not properly locked. Users can continue scrolling past all visible elements until the screen shows only blank space. This is a fundamental PWA UX issue that breaks the native app-like experience.

Acceptance Criteria

  • Menu button on home screen is fully visible and tappable below the Dynamic Island
  • Menu button on session header is fully visible and tappable below the Dynamic Island
  • Viewport is locked in session view - no scrolling past content boundaries
  • Consistent behavior across all screens in PWA standalone mode
  • No regression on desktop/browser experience
  • Works on iPhone 14 Pro and newer (Dynamic Island devices)
  • Works on older iPhones with notch

Implementation Details

Technical Approach

  1. Fix Menu Button Positioning

    • Apply pt-safe-top or top: calc(8px + var(--safe-area-inset-top)) to menu button containers
    • Ensure CSS from packages/app/src/index.css PWA media queries are properly applied
  2. Fix Viewport Locking

    • Add overflow: hidden to appropriate container elements
    • Consider touch-action: none on scroll containers in PWA mode
    • Ensure height: 100dvh is used instead of 100vh for proper iOS behavior
    • Add overscroll-behavior: contain to prevent overscroll bouncing

Code References

File Line Issue
packages/app/src/pages/home.tsx 34-41 Menu button lacks safe area offset
packages/app/src/pages/session.tsx 803 Root container overflow handling
packages/app/src/pages/session.tsx 878 Scroll container may allow overscroll
packages/app/src/pages/layout.tsx 1156 Main content area overflow
packages/app/src/index.css 90-121 PWA standalone mode styles
packages/app/src/components/session/session-header.tsx 50-57 Session header menu button
packages/app/index.html 7 Viewport meta tag configuration

Existing PWA Infrastructure

We already have safe area CSS variables defined in packages/app/src/index.css:

:root {
  --safe-area-inset-top: env(safe-area-inset-top, 0px);
  --safe-area-inset-bottom: env(safe-area-inset-bottom, 0px);
  /* ... */
}

@media (display-mode: standalone) {
  header[data-tauri-drag-region] {
    padding-top: var(--safe-area-inset-top);
    min-height: calc(3rem + var(--safe-area-inset-top));
  }
}

The issue is that:

  1. Home page menu button doesn't use a header[data-tauri-drag-region] element
  2. Session view scroll containers may have changed during upstream merge

Related Prior Work

Tasks

  • Add safe area top offset to home page menu button (packages/app/src/pages/home.tsx)
  • Verify session header menu button respects safe area (packages/app/src/components/session/session-header.tsx)
  • Fix viewport locking in session view scroll containers
  • Add overscroll-behavior: contain to prevent iOS bounce scrolling past content
  • Consider adopting upstream's h-dvh change from PR Fix a few mobile screen size issues anomalyco/opencode#6808
  • Test on iOS Safari PWA (iPhone with Dynamic Island)
  • Test on older iPhone models with notch
  • Verify no desktop regression

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions