Repository navigation
Description
Problem
Seen in TestFlight 1.8.0 (1541) on iPhone. When Labstream cold-launches into the restricted Offline surface (#259), the "Offline mode" banner is pinned to the top of the screen and covers the navigation bar:
- The large Offline title is clipped to its bottom half on the first frame.
- The navigation bar's Sign In and Settings toolbar buttons are hidden behind the banner on iPhone and iPad, so the only ways to sign in again or open Settings are not visible.
- The secondary line ("Your server could not be reached. Completed downloads remain available.") wraps onto 2–3 lines on iPhone. At accessibility text sizes the banner fills about 40% of the screen and "Reconnect" hyphenates to "Recon-/nect".
Root cause
Labstream/Shared/UI/OfflineLaunchView.swift mounts offlineStatusBanner with .safeAreaInset(edge: .top) outside the NavigationStack. On iOS/iPadOS the inset is added above the stack's content, but the navigation bar still lays out at the top of the window, so the banner (.regularMaterial) sits on top of the bar's inline row and the top of the large title. The banner is also a separate, one-off status pattern: OfflineLibraryView already shows inline notice rows (startup-recovery "Retry Recovery", upgrade notice "Dismiss") in a different layout.
Per-platform findings
Reproduced headlessly with a local DEBUG-only --ui-testing --ui-testing-fixture offline launch, which mounts OfflineLaunchView directly with no server. Screenshots are kept locally (gitignored artifacts/agent-sim-runs/offline-banner/) and are not uploaded.
| Platform | Banner visible? | Result |
|---|---|---|
| iPhone (iOS 27 sim) | Yes | Large title clipped; Sign In/Settings hidden; copy wraps to 3 lines; at AX sizes the banner takes ~40% of the screen and the title is gone. Matches the TestFlight report. |
| iPad (iPadOS 27 sim) | Yes | Large title not clipped (the bar is taller), but Sign In/Settings are still hidden under the banner. Single-line copy. |
| visionOS (27 sim) | No | Title and Sign In/Settings ornaments render, but the banner is not visible at all. The user gets no offline explanation and no Reconnect control. |
| macOS | Not verified | The host session's screen was locked, so no window could be captured. From the code, the same safeAreaInset sits below the unified titlebar/toolbar, so overlap is less likely, but the copy and pattern are the same. Needs a run on an unlocked host. |
| tvOS | N/A | Streaming-only: ContentView compiles the Offline surface out and routes .offline to LoginView. No banner exists. |
Proposed direction
Replace the free-floating top inset with a platform-native status treatment that never overlaps navigation chrome:
- Keep the offline state inside the navigation hierarchy, either as a navigation subtitle plus a toolbar Reconnect action, or as the first row of the Offline list using the same notice-row pattern as the existing recovery/upgrade notices. Do not inset it outside the
NavigationStack. - Shorten the copy to a context line that never wraps (for example "Server unreachable"). The longer explanation can go in the accessibility label or a details affordance.
- Make it visible on visionOS (it is currently missing) and confirm macOS.
- Have one notice-row pattern shared by offline / startup-recovery / upgrade-notice states, so color and button style carry one meaning each.
HTML mockups of 2–3 options are being reviewed before implementation.
Acceptance
- iPhone (default and AX text sizes): no overlap with title or toolbar; Sign In and Settings reachable.
- iPad: same.
- visionOS: offline state and Reconnect visible.
- macOS: verified on an unlocked host via
scripts/deploy-macos-to-host.sh. - tvOS unaffected (no Offline surface).
- A DEBUG
offlineUI fixture is kept so this surface can be screenshot-tested headlessly.
Activity
jlipworth commentedon Oct 18, 2026
Implemented option A in 4dc82ed (merged into
downloads/overhaul, notmain):Server unreachableis a navigation subtitle under the Offline title. Reconnect is a prominent toolbar button next to Sign In and Settings, and its accessibility hint has the full explanation.safeAreaInsetbanner is gone.--ui-testing-fixture offline(DEBUG, not tvOS) mounts the surface without a server. The new mobile UI testtestOfflineLaunchKeepsToolbarActionsReachableasserts Reconnect, Sign In and Settings stay hittable.Verified headlessly:
ci-hygienepass.Left open until physical acceptance on the next internal TestFlight build, plus a macOS visual check.
Move the Offline mode status into navigation chrome (Fixes #415)
jlipworth commentedon Nov 5, 2026
Landed on
mainin #425 (0b7f3fcb, tagv1.8.0). Any device or live acceptance gate already noted here still applies; the issue stays open until it's checked.