Quellcode durchsuchen

feat: support for unread guilds and channels (#582)

Ayyan vor 9 Monaten
Ursprung
Commit
4b8a815a26
4 geänderte Dateien mit 73 neuen und 20 gelöschten Zeilen
  1. 33 7
      cmd/guilds_tree.go
  2. 40 5
      cmd/state.go
  3. 0 4
      internal/config/config.toml
  4. 0 4
      internal/config/theme.go

+ 33 - 7
cmd/guilds_tree.go

@@ -12,6 +12,7 @@ import (
 	"github.com/ayn2op/tview"
 	"github.com/diamondburned/arikawa/v3/discord"
 	"github.com/diamondburned/arikawa/v3/gateway"
+	"github.com/diamondburned/ningen/v3"
 	"github.com/gdamore/tcell/v2"
 )
 
@@ -61,11 +62,35 @@ func (gt *guildsTree) createFolderNode(folder gateway.GuildFolder) {
 	}
 }
 
-func (gt *guildsTree) createGuildNode(n *tview.TreeNode, g discord.Guild) {
-	style := gt.cfg.Theme.GuildsTree.GuildStyle.Style
-	guildNode := tview.NewTreeNode(g.Name).
-		SetReference(g.ID).
-		SetTextStyle(style)
+func (gt *guildsTree) unreadStyle(indication ningen.UnreadIndication) tcell.Style {
+	var style tcell.Style
+	switch indication {
+	case ningen.ChannelRead:
+		style = style.Dim(true)
+	case ningen.ChannelMentioned:
+		style = style.Underline(true)
+		fallthrough
+	case ningen.ChannelUnread:
+		style = style.Bold(true)
+	}
+
+	return style
+}
+
+func (gt *guildsTree) getGuildNodeStyle(guildID discord.GuildID) tcell.Style {
+	indication := discordState.GuildIsUnread(guildID, ningen.GuildUnreadOpts{UnreadOpts: ningen.UnreadOpts{IncludeMutedCategories: true}})
+	return gt.unreadStyle(indication)
+}
+
+func (gt *guildsTree) getChannelNodeStyle(channelID discord.ChannelID) tcell.Style {
+	indication := discordState.ChannelIsUnread(channelID, ningen.UnreadOpts{IncludeMutedCategories: true})
+	return gt.unreadStyle(indication)
+}
+
+func (gt *guildsTree) createGuildNode(n *tview.TreeNode, guild discord.Guild) {
+	guildNode := tview.NewTreeNode(guild.Name).
+		SetReference(guild.ID).
+		SetTextStyle(gt.getGuildNodeStyle(guild.ID))
 	n.AddChild(guildNode)
 }
 
@@ -110,10 +135,9 @@ func (gt *guildsTree) createChannelNode(node *tview.TreeNode, channel discord.Ch
 		}
 	}
 
-	style := gt.cfg.Theme.GuildsTree.ChannelStyle.Style
 	channelNode := tview.NewTreeNode(gt.channelToString(channel)).
 		SetReference(channel.ID).
-		SetTextStyle(style)
+		SetTextStyle(gt.getChannelNodeStyle(channel.ID))
 	node.AddChild(channelNode)
 }
 
@@ -190,6 +214,8 @@ func (gt *guildsTree) onSelected(node *tview.TreeNode) {
 			return
 		}
 
+		go discordState.ReadState.MarkRead(channel.ID, channel.LastMessageID)
+
 		app.messagesList.reset()
 		app.messagesList.drawMsgs(channel.ID)
 		app.messagesList.

+ 40 - 5
cmd/state.go

@@ -16,6 +16,7 @@ import (
 	"github.com/diamondburned/arikawa/v3/utils/httputil/httpdriver"
 	"github.com/diamondburned/arikawa/v3/utils/ws"
 	"github.com/diamondburned/ningen/v3"
+	"github.com/diamondburned/ningen/v3/states/read"
 )
 
 func openState(token string) error {
@@ -33,6 +34,7 @@ func openState(token string) error {
 	discordState.AddHandler(onReady)
 	discordState.AddHandler(onMessageCreate)
 	discordState.AddHandler(onMessageDelete)
+	discordState.AddHandler(onReadUpdate)
 
 	discordState.AddHandler(func(event *gateway.GuildMembersChunkEvent) {
 		app.messagesList.setFetchingChunk(false, uint(len(event.Members)))
@@ -88,12 +90,44 @@ func onRaw(event *ws.RawEvent) {
 	)
 }
 
-func onReady(r *gateway.ReadyEvent) {
-	style := app.cfg.Theme.GuildsTree.PrivateChannelStyle.Style
-	dmNode := tview.NewTreeNode("Direct Messages").
-		SetTextStyle(style).
-		SetSelectedTextStyle(style.Reverse(true))
+func onReadUpdate(event *read.UpdateEvent) {
+	var guildNode *tview.TreeNode
+	app.guildsTree.
+		GetRoot().
+		Walk(func(node, parent *tview.TreeNode) bool {
+			switch node.GetReference() {
+			case event.GuildID:
+				node.SetTextStyle(app.guildsTree.getGuildNodeStyle(event.GuildID))
+				guildNode = node
+				return false
+			case event.ChannelID:
+				// private channel
+				if !event.GuildID.IsValid() {
+					style := app.guildsTree.getChannelNodeStyle(event.ChannelID)
+					node.SetTextStyle(style)
+					return false
+				}
+			}
+
+			return true
+		})
+
+	if guildNode != nil {
+		guildNode.Walk(func(node, parent *tview.TreeNode) bool {
+			if node.GetReference() == event.ChannelID {
+				node.SetTextStyle(app.guildsTree.getChannelNodeStyle(event.ChannelID))
+				return false
+			}
 
+			return true
+		})
+	}
+
+	app.Draw()
+}
+
+func onReady(r *gateway.ReadyEvent) {
+	dmNode := tview.NewTreeNode("Direct Messages")
 	root := app.guildsTree.
 		GetRoot().
 		ClearChildren().
@@ -121,6 +155,7 @@ func onReady(r *gateway.ReadyEvent) {
 
 	app.guildsTree.SetCurrentNode(root)
 	app.SetFocus(app.guildsTree)
+	app.Draw()
 }
 
 func onMessageCreate(msg *gateway.MessageCreateEvent) {

+ 0 - 4
internal/config/config.toml

@@ -124,10 +124,6 @@ auto_expand_folders = true
 graphics = true
 graphics_color = "default"
 
-private_channel_style = { foreground = "default" }
-guild_style = { foreground = "default" }
-channel_style = { foreground = "default" }
-
 [theme.messages_list]
 reply_indicator = ">"
 forwarded_indicator = "<"

+ 0 - 4
internal/config/theme.go

@@ -93,10 +93,6 @@ type (
 		AutoExpandFolders bool   `toml:"auto_expand_folders"`
 		Graphics          bool   `toml:"graphics"`
 		GraphicsColor     string `toml:"graphics_color"`
-
-		PrivateChannelStyle StyleWrapper `toml:"private_channel_style"`
-		GuildStyle          StyleWrapper `toml:"guild_style"`
-		ChannelStyle        StyleWrapper `toml:"channel_style"`
 	}
 
 	MessagesListTheme struct {