Add interactive release search (M6)

Release listing and grab in the shared arr client, a full-screen release
list (sort, hide rejected, rejection reasons, confirmation before grabbing
rejected releases; Usenet only), and a season/episode picker for Sonarr.
Overlays are now a stack so dialogs can open above the release list.
Add a fake Newznab indexer to the dev setup.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-20 18:09:19 +02:00
co-authored by Claude Sonnet 5.5
parent 446cbdd6c5
commit f928427993
18 changed files with 1002 additions and 23 deletions
+16
View File
@@ -95,6 +95,9 @@ func newSearchView(app *App, be backend, cfg config.Arr) *searchView {
case 'a':
v.add(v.list.GetCurrentItem())
return nil
case 'i':
v.interactive(v.list.GetCurrentItem())
return nil
}
return ev
})
@@ -239,6 +242,19 @@ func (v *searchView) showDetails(i int) {
v.details.SetText(v.results[i].details()).ScrollToBeginning()
}
// interactive opens the release list for the result at index i.
func (v *searchView) interactive(i int) {
if i < 0 || i >= len(v.results) {
return
}
r := v.results[i]
if !r.inLibrary() {
v.app.SetMessage(fmt.Sprintf("[yellow]Add %s to %s first (a), then search for releases", tview.Escape(r.title()), v.be.name()))
return
}
v.be.interactive(v, r)
}
// add opens the add dialog for the result at index i.
func (v *searchView) add(i int) {
if i < 0 || i >= len(v.results) {