fix(offline): keep the offline banner off the full-screen player

Every other shell rule in layoutShell.ts already treats /player/* as
immersive; the amber "You're offline" strip was the one piece of chrome
still rendered above it. On the native Android video path that is not
cosmetic: VideoPlayer makes itself transparent so the ExoPlayer
SurfaceView behind the WebView is visible (DR-185), so a shell child that
still paints shows through the picture as a stripe across the top of the
film. Offline is also precisely when a downloaded video plays, so the
banner appeared when it was most in the way — and it offers the viewer
nothing to act on, since local playback needs no server.

The rule moves into the pure module as showOfflineBanner() rather than
staying an inline {#if} in the shell, so the immersive-route contract is
stated in one tested place.

TRACES: UR-003, UR-043 | DR-291 | UT-255
This commit is contained in:
2026-09-22 21:08:03 -04:00
parent 0f928798d7
commit b98cbfe28a
4 changed files with 70 additions and 4 deletions
+23
View File
@@ -129,3 +129,26 @@ export function showBottomUi(input: BottomUiVisibilityInput): boolean {
export function shellReservesBottomInset(input: BottomUiVisibilityInput): boolean {
return !showBottomUi(input);
}
/**
* Whether the shell renders the offline banner ("You're offline…").
*
* The banner is shell chrome, and it is the last piece of it that still
* rendered over the full-screen player — every other rule in this module
* already treats `/player/*` as immersive. On the native Android video path
* that is not merely untidy: VideoPlayer makes itself transparent so the
* ExoPlayer SurfaceView behind the WebView can be seen (DR-185), so any shell
* element that still paints shows through the film. Offline is also exactly
* when a downloaded video plays, so the banner was most likely to be there
* precisely when it was most in the way — and it says nothing the viewer can
* act on while watching: local playback needs no server.
*
* TRACES: UR-003, UR-043 | DR-291
*/
export function showOfflineBanner({
pathname,
isAuthenticated,
isConnected,
}: BottomUiVisibilityInput & { isConnected: boolean }): boolean {
return isAuthenticated && !isConnected && !pathname.startsWith("/player/");
}