Explorar o código

feat: lazy-load channels on guild select (#89)

* feat: set channels tree title to 'Channels'

* feat: lazy-load channels on guild select
ayntgl %!s(int64=4) %!d(string=hai) anos
pai
achega
2be06ef4cd
Modificáronse 3 ficheiros con 69 adicións e 66 borrados
  1. 24 2
      discord.go
  2. 45 5
      ui.go
  3. 0 59
      util.go

+ 24 - 2
discord.go

@@ -4,6 +4,7 @@ import (
 	"encoding/json"
 	"fmt"
 	"regexp"
+	"sort"
 	"strings"
 
 	"github.com/ayntgl/discordgo"
@@ -45,8 +46,29 @@ func onSessionReady(_ *discordgo.Session, r *discordgo.Ready) {
 	n := channelsTree.GetRoot()
 	n.AddChild(dmNode)
 
-	createPrivateChannels(dmNode)
-	createGuilds(n)
+	sort.Slice(r.Guilds, func(a, b int) bool {
+		found := false
+		for _, gID := range session.State.Settings.GuildPositions {
+			if found {
+				if gID == r.Guilds[b].ID {
+					return true
+				}
+			} else {
+				if gID == r.Guilds[a].ID {
+					found = true
+				}
+			}
+		}
+
+		return false
+	})
+
+	for _, g := range r.Guilds {
+		gn := tview.NewTreeNode(g.Name).
+			SetReference(g.ID).
+			Collapse()
+		n.AddChild(gn)
+	}
 
 	channelsTree.SetCurrentNode(n)
 }

+ 45 - 5
ui.go

@@ -1,6 +1,7 @@
 package main
 
 import (
+	"sort"
 	"strings"
 
 	"github.com/atotto/clipboard"
@@ -46,6 +47,7 @@ func newChannelsTree() *tview.TreeView {
 		SetSelectedFunc(onChannelsTreeSelected).
 		SetTopLevel(1).
 		SetRoot(tview.NewTreeNode("")).
+		SetTitle("Channels").
 		SetBorder(true).
 		SetBorderPadding(0, 0, 1, 0)
 
@@ -62,12 +64,50 @@ func onChannelsTreeSelected(n *tview.TreeNode) {
 	// Unhighlight the already-highlighted regions.
 	messagesView.Highlight()
 
-	ref := n.GetReference()
-	// If the node's reference is nil, the selected node is a guild or direct messages node; expand or collapse accordingly.
-	if ref == nil {
+	id := n.GetReference()
+	switch n.GetLevel() {
+	case 1: // Guilds or Direct Messages
+		if len(n.GetChildren()) == 0 {
+			// If the reference of the selected `*TreeNode` is `nil`, it is the direct messages `*TreeNode`.
+			if id == nil {
+				cs := session.State.PrivateChannels
+				sort.Slice(cs, func(i, j int) bool {
+					return cs[i].LastMessageID > cs[j].LastMessageID
+				})
+
+				for _, c := range cs {
+					tag := "[::d]"
+					if util.ChannelIsUnread(session.State, c) {
+						tag = "[::b]"
+					}
+
+					cn := tview.NewTreeNode(tag + util.ChannelToString(c) + "[::-]").
+						SetReference(c.ID).
+						Collapse()
+					n.AddChild(cn)
+				}
+			} else {
+				g, err := session.State.Guild(id.(string))
+				if err != nil {
+					return
+				}
+
+				sort.Slice(g.Channels, func(i, j int) bool {
+					return g.Channels[i].Position < g.Channels[j].Position
+				})
+
+				// Top-level channels
+				createTopLevelChannelsTreeNodes(n, g.Channels)
+				// Category channels
+				createCategoryChannelsTreeNodes(n, g.Channels)
+				// Second-level channels
+				createSecondLevelChannelsTreeNodes(g.Channels)
+			}
+		}
+
 		n.SetExpanded(!n.IsExpanded())
-	} else {
-		c, err := session.State.Channel(ref.(string))
+	default: // Channels
+		c, err := session.State.Channel(id.(string))
 		if err != nil {
 			return
 		}

+ 0 - 59
util.go

@@ -1,70 +1,11 @@
 package main
 
 import (
-	"sort"
-
 	"github.com/ayntgl/discordgo"
 	"github.com/ayntgl/discordo/util"
 	"github.com/rivo/tview"
 )
 
-func createPrivateChannels(n *tview.TreeNode) {
-	cs := session.State.PrivateChannels
-	sort.Slice(cs, func(i, j int) bool {
-		return cs[i].LastMessageID > cs[j].LastMessageID
-	})
-
-	for _, c := range cs {
-		var tag string
-		if util.ChannelIsUnread(session.State, c) {
-			tag = "[::b]"
-		} else {
-			tag = "[::d]"
-		}
-
-		cn := tview.NewTreeNode(tag + util.ChannelToString(c) + "[::-]").
-			SetReference(c.ID)
-		n.AddChild(cn)
-	}
-}
-
-func createGuilds(n *tview.TreeNode) {
-	gs := session.State.Guilds
-	sort.Slice(gs, func(a, b int) bool {
-		found := false
-		for _, gID := range session.State.Settings.GuildPositions {
-			if found {
-				if gID == gs[b].ID {
-					return true
-				}
-			} else {
-				if gID == gs[a].ID {
-					found = true
-				}
-			}
-		}
-
-		return false
-	})
-
-	for _, g := range gs {
-		gn := tview.NewTreeNode(g.Name).Collapse()
-		n.AddChild(gn)
-
-		cs := g.Channels
-		sort.Slice(cs, func(i, j int) bool {
-			return cs[i].Position < cs[j].Position
-		})
-
-		// Top-level channels
-		createTopLevelChannelsTreeNodes(gn, cs)
-		// Category channels
-		createCategoryChannelsTreeNodes(gn, cs)
-		// Second-level channels
-		createSecondLevelChannelsTreeNodes(cs)
-	}
-}
-
 func createTopLevelChannelsTreeNodes(
 	n *tview.TreeNode,
 	cs []*discordgo.Channel,