From ed0dc8e553242c70e0754f1bfc68866f87b32d36 Mon Sep 17 00:00:00 2001 From: Andrej Novikov Date: Thu, 25 Dec 2025 04:16:44 +0200 Subject: [PATCH] feat(guilds_tree): support for forum channels (#612) Co-authored-by: Ayyan --- cmd/guilds_tree.go | 29 +++++++++++++++++++++++++++++ internal/ui/util.go | 2 ++ 2 files changed, 31 insertions(+) diff --git a/cmd/guilds_tree.go b/cmd/guilds_tree.go index 6a2e643..452d67b 100644 --- a/cmd/guilds_tree.go +++ b/cmd/guilds_tree.go @@ -169,6 +169,35 @@ func (gt *guildsTree) onSelected(node *tview.TreeNode) { return } + // Handle forum channels differently - they contain threads, not direct messages + if channel.Type == discord.GuildForum { + // Get all channels from the guild - this includes active threads from GuildCreateEvent + allChannels, err := discordState.Cabinet.Channels(channel.GuildID) + if err != nil { + slog.Error("failed to get channels for forum threads", "err", err, "guild_id", channel.GuildID) + return + } + + // Filter for threads that belong to this forum channel + var forumThreads []discord.Channel + for _, ch := range allChannels { + if ch.ParentID == channel.ID && (ch.Type == discord.GuildPublicThread || + ch.Type == discord.GuildPrivateThread || + ch.Type == discord.GuildAnnouncementThread) { + forumThreads = append(forumThreads, ch) + } + } + + // Add threads as child nodes + for _, thread := range forumThreads { + gt.createChannelNode(node, thread) + } + + // Expand the node to show threads + node.SetExpanded(true) + return + } + go discordState.ReadState.MarkRead(channel.ID, channel.LastMessageID) messages, err := discordState.Messages(channel.ID, uint(gt.cfg.MessagesLimit)) diff --git a/internal/ui/util.go b/internal/ui/util.go index e2dac5f..d5952f6 100644 --- a/internal/ui/util.go +++ b/internal/ui/util.go @@ -73,6 +73,8 @@ func ChannelToString(channel discord.Channel) string { return "s-" + channel.Name case discord.GuildForum: return "f-" + channel.Name + case discord.GuildPublicThread, discord.GuildPrivateThread, discord.GuildAnnouncementThread: + return "t-" + channel.Name default: return channel.Name }