diff --git a/internal/ui/chat/guildstree/keymap.go b/internal/ui/chat/guildstree/keymap.go index bee7d52..e923311 100644 --- a/internal/ui/chat/guildstree/keymap.go +++ b/internal/ui/chat/guildstree/keymap.go @@ -4,6 +4,7 @@ import ( "slices" "github.com/ayn2op/arikawa/v3/discord" + uitree "github.com/ayn2op/discordo/internal/ui/tree" "github.com/ayn2op/tview/help" "github.com/ayn2op/tview/keybind" "github.com/ayn2op/tview/tree" @@ -34,7 +35,7 @@ func (m Model) selectCurrentKeybind() keybind.Keybind { func (m Model) ShortHelp() []keybind.Keybind { cfg := m.cfg.Keybinds.GuildsTree - shortHelp := []keybind.Keybind{cfg.SelectUp.Keybind, cfg.SelectDown.Keybind, m.selectCurrentKeybind()} + shortHelp := append(uitree.SelectHelp(m.root, m.selectionState.CurrentNode(), cfg.TreeKeybinds), m.selectCurrentKeybind()) if m.canCollapseParent(m.selectionState.CurrentNode()) { shortHelp = append(shortHelp, cfg.CollapseParentNode.Keybind) } diff --git a/internal/ui/chat/memberstree/keymap.go b/internal/ui/chat/memberstree/keymap.go index 4076973..738cf45 100644 --- a/internal/ui/chat/memberstree/keymap.go +++ b/internal/ui/chat/memberstree/keymap.go @@ -1,6 +1,7 @@ package memberstree import ( + uitree "github.com/ayn2op/discordo/internal/ui/tree" "github.com/ayn2op/tview/help" "github.com/ayn2op/tview/keybind" ) @@ -9,7 +10,7 @@ var _ help.KeyMap = Model{} func (m Model) ShortHelp() []keybind.Keybind { kbs := m.cfg.Keybinds.MembersTree - short := []keybind.Keybind{kbs.SelectUp.Keybind, kbs.SelectDown.Keybind} + short := uitree.SelectHelp(m.root, m.selectionState.CurrentNode(), kbs) if node := m.selectionState.CurrentNode(); node != nil { if _, ok := node.Reference().(groupRef); ok { desc := "expand" diff --git a/internal/ui/tree/keymap.go b/internal/ui/tree/keymap.go new file mode 100644 index 0000000..2500871 --- /dev/null +++ b/internal/ui/tree/keymap.go @@ -0,0 +1,34 @@ +package tree + +import ( + "github.com/ayn2op/discordo/internal/config" + "github.com/ayn2op/tview/keybind" + "github.com/ayn2op/tview/tree" +) + +// SelectHelp returns the up and down keybinds that move the selection away from current. +func SelectHelp(root, current *tree.Node, kbs config.TreeKeybinds) []keybind.Keybind { + var help []keybind.Keybind + if canSelectUp(root, current) { + help = append(help, kbs.SelectUp.Keybind) + } + if canSelectDown(root, current) { + help = append(help, kbs.SelectDown.Keybind) + } + return help +} + +// canSelectUp reports whether a node is shown above current. +func canSelectUp(root, current *tree.Node) bool { + children := root.Children() + return current != nil && len(children) > 0 && current != children[0] +} + +// canSelectDown reports whether a node is shown below current. +func canSelectDown(root, current *tree.Node) bool { + last := root + for last.Expanded() && len(last.Children()) > 0 { + last = last.Children()[len(last.Children())-1] + } + return last != root && current != last +} diff --git a/internal/ui/tree/keymap_test.go b/internal/ui/tree/keymap_test.go new file mode 100644 index 0000000..b8f3791 --- /dev/null +++ b/internal/ui/tree/keymap_test.go @@ -0,0 +1,33 @@ +package tree + +import ( + "testing" + + "github.com/ayn2op/tview/tree" +) + +func TestCanSelect(t *testing.T) { + root := tree.NewNode("") + first, last, child := tree.NewNode("first"), tree.NewNode("last"), tree.NewNode("child") + root.AddChild(first).AddChild(last.AddChild(child).Collapse()) + + check := func(name string, current *tree.Node, up, down bool) { + t.Helper() + if got := canSelectUp(root, current); got != up { + t.Errorf("%s: canSelectUp = %v, want %v", name, got, up) + } + if got := canSelectDown(root, current); got != down { + t.Errorf("%s: canSelectDown = %v, want %v", name, got, down) + } + } + + check("none", nil, false, true) + check("first", first, false, true) + check("collapsed last", last, true, false) + last.Expand() + check("expanded last", last, true, true) + check("last child", child, true, false) + if canSelectDown(tree.NewNode(""), nil) { + t.Error("empty tree: canSelectDown = true, want false") + } +}