Compare commits
No commits in common. "9e5b7e790697b67aee9a87c349271cf5c4fd10a7" and "c27c4d903cc2f1cc48d28c1370f1316816132b17" have entirely different histories.
9e5b7e7906
...
c27c4d903c
12 changed files with 1 additions and 257 deletions
|
|
@ -850,12 +850,6 @@ Reply (with mention) to the selected message.
|
||||||
|
|
||||||
Default: `"r"`
|
Default: `"r"`
|
||||||
|
|
||||||
### keybinds.messages_list.react
|
|
||||||
|
|
||||||
Add an emoji reaction to the selected message.
|
|
||||||
|
|
||||||
Default: `"a"`
|
|
||||||
|
|
||||||
### keybinds.messages_list.cancel
|
### keybinds.messages_list.cancel
|
||||||
|
|
||||||
Default: `"esc"`
|
Default: `"esc"`
|
||||||
|
|
|
||||||
|
|
@ -108,8 +108,6 @@ type MessagesListKeybinds struct {
|
||||||
Reply Keybind `toml:"reply"`
|
Reply Keybind `toml:"reply"`
|
||||||
// Reply (with mention) to the selected message.
|
// Reply (with mention) to the selected message.
|
||||||
ReplyMention Keybind `toml:"reply_mention"`
|
ReplyMention Keybind `toml:"reply_mention"`
|
||||||
// Add an emoji reaction to the selected message.
|
|
||||||
React Keybind `toml:"react"`
|
|
||||||
|
|
||||||
Cancel Keybind `toml:"cancel"`
|
Cancel Keybind `toml:"cancel"`
|
||||||
Edit Keybind `toml:"edit"`
|
Edit Keybind `toml:"edit"`
|
||||||
|
|
@ -277,7 +275,6 @@ func defaultKeybinds() Keybinds {
|
||||||
SelectReply: key("sel reply", "s"),
|
SelectReply: key("sel reply", "s"),
|
||||||
Reply: key("reply", "R"),
|
Reply: key("reply", "R"),
|
||||||
ReplyMention: key("@reply", "r"),
|
ReplyMention: key("@reply", "r"),
|
||||||
React: key("react", "a"),
|
|
||||||
|
|
||||||
Cancel: key("cancel", "esc"),
|
Cancel: key("cancel", "esc"),
|
||||||
Edit: key("edit", "e"),
|
Edit: key("edit", "e"),
|
||||||
|
|
|
||||||
|
|
@ -10,20 +10,12 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
ID discord.EmojiID
|
|
||||||
Name string
|
Name string
|
||||||
InsertText string
|
InsertText string
|
||||||
Display string
|
Display string
|
||||||
Custom bool
|
Custom bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// APIEmoji returns the formatted API emoji identifier for reactions.
|
|
||||||
func (i Item) APIEmoji() discord.APIEmoji {
|
|
||||||
if i.Custom && i.ID.IsValid() {
|
|
||||||
return discord.NewAPIEmoji(i.ID, i.Name)
|
|
||||||
}
|
|
||||||
return discord.APIEmoji(i.InsertText)
|
|
||||||
}
|
|
||||||
type itemList []Item
|
type itemList []Item
|
||||||
|
|
||||||
func (l itemList) String(i int) string {
|
func (l itemList) String(i int) string {
|
||||||
|
|
@ -64,7 +56,6 @@ func Search(query string, custom []discord.Emoji, limit int) []Item {
|
||||||
customItems := make([]Item, 0, len(custom))
|
customItems := make([]Item, 0, len(custom))
|
||||||
for _, e := range custom {
|
for _, e := range custom {
|
||||||
customItems = append(customItems, Item{
|
customItems = append(customItems, Item{
|
||||||
ID: e.ID,
|
|
||||||
Name: e.Name,
|
Name: e.Name,
|
||||||
InsertText: e.String(),
|
InsertText: e.String(),
|
||||||
Display: ":" + e.Name + ":",
|
Display: ":" + e.Name + ":",
|
||||||
|
|
|
||||||
|
|
@ -1,63 +0,0 @@
|
||||||
package emojipicker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/ayn2op/arikawa/v3/discord"
|
|
||||||
"github.com/ayn2op/discordo/internal/config"
|
|
||||||
"github.com/ayn2op/discordo/internal/emoji"
|
|
||||||
uipicker "github.com/ayn2op/discordo/internal/ui/picker"
|
|
||||||
"github.com/ayn2op/ningen/v3"
|
|
||||||
"github.com/ayn2op/tview"
|
|
||||||
"github.com/ayn2op/tview/picker"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Model struct {
|
|
||||||
uipicker.Model
|
|
||||||
cfg *config.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewModel(cfg *config.Config) Model {
|
|
||||||
return Model{Model: uipicker.NewModel(cfg, "Add Reaction"), cfg: cfg}
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ tview.Model[Model] = Model{}
|
|
||||||
|
|
||||||
// View shows the picker in a box titled Add Reaction.
|
|
||||||
func (m Model) View() tview.Widget {
|
|
||||||
return m.Model.View(func(item picker.Item) tview.Msg {
|
|
||||||
apiEmoji, ok := item.Reference.(discord.APIEmoji)
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return SelectedMsg{Emoji: apiEmoji}
|
|
||||||
}, CancelMsg{})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
|
|
||||||
var cmd tview.Cmd
|
|
||||||
m.Model, cmd = m.Model.Update(msg)
|
|
||||||
return m, cmd
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshEmojis repopulates the picker with custom guild emojis and Unicode emojis.
|
|
||||||
func (m *Model) RefreshEmojis(state *ningen.State, guildID discord.GuildID) {
|
|
||||||
var customEmojis []discord.Emoji
|
|
||||||
if state != nil && state.EmojiState != nil {
|
|
||||||
guilds, err := state.EmojiState.ForGuild(guildID)
|
|
||||||
if err == nil {
|
|
||||||
for _, g := range guilds {
|
|
||||||
customEmojis = append(customEmojis, g.Emojis...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
results := emoji.Search("", customEmojis, 2500)
|
|
||||||
items := make(picker.Items, 0, len(results))
|
|
||||||
for _, item := range results {
|
|
||||||
items = append(items, picker.Item{
|
|
||||||
Text: item.Display,
|
|
||||||
FilterText: item.Name,
|
|
||||||
Reference: item.APIEmoji(),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
m.SetItems(items)
|
|
||||||
}
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
package emojipicker
|
|
||||||
|
|
||||||
import (
|
|
||||||
"path/filepath"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/ayn2op/arikawa/v3/discord"
|
|
||||||
"github.com/ayn2op/arikawa/v3/state"
|
|
||||||
"github.com/ayn2op/arikawa/v3/state/store/defaultstore"
|
|
||||||
"github.com/ayn2op/discordo/internal/config"
|
|
||||||
"github.com/ayn2op/ningen/v3"
|
|
||||||
ningenEmoji "github.com/ayn2op/ningen/v3/states/emoji"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestEmojiPickerRefresh(t *testing.T) {
|
|
||||||
cfg, err := config.Load(filepath.Join(t.TempDir(), "config.toml"))
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
st := ningen.FromState(state.NewWithStore("", defaultstore.New()))
|
|
||||||
guildID := discord.GuildID(100)
|
|
||||||
st.EmojiState = ningenEmoji.NewState(st.Cabinet)
|
|
||||||
_ = st.Cabinet.GuildSet(&discord.Guild{ID: guildID}, false)
|
|
||||||
_ = st.Cabinet.EmojiSet(guildID, []discord.Emoji{
|
|
||||||
{ID: 555, Name: "custom_pepe"},
|
|
||||||
}, false)
|
|
||||||
|
|
||||||
p := NewModel(cfg)
|
|
||||||
p.RefreshEmojis(st, guildID)
|
|
||||||
|
|
||||||
widget := p.View()
|
|
||||||
if widget == nil {
|
|
||||||
t.Fatal("expected non-nil view")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Test Update
|
|
||||||
p, _ = p.Update(CancelMsg{})
|
|
||||||
}
|
|
||||||
|
|
@ -1,10 +0,0 @@
|
||||||
package emojipicker
|
|
||||||
|
|
||||||
import "github.com/ayn2op/arikawa/v3/discord"
|
|
||||||
|
|
||||||
type (
|
|
||||||
SelectedMsg struct {
|
|
||||||
Emoji discord.APIEmoji
|
|
||||||
}
|
|
||||||
CancelMsg struct{}
|
|
||||||
)
|
|
||||||
|
|
@ -17,7 +17,6 @@ func (m Model) ShortHelp() []keybind.Keybind {
|
||||||
}
|
}
|
||||||
|
|
||||||
if selectedMessage, ok := m.selectedMessage(); ok {
|
if selectedMessage, ok := m.selectedMessage(); ok {
|
||||||
help = append(help, cfg.React.Keybind)
|
|
||||||
if !ui.IsMe(m.state, selectedMessage.Author.ID) {
|
if !ui.IsMe(m.state, selectedMessage.Author.ID) {
|
||||||
help = append(help, cfg.Reply.Keybind)
|
help = append(help, cfg.Reply.Keybind)
|
||||||
}
|
}
|
||||||
|
|
@ -36,7 +35,6 @@ func (m Model) FullHelp() [][]keybind.Keybind {
|
||||||
cfg := m.cfg.Keybinds.MessagesList
|
cfg := m.cfg.Keybinds.MessagesList
|
||||||
var actions, manage, attachments []keybind.Keybind
|
var actions, manage, attachments []keybind.Keybind
|
||||||
if message, ok := m.selectedMessage(); ok {
|
if message, ok := m.selectedMessage(); ok {
|
||||||
actions = append(actions, cfg.React.Keybind)
|
|
||||||
mine := ui.IsMe(m.state, message.Author.ID)
|
mine := ui.IsMe(m.state, message.Author.ID)
|
||||||
if !mine {
|
if !mine {
|
||||||
actions = append(actions, cfg.Reply.Keybind, cfg.ReplyMention.Keybind)
|
actions = append(actions, cfg.Reply.Keybind, cfg.ReplyMention.Keybind)
|
||||||
|
|
|
||||||
|
|
@ -464,8 +464,6 @@ func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
|
||||||
return m, m.seek(m.voiceStatus.Position + seekStep)
|
return m, m.seek(m.voiceStatus.Position + seekStep)
|
||||||
case keybind.Matches(msg, kbs.Download.Keybind):
|
case keybind.Matches(msg, kbs.Download.Keybind):
|
||||||
return m, m.download()
|
return m, m.download()
|
||||||
case keybind.Matches(msg, kbs.React.Keybind):
|
|
||||||
return m, m.react()
|
|
||||||
case keybind.Matches(msg, kbs.Reply.Keybind):
|
case keybind.Matches(msg, kbs.Reply.Keybind):
|
||||||
return m, m.reply(false)
|
return m, m.reply(false)
|
||||||
case keybind.Matches(msg, kbs.ReplyMention.Keybind):
|
case keybind.Matches(msg, kbs.ReplyMention.Keybind):
|
||||||
|
|
|
||||||
|
|
@ -401,20 +401,3 @@ func TestModelReactionsView(t *testing.T) {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestModelReact(t *testing.T) {
|
|
||||||
ml := newTestModel(t, testConfig(t))
|
|
||||||
msg := discord.Message{ID: 10, ChannelID: 1}
|
|
||||||
ml.items = []messageItem{{message: msg}}
|
|
||||||
ml.cursor = 0
|
|
||||||
|
|
||||||
cmd := ml.react()
|
|
||||||
if cmd == nil {
|
|
||||||
t.Fatal("expected non-nil cmd for react()")
|
|
||||||
}
|
|
||||||
result := cmd()
|
|
||||||
reactMsg, ok := result.(ReactMsg)
|
|
||||||
if !ok || reactMsg.Message.ID != 10 {
|
|
||||||
t.Fatalf("result = %v, want ReactMsg with ID 10", result)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -25,11 +25,6 @@ import (
|
||||||
// Msg is implemented by the messages the list sends itself, which must reach it whatever has the focus.
|
// Msg is implemented by the messages the list sends itself, which must reach it whatever has the focus.
|
||||||
type Msg interface{ messagesList() }
|
type Msg interface{ messagesList() }
|
||||||
|
|
||||||
// ReactMsg requests opening the reaction picker for the message.
|
|
||||||
type ReactMsg struct {
|
|
||||||
Message discord.Message
|
|
||||||
}
|
|
||||||
|
|
||||||
type olderMessagesLoadedMsg struct {
|
type olderMessagesLoadedMsg struct {
|
||||||
channelID discord.ChannelID
|
channelID discord.ChannelID
|
||||||
older []discord.Message
|
older []discord.Message
|
||||||
|
|
@ -350,15 +345,6 @@ func (m Model) reply(mention bool) tview.Cmd {
|
||||||
return func() tview.Msg { return ReplyMsg{Message: message, Name: name, Mention: mention} }
|
return func() tview.Msg { return ReplyMsg{Message: message, Name: name, Mention: mention} }
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m Model) react() tview.Cmd {
|
|
||||||
selectedMessage, ok := m.selectedMessage()
|
|
||||||
if !ok {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
message := *selectedMessage
|
|
||||||
return func() tview.Msg { return ReactMsg{Message: message} }
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m Model) editSelectedMessage() tview.Cmd {
|
func (m Model) editSelectedMessage() tview.Cmd {
|
||||||
selectedMessage, ok := m.selectedMessage()
|
selectedMessage, ok := m.selectedMessage()
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ import (
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/channelspicker"
|
"github.com/ayn2op/discordo/internal/ui/chat/channelspicker"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/commandslist"
|
"github.com/ayn2op/discordo/internal/ui/chat/commandslist"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/composer"
|
"github.com/ayn2op/discordo/internal/ui/chat/composer"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/emojipicker"
|
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/emojislist"
|
"github.com/ayn2op/discordo/internal/ui/chat/emojislist"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/guildstree"
|
"github.com/ayn2op/discordo/internal/ui/chat/guildstree"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/memberstree"
|
"github.com/ayn2op/discordo/internal/ui/chat/memberstree"
|
||||||
|
|
@ -55,11 +54,9 @@ type Model struct {
|
||||||
membersTree memberstree.Model
|
membersTree memberstree.Model
|
||||||
messagesList messageslist.Model
|
messagesList messageslist.Model
|
||||||
composer composer.Model
|
composer composer.Model
|
||||||
channelsPicker channelspicker.Model
|
channelsPicker channelspicker.Model
|
||||||
// attachmentsPicker picks an attachment or link of the selected message.
|
// attachmentsPicker picks an attachment or link of the selected message.
|
||||||
attachmentsPicker attachmentspicker.Model
|
attachmentsPicker attachmentspicker.Model
|
||||||
emojiPicker emojipicker.Model
|
|
||||||
reactingMessage *discord.Message
|
|
||||||
|
|
||||||
selectedChannel *discord.Channel
|
selectedChannel *discord.Channel
|
||||||
// windowUnfocused reports whether the terminal window lost focus.
|
// windowUnfocused reports whether the terminal window lost focus.
|
||||||
|
|
@ -115,7 +112,6 @@ func NewModel(cfg *config.Config, token string) Model {
|
||||||
m.composer = composer.NewModel(cfg, m.state)
|
m.composer = composer.NewModel(cfg, m.state)
|
||||||
m.channelsPicker = channelspicker.NewModel(cfg)
|
m.channelsPicker = channelspicker.NewModel(cfg)
|
||||||
m.attachmentsPicker = attachmentspicker.NewModel(cfg)
|
m.attachmentsPicker = attachmentspicker.NewModel(cfg)
|
||||||
m.emojiPicker = emojipicker.NewModel(cfg)
|
|
||||||
|
|
||||||
m.guildsTreeVisible = cfg.Sidebar.Visible
|
m.guildsTreeVisible = cfg.Sidebar.Visible
|
||||||
m.membersTreeVisible = cfg.MembersTree.Visible
|
m.membersTreeVisible = cfg.MembersTree.Visible
|
||||||
|
|
@ -135,7 +131,6 @@ const (
|
||||||
overlayNone overlay = iota
|
overlayNone overlay = iota
|
||||||
overlayChannelsPicker
|
overlayChannelsPicker
|
||||||
overlayAttachmentsPicker
|
overlayAttachmentsPicker
|
||||||
overlayEmojiPicker
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// pickerView returns the view of the picker shown on top, or nil if none is open.
|
// pickerView returns the view of the picker shown on top, or nil if none is open.
|
||||||
|
|
@ -145,8 +140,6 @@ func (m Model) pickerView() tview.Widget {
|
||||||
return m.channelsPicker.View()
|
return m.channelsPicker.View()
|
||||||
case overlayAttachmentsPicker:
|
case overlayAttachmentsPicker:
|
||||||
return m.attachmentsPicker.View()
|
return m.attachmentsPicker.View()
|
||||||
case overlayEmojiPicker:
|
|
||||||
return m.emojiPicker.View()
|
|
||||||
default:
|
default:
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
@ -252,54 +245,6 @@ func (m Model) Update(msg tview.Msg) (Model, tview.Cmd) {
|
||||||
m.attachmentsPicker.SetItems(picker.Items(msg))
|
m.attachmentsPicker.SetItems(picker.Items(msg))
|
||||||
m.overlay = overlayAttachmentsPicker
|
m.overlay = overlayAttachmentsPicker
|
||||||
return m, nil
|
return m, nil
|
||||||
case messageslist.ReactMsg:
|
|
||||||
m.overlay = overlayEmojiPicker
|
|
||||||
m.reactingMessage = &msg.Message
|
|
||||||
var gID discord.GuildID
|
|
||||||
if m.selectedChannel != nil {
|
|
||||||
gID = m.selectedChannel.GuildID
|
|
||||||
}
|
|
||||||
m.emojiPicker.RefreshEmojis(m.state, gID)
|
|
||||||
return m, nil
|
|
||||||
case emojipicker.CancelMsg:
|
|
||||||
m.overlay = overlayNone
|
|
||||||
m.reactingMessage = nil
|
|
||||||
return m, nil
|
|
||||||
case emojipicker.SelectedMsg:
|
|
||||||
m.overlay = overlayNone
|
|
||||||
if m.reactingMessage == nil || m.selectedChannel == nil {
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
chID := m.selectedChannel.ID
|
|
||||||
msgID := m.reactingMessage.ID
|
|
||||||
targetEmoji := msg.Emoji
|
|
||||||
reactions := m.reactingMessage.Reactions
|
|
||||||
m.reactingMessage = nil
|
|
||||||
|
|
||||||
alreadyReacted := false
|
|
||||||
for _, r := range reactions {
|
|
||||||
if r.Emoji.APIString() == targetEmoji && r.Me {
|
|
||||||
alreadyReacted = true
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return m, func() tview.Msg {
|
|
||||||
if m.state == nil || m.state.Client == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
client := m.state.Client
|
|
||||||
if alreadyReacted {
|
|
||||||
if err := client.Unreact(chID, msgID, targetEmoji); err != nil {
|
|
||||||
slog.Error("failed to remove reaction", "channel_id", chID, "message_id", msgID, "emoji", targetEmoji, "err", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err := client.React(chID, msgID, targetEmoji); err != nil {
|
|
||||||
slog.Error("failed to add reaction", "channel_id", chID, "message_id", msgID, "emoji", targetEmoji, "err", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
case messageslist.ReplyMsg:
|
case messageslist.ReplyMsg:
|
||||||
m.composer.StartReply(msg.Message, msg.Name, msg.Mention)
|
m.composer.StartReply(msg.Message, msg.Name, msg.Mention)
|
||||||
m.setFocus(paneComposer)
|
m.setFocus(paneComposer)
|
||||||
|
|
@ -383,8 +328,6 @@ func (m *Model) route(msg tview.Msg) tview.Cmd {
|
||||||
m.channelsPicker, cmd = m.channelsPicker.Update(msg)
|
m.channelsPicker, cmd = m.channelsPicker.Update(msg)
|
||||||
case overlayAttachmentsPicker:
|
case overlayAttachmentsPicker:
|
||||||
m.attachmentsPicker, cmd = m.attachmentsPicker.Update(msg)
|
m.attachmentsPicker, cmd = m.attachmentsPicker.Update(msg)
|
||||||
case overlayEmojiPicker:
|
|
||||||
m.emojiPicker, cmd = m.emojiPicker.Update(msg)
|
|
||||||
default:
|
default:
|
||||||
cmd = m.updatePane(m.focused, msg)
|
cmd = m.updatePane(m.focused, msg)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,6 @@ import (
|
||||||
"github.com/ayn2op/arikawa/v3/discord"
|
"github.com/ayn2op/arikawa/v3/discord"
|
||||||
"github.com/ayn2op/arikawa/v3/gateway"
|
"github.com/ayn2op/arikawa/v3/gateway"
|
||||||
"github.com/ayn2op/discordo/internal/config"
|
"github.com/ayn2op/discordo/internal/config"
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/emojipicker"
|
|
||||||
"github.com/ayn2op/discordo/internal/ui/chat/messageslist"
|
|
||||||
"github.com/ayn2op/tview"
|
"github.com/ayn2op/tview"
|
||||||
"github.com/gdamore/tcell/v3"
|
"github.com/gdamore/tcell/v3"
|
||||||
)
|
)
|
||||||
|
|
@ -101,35 +99,3 @@ func TestModelCycleFocus(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestModelReactions(t *testing.T) {
|
|
||||||
m := newTestModel(t)
|
|
||||||
channel := discord.Channel{ID: 1, GuildID: 2, Type: discord.GuildText}
|
|
||||||
m.setSelectedChannel(&channel)
|
|
||||||
|
|
||||||
msg := discord.Message{ID: 10, ChannelID: 1}
|
|
||||||
*m, _ = m.Update(messageslist.ReactMsg{Message: msg})
|
|
||||||
if m.overlay != overlayEmojiPicker {
|
|
||||||
t.Fatalf("overlay = %v, want overlayEmojiPicker", m.overlay)
|
|
||||||
}
|
|
||||||
if m.reactingMessage == nil || m.reactingMessage.ID != 10 {
|
|
||||||
t.Fatalf("reactingMessage = %v, want ID 10", m.reactingMessage)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Cancel closes overlay
|
|
||||||
*m, _ = m.Update(emojipicker.CancelMsg{})
|
|
||||||
if m.overlay != overlayNone {
|
|
||||||
t.Fatalf("overlay after cancel = %v, want overlayNone", m.overlay)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Select triggers react command and closes overlay
|
|
||||||
*m, _ = m.Update(messageslist.ReactMsg{Message: msg})
|
|
||||||
var cmd tview.Cmd
|
|
||||||
*m, cmd = m.Update(emojipicker.SelectedMsg{Emoji: discord.APIEmoji("😄")})
|
|
||||||
if m.overlay != overlayNone {
|
|
||||||
t.Fatalf("overlay after select = %v, want overlayNone", m.overlay)
|
|
||||||
}
|
|
||||||
if cmd == nil {
|
|
||||||
t.Fatal("expected non-nil command for reaction action")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue