diff --git a/internal/ui/form.go b/internal/ui/form.go index 2822ccd..7ea3e02 100644 --- a/internal/ui/form.go +++ b/internal/ui/form.go @@ -116,8 +116,13 @@ func focusedDropDown(f *tview.Form, item int) (*tview.DropDown, bool) { if item < 0 { return nil, false } - dd, ok := f.GetFormItem(item).(*tview.DropDown) - return dd, ok + switch it := f.GetFormItem(item).(type) { + case *tview.DropDown: + return it, true + case *serverChoice: // a dropdown with extras; the keys work the same + return it.DropDown, true + } + return nil, false } // bindSearchNow keeps a "Search now" checkbox consistent with whether a search diff --git a/internal/ui/settings_test.go b/internal/ui/settings_test.go index f3e4ba0..b51189e 100644 --- a/internal/ui/settings_test.go +++ b/internal/ui/settings_test.go @@ -411,3 +411,40 @@ func TestDefaultsAreChosenFromTheServer(t *testing.T) { t.Errorf("offline: %d options, result %q", p.GetOptionCount(), v.status.GetText(false)) } } + +func TestServerChoiceWorksWithTheArrowKeys(t *testing.T) { + a := newTestApp(t) + v := a.settings + p := v.choices["radarr.profile"] + v.choiceGen["radarr"] = 1 + v.applyChoices("radarr", 1, []string{"Any", "HD-1080p"}, nil, nil) + v.focusGroup(0, false) + keys := v.form.GetInputCapture() + send := func(k tcell.Key) { keys(tcell.NewEventKey(k, 0, 0)) } + send(tcell.KeyDown) // API key + send(tcell.KeyDown) // Default quality profile + if item, _ := v.form.GetFocusedItemIndex(); v.form.GetFormItem(item) != p { + t.Fatalf("on %q", v.form.GetFormItem(item).GetLabel()) + } + + // → and ← change the value, like on every other dropdown. + send(tcell.KeyRight) + send(tcell.KeyRight) + if p.value != "HD-1080p" || !v.dirty { + t.Errorf("→→: value %q, dirty %v", p.value, v.dirty) + } + send(tcell.KeyLeft) + if p.value != "Any" { + t.Errorf("←: value %q", p.value) + } + // While its list is open, ↑↓ belong to the list, not to the form. + var focus func(tview.Primitive) + focus = func(q tview.Primitive) { q.Focus(focus) } + p.InputHandler()(tcell.NewEventKey(tcell.KeyEnter, 0, 0), focus) + if !p.IsOpen() { + t.Fatal("Enter does not open the list") + } + if got := keys(tcell.NewEventKey(tcell.KeyDown, 0, 0)); got == nil { + t.Error("↓ in the open list was taken by the form") + } +}