'use strict'; // Home: "Pick up where you left off" (Continue watching and Continue listening), shown above the day's agenda in the evening and below it in the morning. async function homeResume(el) { if (!el) return; const bits = await Promise.allSettled([ allowed('video') ? (async () => { const st = await jfetch('/api/plex/status'); if (!st.signedIn || !st.server) return ''; px.serverKey = st.server; const items = ((await px.get('/library/onDeck?X-Plex-Container-Start=0&X-Plex-Container-Size=8')).Metadata || []).filter(m => m.type === 'movie' || m.type === 'episode').slice(0, 6); return items.length ? `

Continue watching

${items.map(m => vdCard(m, true)).join('')}
` : ''; })() : '', allowed('audio') ? (async () => { const [data] = await Promise.all([abApi('/books'), abLoadProg()]), books = Array.isArray(data) ? data : (data.books || Object.values(data)); const cont = books.filter(b => { const p = abProg[abId(b)]; return p && p.pos > 10 && p.dur && p.pos < p.dur - 30; }).sort((a, b) => abProg[abId(b)].t - abProg[abId(a)].t).slice(0, 6); today.books = cont; return cont.length ? `

Continue listening

${cont.map(b => { const p = abProg[abId(b)], pc = Math.min(100, p.pos / p.dur * 100); return `${pc > 1 ? `` : ''}${esc(abTitle(b))}${esc(abAuthor(b))}`; }).join('')}
` : ''; })() : '', ]); const html = bits.map(b => b.status === 'fulfilled' ? b.value : '').join(''); if (!html || !el.isConnected) return; el.innerHTML = `

Pick up where you left off

${html}`; el.querySelectorAll('a[data-book]').forEach(a => a.onclick = e => { e.preventDefault(); const b = (today.books || []).find(x => abId(x) === a.dataset.book); if (b) abSheet(b); }); } const today = { books: [] };