2026-03-16 19:19:22 +01:00
{% extends "base.html" %}
{% block title %}diora — radio player{% endblock %}
{% block content %}
<!-- ===== NOW PLAYING BAR ===== -->
< section class = "now-playing-bar" id = "now-playing-bar" >
< div class = "now-playing-info" >
< span class = "now-playing-station" id = "now-playing-station" > — no station —< / span >
< span class = "now-playing-track" id = "now-playing-track" > < / span >
< / div >
< div class = "now-playing-controls" >
2026-03-16 20:38:08 +01:00
< button class = "btn btn-play" id = "play-stop-btn" onclick = "togglePlayStop()" style = "display:none;" > ▶ Play< / button >
2026-03-16 19:19:22 +01:00
< label class = "volume-label" >
< span > vol< / span >
2026-03-16 21:07:12 +01:00
< input type = "range" id = "volume" min = "0" max = "255" value = "204" class = "volume-slider" >
< input type = "number" id = "volume-num" min = "0" max = "255" value = "204" class = "volume-num" >
2026-03-16 19:19:22 +01:00
< / label >
< button class = "btn btn-save" id = "save-station-btn" style = "display:none;" onclick = "saveCurrentStation()" > ★ Save< / button >
2026-03-16 20:18:39 +01:00
< button class = "btn-icon" id = "dnd-btn" onclick = "toggleDND()" title = "Focus mode (hides UI, press Esc to exit)" > ⊙< / button >
2026-04-05 14:22:07 +02:00
< button class = "btn-icon" id = "focus-station-btn" onclick = "openRadioSidebar()" title = "Radio" > 📻< / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / div >
< div class = "podcast-seek-bar" id = "podcast-seek-bar" style = "display:none;" >
< button class = "btn-icon skip-btn" onclick = "skipBack()" title = "Back 15s" > ⏪  15< / button >
< span class = "seek-time" id = "seek-current" > 0:00< / span >
< input type = "range" id = "seek-slider" class = "seek-slider" min = "0" max = "100" value = "0" >
< span class = "seek-time" id = "seek-duration" > 0:00< / span >
< button class = "btn-icon skip-btn" onclick = "skipForward()" title = "Forward 30s" > 30  ⏩< / button >
< div class = "speed-btns" id = "speed-btns" >
< button class = "speed-btn" onclick = "setPlaybackRate(0.75)" > ¾×< / button >
< button class = "speed-btn active" onclick = "setPlaybackRate(1)" > 1× < / button >
< button class = "speed-btn" onclick = "setPlaybackRate(1.25)" > 1¼× < / button >
< button class = "speed-btn" onclick = "setPlaybackRate(1.5)" > 1½× < / button >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< button class = "speed-btn" onclick = "setPlaybackRate(1.75)" > 1¾× < / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< button class = "speed-btn" onclick = "setPlaybackRate(2)" > 2× < / button >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< button class = "speed-btn" onclick = "setPlaybackRate(2.5)" > 2½× < / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / div >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< button class = "btn-icon sleep-timer-btn" id = "sleep-timer-btn" onclick = "openSleepTimerMenu()" title = "Sleep timer" > Sleep< / button >
2026-03-16 19:19:22 +01:00
< / div >
< div class = "timer-widget" id = "timer-widget" >
< span class = "timer-phase" id = "timer-phase-label" > focus< / span >
< span class = "timer-display" id = "timer-display" > 25:00< / span >
< button class = "btn-icon" id = "timer-toggle-btn" onclick = "toggleTimer()" title = "Start/pause timer" > ▶< / button >
< button class = "btn-icon" id = "timer-reset-btn" onclick = "resetTimer()" title = "Reset timer" > ↺< / button >
< span class = "focus-today" id = "focus-today-widget" style = "display:none;" > < / span >
< button class = "btn-icon dnd-only" id = "dnd-light-btn" onclick = "toggleDNDLight()" title = "Toggle black background" > 💡< / button >
< / div >
< / section >
<!-- ===== AFFILIATE / TRACK INFO ===== -->
2026-03-16 20:47:02 +01:00
< section class = "affiliate-section" id = "affiliate-section" style = "display:none;" { % if not amazon_enabled % } data-disabled = "true" { % endif % } >
2026-03-16 19:19:22 +01:00
< img class = "affiliate-artwork" id = "affiliate-artwork" src = "" alt = "Album art" >
< div class = "affiliate-info" >
< div class = "affiliate-track" id = "affiliate-track-name" > < / div >
< div class = "affiliate-artist" id = "affiliate-artist-name" > < / div >
< div class = "affiliate-album" id = "affiliate-album-name" > < / div >
< a class = "btn btn-amazon" id = "affiliate-amazon-link" href = "#" target = "_blank" rel = "noopener noreferrer" >
Buy on Amazon Music
< / a >
< / div >
< / section >
<!-- ===== TABS ===== -->
< div class = "tabs" id = "tabs" >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< button class = "tab-btn active" onclick = "showTab('radio')" > Radio< / button >
2026-03-16 19:19:22 +01:00
< button class = "tab-btn" onclick = "showTab('focus')" > Focus< / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< button class = "tab-btn" onclick = "showTab('podcasts')" > Podcasts< / button >
< button class = "tab-btn" onclick = "showTab('books')" > Books< / button >
2026-03-16 19:19:22 +01:00
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
<!-- ===== RADIO TAB ===== -->
< section class = "tab-panel" id = "tab-radio" >
< div class = "tabs sub-tabs" id = "radio-sub-tabs" >
2026-03-19 19:43:23 +01:00
< button class = "tab-btn" onclick = "showRadioTab('search')" > Search< / button >
< button class = "tab-btn active" onclick = "showRadioTab('saved')" > Saved< / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< button class = "tab-btn" onclick = "showRadioTab('history')" > History< / button >
2026-03-16 19:19:22 +01:00
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
<!-- ===== SEARCH SUB - PANEL ===== -->
2026-03-19 19:43:23 +01:00
< div class = "sub-tab-panel" id = "tab-search" style = "display:none;" >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< div class = "search-bar" >
< input type = "text" id = "search-input" class = "search-input" placeholder = "Search radio-browser.info…" onkeydown = "if(event.key==='Enter') doSearch()" >
< button class = "btn" onclick = "doSearch()" > Search< / button >
2026-03-16 19:19:22 +01:00
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< div class = "mood-chips" id = "mood-chips" > < / div >
< div id = "curated-lists" class = "curated-lists-container" > < / div >
< div id = "search-status" class = "status-msg" > < / div >
< table class = "data-table" id = "search-results-table" style = "display:none;" >
2026-03-16 19:19:22 +01:00
< thead >
< tr >
< th > Name< / th >
< th > Bitrate< / th >
< th > Country< / th >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< th > Tags< / th >
2026-03-16 19:19:22 +01:00
< th > < / th >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / tr >
< / thead >
< tbody id = "search-results-body" > < / tbody >
< / table >
< / div >
<!-- ===== SAVED SUB - PANEL ===== -->
2026-03-19 19:43:23 +01:00
< div class = "sub-tab-panel" id = "tab-saved" >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
{% if featured_stations %}
< div class = "featured-section" >
< p class = "featured-label" > ★ Featured< / p >
< ul class = "featured-list" >
{% for s in featured_stations %}
< li >
{% if s.favicon_url %}< img src = "{{ s.favicon_url }}" class = "station-favicon" alt = "" > {% endif %}
< button class = "btn btn-sm" onclick = "playStation('{{ s.url|escapejs }}', '{{ s.name|escapejs }}', null)" >
▶ {{ s.name }}
< / button >
{% if s.description %}< span class = "muted" > {{ s.description }}< / span > {% endif %}
< / li >
{% endfor %}
< / ul >
< / div >
{% endif %}
{% if user.is_authenticated %}
< div id = "recommendations" class = "recommendations-section" >
<!-- populated by JS -->
< / div >
< div class = "import-bar" >
< label class = "btn btn-sm" for = "m3u-file-input" title = "Import .m3u / .m3u8 from the desktop app" >
⇧ Import M3U
< / label >
< input type = "file" id = "m3u-file-input" accept = ".m3u,.m3u8" style = "display:none;" onchange = "importM3U(this)" >
< span id = "import-status" class = "muted" > < / span >
< / div >
< table class = "data-table" id = "saved-table" >
< thead >
< tr >
< th > ★ < / th >
< th > Name< / th >
< th > Bitrate< / th >
< th > Country< / th >
< th title = "Notes" > ✎< / th >
< th > < / th >
< th > < / th >
< / tr >
< / thead >
< tbody id = "saved-tbody" >
{% for station in saved_stations %}
< tr id = "saved-row-{{ station.id }}" data-id = "{{ station.id }}" data-url = "{{ station.url }}" data-name = "{{ station.name }}" >
< td >
< button class = "btn-icon fav-btn {% if station.is_favorite %}active{% endif %}"
onclick="toggleFav({{ station.id }})"
title="Toggle favorite">★ < / button >
< / td >
< td class = "station-name-cell" > {{ station.name }}< / td >
< td > {{ station.bitrate }}< / td >
< td > {{ station.country }}< / td >
< td class = "notes-cell" onclick = "editNotes({{ station.id }}, this.textContent.trim())" title = "{{ station.notes|default:'' }}" style = "cursor:pointer; color:#666; max-width:120px; overflow:hidden; text-overflow:ellipsis; white-space:nowrap;" > {{ station.notes }}< / td >
< td >
< button class = "btn btn-sm"
onclick="playStation('{{ station.url }}', '{{ station.name|escapejs }}', {{ station.id }})">
▶ Play
< / button >
< / td >
< td >
< button class = "btn btn-sm btn-danger"
onclick="removeStation({{ station.id }})">
Remove
< / button >
< / td >
< / tr >
{% empty %}
< tr id = "saved-empty-row" > < td colspan = "7" class = "empty-msg" > No saved stations yet.< / td > < / tr >
{% endfor %}
< / tbody >
< / table >
{% else %}
< p class = "auth-prompt" >
< a href = "{% url 'login' %}" > Log in< / a > or < a href = "{% url 'register' %}" > register< / a >
to save stations and sync across devices.
< / p >
{% endif %}
< / div >
<!-- ===== HISTORY SUB - PANEL ===== -->
< div class = "sub-tab-panel" id = "tab-history" style = "display:none;" >
< table class = "data-table" id = "history-table" >
< thead >
< tr >
< th > Time< / th >
< th > Station< / th >
< th > Track< / th >
< th > ♬ < / th >
2026-03-16 19:19:22 +01:00
< th > < / th >
< / tr >
< / thead >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< tbody id = "history-tbody" >
{% for entry in history %}
< tr data-id = "{{ entry.id }}" >
< td class = "history-time" > {{ entry.played_at|slice:":16"|cut:"T" }}< / td >
< td > {{ entry.station_name }}< / td >
< td > {{ entry.track }}< / td >
< td > {% if entry.scrobbled %}< span title = "Scrobbled to Last.fm" > ✓ < / span > {% endif %}< / td >
< td > < button class = "btn-delete-history" onclick = "deleteHistoryEntry({{ entry.id }}, this)" title = "Remove" > ✕< / button > < / td >
2026-03-16 19:19:22 +01:00
< / tr >
{% empty %}
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< tr id = "history-empty-row" > < td colspan = "5" class = "empty-msg" > No history yet.< / td > < / tr >
2026-03-16 19:19:22 +01:00
{% endfor %}
< / tbody >
< / table >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / div >
2026-03-16 19:19:22 +01:00
< / section >
<!-- ===== FOCUS TAB ===== -->
< section class = "tab-panel" id = "tab-focus" style = "display:none;" >
< table class = "data-table" id = "focus-table" >
< thead >
< tr >
< th > Time< / th >
< th > Station< / th >
< th > Duration< / th >
< / tr >
< / thead >
< tbody id = "focus-tbody" >
< tr > < td colspan = "3" class = "empty-msg" > No focus sessions yet. Start the timer!< / td > < / tr >
< / tbody >
< / table >
< / section >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
<!-- ===== PODCASTS TAB ===== -->
< section class = "tab-panel" id = "tab-podcasts" style = "display:none;" >
{% if user.is_authenticated %}
< div class = "podcast-toolbar" >
< button class = "btn btn-sm" onclick = "showPodcastView('feeds')" > Feeds< / button >
< button class = "btn btn-sm" onclick = "showPodcastView('inbox')" > Inbox< / button >
< button class = "btn btn-sm" onclick = "showPodcastView('queue')" > Queue< / button >
< button class = "btn btn-sm" onclick = "podcastSearchOpen()" > + Search< / button >
2026-03-20 09:18:38 +01:00
< button class = "btn btn-sm" id = "refresh-all-btn" onclick = "refreshAllFeedsBtn(this)" title = "Refresh all feeds" > ↻ All< / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< label class = "btn btn-sm" for = "opml-file-input" > Import OPML< / label >
< input type = "file" id = "opml-file-input" accept = ".opml,.xml" style = "display:none;" onchange = "importOPML(this)" >
< span id = "opml-status" class = "muted" > < / span >
< / div >
<!-- Search pane -->
< div class = "podcast-pane" id = "podcast-search-pane" style = "display:none;" >
< div class = "search-bar" >
< input type = "text" id = "podcast-search-input" class = "search-input" placeholder = "Search podcasts…"
onkeydown="if(event.key==='Enter') doPodcastSearch()">
< button class = "btn" onclick = "doPodcastSearch()" > Search< / button >
< / div >
< div id = "podcast-search-status" class = "status-msg" > < / div >
< div id = "podcast-search-list" class = "podcast-search-list" > < / div >
< / div >
<!-- Feeds pane -->
< div class = "podcast-pane" id = "podcast-feeds-pane" >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< div class = "feed-list-toolbar" >
< input type = "text" id = "feed-filter-input" class = "search-input" placeholder = "Search subscriptions…"
oninput="filterFeeds(this.value)">
< select id = "feed-sort-select" onchange = "sortFeeds(this.value)" class = "feed-sort-select" >
< option value = "alpha" > A– Z< / option >
< option value = "alpha-desc" > Z– A< / option >
< option value = "added" > Recently added< / option >
2026-03-20 09:07:01 +01:00
< option value = "latest_episode" > Most recent episode< / option >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< / select >
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< div id = "podcast-feed-list" class = "podcast-feed-list" >
< p class = "muted" > Loading…< / p >
< / div >
< / div >
<!-- Inbox pane -->
< div class = "podcast-pane" id = "podcast-inbox-pane" style = "display:none;" >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< div class = "inbox-toolbar" >
< label class = "inbox-select-all-label" >
< input type = "checkbox" id = "inbox-select-all" onchange = "inboxSelectAll(this.checked)" >
< span > All< / span >
< / label >
< div class = "inbox-bulk-actions" id = "inbox-bulk-actions" style = "display:none;" >
< span id = "inbox-selection-count" class = "muted" > < / span >
< button class = "btn btn-sm" onclick = "inboxBulkQueueAdd()" > +Queue< / button >
< button class = "btn btn-sm" onclick = "inboxBulkMarkPlayed()" > ✓ Played< / button >
< button class = "btn btn-sm" onclick = "inboxBulkDownload()" > ⬇ Download< / button >
< button class = "btn btn-sm btn-danger" onclick = "inboxBulkDismiss()" > ✕ Dismiss< / button >
< / div >
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< div id = "podcast-inbox-list" class = "episode-list" > < / div >
2026-03-20 09:13:47 +01:00
< div class = "inbox-load-more" id = "inbox-load-more-bar" style = "display:none;" >
< button class = "btn btn-sm" onclick = "inboxLoadMore()" > Load more< / button >
< span id = "inbox-count-label" class = "muted" > < / span >
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / div >
<!-- Episodes pane -->
< div class = "podcast-pane" id = "podcast-episodes-pane" style = "display:none;" >
Add podcast enhancements: AntennaPod parity features + inbox management
- 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>
2026-03-20 08:55:11 +01:00
< div class = "episode-search-bar" id = "episode-search-bar" style = "display:none;" >
< input type = "text" id = "episode-filter-input" class = "search-input"
placeholder="Filter episodes…" oninput="filterEpisodes(this.value)">
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< div id = "podcast-feed-header" class = "podcast-feed-header" > < / div >
< div id = "podcast-episode-list" class = "episode-list" > < / div >
< / div >
<!-- Queue pane -->
< div class = "podcast-pane" id = "podcast-queue-pane" style = "display:none;" >
< ol id = "podcast-queue-ol" class = "podcast-queue-ol" > < / ol >
< / div >
{% else %}
< p class = "auth-prompt" >
< a href = "{% url 'login' %}" > Log in< / a > or < a href = "{% url 'register' %}" > register< / a >
to subscribe to podcasts.
< / p >
{% endif %}
< / section >
<!-- ===== BOOKS TAB ===== -->
< section class = "tab-panel" id = "tab-books" style = "display:none;" >
{% if user.is_authenticated %}
2026-03-19 22:16:22 +01:00
< div id = "book-upload-area" >
2026-03-19 21:29:51 +01:00
< div class = "book-drop-zone" id = "book-drop-zone" >
< span > Drop .epub or .pdf here or < label for = "book-file-input" style = "cursor:pointer;text-decoration:underline;" > browse< / label > < / span >
< input type = "file" id = "book-file-input" accept = ".epub,.pdf" style = "display:none;" onchange = "bookFileSelected(this)" >
< span id = "book-upload-status" class = "muted" > < / span >
< / div >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< / div >
< div id = "book-list" class = "book-list" > < / div >
{% else %}
< p class = "auth-prompt" >
< a href = "{% url 'login' %}" > Log in< / a > or < a href = "{% url 'register' %}" > register< / a >
to use the encrypted ebook reader.
< / p >
{% endif %}
< / section >
<!-- ===== READER OVERLAY ===== -->
< div id = "reader-overlay" class = "reader-overlay" style = "display:none;" >
< div class = "reader-header" >
< span id = "reader-title" class = "reader-title" > < / span >
< div class = "reader-header-actions" >
< span class = "reader-progress-wrap" >
< input type = "number" id = "reader-progress-input" class = "volume-num" min = "0" max = "100" value = "0" style = "display:none;" >
< span id = "reader-progress-suffix" class = "muted" > < / span >
< / span >
2026-05-31 15:41:35 +02:00
< button class = "btn-icon" id = "reader-search-btn" onclick = "toggleReaderSearch()" title = "Search" > 🔍< / button >
< button class = "btn-icon" id = "reader-settings-btn" onclick = "toggleSettingsPanel()" title = "Font & layout" > ⚙< / button >
< button class = "btn-icon" id = "reader-bookmark-btn" onclick = "addBookmark()" title = "Bookmark" > ★< / button >
< button class = "btn-icon" id = "reader-bm-list-btn" onclick = "openBookmarksSidebar()" title = "Bookmarks" > ☰< / button >
< button class = "btn-icon" id = "reader-toc-btn" onclick = "openTocSidebar()" title = "Table of contents" > ≡< / button >
< button class = "btn-icon" id = "reader-reset-pos-btn" onclick = "saveReaderProgress(true)" title = "Diese Position als Lesefortschritt setzen (überschreibt gespeicherten Fortschritt)" > ⚑< / button >
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
< button class = "btn-icon" onclick = "closeReader()" title = "Close (Esc)" > ✕< / button >
< / div >
< / div >
< div id = "reader-content" class = "reader-content" > < / div >
< / div >
<!-- ===== SIDEBAR ===== -->
< div id = "sidebar-overlay" class = "sidebar-overlay" onclick = "closeSidebar()" style = "display:none;" > < / div >
< aside id = "sidebar" class = "sidebar" >
< div class = "sidebar-header" >
< span id = "sidebar-title" class = "sidebar-title" > < / span >
< button class = "btn-icon sidebar-close" onclick = "closeSidebar()" title = "Close" > ✕< / button >
< / div >
< div id = "sidebar-body" class = "sidebar-body" > < / div >
< / aside >
2026-03-16 19:19:22 +01:00
{% endblock %}
{% block extra_js %}
< script >
// Pass Django context into JS
2026-03-20 12:58:38 +01:00
const INITIAL_SAVED = {{ saved_stations_json|safe }};
const INITIAL_FEATURED = {{ featured_stations_json|safe }};
2026-03-16 19:19:22 +01:00
const IS_AUTHENTICATED = {{ user.is_authenticated|yesno:"true,false" }};
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
const INITIAL_PODCAST_FEEDS = {{ initial_podcast_feeds|safe }};
2026-03-19 21:04:51 +01:00
window.USER_ID = {{ user.id|default:"null" }};
Add ebook reader features: highlights, bookmarks, search, settings, PDF paginated mode
- Backend: EBookHighlights and EBookBookmarks models with encrypted blob storage;
GET/POST views with size guards (700 KB / 100 KB); migration applied
- Reader header: search, settings, bookmark add/list buttons
- Font & layout settings panel (font size, line height, max width, themes for EPUB;
zoom, invert, paginated for PDF); persisted in localStorage
- Bookmarks: encrypted per-book blob, toast on add, sidebar with jump/delete
- Full-text search: EPUB TreeWalker mark injection, PDF span search; Ctrl+F / F3;
arrow key cycling; highlights re-applied on search clear
- PDF paginated mode: single-page view, tap-zone / swipe / arrow key navigation,
smart zoom (text bounding box → scale+translate canvas), auto-enable on mobile
- Progress tracking fixes: save before hiding overlay (was always writing 100%),
wait for EPUB images to load before restoring scroll, PDF paginated uses page
fraction, sendBeacon cache for unload/visibilitychange reliability
- PDF text layer disabled pending overlay rendering fix
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 13:08:42 +01:00
let USER_FOCUS_STATION = {{ focus_station_json|safe }};
2026-03-16 19:19:22 +01:00
< / script >
< script src = "/static/js/app.js" > < / script >
{% endblock %}