Commit Graph
253 Commits
Author SHA1 Message Date
Dark-Alex-17 c9244b0459 feat(radarr): make the collection movie overview popup scrollable
A collection movie's overview renders in a popup that does not scroll,
so a long overview overflows with no way to read the rest. The popup now
scrolls.

The popup owns its own ScrollableText, built from the selected collection
movie's overview when it opens and torn down on Esc so a reopened popup
starts at the top. Scrolling mutates only that owned state. The
background renders the Collection record's overview and the movies
table, neither of which carries a scroll offset, so they cannot scroll
along with the popup. The popup also gains the loading and absent
fallbacks the rest of the tree already has.

Give the collection movie fixture an overview distinct from its
collection's, and a multi-paragraph one, so the snapshots can tell the
two records apart and a scrolled popup is distinguishable from an
unscrolled one.
2026-09-08 22:07:22 -06:00
Dark-Alex-17 b3ce15a564 feat(sonarr): add a scrollable overview popup to series details
A series' overview renders as one line of a description box that does
not scroll, so a long overview overflows with no way to read the rest.
Pressing v on the series details Seasons tab now opens a popup holding
the full overview.

The popup owns its own ScrollableText, built fresh from the series'
overview when it opens and torn down on Esc so a reopened popup starts
at the top. Scrolling mutates only that owned state. The background
paragraph renders the Series record's overview, which carries no scroll
offset, so it cannot scroll along with the popup.

Cite the existing view keybinding from the series details context clues
and give the popup its own clue set so it does not inherit the hints of
the view underneath.

Enrich the shared series fixture to a multi-paragraph overview, and the
raw response fixture that encodes the same series, so a scrolled popup
is distinguishable from an unscrolled one.
2026-09-08 21:31:25 -06:00
Dark-Alex-17 ca04498717 feat(lidarr): add a scrollable overview popup to artist details
An artist's overview renders as one line of a description box that does
not scroll, so a long overview overflows with no way to read the rest.
Pressing v on the artist details Albums tab now opens a popup holding
the full overview.

The popup owns its own ScrollableText, built fresh from the artist's
overview when it opens and torn down on Esc so a reopened popup starts
at the top. Scrolling mutates only that owned state. The background
paragraph renders the Artist record's overview, which carries no scroll
offset, so it cannot scroll along with the popup.

Cite the existing view keybinding from the artist details context clues
and give the popup its own clue set so it does not inherit the hints of
the view underneath.

Enrich the shared artist fixture to a multi-paragraph overview, and the
blocklist response fixtures that embed the same artist, so a scrolled
popup is distinguishable from an unscrolled one.
2026-09-08 21:05:50 -06:00
Dark-Alex-17 27c458307f feat(readarr): add a scrollable overview popup to author details
An author's overview renders as the last line of a description box that
does not scroll, so a long overview overflows with no way to read the
rest. Pressing v on the author details Books tab now opens a popup
holding the full overview.

The popup owns its own ScrollableText, built fresh from the author's
overview when it opens and torn down on Esc so a reopened popup starts
at the top. Scrolling mutates only that owned state. The background
paragraph renders the Author record's overview, which carries no scroll
offset, so it cannot scroll along with the popup.

Add a view keybinding bound to v, cite it from the author details
context clues, and give the popup its own clue set so it does not
inherit the hints of the view underneath.
2026-09-08 18:05:52 -06:00
Dark-Alex-17 7d1ff86c68 feat(readarr): add the add author UI
Renders the author search box, the search results table, and the
multi-step add confirmation prompt with its five dropdown popups.

The prompt's per-field highlighting is conveyed purely by style, which
render_to_string_with_app discards, so the highlight mapping is extracted
into add_author_prompt_highlights and unit tested per selection step.

Enriches the fully populated author search fixture with a second result
that is absent from the library, so both branches of the in-library
marker render in one snapshot and every table column carries a value.
2026-09-03 18:03:12 -06:00
Dark-Alex-17 a311e2b895 fix(readarr): stop appending stray colons to the edition overview
Every line of the edition details popup was parsed as a label and a value,
so a line carrying no colon had one appended to it. A multi-line overview
therefore rendered with a spurious colon at the end of each continuation
line, and Goodreads sourced descriptions, which use CRLF, turned their
blank lines into a lone colon.

