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 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 84 insertions(+), 5 deletions(-) (limited to 'src/components/channels.cpp') 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 {}; } -- 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/components/channels.cpp') 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 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/components/channels.cpp') 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 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/components/channels.cpp') 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/components/channels.cpp') 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/components/channels.cpp') 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 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/components/channels.cpp') 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