feat: auto-download after sync, master stop, and batch downloads#34
Merged
Promises merged 3 commits intoJul 19, 2026
Merged
Conversation
The notification Cancel button only appeared while downloading, and neither the notification nor the in-app cancel could interrupt the post-download stages: a decrypt or a multi-GB SAF copy of a large audiobook ran to completion even after the user cancelled. Cancel is now offered in every stage, in the notification and the library list. The orchestrator tracks the running FFmpeg session per book and, on cancel, cancels that specific session (so parallel conversions are unaffected) and sets a flag that the buffered copy and the validation loop check, aborting promptly. Decrypt uses executeAsync so its session id is available to cancel. The cancel broadcast now always stops monitoring (which performs the abort) rather than only when the Rust download-cancel succeeds — past the download stage that call fails, which previously left the copy running. Cancelling mid-copy also deletes the partial output file and any folders created for it, so a later library scan cannot find and relink it. A book counts as downloaded only once its final file is saved, not when the download task first reports "completed" (that status is also set when only the download, not the whole pipeline, finished). Cancelled, failed and interrupted books stay retriable: the library shows the download button again and clears the stale task before re-enqueuing. Retry works again — it accepts the ".aaxc" encrypted cache (not only legacy ".aax"), and the error notification gained a real Retry action instead of an inert "tap to retry" hint.
Auto-download existed but never worked: enabling it could crash on an uninitialized worker, no code ever emitted the sync-complete event it listens for, the listener was armed only from the UI toggle so a relaunch left nothing listening, the WiFi gate read a flag no running code ever set, and the book scan read fields the query never returned — so nothing was ever enqueued. It also ran on a second download engine with none of the cancel/cleanup behavior of the foreground pipeline. Auto-download now works end to end and runs on the same pipeline as manual downloads: a completed library sync (from the in-app sync or the scheduled WorkManager sync) triggers a check that picks downloadable books without a saved file and enqueues them through DownloadService, giving them the same per-stage progress, cancel, cleanup, notifications and per-book dedup. Enabling the toggle — now also available in Settings > Library Sync, default off — only arms the listener; downloads start after the next sync, and replayed events from before arming are ignored. The WiFi-only gate queries connectivity live. The background worker pipeline gained the same mid-stage cancel as the foreground one (per-book FFmpeg session cancel, cooperative validation/copy abort, partial-file and folder cleanup, tasks end cancelled instead of stuck), and clearing tasks stops monitoring loops instead of leaving them polling. New master "Stop All Downloads" control in Settings with two scopes: cancel all downloads (active, queued, paused — the foreground engine is torn down and each Rust cancel is verified and counted) or additionally stop background task processing and scheduled work. Completed download rows are never touched: they link downloaded books to their files, so stopping never un-downloads a book and needs no re-sync to recover. Guarded against decrypting an empty or missing download (previously surfaced as a misleading activation-bytes error), and download cancellation is no longer logged as an error. The library gained a batch mode: a toolbar toggle switches to multi-select, tapping selects downloadable books, and one action downloads the selection with an honest started-count summary. The audio validation routine is shared by both pipelines instead of duplicated, and a cancelled validation propagates as a cancel rather than a corrupt-file verdict.
Owner
|
Thank you, I am still traveling, I will see if I can make some time at a hotel and review it. |
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.
Summary
Auto-download existed in the codebase but had never worked: enabling it could crash, nothing ever emitted the sync event it waits for, a relaunch left no listener armed, its WiFi gate read a flag nothing sets, and its book scan read fields the query doesn't return — so it never downloaded anything. It also ran on a second download engine that could only be stopped during the download stage, which is how stuck, uncancelable tasks appeared. This makes auto-download work end to end on the same pipeline as manual downloads, adds a master "Stop All" control with two scopes, and adds a batch multi-select download mode to the library. Builds on #33.
What changed
file_path/audible_product_id/authors, picks downloadable books without a saved file, and enqueues through the same DownloadService/DownloadOrchestrator as manual downloads — same per-stage progress, cancel, cleanup, per-book notifications, and duplicate-enqueue protection (also enforced in the service itself).User impact
Turning on auto-download (now a normal setting, off by default) downloads new, not-yet-downloaded books after each library sync over WiFi. Auto-downloads behave exactly like manual ones: visible progress for every stage, cancelable mid-stage, no leftovers on cancel. One button stops everything — downloads only, or every running process — without breaking the "downloaded" state of finished books, and without needing a re-sync afterwards. Multiple books can be selected and downloaded in one go from the library.
Implementation notes
The second download engine (background DownloadWorker) is still used for restored tasks, so it received the same cancel/cleanup mechanics as the orchestrator rather than being removed in this change; new auto-downloads no longer use it and route through the foreground service. The sync-complete event carries an emission timestamp so the listener can drop events replayed by the shared flow's buffer — otherwise enabling the toggle right after a sync would immediately start downloads, which the listener-only design is meant to avoid. Master stop only cancels rows in cancelable states; a completed row doubles as the downloaded-book file link, which is why it must survive.
Validation
Automated validation:
npm run typecheckManual Android validation: