diff --git a/public/app.js b/public/app.js index ec69e4d..775707b 100644 --- a/public/app.js +++ b/public/app.js @@ -128,7 +128,8 @@ function route() { try { editor?.destroyEditor(); } catch {} editor = null; document.body.classList.toggle('editing', name === 'edit'); - document.body.classList.remove('inedit'); + document.body.classList.remove('inedit', 'onaudio'); + const aw = $('#audiowrap'); if (aw) aw.className = 'off'; // hide (not destroy) the audiobooks frame renderNav(name === 'edit' ? 'files' : name); routes[name](rest.map(decodeURIComponent)); $('#view').scrollTop = 0; @@ -465,11 +466,18 @@ function viewAudio() { const url = cfg.audiobooks, c = abCreds(); $('#view').innerHTML = `
`; + // Create the frame once and keep it: it is only shown/hidden, never rebuilt, so playback carries on across tabs. + const wrap = $('#audiowrap'); + if (!wrap.firstChild) { + const f = document.createElement('iframe'); + f.src = url; f.title = 'Audiobooks'; f.allow = 'autoplay; fullscreen; picture-in-picture; clipboard-write'; + wrap.appendChild(f); + } + wrap.className = 'on'; document.body.classList.add('onaudio'); const copy = async (v, what) => { try { await navigator.clipboard.writeText(v); toast(what + ' copied. Paste it into the sign-in box.'); } catch { toast('Could not copy'); } }; const cu = $('#cu'), cp = $('#cp'); if (cu) cu.onclick = () => copy(c.u, 'Username'); diff --git a/public/index.html b/public/index.html index d1428d1..f2cb97e 100644 --- a/public/index.html +++ b/public/index.html @@ -17,7 +17,7 @@