Plein écran : attente bornée, repli tourné si l'écran reste en portrait, paysage forcé en mode immersif ; plan : résultat et corrections de la recette
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
b8c2997ec0
commit
155a953c3b
+27
-6
@@ -52,6 +52,8 @@ const SLIDE_MS = 160;
|
||||
const PAUSE_MS = 120;
|
||||
/** Durée du bandeau « Reprendre l'ancienne ». */
|
||||
export const BANNER_MS = 10_000;
|
||||
/** Attente au plus de la réponse à une demande de plein écran. */
|
||||
const FULLSCREEN_WAIT_MS = 1000;
|
||||
|
||||
/** Le dernier plateau affiché, gardé pour le redessiner dès l'ouverture. */
|
||||
export interface CachedBoard {
|
||||
@@ -276,7 +278,12 @@ export function startApp(options: AppOptions): void {
|
||||
// ----------------------------------------------------------- Mise en page
|
||||
|
||||
function layout(): Layout {
|
||||
return rotatedActive() || landscapeQuery.matches ? "landscape" : "portrait";
|
||||
// Plein écran demandé (« le plateau est l'écran ») : paysage dès que
|
||||
// l'écran est plus large que haut, quelle que soit sa taille.
|
||||
const immersiveLandscape = immersive && !portraitQuery.matches;
|
||||
return rotatedActive() || landscapeQuery.matches || immersiveLandscape
|
||||
? "landscape"
|
||||
: "portrait";
|
||||
}
|
||||
|
||||
function rotatedActive(): boolean {
|
||||
@@ -970,25 +977,39 @@ export function startApp(options: AppOptions): void {
|
||||
// ------------------------------------------------- Plein écran (ADR 0012)
|
||||
|
||||
async function enterImmersive(): Promise<void> {
|
||||
// Certains navigateurs ne répondent jamais à la demande (Firefox sans
|
||||
// écran) : on n'attend pas plus d'une seconde, la vue paysage
|
||||
// s'applique quand même.
|
||||
try {
|
||||
await document.documentElement.requestFullscreen?.({ navigationUI: "hide" });
|
||||
await Promise.race([
|
||||
document.documentElement.requestFullscreen?.({ navigationUI: "hide" }),
|
||||
new Promise((resolve) => setTimeout(resolve, FULLSCREEN_WAIT_MS)),
|
||||
]);
|
||||
} catch {
|
||||
// Refusé : la vue paysage s'applique quand même.
|
||||
}
|
||||
let locked = false;
|
||||
let locked = false; // vrai : le navigateur a accepté de verrouiller
|
||||
try {
|
||||
const orientation = screen.orientation as unknown as {
|
||||
lock?: (orientation: string) => Promise<void>;
|
||||
};
|
||||
if (orientation.lock !== undefined) {
|
||||
await orientation.lock("landscape");
|
||||
await Promise.race([
|
||||
orientation.lock("landscape"),
|
||||
new Promise((_, reject) => setTimeout(reject, FULLSCREEN_WAIT_MS)),
|
||||
]);
|
||||
locked = true;
|
||||
}
|
||||
} catch {
|
||||
// Verrouillage refusé : repli par rotation CSS ci-dessous.
|
||||
}
|
||||
// Verrouillage accepté : l'écran tourne dans l'instant. S'il est
|
||||
// toujours en portrait (navigateur qui accepte sans tourner), repli.
|
||||
for (let i = 0; locked && portraitQuery.matches && i < 6; i++) {
|
||||
await new Promise((resolve) => setTimeout(resolve, 100));
|
||||
}
|
||||
immersive = true;
|
||||
rotated = !locked && portraitQuery.matches;
|
||||
rotated = portraitQuery.matches;
|
||||
render();
|
||||
}
|
||||
|
||||
@@ -1000,10 +1021,10 @@ export function startApp(options: AppOptions): void {
|
||||
} catch {
|
||||
// Rien à déverrouiller.
|
||||
}
|
||||
render();
|
||||
if (document.fullscreenElement) {
|
||||
await document.exitFullscreen().catch(() => undefined);
|
||||
}
|
||||
render();
|
||||
}
|
||||
|
||||
// Sortie du plein écran par le retour du téléphone : la vue revient.
|
||||
|
||||
Reference in New Issue
Block a user