diff options
Diffstat (limited to 'discord/guild.cpp')
-rw-r--r-- | discord/guild.cpp | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/discord/guild.cpp b/discord/guild.cpp index 602cdb2..5875a11 100644 --- a/discord/guild.cpp +++ b/discord/guild.cpp @@ -1,4 +1,5 @@ #include "guild.hpp" +#include "../abaddon.hpp" void from_json(const nlohmann::json &j, Guild &m) { JS_D("id", m.ID); @@ -64,3 +65,53 @@ bool Guild::HasIcon() const { std::string Guild::GetIconURL(std::string ext, std::string size) const { return "https://cdn.discordapp.com/icons/" + std::to_string(ID) + "/" + Icon + "." + ext + "?size=" + size; } + +std::vector<Snowflake> Guild::GetSortedChannels(Snowflake ignore) const { + std::vector<Snowflake> ret; + + const auto &discord = Abaddon::Get().GetDiscordClient(); + auto channels = discord.GetChannelsInGuild(ID); + + std::unordered_map<Snowflake, std::vector<const Channel *>> category_to_channels; + std::map<int, std::vector<const Channel *>> position_to_categories; + std::map<int, std::vector<const Channel *>> orphan_channels; + for (const auto &channel_id : channels) { + const auto *data = discord.GetChannel(channel_id); + if (data == nullptr) continue; + if (!data->ParentID.IsValid() && data->Type == ChannelType::GUILD_TEXT) + orphan_channels[data->Position].push_back(data); + else if (data->ParentID.IsValid() && data->Type == ChannelType::GUILD_TEXT) + category_to_channels[data->ParentID].push_back(data); + else if (data->Type == ChannelType::GUILD_CATEGORY) + position_to_categories[data->Position].push_back(data); + } + + for (auto &[pos, channels] : orphan_channels) { + std::sort(channels.begin(), channels.end(), [&](const Channel *a, const Channel *b) -> bool { + return a->ID < b->ID; + }); + for (auto &chan : channels) + ret.push_back(chan->ID); + } + + for (auto &[pos, categories] : position_to_categories) { + std::sort(categories.begin(), categories.end(), [&](const Channel *a, const Channel *b) -> bool { + return a->ID < b->ID; + }); + for (auto &category : categories) { + ret.push_back(category->ID); + if (ignore == category->ID) continue; // stupid hack to save me some time + auto it = category_to_channels.find(category->ID); + if (it == category_to_channels.end()) continue; + auto &channels = it->second; + std::sort(channels.begin(), channels.end(), [&](const Channel *a, const Channel *b) -> bool { + return a->Position < b->Position; + }); + for (auto &channel : channels) { + ret.push_back(channel->ID); + } + } + } + + return ret; +} |