From 17e85fb63108df2bd2a11b26292afc616ea74cfe Mon Sep 17 00:00:00 2001 From: Alexan Hayrapetyan Date: Fri, 22 May 2026 14:22:46 -0700 Subject: [PATCH] feat(demo): keep screen awake during conversion --- public/demo.html | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/public/demo.html b/public/demo.html index 727a0ce..3936381 100644 --- a/public/demo.html +++ b/public/demo.html @@ -184,6 +184,8 @@

About

let sourceBase = 'document'; let currentUserCode = null; let currentBlobUrl = null; + let conversionWakeLock = null; + let conversionActive = false; const $ = (id) => document.getElementById(id); const show = (id) => { $(id).hidden = false; }; @@ -226,6 +228,29 @@

About

try { const j = await res.json(); return (j.error && j.error.message) || res.statusText; } catch { return res.statusText; } } + async function acquireConversionWakeLock() { + if (!('wakeLock' in navigator) || document.visibilityState !== 'visible' || conversionWakeLock) return; + try { + conversionWakeLock = await navigator.wakeLock.request('screen'); + conversionWakeLock.addEventListener('release', () => { conversionWakeLock = null; }); + } catch { + // Wake Lock is best-effort: unsupported browsers or denied requests should not block conversion. + } + } + async function startConversionWakeLock() { + conversionActive = true; + await acquireConversionWakeLock(); + } + async function stopConversionWakeLock() { + conversionActive = false; + if (!conversionWakeLock) return; + const lock = conversionWakeLock; + conversionWakeLock = null; + try { await lock.release(); } catch {} + } + document.addEventListener('visibilitychange', () => { + if (conversionActive && document.visibilityState === 'visible') void acquireConversionWakeLock(); + }); // ----- Step 1: GitHub device flow ----- $('signin-btn').addEventListener('click', startDeviceFlow); @@ -312,6 +337,7 @@

About

setError(''); const files = $('images').files; if (!files.length) { setError('Please choose at least one image.'); return; } + await startConversionWakeLock(); // Output download name mirrors the uploaded file. sourceBase = (files[0].name.replace(/\.[^.]+$/, '').replace(/[^A-Za-z0-9._-]/g, '_')) || 'document'; const fd = new FormData(); @@ -329,6 +355,7 @@

About

announce('Starting… ' + d.image_count + ' page(s) uploaded.'); pollStatus(); } catch (e) { + await stopConversionWakeLock(); setError('Upload failed: ' + e.message); } finally { btn.removeAttribute('aria-busy'); @@ -353,6 +380,7 @@

About

if (d && d.status === 'ready_for_review') { announce('Done! Your accessible HTML is ready.'); + await stopConversionWakeLock(); try { await showResult(d); } catch (e) { @@ -361,6 +389,7 @@

About

return; // terminal — stop polling } if (d && d.status === 'failed') { + await stopConversionWakeLock(); setError('Conversion failed: ' + (d.error || 'unknown error') + '. You can try again.'); hide('status-section'); show('upload-section'); focusHeading('step2-h'); return; // terminal — stop polling @@ -412,6 +441,7 @@

About

setError(''); const fb = $('feedback-text').value.trim(); if (!fb) { setError('Please enter some feedback first.'); return; } + await startConversionWakeLock(); try { const res = await api('/sessions/' + sessionId + '/feedback', { method: 'POST', headers: { 'content-type': 'application/json' }, @@ -423,6 +453,7 @@

About

announce('Re-running with your feedback…'); pollStatus(); } catch (e) { + await stopConversionWakeLock(); setError('Could not submit feedback: ' + e.message); } });