Commit Graph
46 Commits
Author SHA1 Message Date
Allamagoosa 1eddccbe63 Bound concurrency by the hard limit and say what the machine will do
Taking the alternative offered in review. The spinner's maximum is the flat
hard limit now, the same number in both UIs and on every machine, and
machine capability is applied only at the point of use.

Bounding the control by capability made it lie in two directions at once.
Below the stored value, a two-way spinner coerces its display down to its
maximum and writes that back, so opening the panel on a smaller machine
overwrote an 8 chosen on a larger one. Raising the bound to meet the stored
value fixed that but left a stored 8 displaying 8 on a two-core box that
will only ever run 2. The two UIs had also drifted apart: Avalonia bound
Maximum and ratcheted down, WinForms set it once in the constructor, so
within a session you could lower and re-raise in one and not the other.

What is left is the gap between what the setting says and what runs, and
that is now stated rather than hidden. Chardonnay shows "(2 on this
machine)" beside the spinner, in the spare column the settings row already
had. Classic's settings table is full at three columns with no width to
spare, so it says the same thing in the control's tooltip.
2026-08-20 17:13:02 -07:00
Allamagoosa 5d0ed3af68 Make auto-scroll mean the same thing in both UIs
WinForms had been changed to pin the first active download to the top on every
start, which interrupts anyone who has scrolled further down the queue - the
behaviour master's comment says it deliberately avoids. Avalonia kept master's
gentler version but never read the setting, so Chardonnay's checkbox did nothing.

Both now run master's logic - scroll the new item into view only when the
previous one is visible - gated by AutoScrollQueue. VirtualFlowControl.ScrollToTop
had no callers left, so it goes.
2026-08-20 13:19:32 -07:00
Allamagoosa 986dda5eaa Review #1885: Avalonia parity, and cap concurrency by processor count
Chardonnay had parallel downloads with no way to configure them, since
the queue logic lives in shared UI code but each UI supplies its own
controls. Adds the Auto-scroll toggle and the 'At once' spinner to
Chardonnay's queue panel, bound to the same view model properties the
WinForms panel uses.

Also uses Environment.ProcessorCount as the spinner's ceiling rather
than its default: min(ProcessorCount, 10). Downloading is bound by
Audible's license throttling rather than local CPU, so core count says
nothing about how many concurrent downloads will succeed - it only
bounds how many decrypts can usefully run at once. The default stays 3.

Spinner bounds are bound rather than hardcoded, so the two UIs cannot
drift apart.
2026-08-16 14:08:49 -07:00
Allamagoosa 2db63a8edd Review #1885: one concurrency setting with a safe default and a numeric control
Replaces the MultiThreadEnabled checkbox and the ProcessorCount default
with a single MaxConcurrentDownloads value where 1 means serial - the
behaviour Libation had before parallel downloads existed.

The old pairing could not express 'off' at all: the bool was hardcoded
true in the view model constructor and the int setter clamped to a
minimum of 2, so there was no way back to one-at-a-time downloads.
Collapsing both into one value makes that state unreachable rather than
merely fixed, and removes the risk of the two settings disagreeing.

Bounds live in Configuration as named constants: minimum 1, default 3,
maximum 10. Audible throttles license requests, so the default is
deliberately conservative and the cap keeps users from choosing a number
that produces license denials instead of speed.

WinForms swaps the 'Parallel downloads' checkbox for an 'At once:'
spinner that reads its bounds from those constants.
2026-08-16 14:08:49 -07:00
SirBiggin d93d325913 Added Multi Threading for downloads and Auto Scroll to view current downloads 2026-08-16 14:08:39 -07:00
Cursor Agentandrmcrackan 818510d1b0 feat(limit): add opt-in daily download limit core, history store and enforcement
Records every successful audiobook download in the library database (a new
DownloadHistory table) and, when the user opts in, stops downloading once the
rolling 24 hour window is full.

The history lives in the database rather than a file under LibationFiles
because in Docker only the database is on a volume; a file there is discarded
on every container restart.

The limit is checked immediately before each book downloads, never at queueing
time, so a full queue stays full and the user can raise or disable the limit
mid-run. When nothing in the queue can proceed the queue pauses and re-checks
every 15 seconds, recomputing settings, history and clock from scratch, so a
queue left running for days drip-feeds itself as downloads age out. The CLI
never waits: it skips covered titles and reports a count.

Co-authored-by: rmcrackan <rmcrackan@gmail.com>
2026-08-14 17:16:47 +00:00
Michael Bucari-Tovo d67692355f Enable project-wide nullable reference types
Added DB migration for nullable types.
2026-02-05 12:43:05 -07:00
MBucari 29a5c943cb Auto-scroll process queue 2025-12-29 21:52:36 -07:00
Michael Bucari-Tovo cdb91ae2ca Add dark mode to winforms
- Add dark theme icon variants
- Change all light theme icon fill colors to match Chardonnay

