mirror of
https://github.com/uowuo/abaddon.git
synced 2026-01-14 05:00:05 +00:00
- crash when assuming group dms have someone other than urself - crash from lifetime error with user note update
206 lines
6.7 KiB
C++
206 lines
6.7 KiB
C++
#include "userinfopane.hpp"
|
|
#include <unordered_set>
|
|
#include "../../abaddon.hpp"
|
|
|
|
ConnectionItem::ConnectionItem(const ConnectionData &conn)
|
|
: m_name(conn.Name)
|
|
, m_box(Gtk::ORIENTATION_HORIZONTAL) {
|
|
Glib::RefPtr<Gdk::Pixbuf> pixbuf;
|
|
try {
|
|
pixbuf = Gdk::Pixbuf::create_from_file("./res/" + conn.Type + ".png", 32, 32);
|
|
} catch (const Glib::Exception &e) {}
|
|
std::string url;
|
|
if (conn.Type == "github")
|
|
url = "https://github.com/" + conn.Name;
|
|
else if (conn.Type == "steam")
|
|
url = "https://steamcommunity.com/profiles/" + conn.ID;
|
|
else if (conn.Type == "twitch")
|
|
url = "https://twitch.tv/" + conn.Name;
|
|
else if (conn.Type == "twitter")
|
|
url = "https://twitter.com/i/user/" + conn.ID;
|
|
else if (conn.Type == "spotify")
|
|
url = "https://open.spotify.com/user/" + conn.ID;
|
|
else if (conn.Type == "reddit")
|
|
url = "https://reddit.com/u/" + conn.Name;
|
|
else if (conn.Type == "youtube")
|
|
url = "https://www.youtube.com/channel/" + conn.ID;
|
|
else if (conn.Type == "facebook")
|
|
url = "https://www.facebook.com/" + conn.ID;
|
|
if (pixbuf) {
|
|
m_image = Gtk::manage(new Gtk::Image(pixbuf));
|
|
m_image->get_style_context()->add_class("profile-connection-image");
|
|
m_box.add(*m_image);
|
|
}
|
|
m_box.set_halign(Gtk::ALIGN_START);
|
|
m_box.set_size_request(200, -1);
|
|
m_box.get_style_context()->add_class("profile-connection");
|
|
m_name.get_style_context()->add_class("profile-connection-label");
|
|
m_name.set_valign(Gtk::ALIGN_CENTER);
|
|
m_name.set_single_line_mode(true);
|
|
m_name.set_ellipsize(Pango::ELLIPSIZE_END);
|
|
m_box.add(m_name);
|
|
if (url != "") {
|
|
auto cb = [this, url](GdkEventButton *event) -> bool {
|
|
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) {
|
|
LaunchBrowser(url);
|
|
return true;
|
|
}
|
|
return false;
|
|
};
|
|
signal_button_press_event().connect(sigc::track_obj(cb, *this));
|
|
AddPointerCursor(*this);
|
|
}
|
|
m_overlay.add(m_box);
|
|
if (conn.IsVerified) {
|
|
try {
|
|
static auto pb = Gdk::Pixbuf::create_from_file("./res/checkmark.png", 24, 24);
|
|
m_check = Gtk::manage(new Gtk::Image(pb));
|
|
m_check->get_style_context()->add_class("profile-connection-check");
|
|
m_check->set_margin_end(25);
|
|
m_check->set_valign(Gtk::ALIGN_CENTER);
|
|
m_check->set_halign(Gtk::ALIGN_END);
|
|
m_check->show();
|
|
m_overlay.add_overlay(*m_check);
|
|
} catch (const Glib::Exception &e) {}
|
|
}
|
|
m_overlay.set_hexpand(false);
|
|
m_overlay.set_halign(Gtk::ALIGN_START);
|
|
add(m_overlay);
|
|
show_all_children();
|
|
}
|
|
|
|
ConnectionsContainer::ConnectionsContainer() {
|
|
get_style_context()->add_class("profile-connections");
|
|
set_column_homogeneous(true);
|
|
set_row_spacing(10);
|
|
set_column_spacing(10);
|
|
show_all_children();
|
|
}
|
|
|
|
void ConnectionsContainer::SetConnections(const std::vector<ConnectionData> &connections) {
|
|
for (auto child : get_children())
|
|
delete child;
|
|
|
|
static const std::unordered_set<std::string> supported_services = {
|
|
"battlenet",
|
|
"github",
|
|
"leagueoflegends",
|
|
"reddit",
|
|
"skype",
|
|
"spotify",
|
|
"steam",
|
|
"twitch",
|
|
"twitter",
|
|
"xbox",
|
|
"youtube",
|
|
"facebook"
|
|
};
|
|
|
|
for (int i = 0; i < connections.size(); i++) {
|
|
const auto &conn = connections[i];
|
|
if (supported_services.find(conn.Type) == supported_services.end()) continue;
|
|
auto widget = Gtk::manage(new ConnectionItem(conn));
|
|
widget->show();
|
|
attach(*widget, i % 2, i / 2, 1, 1);
|
|
}
|
|
|
|
set_halign(Gtk::ALIGN_FILL);
|
|
set_hexpand(true);
|
|
}
|
|
|
|
NotesContainer::NotesContainer()
|
|
: Gtk::Box(Gtk::ORIENTATION_VERTICAL) {
|
|
get_style_context()->add_class("profile-notes");
|
|
m_label.get_style_context()->add_class("profile-notes-label");
|
|
m_note.get_style_context()->add_class("profile-notes-text");
|
|
|
|
m_label.set_markup("<b>NOTE</b>");
|
|
m_label.set_halign(Gtk::ALIGN_START);
|
|
|
|
m_note.set_wrap_mode(Gtk::WRAP_WORD_CHAR);
|
|
m_note.signal_key_press_event().connect(sigc::mem_fun(*this, &NotesContainer::OnNoteKeyPress), false);
|
|
|
|
add(m_label);
|
|
add(m_note);
|
|
show_all_children();
|
|
}
|
|
|
|
void NotesContainer::SetNote(const std::string ¬e) {
|
|
m_note.get_buffer()->set_text(note);
|
|
}
|
|
|
|
void NotesContainer::UpdateNote() {
|
|
auto text = m_note.get_buffer()->get_text();
|
|
if (text.size() > 256)
|
|
text = text.substr(0, 256);
|
|
m_signal_update_note.emit(text);
|
|
}
|
|
|
|
bool NotesContainer::OnNoteKeyPress(GdkEventKey *event) {
|
|
if (event->type != GDK_KEY_PRESS) return false;
|
|
const auto text = m_note.get_buffer()->get_text();
|
|
if (event->keyval == GDK_KEY_Return) {
|
|
if (event->state & GDK_SHIFT_MASK) {
|
|
int newlines = 0;
|
|
for (const auto c : text)
|
|
if (c == '\n') newlines++;
|
|
return newlines >= 5;
|
|
} else {
|
|
UpdateNote();
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
NotesContainer::type_signal_update_note NotesContainer::signal_update_note() {
|
|
return m_signal_update_note;
|
|
}
|
|
|
|
ProfileUserInfoPane::ProfileUserInfoPane(Snowflake ID)
|
|
: Gtk::Box(Gtk::ORIENTATION_VERTICAL)
|
|
, UserID(ID) {
|
|
get_style_context()->add_class("profile-info-pane");
|
|
m_created.get_style_context()->add_class("profile-info-created");
|
|
|
|
m_note.signal_update_note().connect([this](const Glib::ustring ¬e) {
|
|
auto cb = [this](bool success) {
|
|
if (!success) {
|
|
Gtk::MessageDialog dlg("Failed to set note", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
dlg.set_position(Gtk::WIN_POS_CENTER);
|
|
dlg.run();
|
|
}
|
|
};
|
|
Abaddon::Get().GetDiscordClient().SetUserNote(UserID, note, sigc::track_obj(cb, *this));
|
|
});
|
|
|
|
auto &discord = Abaddon::Get().GetDiscordClient();
|
|
auto note_update_cb = [this](Snowflake id, std::string note) {
|
|
if (id == UserID)
|
|
m_note.SetNote(note);
|
|
};
|
|
discord.signal_note_update().connect(sigc::track_obj(note_update_cb, m_note));
|
|
|
|
auto fetch_note_cb = [this](const std::string ¬e) {
|
|
m_note.SetNote(note);
|
|
};
|
|
discord.FetchUserNote(UserID, sigc::track_obj(fetch_note_cb, *this));
|
|
|
|
m_created.set_halign(Gtk::ALIGN_START);
|
|
m_created.set_margin_top(5);
|
|
m_created.set_text("Account created: " + ID.GetLocalTimestamp());
|
|
|
|
m_conns.set_halign(Gtk::ALIGN_START);
|
|
m_conns.set_hexpand(true);
|
|
|
|
add(m_created);
|
|
add(m_note);
|
|
add(m_conns);
|
|
show_all_children();
|
|
}
|
|
|
|
void ProfileUserInfoPane::SetConnections(const std::vector<ConnectionData> &connections) {
|
|
m_conns.SetConnections(connections);
|
|
}
|