Files
EventSnap/frontend/src/lib/diashow/wakelock.ts
MechaCat02 8a769b52bf feat(diashow): live slideshow with two-queue policy + pluggable transitions
A fullscreen auto-advancing slideshow any user can start. Design:
docs/CONCEPT_DIASHOW.md.

- lib/diashow/queue.ts: SlideQueue state machine — liveQueue drains first
  (FIFO, seeded by SSE upload-processed), then shuffleQueue (refilled
  from allKnown minus a 5-id ring buffer of recently shown). Pure logic,
  unit-testable.
- lib/diashow/wakelock.ts: Screen Wake Lock wrapper that re-acquires on
  visibility change (the OS drops the lock when the tab hides).
- lib/diashow/transitions/{index,crossfade,kenburns}.ts: registry +
  the v1 transitions. Adding a new animation is one file + one entry —
  the extensibility target from docs/FEATURES §2.9.
- routes/diashow/+page.svelte: fullscreen page, hides bottom nav,
  6 s default dwell (3/6/10 configurable), keyboard shortcuts
  (Escape exits, Space toggles pause), tap-to-reveal overlay with
  pause / dwell / transition / exit. Respects $dataMode to choose
  preview vs. original URL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 14:32:55 +02:00

55 lines
1.5 KiB
TypeScript

// Thin wrapper around the Screen Wake Lock API. Held by the diashow page so a phone
// driving a projector doesn't sleep. No-op on unsupported browsers (Firefox, older
// Safari).
//
// Wake locks die when the document goes hidden; the page re-acquires on visible to
// keep the screen on across short interruptions.
interface SentinelLike {
release: () => Promise<void>;
}
let sentinel: SentinelLike | null = null;
let visibilityHandler: (() => void) | null = null;
export async function acquireWakeLock(): Promise<void> {
const wakeLock = (navigator as Navigator & { wakeLock?: { request: (t: string) => Promise<SentinelLike> } }).wakeLock;
if (!wakeLock) return;
try {
sentinel = await wakeLock.request('screen');
} catch {
// User denied, or already released — nothing useful to do.
sentinel = null;
}
// Re-acquire when the page becomes visible again (the OS releases the lock
// while the tab is hidden).
if (!visibilityHandler) {
visibilityHandler = async () => {
if (document.visibilityState === 'visible' && sentinel === null) {
try {
sentinel = await wakeLock.request('screen');
} catch {
sentinel = null;
}
}
};
document.addEventListener('visibilitychange', visibilityHandler);
}
}
export async function releaseWakeLock(): Promise<void> {
if (sentinel) {
try {
await sentinel.release();
} catch {
// ignore — release after release is fine
}
sentinel = null;
}
if (visibilityHandler) {
document.removeEventListener('visibilitychange', visibilityHandler);
visibilityHandler = null;
}
}