1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
#include "notifications.hpp"
#include "misc/chatutil.hpp"
#include "discord/message.hpp"
Notifications::Notifications() {
}
bool CheckGuildMessage(const Message &message) {
auto &discord = Abaddon::Get().GetDiscordClient();
if (!message.GuildID.has_value()) return false;
const auto guild = discord.GetGuild(*message.GuildID);
if (!guild.has_value()) return false;
const auto guild_settings = discord.GetSettingsForGuild(*message.GuildID);
// if theres no guild settings then just use default message notifications level
// (there will be no channel settings)
if (!guild_settings.has_value()) {
if (guild->DefaultMessageNotifications.has_value()) {
switch (*guild->DefaultMessageNotifications) {
case DefaultNotificationLevel::ALL_MESSAGES:
return true;
case DefaultNotificationLevel::ONLY_MENTIONS:
return message.DoesMentionEveryoneOrUser(discord.GetUserData().ID);
default:
return false;
}
}
return false;
} else if (guild_settings->Muted) {
// if there are guild settings and the guild is muted then dont notify
return false;
}
// if the channel category is muted then dont notify
const auto channel = discord.GetChannel(message.ChannelID);
std::optional<UserGuildSettingsChannelOverride> category_settings;
if (channel.has_value() && channel->ParentID.has_value()) {
category_settings = guild_settings->GetOverride(*channel->ParentID);
if (category_settings.has_value() && category_settings->Muted) {
return false;
}
}
const auto channel_settings = guild_settings->GetOverride(message.ChannelID);
// 🥴
NotificationLevel level;
if (channel_settings.has_value()) {
if (channel_settings->MessageNotifications == NotificationLevel::USE_UPPER) {
if (category_settings.has_value()) {
if (category_settings->MessageNotifications == NotificationLevel::USE_UPPER) {
level = guild_settings->MessageNotifications;
} else {
level = category_settings->MessageNotifications;
}
} else {
level = guild_settings->MessageNotifications;
}
} else {
level = channel_settings->MessageNotifications;
}
} else {
if (category_settings.has_value()) {
if (category_settings->MessageNotifications == NotificationLevel::USE_UPPER) {
level = guild_settings->MessageNotifications;
} else {
level = category_settings->MessageNotifications;
}
} else {
level = guild_settings->MessageNotifications;
}
}
// there are channel settings, so use them
switch (level) {
case NotificationLevel::ALL_MESSAGES:
return true;
case NotificationLevel::ONLY_MENTIONS:
return message.DoesMentionEveryoneOrUser(discord.GetUserData().ID);
case NotificationLevel::NO_MESSAGES:
return false;
default:
return false;
}
}
void Notifications::CheckMessage(const Message &message) {
// ignore if our status is do not disturb
if (IsDND()) return;
auto &discord = Abaddon::Get().GetDiscordClient();
// ignore if the channel is muted
if (discord.IsChannelMuted(message.ChannelID)) return;
// ignore if focused and message's channel is active
if (Abaddon::Get().IsMainWindowActive() && Abaddon::Get().GetActiveChannelID() == message.ChannelID) return;
// ignore if its our own message
if (message.Author.ID == Abaddon::Get().GetDiscordClient().GetUserData().ID) return;
// notify messages in DMs
const auto channel = discord.GetChannel(message.ChannelID);
if (channel->IsDM()) {
NotifyMessageDM(message);
} else if (CheckGuildMessage(message)) {
NotifyMessageGuild(message);
}
}
Glib::ustring Sanitize(const Message &message) {
auto buf = Gtk::TextBuffer::create();
Gtk::TextBuffer::iterator begin, end;
buf->get_bounds(begin, end);
buf->insert(end, message.Content);
ChatUtil::CleanupEmojis(buf);
ChatUtil::HandleUserMentions(buf, message.ChannelID, true);
return Glib::Markup::escape_text(buf->get_text());
}
void Notifications::NotifyMessageDM(const Message &message) {
Glib::ustring default_action = "app.go-to-channel";
default_action += "::";
default_action += std::to_string(message.ChannelID);
const auto title = message.Author.Username;
const auto body = Sanitize(message);
Abaddon::Get().GetImageManager().GetCache().GetFileFromURL(message.Author.GetAvatarURL("png", "64"), [=](const std::string &path) {
m_notifier.Notify(title, body, default_action, path);
});
}
void Notifications::NotifyMessageGuild(const Message &message) {
Glib::ustring default_action = "app.go-to-channel";
default_action += "::";
default_action += std::to_string(message.ChannelID);
Glib::ustring title = message.Author.Username;
if (const auto channel = Abaddon::Get().GetDiscordClient().GetChannel(message.ChannelID); channel.has_value() && channel->Name.has_value()) {
if (channel->ParentID.has_value()) {
const auto category = Abaddon::Get().GetDiscordClient().GetChannel(*channel->ParentID);
if (category.has_value() && category->Name.has_value()) {
title += " (#" + *channel->Name + ", " + *category->Name + ")";
} else {
title += " (#" + *channel->Name + ")";
}
} else {
title += " (#" + *channel->Name + ")";
}
}
const auto body = Sanitize(message);
Abaddon::Get().GetImageManager().GetCache().GetFileFromURL(message.Author.GetAvatarURL("png", "64"), [=](const std::string &path) {
m_notifier.Notify(title, body, default_action, path);
});
}
bool Notifications::IsDND() const {
auto &discord = Abaddon::Get().GetDiscordClient();
const auto status = discord.GetUserStatus(discord.GetUserData().ID);
return status == PresenceStatus::DND;
}
|