Split each line on the first colon only, leave a line without one
unlabelled, and trim the trailing carriage return so a CRLF blank line
renders as a real paragraph break.

Building the line is now a named function so its branches can be asserted
directly. Rendered text discards the carriage return, so a snapshot alone
cannot tell the trimming apart from leaving it in place.

A continuation line that happens to contain a colon is still styled as a
label. Telling those apart needs the details to be built as styled lines
rather than flattened to text and parsed back.
2026-09-03 13:20:21 -06:00
Dark-Alex-17 280e691a94 feat(readarr): render the edition details popup
Draw the edition details popup over the book details view. The popup body is
the scrollable text the book details handler builds from the already loaded
edition row, so it needs no tabs and no network call.

The text styling is extracted into a named function so both branches are unit
tested, and the shared test fixture now holds the real field lines instead of a
placeholder, which exercises the scroll offset and the values that themselves
contain a colon.
2026-09-03 12:18:56 -06:00
Dark-Alex-17 b4c6994362 feat(readarr): render the book details popup
Draw the book details popup over the author details view, with the editions
table, book history, the book file info tab, and the manual search releases
table, plus the automatic search, delete book file, download release, and
history details prompts.

Edition row styling is extracted into a named function so each branch is unit
tested; text snapshots discard colour and cannot see it. The shared test
fixture now populates the edition format, ISBN13, ASIN, and publisher, and the
book file media info, so the rendered columns are exercised rather than blank.
2026-09-03 12:12:03 -06:00
Dark-Alex-17 d97c20d5ac feat(readarr): reach the book file info tab from the book details tabs
The book details handler already accepted the book file info block, but the
tab state declared only three tabs, so left and right could never reach it.
Add the File tab between History and Manual Search, backed by a new context
clue static covering refresh, delete book file, and esc.
2026-09-03 12:00:40 -06:00
Dark-Alex-17 e9b9aa3a14 feat(readarr): trigger automatic author searches and expose the command on the CLI
Posts the AuthorSearch command to the command endpoint with the author ID, queueing an indexer search for that author. The response is returned verbatim and no app state is mutated.

Introduces ReadarrCommandBody, the request body shared by the author and book command calls. Both ID fields are omitted from the payload when absent rather than sent as null.
2026-08-27 10:35:04 -06:00
Dark-Alex-17 ac8a11233f feat(readarr): delete Readarr authors and expose the command on the CLI 2026-08-27 09:54:38 -06:00
Dark-Alex-17 fcfc29894e feat(readarr): edit Readarr authors and expose the command on the CLI 2026-08-27 09:43:07 -06:00
Dark-Alex-17 e514e9b6cc feat(readarr): add authors to Readarr and expose the command on the CLI 2026-08-26 17:17:41 -06:00
Dark-Alex-17 3475660eb2 feat(readarr): add Readarr root folders and expose the command on the CLI 2026-08-26 10:31:40 -06:00
Dark-Alex-17 e0e82e654e fix: tolerate update records that omit the changes list
The changes field was required, so a single record without it failed the
whole response and emptied the updates list. A live instance returns five
update records of which one has no changes key, so this is reachable rather
than theoretical.

This affects every servarr, since Update is shared.
2026-08-20 21:06:28 -06:00
Dark-Alex-17 29f043f5c7 feat: scaffold Readarr support across the state, app, handler, UI, and CLI layers
Promote Route::Readarr from a unit stub to a tuple variant and wire Readarr
through every layer, mirroring the Lidarr tree. Readarr appears as a fourth
servarr tab and its library view renders the Authors table.

Adds ReadarrData and its modals, the tick and context clue modules, the
top-level ReadarrHandler, ReadarrUi with the Authors library view, and an
empty ReadarrCommand behind ReadarrCliHandler. The default port is 8787.

