forked from OpenGamers/abaddon
handle mutable categories
This commit is contained in:
parent
8695562cb4
commit
40106ddeb1
@ -116,7 +116,15 @@ ChannelList::ChannelList()
|
||||
m_menu_category_copy_id.signal_activate().connect([this] {
|
||||
Gtk::Clipboard::get()->set_text(std::to_string((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]));
|
||||
});
|
||||
|
||||
m_menu_category_toggle_mute.signal_activate().connect([this] {
|
||||
const auto id = static_cast<Snowflake>((*m_model->get_iter(m_path_for_menu))[m_columns.m_id]);
|
||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||
if (discord.IsChannelMuted(id))
|
||||
discord.UnmuteChannel(id, NOOP_CALLBACK);
|
||||
else
|
||||
discord.MuteChannel(id, NOOP_CALLBACK);
|
||||
});
|
||||
m_menu_category.append(m_menu_category_toggle_mute);
|
||||
m_menu_category.append(m_menu_category_copy_id);
|
||||
m_menu_category.show_all();
|
||||
|
||||
@ -177,6 +185,7 @@ ChannelList::ChannelList()
|
||||
m_menu_thread.show_all();
|
||||
|
||||
m_menu_guild.signal_popped_up().connect(sigc::mem_fun(*this, &ChannelList::OnGuildSubmenuPopup));
|
||||
m_menu_category.signal_popped_up().connect(sigc::mem_fun(*this, &ChannelList::OnCategorySubmenuPopup));
|
||||
m_menu_channel.signal_popped_up().connect(sigc::mem_fun(*this, &ChannelList::OnChannelSubmenuPopup));
|
||||
m_menu_thread.signal_popped_up().connect(sigc::mem_fun(*this, &ChannelList::OnThreadSubmenuPopup));
|
||||
|
||||
@ -857,6 +866,16 @@ void ChannelList::OnGuildSubmenuPopup(const Gdk::Rectangle *flipped_rect, const
|
||||
m_menu_guild_toggle_mute.set_label("Mute");
|
||||
}
|
||||
|
||||
void ChannelList::OnCategorySubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y) {
|
||||
const auto iter = m_model->get_iter(m_path_for_menu);
|
||||
if (!iter) return;
|
||||
const auto id = static_cast<Snowflake>((*iter)[m_columns.m_id]);
|
||||
if (Abaddon::Get().GetDiscordClient().IsChannelMuted(id))
|
||||
m_menu_category_toggle_mute.set_label("Unmute");
|
||||
else
|
||||
m_menu_category_toggle_mute.set_label("Mute");
|
||||
}
|
||||
|
||||
void ChannelList::OnChannelSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y) {
|
||||
const auto iter = m_model->get_iter(m_path_for_menu);
|
||||
if (!iter) return;
|
||||
|
@ -114,6 +114,7 @@ protected:
|
||||
|
||||
Gtk::Menu m_menu_category;
|
||||
Gtk::MenuItem m_menu_category_copy_id;
|
||||
Gtk::MenuItem m_menu_category_toggle_mute;
|
||||
|
||||
Gtk::Menu m_menu_channel;
|
||||
Gtk::MenuItem m_menu_channel_copy_id;
|
||||
@ -131,6 +132,7 @@ protected:
|
||||
Gtk::MenuItem m_menu_thread_unarchive;
|
||||
|
||||
void OnGuildSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y);
|
||||
void OnCategorySubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y);
|
||||
void OnChannelSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y);
|
||||
void OnThreadSubmenuPopup(const Gdk::Rectangle *flipped_rect, const Gdk::Rectangle *final_rect, bool flipped_x, bool flipped_y);
|
||||
|
||||
|
@ -327,7 +327,11 @@ void CellRendererChannels::render_vfunc_category(const Cairo::RefPtr<Cairo::Cont
|
||||
|
||||
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
|
||||
|
||||
static Gdk::RGBA muted_color("#7f7f7f");
|
||||
if (Abaddon::Get().GetDiscordClient().IsChannelMuted(m_property_id.get_value()))
|
||||
m_renderer_text.property_foreground_rgba() = muted_color;
|
||||
m_renderer_text.render(cr, widget, background_area, text_cell_area, flags);
|
||||
m_renderer_text.property_foreground_set() = false;
|
||||
}
|
||||
|
||||
// text channel
|
||||
|
@ -78,6 +78,14 @@ bool ChannelData::IsJoinedThread() const {
|
||||
return Abaddon::Get().GetDiscordClient().IsThreadJoined(ID);
|
||||
}
|
||||
|
||||
bool ChannelData::IsCategory() const noexcept {
|
||||
return Type == ChannelType::GUILD_CATEGORY;
|
||||
}
|
||||
|
||||
std::vector<Snowflake> ChannelData::GetChildIDs() const {
|
||||
return Abaddon::Get().GetDiscordClient().GetChildChannelIDs(ID);
|
||||
}
|
||||
|
||||
std::optional<PermissionOverwrite> ChannelData::GetOverwrite(Snowflake id) const {
|
||||
return Abaddon::Get().GetDiscordClient().GetPermissionOverwrite(ID, id);
|
||||
}
|
||||
|
@ -88,6 +88,8 @@ struct ChannelData {
|
||||
bool IsDM() const noexcept;
|
||||
bool IsThread() const noexcept;
|
||||
bool IsJoinedThread() const;
|
||||
bool IsCategory() const noexcept;
|
||||
std::vector<Snowflake> GetChildIDs() const;
|
||||
std::optional<PermissionOverwrite> GetOverwrite(Snowflake id) const;
|
||||
std::vector<UserData> GetDMRecipients() const;
|
||||
};
|
||||
|
@ -307,6 +307,10 @@ void DiscordClient::GetArchivedPrivateThreads(Snowflake channel_id, sigc::slot<v
|
||||
});
|
||||
}
|
||||
|
||||
std::vector<Snowflake> DiscordClient::GetChildChannelIDs(Snowflake parent_id) const {
|
||||
return m_store.GetChannelIDsWithParentID(parent_id);
|
||||
}
|
||||
|
||||
bool DiscordClient::IsThreadJoined(Snowflake thread_id) const {
|
||||
return std::find(m_joined_threads.begin(), m_joined_threads.end(), thread_id) != m_joined_threads.end();
|
||||
}
|
||||
@ -1184,10 +1188,15 @@ bool DiscordClient::GetUnreadStateForGuild(Snowflake id, int &total_mentions) co
|
||||
const auto channels = GetChannelsInGuild(id);
|
||||
for (const auto channel_id : channels) {
|
||||
const auto channel_unread = GetUnreadStateForChannel(channel_id);
|
||||
if (!has_any_unread && channel_unread > -1 && !IsChannelMuted(channel_id))
|
||||
has_any_unread = true;
|
||||
if (channel_unread > -1)
|
||||
total_mentions += channel_unread;
|
||||
|
||||
// channels under muted categories wont contribute to unread state
|
||||
if (const auto iter = m_channel_muted_parent.find(channel_id); iter != m_channel_muted_parent.end())
|
||||
continue;
|
||||
|
||||
if (!has_any_unread && channel_unread > -1 && !IsChannelMuted(channel_id))
|
||||
has_any_unread = true;
|
||||
}
|
||||
return has_any_unread;
|
||||
}
|
||||
@ -1974,11 +1983,19 @@ void DiscordClient::HandleGatewayUserGuildSettingsUpdate(const GatewayMessage &m
|
||||
if (now_muted) {
|
||||
m_muted_channels.insert(channel_id);
|
||||
if (!was_muted) {
|
||||
if (const auto chan = GetChannel(channel_id); chan.has_value() && chan->IsCategory())
|
||||
for (const auto child_id : chan->GetChildIDs())
|
||||
m_channel_muted_parent.insert(child_id);
|
||||
|
||||
m_signal_channel_muted.emit(channel_id);
|
||||
}
|
||||
} else {
|
||||
m_muted_channels.erase(channel_id);
|
||||
if (was_muted) {
|
||||
if (const auto chan = GetChannel(channel_id); chan.has_value() && chan->IsCategory())
|
||||
for (const auto child_id : chan->GetChildIDs())
|
||||
m_channel_muted_parent.erase(child_id);
|
||||
|
||||
m_signal_channel_unmuted.emit(channel_id);
|
||||
}
|
||||
}
|
||||
@ -2357,6 +2374,14 @@ void DiscordClient::HandleReadyReadState(const ReadyEventData &data) {
|
||||
}
|
||||
|
||||
void DiscordClient::HandleReadyGuildSettings(const ReadyEventData &data) {
|
||||
// i dont like this implementation for muted categories but its rather simple and doesnt use a horriiible amount of ram
|
||||
|
||||
std::unordered_map<Snowflake, std::vector<Snowflake>> category_children;
|
||||
for (const auto &guild : data.Guilds)
|
||||
for (const auto &channel : *guild.Channels)
|
||||
if (channel.ParentID.has_value() && !channel.IsThread())
|
||||
category_children[*channel.ParentID].push_back(channel.ID);
|
||||
|
||||
const auto now = Snowflake::FromNow();
|
||||
for (const auto &entry : data.GuildSettings.Entries) {
|
||||
// even if muted is true a guild/channel can be unmuted if the current time passes mute_config.end_time
|
||||
@ -2371,6 +2396,10 @@ void DiscordClient::HandleReadyGuildSettings(const ReadyEventData &data) {
|
||||
}
|
||||
for (const auto &override : entry.ChannelOverrides) {
|
||||
if (override.Muted) {
|
||||
if (const auto iter = category_children.find(override.ChannelID); iter != category_children.end())
|
||||
for (const auto child : iter->second)
|
||||
m_channel_muted_parent.insert(child);
|
||||
|
||||
if (override.MuteConfig.EndTime.has_value()) {
|
||||
const auto end = Snowflake::FromISO8601(*override.MuteConfig.EndTime);
|
||||
if (end.IsValid() && end > now)
|
||||
|
@ -82,6 +82,7 @@ public:
|
||||
std::vector<ChannelData> GetActiveThreads(Snowflake channel_id) const;
|
||||
void GetArchivedPublicThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback);
|
||||
void GetArchivedPrivateThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback);
|
||||
std::vector<Snowflake> GetChildChannelIDs(Snowflake parent_id) const;
|
||||
|
||||
bool IsThreadJoined(Snowflake thread_id) const;
|
||||
bool HasGuildPermission(Snowflake user_id, Snowflake guild_id, Permission perm) const;
|
||||
@ -290,6 +291,7 @@ private:
|
||||
std::unordered_set<Snowflake> m_muted_guilds;
|
||||
std::unordered_set<Snowflake> m_muted_channels;
|
||||
std::unordered_map<Snowflake, int> m_unread;
|
||||
std::unordered_set<Snowflake> m_channel_muted_parent;
|
||||
|
||||
UserData m_user_data;
|
||||
UserSettings m_user_settings;
|
||||
|
@ -571,6 +571,21 @@ std::vector<ChannelData> Store::GetActiveThreads(Snowflake channel_id) const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<Snowflake> Store::GetChannelIDsWithParentID(Snowflake channel_id) const {
|
||||
auto &s = m_stmt_get_chan_ids_parent;
|
||||
|
||||
s->Bind(1, channel_id);
|
||||
|
||||
std::vector<Snowflake> ret;
|
||||
while (s->FetchOne()) {
|
||||
Snowflake x;
|
||||
s->Get(0, x);
|
||||
ret.push_back(x);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void Store::AddReaction(const MessageReactionAddObject &data, bool byself) {
|
||||
auto &s = m_stmt_add_reaction;
|
||||
|
||||
@ -2120,6 +2135,14 @@ bool Store::CreateStatements() {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_stmt_get_chan_ids_parent = std::make_unique<Statement>(m_db, R"(
|
||||
SELECT id FROM channels WHERE parent_id = ?
|
||||
)");
|
||||
if (!m_stmt_get_chan_ids_parent->OK()) {
|
||||
fprintf(stderr, "failed to prepare get channel ids for parent statement: %s\n", m_db.ErrStr());
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
std::vector<Message> GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit) const;
|
||||
std::vector<Message> GetPinnedMessages(Snowflake channel_id) const;
|
||||
std::vector<ChannelData> GetActiveThreads(Snowflake channel_id) const; // public
|
||||
std::vector<Snowflake> GetChannelIDsWithParentID(Snowflake channel_id) const;
|
||||
|
||||
void AddReaction(const MessageReactionAddObject &data, bool byself);
|
||||
void RemoveReaction(const MessageReactionRemoveObject &data, bool byself);
|
||||
@ -300,5 +301,6 @@ private:
|
||||
STMT(add_reaction);
|
||||
STMT(sub_reaction);
|
||||
STMT(get_reactions);
|
||||
STMT(get_chan_ids_parent);
|
||||
#undef STMT
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user