Zoom is now baked into the canvas render scale instead of being applied
via CSS zoom. CSS zoom only scales pixels already on the canvas, causing
blurriness at high DPR (e.g. PWA on mobile). Now the canvas is rendered
at the correct resolution for the chosen zoom level.
Also: stop nulling currentPdfDoc on re-render so PDF.js page cache is
preserved, making zoom re-renders significantly faster.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The 📻 button now opens a sidebar with the currently playing station/track,
play/stop + volume control, and the saved stations list. The old focus
station configuration UI (presets, custom URL input, save-to-server) and
the auto-play-on-book-open behavior are removed.
Closes#6
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Spread mode: new toggle in reader settings renders pages side-by-side
(cover alone, then pairs 2-3, 4-5...) using full screen width. Each
page scales to half the container. Navigation and scroll position
tracking are unchanged since per-page IDs are preserved.
Pinch-to-zoom: captures 2-finger pinch on the PDF reader, blocking
native browser zoom. Live CSS zoom during gesture, snaps to nearest
10% step on release. Single-finger scroll unaffected. applyPdfZoom
moved to module level so touch handlers can call it. Touch listeners
cleaned up on reader close.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Hide volume label/slider/input on mobile (≤600px)
- Add − and + buttons flanking the PDF zoom slider
- Preserve scroll fraction across zoom changes in PDF scroll mode
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
After opening a book, a 5-second timer adds body.reader-immersive which:
- Slides navbar up (translateY(-100%))
- Slides now-playing bar down (translateY(100%))
- Expands reader overlay to full viewport (top:0, bottom:0)
- Collapses reader header (max-height:0)
Mouse near top edge (<60px): shows navbar + reader header
Mouse near bottom edge (<60px): shows now-playing bar
Touch at top/bottom edge: shows respective bar for 3s then hides again
closeReader() cleans up all classes and event listeners
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add render generation counter (_pdfRenderGen) to abort overlapping renders
- Wrap all pages in #pdf-viewport div; zoom slider just updates style.zoom
- Use 'input' event on zoom slider for live preview without re-rendering
- enterPdfPaginatedMode resets viewport zoom to 1; exitPdfPaginatedMode restores it
- Remove pdfZoom factor from renderPdf scale (CSS zoom handles it now)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove max-width:100% from .pdf-page so canvas can exceed container width
- Override max-width:65ch on .pdf-page-wrapper (inherited from reader-content > *)
- Apply pdfZoom factor in pdfSmartZoomPage so paginated mode respects the zoom slider
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Feed title in inbox and queue is now a link that opens the feed's episode list
- Episode title in inbox is now clickable and opens the show notes sidebar
- Backend: include description in inbox API response so sidebar has content
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Auto-play next episode from queue when current episode ends
- Sleep timer (N minutes or end-of-episode) with countdown in button
- In-feed episode filter (client-side search)
- Auto-queue new episodes per feed (⚡Q toggle, inserts at top of queue)
- More playback speeds: 1¾× and 2½× added
- Progress bars + structured meta line in all episode list views (feed, inbox, queue)
- Queue drag-and-drop reorder
- Feed list search filter and sort options (A–Z, Z–A, recently added/refreshed)
- DB migration: PodcastFeed.auto_queue, EpisodeProgress.dismissed
- Inbox: dismiss episodes without marking played, checkboxes for multi-select,
bulk actions (add to queue, mark played, download, dismiss), load-more pagination
- Refresh button in single feed view header
- Hourly background refresh of all subscribed feeds
- Full Media Session API for radio and podcast: Windows taskbar thumbnail buttons
(play/pause/stop/next/seek) now work correctly for both modes
- Playing an episode auto-adds it to the queue if not already there
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>