Ga naar hoofdinhoud

Epub-lezer

De lezer is native, puur Flutter — geen webview (Linux heeft er geen). Hij leeft in lib/utils/epub/, lib/pages/ReaderPage.dart en lib/components/reader/. Hij rendert één hoofdstuk tegelijk als een scrollende blokkenlijst, synchroniseert de leespositie met de server (inclusief de audioboekkoppeling) en speelt EPUB 3-voorleesaudio af.

EpubResourceClient — lib/utils/epub/EpubResourceClient.dart

De epub wordt nooit in zijn geheel gedownload. Individuele entries worden lui opgehaald via het /epub/{mediaFileId}/resource/-endpoint van de node, geauthenticeerd met stream-tokens (StreamTokenService) en bewaard in een LRU-cache.

EpubPackage — lib/utils/epub/EpubPackage.dart

De server bewaart geen spine of inhoudsopgave, dus de client parset de boekstructuur zelf: container.xml, het OPF-packagedocument, en het EPUB 3-nav-document of de NCX-fallback.

ChapterContent en de blok-locator

ChapterContent (lib/utils/epub/ChapterContent.dart) splitst een hoofdstuk in top-level blokken; de blokindex is de locatorcoördinaat. Posities staan in het opake readingLocation-veld van de server als:

ister:v1;spine=…;block=…

EpubLocator.tryParse (lib/utils/epub/EpubLocator.dart) wijst de epubcfi-strings van de oude weblezer bewust af; die vallen dan terug op de voortgangsfractie — oude posities degraderen netjes in plaats van verkeerd op te lossen.

ReadingSyncService — lib/utils/epub/ReadingSyncService.dart

Voortgangssync gebruikt het REST-paar GET /book-progress en een gedebouncede POST /reading-progressniet de GraphQL-mutatie updateReadingProgress. REST draagt de audioboek-hoofdstukkoppeling die de server spiegelt, zodat lezen en luisteren op dezelfde plek hervatten.

De audio⇄tekst-koppeling is zin-exact via de SMIL-tijdlijn (lib/utils/epub/SmilDocument.dart) wanneer de duur daarvan overeenkomt met de duur van het audioboekhoofdstuk, en geïnterpoleerd in de andere gevallen.

ReadAloudController — lib/utils/epub/ReadAloudController.dart

Speelt EPUB 3-media-overlays af op een eigen media_kit Player (per zin clip-gescheduled) en pauzeert MediaPlayerHandler bij de start, zodat de twee nooit om de uitvoer vechten. ChapterView (lib/components/reader/) markeert de actuele zin.

ReaderPage — lib/pages/ReaderPage.dart

Bindt alles samen: zonder chapter-queryparam opent het boek op de opgeslagen leespositie — of op de audioboekpositie wanneer die nieuwer is; mét, op dat hoofdstuk (gematcht tegen de inhoudsopgave, met de spine als fallback). readAloud start de media-overlay-audio zodra het hoofdstuk getoond wordt. Ondersteunende delen: ReaderBookController, ReaderPreferences, ReaderSettingsSheet, ReaderTocDrawer.

Striplezer, in het kort

ComicReaderPage (lib/pages/ComicReaderPage.dart) met een eigen stack in lib/utils/comic/: pagina-afbeeldingen in een swipende PageView, één spread per weergave (één pagina, of twee naast elkaar op een brede viewport), pinch-zoom, rechts-naar-links lezen dat per serie bewaard blijft, een miniatuurstrook, D-pad-/toetsenbordpaging en voortgangssync via ComicSyncService. Formaat-blind door ComicPageSource: cbz-pagina's streamen van de node (ComicResourceClient), pdf-pagina's worden lokaal gerenderd (PdfPageSource).