145 lines
4.5 KiB
Go
145 lines
4.5 KiB
Go
package chat
|
|
|
|
import (
|
|
"log/slog"
|
|
|
|
"github.com/ayn2op/arikawa/v3/discord"
|
|
"github.com/ayn2op/arikawa/v3/gateway"
|
|
"github.com/ayn2op/arikawa/v3/utils/httputil/httpdriver"
|
|
"github.com/ayn2op/arikawa/v3/utils/ws"
|
|
"github.com/ayn2op/discordo/internal/ui"
|
|
"github.com/ayn2op/ningen/v3/states/read"
|
|
"github.com/ayn2op/tview"
|
|
)
|
|
|
|
func onRequest(r httpdriver.Request) error {
|
|
if req, ok := r.(*httpdriver.DefaultRequest); ok {
|
|
slog.Debug("new HTTP request", "method", req.Method, "url", req.URL)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (m *Model) loadGuildsTree(event *gateway.ReadyEvent) tview.Cmd {
|
|
cmd := m.updatePane(paneGuildsTree, event)
|
|
m.setFocus(paneGuildsTree)
|
|
return cmd
|
|
}
|
|
|
|
func (m *Model) addMessageOrNotify(message *gateway.MessageCreateEvent) tview.Cmd {
|
|
cmd := m.updatePane(paneGuildsTree, message)
|
|
|
|
if channel := m.selectedChannel; channel != nil && channel.ID == message.ChannelID {
|
|
delete(m.typers, message.Author.ID)
|
|
cmd = tview.Batch(cmd, m.messagesList.AddMessage(message.Message))
|
|
if !m.windowUnfocused || !m.cfg.Notifications.WhenUnfocused {
|
|
return cmd
|
|
}
|
|
}
|
|
return tview.Batch(cmd, m.notify(*message))
|
|
}
|
|
|
|
func (m Model) notify(message gateway.MessageCreateEvent) tview.Cmd {
|
|
return func() tview.Msg {
|
|
if !m.cfg.Notifications.Enabled || m.cfg.Status == discord.DoNotDisturbStatus {
|
|
return nil
|
|
}
|
|
|
|
mentions := m.state.MessageMentions(&message.Message)
|
|
if mentions == 0 {
|
|
return nil
|
|
}
|
|
|
|
// Handle sent files
|
|
content := message.Content
|
|
if message.Content == "" && len(message.Attachments) > 0 {
|
|
content = "Uploaded " + message.Attachments[0].Filename
|
|
}
|
|
|
|
if content == "" {
|
|
return nil
|
|
}
|
|
|
|
title := message.Author.DisplayOrUsername()
|
|
channel, err := m.state.Cabinet.Channel(message.ChannelID)
|
|
if err != nil {
|
|
slog.Error("failed to get channel from state", "err", err, "channel_id", message.ChannelID)
|
|
return nil
|
|
}
|
|
|
|
if channel.GuildID.IsValid() {
|
|
guild, err := m.state.Cabinet.Guild(channel.GuildID)
|
|
if err != nil {
|
|
slog.Error("failed to get guild from state", "err", err, "guild_id", channel.GuildID)
|
|
return nil
|
|
}
|
|
|
|
if member := message.Member; member != nil && member.Nick != "" {
|
|
title = member.Nick
|
|
}
|
|
|
|
title += " (#" + channel.Name + ", " + guild.Name + ")"
|
|
}
|
|
|
|
return tview.Notify(title, content)()
|
|
}
|
|
}
|
|
|
|
func (m Model) refreshMemberNames(event *gateway.GuildMembersChunkEvent) tview.Cmd {
|
|
m.messagesList.InvalidateRendered()
|
|
return m.composer.CacheMemberSearch(event)
|
|
}
|
|
|
|
func (m Model) showTypingIndicator(event *gateway.TypingStartEvent) tview.Cmd {
|
|
if channel := m.selectedChannel; channel == nil || channel.ID != event.ChannelID || ui.IsMe(m.state, event.UserID) {
|
|
return nil
|
|
}
|
|
return m.addTyper(event.UserID)
|
|
}
|
|
|
|
// applyEvent updates the model with a gateway event and returns what the event needs done.
|
|
func (m *Model) applyEvent(event gateway.Event) tview.Cmd {
|
|
switch event := event.(type) {
|
|
case *ws.RawEvent:
|
|
slog.Debug("new raw event", "code", event.OriginalCode, "type", event.OriginalType)
|
|
|
|
case *gateway.ReadyEvent:
|
|
return tview.Batch(m.loadGuildsTree(event), m.updatePane(paneMembersTree, event))
|
|
|
|
case *gateway.MessageCreateEvent:
|
|
return m.addMessageOrNotify(event)
|
|
case *gateway.MessageUpdateEvent:
|
|
return m.messagesList.UpdateMessage(event.Message)
|
|
case *gateway.PresenceUpdateEvent:
|
|
return tview.Batch(m.updatePane(paneGuildsTree, event), m.updatePane(paneMembersTree, event))
|
|
case *gateway.GuildMemberListUpdateEvent:
|
|
return m.updatePane(paneMembersTree, event)
|
|
case *gateway.MessageDeleteEvent:
|
|
m.messagesList.DeleteMessage(event.ChannelID, event.ID)
|
|
case *gateway.MessageReactionAddEvent:
|
|
m.messagesList.RefreshMessage(event.ChannelID, event.MessageID)
|
|
case *gateway.MessageReactionAddManyEvent:
|
|
m.messagesList.RefreshMessage(event.ChannelID, event.MessageID)
|
|
case *gateway.MessageReactionRemoveEvent:
|
|
m.messagesList.RefreshMessage(event.ChannelID, event.MessageID)
|
|
case *gateway.MessageReactionRemoveAllEvent:
|
|
m.messagesList.RefreshMessage(event.ChannelID, event.MessageID)
|
|
case *gateway.MessageReactionRemoveEmojiEvent:
|
|
m.messagesList.RefreshMessage(event.ChannelID, event.MessageID)
|
|
|
|
case *gateway.GuildMembersChunkEvent:
|
|
return m.refreshMemberNames(event)
|
|
case *gateway.GuildMemberRemoveEvent:
|
|
m.composer.OnGuildMemberRemove(event)
|
|
|
|
case *gateway.TypingStartEvent:
|
|
if m.cfg.TypingIndicator.Receive {
|
|
return m.showTypingIndicator(event)
|
|
}
|
|
|
|
case *read.UpdateEvent:
|
|
return m.updatePane(paneGuildsTree, event)
|
|
case *gateway.VoiceStateUpdateEvent:
|
|
return m.updatePane(paneGuildsTree, event)
|
|
}
|
|
return nil
|
|
}
|