- EBook.is_read (Migration) + neuer /books/<id>/read/-Endpoint zum Togglen
- book_list liefert is_read und has_highlights (Existenz einer Highlights-Zeile)
- Reader öffnet die Notizen-Sidebar automatisch, wenn das Buch bereits
Markierungen/Notizen hat, statt sie hinter dem manuellen Toggle zu verstecken
- Buch-Übersicht: Download-Button für Notizen/Markierungen direkt aus der Liste
(ohne den Reader zu öffnen), "Als gelesen markieren" mit Bestätigungsdialog,
Filter "Gelesene Bücher anzeigen" (standardmäßig aus)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Vier vom Nutzer gemeldete Bugs behoben:
- Markierter Text war kaum lesbar: der globale weiße Text-Outline (fürs
Hintergrundbild-Feature gedacht) kollidierte mit der Highlight-Farbe.
Reader sitzt immer auf eigenem, opakem Hintergrund — Outline dort komplett
deaktiviert.
- "Notiz zu Markierung hinzufügen" öffnete weiterhin die rechte Sidebar statt
den Rand. Jeder Notiz-Eintragspunkt (Highlight+Notiz aus der Textauswahl,
Edit-Note-Klick auf eine Markierung im Fließtext) läuft jetzt über
_openMarginAndEditNote() — öffnet bei Bedarf den Rand und bearbeitet dort
inline. openNoteEditor()/rechte Sidebar für Notizen komplett entfernt.
- Kernursache für "Notiz verschwindet, Markierung heftet sich an falsche
Notiz": Anker basierten auf XPath mit Sibling-Index unter den Textknoten
eines Blocks — jede weitere Markierung im selben Block (surroundContents
spaltet Textknoten) verschob diese Indizes und korrumpierte lautlos ALLE
anderen Anker im selben Block. Anker adressieren jetzt stattdessen
Block-Index + Zeichen-Offset innerhalb des Blocks (wie das bestehende
Lesefortschritt-Ankersystem) — Wrapping/Unwrapping durch andere
Markierungen ändert weder Blockreihenfolge noch Zeichenanzahl, ist also
erschütterungsfrei für andere Anker im selben Block.
- Löschen einer Markierung riss zuvor aus demselben Grund weiter unten
liegende Notizen optisch mit raus (Daten blieben in der DB) — mit dem
neuen Ankersystem behoben.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Notizen setzen/bearbeiten passiert jetzt inline an der Stelle im Notizen-Rand,
wo die Notiz auch angezeigt wird — kein Wechsel mehr zur rechten Sidebar.
Textfeld wird beim Öffnen automatisch fokussiert und ausgewählt. Enter
speichert, Escape verwirft die Änderung.
Stift-Button (Marker-Modus) zieht in die Titelzeile des Notizen-Rands um,
neben "Notes" — vorher musste man dafür ständig zur Hauptleiste zurück, die
im Immersive-Modus eingeklappt ist.
Nebenbei zwei Bugs beim Testen gefunden und behoben: ein Klick auf leere
Randfläche während ein Editor bereits offen war, legte durchs Blur-Event
gleichzeitig eine zweite, ungewollte Notiz an; und Escape im Notizfeld
bubbled zum globalen Escape-Handler durch, der dann den ganzen Reader
schloss (und damit die gerade bearbeiteten Highlights aus dem Speicher warf).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Drei Nachbesserungen am Annotationen-Feature nach Live-Test:
- Neuer Stift-Button (Marker-Modus) in der Kopfleiste: Textauswahl löst das
Highlight-Popup nur noch aus, wenn der Modus aktiv ist — vorher war die
Funktion unauffindbar (impliziter "einfach Text markieren"-Gestus ohne
sichtbaren Einstiegspunkt) und hätte jede Textauswahl (auch zum Kopieren)
gekapert.
- Freiform-Notizen bekommen keine Textdekoration mehr im Lesefluss — der
Anker dient nur der Positionierung im Rand, nicht der optischen Markierung.
- Die Margin-Sidebar zeigt Notiztext jetzt direkt lesbar als kleine
Post-it-Karte an der zugehörigen Stelle (mit Stapel-Logik gegen
Überlappung), statt nur ein abstraktes Symbol zum Anklicken. Reine
Highlights ohne Notiz bleiben ein kleiner Farbpunkt.
- Highlight-Popover/Tooltip klammern ihre Position jetzt hart an den
Viewport, damit eine Auswahl nahe Seitenrand nicht unsichtbar außerhalb
des sichtbaren Bereichs landet.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Textauswahl→Highlight-Popover war implementiert, aber nie verdrahtet (kein
mouseup/touchend-Listener) — als Voraussetzung mit behoben. Neu: freiformige
Notizen ohne Textmarkierung, verankert per Klick in einer neuen linken
Margin-Sidebar (Notiz am ersten Wort der Zeile auf Klickhöhe); Sidebar zeigt
Marker für alle Highlights/Notizen im sichtbaren Bereich und schiebt den
Lesetext nach rechts. Export sammelt alle Markierungen/Notizen eines Buchs in
Lesereihenfolge, nach Kapitel gruppiert, als Textdatei. EPUB-only — PDFs haben
noch keinen Text-Layer (siehe Issue #10).
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- Books: Reader sprang beim Scroll+sofortigem Tap auf die alte Position
zurück (Anker-Tracking lief nur alle 2s über den Save-Debounce, jetzt
eigener 150ms-Tracker unabhängig davon)
- Books: +/- Buttons neben den Reader-Slidern (Font/Zeilenhöhe/Breite)
- Books: Sicherheitsnetz-Toast bei plötzlichen großen Scroll-Sprüngen
(Fling, aus Versehen 'G' gedrückt) mit Zurückspringen-Option; bewusste
Sprünge (TOC, Lesezeichen, Fortschritts-Eingabe, Suche) lösen ihn nicht aus
- Radio: Donation-Hinweis kam bei vielen Lieblingssendern gefühlt ständig —
jetzt zusätzlich auf ~1-von-10 Plays gedrosselt
- UI: farbige Emoji-Icons (🔍📻⏪⏩💡 etc.) durch monochrome Unicode-Symbole
ersetzt, die nicht mehr je nach OS/Browser-Font unterschiedlich aussehen;
Lesezeichen-Icon war zudem fast identisch zum TOC-Icon
- UI: native alert()/confirm()/prompt() durch eigenes Modal-System ersetzt
- UI: Hash-basiertes URL-Routing für Tabs (#radio/saved, #podcasts/feeds, …)
— Browser-Zurück/Vor und Deep-Links funktionieren jetzt
- Tests: Playwright e2e-Setup gegen isolierte Test-DB (DIORA_DB_NAME),
Smoke- und Auth-Specs
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Statt padding-top gegen die Navbar zu kämpfen ist #tabs jetzt
position:fixed direkt unterhalb der Navbar (top:var(--nav-h),
z-index:150). Damit ist die Leiste garantiert immer sichtbar,
unabhängig vom Scroll-Zustand oder Offline-Status.
main-content padding-top auf calc(var(--nav-h)+3rem) erhöht um
Platz für Navbar+Tabs zu schaffen. Offline-Banner vereinfacht zu
einer body-Klasse (kein fixed DOM-Element mehr).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- main-content padding-top auf calc(var(--nav-h) + 0.75rem) erhöht
damit die Tab-Leiste (Radio/Focus/Podcasts/Books) sicher unterhalb
der fixed Navbar liegt — auf Desktop und Mobile
- SW v10: sendet SW_ACTIVATED an alle offenen Tabs wenn ein neuer SW
übernimmt; app.js lädt daraufhin neu (außer wenn ein Buch geöffnet
ist) — verhindert dass der Browser eine uralte HTTP-gecachte Version
ausliefert
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Bei Offline-Start oder Wechsel in Flugzeugmodus: roter Banner
unterhalb der Navbar, automatischer Wechsel zum Books-Tab (einziger
sinnvoller Tab offline), Upload-Zone wird ausgeblendet
- Bei Rückkehr online: Banner verschwindet, Upload-Zone erscheint wieder,
Buchliste wird neu synchronisiert
- openBook unterscheidet jetzt zwischen "nicht gecacht" (Toast-Hinweis
zum einmaligen Online-Öffnen) und echtem Defekt (markBookBroken wie
bisher) — kein stilles Scheitern mehr
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Popover had transparent background because --bg-card is explicitly
transparent; now uses hardcoded colors with theme-aware overrides.
Also strips title attributes during EPUB sanitization to prevent
native browser tooltips from appearing while reading.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- IndexedDB v2 mit zwei neuen Stores: book_meta (Buchliste +
Lesefortschritt) und book_annotations (Lesezeichen & Highlights)
- loadBookList fällt bei Netzwerkfehler auf lokalen Meta-Cache zurück,
blendet Upload-Zone aus und zeigt Offline-Hinweis
- Leseposition (scroll_fraction + position_anchor) wird bei jedem
Auto-Save lokal gecacht, sodass offline-Öffnen am richtigen Ort
landet
- Lesezeichen und Highlights werden nach Server-Abruf lokal gecacht
und bei Netzwerkfehler von dort geladen; Änderungen offline bleiben
bis zur nächsten Synchronisierung erhalten
- Mobile Reader-Header: kompaktere Abstände, Fortschritts-Input auf
kleinen Screens ausgeblendet
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hovering over a footnote reference shows the footnote content in a
floating popover; moving the mouse away dismisses it. On mobile, a
tap toggles the popover with an ✕ close button.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Publisher EPUBs often set font-weight via <b>/<strong> tags or inline
style attributes. A new toggle in the settings panel adds the
.reader-no-bold class which overrides all font weights to normal.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Moved overlay out of contentEl (which renderPdf clears immediately)
into the reader-overlay element. It now stays visible for the entire
render duration and is removed only after renderPdf resolves.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Displays a dark background with a spinning indicator in the reader
content area before renderPdf starts. renderPdf clears innerHTML
itself when it begins, so no explicit cleanup needed.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
html/body no longer scroll — overflow: hidden on both.
.main-content gets height: calc(100% - nav-h) and overflow-y: auto
so it's the single scroll container. The reader overlay is
position: fixed so it's unaffected.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds display_override: window-controls-overlay to the manifest so
the app extends into the titlebar area. The navbar becomes draggable
and uses env(titlebar-area-*) to avoid the window controls buttons.
Interactive elements stay clickable via -webkit-app-region: no-drag.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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>