diff --git a/assets/preview.png b/assets/preview.png index d6923d0..f0d09fe 100644 Binary files a/assets/preview.png and b/assets/preview.png differ diff --git a/discordo.go b/discordo.go index cd02f85..2b148b2 100644 --- a/discordo.go +++ b/discordo.go @@ -1,6 +1,7 @@ package main import ( + "sort" "strings" "github.com/bwmarrin/discordgo" @@ -15,7 +16,8 @@ var ( loginModal *tview.Modal loginForm *tview.Form guildsDropDown *tview.DropDown - channelsList *tview.List + channelsTreeView *tview.TreeView + channelsTreeNode *tview.TreeNode messagesTextView *tview.TextView messageInputField *tview.InputField mainFlex *tview.Flex @@ -28,25 +30,13 @@ var ( ) func main() { - tview.Borders.HorizontalFocus = tview.Borders.Horizontal - tview.Borders.VerticalFocus = tview.Borders.Vertical - tview.Borders.TopLeftFocus = tview.Borders.TopLeft - tview.Borders.TopRightFocus = tview.Borders.TopRight - tview.Borders.BottomLeftFocus = tview.Borders.BottomLeft - tview.Borders.BottomRightFocus = tview.Borders.BottomRight - tview.Borders.Horizontal = ' ' - tview.Borders.Vertical = ' ' - tview.Borders.TopLeft = ' ' - tview.Borders.TopRight = ' ' - tview.Borders.BottomLeft = ' ' - tview.Borders.BottomRight = ' ' - theme = util.NewTheme() loginModal = ui.NewLoginModal(onLoginModalDone) guildsDropDown = ui.NewGuildsDropDown(onGuildsDropDownSelected, theme) - channelsList = ui.NewChannelsList(onChannelsListSelected, theme) + channelsTreeNode = ui.NewChannelsTreeNode() + channelsTreeView = ui.NewChannelsTreeView(channelsTreeNode, onChannelsTreeViewSelected, theme) messagesTextView = ui.NewMessagesTextView(onMessagesTextViewChanged, theme) - mainFlex = ui.NewMainFlex(guildsDropDown, channelsList, messagesTextView) + mainFlex = ui.NewMainFlex(guildsDropDown, channelsTreeView, messagesTextView) app = ui.NewApp() token := util.GetPassword("token") @@ -145,7 +135,7 @@ func onMessageCreate(_ *discordgo.Session, message *discordgo.MessageCreate) { } func onGuildsDropDownSelected(text string, _ int) { - channelsList.Clear() + channelsTreeNode.ClearChildren() messagesTextView.Clear() if messageInputField != nil { @@ -162,17 +152,33 @@ func onGuildsDropDownSelected(text string, _ int) { } } - channelsList.SetTitle("Channels") - app.SetFocus(channelsList) + channelsTreeView.SetTitle("Channels") + app.SetFocus(channelsTreeView) - for i := range currentGuild.Channels { - channel := currentGuild.Channels[i] - channelsList.AddItem(channel.Name, "", 0, nil) + channels := currentGuild.Channels + sort.Slice(channels, func(i, j int) bool { + return channels[i].Position < channels[j].Position + }) + + for i := range channels { + channel := channels[i] + channelNode := tview.NewTreeNode(channel.Name). + SetReference(channel) + + if channel.ParentID == "" { + channelsTreeNode.AddChild(channelNode) + continue + } + + if channel.Type == discordgo.ChannelTypeGuildCategory { + channelNode.SetColor(tcell.ColorLightCyan) + channelsTreeNode.AddChild(channelNode) + continue + } } - } -func onChannelsListSelected(i int, mainText string, secondaryText string, _ rune) { +func onChannelsTreeViewSelected(node *tview.TreeNode) { messagesTextView.Clear() if messageInputField == nil { @@ -180,14 +186,33 @@ func onChannelsListSelected(i int, mainText string, secondaryText string, _ rune mainFlex.AddItem(messageInputField, 3, 1, false) } - currentChannel = currentGuild.Channels[i] + currentChannel = node.GetReference().(*discordgo.Channel) + switch currentChannel.Type { + case discordgo.ChannelTypeGuildCategory: + if len(node.GetChildren()) == 0 { + for i := range currentGuild.Channels { + channel := currentGuild.Channels[i] + if channel.ParentID == currentChannel.ID { + channelNode := tview.NewTreeNode(channel.Name). + SetReference(channel) + node.AddChild(channelNode) + } + } + } else { + node.SetExpanded(!node.IsExpanded()) + } + case discordgo.ChannelTypeGuildText: + messagesTextView.SetTitle(currentChannel.Name) + app.SetFocus(messageInputField) - messagesTextView.SetTitle(currentChannel.Name) - app.SetFocus(messageInputField) + messages, err := session.ChannelMessages(currentChannel.ID, 50, "", "", "") + if err != nil { + panic(err) + } - messages := util.GetMessages(session, currentChannel.ID, 50) - for i := len(messages) - 1; i >= 0; i-- { - util.WriteMessage(messagesTextView, session, messages[i]) + for i := len(messages) - 1; i >= 0; i-- { + go util.WriteMessage(messagesTextView, session, messages[i]) + } } } @@ -200,7 +225,10 @@ func onMessageInputFieldDone(key tcell.Key) { return } - util.SendMessage(session, currentChannel.ID, currentText) + _, err := session.ChannelMessageSend(currentChannel.ID+"123", currentText) + if err != nil { + panic(err) + } messageInputField.SetText("") } diff --git a/ui/flex.go b/ui/flex.go index e35ea17..24c1e91 100644 --- a/ui/flex.go +++ b/ui/flex.go @@ -4,8 +4,10 @@ import ( "github.com/rivo/tview" ) -func NewMainFlex(guildsDropDown *tview.DropDown, channelsList *tview.List, messagesTextView *tview.TextView) (mainFlex *tview.Flex) { - midFlex := NewMidFlex(channelsList, messagesTextView) +func NewMainFlex(guildsDropDown *tview.DropDown, channelsTreeView *tview.TreeView, messagesTextView *tview.TextView) (mainFlex *tview.Flex) { + midFlex := tview.NewFlex(). + AddItem(channelsTreeView, 20, 1, false). + AddItem(messagesTextView, 0, 3, false) mainFlex = tview.NewFlex(). SetDirection(tview.FlexRow). AddItem(guildsDropDown, 3, 1, false). @@ -13,11 +15,3 @@ func NewMainFlex(guildsDropDown *tview.DropDown, channelsList *tview.List, messa return } - -func NewMidFlex(channelsList *tview.List, messagesTextView *tview.TextView) (midFlex *tview.Flex) { - midFlex = tview.NewFlex(). - AddItem(channelsList, 20, 1, false). - AddItem(messagesTextView, 0, 3, false) - - return -} diff --git a/ui/lists.go b/ui/lists.go deleted file mode 100644 index 48f4d5c..0000000 --- a/ui/lists.go +++ /dev/null @@ -1,22 +0,0 @@ -package ui - -import ( - "github.com/gdamore/tcell/v2" - "github.com/rigormorrtiss/discordo/util" - "github.com/rivo/tview" -) - -func NewChannelsList(onChannelsListSelected func(i int, mainText string, secondaryText string, _ rune), theme *util.Theme) (channelsList *tview.List) { - channelsList = tview.NewList(). - ShowSecondaryText(false). - SetSelectedFunc(onChannelsListSelected) - channelsList. - SetMainTextColor(tcell.GetColor(theme.ListMainTextForeground)). - SetSelectedTextColor(tcell.GetColor(theme.ListSelectedForeground)). - SetSelectedBackgroundColor(tcell.GetColor(theme.ListBackground)). - SetBackgroundColor(tcell.GetColor(theme.ListBackground)). - SetBorder(true). - SetBorderPadding(0, 0, 1, 1) - - return -} diff --git a/ui/treeviews.go b/ui/treeviews.go new file mode 100644 index 0000000..22ab378 --- /dev/null +++ b/ui/treeviews.go @@ -0,0 +1,26 @@ +package ui + +import ( + "github.com/gdamore/tcell/v2" + "github.com/rigormorrtiss/discordo/util" + "github.com/rivo/tview" +) + +func NewChannelsTreeView(channelsTreeNode *tview.TreeNode, onChannelsTreeViewSelected func(node *tview.TreeNode), theme *util.Theme) (channelsTreeView *tview.TreeView) { + channelsTreeView = tview.NewTreeView(). + SetTopLevel(1). + SetRoot(channelsTreeNode). + SetCurrentNode(channelsTreeNode). + SetSelectedFunc(onChannelsTreeViewSelected) + channelsTreeView. + SetBackgroundColor(tcell.GetColor(theme.TreeViewBackground)). + SetBorder(true). + SetBorderPadding(0, 0, 1, 1) + + return +} + +func NewChannelsTreeNode() (channelsTreeNode *tview.TreeNode) { + channelsTreeNode = tview.NewTreeNode("") + return +} diff --git a/util/discord.go b/util/discord.go index bd813f2..43ecf90 100644 --- a/util/discord.go +++ b/util/discord.go @@ -45,19 +45,3 @@ func WriteMessage(messagesTextView *tview.TextView, session *discordgo.Session, fmt.Fprintln(messagesTextView, content.String()) } - -func SendMessage(session *discordgo.Session, channelID string, content string) { - _, err := session.ChannelMessageSend(channelID, content) - if err != nil { - panic(err) - } -} - -func GetMessages(session *discordgo.Session, channelID string, limit int) (messages []*discordgo.Message) { - messages, err := session.ChannelMessages(channelID, limit, "", "", "") - if err != nil { - panic(err) - } - - return -} diff --git a/util/theme.go b/util/theme.go index 1046caf..ffa4c30 100644 --- a/util/theme.go +++ b/util/theme.go @@ -11,9 +11,7 @@ type Theme struct { InputFieldBackground string `json:"inputField.background"` InputFieldForeground string `json:"inputField.foreground"` InputFieldPlaceholderForeground string `json:"inputField.placeholderTextForeground"` - ListBackground string `json:"list.background"` - ListMainTextForeground string `json:"list.mainTextForeground"` - ListSelectedForeground string `json:"list.selectedTextForeground"` + TreeViewBackground string `json:"treeview.background"` TextViewBackground string `json:"textview.background"` TextViewForeground string `json:"textview.foreground"` } @@ -22,9 +20,7 @@ func NewTheme() *Theme { var theme Theme theme.TextViewBackground = "#2E3440" theme.TextViewForeground = "#D8DEE9" - theme.ListBackground = "#2E3440" - theme.ListMainTextForeground = "#4C566A" - theme.ListSelectedForeground = "#ECEFF4" + theme.TreeViewBackground = "#2E3440" theme.InputFieldBackground = "#3B4252" theme.InputFieldForeground = "#D8DEE9" theme.InputFieldPlaceholderForeground = "#D8DEE9"