From 156bd2b720516cc17b82afa2e2583a8c519e836f Mon Sep 17 00:00:00 2001
From: ouwou <26526779+ouwou@users.noreply.github.com>
Date: Sat, 4 Feb 2023 23:17:35 -0500
Subject: [PATCH] fix channel tree expansion under folders
---
src/components/channels.cpp | 45 ++++++++++++++++++++++++++++---------
src/components/channels.hpp | 9 +++++++-
2 files changed, 42 insertions(+), 12 deletions(-)
diff --git a/src/components/channels.cpp b/src/components/channels.cpp
index 589b1032..934326dc 100644
--- a/src/components/channels.cpp
+++ b/src/components/channels.cpp
@@ -535,22 +535,27 @@ void ChannelList::SetActiveChannel(Snowflake id, bool expand_to) {
void ChannelList::UseExpansionState(const ExpansionStateRoot &root) {
auto recurse = [this](auto &self, const ExpansionStateRoot &root) -> void {
- // and these are only channels
for (const auto &[id, state] : root.Children) {
- if (const auto iter = m_tmp_channel_map.find(id); iter != m_tmp_channel_map.end()) {
+ Gtk::TreeModel::iterator row_iter;
+ if (const auto map_iter = m_tmp_row_map.find(id); map_iter != m_tmp_row_map.end()) {
+ row_iter = map_iter->second;
+ } else if (const auto map_iter = m_tmp_guild_row_map.find(id); map_iter != m_tmp_guild_row_map.end()) {
+ row_iter = map_iter->second;
+ }
+
+ if (row_iter) {
if (state.IsExpanded)
- m_view.expand_row(m_model->get_path(iter->second), false);
+ m_view.expand_row(m_model->get_path(row_iter), false);
else
- m_view.collapse_row(m_model->get_path(iter->second));
+ m_view.collapse_row(m_model->get_path(row_iter));
}
self(self, state.Children);
}
};
- // top level is guild
for (const auto &[id, state] : root.Children) {
- if (const auto iter = GetIteratorForGuildFromID(id)) {
+ if (const auto iter = GetIteratorForTopLevelFromID(id)) {
if (state.IsExpanded)
m_view.expand_row(m_model->get_path(iter), false);
else
@@ -560,7 +565,7 @@ void ChannelList::UseExpansionState(const ExpansionStateRoot &root) {
recurse(recurse, state.Children);
}
- m_tmp_channel_map.clear();
+ m_tmp_row_map.clear();
}
ExpansionStateRoot ChannelList::GetExpansionState() const {
@@ -598,6 +603,7 @@ Gtk::TreeModel::iterator ChannelList::AddFolder(const UserSettingsGuildFoldersEn
auto folder_row = *m_model->append();
folder_row[m_columns.m_type] = RenderType::Folder;
folder_row[m_columns.m_id] = *folder.ID;
+ m_tmp_row_map[*folder.ID] = folder_row;
if (folder.Name.has_value()) {
folder_row[m_columns.m_name] = Glib::Markup::escape_text(*folder.Name);
} else {
@@ -631,6 +637,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
guild_row[m_columns.m_id] = guild.ID;
guild_row[m_columns.m_name] = "" + Glib::Markup::escape_text(guild.Name) + "";
guild_row[m_columns.m_icon] = img.GetPlaceholder(GuildIconSize);
+ m_tmp_guild_row_map[guild.ID] = guild_row;
if (Abaddon::Get().GetSettings().ShowAnimations && guild.HasAnimatedIcon()) {
const auto cb = [this, id = guild.ID](const Glib::RefPtr &pb) {
@@ -678,7 +685,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
if (it == threads.end()) return;
for (const auto &thread : it->second)
- m_tmp_channel_map[thread.ID] = CreateThreadRow(row.children(), thread);
+ m_tmp_row_map[thread.ID] = CreateThreadRow(row.children(), thread);
};
for (const auto &channel : orphan_channels) {
@@ -689,7 +696,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
channel_row[m_columns.m_sort] = *channel.Position + OrphanChannelSortOffset;
channel_row[m_columns.m_nsfw] = channel.NSFW();
add_threads(channel, channel_row);
- m_tmp_channel_map[channel.ID] = channel_row;
+ m_tmp_row_map[channel.ID] = channel_row;
}
for (const auto &[category_id, channels] : categories) {
@@ -701,7 +708,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
cat_row[m_columns.m_name] = Glib::Markup::escape_text(*category->Name);
cat_row[m_columns.m_sort] = *category->Position;
cat_row[m_columns.m_expanded] = true;
- m_tmp_channel_map[category_id] = cat_row;
+ m_tmp_row_map[category_id] = cat_row;
// m_view.expand_row wont work because it might not have channels
for (const auto &channel : channels) {
@@ -712,7 +719,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk
channel_row[m_columns.m_sort] = *channel.Position;
channel_row[m_columns.m_nsfw] = channel.NSFW();
add_threads(channel, channel_row);
- m_tmp_channel_map[channel.ID] = channel_row;
+ m_tmp_row_map[channel.ID] = channel_row;
}
}
@@ -753,6 +760,22 @@ void ChannelList::UpdateChannelCategory(const ChannelData &channel) {
(*iter)[m_columns.m_name] = Glib::Markup::escape_text(*channel.Name);
}
+// todo this all needs refactoring for shooore
+Gtk::TreeModel::iterator ChannelList::GetIteratorForTopLevelFromID(Snowflake id) {
+ for (const auto &child : m_model->children()) {
+ if ((child[m_columns.m_type] == RenderType::Guild || child[m_columns.m_type] == RenderType::Folder) && child[m_columns.m_id] == id) {
+ return child;
+ } else if (child[m_columns.m_type] == RenderType::Folder) {
+ for (const auto &folder_child : child->children()) {
+ if (folder_child[m_columns.m_id] == id) {
+ return folder_child;
+ }
+ }
+ }
+ }
+ return {};
+}
+
Gtk::TreeModel::iterator ChannelList::GetIteratorForGuildFromID(Snowflake id) {
for (const auto &child : m_model->children()) {
if (child[m_columns.m_type] == RenderType::Guild && child[m_columns.m_id] == id) {
diff --git a/src/components/channels.hpp b/src/components/channels.hpp
index 6c16fcda..da006dce 100644
--- a/src/components/channels.hpp
+++ b/src/components/channels.hpp
@@ -4,6 +4,11 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
#include
#include "discord/discord.hpp"
#include "state.hpp"
@@ -80,6 +85,7 @@ class ChannelList : public Gtk::ScrolledWindow {
void UpdateChannelCategory(const ChannelData &channel);
// separation necessary because a channel and guild can share the same id
+ Gtk::TreeModel::iterator GetIteratorForTopLevelFromID(Snowflake id);
Gtk::TreeModel::iterator GetIteratorForGuildFromID(Snowflake id);
Gtk::TreeModel::iterator GetIteratorForChannelFromID(Snowflake id);
@@ -155,7 +161,8 @@ class ChannelList : public Gtk::ScrolledWindow {
// (GetIteratorForChannelFromID is rather slow)
// only temporary since i dont want to worry about maintaining this map
- std::unordered_map m_tmp_channel_map;
+ std::unordered_map m_tmp_row_map;
+ std::unordered_map m_tmp_guild_row_map;
public:
using type_signal_action_channel_item_select = sigc::signal;