| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150 |
- package chat
- import (
- "log/slog"
- "strings"
- "github.com/ayn2op/discordo/internal/config"
- "github.com/ayn2op/discordo/internal/ui"
- "github.com/ayn2op/discordo/pkg/picker"
- "github.com/ayn2op/tview"
- "github.com/ayn2op/tview/help"
- "github.com/ayn2op/tview/keybind"
- "github.com/diamondburned/arikawa/v3/discord"
- "github.com/gdamore/tcell/v3"
- )
- type channelsPicker struct {
- *picker.Picker
- chatView *Model
- }
- var _ help.KeyMap = (*channelsPicker)(nil)
- func newChannelsPicker(cfg *config.Config, chatView *Model) *channelsPicker {
- cp := &channelsPicker{picker.New(), chatView}
- cp.Box = ui.ConfigureBox(tview.NewBox(), &cfg.Theme)
- // When a child of the parent flex is focused, the parent layout itself is not reported as focused.
- // Instead, the focused child (picker) is considered focused.
- // Therefore, we manually set the active border style on the picker to ensure it displays the correct focused appearance.
- cp.
- SetBlurFunc(nil).
- SetFocusFunc(nil).
- SetBorderSet(cfg.Theme.Border.ActiveSet.BorderSet).
- SetBorderStyle(cfg.Theme.Border.ActiveStyle.Style).
- SetTitleStyle(cfg.Theme.Title.ActiveStyle.Style).
- SetFooterStyle(cfg.Theme.Footer.ActiveStyle.Style)
- cp.SetTitle("Channels")
- cp.SetScrollBarVisibility(cfg.Theme.ScrollBar.Visibility.ScrollBarVisibility)
- cp.SetScrollBar(tview.NewScrollBar().
- SetTrackStyle(cfg.Theme.ScrollBar.TrackStyle.Style).
- SetThumbStyle(cfg.Theme.ScrollBar.ThumbStyle.Style).
- SetGlyphSet(cfg.Theme.ScrollBar.GlyphSet.GlyphSet))
- cp.SetKeyMap(&picker.KeyMap{
- Cancel: cfg.Keybinds.Picker.Cancel.Keybind,
- Up: cfg.Keybinds.Picker.Up.Keybind,
- Down: cfg.Keybinds.Picker.Down.Keybind,
- Top: cfg.Keybinds.Picker.Top.Keybind,
- Bottom: cfg.Keybinds.Picker.Bottom.Keybind,
- Select: cfg.Keybinds.Picker.Select.Keybind,
- })
- return cp
- }
- func (cp *channelsPicker) HandleEvent(event tcell.Event) tview.Command {
- switch event := event.(type) {
- case *picker.SelectedEvent:
- channelID, ok := event.Reference.(discord.ChannelID)
- if !ok || !channelID.IsValid() {
- return nil
- }
- channel, err := cp.chatView.state.Cabinet.Channel(channelID)
- if err != nil {
- slog.Error("failed to get channel from state", "err", err, "channel_id", channelID)
- return nil
- }
- node := cp.chatView.guildsTree.findNodeByChannelID(channel.ID)
- if node == nil {
- slog.Error("failed to locate channel in tree", "channel_id", channel.ID)
- return nil
- }
- cp.chatView.guildsTree.expandPathToNode(node)
- cp.chatView.guildsTree.SetCurrentNode(node)
- if channel.Type != discord.GuildCategory {
- cp.chatView.guildsTree.onSelected(node)
- }
- cp.chatView.closePicker()
- cp.chatView.focusMessageInput()
- return nil
- case *picker.CancelEvent:
- cp.chatView.closePicker()
- return nil
- }
- return cp.Picker.HandleEvent(event)
- }
- func (cp *channelsPicker) update() {
- cp.ClearItems()
- state := cp.chatView.state
- privateChannels, err := state.Cabinet.PrivateChannels()
- if err != nil {
- slog.Error("failed to get private channels from state", "err", err)
- return
- }
- ui.SortPrivateChannels(privateChannels)
- for _, channel := range privateChannels {
- cp.addChannel(nil, channel)
- }
- guilds, err := state.Cabinet.Guilds()
- if err != nil {
- slog.Error("failed to get guilds from state", "err", err)
- return
- }
- for _, guild := range guilds {
- channels, err := state.Cabinet.Channels(guild.ID)
- if err != nil {
- slog.Error("failed to get channels from state", "err", err, "guild_id", guild.ID)
- continue
- }
- for _, channel := range channels {
- cp.addChannel(&guild, channel)
- }
- }
- cp.Update()
- }
- func (cp *channelsPicker) addChannel(guild *discord.Guild, channel discord.Channel) {
- var b strings.Builder
- b.WriteString(ui.ChannelToString(channel, cp.chatView.cfg.Icons, cp.chatView.state))
- if guild != nil {
- b.WriteString(" - ")
- b.WriteString(guild.Name)
- }
- name := b.String()
- cp.AddItem(picker.Item{Text: name, FilterText: name, Reference: channel.ID})
- }
- func (cp *channelsPicker) ShortHelp() []keybind.Keybind {
- cfg := cp.chatView.cfg.Keybinds.Picker
- return []keybind.Keybind{cfg.Up.Keybind, cfg.Down.Keybind, cfg.Select.Keybind, cfg.Cancel.Keybind}
- }
- func (cp *channelsPicker) FullHelp() [][]keybind.Keybind {
- cfg := cp.chatView.cfg.Keybinds.Picker
- return [][]keybind.Keybind{
- {cfg.Up.Keybind, cfg.Down.Keybind, cfg.Top.Keybind, cfg.Bottom.Keybind},
- {cfg.Select.Keybind, cfg.Cancel.Keybind},
- }
- }
|