CI / Build & Quality Checks (push) Skipped
CI / Secret scan (gitleaks) (push) Skipped
CI / Playwright smoke (e2e) (push) Skipped
CI / Build & Quality Checks (pull_request) Successful in 3m31s
CI / Trigger Desktop Build (pull_request) Skipped
CI / Docker image build & smoke test (pull_request) Skipped
CI / Secret scan (gitleaks) (pull_request) Successful in 11s
CI / Playwright smoke (e2e) (pull_request) Successful in 18m48s
Landscape, at most 500px tall, touch input (a sideways phone is ~840px wide, the Tablet size class, so the trigger is the screen shape), in this room's joined call, chat closed: the call takes the whole screen. No room header, sidebar or call-status bar; safe-area insets respected. - Taps inside the call frame never reach the app, so while the controls are hidden a transparent layer covers the call: the first tap shows the call bar plus Chat / Exit full screen, which hide again after 4 s without a touch; with them up the call underneath stays usable. - In an Android browser tab the first tap also enters the browser's own full screen (hides the address bar); left again on rotate back, hang up or exit. No effect on iPhone or the installed app. - Exit full screen lasts until the phone is upright again. - The frame is transparent (room wallpaper), so in full screen it gets an opaque base colour under the wallpaper. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017PCb59uY3UKqDqt7B6hzd5
42 lines
1.5 KiB
TypeScript
42 lines
1.5 KiB
TypeScript
/**
|
|
* [Gitea #126] Phone turned sideways in a call: the call takes the whole
|
|
* screen. A phone in landscape is ~840px wide (the "Tablet" size class), so
|
|
* the trigger is the shape of the screen, not the size class: landscape, at
|
|
* most 500px tall, touch input. Tablets and desktops never match.
|
|
*/
|
|
export const LANDSCAPE_PHONE_QUERY =
|
|
'(orientation: landscape) and (max-height: 500px) and (pointer: coarse)';
|
|
|
|
/** Controls hide again after this long without a touch on them. */
|
|
export const CONTROLS_AUTOHIDE_MS = 4000;
|
|
|
|
export type ImmersiveInputs = {
|
|
landscapePhone: boolean;
|
|
/** This room's call is the one we are in, and we have joined it. */
|
|
joinedHere: boolean;
|
|
/** The in-call chat is open (it replaces the call on small screens). */
|
|
chatOpen: boolean;
|
|
/** "Exit full screen" was pressed since the phone was last upright. */
|
|
dismissed: boolean;
|
|
};
|
|
|
|
/** Pure: whether the call should be full screen. */
|
|
export const shouldGoImmersive = (i: ImmersiveInputs): boolean =>
|
|
i.landscapePhone && i.joinedHere && !i.chatOpen && !i.dismissed;
|
|
|
|
/**
|
|
* Pure: use the browser's own full-screen mode too? Only where an address bar
|
|
* takes room: an Android browser tab (not the installed app / iOS, which have
|
|
* none or don't support it), when the page isn't already full screen.
|
|
*/
|
|
export const wantsBrowserFullscreen = (env: {
|
|
userAgent: string;
|
|
standalone: boolean;
|
|
fullscreenEnabled: boolean;
|
|
alreadyFullscreen: boolean;
|
|
}): boolean =>
|
|
/Android/i.test(env.userAgent) &&
|
|
!env.standalone &&
|
|
env.fullscreenEnabled &&
|
|
!env.alreadyFullscreen;
|