feat(reader): podcast episode prev/next on the transport row's outer buttons

User design (round 3): one set of big buttons does the big navigation.
The outer prev/next step buttons were chapter-only even on podcasts,
while episode nav hid as small icons in the top-left cluster. Now:

- Podcasts (sequence context present): the outer buttons navigate
  EPISODES via goToPrev/goToNextEpisode (progress pushed before the
  hop); disabled ghost buttons at the first/last episode keep the row
  shape. Embedded-chapter jumps stay on the Chapter pill's list.
- Books: unchanged chapter stepping.
- Keyboard (h/l shortcuts) and hardware media keys (MediaTrackPrev/
  Next) funnel through stepChapter, which is now sequence-aware —
  headset next-track = next episode on podcasts.
- The top-left episode icons are gone; the 'Ep N/M' counter stays.
- Help-modal labels say 'chapter, or episode on podcasts'.

Same icons both modes (extracted audioStepPrev/NextIcon partials);
books are untouched — no sequence context, byte-identical behavior.
This commit is contained in:
John O'Keefe committed 2026-10-30 12:46:36 -04:00
1 parent ace9e57d27
commit b293741eb1
5 files changed
+387 -219

No files matched your search

+10
View File
@@ -664,6 +664,16 @@ Alpine.data("audioReader", () => ({
},
stepChapter(delta: 1 | -1) {
// Podcast sequence context: the chapter-step buttons AND every
// route that funnels through here (arrow-key/media-key shortcuts,
// hardware headset prev/next track) navigate EPISODES — one set of
// big buttons does the big navigation (round-3 user design,
// 2026-10-30). Edge episodes are server-gated (no url → no-op).
if (readConfig().podcastSequence) {
if (delta === -1) this.goToPrevEpisode();
else this.goToNextEpisode(false);
return;
}
const next = this.currentChapterIdx + delta;
if (next < 0 || next >= this.chapters.length) return;
this.jumpToChapter(next);