47 lines
3.5 KiB
JavaScript
47 lines
3.5 KiB
JavaScript
'use strict';
|
|
// ---- Audiobooks: embedded site. Sign-in details saved in Settings (this browser only) can be copied with one tap,
|
|
// because a page can't type into another site's login form.
|
|
const abCreds = () => store.get('ab_creds', { u: '', p: '' });
|
|
// Podcast Admin (Verse by Verse): the site refuses to be framed (X-Frame-Options), so this is a launcher.
|
|
function viewVerse() {
|
|
const url = cfg.verse, host = new URL(url).host;
|
|
$('#view').innerHTML = `<div class="wrap"><h1>Podcast Admin</h1><p class="sub">${esc(host + new URL(url).pathname)}</p>
|
|
<div class="card" style="max-width:none"><p style="margin-top:0">This site doesn't allow being shown inside another app, so it opens in its own tab.</p>
|
|
<div class="bar"><a class="btn" href="${esc(url)}" target="_blank" rel="noopener">${icon('book')}Open admin</a></div></div></div>`;
|
|
}
|
|
|
|
// Frames that must keep running (audio) live outside #view: created once, then only shown or hidden.
|
|
function showFrame(key, url, title, allow) {
|
|
const wrap = $('#audiowrap');
|
|
let f = wrap.querySelector(`iframe[data-k="${key}"]`);
|
|
if (!f) { f = document.createElement('iframe'); f.dataset.k = key; f.src = url; f.title = title; f.allow = allow; wrap.appendChild(f); }
|
|
wrap.querySelectorAll('iframe').forEach(x => x.classList.toggle('act', x === f));
|
|
wrap.className = 'on'; document.body.classList.add('onaudio');
|
|
}
|
|
|
|
// The frame is created once and kept alive, so playback carries on while you use other tabs.
|
|
// It loads /api/audiobooks/enter, where the server adds the site's secret sign-in link itself (the key never reaches this page).
|
|
const ENTER = '/api/audiobooks/enter';
|
|
function viewAudio() {
|
|
const c = abCreds(), old = $('#audiowrap iframe[data-k="audio"]');
|
|
$('#view').innerHTML = `<div class="abbar"><span class="grow"><b>Audiobooks</b><small id="abst">${old ? '' : 'Opening…'}</small></span>
|
|
${c.u ? `<button class="ibtn" id="cu" aria-label="Copy username" title="Copy username">${icon('copy')}</button>` : ''}
|
|
<button class="ibtn" id="ar" aria-label="Reload" title="Reload">${icon('refresh')}</button>
|
|
<button class="ibtn" id="af" aria-label="Full screen" title="Full screen">${icon('full')}</button>
|
|
<a class="ibtn" href="${ENTER}" target="_blank" rel="noopener" aria-label="Open in new tab" title="Open in new tab">${icon('ext')}</a></div>`;
|
|
const setSt = t => { const e = $('#abst'); if (e) e.textContent = t; };
|
|
const open = fresh => {
|
|
setSt('Opening…');
|
|
let f = $('#audiowrap iframe[data-k="audio"]'); if (f) f.remove();
|
|
showFrame('audio', ENTER + (fresh ? '?t=' + Date.now() : ''), 'Audiobooks', 'autoplay; fullscreen; picture-in-picture; clipboard-write; encrypted-media');
|
|
f = $('#audiowrap iframe[data-k="audio"]'); f.referrerPolicy = 'no-referrer';
|
|
let done = false;
|
|
f.addEventListener('load', () => { done = true; setSt(''); });
|
|
setTimeout(() => { if (!done) setSt('Still loading… if it stays blank, tap the arrow to open it in its own tab'); }, 10000);
|
|
};
|
|
if (!old) open(false); else { showFrame('audio', '', 'Audiobooks', ''); setSt(''); }
|
|
$('#ar').onclick = () => open(true);
|
|
$('#af').onclick = () => { const f = $('#audiowrap iframe[data-k="audio"]'); if (f && f.requestFullscreen) f.requestFullscreen().catch(() => toast('Full screen is not available here')); else toast('Full screen is not available here'); };
|
|
const cu = $('#cu'); if (cu) cu.onclick = async () => { try { await navigator.clipboard.writeText(c.u); toast('Username copied. Password is in Settings.'); } catch { toast('Could not copy'); } };
|
|
}
|