parse user mentions a better way
This commit is contained in:
@@ -170,7 +170,8 @@ void ChatMessageItemContainer::UpdateTextComponent(Gtk::TextView *tv) {
|
|||||||
b->get_bounds(s, e);
|
b->get_bounds(s, e);
|
||||||
switch (data->Type) {
|
switch (data->Type) {
|
||||||
case MessageType::DEFAULT:
|
case MessageType::DEFAULT:
|
||||||
b->insert_markup(s, ParseMessageContent(Glib::Markup::escape_text(data->Content)));
|
b->insert_markup(s, Glib::Markup::escape_text(data->Content));
|
||||||
|
HandleUserMentions(tv);
|
||||||
HandleLinks(tv);
|
HandleLinks(tv);
|
||||||
HandleChannelMentions(tv);
|
HandleChannelMentions(tv);
|
||||||
break;
|
break;
|
||||||
@@ -362,32 +363,49 @@ void ChatMessageItemContainer::HandleImage(const AttachmentData &data, Gtk::Imag
|
|||||||
Glib::signal_idle().connect(sigc::bind(sigc::mem_fun(*this, &ChatMessageItemContainer::EmitImageLoad), url));
|
Glib::signal_idle().connect(sigc::bind(sigc::mem_fun(*this, &ChatMessageItemContainer::EmitImageLoad), url));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string ChatMessageItemContainer::ParseMessageContent(std::string content) {
|
void ChatMessageItemContainer::HandleUserMentions(Gtk::TextView *tv) {
|
||||||
content = ParseMentions(content);
|
constexpr static const auto mentions_regex = R"(<@!?(\d+)>)";
|
||||||
|
|
||||||
return content;
|
std::regex rgx(mentions_regex, std::regex_constants::ECMAScript);
|
||||||
}
|
|
||||||
|
|
||||||
std::string ChatMessageItemContainer::ParseMentions(std::string content) {
|
auto buf = tv->get_buffer();
|
||||||
constexpr static const auto mentions_regex = R"(<@!?(\d+)>)";
|
std::string text = buf->get_text();
|
||||||
|
const auto &discord = Abaddon::Get().GetDiscordClient();
|
||||||
|
|
||||||
return RegexReplaceMany(content, mentions_regex, [this](const std::string &idstr) -> std::string {
|
std::string::const_iterator sstart(text.begin());
|
||||||
const Snowflake id(idstr);
|
std::smatch match;
|
||||||
const auto &discord = Abaddon::Get().GetDiscordClient();
|
while (std::regex_search(sstart, text.cend(), match, rgx)) {
|
||||||
const auto *user = discord.GetUser(id);
|
const std::string user_id = match.str(1);
|
||||||
|
const auto *user = discord.GetUser(user_id);
|
||||||
const auto *channel = discord.GetChannel(ChannelID);
|
const auto *channel = discord.GetChannel(ChannelID);
|
||||||
if (channel == nullptr || user == nullptr) return idstr;
|
if (user == nullptr || channel == nullptr) {
|
||||||
|
sstart = match.suffix().first;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string replacement;
|
||||||
|
|
||||||
if (channel->Type == ChannelType::DM || channel->Type == ChannelType::GROUP_DM)
|
if (channel->Type == ChannelType::DM || channel->Type == ChannelType::GROUP_DM)
|
||||||
return "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>";
|
replacement = "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>";
|
||||||
|
else {
|
||||||
|
const auto role_id = user->GetHoistedRole(channel->GuildID, true);
|
||||||
|
const auto *role = discord.GetRole(role_id);
|
||||||
|
if (role == nullptr)
|
||||||
|
replacement = "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>";
|
||||||
|
else
|
||||||
|
replacement = "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</span></b>";
|
||||||
|
}
|
||||||
|
|
||||||
const auto colorid = user->GetHoistedRole(channel->GuildID, true);
|
const auto start = std::distance(text.cbegin(), sstart) + match.position();
|
||||||
const auto *role = discord.GetRole(colorid);
|
auto erase_from = buf->get_iter_at_offset(start);
|
||||||
if (role == nullptr)
|
auto erase_to = buf->get_iter_at_offset(start + match.length());
|
||||||
return "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>";
|
auto it = buf->erase(erase_from, erase_to);
|
||||||
|
|
||||||
return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</span></b>";
|
buf->insert_markup(it, replacement);
|
||||||
});
|
|
||||||
|
text = buf->get_text();
|
||||||
|
sstart = text.begin();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatMessageItemContainer::HandleChannelMentions(Gtk::TextView *tv) {
|
void ChatMessageItemContainer::HandleChannelMentions(Gtk::TextView *tv) {
|
||||||
|
@@ -26,9 +26,7 @@ protected:
|
|||||||
Gtk::Box *CreateAttachmentComponent(const AttachmentData &data); // non-image attachments
|
Gtk::Box *CreateAttachmentComponent(const AttachmentData &data); // non-image attachments
|
||||||
void HandleImage(const AttachmentData &data, Gtk::Image *img, std::string url);
|
void HandleImage(const AttachmentData &data, Gtk::Image *img, std::string url);
|
||||||
|
|
||||||
// expects content run through Glib::Markup::escape_text
|
void HandleUserMentions(Gtk::TextView *tv);
|
||||||
std::string ParseMessageContent(std::string content);
|
|
||||||
std::string ParseMentions(std::string content);
|
|
||||||
|
|
||||||
void HandleChannelMentions(Gtk::TextView *tv);
|
void HandleChannelMentions(Gtk::TextView *tv);
|
||||||
bool OnClickChannel(GdkEventButton *ev);
|
bool OnClickChannel(GdkEventButton *ev);
|
||||||
|
Reference in New Issue
Block a user