diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-10-12 20:20:37 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-10-12 20:20:37 -0400 |
commit | c09a36d75c4a67b37f64bc8fc6afe30276627f5a (patch) | |
tree | 541007843fa9ae38decf0397a7cc54687509ca9b /components | |
parent | f5ae8c3d3fd4c6b928da6c7c3c785525fc60b7b4 (diff) | |
download | abaddon-portaudio-c09a36d75c4a67b37f64bc8fc6afe30276627f5a.tar.gz abaddon-portaudio-c09a36d75c4a67b37f64bc8fc6afe30276627f5a.zip |
parse user mentions a better way
Diffstat (limited to 'components')
-rw-r--r-- | components/chatmessage.cpp | 56 | ||||
-rw-r--r-- | components/chatmessage.hpp | 4 |
2 files changed, 38 insertions, 22 deletions
diff --git a/components/chatmessage.cpp b/components/chatmessage.cpp index f804572..93355de 100644 --- a/components/chatmessage.cpp +++ b/components/chatmessage.cpp @@ -170,7 +170,8 @@ void ChatMessageItemContainer::UpdateTextComponent(Gtk::TextView *tv) { b->get_bounds(s, e); switch (data->Type) { 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); HandleChannelMentions(tv); 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)); } -std::string ChatMessageItemContainer::ParseMessageContent(std::string content) { - content = ParseMentions(content); +void ChatMessageItemContainer::HandleUserMentions(Gtk::TextView *tv) { + 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) { - constexpr static const auto mentions_regex = R"(<@!?(\d+)>)"; + auto buf = tv->get_buffer(); + std::string text = buf->get_text(); + const auto &discord = Abaddon::Get().GetDiscordClient(); - return RegexReplaceMany(content, mentions_regex, [this](const std::string &idstr) -> std::string { - const Snowflake id(idstr); - const auto &discord = Abaddon::Get().GetDiscordClient(); - const auto *user = discord.GetUser(id); + std::string::const_iterator sstart(text.begin()); + std::smatch match; + while (std::regex_search(sstart, text.cend(), match, rgx)) { + const std::string user_id = match.str(1); + const auto *user = discord.GetUser(user_id); 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) - 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 start = std::distance(text.cbegin(), sstart) + match.position(); + auto erase_from = buf->get_iter_at_offset(start); + auto erase_to = buf->get_iter_at_offset(start + match.length()); + auto it = buf->erase(erase_from, erase_to); - const auto colorid = user->GetHoistedRole(channel->GuildID, true); - const auto *role = discord.GetRole(colorid); - if (role == nullptr) - return "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>"; + buf->insert_markup(it, replacement); - return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</span></b>"; - }); + text = buf->get_text(); + sstart = text.begin(); + } } void ChatMessageItemContainer::HandleChannelMentions(Gtk::TextView *tv) { diff --git a/components/chatmessage.hpp b/components/chatmessage.hpp index 35d4fea..9da0707 100644 --- a/components/chatmessage.hpp +++ b/components/chatmessage.hpp @@ -26,9 +26,7 @@ protected: Gtk::Box *CreateAttachmentComponent(const AttachmentData &data); // non-image attachments void HandleImage(const AttachmentData &data, Gtk::Image *img, std::string url); - // expects content run through Glib::Markup::escape_text - std::string ParseMessageContent(std::string content); - std::string ParseMentions(std::string content); + void HandleUserMentions(Gtk::TextView *tv); void HandleChannelMentions(Gtk::TextView *tv); bool OnClickChannel(GdkEventButton *ev); |