* Move message handler into seperate methods
MODIFY
internal/discordgoplus/channel.go
internal/discordgoplus/channel.go
@@ -18,6 +18,24 @@ func GetChannelNameForTree(channel *discordgo.Channel) string {
return channel.Name
}
+// SortMessagesByTimestamp sorts all messages in the given array according to
+// their creation date.
+func SortMessagesByTimestamp(messages []*discordgo.Message) {
+ sort.Slice(messages, func(a, b int) bool {
+ timeA, parseError := messages[a].Timestamp.Parse()
+ if parseError != nil {
+ return false
+ }
+
+ timeB, parseError := messages[b].Timestamp.Parse()
+ if parseError != nil {
+ return true
+ }
+
+ return timeA.Before(timeB)
+ })
+}
+
// GetPrivateChannelName generates a name for a private channel.
func GetPrivateChannelName(channel *discordgo.Channel) string {
var channelName string

MODIFY
internal/ui/window.go
internal/ui/window.go
@@ -580,16 +580,130 @@ func NewWindow(app *tview.Application, discord *discordgo.Session) (*Window, err
messageDeleteChan := make(chan *discordgo.Message, 50)
messageEditChan := make(chan *discordgo.Message, 50)
+ window.addMessageEventHandler(messageInputChan, messageEditChan, messageDeleteChan)
+ window.startMessageHandlerRoutines(messageInputChan, messageEditChan, messageDeleteChan)
+
+ window.channelTitle = tview.NewTextView()
+ window.channelTitle.SetBorderSides(true, true, false, true)
+ window.channelTitle.SetBorder(true)
+
+ window.userList = NewUserTree(window.session.State)
+
+ if config.GetConfig().OnTypeInListBehaviour == config.SearchOnTypeInList {
+ var guildJumpBuffer string
+ var guildJumpTime time.Time
+ guildList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
+ guildList, guildRootNode, &guildJumpTime, &guildJumpBuffer))
+ var channelJumpBuffer string
+ var channelJumpTime time.Time
+ channelTree.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
+ channelTree, channelRootNode, &channelJumpTime, &channelJumpBuffer))
+ var userJumpBuffer string
+ var userJumpTime time.Time
+ window.userList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
+ window.userList.internalTreeView, window.userList.rootNode, &userJumpTime, &userJumpBuffer))
+ var privateJumpBuffer string
+ var privateJumpTime time.Time
+ window.privateList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
+ window.privateList.GetComponent(), window.privateList.internalTreeView.GetRoot(),
+ &privateJumpTime, &privateJumpBuffer))
+ } else if config.GetConfig().OnTypeInListBehaviour == config.FocusMessageInputOnTypeInList {
+ guildList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
+ guildList.Box, window.app, window.messageInput.internalTextView))
+ channelTree.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
+ channelTree.Box, window.app, window.messageInput.internalTextView))
+ window.userList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
+ window.userList.internalTreeView.Box, window.app, window.messageInput.internalTextView))
+ window.privateList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
+ window.privateList.GetComponent().Box, window.app, window.messageInput.internalTextView))
+ window.chatView.internalTextView.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
+ window.chatView.internalTextView.Box, window.app, window.messageInput.internalTextView))
+ }
+
+ window.rootContainer = tview.NewFlex().
+ SetDirection(tview.FlexColumn)
+ window.rootContainer.SetTitleAlign(tview.AlignCenter)
+
+ app.SetRoot(window.rootContainer, true)
+ app.SetInputCapture(window.handleGlobalShortcuts)
+
+ conf := config.GetConfig()
+
+ if conf.UseFixedLayout {
+ window.rootContainer.AddItem(window.leftArea, conf.FixedSizeLeft, 7, true)
+ window.rootContainer.AddItem(window.chatArea, 0, 1, false)
+ window.rootContainer.AddItem(window.userList.internalTreeView, conf.FixedSizeRight, 6, false)
+ } else {
+ window.rootContainer.AddItem(window.leftArea, 0, 7, true)
+ window.rootContainer.AddItem(window.chatArea, 0, 20, false)
+ window.rootContainer.AddItem(window.userList.internalTreeView, 0, 6, false)
+ }
+
+ mentionWindow.SetVisible(false)
+ mentionWindow.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
+ switch key := event.Key(); key {
+ case tcell.KeyRune, tcell.KeyDelete, tcell.KeyBackspace, tcell.KeyBackspace2, tcell.KeyLeft, tcell.KeyRight, tcell.KeyCtrlA, tcell.KeyCtrlV:
+ window.messageInput.internalTextView.GetInputCapture()(event)
+ return nil
+ }
+ return event
+ })
+ mentionWindow.SetSelectedFunc(func(node *tview.TreeNode) {
+ beginIdx, endIdx := window.messageInput.GetCurrentMentionIndices()
+ if beginIdx != endIdx {
+ data, ok := node.GetReference().(string)
+ oldText := window.messageInput.GetText()
+ if ok {
+ newText := oldText[:beginIdx] + strings.TrimSpace(data) + oldText[endIdx+1:] + " "
+ window.messageInput.SetText(newText)
+ } else {
+ role, ok := node.GetReference().(*discordgo.Role)
+ if ok {
+ newText := oldText[:beginIdx-1] + "<@&" + strings.TrimSpace(role.ID) + ">" + oldText[endIdx+1:] + " "
+ window.messageInput.SetText(newText)
+ }
+ }
+ }
+ window.messageInput.mentionHideHandler()
+ })
+
+ window.chatArea.AddItem(window.channelTitle, 2, 0, false)
+ window.chatArea.AddItem(window.messageContainer, 0, 1, false)
+ window.chatArea.AddItem(mentionWindow, 2, 2, true)
+ window.chatArea.AddItem(window.messageInput.GetPrimitive(), window.messageInput.GetRequestedHeight(), 0, false)
+
+ window.commandView.commandOutput.SetVisible(false)
+ window.commandView.commandInput.SetVisible(false)
+
+ window.chatArea.AddItem(window.commandView.commandOutput, 0, 1, false)
+ window.chatArea.AddItem(window.commandView.commandInput, 3, 0, false)
+
+ if conf.ShowFrame {
+ window.rootContainer.SetTitle("Cordless")
+ window.rootContainer.SetBorder(true)
+ } else {
+ window.rootContainer.SetTitle("")
+ window.rootContainer.SetBorder(false)
+ }
+
+ window.SwitchToGuildsPage()
+
+ app.SetFocus(guildList)
+
+ return &window, nil
+}
+
+func (window *Window) addMessageEventHandler(inputChannel, editChannel, deleteChannel chan *discordgo.Message) {
window.session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) {
if window.selectedChannel != nil {
- messageInputChan <- m.Message
+ inputChannel <- m.Message
}
})
window.session.AddHandler(func(s *discordgo.Session, m *discordgo.MessageDelete) {
if window.selectedChannel != nil {
if m.ChannelID == window.selectedChannel.ID {
- messageDeleteChan <- m.Message
+ deleteChannel <- m.Message
}
}
})
@@ -599,15 +713,17 @@ func NewWindow(app *tview.Application, discord *discordgo.Session) (*Window, err
if m.ChannelID == window.selectedChannel.ID &&
//Ignore just-embed edits
m.Content != "" {
- messageEditChan <- m.Message
+ editChannel <- m.Message
}
}
})
+}
+func (window *Window) startMessageHandlerRoutines(inputChannel, editChannel, deleteChannel chan *discordgo.Message) {
go func() {
for {
select {
- case message := <-messageInputChan:
+ case message := <-inputChannel:
//UPDATE CACHE
window.session.State.MessageAdd(message)
@@ -706,7 +822,7 @@ func NewWindow(app *tview.Application, discord *discordgo.Session) (*Window, err
go func() {
for {
select {
- case messageDeleted := <-messageDeleteChan:
+ case messageDeleted := <-deleteChannel:
//UPDATE CACHE
window.session.State.MessageRemove(messageDeleted)
for index, message := range window.chatView.data {
@@ -724,7 +840,7 @@ func NewWindow(app *tview.Application, discord *discordgo.Session) (*Window, err
go func() {
for {
select {
- case messageEdited := <-messageEditChan:
+ case messageEdited := <-editChannel:
//UPDATE CACHE
window.session.State.MessageAdd(messageEdited)
for _, message := range window.chatView.data {
@@ -739,115 +855,6 @@ func NewWindow(app *tview.Application, discord *discordgo.Session) (*Window, err
}
}
}()
-
- window.channelTitle = tview.NewTextView()
- window.channelTitle.SetBorderSides(true, true, false, true)
- window.channelTitle.SetBorder(true)
-
- window.userList = NewUserTree(window.session.State)
-
- if config.GetConfig().OnTypeInListBehaviour == config.SearchOnTypeInList {
- var guildJumpBuffer string
- var guildJumpTime time.Time
- guildList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
- guildList, guildRootNode, &guildJumpTime, &guildJumpBuffer))
- var channelJumpBuffer string
- var channelJumpTime time.Time
- channelTree.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
- channelTree, channelRootNode, &channelJumpTime, &channelJumpBuffer))
- var userJumpBuffer string
- var userJumpTime time.Time
- window.userList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
- window.userList.internalTreeView, window.userList.rootNode, &userJumpTime, &userJumpBuffer))
- var privateJumpBuffer string
- var privateJumpTime time.Time
- window.privateList.SetInputCapture(treeview.CreateSearchOnTypeInuptHandler(
- window.privateList.GetComponent(), window.privateList.internalTreeView.GetRoot(),
- &privateJumpTime, &privateJumpBuffer))
- } else if config.GetConfig().OnTypeInListBehaviour == config.FocusMessageInputOnTypeInList {
- guildList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
- guildList.Box, window.app, window.messageInput.internalTextView))
- channelTree.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
- channelTree.Box, window.app, window.messageInput.internalTextView))
- window.userList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
- window.userList.internalTreeView.Box, window.app, window.messageInput.internalTextView))
- window.privateList.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
- window.privateList.GetComponent().Box, window.app, window.messageInput.internalTextView))
- window.chatView.internalTextView.SetInputCapture(treeview.CreateFocusTextViewOnTypeInputHandler(
- window.chatView.internalTextView.Box, window.app, window.messageInput.internalTextView))
- }
-
- window.rootContainer = tview.NewFlex().
- SetDirection(tview.FlexColumn)
- window.rootContainer.SetTitleAlign(tview.AlignCenter)
-
- app.SetRoot(window.rootContainer, true)
- app.SetInputCapture(window.handleGlobalShortcuts)
-
- conf := config.GetConfig()
-
- if conf.UseFixedLayout {
- window.rootContainer.AddItem(window.leftArea, conf.FixedSizeLeft, 7, true)
- window.rootContainer.AddItem(window.chatArea, 0, 1, false)
- window.rootContainer.AddItem(window.userList.internalTreeView, conf.FixedSizeRight, 6, false)
- } else {
- window.rootContainer.AddItem(window.leftArea, 0, 7, true)
- window.rootContainer.AddItem(window.chatArea, 0, 20, false)
- window.rootContainer.AddItem(window.userList.internalTreeView, 0, 6, false)
- }
-
- mentionWindow.SetVisible(false)
- mentionWindow.SetInputCapture(func(event *tcell.EventKey) *tcell.EventKey {
- switch key := event.Key(); key {
- case tcell.KeyRune, tcell.KeyDelete, tcell.KeyBackspace, tcell.KeyBackspace2, tcell.KeyLeft, tcell.KeyRight, tcell.KeyCtrlA, tcell.KeyCtrlV:
- window.messageInput.internalTextView.GetInputCapture()(event)
- return nil
- }
- return event
- })
- mentionWindow.SetSelectedFunc(func(node *tview.TreeNode) {
- beginIdx, endIdx := window.messageInput.GetCurrentMentionIndices()
- if beginIdx != endIdx {
- data, ok := node.GetReference().(string)
- oldText := window.messageInput.GetText()
- if ok {
- newText := oldText[:beginIdx] + strings.TrimSpace(data) + oldText[endIdx+1:] + " "
- window.messageInput.SetText(newText)
- } else {
- role, ok := node.GetReference().(*discordgo.Role)
- if ok {
- newText := oldText[:beginIdx-1] + "<@&" + strings.TrimSpace(role.ID) + ">" + oldText[endIdx+1:] + " "
- window.messageInput.SetText(newText)
- }
- }
- }
- window.messageInput.mentionHideHandler()
- })
-
- window.chatArea.AddItem(window.channelTitle, 2, 0, false)
- window.chatArea.AddItem(window.messageContainer, 0, 1, false)
- window.chatArea.AddItem(mentionWindow, 2, 2, true)
- window.chatArea.AddItem(window.messageInput.GetPrimitive(), window.messageInput.GetRequestedHeight(), 0, false)
-
- window.commandView.commandOutput.SetVisible(false)
- window.commandView.commandInput.SetVisible(false)
-
- window.chatArea.AddItem(window.commandView.commandOutput, 0, 1, false)
- window.chatArea.AddItem(window.commandView.commandInput, 3, 0, false)
-
- if conf.ShowFrame {
- window.rootContainer.SetTitle("Cordless")
- window.rootContainer.SetBorder(true)
- } else {
- window.rootContainer.SetTitle("")
- window.rootContainer.SetBorder(false)
- }
-
- window.SwitchToGuildsPage()
-
- app.SetFocus(guildList)
-
- return &window, nil
}
func (window *Window) registerGuildMemberHandlers() {
@@ -1181,19 +1188,7 @@ func (window *Window) LoadChannel(channel *discordgo.Channel) error {
messages = channel.Messages
}
- sort.Slice(messages, func(a, b int) bool {
- timeA, parseError := messages[a].Timestamp.Parse()
- if parseError != nil {
- return false
- }
-
- timeB, parseError := messages[b].Timestamp.Parse()
- if parseError != nil {
- return true
- }
-
- return timeA.Before(timeB)
- })
+ discordgoplus.SortMessagesByTimestamp(messages)
window.SetMessages(messages)
window.chatView.ClearSelection()

* Move message handler into seperate methods