feat: backup/restore, user profile popover, image compress, video blur, wake lock
- backup/restore dialog + user profile popover components - image compression, video blur, wake lock utilities - message cache + conversation messages hook refinements - call context, active speakers, screen share dialog tweaks - audio + screen share settings persistence - refreshed app icons (smaller sizes) across all platforms
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
// 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<void>;
|
||||
addEventListener: (event: string, fn: () => void) => void;
|
||||
}
|
||||
|
||||
interface WakeLockNavigator {
|
||||
wakeLock?: {
|
||||
request: (type: 'screen') => Promise<WakeLockSentinelLike>;
|
||||
};
|
||||
}
|
||||
|
||||
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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user