very primitive embeds

This commit is contained in:
ouwou
2020-09-03 01:54:40 -04:00
parent 76cabbd37f
commit 2fab0c3e0d
6 changed files with 150 additions and 7 deletions

View File

@@ -1,3 +1,5 @@
#include <sstream>
#include <iomanip>
#include "chatmessage.hpp"
#include "../abaddon.hpp"
@@ -165,3 +167,92 @@ void ChatMessageTextItem::UpdateAttributes() {
buf->insert_markup(end, "<span color='#999999'> [edited]</span>");
}
}
ChatMessageEmbedItem::ChatMessageEmbedItem(const MessageData *data) {
m_embed = data->Embeds[0];
DoLayout();
AttachMenuHandler(this);
}
void ChatMessageEmbedItem::DoLayout() {
m_main = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
auto children = get_children();
auto it = children.begin();
while (it != children.end()) {
delete *it;
it++;
}
if (m_embed.Title.length() > 0) {
auto *title_label = Gtk::manage(new Gtk::Label);
title_label->set_use_markup(true);
title_label->set_markup("<b>" + Glib::Markup::escape_text(m_embed.Title) + "</b>");
title_label->set_halign(Gtk::ALIGN_CENTER);
m_main->pack_start(*title_label);
}
if (m_embed.Description.length() > 0) {
auto *desc_label = Gtk::manage(new Gtk::Label);
desc_label->set_text(m_embed.Description);
desc_label->set_line_wrap(true);
desc_label->set_line_wrap_mode(Pango::WRAP_WORD_CHAR);
desc_label->set_max_width_chars(50);
desc_label->set_halign(Gtk::ALIGN_START);
m_main->pack_start(*desc_label);
}
auto style = m_main->get_style_context();
if (m_embed.Color != -1) {
auto provider = Gtk::CssProvider::create(); // this seems wrong
int r = (m_embed.Color & 0xFF0000) >> 16;
int g = (m_embed.Color & 0x00FF00) >> 8;
int b = (m_embed.Color & 0x0000FF) >> 0;
std::stringstream css; // lol
css << ".embed { border-left: 2px solid #"
<< std::hex << std::setw(2) << std::setfill('0') << r
<< std::hex << std::setw(2) << std::setfill('0') << g
<< std::hex << std::setw(2) << std::setfill('0') << b
<< "; }";
provider->load_from_data(css.str());
style->add_provider(provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
style->add_class("embed");
set_margin_bottom(8);
add(*m_main);
show_all();
}
void ChatMessageEmbedItem::UpdateAttributes() {
bool deleted = m_was_deleted;
bool edited = m_was_edited && !m_was_deleted;
if (m_attrib_label == nullptr) {
m_attrib_label = Gtk::manage(new Gtk::Label);
m_attrib_label->set_use_markup(true);
m_attrib_label->show();
m_main->pack_end(*m_attrib_label);
}
if (deleted)
m_attrib_label->set_markup(" <span color='#ff0000'> [deleted]</span>");
else if (edited)
m_attrib_label->set_markup(" <span color='#999999'> [edited]</span>");
}
void ChatMessageEmbedItem::MarkAsDeleted() {
m_was_deleted = true;
// UpdateAttributes(); untested
}
void ChatMessageEmbedItem::MarkAsEdited() {
m_was_edited = true;
// UpdateAttributes();
}

View File

@@ -5,6 +5,7 @@
enum class ChatDisplayType {
Unknown,
Text,
Embed,
};
class Abaddon;
@@ -76,3 +77,24 @@ protected:
Gtk::MenuItem *m_menu_copy_content;
Gtk::MenuItem *m_menu_delete_message;
};
class ChatMessageEmbedItem
: public Gtk::EventBox
, public ChatMessageItem {
public:
ChatMessageEmbedItem(const MessageData *data);
virtual void MarkAsDeleted();
virtual void MarkAsEdited();
protected:
void DoLayout();
void UpdateAttributes();
bool m_was_deleted = false;
bool m_was_edited = false;
EmbedData m_embed;
Gtk::Box *m_main;
Gtk::Label *m_attrib_label = nullptr;
};

View File

@@ -85,6 +85,8 @@ Snowflake ChatWindow::GetActiveChannel() const {
ChatDisplayType ChatWindow::GetMessageDisplayType(const MessageData *data) {
if (data->Type == MessageType::DEFAULT && data->Content.size() > 0)
return ChatDisplayType::Text;
else if (data->Type == MessageType::DEFAULT && data->Embeds.size() > 0)
return ChatDisplayType::Embed;
return ChatDisplayType::Unknown;
}
@@ -121,6 +123,13 @@ void ChatWindow::ProcessMessage(const MessageData *data, bool prepend) {
text->SetAbaddon(m_abaddon);
container->AddNewContent(text, prepend);
m_id_to_widget[data->ID] = text;
} else if (type == ChatDisplayType::Embed) {
auto *widget = Gtk::manage(new ChatMessageEmbedItem(data));
widget->ID = data->ID;
widget->ChannelID = m_active_channel;
widget->SetAbaddon(m_abaddon);
container->AddNewContent(widget, prepend);
m_id_to_widget[data->ID] = widget;
}
container->show_all();

View File

@@ -1 +1,6 @@
.embed {
background-color: #eeeeee;
border-radius: 5px;
border-left: 2px solid red;
padding: 10px;
}

View File

@@ -62,7 +62,7 @@ void from_json(const nlohmann::json &j, GuildData &m) {
JS_D("name", m.Name);
JS_N("icon", m.Icon);
JS_N("splash", m.Splash);
JS_N("discovery_splash", m.DiscoverySplash);
JS_ON("discovery_splash", m.DiscoverySplash);
JS_O("owner", m.IsOwner);
JS_D("owner_id", m.OwnerID);
JS_O("permissions", m.Permissions);
@@ -143,7 +143,7 @@ void from_json(const nlohmann::json &j, MessageData &m) {
// JS_D("mention_roles", m.MentionRoles);
// JS_O("mention_channels", m.MentionChannels);
// JS_D("attachments", m.Attachments);
// JS_D("embeds", m.Embeds);
JS_D("embeds", m.Embeds);
// JS_O("reactions", m.Reactions);
JS_O("nonce", m.Nonce);
JS_D("pinned", m.IsPinned);
@@ -251,7 +251,7 @@ void from_json(const nlohmann::json &j, EmbedVideoData &m) {
void from_json(const nlohmann::json &j, EmbedProviderData &m) {
JS_O("name", m.Name);
JS_O("url", m.URL);
JS_ON("url", m.URL);
}
void from_json(const nlohmann::json &j, EmbedAuthorData &m) {
@@ -267,6 +267,22 @@ void from_json(const nlohmann::json &j, EmbedFieldData &m) {
JS_O("inline", m.Inline);
}
void from_json(const nlohmann::json &j, EmbedData &m) {
JS_O("title", m.Title);
JS_O("type", m.Type);
JS_O("description", m.Description);
JS_O("url", m.URL);
JS_O("timestamp", m.Timestamp);
JS_O("color", m.Color);
JS_O("footer", m.Footer);
JS_O("image", m.Image);
JS_O("thumbnail", m.Thumbnail);
JS_O("video", m.Video);
JS_O("provider", m.Provider);
JS_O("author", m.Author);
JS_O("fields", m.Fields);
}
void to_json(nlohmann::json &j, const IdentifyProperties &m) {
j["$os"] = m.OS;
j["$browser"] = m.Browser;

View File

@@ -144,7 +144,7 @@ struct GuildData {
std::string Name; //
std::string Icon; // null
std::string Splash; // null
std::string DiscoverySplash; // null
std::string DiscoverySplash; // opt, null (docs wrong)
bool IsOwner = false; // opt
Snowflake OwnerID; //
int Permissions = 0; // opt
@@ -293,7 +293,7 @@ struct EmbedVideoData {
struct EmbedProviderData {
std::string Name; // opt
std::string URL; // opt
std::string URL; // opt, null (docs wrong)
friend void from_json(const nlohmann::json &j, EmbedProviderData &m);
};
@@ -321,7 +321,7 @@ struct EmbedData {
std::string Description; // opt
std::string URL; // opt
std::string Timestamp; // opt
int Color = 0; // opt
int Color = -1; // opt
EmbedFooterData Footer; // opt
EmbedImageData Image; // opt
EmbedThumbnailData Thumbnail; // opt