Feat: web platform feature parity#136
Draft
ddfreiling wants to merge 32 commits into
Draft
Conversation
Bumps the three ts-toolkit packages to latest: @readium/navigator 2.2.4 → 2.5.5 @readium/navigator-html-injectables 2.2.1 → 2.4.2 @readium/shared 2.1.1 → 2.2.0 Adapter changes required by the new API surface: - EpubNavigator/WebPubNavigator listeners: add stub handlers for contentProtection, peripheral, and contextMenu (now required fields). - EpubPreferences: add scrollPaddingLeft / scrollPaddingRight fields introduced in 2.5.x. - helpers.ts: note that highlightSelection() is experimental and will be superseded once ts-toolkit PR #209 (Decorator API) merges. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Brings the web platform to parity with iOS and Android for timebased
playback features. All three share the same Dart API and event streams
(onTimebasedPlayerStateChanged, onTextLocatorChanged) already wired up
for audiobooks on native.
AudioNavigator (audiobooks)
- New Audio/audioNavigator.ts wraps @readium/navigator AudioNavigator.
- Introduces AudioLocatorMapper — an optional hook applied by every
state-emitting listener (play, pause, positionChanged, trackEnded,
error, stalled) so all state transitions carry correctly-mapped
locators, not just periodic poll events.
- openPublication now initialises AudioNavigator for audiobook profiles
(was a TODO stub).
TTS (Audio/ttsNavigator.ts + Audio/ttsPreferences.ts)
- WebTTSEngine walks EPUB text via PublicationContentIterator +
HTMLResourceContentIterator and speaks each TextElement via the
browser SpeechSynthesis API.
- Sub-utterance onboundary granularity (word/sentence) with 100 ms
throttle; degrades silently when unavailable (Firefox, some mobile).
- Voice list: { identifier, name, language, networkRequired } —
gender/quality enriched by ReaderTTSVoiceUtils in the platform
interface via readium/speech voice data.
- Per-language voice map and global voice override.
- TODO(#209): visual word/sentence highlight deferred until ts-toolkit
Decorator API (PR #209) merges.
Media Overlay / Sync Narration
(Audio/syncNarration.ts + Audio/mediaOverlayNavigator.ts)
- Parses Readium Sync Narration JSON alternates
(application/vnd.readium.narration+json) into SyncNarrationItem[].
- Builds a synthetic audiobook reading order (one Link per unique audio
file) and reuses AudioNavigator via AudioLocatorMapper to emit
text-based locators on every state event — matching iOS/Android.
- audioSeekBy wired through AudioNavigator.jump(seconds).
Dart wiring
- js_publication_channel.dart: JS interop + static wrappers for the
full timebased playback API (play, pause, resume, stop, next,
previous, seekBy, setAudioPreferences, ttsEnable,
ttsGetAvailableVoices, ttsSetVoice, ttsSetPreferences, audioEnable).
- flutter_readium_web.dart: replaces UnimplementedError stubs for all
playback methods with real JsPublicationChannel calls.
- readium_webview.dart: registers updateTimebasedPlayerState JS export
so AudioNavigator/TTS state events reach the Dart stream.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Webpack 5's default splitChunks optimisation, combined with the pre-split @readium/* packages (locale and ReadiumCSS variant files), was generating 30+ chunk files alongside the main bundle. These had to be committed and served as separate assets. Fix: add splitChunks: false and output.asyncChunks: false to webpack.config.js. asyncChunks: false (Webpack 5.84+) inlines all dynamic imports — including the ReadiumCSS injection files that @readium/navigator loads lazily — into the single bundle. The trade-off is a slightly larger readiumReader.js (~1.2 MiB dev build) with no practical penalty since the webview loads everything up front. Deleted all stale chunk files from lib/helpers/. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Link.fromJsonArray: guard against non-Map elements (e.g. JSON-LD @context strings embedded in link arrays) instead of hard-casting, preventing a TypeError on manifests that follow the JSON-LD convention. - MediaType: add readiumNarration constant for application/vnd.readium.narration+json (Readium Sync Narration format). - Publication.containsMediaOverlays: extend to recognise both vnd.syncnarr+json and vnd.readium.narration+json alternates, so isAudioBook returns true for Sync Narration EPUBs and the example app's play-button dispatch routes them to audioEnable correctly. - FlutterReadiumWebPlugin: override setLogLevel (was throwing UnimplementedError; the web layer needs only ReadiumLog.setLevel). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PlayerControlsBloc: add SeekRelative event dispatching audioSeekBy so ±10 s relative seeks can be triggered from the UI. - PlayerControlsWidget: show replay-10 / forward-10 buttons when audio (audiobook or Media Overlay) is active; buttons carry ValueKeys for marionette automation. - webManifestList.json: replace placeholder URLs with a Nota EPUB and audio-only webpub for smoke-testing TTS and Media Overlay on web. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add a 'build_web' task that runs bin/update_web_example (builds the TS bundle and copies readiumReader.js into example/web/) and an 'example (web)' launch configuration that targets Chrome, running the build task as a pre-launch step. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
browser scrolling in publication emits updates with 60hz
upstream PR has been opened
timing between calls during init was all wrong before, now uses a ready promise for when first track is loaded. Should avoid observed race-conditions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Attempting to bring web platform up-to-speed.
Initial skeleton impl. done with help by AI, but tested and corrected from there.
It needs testing and further work:
tocHrefenricher and ToC skip/goTo worksdisableSynchronizationworks for TTS and Overlays publications