refactor(cmd): separate chat UI widgets from application

This commit is contained in:
ayn2op 2025-11-23 14:03:34 -05:00
parent 1589d7b47f
commit b3ac0dc6b4
6 changed files with 248 additions and 217 deletions

View file

@ -4,9 +4,7 @@ import (
"log/slog"
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/discordo/internal/keyring"
"github.com/ayn2op/discordo/internal/login"
"github.com/ayn2op/discordo/internal/ui"
"github.com/ayn2op/tview"
"github.com/gdamore/tcell/v2"
"golang.design/x/clipboard"
@ -20,33 +18,21 @@ const (
)
type application struct {
cfg *config.Config
*tview.Application
pages *tview.Pages
flex *tview.Flex
guildsTree *guildsTree
messagesList *messagesList
messageInput *messageInput
chatView *chatView
cfg *config.Config
}
func newApplication(cfg *config.Config) *application {
app := &application{
cfg: cfg,
Application: tview.NewApplication(),
pages: tview.NewPages(),
flex: tview.NewFlex(),
guildsTree: newGuildsTree(cfg),
messagesList: newMessagesList(cfg),
messageInput: newMessageInput(cfg),
Application: tview.NewApplication(),
cfg: cfg,
}
if err := clipboard.Init(); err != nil {
slog.Error("failed to init clipboard", "err", err)
}
app.pages.SetInputCapture(app.onPagesInputCapture)
app.
EnableMouse(cfg.Mouse).
SetInputCapture(app.onInputCapture).
@ -65,12 +51,12 @@ func (a *application) run(token string) error {
return a.SetRoot(loginForm, true).Run()
}
a.chatView = newChatView(a.Application, a.cfg)
if err := openState(token); err != nil {
return err
}
a.init()
return a.SetRoot(a.pages, true).Run()
return a.SetRoot(a.chatView, true).Run()
}
func (a *application) quit() {
@ -83,23 +69,6 @@ func (a *application) quit() {
a.Stop()
}
func (a *application) init() {
a.pages.Clear()
a.flex.Clear()
right := tview.NewFlex().
SetDirection(tview.FlexRow).
AddItem(a.messagesList, 0, 1, false).
AddItem(a.messageInput, 3, 1, false)
// The guilds tree is always focused first at start-up.
a.flex.
AddItem(a.guildsTree, 0, 1, true).
AddItem(right, 0, 4, false)
a.pages.AddAndSwitchToPage(flexPageName, a.flex, true)
}
func (a *application) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
switch event.Name() {
case a.cfg.Keys.Quit:
@ -112,117 +81,3 @@ func (a *application) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
return event
}
func (a *application) onPagesInputCapture(event *tcell.EventKey) *tcell.EventKey {
switch event.Name() {
case a.cfg.Keys.FocusGuildsTree:
a.messageInput.removeMentionsList()
a.focusGuildsTree()
return nil
case a.cfg.Keys.FocusMessagesList:
a.messageInput.removeMentionsList()
a.SetFocus(a.messagesList)
return nil
case a.cfg.Keys.FocusMessageInput:
a.focusMessageInput()
return nil
case a.cfg.Keys.FocusPrevious:
a.focusPrevious()
return nil
case a.cfg.Keys.FocusNext:
a.focusNext()
return nil
case a.cfg.Keys.Logout:
a.quit()
if err := keyring.DeleteToken(); err != nil {
slog.Error("failed to delete token from keyring", "err", err)
return nil
}
return nil
case a.cfg.Keys.ToggleGuildsTree:
a.toggleGuildsTree()
return nil
}
return event
}
func (a *application) toggleGuildsTree() {
// The guilds tree is visible if the number of items is two.
if a.flex.GetItemCount() == 2 {
a.flex.RemoveItem(a.guildsTree)
if a.guildsTree.HasFocus() {
a.SetFocus(a.flex)
}
} else {
a.init()
a.SetFocus(a.guildsTree)
}
}
func (a *application) focusGuildsTree() bool {
// The guilds tree is not hidden if the number of items is two.
if a.flex.GetItemCount() == 2 {
a.SetFocus(a.guildsTree)
return true
}
return false
}
func (a *application) focusMessageInput() bool {
if !a.messageInput.GetDisabled() {
a.SetFocus(a.messageInput)
return true
}
return false
}
func (a *application) focusPrevious() {
switch a.GetFocus() {
case a.guildsTree:
a.SetFocus(a.messageInput)
case a.messagesList: // Handle both a.messagesList and a.flex as well as other edge cases (if there is).
if ok := a.focusGuildsTree(); !ok {
a.SetFocus(a.messageInput)
}
case a.messageInput:
a.SetFocus(a.messagesList)
}
}
func (a *application) focusNext() {
switch a.GetFocus() {
case a.guildsTree:
a.SetFocus(a.messagesList)
case a.messagesList:
a.SetFocus(a.messageInput)
case a.messageInput: // Handle both a.messageInput and a.flex as well as other edge cases (if there is).
if ok := a.focusGuildsTree(); !ok {
a.SetFocus(a.messagesList)
}
}
}
func (a *application) showConfirmModal(prompt string, buttons []string, onDone func(label string)) {
previousFocus := a.GetFocus()
modal := tview.NewModal().
SetText(prompt).
AddButtons(buttons).
SetDoneFunc(func(_ int, buttonLabel string) {
a.pages.RemovePage(confirmModalPageName).SwitchToPage(flexPageName)
a.SetFocus(previousFocus)
if onDone != nil {
onDone(buttonLabel)
}
})
a.pages.
AddAndSwitchToPage(confirmModalPageName, ui.Centered(modal, 0, 0), true).
ShowPage(flexPageName)
}

176
cmd/chatview.go Normal file
View file

@ -0,0 +1,176 @@
package cmd
import (
"log/slog"
"github.com/ayn2op/discordo/internal/config"
"github.com/ayn2op/discordo/internal/keyring"
"github.com/ayn2op/discordo/internal/ui"
"github.com/ayn2op/tview"
"github.com/gdamore/tcell/v2"
)
type chatView struct {
*tview.Pages
mainFlex *tview.Flex
rightFlex *tview.Flex
guildsTree *guildsTree
messagesList *messagesList
messageInput *messageInput
app *tview.Application
cfg *config.Config
}
func newChatView(app *tview.Application, cfg *config.Config) *chatView {
cv := &chatView{
Pages: tview.NewPages(),
mainFlex: tview.NewFlex(),
rightFlex: tview.NewFlex(),
guildsTree: newGuildsTree(cfg),
messagesList: newMessagesList(cfg),
messageInput: newMessageInput(cfg),
app: app,
cfg: cfg,
}
cv.SetInputCapture(cv.onInputCapture)
cv.init()
return cv
}
func (cv *chatView) init() {
cv.Clear()
cv.mainFlex.Clear()
cv.rightFlex.
SetDirection(tview.FlexRow).
AddItem(cv.messagesList, 0, 1, false).
AddItem(cv.messageInput, 3, 1, false)
// The guilds tree is always focused first at start-up.
cv.mainFlex.
AddItem(cv.guildsTree, 0, 1, true).
AddItem(cv.rightFlex, 0, 4, false)
cv.AddAndSwitchToPage(flexPageName, cv.mainFlex, true)
}
func (cv *chatView) toggleGuildsTree() {
// The guilds tree is visible if the number of items is two.
if cv.mainFlex.GetItemCount() == 2 {
cv.mainFlex.RemoveItem(cv.guildsTree)
if cv.guildsTree.HasFocus() {
cv.app.SetFocus(cv.mainFlex)
}
} else {
cv.init()
cv.app.SetFocus(cv.guildsTree)
}
}
func (cv *chatView) focusGuildsTree() bool {
// The guilds tree is not hidden if the number of items is two.
if cv.mainFlex.GetItemCount() == 2 {
cv.app.SetFocus(cv.guildsTree)
return true
}
return false
}
func (cv *chatView) focusMessageInput() bool {
if !cv.messageInput.GetDisabled() {
cv.app.SetFocus(cv.messageInput)
return true
}
return false
}
func (cv *chatView) focusPrevious() {
switch cv.app.GetFocus() {
case cv.guildsTree:
cv.app.SetFocus(cv.messageInput)
case cv.messagesList: // Handle both a.messagesList and a.flex as well as other edge cases (if there is).
if ok := cv.focusGuildsTree(); !ok {
cv.app.SetFocus(cv.messageInput)
}
case cv.messageInput:
cv.app.SetFocus(cv.messagesList)
}
}
func (cv *chatView) focusNext() {
switch cv.app.GetFocus() {
case cv.guildsTree:
cv.app.SetFocus(cv.messagesList)
case cv.messagesList:
cv.app.SetFocus(cv.messageInput)
case cv.messageInput: // Handle both a.messageInput and a.flex as well as other edge cases (if there is).
if ok := cv.focusGuildsTree(); !ok {
cv.app.SetFocus(cv.messagesList)
}
}
}
func (cv *chatView) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
switch event.Name() {
case cv.cfg.Keys.FocusGuildsTree:
cv.messageInput.removeMentionsList()
cv.focusGuildsTree()
return nil
case cv.cfg.Keys.FocusMessagesList:
cv.messageInput.removeMentionsList()
cv.app.SetFocus(cv.messagesList)
return nil
case cv.cfg.Keys.FocusMessageInput:
cv.focusMessageInput()
return nil
case cv.cfg.Keys.FocusPrevious:
cv.focusPrevious()
return nil
case cv.cfg.Keys.FocusNext:
cv.focusNext()
return nil
case cv.cfg.Keys.Logout:
app.quit()
if err := keyring.DeleteToken(); err != nil {
slog.Error("failed to delete token from keyring", "err", err)
return nil
}
return nil
case cv.cfg.Keys.ToggleGuildsTree:
cv.toggleGuildsTree()
return nil
}
return event
}
func (cv *chatView) showConfirmModal(prompt string, buttons []string, onDone func(label string)) {
previousFocus := cv.app.GetFocus()
modal := tview.NewModal().
SetText(prompt).
AddButtons(buttons).
SetDoneFunc(func(_ int, buttonLabel string) {
cv.RemovePage(confirmModalPageName).SwitchToPage(flexPageName)
cv.app.SetFocus(previousFocus)
if onDone != nil {
onDone(buttonLabel)
}
})
cv.
AddAndSwitchToPage(confirmModalPageName, ui.Centered(modal, 0, 0), true).
ShowPage(flexPageName)
}

View file

@ -143,7 +143,7 @@ PARENT_CHANNELS:
}
func (gt *guildsTree) onSelected(node *tview.TreeNode) {
app.messageInput.reset()
app.chatView.messageInput.reset()
if len(node.GetChildren()) != 0 {
node.SetExpanded(!node.IsExpanded())
@ -181,21 +181,21 @@ func (gt *guildsTree) onSelected(node *tview.TreeNode) {
}
if guildID := channel.GuildID; guildID.IsValid() {
app.messagesList.requestGuildMembers(guildID, messages)
app.chatView.messagesList.requestGuildMembers(guildID, messages)
}
app.messagesList.reset()
app.messagesList.setTitle(*channel)
app.messagesList.drawMessages(messages)
app.messagesList.ScrollToEnd()
app.chatView.messagesList.reset()
app.chatView.messagesList.setTitle(*channel)
app.chatView.messagesList.drawMessages(messages)
app.chatView.messagesList.ScrollToEnd()
hasNoPerm := channel.Type != discord.DirectMessage && channel.Type != discord.GroupDM && !discordState.HasPermissions(channel.ID, discord.PermissionSendMessages)
app.messageInput.SetDisabled(hasNoPerm)
app.chatView.messageInput.SetDisabled(hasNoPerm)
if hasNoPerm {
app.messageInput.SetPlaceholder("You do not have permission to send messages in this channel.")
app.chatView.messageInput.SetPlaceholder("You do not have permission to send messages in this channel.")
} else {
app.messageInput.SetPlaceholder("Message...")
app.SetFocus(app.messageInput)
app.chatView.messageInput.SetPlaceholder("Message...")
app.SetFocus(app.chatView.messageInput)
}
gt.selectedChannelID = channel.ID

View file

@ -101,7 +101,7 @@ func (mi *messageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
return tcell.NewEventKey(tcell.KeyCtrlV, 0, tcell.ModNone)
case mi.cfg.Keys.MessageInput.Send:
if app.pages.GetVisibile(mentionsListPageName) {
if app.chatView.GetVisibile(mentionsListPageName) {
mi.tabComplete(false)
return nil
}
@ -117,7 +117,7 @@ func (mi *messageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
mi.openFilePicker()
return nil
case mi.cfg.Keys.MessageInput.Cancel:
if app.pages.GetVisibile(mentionsListPageName) {
if app.chatView.GetVisibile(mentionsListPageName) {
mi.stopTabCompletion()
} else {
mi.reset()
@ -130,7 +130,7 @@ func (mi *messageInput) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
}
if mi.cfg.AutocompleteLimit > 0 {
if app.pages.GetVisibile(mentionsListPageName) {
if app.chatView.GetVisibile(mentionsListPageName) {
switch event.Name() {
case mi.cfg.Keys.MentionsList.Up:
mi.mentionsList.InputHandler()(tcell.NewEventKey(tcell.KeyUp, 0, tcell.ModNone), nil)
@ -155,7 +155,7 @@ func (mi *messageInput) paste() {
}
func (mi *messageInput) send() {
if !app.guildsTree.selectedChannelID.IsValid() {
if !app.chatView.guildsTree.selectedChannelID.IsValid() {
return
}
@ -164,13 +164,13 @@ func (mi *messageInput) send() {
return
}
text = processText(app.guildsTree.selectedChannelID, []byte(text))
text = processText(app.chatView.guildsTree.selectedChannelID, []byte(text))
if text == "" {
return
}
if mi.edit {
m, err := app.messagesList.selectedMessage()
m, err := app.chatView.messagesList.selectedMessage()
if err != nil {
slog.Error("failed to get selected message", "err", err)
return
@ -185,8 +185,8 @@ func (mi *messageInput) send() {
} else {
data := mi.sendMessageData
data.Content = text
if _, err := discordState.SendMessageComplex(app.guildsTree.selectedChannelID, *data); err != nil {
slog.Error("failed to send message in channel", "channel_id", app.guildsTree.selectedChannelID, "err", err)
if _, err := discordState.SendMessageComplex(app.chatView.guildsTree.selectedChannelID, *data); err != nil {
slog.Error("failed to send message in channel", "channel_id", app.chatView.guildsTree.selectedChannelID, "err", err)
}
}
@ -198,8 +198,8 @@ func (mi *messageInput) send() {
}
mi.reset()
app.messagesList.Highlight()
app.messagesList.ScrollToEnd()
app.chatView.messagesList.Highlight()
app.chatView.messagesList.ScrollToEnd()
}
func processText(cID discord.ChannelID, src []byte) string {
@ -236,7 +236,7 @@ func expandMentions(cID discord.ChannelID, src []byte) []byte {
return mentionRegex.ReplaceAllFunc(src, func(input []byte) []byte {
output := input
name := string(input[1:])
discordState.MemberStore.Each(app.guildsTree.selectedGuildID, func(m *discord.Member) bool {
discordState.MemberStore.Each(app.chatView.guildsTree.selectedGuildID, func(m *discord.Member) bool {
if strings.EqualFold(m.User.Username, name) && channelHasUser(cID, m.User.ID) {
output = []byte(m.User.ID.Mention())
return true
@ -259,8 +259,8 @@ func (mi *messageInput) tabComplete(isAuto bool) {
}
pos := posEnd - (len(name) + 1)
gID := app.guildsTree.selectedGuildID
cID := app.guildsTree.selectedChannelID
gID := app.chatView.guildsTree.selectedGuildID
cID := app.chatView.guildsTree.selectedChannelID
if !isAuto {
if mi.cfg.AutocompleteLimit == 0 {
@ -373,10 +373,10 @@ func (mi *messageInput) searchMember(gID discord.GuildID, name string) {
}
mi.lastSearch = time.Now()
app.messagesList.waitForChunkEvent()
app.messagesList.setFetchingChunk(true, 0)
app.chatView.messagesList.waitForChunkEvent()
app.chatView.messagesList.setFetchingChunk(true, 0)
discordState.MemberState.SearchMember(gID, name)
mi.cache.Create(key, app.messagesList.waitForChunkEvent())
mi.cache.Create(key, app.chatView.messagesList.waitForChunkEvent())
}
func (mi *messageInput) showMentionList(col int) {
@ -387,7 +387,7 @@ func (mi *messageInput) showMentionList(col int) {
l := mi.mentionsList
x, _, _, _ := mi.GetInnerRect()
_, y, _, _ := mi.GetRect()
_, _, maxW, maxH := app.messagesList.GetInnerRect()
_, _, maxW, maxH := app.chatView.messagesList.GetInnerRect()
if t := int(mi.cfg.Theme.MentionsList.MaxHeight); t != 0 {
maxH = min(maxH, t)
}
@ -409,7 +409,7 @@ func (mi *messageInput) showMentionList(col int) {
l.SetRect(x, y, w, h)
app.pages.
app.chatView.
AddAndSwitchToPage(mentionsListPageName, l, false).
ShowPage(flexPageName)
app.SetFocus(mi)
@ -448,7 +448,7 @@ func (mi *messageInput) addMentionItem(gID discord.GuildID, m *discord.Member) b
}
func (mi *messageInput) removeMentionsList() {
app.pages.
app.chatView.
RemovePage(mentionsListPageName).
SwitchToPage(flexPageName)
}
@ -504,7 +504,7 @@ func (mi *messageInput) addTitle(s string) {
}
func (mi *messageInput) openFilePicker() {
if !app.guildsTree.selectedChannelID.IsValid() {
if !app.chatView.guildsTree.selectedChannelID.IsValid() {
return
}

View file

@ -239,7 +239,7 @@ func (ml *messagesList) selectedMessage() (*discord.Message, error) {
return nil, errors.New("no message is currently selected")
}
m, err := discordState.Cabinet.Message(app.guildsTree.selectedChannelID, ml.selectedMessageID)
m, err := discordState.Cabinet.Message(app.chatView.guildsTree.selectedChannelID, ml.selectedMessageID)
if err != nil {
return nil, fmt.Errorf("could not retrieve selected message: %w", err)
}
@ -248,7 +248,7 @@ func (ml *messagesList) selectedMessage() (*discord.Message, error) {
}
func (ml *messagesList) selectedMessageIndex() (int, error) {
ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
ms, err := discordState.Cabinet.Messages(app.chatView.guildsTree.selectedChannelID)
if err != nil {
return -1, err
}
@ -294,9 +294,9 @@ func (ml *messagesList) onInputCapture(event *tcell.EventKey) *tcell.EventKey {
}
func (ml *messagesList) _select(name string) {
ms, err := discordState.Cabinet.Messages(app.guildsTree.selectedChannelID)
ms, err := discordState.Cabinet.Messages(app.chatView.guildsTree.selectedChannelID)
if err != nil {
slog.Error("failed to get messages", "err", err, "channel_id", app.guildsTree.selectedChannelID)
slog.Error("failed to get messages", "err", err, "channel_id", app.chatView.guildsTree.selectedChannelID)
return
}
@ -450,7 +450,7 @@ func (ml *messagesList) showAttachmentsList(urls []string, attachments []discord
SetHighlightFullLine(true).
ShowSecondaryText(false).
SetDoneFunc(func() {
app.pages.RemovePage(attachmentsListPageName).SwitchToPage(flexPageName)
app.chatView.RemovePage(attachmentsListPageName).SwitchToPage(flexPageName)
app.SetFocus(ml)
})
list.
@ -486,7 +486,7 @@ func (ml *messagesList) showAttachmentsList(urls []string, attachments []discord
})
}
app.pages.
app.chatView.
AddAndSwitchToPage(attachmentsListPageName, ui.Centered(list, 0, 0), true).
ShowPage(flexPageName)
}
@ -548,7 +548,7 @@ func (ml *messagesList) reply(mention bool) {
}
}
data := app.messageInput.sendMessageData
data := app.chatView.messageInput.sendMessageData
data.Reference = &discord.MessageReference{MessageID: ml.selectedMessageID}
data.AllowedMentions = &api.AllowedMentions{RepliedUser: option.False}
@ -558,9 +558,9 @@ func (ml *messagesList) reply(mention bool) {
title = "[@] " + title
}
app.messageInput.sendMessageData = data
app.messageInput.addTitle(title + name)
app.SetFocus(app.messageInput)
app.chatView.messageInput.sendMessageData = data
app.chatView.messageInput.addTitle(title + name)
app.SetFocus(app.chatView.messageInput)
}
func (ml *messagesList) edit() {
@ -581,10 +581,10 @@ func (ml *messagesList) edit() {
return
}
app.messageInput.SetTitle("Editing")
app.messageInput.edit = true
app.messageInput.SetText(message.Content, true)
app.SetFocus(app.messageInput)
app.chatView.messageInput.SetTitle("Editing")
app.chatView.messageInput.edit = true
app.chatView.messageInput.SetText(message.Content, true)
app.SetFocus(app.chatView.messageInput)
}
func (ml *messagesList) confirmDelete() {
@ -594,7 +594,7 @@ func (ml *messagesList) confirmDelete() {
}
}
app.showConfirmModal(
app.chatView.showConfirmModal(
"Are you sure you want to delete this message?",
[]string{"Yes", "No"},
onChoice,
@ -621,16 +621,16 @@ func (ml *messagesList) delete() {
}
}
if err := discordState.DeleteMessage(app.guildsTree.selectedChannelID, msg.ID, ""); err != nil {
slog.Error("failed to delete message", "channel_id", app.guildsTree.selectedChannelID, "message_id", msg.ID, "err", err)
if err := discordState.DeleteMessage(app.chatView.guildsTree.selectedChannelID, msg.ID, ""); err != nil {
slog.Error("failed to delete message", "channel_id", app.chatView.guildsTree.selectedChannelID, "message_id", msg.ID, "err", err)
return
}
ml.selectedMessageID = 0
ml.Highlight()
if err := discordState.MessageRemove(app.guildsTree.selectedChannelID, msg.ID); err != nil {
slog.Error("failed to delete message", "channel_id", app.guildsTree.selectedChannelID, "message_id", msg.ID, "err", err)
if err := discordState.MessageRemove(app.chatView.guildsTree.selectedChannelID, msg.ID); err != nil {
slog.Error("failed to delete message", "channel_id", app.chatView.guildsTree.selectedChannelID, "message_id", msg.ID, "err", err)
return
}

View file

@ -45,11 +45,11 @@ func openState(token string) error {
discordState.AddHandler(onReadUpdate)
discordState.AddHandler(func(event *gateway.GuildMembersChunkEvent) {
app.messagesList.setFetchingChunk(false, uint(len(event.Members)))
app.chatView.messagesList.setFetchingChunk(false, uint(len(event.Members)))
})
discordState.AddHandler(func(event *gateway.GuildMemberRemoveEvent) {
app.messageInput.cache.Invalidate(event.GuildID.String()+" "+event.User.Username, discordState.MemberState.SearchLimit)
app.chatView.messageInput.cache.Invalidate(event.GuildID.String()+" "+event.User.Username, discordState.MemberState.SearchLimit)
})
discordState.StateLog = func(err error) {
@ -79,18 +79,18 @@ func onRaw(event *ws.RawEvent) {
func onReadUpdate(event *read.UpdateEvent) {
var guildNode *tview.TreeNode
app.guildsTree.
app.chatView.guildsTree.
GetRoot().
Walk(func(node, parent *tview.TreeNode) bool {
switch node.GetReference() {
case event.GuildID:
node.SetTextStyle(app.guildsTree.getGuildNodeStyle(event.GuildID))
node.SetTextStyle(app.chatView.guildsTree.getGuildNodeStyle(event.GuildID))
guildNode = node
return false
case event.ChannelID:
// private channel
if !event.GuildID.IsValid() {
style := app.guildsTree.getChannelNodeStyle(event.ChannelID)
style := app.chatView.guildsTree.getChannelNodeStyle(event.ChannelID)
node.SetTextStyle(style)
return false
}
@ -102,7 +102,7 @@ func onReadUpdate(event *read.UpdateEvent) {
if guildNode != nil {
guildNode.Walk(func(node, parent *tview.TreeNode) bool {
if node.GetReference() == event.ChannelID {
node.SetTextStyle(app.guildsTree.getChannelNodeStyle(event.ChannelID))
node.SetTextStyle(app.chatView.guildsTree.getChannelNodeStyle(event.ChannelID))
return false
}
@ -115,7 +115,7 @@ func onReadUpdate(event *read.UpdateEvent) {
func onReady(r *gateway.ReadyEvent) {
dmNode := tview.NewTreeNode("Direct Messages")
root := app.guildsTree.
root := app.chatView.guildsTree.
GetRoot().
ClearChildren().
AddChild(dmNode)
@ -134,20 +134,20 @@ func onReady(r *gateway.ReadyEvent) {
continue
}
app.guildsTree.createGuildNode(root, *guild)
app.chatView.guildsTree.createGuildNode(root, *guild)
} else {
app.guildsTree.createFolderNode(folder)
app.chatView.guildsTree.createFolderNode(folder)
}
}
app.guildsTree.SetCurrentNode(root)
app.SetFocus(app.guildsTree)
app.chatView.guildsTree.SetCurrentNode(root)
app.SetFocus(app.chatView.guildsTree)
app.Draw()
}
func onMessageCreate(message *gateway.MessageCreateEvent) {
if app.guildsTree.selectedChannelID == message.ChannelID {
app.messagesList.drawMessage(app.messagesList, message.Message)
if app.chatView.guildsTree.selectedChannelID == message.ChannelID {
app.chatView.messagesList.drawMessage(app.chatView.messagesList, message.Message)
app.Draw()
}
@ -157,21 +157,21 @@ func onMessageCreate(message *gateway.MessageCreateEvent) {
}
func onMessageUpdate(message *gateway.MessageUpdateEvent) {
if app.guildsTree.selectedChannelID == message.ChannelID {
if app.chatView.guildsTree.selectedChannelID == message.ChannelID {
onMessageDelete(&gateway.MessageDeleteEvent{ID: message.ID, ChannelID: message.ChannelID, GuildID: message.GuildID})
}
}
func onMessageDelete(message *gateway.MessageDeleteEvent) {
if app.guildsTree.selectedChannelID == message.ChannelID {
if app.chatView.guildsTree.selectedChannelID == message.ChannelID {
messages, err := discordState.Cabinet.Messages(message.ChannelID)
if err != nil {
slog.Error("failed to get messages from state", "err", err, "channel_id", message.ChannelID)
return
}
app.messagesList.reset()
app.messagesList.drawMessages(messages)
app.chatView.messagesList.reset()
app.chatView.messagesList.drawMessages(messages)
app.Draw()
}
}