Promoting the route variant compiles cleanly without any of the arms that
give it behaviour, so all six of those sites are wired explicitly here:
App::on_tick, handlers::handle_events, handle_prompt_toggle,
ServarrContextClueProvider, ui(), and verify_config_present_for_cli. Each was
checked by removing the arm and confirming its covering assertion then fails.

ReadarrEvent and ReadarrCommand are both declared empty. They gain variants
alongside the network calls and CLI commands that use them, which keeps each
later change to a single function.

Adding the tab changes the rendered tab bar, so 13 existing snapshots
regenerate. The only delta in each is that single tab bar line.

This scaffold adds 24 dead_code warnings, all inside the Readarr tree and
none outside it. They clear as the handlers, UI, network events, and CLI
commands that consume these items land: block arrays awaiting their accepts
implementations and BlockSelectionState seeding, modal and state fields
awaiting their handlers, the CLI handler fields awaiting an inhabited command
enum, and the top-level handler fields awaiting sub-handlers. The count must
strictly decrease from here, so a later increase is a defect rather than
transient noise. The 12 pre-existing collapsible_match warnings are unrelated
and untouched.
2026-08-20 15:28:49 -06:00
Dark-Alex-17 4db9b92146 refactor: move shared servarr types into servarr_models
SystemStatus was declared three times, byte for byte identically, in
radarr_models, sonarr_models, and lidarr_models. MetadataProfile and the
Lidarr release download body were each declared in a single servarr module
despite having nothing servarr specific about them: MetadataProfile is an
id and name pair structurally identical to QualityProfile, which already
lives in servarr_models, and a download body of a guid plus an indexer id
is the generic form of that request.

Move all three into servarr_models, preserving that file's alphabetical
ordering, and drop the prefix from LidarrReleaseDownloadBody now that it is
no longer owned by one servarr.

RadarrReleaseDownloadBody and SonarrReleaseDownloadBody deliberately stay
where they are. Radarr's carries a movie id and Sonarr's carries optional
series, episode, and season fields, so the three types are not
interchangeable and only the Lidarr shape is the common one.

