From 7111df5c82b9fd591c254c77652368624b0b0797 Mon Sep 17 00:00:00 2001 From: ayn2op Date: Fri, 30 Dec 2022 20:05:26 +0530 Subject: [PATCH] Rewrite --- channels_tree.go | 18 -------- config.go | 19 +++++---- go.mod | 16 +++---- go.sum | 27 +++++++----- guilds_tree.go | 109 ++++++++++++++++++++++++++++++++++++++++++++--- main.go | 9 +--- messages_text.go | 22 ++++++++++ out.log | 3 ++ state.go | 12 +++--- 9 files changed, 169 insertions(+), 66 deletions(-) delete mode 100644 channels_tree.go create mode 100644 out.log diff --git a/channels_tree.go b/channels_tree.go deleted file mode 100644 index 38c3d2e..0000000 --- a/channels_tree.go +++ /dev/null @@ -1,18 +0,0 @@ -package main - -import "github.com/rivo/tview" - -type ChannelsTree struct { - *tview.TreeView -} - -func newChannelsTree() *ChannelsTree { - ct := &ChannelsTree{ - TreeView: tview.NewTreeView(), - } - - ct.SetBorder(true) - ct.SetBorderPadding(cfg.BorderPadding()) - - return ct -} diff --git a/config.go b/config.go index 731750b..a8545a4 100644 --- a/config.go +++ b/config.go @@ -13,13 +13,9 @@ type ThemeConfig struct { } type Config struct { - Mouse bool - Theme ThemeConfig -} - -func (c *Config) BorderPadding() (int, int, int, int) { - pad := c.Theme.BorderPadding - return pad[0], pad[1], pad[2], pad[3] + Mouse bool + MessagesLimit uint + Theme ThemeConfig } func newConfig() (*Config, error) { @@ -34,7 +30,9 @@ func newConfig() (*Config, error) { } c := Config{ - Mouse: true, + Mouse: true, + MessagesLimit: 50, + Theme: ThemeConfig{ BorderPadding: [...]int{1, 1, 1, 1}, }, @@ -66,3 +64,8 @@ func newConfig() (*Config, error) { return &c, nil } + +func (c *Config) BorderPadding() (int, int, int, int) { + pad := c.Theme.BorderPadding + return pad[0], pad[1], pad[2], pad[3] +} diff --git a/go.mod b/go.mod index 8ec05de..7c986c3 100644 --- a/go.mod +++ b/go.mod @@ -4,20 +4,20 @@ go 1.19 require ( github.com/diamondburned/arikawa/v3 v3.1.0 - github.com/rivo/tview v0.0.0-20221221172820-02e38ea9604c + github.com/rivo/tview v0.0.0-20221229180733-b86a50a5126c ) require ( github.com/gdamore/encoding v1.0.0 // indirect github.com/gdamore/tcell/v2 v2.5.3 // indirect github.com/gorilla/schema v1.2.0 // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/gorilla/websocket v1.5.0 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-runewidth v0.0.13 // indirect + github.com/mattn/go-runewidth v0.0.14 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/rivo/uniseg v0.4.2 // indirect - golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 // indirect - golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d // indirect - golang.org/x/text v0.3.7 // indirect - golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac // indirect + github.com/rivo/uniseg v0.4.3 // indirect + golang.org/x/sys v0.3.0 // indirect + golang.org/x/term v0.3.0 // indirect + golang.org/x/text v0.5.0 // indirect + golang.org/x/time v0.3.0 // indirect ) diff --git a/go.sum b/go.sum index cdfe7bd..6085ebd 100644 --- a/go.sum +++ b/go.sum @@ -6,34 +6,39 @@ github.com/gdamore/tcell/v2 v2.5.3 h1:b9XQrT6QGbgI7JvZOJXFNczOQeIYbo8BfeSMzt2sAV github.com/gdamore/tcell/v2 v2.5.3/go.mod h1:wSkrPaXoiIWZqW/g7Px4xc79di6FTcpB8tvaKJ6uGBo= github.com/gorilla/schema v1.2.0 h1:YufUaxZYCKGFuAq3c96BOhjgd5nmXiOY9NGzF247Tsc= github.com/gorilla/schema v1.2.0/go.mod h1:kgLaKoK1FELgZqMAVxx/5cbj0kT+57qxUrAlIO2eleU= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc= +github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= -github.com/mattn/go-runewidth v0.0.13 h1:lTGmDsbAYt5DmK6OnoV7EuIF1wEIFAcxld6ypU4OSgU= github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= +github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU= +github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/rivo/tview v0.0.0-20221221172820-02e38ea9604c h1:Y4GSXEYKYAtguH10lmQmYb7hRkJ7U+m8GvnFHKU2jrk= -github.com/rivo/tview v0.0.0-20221221172820-02e38ea9604c/go.mod h1:lBUy/T5kyMudFzWUH/C2moN+NlU5qF505vzOyINXuUQ= +github.com/rivo/tview v0.0.0-20221229180733-b86a50a5126c h1:Xa0IDAwI/b4D3AQwFOhvOeYB/H0N8Bhhe3XJWSa2vjg= +github.com/rivo/tview v0.0.0-20221229180733-b86a50a5126c/go.mod h1:lBUy/T5kyMudFzWUH/C2moN+NlU5qF505vzOyINXuUQ= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.2 h1:YwD0ulJSJytLpiaWua0sBDusfsCZohxjxzVTYjwxfV8= -github.com/rivo/uniseg v0.4.2/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= +github.com/rivo/uniseg v0.4.3 h1:utMvzDsuh3suAEnhH0RdHmoPbU648o6CvXxTx4SBMOw= +github.com/rivo/uniseg v0.4.3/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211001092434-39dca1131b70/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220318055525-2edf467146b5 h1:saXMvIOKvRFwbOMicHXr0B1uwoxq9dGmLe5ExMES6c4= golang.org/x/sys v0.0.0-20220318055525-2edf467146b5/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.3.0 h1:w8ZOecv6NaNa/zC8944JTU3vz4u6Lagfk4RPQxv92NQ= +golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201210144234-2321bbc49cbf/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d h1:SZxvLBoTP5yHO3Frd4z4vrF+DBX9vMVanchswa69toE= -golang.org/x/term v0.0.0-20210220032956-6a3ed077a48d/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.3.0 h1:qoo4akIqOcDME5bhc/NgxUdovd6BSS2uMsVjB56q1xI= +golang.org/x/term v0.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= +golang.org/x/text v0.5.0 h1:OLmvp0KP+FVG99Ct/qFiL/Fhk4zp4QQnZ7b2U+5piUM= +golang.org/x/text v0.5.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= +golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= diff --git a/guilds_tree.go b/guilds_tree.go index bc6e2f7..6dc2ca1 100644 --- a/guilds_tree.go +++ b/guilds_tree.go @@ -1,31 +1,37 @@ package main import ( + "log" + "github.com/diamondburned/arikawa/v3/discord" "github.com/rivo/tview" ) type GuildsTree struct { *tview.TreeView + + root *tview.TreeNode } func newGuildsTree() *GuildsTree { gt := &GuildsTree{ TreeView: tview.NewTreeView(), + + root: tview.NewTreeNode(""), } - root := tview.NewTreeNode("") - gt.SetRoot(root) + gt.SetRoot(gt.root) gt.SetTopLevel(1) gt.SetSelectedFunc(gt.onSelected) + gt.SetTitle("Guilds") gt.SetBorder(true) gt.SetBorderPadding(cfg.BorderPadding()) return gt } -func (gt *GuildsTree) newGuild(n *tview.TreeNode, gid discord.GuildID) error { +func (gt *GuildsTree) newGuildFromID(n *tview.TreeNode, gid discord.GuildID) error { g, err := discordState.Cabinet.Guild(gid) if err != nil { return err @@ -37,9 +43,100 @@ func (gt *GuildsTree) newGuild(n *tview.TreeNode, gid discord.GuildID) error { return nil } -func (gt *GuildsTree) onSelected(n *tview.TreeNode) { - ref := n.GetReference() - if ref == nil { +func (gt *GuildsTree) newChannel(n *tview.TreeNode, c discord.Channel) { + cn := tview.NewTreeNode(gt.channelToString(c)) + cn.SetReference(c.ID) + n.AddChild(cn) +} +func (gt *GuildsTree) channelToString(c discord.Channel) string { + switch c.Type { + case discord.GuildText: + return "#" + c.Name + case discord.GuildVoice: + return "v-" + c.Name + case discord.GuildNews: + return "n-" + c.Name + case discord.GuildStore: + return "s-" + c.Name + default: + return c.Name + } +} + +func (gt *GuildsTree) onSelected(n *tview.TreeNode) { + if len(n.GetChildren()) != 0 { + n.SetExpanded(!n.IsExpanded()) + } + + switch ref := n.GetReference().(type) { + case discord.GuildID: + cs, err := discordState.Cabinet.Channels(ref) + if err != nil { + log.Println(err) + return + } + + // Orphan (top-level) channels + for _, c := range cs { + if c.Type != discord.GuildCategory && !c.ParentID.IsValid() { + gt.newChannel(n, c) + } + } + + // Category channels + CATEGORY: + for _, c := range cs { + if c.Type == discord.GuildCategory { + for _, nestedChannel := range cs { + if nestedChannel.ParentID == c.ID { + gt.newChannel(n, c) + continue CATEGORY + } + } + + gt.newChannel(n, c) + } + } + + // Children (category-bound) channels + for _, c := range cs { + if c.ParentID.IsValid() { + var parent *tview.TreeNode + n.Walk(func(node, _ *tview.TreeNode) bool { + if node.GetReference() == c.ParentID { + parent = node + return false + } + + return true + }) + + if parent != nil { + gt.newChannel(parent, c) + } + } + } + case discord.ChannelID: + messagesText.Clear() + + c, err := discordState.Cabinet.Channel(ref) + if err != nil { + log.Println(err) + return + } + + ms, err := discordState.Messages(ref, cfg.MessagesLimit) + if err != nil { + log.Println(err) + return + } + + for _, m := range ms { + messagesText.newMessage(&m) + } + + messagesText.SetTitle(gt.channelToString(*c)) + app.SetFocus(messagesText) } } diff --git a/main.go b/main.go index f38fa5e..ea85325 100644 --- a/main.go +++ b/main.go @@ -17,7 +17,6 @@ var ( app *tview.Application flex *tview.Flex guildsTree *GuildsTree - channelsTree *ChannelsTree messagesText *MessagesText messageInput *MessageInput ) @@ -39,7 +38,6 @@ func main() { app = tview.NewApplication() guildsTree = newGuildsTree() - channelsTree = newChannelsTree() messagesText = newMessagesText() messageInput = newMessageInput() @@ -48,18 +46,13 @@ func main() { log.Fatal(err) } - left := tview.NewFlex() - left.SetDirection(tview.FlexRow) - left.AddItem(guildsTree, 0, 1, true) - left.AddItem(channelsTree, 0, 1, false) - right := tview.NewFlex() right.SetDirection(tview.FlexRow) right.AddItem(messagesText, 0, 1, false) right.AddItem(messageInput, 3, 1, false) flex = tview.NewFlex() - flex.AddItem(left, 0, 1, false) + flex.AddItem(guildsTree, 0, 1, false) flex.AddItem(right, 0, 4, false) app.EnableMouse(cfg.Mouse) diff --git a/messages_text.go b/messages_text.go index 01b15d0..e2299b6 100644 --- a/messages_text.go +++ b/messages_text.go @@ -1,11 +1,17 @@ package main import ( + "fmt" + "strings" + + "github.com/diamondburned/arikawa/v3/discord" "github.com/rivo/tview" ) type MessagesText struct { *tview.TextView + + builder strings.Builder } func newMessagesText() *MessagesText { @@ -21,3 +27,19 @@ func newMessagesText() *MessagesText { return mt } + +func (mt *MessagesText) newMessage(m *discord.Message) { + switch m.Type { + case discord.DefaultMessage: + { + mt.builder.WriteString("[blue::b]") + mt.builder.WriteString(m.Author.Username) + mt.builder.WriteString("[-:-:-]") + } + + mt.builder.WriteByte('\n') + mt.builder.WriteByte('\n') + } + + fmt.Fprintln(mt, mt.builder.String()) +} diff --git a/out.log b/out.log new file mode 100644 index 0000000..c3a53e5 --- /dev/null +++ b/out.log @@ -0,0 +1,3 @@ +2022/12/30 20:03:24 Discord 403 error: Missing Access +2022/12/30 20:03:44 Discord 403 error: Missing Access +2022/12/30 20:03:58 Discord 403 error: Missing Access diff --git a/state.go b/state.go index e2966cb..bc9fe73 100644 --- a/state.go +++ b/state.go @@ -23,24 +23,22 @@ func newState(token string) *State { } func (s *State) onReady(r *gateway.ReadyEvent) { - root := guildsTree.GetRoot() - dmNode := tview.NewTreeNode("Direct Messages") - root.AddChild(dmNode) + guildsTree.root.AddChild(dmNode) for _, gf := range r.UserSettings.GuildFolders { /// If the ID of the guild folder is zero, the guild folder only contains single guild. if gf.ID == 0 { - if err := guildsTree.newGuild(root, gf.GuildIDs[0]); err != nil { + if err := guildsTree.newGuildFromID(guildsTree.root, gf.GuildIDs[0]); err != nil { log.Println(err) continue } } else { gfNode := tview.NewTreeNode("Folder") - root.AddChild(gfNode) + guildsTree.root.AddChild(gfNode) for _, gid := range gf.GuildIDs { - if err := guildsTree.newGuild(gfNode, gid); err != nil { + if err := guildsTree.newGuildFromID(gfNode, gid); err != nil { log.Println(err) continue } @@ -48,6 +46,6 @@ func (s *State) onReady(r *gateway.ReadyEvent) { } } - guildsTree.SetCurrentNode(root) + guildsTree.SetCurrentNode(guildsTree.root) app.SetFocus(guildsTree) }