REVAMP : Firefox handling
All checks were successful
release / build (push) Successful in 25s
release / verify-windows (push) Successful in 1m15s

This commit is contained in:
jeanotx32
2026-08-12 01:46:14 +02:00
parent 3bd4d5f2ba
commit 77bfa0b8c5
14 changed files with 1223 additions and 108 deletions

View File

@@ -1,13 +1,14 @@
import { EventEmitter } from 'node:events';
import type {
AgentEvent,
FullscreenSettings,
LogLevel,
StreamState,
WatchSettings,
WatchState,
} from '@stream-control/shared';
import { emptyWatchState, fetchStripchatStatus } from '@stream-control/shared';
import { sendHotkey } from './hotkey.ts';
import { describeFullscreen, type FullscreenOutcome } from './fullscreen.ts';
export interface ProbeResult {
/** Statut brut renvoyé par la plateforme. */
@@ -28,6 +29,15 @@ export interface WatchActions {
resumeRecording(): Promise<void>;
/** Clôture définitive : ferme aussi la fenêtre du navigateur si elle est pilotée. */
stopRecording(): Promise<void>;
/**
* Rappelle le plein écran du lecteur.
*
* Injecté plutôt qu'appelé en direct : selon le mode de pilotage, c'est une
* touche envoyée au serveur d'affichage ou une commande WebDriver adressée à
* Firefox. Le surveillant n'a pas à connaître cette différence — il sait
* seulement que le flux public est revenu.
*/
restoreFullscreen(settings: FullscreenSettings): Promise<FullscreenOutcome>;
}
/**
@@ -347,20 +357,25 @@ export class StreamWatcher extends EventEmitter {
if (this.fullscreenTimer) clearTimeout(this.fullscreenTimer);
this.fullscreenTimer = setTimeout(() => {
this.fullscreenTimer = null;
void this.restoreFullscreen();
// L'échec est déjà journalisé par restoreFullscreen ; le rattraper ici
// évite un rejet non géré pour une erreur dont on a déjà rendu compte.
void this.restoreFullscreen().catch(() => undefined);
}, this.settings.fullscreen.delayMs);
this.fullscreenTimer.unref?.();
}
async restoreFullscreen(): Promise<{ method: string; window?: string }> {
const { key, windowMatch } = this.settings.fullscreen;
async restoreFullscreen(): Promise<FullscreenOutcome> {
const fullscreen = this.settings.fullscreen;
try {
const result = await sendHotkey({ key, windowMatch });
const result = await this.actions.restoreFullscreen(fullscreen);
// Un `confirmed: false` n'est pas un échec de commande : la demande est
// partie, la page ne l'a pas suivie. Le distinguer permet de la relire
// dans l'historique sans la confondre avec une erreur de configuration.
this.emit(
'log',
'info',
`Plein écran rappelé : touche « ${key} » envoyée à « ${result.window ?? windowMatch} »`,
'fullscreen.restored',
result.confirmed === false ? 'warn' : 'info',
describeFullscreen(result, fullscreen.key),
result.confirmed === false ? 'fullscreen.failed' : 'fullscreen.restored',
);
return result;
} catch (err) {