// search_picker.go implements a fuzzy search overlay for messages in the // current channel. Opened via the search keybind, it lets users filter // messages by author name and content, then jump to the selected message. package chat import ( "github.com/ayn2op/discordo/internal/config" "github.com/ayn2op/tview" "github.com/ayn2op/tview/help" "github.com/ayn2op/tview/keybind" "github.com/ayn2op/tview/picker" ) const searchPickerLayerName = "searchPicker" type searchPicker struct { *picker.Model chatView *Model browseMode bool } var _ help.KeyMap = (*searchPicker)(nil) func newSearchPicker(cfg *config.Config, chatView *Model) *searchPicker { sp := &searchPicker{Model: picker.NewModel(), chatView: chatView} ConfigurePicker(sp.Model, cfg, "Search") return sp } // resetBrowse starts the search picker in input mode so users can type a query immediately. func (sp *searchPicker) resetBrowse() { sp.browseMode = false } func (sp *searchPicker) HandleEvent(event tview.Event) tview.Command { switch event := event.(type) { case *tview.KeyEvent: if cmd, handled := pickerBrowseHandleKey(event, &sp.browseMode, sp.Model, func() { sp.chatView.closeSearch() }); handled { return cmd } case *picker.SelectedEvent: messageIndex, ok := event.Reference.(int) if !ok { return nil } sp.chatView.closeSearch() sp.chatView.messagesList.SetCursor(messageIndex) return tview.SetFocus(sp.chatView.messagesList) case *picker.CancelEvent: sp.chatView.closeSearch() return nil } return sp.Model.HandleEvent(event) } func (sp *searchPicker) update() { messages := sp.chatView.messagesList.messages items := make(picker.Items, 0, len(messages)) for i, msg := range messages { text := msg.Author.DisplayOrUsername() + ": " + msg.Content if len(text) > 120 { text = text[:120] + "..." } items = append(items, picker.Item{ Text: text, FilterText: msg.Author.DisplayOrUsername() + " " + msg.Content, Reference: i, }) } sp.Model.SetItems(items) } func (sp *searchPicker) ShortHelp() []keybind.Keybind { return pickerShortHelp(sp.chatView.cfg.Keybinds.Picker) } func (sp *searchPicker) FullHelp() [][]keybind.Keybind { return pickerFullHelp(sp.chatView.cfg.Keybinds.Picker) }