From ee67037a3fce6413ec6b6a78a8588d775020f1c8 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 8 Aug 2022 23:25:34 -0400 Subject: store token in keychain --- src/settings.cpp | 48 ++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 46 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/settings.cpp b/src/settings.cpp index 242bd7c..7564d4d 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1,6 +1,15 @@ #include "settings.hpp" #include #include +#include + +#ifdef WITH_KEYCHAIN + #include +#endif + +const std::string KeychainPackage = "com.github.uowuo.abaddon"; +const std::string KeychainService = "client-token"; +const std::string KeychainUser = "discord"; SettingsManager::SettingsManager(const std::string &filename) : m_filename(filename) { @@ -36,7 +45,6 @@ void SettingsManager::ReadSettings() { SMSTR("discord", "api_base", APIBaseURL); SMSTR("discord", "gateway", GatewayURL); - SMSTR("discord", "token", DiscordToken); SMBOOL("discord", "memory_db", UseMemoryDB); SMBOOL("discord", "prefetch", Prefetch); SMSTR("gui", "css", MainCSS); @@ -58,6 +66,32 @@ void SettingsManager::ReadSettings() { SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor); SMSTR("style", "unreadcolor", UnreadIndicatorColor); +#ifdef WITH_KEYCHAIN + keychain::Error error {}; + + // convert to keychain if present in normal settings + SMSTR("discord", "token", DiscordToken); + + if (!m_settings.DiscordToken.empty()) { + keychain::Error set_error {}; + + keychain::setPassword(KeychainPackage, KeychainService, KeychainUser, m_settings.DiscordToken, set_error); + if (set_error) { + printf("keychain error setting token: %s\n", set_error.message.c_str()); + } else { + m_file.remove_key("discord", "token"); + } + } + + m_settings.DiscordToken = keychain::getPassword(KeychainPackage, KeychainService, KeychainUser, error); + if (error && error.type != keychain::ErrorType::NotFound) { + printf("keychain error reading token: %s (%d)\n", error.message.c_str(), error.code); + } + +#else + SMSTR("discord", "token", DiscordToken); +#endif + #undef SMBOOL #undef SMSTR #undef SMINT @@ -89,7 +123,6 @@ void SettingsManager::Close() { SMSTR("discord", "api_base", APIBaseURL); SMSTR("discord", "gateway", GatewayURL); - SMSTR("discord", "token", DiscordToken); SMBOOL("discord", "memory_db", UseMemoryDB); SMBOOL("discord", "prefetch", Prefetch); SMSTR("gui", "css", MainCSS); @@ -111,6 +144,17 @@ void SettingsManager::Close() { SMSTR("style", "mentionbadgetextcolor", MentionBadgeTextColor); SMSTR("style", "unreadcolor", UnreadIndicatorColor); +#ifdef WITH_KEYCHAIN + keychain::Error error {}; + + keychain::setPassword(KeychainPackage, KeychainService, KeychainUser, m_settings.DiscordToken, error); + if (error) { + printf("keychain error setting token: %s\n", error.message.c_str()); + } +#else + SMSTR("discord", "token", DiscordToken); +#endif + #undef SMSTR #undef SMBOOL #undef SMINT -- cgit v1.2.3 From 77dd9fabfa054bd8fa24f869b976da7ee69c8a87 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Tue, 9 Aug 2022 02:06:24 -0400 Subject: change service clear user --- src/settings.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/settings.cpp b/src/settings.cpp index 7564d4d..6afc351 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -8,8 +8,8 @@ #endif const std::string KeychainPackage = "com.github.uowuo.abaddon"; -const std::string KeychainService = "client-token"; -const std::string KeychainUser = "discord"; +const std::string KeychainService = "abaddon-client-token"; +const std::string KeychainUser = ""; SettingsManager::SettingsManager(const std::string &filename) : m_filename(filename) { -- cgit v1.2.3 From 2a9f49a1485a145668923a550347af8890e88bf0 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Thu, 3 Nov 2022 00:45:31 -0400 Subject: add menu item + shortcuts to hide channel and member lists (closes #118) --- src/windows/mainwindow.cpp | 16 ++++++++++++++++ src/windows/mainwindow.hpp | 2 ++ 2 files changed, 18 insertions(+) (limited to 'src') diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 20da46b..8a85d49 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -265,6 +265,12 @@ void MainWindow::SetupMenu() { m_menu_view_threads.set_label("Threads"); m_menu_view_mark_guild_as_read.set_label("Mark Server as Read"); m_menu_view_mark_guild_as_read.add_accelerator("activate", m_accels, GDK_KEY_Escape, Gdk::SHIFT_MASK, Gtk::ACCEL_VISIBLE); + m_menu_view_channels.set_label("Channels"); + m_menu_view_channels.add_accelerator("activate", m_accels, GDK_KEY_L, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + m_menu_view_channels.set_active(true); + m_menu_view_members.set_label("Members"); + m_menu_view_members.add_accelerator("activate", m_accels, GDK_KEY_M, Gdk::CONTROL_MASK, Gtk::ACCEL_VISIBLE); + m_menu_view_members.set_active(true); #ifdef WITH_LIBHANDY m_menu_view_go_back.set_label("Go Back"); m_menu_view_go_forward.set_label("Go Forward"); @@ -275,6 +281,8 @@ void MainWindow::SetupMenu() { m_menu_view_sub.append(m_menu_view_pins); m_menu_view_sub.append(m_menu_view_threads); m_menu_view_sub.append(m_menu_view_mark_guild_as_read); + m_menu_view_sub.append(m_menu_view_channels); + m_menu_view_sub.append(m_menu_view_members); #ifdef WITH_LIBHANDY m_menu_view_sub.append(m_menu_view_go_back); m_menu_view_sub.append(m_menu_view_go_forward); @@ -354,6 +362,14 @@ void MainWindow::SetupMenu() { } }); + m_menu_view_channels.signal_activate().connect([this]() { + m_channel_list.set_visible(m_menu_view_channels.get_active()); + }); + + m_menu_view_members.signal_activate().connect([this]() { + m_members.GetRoot()->set_visible(m_menu_view_members.get_active()); + }); + #ifdef WITH_LIBHANDY m_menu_view_go_back.signal_activate().connect([this] { GoBack(); diff --git a/src/windows/mainwindow.hpp b/src/windows/mainwindow.hpp index 6e95b72..78e0115 100644 --- a/src/windows/mainwindow.hpp +++ b/src/windows/mainwindow.hpp @@ -79,6 +79,8 @@ private: Gtk::MenuItem m_menu_view_pins; Gtk::MenuItem m_menu_view_threads; Gtk::MenuItem m_menu_view_mark_guild_as_read; + Gtk::CheckMenuItem m_menu_view_channels; + Gtk::CheckMenuItem m_menu_view_members; #ifdef WITH_LIBHANDY Gtk::MenuItem m_menu_view_go_back; Gtk::MenuItem m_menu_view_go_forward; -- cgit v1.2.3 From e0e0a6c76708fdf12113bf1b5c4ee96eacc35cae Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 21 Dec 2022 21:49:18 -0500 Subject: add option to dump ready payload because thats useful --- src/discord/discord.cpp | 15 +++++++++++++++ src/discord/discord.hpp | 4 ++++ src/windows/mainwindow.cpp | 6 ++++++ src/windows/mainwindow.hpp | 1 + 4 files changed, 26 insertions(+) (limited to 'src') diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 2808e17..6739493 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -1204,6 +1204,10 @@ void DiscordClient::SetUserAgent(const std::string &agent) { m_websocket.SetUserAgent(agent); } +void DiscordClient::SetDumpReady(bool dump) { + m_dump_ready = dump; +} + bool DiscordClient::IsChannelMuted(Snowflake id) const noexcept { return m_muted_channels.find(id) != m_muted_channels.end(); } @@ -1566,6 +1570,17 @@ void DiscordClient::ProcessNewGuild(GuildData &guild) { void DiscordClient::HandleGatewayReady(const GatewayMessage &msg) { m_ready_received = true; + + if (m_dump_ready) { + const auto name = "./payload_ready-" + Glib::DateTime::create_now_utc().format("%Y-%m-%d_%H-%M-%S") + ".json"; + auto *fp = std::fopen(name.c_str(), "wb"); + if (fp != nullptr) { + const auto contents = msg.Data.dump(4); + std::fwrite(contents.data(), contents.size(), 1, fp); + std::fclose(fp); + } + } + ReadyEventData data = msg.Data; for (auto &g : data.Guilds) ProcessNewGuild(g); diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index c2bea7d..685d096 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -211,6 +211,8 @@ public: void UpdateToken(const std::string &token); void SetUserAgent(const std::string &agent); + void SetDumpReady(bool dump); + bool IsChannelMuted(Snowflake id) const noexcept; bool IsGuildMuted(Snowflake id) const noexcept; int GetUnreadStateForChannel(Snowflake id) const noexcept; @@ -229,6 +231,8 @@ private: std::vector m_decompress_buf; z_stream m_zstream; + bool m_dump_ready = false; + static std::string GetAPIURL(); static std::string GetGatewayURL(); diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 8a85d49..f1d16ec 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -255,8 +255,10 @@ void MainWindow::SetupMenu() { m_menu_file.set_submenu(m_menu_file_sub); m_menu_file_reload_css.set_label("Reload CSS"); m_menu_file_clear_cache.set_label("Clear file cache"); + m_menu_file_dump_ready.set_label("Dump ready message"); m_menu_file_sub.append(m_menu_file_reload_css); m_menu_file_sub.append(m_menu_file_clear_cache); + m_menu_file_sub.append(m_menu_file_dump_ready); m_menu_view.set_label("View"); m_menu_view.set_submenu(m_menu_view_sub); @@ -335,6 +337,10 @@ void MainWindow::SetupMenu() { Abaddon::Get().GetImageManager().ClearCache(); }); + m_menu_file_dump_ready.signal_toggled().connect([this]() { + Abaddon::Get().GetDiscordClient().SetDumpReady(m_menu_file_dump_ready.get_active()); + }); + m_menu_discord_add_recipient.signal_activate().connect([this] { m_signal_action_add_recipient.emit(GetChatActiveChannel()); }); diff --git a/src/windows/mainwindow.hpp b/src/windows/mainwindow.hpp index 78e0115..35ca7f1 100644 --- a/src/windows/mainwindow.hpp +++ b/src/windows/mainwindow.hpp @@ -72,6 +72,7 @@ private: Gtk::Menu m_menu_file_sub; Gtk::MenuItem m_menu_file_reload_css; Gtk::MenuItem m_menu_file_clear_cache; + Gtk::CheckMenuItem m_menu_file_dump_ready; Gtk::MenuItem m_menu_view; Gtk::Menu m_menu_view_sub; -- cgit v1.2.3 From 1ba3daa04ac374504a5cdf62cb5fde44f12027bc Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 23 Dec 2022 20:14:10 -0500 Subject: basic folder support --- src/components/channels.cpp | 89 +++++++++++++++++++++++++++++++-- src/components/channels.hpp | 3 +- src/components/channelscellrenderer.cpp | 69 +++++++++++++++++++++++++ src/components/channelscellrenderer.hpp | 12 +++++ src/discord/discord.cpp | 4 ++ src/discord/discord.hpp | 1 + src/discord/usersettings.hpp | 7 +-- 7 files changed, 176 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 497c021..b14a3c1 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -262,7 +262,42 @@ void ChannelList::UpdateListing() { auto &discord = Abaddon::Get().GetDiscordClient(); - const auto guild_ids = discord.GetUserSortedGuilds(); + /* + guild_folders looks something like this + "guild_folders": [ + { + "color": null, + "guild_ids": [ + "8009060___________" + ], + "id": null, + "name": null + }, + { + "color": null, + "guild_ids": [ + "99615594__________", + "86132141__________", + "35450138__________", + "83714048__________" + ], + "id": 2853066769, + "name": null + } + ] + + so if id != null then its a folder (they can have single entries) + */ + + int sort_value = 0; + + const auto folders = discord.GetUserSettings().GuildFolders; + for (const auto &group : folders) { + auto iter = AddFolder(group); + (*iter)[m_columns.m_sort] = sort_value++; + } + + /* int sortnum = 0; for (const auto &guild_id : guild_ids) { const auto guild = discord.GetGuild(guild_id); @@ -271,6 +306,7 @@ void ChannelList::UpdateListing() { auto iter = AddGuild(*guild); (*iter)[m_columns.m_sort] = sortnum++; } + */ m_updating_listing = false; @@ -278,7 +314,7 @@ void ChannelList::UpdateListing() { } void ChannelList::UpdateNewGuild(const GuildData &guild) { - AddGuild(guild); + AddGuild(guild, m_model->children()); // update sort order int sortnum = 0; for (const auto guild_id : Abaddon::Get().GetDiscordClient().GetUserSortedGuilds()) { @@ -405,6 +441,8 @@ void ChannelList::OnThreadListSync(const ThreadListSyncData &data) { // get the threads in the guild std::vector threads; auto guild_iter = GetIteratorForGuildFromID(data.GuildID); + if (!guild_iter) return; + std::queue queue; queue.push(guild_iter); @@ -546,11 +584,45 @@ ExpansionStateRoot ChannelList::GetExpansionState() const { return r; } -Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) { +Gtk::TreeModel::iterator ChannelList::AddFolder(const UserSettingsGuildFoldersEntry &folder) { + if (!folder.ID.has_value()) { + // just a guild + if (!folder.GuildIDs.empty()) { + const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(folder.GuildIDs[0]); + if (guild.has_value()) { + return AddGuild(*guild, m_model->children()); + } + } + } else { + auto folder_row = *m_model->append(); + folder_row[m_columns.m_type] = RenderType::Folder; + folder_row[m_columns.m_id] = *folder.ID; + if (folder.Name.has_value()) { + folder_row[m_columns.m_name] = Glib::Markup::escape_text(*folder.Name); + } else { + folder_row[m_columns.m_name] = "Folder"; + } + + int sort_value = 0; + for (const auto &guild_id : folder.GuildIDs) { + const auto guild = Abaddon::Get().GetDiscordClient().GetGuild(guild_id); + if (guild.has_value()) { + auto guild_row = AddGuild(*guild, folder_row->children()); + (*guild_row)[m_columns.m_sort] = sort_value++; + } + } + + return folder_row; + } + + return {}; +} + +Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root) { auto &discord = Abaddon::Get().GetDiscordClient(); auto &img = Abaddon::Get().GetImageManager(); - auto guild_row = *m_model->append(); + auto guild_row = *m_model->append(root); guild_row[m_columns.m_type] = RenderType::Guild; guild_row[m_columns.m_id] = guild.ID; guild_row[m_columns.m_name] = "" + Glib::Markup::escape_text(guild.Name) + ""; @@ -679,8 +751,15 @@ void ChannelList::UpdateChannelCategory(const ChannelData &channel) { Gtk::TreeModel::iterator ChannelList::GetIteratorForGuildFromID(Snowflake id) { for (const auto &child : m_model->children()) { - if (child[m_columns.m_id] == id) + if (child[m_columns.m_type] == RenderType::Guild && 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 {}; } diff --git a/src/components/channels.hpp b/src/components/channels.hpp index 53a68c9..37a3610 100644 --- a/src/components/channels.hpp +++ b/src/components/channels.hpp @@ -72,7 +72,8 @@ protected: ModelColumns m_columns; Glib::RefPtr m_model; - Gtk::TreeModel::iterator AddGuild(const GuildData &guild); + Gtk::TreeModel::iterator AddFolder(const UserSettingsGuildFoldersEntry &folder); + Gtk::TreeModel::iterator AddGuild(const GuildData &guild, const Gtk::TreeNodeChildren &root); Gtk::TreeModel::iterator UpdateCreateChannelCategory(const ChannelData &channel); Gtk::TreeModel::iterator CreateThreadRow(const Gtk::TreeNodeChildren &children, const ChannelData &channel); diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 9afce8a..9e2d391 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -57,6 +57,8 @@ Glib::PropertyProxy CellRendererChannels::property_nsfw() { void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const { switch (m_property_type.get_value()) { + case RenderType::Folder: + return get_preferred_width_vfunc_folder(widget, minimum_width, natural_width); case RenderType::Guild: return get_preferred_width_vfunc_guild(widget, minimum_width, natural_width); case RenderType::Category: @@ -74,6 +76,8 @@ void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &m void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const { switch (m_property_type.get_value()) { + case RenderType::Folder: + return get_preferred_width_for_height_vfunc_folder(widget, height, minimum_width, natural_width); case RenderType::Guild: return get_preferred_width_for_height_vfunc_guild(widget, height, minimum_width, natural_width); case RenderType::Category: @@ -91,6 +95,8 @@ void CellRendererChannels::get_preferred_width_for_height_vfunc(Gtk::Widget &wid void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int &minimum_height, int &natural_height) const { switch (m_property_type.get_value()) { + case RenderType::Folder: + return get_preferred_height_vfunc_folder(widget, minimum_height, natural_height); case RenderType::Guild: return get_preferred_height_vfunc_guild(widget, minimum_height, natural_height); case RenderType::Category: @@ -108,6 +114,8 @@ void CellRendererChannels::get_preferred_height_vfunc(Gtk::Widget &widget, int & void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const { switch (m_property_type.get_value()) { + case RenderType::Folder: + return get_preferred_height_for_width_vfunc_folder(widget, width, minimum_height, natural_height); case RenderType::Guild: return get_preferred_height_for_width_vfunc_guild(widget, width, minimum_height, natural_height); case RenderType::Category: @@ -125,6 +133,8 @@ void CellRendererChannels::get_preferred_height_for_width_vfunc(Gtk::Widget &wid void CellRendererChannels::render_vfunc(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { switch (m_property_type.get_value()) { + case RenderType::Folder: + return render_vfunc_folder(cr, widget, background_area, cell_area, flags); case RenderType::Guild: return render_vfunc_guild(cr, widget, background_area, cell_area, flags); case RenderType::Category: @@ -140,6 +150,65 @@ void CellRendererChannels::render_vfunc(const Cairo::RefPtr &cr, } } +// folder functions + +void CellRendererChannels::get_preferred_width_vfunc_folder(Gtk::Widget &widget, int &minimum_width, int &natural_width) const { + m_renderer_text.get_preferred_width(widget, minimum_width, natural_width); +} + +void CellRendererChannels::get_preferred_width_for_height_vfunc_folder(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const { + m_renderer_text.get_preferred_width_for_height(widget, height, minimum_width, natural_width); +} + +void CellRendererChannels::get_preferred_height_vfunc_folder(Gtk::Widget &widget, int &minimum_height, int &natural_height) const { + m_renderer_text.get_preferred_height(widget, minimum_height, natural_height); +} + +void CellRendererChannels::get_preferred_height_for_width_vfunc_folder(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const { + m_renderer_text.get_preferred_height_for_width(widget, width, minimum_height, natural_height); +} + +void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr &cr, Gtk::Widget &widget, const Gdk::Rectangle &background_area, const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) { + constexpr static int len = 5; + int x1, y1, x2, y2, x3, y3; + if (property_expanded()) { + x1 = background_area.get_x() + 7; + y1 = background_area.get_y() + background_area.get_height() / 2 - len; + x2 = background_area.get_x() + 7 + len; + y2 = background_area.get_y() + background_area.get_height() / 2 + len; + x3 = background_area.get_x() + 7 + len * 2; + y3 = background_area.get_y() + background_area.get_height() / 2 - len; + } else { + x1 = background_area.get_x() + 7; + y1 = background_area.get_y() + background_area.get_height() / 2 - len; + x2 = background_area.get_x() + 7 + len * 2; + y2 = background_area.get_y() + background_area.get_height() / 2; + x3 = background_area.get_x() + 7; + y3 = background_area.get_y() + background_area.get_height() / 2 + len; + } + cr->move_to(x1, y1); + cr->line_to(x2, y2); + cr->line_to(x3, y3); + const auto expander_color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelsExpanderColor); + cr->set_source_rgb(expander_color.get_red(), expander_color.get_green(), expander_color.get_blue()); + cr->stroke(); + + Gtk::Requisition text_minimum, text_natural; + m_renderer_text.get_preferred_size(widget, text_minimum, text_natural); + + const int text_x = background_area.get_x() + 22; + const int text_y = background_area.get_y() + background_area.get_height() / 2 - text_natural.height / 2; + const int text_w = text_natural.width; + const int text_h = text_natural.height; + + Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h); + + static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor); + m_renderer_text.property_foreground_rgba() = color; + m_renderer_text.render(cr, widget, background_area, text_cell_area, flags); + m_renderer_text.property_foreground_set() = false; +} + // guild functions void CellRendererChannels::get_preferred_width_vfunc_guild(Gtk::Widget &widget, int &minimum_width, int &natural_width) const { diff --git a/src/components/channelscellrenderer.hpp b/src/components/channelscellrenderer.hpp index e2be9b2..00c3603 100644 --- a/src/components/channelscellrenderer.hpp +++ b/src/components/channelscellrenderer.hpp @@ -6,6 +6,7 @@ #include "discord/snowflake.hpp" enum class RenderType : uint8_t { + Folder, Guild, Category, TextChannel, @@ -39,6 +40,17 @@ protected: const Gdk::Rectangle &cell_area, Gtk::CellRendererState flags) override; + // guild functions + void get_preferred_width_vfunc_folder(Gtk::Widget &widget, int &minimum_width, int &natural_width) const; + void get_preferred_width_for_height_vfunc_folder(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const; + void get_preferred_height_vfunc_folder(Gtk::Widget &widget, int &minimum_height, int &natural_height) const; + void get_preferred_height_for_width_vfunc_folder(Gtk::Widget &widget, int width, int &minimum_height, int &natural_height) const; + void render_vfunc_folder(const Cairo::RefPtr &cr, + Gtk::Widget &widget, + const Gdk::Rectangle &background_area, + const Gdk::Rectangle &cell_area, + Gtk::CellRendererState flags); + // guild functions void get_preferred_width_vfunc_guild(Gtk::Widget &widget, int &minimum_width, int &natural_width) const; void get_preferred_width_for_height_vfunc_guild(Gtk::Widget &widget, int height, int &minimum_width, int &natural_width) const; diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 6739493..15fed3a 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -2292,6 +2292,10 @@ std::set DiscordClient::GetPrivateChannels() const { return {}; } +const UserSettings &DiscordClient::GetUserSettings() const { + return m_user_settings; +} + EPremiumType DiscordClient::GetSelfPremiumType() const { const auto &data = GetUserData(); if (data.PremiumType.has_value()) diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index 685d096..6f90659 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -60,6 +60,7 @@ public: std::vector GetMessagesForChannel(Snowflake id, size_t limit = 50) const; std::vector GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit = 50) const; std::set GetPrivateChannels() const; + const UserSettings &GetUserSettings() const; EPremiumType GetSelfPremiumType() const; diff --git a/src/discord/usersettings.hpp b/src/discord/usersettings.hpp index 2631c45..513390b 100644 --- a/src/discord/usersettings.hpp +++ b/src/discord/usersettings.hpp @@ -1,13 +1,14 @@ #pragma once #include "json.hpp" #include "snowflake.hpp" +#include #include struct UserSettingsGuildFoldersEntry { - int Color = -1; // null + std::optional Color; std::vector GuildIDs; - Snowflake ID; // null (this can be a snowflake as a string or an int that isnt a snowflake lol) - std::string Name; // null + std::optional ID; // (this can be a snowflake as a string or an int that isnt a snowflake lol) + std::optional Name; friend void from_json(const nlohmann::json &j, UserSettingsGuildFoldersEntry &m); }; -- cgit v1.2.3 From d2cbe00af25bacd40fc4c55191bf9c9073aca1bf Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 24 Dec 2022 02:44:56 -0500 Subject: colors, fallback if guild_folders is empty --- src/components/channels.cpp | 36 ++++++++++++++++++++------------- src/components/channels.hpp | 1 + src/components/channelscellrenderer.cpp | 13 ++++++++++-- src/components/channelscellrenderer.hpp | 2 ++ 4 files changed, 36 insertions(+), 16 deletions(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index b14a3c1..5e4570b 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -89,6 +89,7 @@ ChannelList::ChannelList() column->add_attribute(renderer->property_id(), m_columns.m_id); column->add_attribute(renderer->property_expanded(), m_columns.m_expanded); column->add_attribute(renderer->property_nsfw(), m_columns.m_nsfw); + column->add_attribute(renderer->property_color(), m_columns.m_color); m_view.append_column(*column); m_menu_guild_copy_id.signal_activate().connect([this] { @@ -292,27 +293,29 @@ void ChannelList::UpdateListing() { int sort_value = 0; const auto folders = discord.GetUserSettings().GuildFolders; - for (const auto &group : folders) { - auto iter = AddFolder(group); - (*iter)[m_columns.m_sort] = sort_value++; - } - - /* - int sortnum = 0; - for (const auto &guild_id : guild_ids) { - const auto guild = discord.GetGuild(guild_id); - if (!guild.has_value()) continue; - - auto iter = AddGuild(*guild); - (*iter)[m_columns.m_sort] = sortnum++; + if (folders.empty()) { + // fallback if no organization has occurred (guild_folders will be empty) + const auto guild_ids = discord.GetUserSortedGuilds(); + for (const auto &guild_id : guild_ids) { + const auto guild = discord.GetGuild(guild_id); + if (!guild.has_value()) continue; + + auto iter = AddGuild(*guild, m_model->children()); + (*iter)[m_columns.m_sort] = sort_value++; + } + } else { + for (const auto &group : folders) { + auto iter = AddFolder(group); + (*iter)[m_columns.m_sort] = sort_value++; + } } - */ m_updating_listing = false; AddPrivateChannels(); } +// TODO update for folders void ChannelList::UpdateNewGuild(const GuildData &guild) { AddGuild(guild, m_model->children()); // update sort order @@ -602,6 +605,9 @@ Gtk::TreeModel::iterator ChannelList::AddFolder(const UserSettingsGuildFoldersEn } else { folder_row[m_columns.m_name] = "Folder"; } + if (folder.Color.has_value()) { + folder_row[m_columns.m_color] = IntToRGBA(*folder.Color); + } int sort_value = 0; for (const auto &guild_id : folder.GuildIDs) { @@ -973,6 +979,7 @@ void ChannelList::MoveRow(const Gtk::TreeModel::iterator &iter, const Gtk::TreeM M(m_sort); M(m_nsfw); M(m_expanded); + M(m_color); #undef M // recursively move children @@ -1085,4 +1092,5 @@ ChannelList::ModelColumns::ModelColumns() { add(m_sort); add(m_nsfw); add(m_expanded); + add(m_color); } diff --git a/src/components/channels.hpp b/src/components/channels.hpp index 37a3610..6ceaada 100644 --- a/src/components/channels.hpp +++ b/src/components/channels.hpp @@ -61,6 +61,7 @@ protected: Gtk::TreeModelColumn> m_icon_anim; Gtk::TreeModelColumn m_sort; Gtk::TreeModelColumn m_nsfw; + Gtk::TreeModelColumn> m_color; // for folders right now // Gtk::CellRenderer's property_is_expanded only works how i want it to if it has children // because otherwise it doesnt count as an "expander" (property_is_expander) // so this solution will have to do which i hate but the alternative is adding invisible children diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 9e2d391..69f0450 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -18,7 +18,8 @@ CellRendererChannels::CellRendererChannels() , m_property_pixbuf(*this, "pixbuf") , m_property_pixbuf_animation(*this, "pixbuf-animation") , m_property_expanded(*this, "expanded") - , m_property_nsfw(*this, "nsfw") { + , m_property_nsfw(*this, "nsfw") + , m_property_color(*this, "color") { property_mode() = Gtk::CELL_RENDERER_MODE_ACTIVATABLE; property_xpad() = 2; property_ypad() = 2; @@ -55,6 +56,10 @@ Glib::PropertyProxy CellRendererChannels::property_nsfw() { return m_property_nsfw.get_proxy(); } +Glib::PropertyProxy> CellRendererChannels::property_color() { + return m_property_color.get_proxy(); +} + void CellRendererChannels::get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const { switch (m_property_type.get_value()) { case RenderType::Folder: @@ -204,7 +209,11 @@ void CellRendererChannels::render_vfunc_folder(const Cairo::RefPtr> property_icon_animation(); Glib::PropertyProxy property_expanded(); Glib::PropertyProxy property_nsfw(); + Glib::PropertyProxy> property_color(); protected: void get_preferred_width_vfunc(Gtk::Widget &widget, int &minimum_width, int &natural_width) const override; @@ -130,6 +131,7 @@ private: Glib::Property> m_property_pixbuf_animation; // guild Glib::Property m_property_expanded; // category Glib::Property m_property_nsfw; // channel + Glib::Property> m_property_color; // folder // same pitfalls as in https://github.com/uowuo/abaddon/blob/60404783bd4ce9be26233fe66fc3a74475d9eaa3/components/cellrendererpixbufanimation.hpp#L32-L39 // this will manifest though since guild icons can change -- cgit v1.2.3 From dc7047265f70c68946298ec09a43e105484caad3 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 21 Jan 2023 00:57:09 -0500 Subject: speed up channel list population on connect a good bit --- src/discord/discord.cpp | 16 +++++++--------- src/discord/store.cpp | 42 ++++++++++++++++++++++++++++++++++++++++++ src/discord/store.hpp | 4 ++++ 3 files changed, 53 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 2808e17..d7cee4c 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -341,12 +341,10 @@ bool DiscordClient::HasChannelPermission(Snowflake user_id, Snowflake channel_id } Permission DiscordClient::ComputePermissions(Snowflake member_id, Snowflake guild_id) const { - const auto member = GetMember(member_id, guild_id); - const auto guild = GetGuild(guild_id); - if (!member.has_value() || !guild.has_value()) - return Permission::NONE; + const auto member_roles = m_store.GetMemberRoles(guild_id, member_id); + const auto guild_owner = m_store.GetGuildOwner(guild_id); - if (guild->OwnerID == member_id) + if (guild_owner == member_id) return Permission::ALL; const auto everyone = GetRole(guild_id); @@ -354,7 +352,7 @@ Permission DiscordClient::ComputePermissions(Snowflake member_id, Snowflake guil return Permission::NONE; Permission perms = everyone->Permissions; - for (const auto role_id : member->Roles) { + for (const auto role_id : member_roles) { const auto role = GetRole(role_id); if (role.has_value()) perms |= role->Permissions; @@ -371,8 +369,8 @@ Permission DiscordClient::ComputeOverwrites(Permission base, Snowflake member_id return Permission::ALL; const auto channel = GetChannel(channel_id); - const auto member = GetMember(member_id, *channel->GuildID); - if (!member.has_value() || !channel.has_value()) + const auto member_roles = m_store.GetMemberRoles(*channel->GuildID, member_id); + if (!channel.has_value()) return Permission::NONE; Permission perms = base; @@ -384,7 +382,7 @@ Permission DiscordClient::ComputeOverwrites(Permission base, Snowflake member_id Permission allow = Permission::NONE; Permission deny = Permission::NONE; - for (const auto role_id : member->Roles) { + for (const auto role_id : member_roles) { const auto overwrite = GetPermissionOverwrite(channel_id, role_id); if (overwrite.has_value()) { allow |= overwrite->Allow; diff --git a/src/discord/store.cpp b/src/discord/store.cpp index 892f4aa..7f674c4 100644 --- a/src/discord/store.cpp +++ b/src/discord/store.cpp @@ -473,6 +473,40 @@ std::vector Store::GetBans(Snowflake guild_id) const { return ret; } +Snowflake Store::GetGuildOwner(Snowflake guild_id) const { + auto &s = m_stmt_get_guild_owner; + + s->Bind(1, guild_id); + if (s->FetchOne()) { + Snowflake ret; + s->Get(0, ret); + s->Reset(); + return ret; + } + + s->Reset(); + + return Snowflake::Invalid; +} + +std::vector Store::GetMemberRoles(Snowflake guild_id, Snowflake user_id) const { + std::vector ret; + + auto &s = m_stmt_get_member_roles; + + s->Bind(1, user_id); + s->Bind(2, guild_id); + + while (s->FetchOne()) { + auto &f = ret.emplace_back(); + s->Get(0, f); + } + + s->Reset(); + + return ret; +} + std::vector Store::GetLastMessages(Snowflake id, size_t num) const { auto &s = m_stmt_get_last_msgs; std::vector msgs; @@ -2198,6 +2232,14 @@ bool Store::CreateStatements() { return false; } + m_stmt_get_guild_owner = std::make_unique(m_db, R"( + SELECT owner_id FROM guilds WHERE id = ? + )"); + if (!m_stmt_get_guild_owner->OK()) { + fprintf(stderr, "failed to prepare get guild owner statement: %s\n", m_db.ErrStr()); + return false; + } + return true; } diff --git a/src/discord/store.hpp b/src/discord/store.hpp index da97dd5..f1e2f05 100644 --- a/src/discord/store.hpp +++ b/src/discord/store.hpp @@ -39,6 +39,9 @@ public: std::optional GetBan(Snowflake guild_id, Snowflake user_id) const; std::vector GetBans(Snowflake guild_id) const; + Snowflake GetGuildOwner(Snowflake guild_id) const; + std::vector GetMemberRoles(Snowflake guild_id, Snowflake user_id) const; + std::vector GetLastMessages(Snowflake id, size_t num) const; std::vector GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit) const; std::vector GetPinnedMessages(Snowflake channel_id) const; @@ -308,5 +311,6 @@ private: STMT(get_chan_ids_parent); STMT(get_guild_member_ids); STMT(clr_role); + STMT(get_guild_owner); #undef STMT }; -- cgit v1.2.3 From fea6db3394d0283d28b7e03b74c34b0296b9b59f Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 21 Jan 2023 01:02:14 -0500 Subject: mimic discord group dm naming scheme (closes #133) --- src/components/channels.cpp | 12 ++---------- src/discord/channel.cpp | 40 +++++++++++++++++++++++++++++++--------- src/discord/channel.hpp | 1 + 3 files changed, 34 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 497c021..88e5a71 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -759,14 +759,10 @@ void ChannelList::AddPrivateChannels() { auto row = *iter; row[m_columns.m_type] = RenderType::DM; row[m_columns.m_id] = dm_id; + row[m_columns.m_name] = Glib::Markup::escape_text(dm->GetDisplayName()); row[m_columns.m_sort] = static_cast(-(dm->LastMessageID.has_value() ? *dm->LastMessageID : dm_id)); row[m_columns.m_icon] = img.GetPlaceholder(DMIconSize); - if (dm->Type == ChannelType::DM && top_recipient.has_value()) - row[m_columns.m_name] = Glib::Markup::escape_text(top_recipient->Username); - else if (dm->Type == ChannelType::GROUP_DM) - row[m_columns.m_name] = std::to_string(recipients.size()) + " members"; - if (dm->HasIcon()) { const auto cb = [this, iter](const Glib::RefPtr &pb) { if (iter) @@ -796,14 +792,10 @@ void ChannelList::UpdateCreateDMChannel(const ChannelData &dm) { auto row = *iter; row[m_columns.m_type] = RenderType::DM; row[m_columns.m_id] = dm.ID; + row[m_columns.m_name] = Glib::Markup::escape_text(dm.GetDisplayName()); row[m_columns.m_sort] = static_cast(-(dm.LastMessageID.has_value() ? *dm.LastMessageID : dm.ID)); row[m_columns.m_icon] = img.GetPlaceholder(DMIconSize); - if (dm.Type == ChannelType::DM && top_recipient.has_value()) - row[m_columns.m_name] = Glib::Markup::escape_text(top_recipient->Username); - else if (dm.Type == ChannelType::GROUP_DM) - row[m_columns.m_name] = std::to_string(recipients.size()) + " members"; - if (top_recipient.has_value()) { const auto cb = [this, iter](const Glib::RefPtr &pb) { if (iter) diff --git a/src/discord/channel.cpp b/src/discord/channel.cpp index 498b2e5..1806201 100644 --- a/src/discord/channel.cpp +++ b/src/discord/channel.cpp @@ -84,6 +84,10 @@ bool ChannelData::IsCategory() const noexcept { return Type == ChannelType::GUILD_CATEGORY; } +bool ChannelData::IsText() const noexcept { + return Type == ChannelType::GUILD_TEXT || Type == ChannelType::GUILD_NEWS; +} + bool ChannelData::HasIcon() const noexcept { return Icon.has_value(); } @@ -102,15 +106,14 @@ std::string ChannelData::GetIconURL() const { std::string ChannelData::GetDisplayName() const { if (Name.has_value()) { - return "#" + *Name; + if (IsDM()) { + return *Name; + } else { + return "#" + *Name; + } } else { - const auto recipients = GetDMRecipients(); - if (Type == ChannelType::DM && !recipients.empty()) - return recipients[0].Username; - else if (Type == ChannelType::GROUP_DM) - return std::to_string(recipients.size()) + " members"; + return GetRecipientsDisplay(); } - return "Unknown"; } std::vector ChannelData::GetChildIDs() const { @@ -139,6 +142,25 @@ std::vector ChannelData::GetDMRecipients() const { return {}; } -bool ChannelData::IsText() const noexcept { - return Type == ChannelType::GUILD_TEXT || Type == ChannelType::GUILD_NEWS; + +std::string ChannelData::GetRecipientsDisplay() const { + const auto self_id = Abaddon::Get().GetDiscordClient().GetUserData().ID; + const auto recipients = GetDMRecipients(); + + if (Type == ChannelType::DM && !recipients.empty()) { + return recipients[0].Username; + } + + Glib::ustring r; + for (size_t i = 0; i < recipients.size(); i++) { + const auto &recipient = recipients[i]; + r += recipient.Username; + if (i < recipients.size() - 1) { + r += ", "; + } + } + + if (r.empty()) r = "Unnamed"; + + return r; } diff --git a/src/discord/channel.hpp b/src/discord/channel.hpp index 77cf029..df944ec 100644 --- a/src/discord/channel.hpp +++ b/src/discord/channel.hpp @@ -106,4 +106,5 @@ struct ChannelData { [[nodiscard]] std::vector GetChildIDs() const; [[nodiscard]] std::optional GetOverwrite(Snowflake id) const; [[nodiscard]] std::vector GetDMRecipients() const; + [[nodiscard]] std::string GetRecipientsDisplay() const; }; -- cgit v1.2.3 From 7cd63de4000d583f866011ba1e58789fc8caf24f Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Wed, 25 Jan 2023 22:36:24 -0500 Subject: make window title consistent (#133) --- src/abaddon.cpp | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'src') diff --git a/src/abaddon.cpp b/src/abaddon.cpp index d759426..0f4658a 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -725,19 +725,7 @@ void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { const bool can_access = channel->IsDM() || m_discord.HasChannelPermission(m_discord.GetUserData().ID, id, Permission::VIEW_CHANNEL); - if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS) - m_main_window->set_title(std::string(APP_TITLE) + " - #" + *channel->Name); - else { - std::string display; - const auto recipients = channel->GetDMRecipients(); - if (recipients.size() > 1) - display = std::to_string(recipients.size()) + " users"; - else if (recipients.size() == 1) - display = recipients[0].Username; - else - display = "Empty group"; - m_main_window->set_title(std::string(APP_TITLE) + " - " + display); - } + m_main_window->set_title(std::string(APP_TITLE) + " - " + channel->GetDisplayName()); m_main_window->UpdateChatActiveChannel(id, expand_to); if (m_channels_requested.find(id) == m_channels_requested.end()) { // dont fire requests we know will fail -- cgit v1.2.3 From ff47134dc64ac2f0fa7bfee64313b2522709b9b9 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 28 Jan 2023 19:05:57 -0500 Subject: make embed labels selectable, let chat textview take focus --- src/components/chatlist.cpp | 1 - src/components/chatmessage.cpp | 11 ++++++++--- 2 files changed, 8 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/components/chatlist.cpp b/src/components/chatlist.cpp index d2995ee..9becbdb 100644 --- a/src/components/chatlist.cpp +++ b/src/components/chatlist.cpp @@ -6,7 +6,6 @@ ChatList::ChatList() { m_list.get_style_context()->add_class("messages"); - set_can_focus(false); set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_ALWAYS); get_vadjustment()->signal_value_changed().connect(sigc::mem_fun(*this, &ChatList::OnVAdjustmentValueChanged)); diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index 3afdf9f..20e88ea 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -166,7 +166,8 @@ Gtk::TextView *ChatMessageItemContainer::CreateTextComponent(const Message &data if (data.IsPending) tv->get_style_context()->add_class("pending"); tv->get_style_context()->add_class("message-text"); - tv->set_can_focus(false); + tv->set_can_focus(true); + tv->set_cursor_visible(false); tv->set_editable(false); tv->set_wrap_mode(Gtk::WRAP_WORD_CHAR); tv->set_halign(Gtk::ALIGN_FILL); @@ -335,6 +336,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb author_lbl->set_hexpand(false); author_lbl->set_text(*embed.Author->Name); author_lbl->get_style_context()->add_class("embed-author"); + author_lbl->set_selectable(true); author_box->add(*author_lbl); } } @@ -351,6 +353,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb title_label->set_line_wrap(true); title_label->set_line_wrap_mode(Pango::WRAP_WORD_CHAR); title_label->set_max_width_chars(50); + title_label->set_selectable(true); title_ev->add(*title_label); content->pack_start(*title_ev); @@ -380,6 +383,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb desc_label->set_halign(Gtk::ALIGN_START); desc_label->set_hexpand(false); desc_label->get_style_context()->add_class("embed-description"); + desc_label->set_selectable(true); content->pack_start(*desc_label); } } @@ -422,6 +426,8 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb field_box->pack_start(*field_val); field_lbl->get_style_context()->add_class("embed-field-title"); field_val->get_style_context()->add_class("embed-field-value"); + field_lbl->set_selectable(true); + field_val->set_selectable(true); flow->insert(*field_box, -1); } } @@ -445,6 +451,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb footer_lbl->set_hexpand(false); footer_lbl->set_text(embed.Footer->Text); footer_lbl->get_style_context()->add_class("embed-footer"); + footer_lbl->set_selectable(true); content->pack_start(*footer_lbl); } @@ -1170,8 +1177,6 @@ ChatMessageHeader::ChatMessageHeader(const Message &data) m_meta_box.set_hexpand(true); m_meta_box.set_can_focus(false); - m_content_box.set_can_focus(false); - const auto on_enter_cb = [this](const GdkEventCrossing *event) -> bool { if (m_anim_avatar) m_avatar.property_pixbuf_animation() = m_anim_avatar; -- cgit v1.2.3 From 5a6f8cac09770d315fe4a3258fa6116e65750f24 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 29 Jan 2023 21:33:34 -0500 Subject: first pass compile time optimization --- CMakeLists.txt | 2 + src/abaddon.cpp | 2 - src/abaddon.hpp | 1 - src/components/cellrendererpixbufanimation.hpp | 1 - src/components/channels.cpp | 2 - src/components/channels.hpp | 1 - src/components/channelscellrenderer.cpp | 2 - src/components/channelscellrenderer.hpp | 1 - src/components/channeltabswitcherhandy.cpp | 1 - src/components/channeltabswitcherhandy.hpp | 3 +- src/components/chatinput.cpp | 1 - src/components/chatinput.hpp | 1 - src/components/chatinputindicator.cpp | 2 - src/components/chatinputindicator.hpp | 1 - src/components/chatlist.cpp | 1 - src/components/chatlist.hpp | 1 - src/components/chatmessage.cpp | 2 - src/components/chatmessage.hpp | 1 - src/components/chatwindow.cpp | 1 - src/components/chatwindow.hpp | 1 - src/components/completer.cpp | 2 - src/components/completer.hpp | 1 - src/components/draglistbox.hpp | 1 - src/components/friendslist.cpp | 1 - src/components/friendslist.hpp | 1 - src/components/lazyimage.cpp | 1 - src/components/lazyimage.hpp | 1 - src/components/memberlist.cpp | 2 - src/components/memberlist.hpp | 1 - src/components/progressbar.cpp | 1 - src/components/progressbar.hpp | 1 - src/components/ratelimitindicator.cpp | 1 - src/components/ratelimitindicator.hpp | 1 - src/components/statusindicator.cpp | 1 - src/components/statusindicator.hpp | 1 - src/dialogs/confirm.hpp | 1 - src/dialogs/editmessage.hpp | 1 - src/dialogs/friendpicker.cpp | 1 - src/dialogs/friendpicker.hpp | 1 - src/dialogs/setstatus.hpp | 1 - src/dialogs/textinput.hpp | 2 - src/dialogs/token.hpp | 1 - src/dialogs/verificationgate.cpp | 1 - src/dialogs/verificationgate.hpp | 1 - src/discord/activity.hpp | 1 - src/discord/channel.cpp | 1 - src/discord/discord.cpp | 2 - src/discord/guild.cpp | 1 - src/discord/interactions.cpp | 1 - src/discord/json.hpp | 36 ++++++++-------- src/discord/member.cpp | 1 - src/discord/permissions.hpp | 5 ++- src/discord/snowflake.cpp | 1 - src/discord/store.hpp | 1 - src/discord/user.cpp | 1 - src/emojis.hpp | 1 - src/filecache.cpp | 1 - src/filecache.hpp | 1 - src/imgmanager.cpp | 2 - src/imgmanager.hpp | 1 - src/misc/bitwise.hpp | 38 +++++++++++++++++ src/misc/is_optional.hpp | 9 ++++ src/platform.cpp | 1 - src/startup.cpp | 1 - src/startup.hpp | 2 - src/util.cpp | 1 - src/util.hpp | 59 +++++++------------------- src/windows/guildsettings/auditlogpane.cpp | 1 - src/windows/guildsettings/auditlogpane.hpp | 1 - src/windows/guildsettings/banspane.cpp | 1 - src/windows/guildsettings/banspane.hpp | 1 - src/windows/guildsettings/emojispane.cpp | 1 - src/windows/guildsettings/emojispane.hpp | 1 - src/windows/guildsettings/infopane.cpp | 1 - src/windows/guildsettings/infopane.hpp | 1 - src/windows/guildsettings/invitespane.cpp | 1 - src/windows/guildsettings/invitespane.hpp | 1 - src/windows/guildsettings/memberspane.cpp | 1 - src/windows/guildsettings/memberspane.hpp | 1 - src/windows/guildsettings/rolespane.cpp | 1 - src/windows/guildsettings/rolespane.hpp | 1 - src/windows/guildsettingswindow.cpp | 1 - src/windows/guildsettingswindow.hpp | 1 - src/windows/mainwindow.cpp | 1 - src/windows/mainwindow.hpp | 1 - src/windows/pinnedwindow.cpp | 1 - src/windows/pinnedwindow.hpp | 1 - src/windows/profile/mutualfriendspane.cpp | 1 - src/windows/profile/mutualfriendspane.hpp | 1 - src/windows/profile/mutualguildspane.cpp | 1 - src/windows/profile/mutualguildspane.hpp | 1 - src/windows/profile/userinfopane.cpp | 1 - src/windows/profile/userinfopane.hpp | 1 - src/windows/profilewindow.cpp | 1 - src/windows/profilewindow.hpp | 1 - src/windows/threadswindow.cpp | 1 - src/windows/threadswindow.hpp | 1 - 97 files changed, 87 insertions(+), 166 deletions(-) create mode 100644 src/misc/bitwise.hpp create mode 100644 src/misc/is_optional.hpp (limited to 'src') diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a9e17a..9d57239 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,6 +56,8 @@ target_include_directories(abaddon PUBLIC ${ZLIB_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${SQLite3_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${NLOHMANN_JSON_INCLUDE_DIRS}) +target_precompile_headers(abaddon PRIVATE src/abaddon.hpp src/util.hpp) + if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR (CMAKE_CXX_COMPILER_ID STREQUAL "Clang" AND ((CMAKE_SYSTEM_NAME STREQUAL "Linux") OR (CMAKE_CXX_COMPILER_VERSION LESS 9)))) diff --git a/src/abaddon.cpp b/src/abaddon.cpp index 0f4658a..ba553bb 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -1,4 +1,3 @@ -#include #include #include #include @@ -11,7 +10,6 @@ #include "dialogs/friendpicker.hpp" #include "dialogs/verificationgate.hpp" #include "dialogs/textinput.hpp" -#include "abaddon.hpp" #include "windows/guildsettingswindow.hpp" #include "windows/profilewindow.hpp" #include "windows/pinnedwindow.hpp" diff --git a/src/abaddon.hpp b/src/abaddon.hpp index b067324..8b14699 100644 --- a/src/abaddon.hpp +++ b/src/abaddon.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/src/components/cellrendererpixbufanimation.hpp b/src/components/cellrendererpixbufanimation.hpp index fe2141d..e7949c8 100644 --- a/src/components/cellrendererpixbufanimation.hpp +++ b/src/components/cellrendererpixbufanimation.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include // handles both static and animated diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 88e5a71..80990ab 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -1,8 +1,6 @@ -#include "abaddon.hpp" #include "channels.hpp" #include "imgmanager.hpp" #include "statusindicator.hpp" -#include "util.hpp" #include #include #include diff --git a/src/components/channels.hpp b/src/components/channels.hpp index 53a68c9..cca2ad5 100644 --- a/src/components/channels.hpp +++ b/src/components/channels.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/src/components/channelscellrenderer.cpp b/src/components/channelscellrenderer.cpp index 9afce8a..e7dbf25 100644 --- a/src/components/channelscellrenderer.cpp +++ b/src/components/channelscellrenderer.cpp @@ -1,6 +1,4 @@ -#include "abaddon.hpp" #include "channelscellrenderer.hpp" -#include constexpr static int MentionsRightPad = 7; #ifndef M_PI diff --git a/src/components/channelscellrenderer.hpp b/src/components/channelscellrenderer.hpp index e2be9b2..d20a1b1 100644 --- a/src/components/channelscellrenderer.hpp +++ b/src/components/channelscellrenderer.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/src/components/channeltabswitcherhandy.cpp b/src/components/channeltabswitcherhandy.cpp index c7dc59b..14c5c49 100644 --- a/src/components/channeltabswitcherhandy.cpp +++ b/src/components/channeltabswitcherhandy.cpp @@ -1,7 +1,6 @@ #ifdef WITH_LIBHANDY #include "channeltabswitcherhandy.hpp" - #include "abaddon.hpp" void selected_page_notify_cb(HdyTabView *view, GParamSpec *pspec, ChannelTabSwitcherHandy *switcher) { auto *page = hdy_tab_view_get_selected_page(view); diff --git a/src/components/channeltabswitcherhandy.hpp b/src/components/channeltabswitcherhandy.hpp index 272cad0..f5a31fa 100644 --- a/src/components/channeltabswitcherhandy.hpp +++ b/src/components/channeltabswitcherhandy.hpp @@ -1,8 +1,7 @@ #pragma once // perhaps this should be conditionally included within cmakelists? #ifdef WITH_LIBHANDY - #include - #include + #include #include #include "discord/snowflake.hpp" #include "state.hpp" diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index 2466965..4c4c866 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -1,5 +1,4 @@ #include "chatinput.hpp" -#include "abaddon.hpp" #include "constants.hpp" #include diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp index 807f958..3b7bc79 100644 --- a/src/components/chatinput.hpp +++ b/src/components/chatinput.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/chatsubmitparams.hpp" #include "discord/permissions.hpp" diff --git a/src/components/chatinputindicator.cpp b/src/components/chatinputindicator.cpp index b829c46..13315c6 100644 --- a/src/components/chatinputindicator.cpp +++ b/src/components/chatinputindicator.cpp @@ -1,7 +1,5 @@ #include #include "chatinputindicator.hpp" -#include "abaddon.hpp" -#include "util.hpp" constexpr static const int MaxUsersInIndicator = 4; diff --git a/src/components/chatinputindicator.hpp b/src/components/chatinputindicator.hpp index ec70dfb..40c966e 100644 --- a/src/components/chatinputindicator.hpp +++ b/src/components/chatinputindicator.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include "discord/message.hpp" #include "discord/user.hpp" diff --git a/src/components/chatlist.cpp b/src/components/chatlist.cpp index 9becbdb..93fb46f 100644 --- a/src/components/chatlist.cpp +++ b/src/components/chatlist.cpp @@ -1,5 +1,4 @@ #include "chatlist.hpp" -#include "abaddon.hpp" #include "chatmessage.hpp" #include "constants.hpp" diff --git a/src/components/chatlist.hpp b/src/components/chatlist.hpp index 9cc6992..0248d7f 100644 --- a/src/components/chatlist.hpp +++ b/src/components/chatlist.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include "discord/message.hpp" diff --git a/src/components/chatmessage.cpp b/src/components/chatmessage.cpp index 20e88ea..8c16922 100644 --- a/src/components/chatmessage.cpp +++ b/src/components/chatmessage.cpp @@ -1,7 +1,5 @@ -#include "abaddon.hpp" #include "chatmessage.hpp" #include "lazyimage.hpp" -#include "util.hpp" #include constexpr static int EmojiSize = 24; // settings eventually diff --git a/src/components/chatmessage.hpp b/src/components/chatmessage.hpp index 7851351..c854272 100644 --- a/src/components/chatmessage.hpp +++ b/src/components/chatmessage.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/discord.hpp" class ChatMessageItemContainer : public Gtk::EventBox { diff --git a/src/components/chatwindow.cpp b/src/components/chatwindow.cpp index c5b4d14..1565d0c 100644 --- a/src/components/chatwindow.cpp +++ b/src/components/chatwindow.cpp @@ -1,5 +1,4 @@ #include "chatwindow.hpp" -#include "abaddon.hpp" #include "chatinputindicator.hpp" #include "ratelimitindicator.hpp" #include "chatinput.hpp" diff --git a/src/components/chatwindow.hpp b/src/components/chatwindow.hpp index 802826b..e1bb57a 100644 --- a/src/components/chatwindow.hpp +++ b/src/components/chatwindow.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include "discord/discord.hpp" diff --git a/src/components/completer.cpp b/src/components/completer.cpp index 128bef2..c6a5a08 100644 --- a/src/components/completer.cpp +++ b/src/components/completer.cpp @@ -1,8 +1,6 @@ #include #include #include "completer.hpp" -#include "abaddon.hpp" -#include "util.hpp" constexpr const int CompleterHeight = 150; constexpr const int MaxCompleterEntries = 30; diff --git a/src/components/completer.hpp b/src/components/completer.hpp index 6906f02..d1b1d5f 100644 --- a/src/components/completer.hpp +++ b/src/components/completer.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include "lazyimage.hpp" #include "discord/snowflake.hpp" diff --git a/src/components/draglistbox.hpp b/src/components/draglistbox.hpp index 9f204be..8890792 100644 --- a/src/components/draglistbox.hpp +++ b/src/components/draglistbox.hpp @@ -1,5 +1,4 @@ #pragma once -#include class DragListBox : public Gtk::ListBox { public: diff --git a/src/components/friendslist.cpp b/src/components/friendslist.cpp index b908359..d8a566f 100644 --- a/src/components/friendslist.cpp +++ b/src/components/friendslist.cpp @@ -1,5 +1,4 @@ #include "friendslist.hpp" -#include "abaddon.hpp" #include "lazyimage.hpp" using namespace std::string_literals; diff --git a/src/components/friendslist.hpp b/src/components/friendslist.hpp index 460ad32..c4056f0 100644 --- a/src/components/friendslist.hpp +++ b/src/components/friendslist.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class FriendsListAddComponent : public Gtk::Box { diff --git a/src/components/lazyimage.cpp b/src/components/lazyimage.cpp index 1f005f3..13bd65d 100644 --- a/src/components/lazyimage.cpp +++ b/src/components/lazyimage.cpp @@ -1,7 +1,6 @@ #include "lazyimage.hpp" #include -#include "abaddon.hpp" LazyImage::LazyImage(int w, int h, bool use_placeholder) : m_width(w) diff --git a/src/components/lazyimage.hpp b/src/components/lazyimage.hpp index 4d5a216..50db425 100644 --- a/src/components/lazyimage.hpp +++ b/src/components/lazyimage.hpp @@ -1,5 +1,4 @@ #pragma once -#include // loads an image only when the widget is drawn for the first time class LazyImage : public Gtk::Image { diff --git a/src/components/memberlist.cpp b/src/components/memberlist.cpp index 85ccd05..19b4fb8 100644 --- a/src/components/memberlist.cpp +++ b/src/components/memberlist.cpp @@ -1,6 +1,4 @@ #include "memberlist.hpp" -#include "abaddon.hpp" -#include "util.hpp" #include "lazyimage.hpp" #include "statusindicator.hpp" diff --git a/src/components/memberlist.hpp b/src/components/memberlist.hpp index 60a25bc..7d5da10 100644 --- a/src/components/memberlist.hpp +++ b/src/components/memberlist.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include diff --git a/src/components/progressbar.cpp b/src/components/progressbar.cpp index aa5d748..75f86bb 100644 --- a/src/components/progressbar.cpp +++ b/src/components/progressbar.cpp @@ -1,5 +1,4 @@ #include "progressbar.hpp" -#include "abaddon.hpp" MessageUploadProgressBar::MessageUploadProgressBar() { get_style_context()->add_class("message-progress"); diff --git a/src/components/progressbar.hpp b/src/components/progressbar.hpp index b73521b..483ee47 100644 --- a/src/components/progressbar.hpp +++ b/src/components/progressbar.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include class MessageUploadProgressBar : public Gtk::ProgressBar { diff --git a/src/components/ratelimitindicator.cpp b/src/components/ratelimitindicator.cpp index 820e395..426f18e 100644 --- a/src/components/ratelimitindicator.cpp +++ b/src/components/ratelimitindicator.cpp @@ -1,5 +1,4 @@ #include "ratelimitindicator.hpp" -#include "abaddon.hpp" #include RateLimitIndicator::RateLimitIndicator() diff --git a/src/components/ratelimitindicator.hpp b/src/components/ratelimitindicator.hpp index b4dbb69..c9b6d6e 100644 --- a/src/components/ratelimitindicator.hpp +++ b/src/components/ratelimitindicator.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include #include "discord/message.hpp" diff --git a/src/components/statusindicator.cpp b/src/components/statusindicator.cpp index 4d7415c..47e8b44 100644 --- a/src/components/statusindicator.cpp +++ b/src/components/statusindicator.cpp @@ -1,5 +1,4 @@ #include "statusindicator.hpp" -#include "abaddon.hpp" static const constexpr int Diameter = 8; diff --git a/src/components/statusindicator.hpp b/src/components/statusindicator.hpp index ad9122b..1fa8b9b 100644 --- a/src/components/statusindicator.hpp +++ b/src/components/statusindicator.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/snowflake.hpp" #include "discord/activity.hpp" diff --git a/src/dialogs/confirm.hpp b/src/dialogs/confirm.hpp index 84a089c..86feee7 100644 --- a/src/dialogs/confirm.hpp +++ b/src/dialogs/confirm.hpp @@ -1,5 +1,4 @@ #pragma once -#include class ConfirmDialog : public Gtk::Dialog { public: diff --git a/src/dialogs/editmessage.hpp b/src/dialogs/editmessage.hpp index bf6307d..38ebedb 100644 --- a/src/dialogs/editmessage.hpp +++ b/src/dialogs/editmessage.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include class EditMessageDialog : public Gtk::Dialog { diff --git a/src/dialogs/friendpicker.cpp b/src/dialogs/friendpicker.cpp index 476e5f6..c70a9e9 100644 --- a/src/dialogs/friendpicker.cpp +++ b/src/dialogs/friendpicker.cpp @@ -1,5 +1,4 @@ #include "friendpicker.hpp" -#include "abaddon.hpp" FriendPickerDialog::FriendPickerDialog(Gtk::Window &parent) : Gtk::Dialog("Pick a friend", parent, true) diff --git a/src/dialogs/friendpicker.hpp b/src/dialogs/friendpicker.hpp index 81d02a3..9749dfa 100644 --- a/src/dialogs/friendpicker.hpp +++ b/src/dialogs/friendpicker.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/snowflake.hpp" class FriendPickerDialog : public Gtk::Dialog { diff --git a/src/dialogs/setstatus.hpp b/src/dialogs/setstatus.hpp index b06c182..b0e6a4c 100644 --- a/src/dialogs/setstatus.hpp +++ b/src/dialogs/setstatus.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class SetStatusDialog : public Gtk::Dialog { diff --git a/src/dialogs/textinput.hpp b/src/dialogs/textinput.hpp index fd2d2b8..765240a 100644 --- a/src/dialogs/textinput.hpp +++ b/src/dialogs/textinput.hpp @@ -1,6 +1,4 @@ #pragma once -#include -#include class TextInputDialog : public Gtk::Dialog { public: diff --git a/src/dialogs/token.hpp b/src/dialogs/token.hpp index 7778bfb..9e691c9 100644 --- a/src/dialogs/token.hpp +++ b/src/dialogs/token.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include class TokenDialog : public Gtk::Dialog { diff --git a/src/dialogs/verificationgate.cpp b/src/dialogs/verificationgate.cpp index 698ddff..660ae30 100644 --- a/src/dialogs/verificationgate.cpp +++ b/src/dialogs/verificationgate.cpp @@ -1,5 +1,4 @@ #include "verificationgate.hpp" -#include "abaddon.hpp" VerificationGateDialog::VerificationGateDialog(Gtk::Window &parent, Snowflake guild_id) : Gtk::Dialog("Verification Required", parent, true) diff --git a/src/dialogs/verificationgate.hpp b/src/dialogs/verificationgate.hpp index 0a0dc08..537de3c 100644 --- a/src/dialogs/verificationgate.hpp +++ b/src/dialogs/verificationgate.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include "discord/objects.hpp" diff --git a/src/discord/activity.hpp b/src/discord/activity.hpp index 4382ac0..5b2c3ce 100644 --- a/src/discord/activity.hpp +++ b/src/discord/activity.hpp @@ -1,7 +1,6 @@ #pragma once #include #include -#include "util.hpp" #include "json.hpp" #include "snowflake.hpp" diff --git a/src/discord/channel.cpp b/src/discord/channel.cpp index 1806201..4b1d909 100644 --- a/src/discord/channel.cpp +++ b/src/discord/channel.cpp @@ -1,4 +1,3 @@ -#include "abaddon.hpp" #include "channel.hpp" void from_json(const nlohmann::json &j, ThreadMetadataData &m) { diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index d7cee4c..c1b32d9 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -1,6 +1,4 @@ -#include "abaddon.hpp" #include "discord.hpp" -#include "util.hpp" #include #include diff --git a/src/discord/guild.cpp b/src/discord/guild.cpp index bb99044..06c4acf 100644 --- a/src/discord/guild.cpp +++ b/src/discord/guild.cpp @@ -1,5 +1,4 @@ #include "guild.hpp" -#include "abaddon.hpp" void from_json(const nlohmann::json &j, GuildData &m) { JS_D("id", m.ID); diff --git a/src/discord/interactions.cpp b/src/discord/interactions.cpp index cc439fc..e23fc86 100644 --- a/src/discord/interactions.cpp +++ b/src/discord/interactions.cpp @@ -1,6 +1,5 @@ #include "interactions.hpp" #include "json.hpp" -#include "abaddon.hpp" void from_json(const nlohmann::json &j, MessageInteractionData &m) { JS_D("id", m.ID); diff --git a/src/discord/json.hpp b/src/discord/json.hpp index 3c6968d..b781e78 100644 --- a/src/discord/json.hpp +++ b/src/discord/json.hpp @@ -1,24 +1,24 @@ #pragma once #include #include -#include "util.hpp" +#include "misc/is_optional.hpp" namespace detail { // more or less because idk what to name this stuff template -inline void json_direct(const ::nlohmann::json &j, const char *key, T &val) { - if constexpr (::util::is_optional::value) +inline void json_direct(const nlohmann::json &j, const char *key, T &val) { + if constexpr (is_optional::value) val = j.at(key).get(); else j.at(key).get_to(val); } template -inline void json_optional(const ::nlohmann::json &j, const char *key, T &val) { - if constexpr (::util::is_optional::value) { +inline void json_optional(const nlohmann::json &j, const char *key, T &val) { + if constexpr (is_optional::value) { if (j.contains(key)) val = j.at(key).get(); else - val = ::std::nullopt; + val = std::nullopt; } else { if (j.contains(key)) j.at(key).get_to(val); @@ -26,13 +26,13 @@ inline void json_optional(const ::nlohmann::json &j, const char *key, T &val) { } template -inline void json_nullable(const ::nlohmann::json &j, const char *key, T &val) { - if constexpr (::util::is_optional::value) { +inline void json_nullable(const nlohmann::json &j, const char *key, T &val) { + if constexpr (is_optional::value) { const auto &at = j.at(key); if (!at.is_null()) val = at.get(); else - val = ::std::nullopt; + val = std::nullopt; } else { const auto &at = j.at(key); if (!at.is_null()) @@ -41,16 +41,16 @@ inline void json_nullable(const ::nlohmann::json &j, const char *key, T &val) { } template -inline void json_optional_nullable(const ::nlohmann::json &j, const char *key, T &val) { - if constexpr (::util::is_optional::value) { +inline void json_optional_nullable(const nlohmann::json &j, const char *key, T &val) { + if constexpr (is_optional::value) { if (j.contains(key)) { const auto &at = j.at(key); if (!at.is_null()) val = at.get(); else - val = ::std::nullopt; + val = std::nullopt; } else { - val = ::std::nullopt; + val = std::nullopt; } } else { if (j.contains(key)) { @@ -62,14 +62,14 @@ inline void json_optional_nullable(const ::nlohmann::json &j, const char *key, T } template -inline void json_update_optional_nullable(const ::nlohmann::json &j, const char *key, T &val) { - if constexpr (::util::is_optional::value) { +inline void json_update_optional_nullable(const nlohmann::json &j, const char *key, T &val) { + if constexpr (is_optional::value) { if (j.contains(key)) { const auto &at = j.at(key); if (!at.is_null()) val = at.get(); else - val = ::std::nullopt; + val = std::nullopt; } } else { if (j.contains(key)) { @@ -83,8 +83,8 @@ inline void json_update_optional_nullable(const ::nlohmann::json &j, const char } template -inline void json_update_optional_nullable_default(const ::nlohmann::json &j, const char *key, T &val, const U &fallback) { - if constexpr (::util::is_optional::value) { +inline void json_update_optional_nullable_default(const nlohmann::json &j, const char *key, T &val, const U &fallback) { + if constexpr (is_optional::value) { if (j.contains(key)) { const auto &at = j.at(key); if (at.is_null()) diff --git a/src/discord/member.cpp b/src/discord/member.cpp index e424491..2a8ae24 100644 --- a/src/discord/member.cpp +++ b/src/discord/member.cpp @@ -1,5 +1,4 @@ #include "member.hpp" -#include "abaddon.hpp" void from_json(const nlohmann::json &j, GuildMember &m) { JS_O("user", m.User); diff --git a/src/discord/permissions.hpp b/src/discord/permissions.hpp index 56ef742..d274dd9 100644 --- a/src/discord/permissions.hpp +++ b/src/discord/permissions.hpp @@ -1,8 +1,8 @@ #pragma once #include -#include "snowflake.hpp" #include "json.hpp" -#include "util.hpp" +#include "misc/bitwise.hpp" +#include "snowflake.hpp" constexpr static uint64_t PERMISSION_MAX_BIT = 36; enum class Permission : uint64_t { @@ -46,6 +46,7 @@ enum class Permission : uint64_t { ALL = 0x1FFFFFFFFFULL, }; + template<> struct Bitwise { static const bool enable = true; diff --git a/src/discord/snowflake.cpp b/src/discord/snowflake.cpp index 856e2f7..15dacae 100644 --- a/src/discord/snowflake.cpp +++ b/src/discord/snowflake.cpp @@ -1,5 +1,4 @@ #include "snowflake.hpp" -#include "util.hpp" #include #include #include diff --git a/src/discord/store.hpp b/src/discord/store.hpp index f1e2f05..8e57e43 100644 --- a/src/discord/store.hpp +++ b/src/discord/store.hpp @@ -1,5 +1,4 @@ #pragma once -#include "util.hpp" #include "objects.hpp" #include #include diff --git a/src/discord/user.cpp b/src/discord/user.cpp index 0ab2af5..2ee7361 100644 --- a/src/discord/user.cpp +++ b/src/discord/user.cpp @@ -1,5 +1,4 @@ #include "user.hpp" -#include "abaddon.hpp" bool UserData::IsABot() const noexcept { return IsBot.has_value() && *IsBot; diff --git a/src/emojis.hpp b/src/emojis.hpp index 71d665d..6ba590c 100644 --- a/src/emojis.hpp +++ b/src/emojis.hpp @@ -3,7 +3,6 @@ #include #include #include -#include // shoutout to gtk for only supporting .svg's sometimes diff --git a/src/filecache.cpp b/src/filecache.cpp index 3943e72..b31b31a 100644 --- a/src/filecache.cpp +++ b/src/filecache.cpp @@ -1,4 +1,3 @@ -#include "abaddon.hpp" #include "filecache.hpp" #include diff --git a/src/filecache.hpp b/src/filecache.hpp index 5214fb2..52d1f42 100644 --- a/src/filecache.hpp +++ b/src/filecache.hpp @@ -8,7 +8,6 @@ #include #include #include -#include "util.hpp" #include "http.hpp" class FileCacheWorkerThread { diff --git a/src/imgmanager.cpp b/src/imgmanager.cpp index dbfa5fa..d681222 100644 --- a/src/imgmanager.cpp +++ b/src/imgmanager.cpp @@ -1,8 +1,6 @@ #include "imgmanager.hpp" #include -#include "util.hpp" -#include "abaddon.hpp" ImageManager::ImageManager() { m_cb_dispatcher.connect(sigc::mem_fun(*this, &ImageManager::RunCallbacks)); diff --git a/src/imgmanager.hpp b/src/imgmanager.hpp index 63c604e..3bc0f4e 100644 --- a/src/imgmanager.hpp +++ b/src/imgmanager.hpp @@ -3,7 +3,6 @@ #include #include #include -#include #include "filecache.hpp" class ImageManager { diff --git a/src/misc/bitwise.hpp b/src/misc/bitwise.hpp new file mode 100644 index 0000000..ecce333 --- /dev/null +++ b/src/misc/bitwise.hpp @@ -0,0 +1,38 @@ +#pragma once +#include + +template +struct Bitwise { + static const bool enable = false; +}; + +template +typename std::enable_if::enable, T>::type operator|(T a, T b) { + using x = typename std::underlying_type::type; + return static_cast(static_cast(a) | static_cast(b)); +} + +template +typename std::enable_if::enable, T>::type operator|=(T &a, T b) { + using x = typename std::underlying_type::type; + a = static_cast(static_cast(a) | static_cast(b)); + return a; +} + +template +typename std::enable_if::enable, T>::type operator&(T a, T b) { + using x = typename std::underlying_type::type; + return static_cast(static_cast(a) & static_cast(b)); +} + +template +typename std::enable_if::enable, T>::type operator&=(T &a, T b) { + using x = typename std::underlying_type::type; + a = static_cast(static_cast(a) & static_cast(b)); + return a; +} + +template +typename std::enable_if::enable, T>::type operator~(T a) { + return static_cast(~static_cast::type>(a)); +} diff --git a/src/misc/is_optional.hpp b/src/misc/is_optional.hpp new file mode 100644 index 0000000..2c7c973 --- /dev/null +++ b/src/misc/is_optional.hpp @@ -0,0 +1,9 @@ +#pragma once +#include +#include + +template +struct is_optional : std::false_type {}; + +template +struct is_optional> : std::true_type {}; diff --git a/src/platform.cpp b/src/platform.cpp index 8eff19d..0117e17 100644 --- a/src/platform.cpp +++ b/src/platform.cpp @@ -1,5 +1,4 @@ #include "platform.hpp" -#include "util.hpp" #include #include #include diff --git a/src/startup.cpp b/src/startup.cpp index baedf76..6d1ac96 100644 --- a/src/startup.cpp +++ b/src/startup.cpp @@ -1,5 +1,4 @@ #include "startup.hpp" -#include "abaddon.hpp" #include #include diff --git a/src/startup.hpp b/src/startup.hpp index ba1459d..7c6830f 100644 --- a/src/startup.hpp +++ b/src/startup.hpp @@ -1,7 +1,5 @@ #pragma once #include -#include -#include #include // fetch cookies, build number async diff --git a/src/util.cpp b/src/util.cpp index af583ec..8d21ff4 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -1,4 +1,3 @@ -#include "util.hpp" #include #include #include diff --git a/src/util.hpp b/src/util.hpp index 4b14a7e..fc9568b 100644 --- a/src/util.hpp +++ b/src/util.hpp @@ -13,17 +13,26 @@ #include #include #include -#include -#define NOOP_CALLBACK [](...) {} +#include -namespace util { -template -struct is_optional : ::std::false_type {}; +namespace Glib { +class ustring; +} -template -struct is_optional<::std::optional> : ::std::true_type {}; +namespace Gdk { +class RGBA; +} + +namespace Gtk { +class Widget; +class Menu; +class ListBox; +} // namespace Gtk +#define NOOP_CALLBACK [](...) {} + +namespace util { bool IsFolder(std::string_view path); bool IsFile(std::string_view path); @@ -44,42 +53,6 @@ std::string HumanReadableBytes(uint64_t bytes); std::string FormatISO8601(const std::string &in, int extra_offset = 0, const std::string &fmt = "%x %X"); void AddPointerCursor(Gtk::Widget &widget); -template -struct Bitwise { - static const bool enable = false; -}; - -template -typename std::enable_if::enable, T>::type operator|(T a, T b) { - using x = typename std::underlying_type::type; - return static_cast(static_cast(a) | static_cast(b)); -} - -template -typename std::enable_if::enable, T>::type operator|=(T &a, T b) { - using x = typename std::underlying_type::type; - a = static_cast(static_cast(a) | static_cast(b)); - return a; -} - -template -typename std::enable_if::enable, T>::type operator&(T a, T b) { - using x = typename std::underlying_type::type; - return static_cast(static_cast(a) & static_cast(b)); -} - -template -typename std::enable_if::enable, T>::type operator&=(T &a, T b) { - using x = typename std::underlying_type::type; - a = static_cast(static_cast(a) & static_cast(b)); - return a; -} - -template -typename std::enable_if::enable, T>::type operator~(T a) { - return static_cast(~static_cast::type>(a)); -} - template inline void AlphabeticalSort(T start, T end, std::function::value_type &)> get_string) { std::sort(start, end, [&](const auto &a, const auto &b) -> bool { diff --git a/src/windows/guildsettings/auditlogpane.cpp b/src/windows/guildsettings/auditlogpane.cpp index 868a18f..53bfd15 100644 --- a/src/windows/guildsettings/auditlogpane.cpp +++ b/src/windows/guildsettings/auditlogpane.cpp @@ -1,5 +1,4 @@ #include "auditlogpane.hpp" -#include "abaddon.hpp" using namespace std::string_literals; diff --git a/src/windows/guildsettings/auditlogpane.hpp b/src/windows/guildsettings/auditlogpane.hpp index ac12321..dc44d8f 100644 --- a/src/windows/guildsettings/auditlogpane.hpp +++ b/src/windows/guildsettings/auditlogpane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class GuildSettingsAuditLogPane : public Gtk::ScrolledWindow { diff --git a/src/windows/guildsettings/banspane.cpp b/src/windows/guildsettings/banspane.cpp index d4b002c..bfc7331 100644 --- a/src/windows/guildsettings/banspane.cpp +++ b/src/windows/guildsettings/banspane.cpp @@ -1,5 +1,4 @@ #include "banspane.hpp" -#include "abaddon.hpp" // gtk_list_store_set_value: assertion 'column >= 0 && column < priv->n_columns' failed // dont care to figure out why this happens cuz it doesnt seem to break anything diff --git a/src/windows/guildsettings/banspane.hpp b/src/windows/guildsettings/banspane.hpp index b2420a9..d50b372 100644 --- a/src/windows/guildsettings/banspane.hpp +++ b/src/windows/guildsettings/banspane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/snowflake.hpp" #include "discord/ban.hpp" diff --git a/src/windows/guildsettings/emojispane.cpp b/src/windows/guildsettings/emojispane.cpp index bdab6b8..c86ea64 100644 --- a/src/windows/guildsettings/emojispane.cpp +++ b/src/windows/guildsettings/emojispane.cpp @@ -1,5 +1,4 @@ #include "emojispane.hpp" -#include "abaddon.hpp" #include "components/cellrendererpixbufanimation.hpp" GuildSettingsEmojisPane::GuildSettingsEmojisPane(Snowflake guild_id) diff --git a/src/windows/guildsettings/emojispane.hpp b/src/windows/guildsettings/emojispane.hpp index 1c0edd1..43676c2 100644 --- a/src/windows/guildsettings/emojispane.hpp +++ b/src/windows/guildsettings/emojispane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/emoji.hpp" class GuildSettingsEmojisPane : public Gtk::Box { diff --git a/src/windows/guildsettings/infopane.cpp b/src/windows/guildsettings/infopane.cpp index a27c1a8..e52e27d 100644 --- a/src/windows/guildsettings/infopane.cpp +++ b/src/windows/guildsettings/infopane.cpp @@ -1,5 +1,4 @@ #include "infopane.hpp" -#include "abaddon.hpp" #include GuildSettingsInfoPane::GuildSettingsInfoPane(Snowflake id) diff --git a/src/windows/guildsettings/infopane.hpp b/src/windows/guildsettings/infopane.hpp index d779b99..4d4e87e 100644 --- a/src/windows/guildsettings/infopane.hpp +++ b/src/windows/guildsettings/infopane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/guild.hpp" class GuildSettingsInfoPane : public Gtk::Grid { diff --git a/src/windows/guildsettings/invitespane.cpp b/src/windows/guildsettings/invitespane.cpp index 2d737e9..4426f6a 100644 --- a/src/windows/guildsettings/invitespane.cpp +++ b/src/windows/guildsettings/invitespane.cpp @@ -1,5 +1,4 @@ #include "invitespane.hpp" -#include "abaddon.hpp" GuildSettingsInvitesPane::GuildSettingsInvitesPane(Snowflake id) : GuildID(id) diff --git a/src/windows/guildsettings/invitespane.hpp b/src/windows/guildsettings/invitespane.hpp index 5268d68..24086ca 100644 --- a/src/windows/guildsettings/invitespane.hpp +++ b/src/windows/guildsettings/invitespane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class GuildSettingsInvitesPane : public Gtk::ScrolledWindow { diff --git a/src/windows/guildsettings/memberspane.cpp b/src/windows/guildsettings/memberspane.cpp index 973e380..64c28cb 100644 --- a/src/windows/guildsettings/memberspane.cpp +++ b/src/windows/guildsettings/memberspane.cpp @@ -1,5 +1,4 @@ #include "memberspane.hpp" -#include "abaddon.hpp" GuildSettingsMembersPane::GuildSettingsMembersPane(Snowflake id) : Gtk::Box(Gtk::ORIENTATION_VERTICAL) diff --git a/src/windows/guildsettings/memberspane.hpp b/src/windows/guildsettings/memberspane.hpp index 01398da..3aa558a 100644 --- a/src/windows/guildsettings/memberspane.hpp +++ b/src/windows/guildsettings/memberspane.hpp @@ -1,6 +1,5 @@ #pragma once #include -#include #include "discord/member.hpp" #include "discord/guild.hpp" #include "components/lazyimage.hpp" diff --git a/src/windows/guildsettings/rolespane.cpp b/src/windows/guildsettings/rolespane.cpp index d4fa7c0..158fa11 100644 --- a/src/windows/guildsettings/rolespane.cpp +++ b/src/windows/guildsettings/rolespane.cpp @@ -1,5 +1,4 @@ #include "rolespane.hpp" -#include "abaddon.hpp" GuildSettingsRolesPane::GuildSettingsRolesPane(Snowflake id) : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) diff --git a/src/windows/guildsettings/rolespane.hpp b/src/windows/guildsettings/rolespane.hpp index 2999f32..82594d4 100644 --- a/src/windows/guildsettings/rolespane.hpp +++ b/src/windows/guildsettings/rolespane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include #include "discord/guild.hpp" #include "components/draglistbox.hpp" diff --git a/src/windows/guildsettingswindow.cpp b/src/windows/guildsettingswindow.cpp index 1e3395d..3f19100 100644 --- a/src/windows/guildsettingswindow.cpp +++ b/src/windows/guildsettingswindow.cpp @@ -1,5 +1,4 @@ #include "guildsettingswindow.hpp" -#include "abaddon.hpp" GuildSettingsWindow::GuildSettingsWindow(Snowflake id) : m_main(Gtk::ORIENTATION_VERTICAL) diff --git a/src/windows/guildsettingswindow.hpp b/src/windows/guildsettingswindow.hpp index b591640..0b1ab97 100644 --- a/src/windows/guildsettingswindow.hpp +++ b/src/windows/guildsettingswindow.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/snowflake.hpp" #include "guildsettings/infopane.hpp" #include "guildsettings/banspane.hpp" diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 8a85d49..2c61a98 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -1,5 +1,4 @@ #include "mainwindow.hpp" -#include "abaddon.hpp" MainWindow::MainWindow() : m_main_box(Gtk::ORIENTATION_VERTICAL) diff --git a/src/windows/mainwindow.hpp b/src/windows/mainwindow.hpp index 78e0115..a12dd7c 100644 --- a/src/windows/mainwindow.hpp +++ b/src/windows/mainwindow.hpp @@ -3,7 +3,6 @@ #include "components/chatwindow.hpp" #include "components/memberlist.hpp" #include "components/friendslist.hpp" -#include class MainWindow : public Gtk::Window { public: diff --git a/src/windows/pinnedwindow.cpp b/src/windows/pinnedwindow.cpp index a5484e3..467c2e3 100644 --- a/src/windows/pinnedwindow.cpp +++ b/src/windows/pinnedwindow.cpp @@ -1,5 +1,4 @@ #include "pinnedwindow.hpp" -#include "abaddon.hpp" PinnedWindow::PinnedWindow(const ChannelData &data) : ChannelID(data.ID) { diff --git a/src/windows/pinnedwindow.hpp b/src/windows/pinnedwindow.hpp index cf2ec3c..dd90a77 100644 --- a/src/windows/pinnedwindow.hpp +++ b/src/windows/pinnedwindow.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/errors.hpp" #include "discord/channel.hpp" #include "discord/message.hpp" diff --git a/src/windows/profile/mutualfriendspane.cpp b/src/windows/profile/mutualfriendspane.cpp index ca36e1d..e9f465b 100644 --- a/src/windows/profile/mutualfriendspane.cpp +++ b/src/windows/profile/mutualfriendspane.cpp @@ -1,5 +1,4 @@ #include "mutualfriendspane.hpp" -#include "abaddon.hpp" MutualFriendItem::MutualFriendItem(const UserData &user) : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) { diff --git a/src/windows/profile/mutualfriendspane.hpp b/src/windows/profile/mutualfriendspane.hpp index ef41aa6..5f2c964 100644 --- a/src/windows/profile/mutualfriendspane.hpp +++ b/src/windows/profile/mutualfriendspane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class MutualFriendItem : public Gtk::Box { diff --git a/src/windows/profile/mutualguildspane.cpp b/src/windows/profile/mutualguildspane.cpp index 6c14fc4..ff3f0c1 100644 --- a/src/windows/profile/mutualguildspane.cpp +++ b/src/windows/profile/mutualguildspane.cpp @@ -1,5 +1,4 @@ #include "mutualguildspane.hpp" -#include "abaddon.hpp" MutualGuildItem::MutualGuildItem(const MutualGuildData &guild) : Gtk::Box(Gtk::ORIENTATION_HORIZONTAL) diff --git a/src/windows/profile/mutualguildspane.hpp b/src/windows/profile/mutualguildspane.hpp index 9bdd97e..33a4af9 100644 --- a/src/windows/profile/mutualguildspane.hpp +++ b/src/windows/profile/mutualguildspane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class MutualGuildItem : public Gtk::Box { diff --git a/src/windows/profile/userinfopane.cpp b/src/windows/profile/userinfopane.cpp index b62da93..b6f0d59 100644 --- a/src/windows/profile/userinfopane.cpp +++ b/src/windows/profile/userinfopane.cpp @@ -1,6 +1,5 @@ #include "userinfopane.hpp" #include -#include "abaddon.hpp" ConnectionItem::ConnectionItem(const ConnectionData &conn) : m_box(Gtk::ORIENTATION_HORIZONTAL) diff --git a/src/windows/profile/userinfopane.hpp b/src/windows/profile/userinfopane.hpp index 90a4d55..d83557b 100644 --- a/src/windows/profile/userinfopane.hpp +++ b/src/windows/profile/userinfopane.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class ConnectionItem : public Gtk::EventBox { diff --git a/src/windows/profilewindow.cpp b/src/windows/profilewindow.cpp index d73731d..3d5f140 100644 --- a/src/windows/profilewindow.cpp +++ b/src/windows/profilewindow.cpp @@ -1,5 +1,4 @@ #include "profilewindow.hpp" -#include "abaddon.hpp" ProfileWindow::ProfileWindow(Snowflake user_id) : ID(user_id) diff --git a/src/windows/profilewindow.hpp b/src/windows/profilewindow.hpp index 3d8199b..2052e7b 100644 --- a/src/windows/profilewindow.hpp +++ b/src/windows/profilewindow.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/snowflake.hpp" #include "profile/userinfopane.hpp" #include "profile/mutualguildspane.hpp" diff --git a/src/windows/threadswindow.cpp b/src/windows/threadswindow.cpp index 62cae19..247edf6 100644 --- a/src/windows/threadswindow.cpp +++ b/src/windows/threadswindow.cpp @@ -1,5 +1,4 @@ #include "threadswindow.hpp" -#include "abaddon.hpp" ThreadsWindow::ThreadsWindow(const ChannelData &channel) : m_channel_id(channel.ID) diff --git a/src/windows/threadswindow.hpp b/src/windows/threadswindow.hpp index 276e067..f644e35 100644 --- a/src/windows/threadswindow.hpp +++ b/src/windows/threadswindow.hpp @@ -1,5 +1,4 @@ #pragma once -#include #include "discord/objects.hpp" class ActiveThreadsList : public Gtk::ScrolledWindow { -- cgit v1.2.3 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: fix channel tree expansion under folders --- src/components/channels.cpp | 45 ++++++++++++++++++++++++++++++++++----------- src/components/channels.hpp | 9 ++++++++- 2 files changed, 42 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 589b103..934326d 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 6c16fcd..da006dc 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 @@ protected: 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 @@ protected: // (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; -- cgit v1.2.3 From 41a616edb49b144d4b692e8c33933466e860778b Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 6 Feb 2023 03:02:05 -0500 Subject: fix potential stack overflow this will only happen if: there is a CHANNEL_UPDATE on a channel the channel is part of a guild which is in a folder and the channel is so old that it shares its id with the guild --- src/components/channels.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 934326d..231d9e3 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -799,7 +799,7 @@ Gtk::TreeModel::iterator ChannelList::GetIteratorForChannelFromID(Snowflake id) while (!queue.empty()) { auto item = queue.front(); - if ((*item)[m_columns.m_id] == id) return item; + if ((*item)[m_columns.m_id] == id && (*item)[m_columns.m_type] != RenderType::Guild) return item; for (const auto &child : item->children()) queue.push(child); queue.pop(); -- cgit v1.2.3 From 73ec2adb7b4b4a1a6d3b15b9dc9087941316a4c9 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 6 Feb 2023 19:06:48 -0500 Subject: fix some keybinds not working in the chat input (fixes #135) --- src/components/chatinput.cpp | 11 +++++++++-- src/components/chatinput.hpp | 3 +++ 2 files changed, 12 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index 4c4c866..d19ac4b 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -11,7 +11,10 @@ ChatInputText::ChatInputText() { // hack auto cb = [this](GdkEventKey *e) -> bool { - return event(reinterpret_cast(e)); + // we cant use Widget::event here specifically or else for some reason + // it prevents the default binding set from activating sometimes + // specifically event() will return true (why) preventing default handler from running + return m_signal_key_press_proxy.emit(e); }; m_textview.signal_key_press_event().connect(cb, false); m_textview.set_hexpand(false); @@ -90,12 +93,16 @@ ChatInputText::type_signal_image_paste ChatInputText::signal_image_paste() { return m_signal_image_paste; } +ChatInputText::type_signal_key_press_proxy ChatInputText::signal_key_press_proxy() { + return m_signal_key_press_proxy; +} + ChatInputTextContainer::ChatInputTextContainer() { // triple hack !!! auto cb = [this](GdkEventKey *e) -> bool { return event(reinterpret_cast(e)); }; - m_input.signal_key_press_event().connect(cb, false); + m_input.signal_key_press_proxy().connect(cb); m_upload_img.property_icon_name() = "document-send-symbolic"; m_upload_img.property_icon_size() = Gtk::ICON_SIZE_LARGE_TOOLBAR; diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp index 3b7bc79..bc6a45d 100644 --- a/src/components/chatinput.hpp +++ b/src/components/chatinput.hpp @@ -83,15 +83,18 @@ public: using type_signal_submit = sigc::signal; using type_signal_escape = sigc::signal; using type_signal_image_paste = sigc::signal>; + using type_signal_key_press_proxy = sigc::signal; type_signal_submit signal_submit(); type_signal_escape signal_escape(); type_signal_image_paste signal_image_paste(); + type_signal_key_press_proxy signal_key_press_proxy(); private: type_signal_submit m_signal_submit; type_signal_escape m_signal_escape; type_signal_image_paste m_signal_image_paste; + type_signal_key_press_proxy m_signal_key_press_proxy; }; // file upload, text -- cgit v1.2.3 From 4dd0eb24c40a7276dea4fc349d885f4277795dcb Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Mon, 6 Feb 2023 23:51:02 -0500 Subject: fix potential crash (#136) --- src/components/channels.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/components/channels.cpp b/src/components/channels.cpp index 231d9e3..b691ab5 100644 --- a/src/components/channels.cpp +++ b/src/components/channels.cpp @@ -299,12 +299,12 @@ void ChannelList::UpdateListing() { if (!guild.has_value()) continue; auto iter = AddGuild(*guild, m_model->children()); - (*iter)[m_columns.m_sort] = sort_value++; + if (iter) (*iter)[m_columns.m_sort] = sort_value++; } } else { for (const auto &group : folders) { auto iter = AddFolder(group); - (*iter)[m_columns.m_sort] = sort_value++; + if (iter) (*iter)[m_columns.m_sort] = sort_value++; } } -- cgit v1.2.3