Also fixed #1460  by chaing the directory select control to DirectoryOrCustomSelectControl
2025-12-01 20:39:22 -07:00
Michael Bucari-Tovo 0f4197924e Use LibationUiBase.ReactiveObject where applicable
Also tweak the classic process queue control layout
2025-07-22 11:59:34 -06:00
Michael Bucari-Tovo 80b86086ca Consolidate process queue view models
Remove classic and chardonnay-specific implementations
Refactor TrackedQueue into an IList with INotifyCollectionChanged
2025-07-21 15:56:30 -06:00
MBucari 747451d243 Refactor Classic process queue
The queue is now more MVVM-like.
2025-07-16 22:58:03 -06:00
Michael Bucari-Tovo 4b7939541a Code cleanup and refactoring for clarity 2025-07-16 22:55:57 -06:00
MBucari 4dab16837e Move ProcessQueueViewModel logic into LibationUiBase
Fix UI bug in classic when queue is in popped-out mode.
2025-07-15 22:31:17 -06:00
MBucari 1cf889eed7 Move ProcessBookViewModel logic into LiationUiBase 2025-07-15 15:05:33 -06:00
MBucari b65b1e819b Consolidate queue commands into UI base 2025-07-15 13:32:42 -06:00
Michael Bucari-Tovo 8aa157f2f6 Re-add completed audiobooks to queue (#1219) 2025-05-06 15:43:58 -06:00
Michael Bucari-Tovo 3b7d5a354f Re-add books to queue that failed or were cancelled. 2025-02-28 10:47:26 -07:00
Mbucari 83fa73cef5 Integrate new Title and Subtitle properties into Libation 2023-06-29 21:06:54 -06:00
Mbucari 2c4705de6e Address #625 comments and refactor 2023-06-13 09:05:17 -06:00
Michael Bucari-Tovo 00c8be1f7e Create LibationUiBase for shared UI code 2023-02-08 09:30:13 -07:00
Mbucari e3c9f70dff Move shared GUI code into AppScaffolding 2023-02-06 16:04:58 -07:00
Michael Bucari-Tovo 9ec877999e Add download speed limit 2023-01-02 02:46:46 -07:00
Michael Bucari-Tovo 94469cae3d Add better error messages for license denial #352 2022-12-15 16:22:25 -07:00
Michael Bucari-Tovo 314f4850bc Add logging and error handling to Process Queue. and Processables 2022-06-23 15:38:39 -06:00
Michael Bucari-Tovo e787d33e5a Fix NRE on cancel when there's nothing to cancel. 2022-06-20 16:47:25 -06:00
Michael Bucari-Tovo c51489ac74 Await cancell 2022-06-19 18:49:47 -06:00
Michael Bucari-Tovo 490d121db3 Add unicode replacements for illegal characters 2022-06-19 16:57:44 -06:00
Michael Bucari-Tovo 31812bc2d9 Refactoring 2022-06-08 09:24:06 -06:00
Michael Bucari-Tovo 9c6211e8e0 Improve UI speed when adding many books to queue at once. 2022-06-08 08:39:17 -06:00
Robert McRackan 3f2899e97e * New event SearchEngineCommands.SearchEngineUpdated
* Clean up redundant event notifications
2022-05-25 10:09:27 -04:00
Michael Bucari-Tovo 43d6ea82cd Change failure behavior to match previous implementation 2022-05-24 09:17:09 -06:00
Michael Bucari-Tovo ee62d9ae8d Attempt to fix app hang on LogMe event 2022-05-24 07:36:17 -06:00
Michael Bucari-Tovo d71cdecd35 Refactoring and addressing comments 2022-05-23 21:20:26 -06:00
Michael Bucari-Tovo 6b46fa4cbc Use package installer 2022-05-18 17:32:53 -06:00
Michael Bucari-Tovo 789b9207b5 Use that fancy patterm matching 2022-05-16 15:49:02 -06:00
Michael Bucari-Tovo 843fddabde Changes discussed in email 2022-05-16 14:27:34 -06:00
Michael Bucari-Tovo 15396c611a Add documentation 2022-05-16 13:16:50 -06:00
Michael Bucari-Tovo a490df0f7e Fix possible index range error 2022-05-15 11:10:37 -06:00
Michael Bucari-Tovo 0ff8da2cf0 Add await and make cancel async 2022-05-15 09:30:44 -06:00
Michael Bucari-Tovo c0ef3ccbea Tiny bugfix 2022-05-15 09:00:52 -06:00
Michael Bucari-Tovo 1ab628dee8 Better invocation. Post instead of Send 2022-05-14 23:45:13 -06:00
Michael Bucari-Tovo 5b05c018d5 Remove ValidationFail books from queue display. Nothing to see there. 2022-05-14 20:00:23 -06:00
Michael Bucari-Tovo 73a5d76503 Make thread safe and integrate with Libation UI 2022-05-14 14:39:46 -06:00
Michael Bucari-Tovo 50c35ed519 Change log to gridview and new INotifyPropertyChanged event 2022-05-14 13:52:54 -06:00
Michael Bucari-Tovo 7f08da96bb Documentation and organization 2022-05-14 11:20:19 -06:00