Behavior is unchanged. Every remaining edit is an import path update or the
rename at a call site.
2026-08-20 10:52:05 -06:00
Dark-Alex-17 af573cac2a feat: Added support for a system-wide notification popup mechanism that works across Servarrs 2026-02-03 17:03:12 -07:00
Dark-Alex-17 d8f7febfe1 feat: Improved disk-space UI and CLI that shows the actual path being monitored instead of just a disk number
Check / stable / fmt (push) Has been cancelled
Check / beta / clippy (push) Has been cancelled
Check / stable / clippy (push) Has been cancelled
Check / nightly / doc (push) Has been cancelled
Check / 1.89.0 / check (push) Has been cancelled
Test Suite / ubuntu / beta (push) Has been cancelled
Test Suite / ubuntu / stable (push) Has been cancelled
Test Suite / macos-latest / stable (push) Has been cancelled
Test Suite / windows-latest / stable (push) Has been cancelled
Test Suite / ubuntu / stable / coverage (push) Has been cancelled
2026-01-22 09:36:58 -07:00
Dark-Alex-17 f17f542e8e refactor: Refactored the SonarrEvent enum to not unnecessarily wrap dual series_id and season_number values in a tuple when both values can be passed directly 2026-01-19 16:44:10 -07:00
Dark-Alex-17 89f5ff6bc7 feat: Blocklist support in Lidarr in both the CLI and TUI 2026-01-19 16:13:11 -07:00
Dark-Alex-17 eff1a901eb feat: CLI and TUI support for track history and track details in Lidarr 2026-01-19 14:50:20 -07:00
Dark-Alex-17 7bb5f83a56 feat: Lidarr UI support for album details popup 2026-01-16 23:21:25 -07:00
Dark-Alex-17 bc6ecc39f4 feat: Bulk added CLI support for tracks and album functionalities in Lidarr 2026-01-16 14:38:08 -07:00
Dark-Alex-17 1329589bd6 feat: Implemented the manual artist discography search tab in Lidarr's artist details UI 2026-01-15 14:36:09 -07:00
Dark-Alex-17 c6dc8f6090 feat: Lidarr CLI support for downloading a release 2026-01-15 12:57:54 -07:00
Dark-Alex-17 0ee275d58f fix: Sonarr manual search TUI and CLI incorrectly displaying the same unfiltered results for both season and episode searches 2026-01-15 12:43:16 -07:00
Dark-Alex-17 8dfa664a06 feat: CLI support for searching for discography releases in Lidarr 2026-01-15 11:39:34 -07:00
Dark-Alex-17 d7f0dd5950 feat: Added TUI and CLI support for viewing Artist history in Lidarr 2026-01-14 16:09:37 -07:00
Dark-Alex-17 8b9467bd39 feat: Full Lidarr system support for both the CLI and TUI 2026-01-14 14:50:33 -07:00
Dark-Alex-17 c74d5936d2 feat: Full CLI and TUI support for the Lidarr Indexers tab 2026-01-14 13:30:51 -07:00
Dark-Alex-17 8abcf44866 feat: Full support for adding a root folder in Lidarr from both the CLI and TUI 2026-01-14 09:06:27 -07:00
Dark-Alex-17 d2217509f2 feat: naive lidarr root folder tab implementation. Needs improved add logic 2026-01-13 14:33:12 -07:00
Dark-Alex-17 c68cd75015 feat: Downloads tab support in Lidarr 2026-01-13 13:40:18 -07:00
Dark-Alex-17 ad9e2b3671 feat: Created a History tab in the Radarr UI and created a list history command and mark-history-item-as-failed command for Radarr 2026-01-13 12:35:54 -07:00
Dark-Alex-17 68b08d1cd7 feat: Implemented the Lidarr History tab and CLI support 2026-01-12 14:43:05 -07:00
Dark-Alex-17 f31810e48a feat: TUI support for deleting a Lidarr album from the artist details popup 2026-01-09 17:21:10 -07:00
Dark-Alex-17 09bee7473f feat: CLI support for deleting an album from Lidarr 2026-01-09 16:33:32 -07:00
Dark-Alex-17 b2814371f0 feat: Completed support for viewing Lidarr artist details 2026-01-09 16:22:03 -07:00
Dark-Alex-17 450fdd7106 test: Added tests for the Lidarr context clues for the add artist popup 2026-01-08 15:20:17 -07:00
Dark-Alex-17 c624d1b9e4 feat: Full CLI and TUI support for adding an artist to Lidarr 2026-01-08 15:16:01 -07:00
Dark-Alex-17 e94f78dc7b refactor: Let serde serialize Add Series and Add Movie enums instead of calling to_string up front 2026-01-08 10:52:30 -07:00
Dark-Alex-17 ca208ff5e4 fix: Refactored how quality profiles, language profiles, and metadata profiles are populated for each servarr so they sort using the ID to mimic the web UI better 2026-01-08 10:05:15 -07:00
Dark-Alex-17 243de47cae feat: Initial Lidarr support for searching for new artists 2026-01-07 15:53:18 -07:00
Dark-Alex-17 64d8c65831 fix: Prevented additional empty slice errors in indexer tables 2026-01-07 14:09:12 -07:00
Dark-Alex-17 60c4cf1098 fix: Fixed a bug in all Servarr implementations to not try to get the current selection of a search table when an error is returned from the API 2026-01-07 14:00:02 -07:00
Dark-Alex-17 b1afdaf541 feat: Added CLI and TUI support for editing Lidarr artists 2026-01-07 12:01:03 -07:00
Dark-Alex-17 3c1634d1e3 testing 2026-01-07 10:45:49 -07:00
Dark-Alex-17 9b4eda6a9d feat: Support for updating all Lidarr artists in both the CLI and TUI 2026-01-06 12:47:10 -07:00
Dark-Alex-17 96308afeee feat: Added Lidarr CLI support for fetching the host config and the security config 2026-01-06 11:00:19 -07:00