mirror of
https://github.com/uowuo/abaddon.git
synced 2026-01-15 13:30:06 +00:00
basic mention parsing
This commit is contained in:
@@ -71,7 +71,7 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(Snowflake id) {
|
||||
void ChatMessageItemContainer::UpdateContent() {
|
||||
const auto *data = Abaddon::Get().GetDiscordClient().GetMessage(ID);
|
||||
if (m_text_component != nullptr)
|
||||
m_text_component->get_buffer()->set_text(data->Content);
|
||||
UpdateTextComponent(m_text_component);
|
||||
|
||||
if (m_embed_component != nullptr)
|
||||
delete m_embed_component;
|
||||
@@ -154,12 +154,23 @@ Gtk::TextView *ChatMessageItemContainer::CreateTextComponent(const Message *data
|
||||
tv->set_halign(Gtk::ALIGN_FILL);
|
||||
tv->set_hexpand(true);
|
||||
|
||||
UpdateTextComponent(tv);
|
||||
|
||||
return tv;
|
||||
}
|
||||
|
||||
void ChatMessageItemContainer::UpdateTextComponent(Gtk::TextView *tv) {
|
||||
const auto *data = Abaddon::Get().GetDiscordClient().GetMessage(ID);
|
||||
if (data == nullptr)
|
||||
return;
|
||||
|
||||
auto b = tv->get_buffer();
|
||||
Gtk::TextBuffer::iterator s, e; // lame
|
||||
b->set_text("");
|
||||
Gtk::TextBuffer::iterator s, e;
|
||||
b->get_bounds(s, e);
|
||||
switch (data->Type) {
|
||||
case MessageType::DEFAULT:
|
||||
b->set_text(data->Content);
|
||||
b->insert_markup(s, ParseMessageContent(Glib::Markup::escape_text(data->Content)));
|
||||
break;
|
||||
case MessageType::GUILD_MEMBER_JOIN:
|
||||
b->insert_markup(s, "<span color='#999999'><i>[user joined]</i></span>");
|
||||
@@ -169,8 +180,6 @@ Gtk::TextView *ChatMessageItemContainer::CreateTextComponent(const Message *data
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
return tv;
|
||||
}
|
||||
|
||||
Gtk::EventBox *ChatMessageItemContainer::CreateEmbedComponent(const Message *data) {
|
||||
@@ -351,6 +360,34 @@ 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);
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
std::string ChatMessageItemContainer::ParseMentions(std::string content) {
|
||||
constexpr static const auto mentions_regex = R"(<@(\d+)>)";
|
||||
|
||||
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);
|
||||
const auto *channel = discord.GetChannel(ChannelID);
|
||||
if (channel == nullptr || user == nullptr) return idstr;
|
||||
|
||||
if (channel->Type == ChannelType::DM || channel->Type == ChannelType::GROUP_DM)
|
||||
return "<b>@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</b>";
|
||||
|
||||
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>";
|
||||
|
||||
return "<b><span color=\"#" + IntToCSSColor(role->Color) + "\">@" + Glib::Markup::escape_text(user->Username) + "#" + user->Discriminator + "</span></b>";
|
||||
});
|
||||
}
|
||||
|
||||
void ChatMessageItemContainer::ShowMenu(GdkEvent *event) {
|
||||
const auto &client = Abaddon::Get().GetDiscordClient();
|
||||
const auto *data = client.GetMessage(ID);
|
||||
|
||||
@@ -20,11 +20,16 @@ protected:
|
||||
|
||||
void AddClickHandler(Gtk::Widget *widget, std::string);
|
||||
Gtk::TextView *CreateTextComponent(const Message *data); // Message.Content
|
||||
void UpdateTextComponent(Gtk::TextView *tv);
|
||||
Gtk::EventBox *CreateEmbedComponent(const Message *data); // Message.Embeds[0]
|
||||
Gtk::Image *CreateImageComponent(const AttachmentData &data);
|
||||
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);
|
||||
|
||||
std::unordered_map<std::string, std::pair<Gtk::Image *, AttachmentData>> m_img_loadmap;
|
||||
|
||||
void AttachMenuHandler(Gtk::Widget *widget);
|
||||
|
||||
36
util.hpp
36
util.hpp
@@ -184,3 +184,39 @@ inline double ColorDistance(int c1, int c2) {
|
||||
int b = b1 - b2;
|
||||
return sqrt((((512 + rmean) * r * r) >> 8) + 4 * g * g + (((767 - rmean) * b * b) >> 8));
|
||||
}
|
||||
|
||||
// somehow this works
|
||||
template<typename F>
|
||||
std::string RegexReplaceMany(std::string str, std::string regexstr, F func) {
|
||||
std::regex reg(regexstr, std::regex_constants::ECMAScript);
|
||||
std::smatch match;
|
||||
|
||||
std::vector<std::tuple<int, int, std::string, int>> matches;
|
||||
|
||||
std::string::const_iterator sstart(str.cbegin());
|
||||
while (std::regex_search(sstart, str.cend(), match, reg)) {
|
||||
const auto start = std::distance(str.cbegin(), sstart) + match.position();
|
||||
const auto end = start + match.length();
|
||||
matches.push_back(std::make_tuple(static_cast<int>(start), static_cast<int>(end), match[1].str(), static_cast<int>(match.str().size())));
|
||||
sstart = match.suffix().first;
|
||||
}
|
||||
|
||||
int offset = 0;
|
||||
for (auto it = matches.begin(); it != matches.end(); it++) {
|
||||
const auto start = std::get<0>(*it);
|
||||
const auto end = std::get<1>(*it);
|
||||
const auto match = std::get<2>(*it);
|
||||
const auto full_match_size = std::get<3>(*it);
|
||||
const auto replacement = func(match);
|
||||
const auto diff = full_match_size - replacement.size();
|
||||
|
||||
str = str.substr(0, start) + replacement + str.substr(end);
|
||||
|
||||
offset += diff;
|
||||
|
||||
std::get<0>(*(it + 1)) -= offset;
|
||||
std::get<1>(*(it + 1)) -= offset;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user