Home: Hörbücher als eigener Block, ihre Kapitel nicht unter Podcasts

Ein laufendes Kapitel steht mit „Kapitel i/n · <Buch>“ unter Hörbücher, sonst
das zuletzt gehörte Buch mit ▶ Weiterhören (audiobooks.js __dioraAudiobookGo).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrwnslz 2026-10-16 14:42:20 +02:00
parent 838457f6f9
commit b21f59f4eb
2 changed files with 33 additions and 2 deletions

View file

@ -503,6 +503,9 @@
if (box && fresh) box.innerHTML = fresh.innerHTML; if (box && fresh) box.innerHTML = fresh.innerHTML;
}); });
// Home's "Weiterhören" card (home.js) plays the book from where it was left.
window.__dioraAudiobookGo = feedId => goOn(feedId);
// ---- following the player ------------------------------------------------------------ // ---- following the player ------------------------------------------------------------
let pollTimer = 0; let pollTimer = 0;

View file

@ -91,7 +91,7 @@
card = podCard('Läuft auf ' + (r.device || 'einem anderen Gerät'), r.title || '', r.feed || '', r.artwork || '', card = podCard('Läuft auf ' + (r.device || 'einem anderen Gerät'), r.title || '', r.feed || '', r.artwork || '',
r.dur ? (r.dur - (r.pos || 0)) / 1000 : 0, r.dur ? (r.pos || 0) / r.dur : 0, r.dur ? (r.dur - (r.pos || 0)) / 1000 : 0, r.dur ? (r.pos || 0) / r.dur : 0,
'<button type="button" class="btn btn-sm" data-act="pod-here">Hier weiterhören</button>'); '<button type="button" class="btn btn-sm" data-act="pod-here">Hier weiterhören</button>');
} else if (player.kind === 'podcast') { } else if (player.kind === 'podcast' && !player.book) { // an audiobook's chapter: under Hörbücher
const left = player.dur ? (player.dur - (player.pos || 0)) / 1000 : 0; const left = player.dur ? (player.dur - (player.pos || 0)) / 1000 : 0;
card = podCard(player.playing ? 'Läuft gerade' : 'Weiterhören', player.title, player.feed, player.artwork, left, card = podCard(player.playing ? 'Läuft gerade' : 'Weiterhören', player.title, player.feed, player.artwork, left,
player.dur ? (player.pos || 0) / player.dur : 0, player.dur ? (player.pos || 0) / player.dur : 0,
@ -239,6 +239,33 @@
// ---- page --------------------------------------------------------------------- // ---- page ---------------------------------------------------------------------
// ---- Hörbücher (static/js/audiobooks.js) -------------------------------------------
function audiobookSection() {
const h = podHost();
if (!h || !document.getElementById('tab-audiobooks') || !window.__dioraAudiobookGo) return '';
const player = h.playerState ? parse(h.playerState(), {}) || {} : {};
let books = [];
try { books = JSON.parse(localStorage.getItem('diora_ab_books') || '[]') || []; } catch (e) {}
let card;
if (player.kind === 'podcast' && player.book) {
const b = player.book;
const left = player.dur ? (player.dur - (player.pos || 0)) / 1000 : 0;
card = podCard((player.playing ? 'Läuft gerade' : 'Weiterhören') + ' · Kapitel ' + (b.index + 1) + '/' + b.chapters,
player.title, b.title || player.feed, player.artwork, left, player.dur ? (player.pos || 0) / player.dur : 0,
'<button type="button" class="btn btn-sm home-play" data-act="' + (player.playing ? 'pod-pause' : 'pod-resume') +
'" data-id="' + esc(player.episodeId) + '">' + (player.playing ? '■ Pause' : '▶ Weiter') + '</button>');
} else {
const b = books.filter(x => x.next && x.last_played_at)[0];
if (!b) return '';
card = podCard('Weiterhören · Kapitel ' + (b.next.index + 1) + '/' + b.chapters, b.title, b.author || '',
b.artwork_url, b.total_seconds ? b.total_seconds - b.heard_seconds : 0,
b.total_seconds ? b.heard_seconds / b.total_seconds : 0,
'<button type="button" class="btn btn-sm home-play" data-act="ab-go" data-id="' + esc(b.feed_id) + '">▶ Weiterhören</button>');
}
return section('Hörbücher', card, 'audiobooks');
}
function section(title, body, tabName) { function section(title, body, tabName) {
return '<section class="home-section"><div class="home-head"><h2>' + esc(title) + '</h2>' + return '<section class="home-section"><div class="home-head"><h2>' + esc(title) + '</h2>' +
'<button type="button" class="home-more" data-act="tab" data-tab="' + tabName + '">Alle ›</button></div>' + body + '</section>'; '<button type="button" class="home-more" data-act="tab" data-tab="' + tabName + '">Alle ›</button></div>' + body + '</section>';
@ -256,7 +283,7 @@
} }
let html = '<div class="home-brand">diora</div>'; let html = '<div class="home-brand">diora</div>';
refreshFeeds(3 * 60000); refreshFeeds(3 * 60000);
for (const part of [booksSection, podcastSection, feedsSection, radioSection, ambientSection]) { for (const part of [booksSection, audiobookSection, podcastSection, feedsSection, radioSection, ambientSection]) {
try { html += part(); } catch (e) { console.warn('home', e); } try { html += part(); } catch (e) { console.warn('home', e); }
} }
if (html !== lastHtml) { if (html !== lastHtml) {
@ -293,6 +320,7 @@
if (q) h.podcastPlayEpisode(JSON.stringify(q), 0); if (q) h.podcastPlayEpisode(JSON.stringify(q), 0);
} else if (act === 'pod-resume' && h) h.podcastPlay(Number(el.dataset.id)); } else if (act === 'pod-resume' && h) h.podcastPlay(Number(el.dataset.id));
else if (act === 'pod-pause' && h) h.podcastToggle(); else if (act === 'pod-pause' && h) h.podcastToggle();
else if (act === 'ab-go' && window.__dioraAudiobookGo) window.__dioraAudiobookGo(Number(el.dataset.id));
else if (act === 'pod-here' && h && h.playerTakeOver) h.playerTakeOver(); else if (act === 'pod-here' && h && h.playerTakeOver) h.playerTakeOver();
else if (act === 'pod-open') { else if (act === 'pod-open') {
if (window.__dioraOpenPlayer && h && parse(h.playerState(), {}).kind) window.__dioraOpenPlayer('podcast'); if (window.__dioraOpenPlayer && h && parse(h.playerState(), {}).kind) window.__dioraOpenPlayer('podcast');