Files
Huang Xin 17de9357dd feat(reader): redesign the TTS control as a mini player with an expandable player sheet (#4996)
* feat(reader): add formatCountdown helper for TTS timer chips

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): extract shared TTS playback info hook

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): add TTS scrubber with buffer-ahead fill

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): add TTS speed preset chips

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): add persistent TTS mini player

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): add full TTS player sheet with voice and timer sub-views

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test(reader): cover player sheet view reset on reopen

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): replace TTS icon and popup with mini player and player sheet

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): reserve mini player clearance and retire showTTSBar setting

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: retire shipped TTS follow-ups from TODOS

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore(i18n): translate the TTS player strings

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(reader): pin mini player transport LTR and unmount the closed player sheet

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(reader): collapse sheet speed, voice, and timer controls into one row

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat(tts): stabilize timeline estimates with cumulative voice calibration

Replace the per-sentence EMA with the cumulative ratio of all measured chars to all measured seconds per voice, so the estimated remainder converges instead of re-pricing on every quirky sentence. Legacy stored calibrations migrate as a small prior.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(reader): hide the mini player while the player sheet is open

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(tts): clear stale highlights across sections and stop sentence flash in word mode

Entering a section now scrubs the TTS highlight from every live view, not just the primary, so the outgoing section's last word no longer stays lit in the preloaded neighbor. reapplyCurrentHighlight no longer redraws the whole sentence during word-mode playback while awaiting the first word boundary.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(reader): move the mini player progress line to the bottom edge

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix(reader): make the TTS progress bar and scrubber legible in eink mode

Grey tints wash out on e-ink: the mini player track gets a 1px hairline with a solid base-content fill (buffer fill hidden), and the sheet scrubber gets a crisp 1px border marking the track extent.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* style(reader): drop the player sheet header label on the main view

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:37:59 +02:00

2.5 KiB

TODOS

Cloud Sync provider selection follow-ups (deferred by /autoplan, 2026-07-06)

Deferred from the Cloud Sync provider-selection plan (#4959/#4380). See the Decision Audit Trail in the plan for reasoning.

  • Pre-switch "download all Readest Cloud books" affordance so a fresh device gets full library completeness when a third-party provider is selected. (S)
  • Library-page sync-status indicator for the active third-party provider (fileSyncStore already exposes aggregate progress). (S)
  • Account page active-provider chip. (XS)
  • File-engine parity: reading stats + per-book viewSettings sync via the file layout (readingStatus/tags parity shipped as its own PR). (M)
  • Server-side quota error code (code: 'quota_exceeded', mirroring the share import route) so the client stops string-matching 'Insufficient storage quota'; message drift silently restores retry behavior. (S)
  • Pre-existing: Manage Sync "Books" category gates metadata rows but NOT binary uploads to Readest Cloud (queueUpload never consults isSyncCategoryEnabled('book') despite the category docs claiming it) — align behavior or docs. (S)
  • Sentry cloudSyncProvider tag: Sentry tagging is Rust-mediated (set_webview_info pattern in sentry_config.rs); add a set_cloud_sync_provider command + before_send tag so sync-related reports carry the active provider. Console log lines ship in the meantime. (S, needs src-tauri)

Deferred items from the Edge TTS Web Audio plan review (/autoplan, 2026-07-04). Each was explicitly deferred, not forgotten — see the Decision Audit Trail in .agents/plans/2026-07-03-edge-tts-webaudio.md.

TTS listening engine follow-ups

  • Cross-section gapless playback: preload and schedule the next section's first sentence so chapter boundaries are as seamless as sentence boundaries. (M)
  • Lock-screen ±10s seek offsets in addition to prev/next sentence. (S)
  • Persist measured sentence durations per book so a reopened chapter starts with an exact timeline instead of estimates. (S)
  • Worker offload for decode + WSOLA if device profiling shows main-thread jank on low-end Android. (S)
  • Provider-agnostic voice source hedge: local neural TTS (e.g. Piper/Kokoro WASM) plugging into WebAudioPlayer/SectionTimeline — the engine is designed for this; see "Strategic framing" in the plan. (L)
  • Background chapter prefetch (convert timeline estimates to exact durations ahead of playback). (M)