70 lines
2.1 KiB
Go
70 lines
2.1 KiB
Go
// Package picker holds what discordo's pickers share.
|
|
package picker
|
|
|
|
import (
|
|
"github.com/ayn2op/discordo/internal/config"
|
|
"github.com/ayn2op/discordo/internal/ui"
|
|
"github.com/ayn2op/tview"
|
|
"github.com/ayn2op/tview/keybind"
|
|
"github.com/ayn2op/tview/picker"
|
|
"github.com/ayn2op/tview/scrollbar"
|
|
)
|
|
|
|
// Model is a picker of items shown in a box titled title.
|
|
type Model struct {
|
|
items picker.Items
|
|
searchState picker.SearchState
|
|
cfg *config.Config
|
|
title string
|
|
}
|
|
|
|
func NewModel(cfg *config.Config, title string) Model {
|
|
return Model{searchState: picker.NewSearchState(), cfg: cfg, title: title}
|
|
}
|
|
|
|
func (Model) Init() tview.Cmd { return nil }
|
|
|
|
// View shows the picker, turning the selected item into the message onSelect returns and canceling with onCancel.
|
|
func (m Model) View(onSelect func(picker.Item) tview.Msg, onCancel tview.Msg) tview.Widget {
|
|
cfg := m.cfg
|
|
bar := scrollbar.New().
|
|
SymbolSet(cfg.UI.ScrollBar.SymbolSet.SymbolSet).
|
|
Style(cfg.Theme.ScrollBar.TrackStyle.Style).
|
|
ThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style)
|
|
p := picker.New(m.items, &m.searchState).
|
|
ScrollBar(bar, cfg.UI.ScrollBar.Visibility.ScrollBarVisibility).
|
|
Keybind(bindKeys(cfg.Keybinds.Picker)).
|
|
ListKeybind(ui.SelectionKeybind(cfg.Keybinds.Picker.SelectionKeybinds)).
|
|
OnChange(func(s *picker.SearchState) tview.Msg { return changeMsg(*s) }).
|
|
OnSelect(onSelect).
|
|
OnCancel(onCancel)
|
|
return ui.Box(p, cfg, true).Title(m.title)
|
|
}
|
|
|
|
func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
|
|
if msg, ok := msg.(changeMsg); ok {
|
|
m.searchState = picker.SearchState(msg)
|
|
}
|
|
return m, nil
|
|
}
|
|
|
|
// SetItems replaces the items and clears the query.
|
|
func (m *Model) SetItems(items picker.Items) {
|
|
m.items = items
|
|
m.searchState.Reset()
|
|
}
|
|
|
|
// Reset clears the query.
|
|
func (m *Model) Reset() { m.searchState.Reset() }
|
|
|
|
func bindKeys(kbs config.PickerKeybinds) func(tview.KeyMsg) picker.Action {
|
|
return func(key tview.KeyMsg) picker.Action {
|
|
switch {
|
|
case keybind.Matches(key, kbs.Select.Keybind):
|
|
return picker.ActionSelect
|
|
case keybind.Matches(key, kbs.Cancel.Keybind):
|
|
return picker.ActionCancel
|
|
}
|
|
return picker.ActionNone
|
|
}
|
|
}
|