// Screen wake-lock for active calls. WebKit + WebView2 both ship the // Screen Wake Lock API (tauri 2.x). Browsers release the sentinel when // the page becomes hidden, so we re-acquire on visibilitychange while a // call is active. interface WakeLockSentinelLike { release: () => Promise; addEventListener: (event: string, fn: () => void) => void; } interface WakeLockNavigator { wakeLock?: { request: (type: 'screen') => Promise; }; } let sentinel: WakeLockSentinelLike | null = null; let active = false; let visibilityBound = false; function hasWakeLock(): boolean { return typeof navigator !== 'undefined' && !!(navigator as unknown as WakeLockNavigator).wakeLock; } async function acquire(): Promise { if (sentinel || !hasWakeLock()) return; try { const s = await (navigator as unknown as WakeLockNavigator).wakeLock!.request('screen'); sentinel = s; s.addEventListener('release', () => { sentinel = null; // If still active (released by the browser because we went hidden), // wait for visibility and re-request. }); } catch (err: unknown) { // Permission denied, document not visible, etc. Harmless — the call // still works, the user's screen may dim. Log once. console.warn('wakeLock request failed', err); } } async function release(): Promise { if (!sentinel) return; try { await sentinel.release(); } catch { /* already released */ } sentinel = null; } function onVisibility(): void { if (!active) return; if (document.visibilityState === 'visible') { void acquire(); } } // Called from CallContext when the call enters a state that should keep // the screen awake (connected / connecting). Toggle off again when the // call ends. export async function setCallWakeLock(on: boolean): Promise { active = on; if (on) { if (!visibilityBound) { document.addEventListener('visibilitychange', onVisibility); visibilityBound = true; } await acquire(); } else { if (visibilityBound) { document.removeEventListener('visibilitychange', onVisibility); visibilityBound = false; } await release(); } }