fix up a bunch of clang-tidy stuff

mostly changing references, which i hope doesnt break stuff with models (TreeRow, iterators) since they gave me some strange problems in the past
This commit is contained in:
ouwou 2022-04-05 22:01:53 -04:00
parent 9767e1e7fd
commit 49685c3989
75 changed files with 518 additions and 709 deletions

View File

@ -63,14 +63,14 @@ int Abaddon::StartGTK() {
m_gtk_app = Gtk::Application::create("com.github.uowuo.abaddon");
m_css_provider = Gtk::CssProvider::create();
m_css_provider->signal_parsing_error().connect([this](const Glib::RefPtr<const Gtk::CssSection> &section, const Glib::Error &error) {
m_css_provider->signal_parsing_error().connect([](const Glib::RefPtr<const Gtk::CssSection> &section, const Glib::Error &error) {
Gtk::MessageDialog dlg("css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
dlg.run();
});
m_css_low_provider = Gtk::CssProvider::create();
m_css_low_provider->signal_parsing_error().connect([this](const Glib::RefPtr<const Gtk::CssSection> &section, const Glib::Error &error) {
m_css_low_provider->signal_parsing_error().connect([](const Glib::RefPtr<const Gtk::CssSection> &section, const Glib::Error &error) {
Gtk::MessageDialog dlg("low-priority css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
dlg.run();
@ -165,7 +165,7 @@ void Abaddon::OnShutdown() {
void Abaddon::LoadFromSettings() {
std::string token = GetSettings().DiscordToken;
if (token.size()) {
if (!token.empty()) {
m_discord_token = token;
m_discord.UpdateToken(m_discord_token);
}
@ -292,7 +292,7 @@ void Abaddon::ShowUserMenu(const GdkEvent *event, Snowflake id, Snowflake guild_
delete child;
if (guild.has_value() && user.has_value()) {
const auto roles = user->GetSortedRoles();
m_user_menu_roles->set_visible(roles.size() > 0);
m_user_menu_roles->set_visible(!roles.empty());
for (const auto &role : roles) {
auto *item = Gtk::manage(new Gtk::MenuItem(role.Name));
if (role.Color != 0) {
@ -691,7 +691,7 @@ void Abaddon::ActionSetStatus() {
const auto status = dlg.GetStatusType();
const auto activity_type = dlg.GetActivityType();
const auto activity_name = dlg.GetActivityName();
if (activity_name == "") {
if (activity_name.empty()) {
m_discord.UpdateStatus(status, false);
} else {
ActivityData activity;

View File

@ -14,14 +14,15 @@
class Abaddon {
private:
Abaddon();
public:
static Abaddon &Get();
Abaddon(const Abaddon &) = delete;
Abaddon &operator=(const Abaddon &) = delete;
Abaddon(Abaddon &&) = delete;
Abaddon &operator=(Abaddon &&) = delete;
public:
static Abaddon &Get();
int StartGTK();
void OnShutdown();

View File

@ -10,8 +10,6 @@ CellRendererPixbufAnimation::CellRendererPixbufAnimation()
property_ypad() = 2;
}
CellRendererPixbufAnimation::~CellRendererPixbufAnimation() {}
Glib::PropertyProxy<Glib::RefPtr<Gdk::Pixbuf>> CellRendererPixbufAnimation::property_pixbuf() {
return m_property_pixbuf.get_proxy();
}

View File

@ -6,7 +6,7 @@
class CellRendererPixbufAnimation : public Gtk::CellRenderer {
public:
CellRendererPixbufAnimation();
virtual ~CellRendererPixbufAnimation();
~CellRendererPixbufAnimation() override = default;
Glib::PropertyProxy<Glib::RefPtr<Gdk::Pixbuf>> property_pixbuf();
Glib::PropertyProxy<Glib::RefPtr<Gdk::PixbufAnimation>> property_pixbuf_animation();

View File

@ -291,7 +291,7 @@ void ChannelList::UpdateChannel(Snowflake id) {
auto channel = Abaddon::Get().GetDiscordClient().GetChannel(id);
if (!iter || !channel.has_value()) return;
if (channel->Type == ChannelType::GUILD_CATEGORY) return UpdateChannelCategory(*channel);
if (!IsTextChannel(channel->Type)) return;
if (!channel->IsText()) return;
// refresh stuff that might have changed
const bool is_orphan_TMP = !channel->ParentID.has_value();
@ -399,7 +399,7 @@ void ChannelList::OnThreadListSync(const ThreadListSyncData &data) {
queue.pop();
if ((*item)[m_columns.m_type] == RenderType::Thread)
threads.push_back(static_cast<Snowflake>((*item)[m_columns.m_id]));
for (auto child : item->children())
for (const auto& child : item->children())
queue.push(child);
}
@ -580,7 +580,7 @@ Gtk::TreeModel::iterator ChannelList::AddGuild(const GuildData &guild) {
if (thread.has_value())
threads[*thread->ParentID].push_back(*thread);
}
const auto add_threads = [&](const ChannelData &channel, Gtk::TreeRow row) {
const auto add_threads = [&](const ChannelData &channel, const Gtk::TreeRow& row) {
row[m_columns.m_expanded] = true;
const auto it = threads.find(channel.ID);
@ -648,7 +648,7 @@ Gtk::TreeModel::iterator ChannelList::CreateThreadRow(const Gtk::TreeNodeChildre
thread_row[m_columns.m_type] = RenderType::Thread;
thread_row[m_columns.m_id] = channel.ID;
thread_row[m_columns.m_name] = "- " + Glib::Markup::escape_text(*channel.Name);
thread_row[m_columns.m_sort] = channel.ID;
thread_row[m_columns.m_sort] = static_cast<int64_t>(channel.ID);
thread_row[m_columns.m_nsfw] = false;
return thread_iter;
@ -692,7 +692,7 @@ bool ChannelList::IsTextChannel(ChannelType type) {
}
// this should be unncessary but something is behaving strange so its just in case
void ChannelList::OnRowCollapsed(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) {
void ChannelList::OnRowCollapsed(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) const {
(*iter)[m_columns.m_expanded] = false;
}
@ -737,14 +737,14 @@ void ChannelList::AddPrivateChannels() {
std::optional<UserData> top_recipient;
const auto recipients = dm->GetDMRecipients();
if (recipients.size() > 0)
if (!recipients.empty())
top_recipient = recipients[0];
auto iter = m_model->append(header_row->children());
auto row = *iter;
row[m_columns.m_type] = RenderType::DM;
row[m_columns.m_id] = dm_id;
row[m_columns.m_sort] = -(dm->LastMessageID.has_value() ? *dm->LastMessageID : dm_id);
row[m_columns.m_sort] = static_cast<int64_t>(-(dm->LastMessageID.has_value() ? *dm->LastMessageID : dm_id));
row[m_columns.m_icon] = img.GetPlaceholder(DMIconSize);
if (dm->Type == ChannelType::DM && top_recipient.has_value())
@ -781,7 +781,7 @@ void ChannelList::UpdateCreateDMChannel(const ChannelData &dm) {
auto row = *iter;
row[m_columns.m_type] = RenderType::DM;
row[m_columns.m_id] = dm.ID;
row[m_columns.m_sort] = -(dm.LastMessageID.has_value() ? *dm.LastMessageID : dm.ID);
row[m_columns.m_sort] = static_cast<int64_t>(-(dm.LastMessageID.has_value() ? *dm.LastMessageID : dm.ID));
row[m_columns.m_icon] = img.GetPlaceholder(DMIconSize);
if (dm.Type == ChannelType::DM && top_recipient.has_value())
@ -817,7 +817,7 @@ void ChannelList::OnMessageCreate(const Message &msg) {
if (!channel.has_value()) return;
if (channel->Type == ChannelType::DM || channel->Type == ChannelType::GROUP_DM) {
if (iter)
(*iter)[m_columns.m_sort] = -msg.ID;
(*iter)[m_columns.m_sort] = static_cast<int64_t>(-msg.ID);
}
if (channel->GuildID.has_value())
if ((iter = GetIteratorForGuildFromID(*channel->GuildID)))
@ -826,7 +826,7 @@ void ChannelList::OnMessageCreate(const Message &msg) {
bool ChannelList::OnButtonPressEvent(GdkEventButton *ev) {
if (ev->button == GDK_BUTTON_SECONDARY && ev->type == GDK_BUTTON_PRESS) {
if (m_view.get_path_at_pos(ev->x, ev->y, m_path_for_menu)) {
if (m_view.get_path_at_pos(static_cast<int>(ev->x), static_cast<int>(ev->y), m_path_for_menu)) {
auto row = (*m_model->get_iter(m_path_for_menu));
switch (static_cast<RenderType>(row[m_columns.m_type])) {
case RenderType::Guild:

View File

@ -84,7 +84,7 @@ protected:
bool IsTextChannel(ChannelType type);
void OnRowCollapsed(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
void OnRowCollapsed(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path) const;
void OnRowExpanded(const Gtk::TreeModel::iterator &iter, const Gtk::TreeModel::Path &path);
bool SelectionFunc(const Glib::RefPtr<Gtk::TreeModel> &model, const Gtk::TreeModel::Path &path, bool is_currently_selected);
bool OnButtonPressEvent(GdkEventButton *ev);

View File

@ -27,9 +27,6 @@ CellRendererChannels::CellRendererChannels()
});
}
CellRendererChannels::~CellRendererChannels() {
}
Glib::PropertyProxy<RenderType> CellRendererChannels::property_type() {
return m_property_type.get_proxy();
}
@ -212,7 +209,10 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
const double text_w = text_natural.width;
const double text_h = text_natural.height;
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
Gdk::Rectangle text_cell_area(static_cast<int>(text_x),
static_cast<int>(text_y),
static_cast<int>(text_w),
static_cast<int>(text_h));
static const auto color = Gdk::RGBA(Abaddon::Get().GetSettings().ChannelColor);
m_renderer_text.property_foreground_rgba() = color;
@ -231,7 +231,11 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
const auto cb = [this, &widget, anim, icon_x, icon_y, icon_w, icon_h] {
if (m_pixbuf_anim_iters.at(anim)->advance())
widget.queue_draw_area(icon_x, icon_y, icon_w, icon_h);
widget.queue_draw_area(
static_cast<int>(icon_x),
static_cast<int>(icon_y),
static_cast<int>(icon_w),
static_cast<int>(icon_h));
};
if ((hover_only && is_hovered) || !hover_only)
@ -264,12 +268,12 @@ void CellRendererChannels::render_vfunc_guild(const Cairo::RefPtr<Cairo::Context
const auto y = background_area.get_y();
const auto w = background_area.get_width();
const auto h = background_area.get_height();
cr->rectangle(x, y + h / 2 - 24 / 2, 3, 24);
cr->rectangle(x, y + h / 2.0 - 24.0 / 2.0, 3.0, 24.0);
cr->fill();
}
if (total_mentions < 1) return;
auto *paned = static_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
auto *paned = dynamic_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
if (paned != nullptr) {
const auto edge = std::min(paned->get_position(), background_area.get_width());
@ -415,7 +419,7 @@ void CellRendererChannels::render_vfunc_channel(const Cairo::RefPtr<Cairo::Conte
}
if (unread_state < 1) return;
auto *paned = static_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
auto *paned = dynamic_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
if (paned != nullptr) {
const auto edge = std::min(paned->get_position(), cell_area.get_width());
@ -487,7 +491,7 @@ void CellRendererChannels::render_vfunc_thread(const Cairo::RefPtr<Cairo::Contex
}
if (unread_state < 1) return;
auto *paned = static_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
auto *paned = dynamic_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
if (paned != nullptr) {
const auto edge = std::min(paned->get_position(), cell_area.get_width());
@ -522,7 +526,7 @@ void CellRendererChannels::render_vfunc_dmheader(const Cairo::RefPtr<Cairo::Cont
if (!Abaddon::Get().GetSettings().Unreads) return;
auto *paned = static_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
auto *paned = dynamic_cast<Gtk::Paned *>(widget.get_ancestor(Gtk::Paned::get_type()));
if (paned != nullptr) {
const auto edge = std::min(paned->get_position(), background_area.get_width());
if (const auto unread = Abaddon::Get().GetDiscordClient().GetUnreadDMsCount(); unread > 0)
@ -587,7 +591,10 @@ void CellRendererChannels::render_vfunc_dm(const Cairo::RefPtr<Cairo::Context> &
const double text_w = text_natural.width;
const double text_h = text_natural.height;
Gdk::Rectangle text_cell_area(text_x, text_y, text_w, text_h);
Gdk::Rectangle text_cell_area(static_cast<int>(text_x),
static_cast<int>(text_y),
static_cast<int>(text_w),
static_cast<int>(text_h));
auto &discord = Abaddon::Get().GetDiscordClient();
const auto id = m_property_id.get_value();

View File

@ -18,7 +18,7 @@ enum class RenderType : uint8_t {
class CellRendererChannels : public Gtk::CellRenderer {
public:
CellRendererChannels();
virtual ~CellRendererChannels();
~CellRendererChannels() override = default;
Glib::PropertyProxy<RenderType> property_type();
Glib::PropertyProxy<uint64_t> property_id();
@ -106,7 +106,7 @@ protected:
Gtk::CellRendererState flags);
static void cairo_path_rounded_rect(const Cairo::RefPtr<Cairo::Context> &cr, double x, double y, double w, double h, double r);
void unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area);
static void unread_render_mentions(const Cairo::RefPtr<Cairo::Context> &cr, Gtk::Widget &widget, int mentions, int edge, const Gdk::Rectangle &cell_area);
private:
Gtk::CellRendererText m_renderer_text;

View File

@ -84,14 +84,14 @@ void ChatInputIndicator::OnMessageCreate(const Message &message) {
void ChatInputIndicator::SetTypingString(const Glib::ustring &str) {
m_label.set_text(str);
if (str == "")
if (str.empty())
m_img.hide();
else if (m_img.property_pixbuf_animation().get_value())
m_img.show();
}
void ChatInputIndicator::ComputeTypingString() {
if (m_custom_markup != "") {
if (!m_custom_markup.empty()) {
m_label.set_markup(m_custom_markup);
m_img.hide();
return;
@ -104,7 +104,7 @@ void ChatInputIndicator::ComputeTypingString() {
if (user.has_value())
typers.push_back(*user);
}
if (typers.size() == 0) {
if (typers.empty()) {
SetTypingString("");
} else if (typers.size() == 1) {
SetTypingString(typers[0].Username + " is typing...");

View File

@ -30,7 +30,7 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(const Message &d
if (data.Nonce.has_value())
container->Nonce = *data.Nonce;
if (data.Content.size() > 0 || data.Type != MessageType::DEFAULT) {
if (!data.Content.empty() || data.Type != MessageType::DEFAULT) {
container->m_text_component = container->CreateTextComponent(data);
container->AttachEventHandlers(*container->m_text_component);
container->m_main.add(*container->m_text_component);
@ -78,7 +78,7 @@ ChatMessageItemContainer *ChatMessageItemContainer::FromMessage(const Message &d
container->m_main.add(*widget);
}
if (data.Reactions.has_value() && data.Reactions->size() > 0) {
if (data.Reactions.has_value() && !data.Reactions->empty()) {
container->m_reactions_component = container->CreateReactionsComponent(data);
container->m_main.add(*container->m_reactions_component);
}
@ -114,7 +114,7 @@ void ChatMessageItemContainer::UpdateReactions() {
}
const auto data = Abaddon::Get().GetDiscordClient().GetMessage(ID);
if (data->Reactions.has_value() && data->Reactions->size() > 0) {
if (data->Reactions.has_value() && !data->Reactions->empty()) {
m_reactions_component = CreateReactionsComponent(*data);
m_reactions_component->show_all();
m_main.add(*m_reactions_component);
@ -150,7 +150,7 @@ void ChatMessageItemContainer::UpdateAttributes() {
m_attrib_label->set_markup("<span color='#999999'>[edited]</span>");
}
void ChatMessageItemContainer::AddClickHandler(Gtk::Widget *widget, std::string url) {
void ChatMessageItemContainer::AddClickHandler(Gtk::Widget *widget, const std::string &url) {
// clang-format off
widget->signal_button_press_event().connect([url](GdkEventButton *event) -> bool {
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) {
@ -224,13 +224,13 @@ void ChatMessageItemContainer::UpdateTextComponent(Gtk::TextView *tv) {
}
} break;
case MessageType::RECIPIENT_ADD: {
if (data->Mentions.size() == 0) break;
if (data->Mentions.empty()) break;
const auto &adder = Abaddon::Get().GetDiscordClient().GetUser(data->Author.ID);
const auto &added = data->Mentions[0];
b->insert_markup(s, "<i><span color='#999999'><span color='#eeeeee'>" + adder->Username + "</span> added <span color='#eeeeee'>" + added.Username + "</span></span></i>");
} break;
case MessageType::RECIPIENT_REMOVE: {
if (data->Mentions.size() == 0) break;
if (data->Mentions.empty()) break;
const auto &adder = Abaddon::Get().GetDiscordClient().GetUser(data->Author.ID);
const auto &added = data->Mentions[0];
if (adder->ID == added.ID)
@ -361,7 +361,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb
if (embed.URL.has_value()) {
AddPointerCursor(*title_ev);
auto url = *embed.URL;
title_ev->signal_button_press_event().connect([this, url = std::move(url)](GdkEventButton *event) -> bool {
title_ev->signal_button_press_event().connect([url = std::move(url)](GdkEventButton *event) -> bool {
if (event->button == GDK_BUTTON_PRIMARY) {
LaunchBrowser(url);
return true;
@ -389,7 +389,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateEmbedComponent(const EmbedData &emb
}
// todo: handle inline fields
if (embed.Fields.has_value() && embed.Fields->size() > 0) {
if (embed.Fields.has_value() && !embed.Fields->empty()) {
auto *flow = Gtk::manage(new Gtk::FlowBox);
flow->set_orientation(Gtk::ORIENTATION_HORIZONTAL);
flow->set_min_children_per_line(3);
@ -516,23 +516,6 @@ Gtk::Widget *ChatMessageItemContainer::CreateAttachmentComponent(const Attachmen
return ev;
}
Gtk::Widget *ChatMessageItemContainer::CreateStickerComponentDeprecated(const StickerData &data) {
auto *box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL));
auto *imgw = Gtk::manage(new Gtk::Image);
box->add(*imgw);
auto &img = Abaddon::Get().GetImageManager();
if (data.FormatType == StickerFormatType::PNG || data.FormatType == StickerFormatType::APNG) {
auto cb = [this, imgw](const Glib::RefPtr<Gdk::Pixbuf> &pixbuf) {
imgw->property_pixbuf() = pixbuf;
};
img.LoadFromURL(data.GetURL(), sigc::track_obj(cb, *imgw));
}
AttachEventHandlers(*box);
return box;
}
Gtk::Widget *ChatMessageItemContainer::CreateStickersComponent(const std::vector<StickerItem> &data) {
auto *box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
@ -608,7 +591,7 @@ Gtk::Widget *ChatMessageItemContainer::CreateReactionsComponent(const Message &d
// image
if (is_stock) { // unicode/stock
const auto shortcode = emojis.GetShortCodeForPattern(reaction.Emoji.Name);
if (shortcode != "")
if (!shortcode.empty())
ev->set_tooltip_text(shortcode);
const auto &pb = emojis.GetPixBuf(reaction.Emoji.Name);
@ -784,7 +767,7 @@ void ChatMessageItemContainer::HandleRoleMentions(const Glib::RefPtr<Gtk::TextBu
}
}
void ChatMessageItemContainer::HandleUserMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf) {
void ChatMessageItemContainer::HandleUserMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf) const {
constexpr static const auto mentions_regex = R"(<@!?(\d+)>)";
static auto rgx = Glib::Regex::create(mentions_regex);
@ -861,7 +844,7 @@ void ChatMessageItemContainer::HandleCustomEmojis(Gtk::TextView &tv) {
const auto mark_start = buf->create_mark(start_it, false);
end_it.backward_char();
const auto mark_end = buf->create_mark(end_it, false);
const auto cb = [this, &tv, buf, mark_start, mark_end](const Glib::RefPtr<Gdk::PixbufAnimation> &pixbuf) {
const auto cb = [&tv, buf, mark_start, mark_end](const Glib::RefPtr<Gdk::PixbufAnimation> &pixbuf) {
auto start_it = mark_start->get_iter();
auto end_it = mark_end->get_iter();
end_it.forward_char();
@ -879,7 +862,7 @@ void ChatMessageItemContainer::HandleCustomEmojis(Gtk::TextView &tv) {
const auto mark_start = buf->create_mark(start_it, false);
end_it.backward_char();
const auto mark_end = buf->create_mark(end_it, false);
const auto cb = [this, buf, mark_start, mark_end](const Glib::RefPtr<Gdk::Pixbuf> &pixbuf) {
const auto cb = [buf, mark_start, mark_end](const Glib::RefPtr<Gdk::Pixbuf> &pixbuf) {
auto start_it = mark_start->get_iter();
auto end_it = mark_end->get_iter();
end_it.forward_char();
@ -902,7 +885,7 @@ void ChatMessageItemContainer::HandleEmojis(Gtk::TextView &tv) {
if (Abaddon::Get().GetSettings().ShowCustomEmojis) HandleCustomEmojis(tv);
}
void ChatMessageItemContainer::CleanupEmojis(Glib::RefPtr<Gtk::TextBuffer> buf) {
void ChatMessageItemContainer::CleanupEmojis(const Glib::RefPtr<Gtk::TextBuffer> &buf) {
static auto rgx = Glib::Regex::create(R"(<a?:([\w\d_]+):(\d+)>)");
auto text = GetText(buf);
@ -922,9 +905,9 @@ void ChatMessageItemContainer::CleanupEmojis(Glib::RefPtr<Gtk::TextBuffer> buf)
startpos = mend;
const auto it = buf->erase(start_it, end_it);
const int alen = text.size();
const int alen = static_cast<int>(text.size());
text = GetText(buf);
const int blen = text.size();
const int blen = static_cast<int>(text.size());
startpos -= (alen - blen);
buf->insert(it, new_term);
@ -933,7 +916,7 @@ void ChatMessageItemContainer::CleanupEmojis(Glib::RefPtr<Gtk::TextBuffer> buf)
}
}
void ChatMessageItemContainer::HandleChannelMentions(Glib::RefPtr<Gtk::TextBuffer> buf) {
void ChatMessageItemContainer::HandleChannelMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf) {
static auto rgx = Glib::Regex::create(R"(<#(\d+)>)");
Glib::ustring text = GetText(buf);
@ -990,12 +973,12 @@ bool ChatMessageItemContainer::OnClickChannel(GdkEventButton *ev) {
return false;
int x, y;
m_text_component->window_to_buffer_coords(Gtk::TEXT_WINDOW_WIDGET, ev->x, ev->y, x, y);
m_text_component->window_to_buffer_coords(Gtk::TEXT_WINDOW_WIDGET, static_cast<int>(ev->x), static_cast<int>(ev->y), x, y);
Gtk::TextBuffer::iterator iter;
m_text_component->get_iter_at_location(iter, x, y);
const auto tags = iter.get_tags();
for (auto tag : tags) {
for (const auto &tag : tags) {
const auto it = m_channel_tagmap.find(tag);
if (it != m_channel_tagmap.end()) {
m_signal_action_channel_click.emit(it->second);
@ -1053,12 +1036,12 @@ bool ChatMessageItemContainer::OnLinkClick(GdkEventButton *ev) {
return false;
int x, y;
m_text_component->window_to_buffer_coords(Gtk::TEXT_WINDOW_WIDGET, ev->x, ev->y, x, y);
m_text_component->window_to_buffer_coords(Gtk::TEXT_WINDOW_WIDGET, static_cast<int>(ev->x), static_cast<int>(ev->y), x, y);
Gtk::TextBuffer::iterator iter;
m_text_component->get_iter_at_location(iter, x, y);
const auto tags = iter.get_tags();
for (auto tag : tags) {
for (const auto &tag : tags) {
const auto it = m_link_tagmap.find(tag);
if (it != m_link_tagmap.end()) {
if (ev->button == GDK_BUTTON_PRIMARY) {

View File

@ -19,14 +19,13 @@ public:
void SetFailed();
protected:
void AddClickHandler(Gtk::Widget *widget, std::string);
static void AddClickHandler(Gtk::Widget *widget, const std::string &);
Gtk::TextView *CreateTextComponent(const Message &data); // Message.Content
void UpdateTextComponent(Gtk::TextView *tv);
Gtk::Widget *CreateEmbedsComponent(const std::vector<EmbedData> &embeds);
Gtk::Widget *CreateEmbedComponent(const EmbedData &data); // Message.Embeds[0]
static Gtk::Widget *CreateEmbedComponent(const EmbedData &data); // Message.Embeds[0]
Gtk::Widget *CreateImageComponent(const std::string &proxy_url, const std::string &url, int inw, int inh);
Gtk::Widget *CreateAttachmentComponent(const AttachmentData &data); // non-image attachments
Gtk::Widget *CreateStickerComponentDeprecated(const StickerData &data);
Gtk::Widget *CreateStickersComponent(const std::vector<StickerItem> &data);
Gtk::Widget *CreateReactionsComponent(const Message &data);
Gtk::Widget *CreateReplyComponent(const Message &data);
@ -35,14 +34,14 @@ protected:
static bool IsEmbedImageOnly(const EmbedData &data);
void HandleRoleMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf);
void HandleUserMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf);
void HandleStockEmojis(Gtk::TextView &tv);
void HandleCustomEmojis(Gtk::TextView &tv);
void HandleEmojis(Gtk::TextView &tv);
void CleanupEmojis(Glib::RefPtr<Gtk::TextBuffer> buf);
static void HandleRoleMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf);
void HandleUserMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf) const;
static void HandleStockEmojis(Gtk::TextView &tv);
static void HandleCustomEmojis(Gtk::TextView &tv);
static void HandleEmojis(Gtk::TextView &tv);
static void CleanupEmojis(const Glib::RefPtr<Gtk::TextBuffer> &buf);
void HandleChannelMentions(Glib::RefPtr<Gtk::TextBuffer> buf);
void HandleChannelMentions(const Glib::RefPtr<Gtk::TextBuffer> &buf);
void HandleChannelMentions(Gtk::TextView *tv);
bool OnClickChannel(GdkEventButton *ev);

View File

@ -1,5 +1,4 @@
#include "chatwindow.hpp"
#include "chatmessage.hpp"
#include "abaddon.hpp"
#include "chatinputindicator.hpp"
#include "ratelimitindicator.hpp"
@ -134,7 +133,7 @@ void ChatWindow::AddNewHistory(const std::vector<Message> &msgs) {
m_chat->PrependMessages(msgs.crbegin(), msgs.crend());
}
void ChatWindow::InsertChatInput(std::string text) {
void ChatWindow::InsertChatInput(const std::string &text) {
m_input->InsertText(text);
}
@ -159,7 +158,7 @@ bool ChatWindow::OnInputSubmit(const Glib::ustring &text) {
if (!m_rate_limit_indicator->CanSpeak())
return false;
if (text.size() == 0)
if (text.empty())
return false;
if (m_active_channel.IsValid())

View File

@ -25,7 +25,7 @@ public:
void DeleteMessage(Snowflake id); // add [deleted] indicator
void UpdateMessage(Snowflake id); // add [edited] indicator
void AddNewHistory(const std::vector<Message> &msgs); // prepend messages
void InsertChatInput(std::string text);
void InsertChatInput(const std::string& text);
Snowflake GetOldestListedMessage(); // oldest message that is currently in the ListBox
void UpdateReactions(Snowflake id);
void SetTopic(const std::string &text);

View File

@ -1,4 +1,5 @@
#include <unordered_set>
#include <utility>
#include "completer.hpp"
#include "abaddon.hpp"
#include "util.hpp"
@ -46,7 +47,7 @@ bool Completer::ProcessKeyPress(GdkEventKey *e) {
switch (e->keyval) {
case GDK_KEY_Down: {
if (m_entries.size() == 0) return true;
if (m_entries.empty()) return true;
const auto index = static_cast<size_t>(m_list.get_selected_row()->get_index());
if (index >= m_entries.size() - 1) return true;
m_list.select_row(*m_entries[index + 1]);
@ -54,7 +55,7 @@ bool Completer::ProcessKeyPress(GdkEventKey *e) {
}
return true;
case GDK_KEY_Up: {
if (m_entries.size() == 0) return true;
if (m_entries.empty()) return true;
const auto index = static_cast<size_t>(m_list.get_selected_row()->get_index());
if (index == 0) return true;
m_list.select_row(*m_entries[index - 1]);
@ -62,7 +63,7 @@ bool Completer::ProcessKeyPress(GdkEventKey *e) {
}
return true;
case GDK_KEY_Return: {
if (m_entries.size() == 0) return true;
if (m_entries.empty()) return true;
DoCompletion(m_list.get_selected_row());
}
return true;
@ -74,11 +75,11 @@ bool Completer::ProcessKeyPress(GdkEventKey *e) {
}
void Completer::SetGetRecentAuthors(get_recent_authors_cb cb) {
m_recent_authors_cb = cb;
m_recent_authors_cb = std::move(cb);
}
void Completer::SetGetChannelID(get_channel_id_cb cb) {
m_channel_id_cb = cb;
m_channel_id_cb = std::move(cb);
}
bool Completer::IsShown() const {
@ -86,7 +87,7 @@ bool Completer::IsShown() const {
}
CompleterEntry *Completer::CreateEntry(const Glib::ustring &completion) {
auto entry = Gtk::manage(new CompleterEntry(completion, m_entries.size()));
auto entry = Gtk::manage(new CompleterEntry(completion, static_cast<int>(m_entries.size())));
m_entries.push_back(entry);
entry->show_all();
m_list.add(*entry);
@ -152,7 +153,7 @@ void Completer::CompleteEmojis(const Glib::ustring &term) {
const auto make_entry = [&](const Glib::ustring &name, const Glib::ustring &completion, const Glib::ustring &url = "", bool animated = false) -> CompleterEntry * {
const auto entry = CreateEntry(completion);
entry->SetText(name);
if (url == "") return entry;
if (url.empty()) return entry;
if (animated)
entry->SetAnimation(url);
else
@ -173,8 +174,8 @@ void Completer::CompleteEmojis(const Glib::ustring &term) {
const auto emoji = *discord.GetEmoji(tmp.ID);
if (emoji.IsAnimated.has_value() && *emoji.IsAnimated) continue;
if (emoji.IsAvailable.has_value() && !*emoji.IsAvailable) continue;
if (emoji.Roles.has_value() && emoji.Roles->size() > 0) continue;
if (term.size() > 0)
if (emoji.Roles.has_value() && !emoji.Roles->empty()) continue;
if (!term.empty())
if (!StringContainsCaseless(emoji.Name, term)) continue;
if (i++ > MaxCompleterEntries) break;
@ -190,8 +191,8 @@ void Completer::CompleteEmojis(const Glib::ustring &term) {
const auto emoji = *discord.GetEmoji(tmp.ID);
const bool is_animated = emoji.IsAnimated.has_value() && *emoji.IsAnimated;
if (emoji.IsAvailable.has_value() && !*emoji.IsAvailable) continue;
if (emoji.Roles.has_value() && emoji.Roles->size() > 0) continue;
if (term.size() > 0)
if (emoji.Roles.has_value() && !emoji.Roles->empty()) continue;
if (!term.empty())
if (!StringContainsCaseless(emoji.Name, term)) continue;
if (i++ > MaxCompleterEntries) goto done;
@ -275,7 +276,7 @@ void Completer::OnTextBufferChanged() {
default:
break;
}
if (m_entries.size() > 0) {
if (!m_entries.empty()) {
m_list.select_row(*m_entries[0]);
set_reveal_child(true);
} else {
@ -329,8 +330,8 @@ Glib::ustring Completer::GetTerm() {
return m_start.get_text(m_end);
}
CompleterEntry::CompleterEntry(const Glib::ustring &completion, int index)
: m_completion(completion)
CompleterEntry::CompleterEntry(Glib::ustring completion, int index)
: m_completion(std::move(completion))
, m_index(index)
, m_box(Gtk::ORIENTATION_HORIZONTAL) {
set_halign(Gtk::ALIGN_START);

View File

@ -8,7 +8,7 @@ constexpr static int CompleterImageSize = 24;
class CompleterEntry : public Gtk::ListBoxRow {
public:
CompleterEntry(const Glib::ustring &completion, int index);
CompleterEntry(Glib::ustring completion, int index);
void SetTextColor(int color); // SetText will reset
void SetText(const Glib::ustring &text);
void SetImage(const Glib::RefPtr<Gdk::Pixbuf> &pb);

View File

@ -102,7 +102,7 @@ bool DragListBox::scroll() {
}
void DragListBox::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &context, int x, int y, const Gtk::SelectionData &selection_data, guint info, guint time) {
int index = 0;
int index;
if (m_hover_row != nullptr) {
if (m_top) {
index = m_hover_row->get_index() - 1;
@ -130,7 +130,7 @@ void DragListBox::on_drag_data_received(const Glib::RefPtr<Gdk::DragContext> &co
void DragListBox::add_draggable(Gtk::ListBoxRow *widget) {
widget->drag_source_set(m_entries, Gdk::BUTTON1_MASK, Gdk::ACTION_MOVE);
widget->signal_drag_begin().connect(sigc::bind<0>(sigc::mem_fun(*this, &DragListBox::row_drag_begin), widget));
widget->signal_drag_data_get().connect([this, widget](const Glib::RefPtr<Gdk::DragContext> &context, Gtk::SelectionData &selection_data, guint info, guint time) {
widget->signal_drag_data_get().connect([widget](const Glib::RefPtr<Gdk::DragContext> &context, Gtk::SelectionData &selection_data, guint info, guint time) {
selection_data.set("GTK_LIST_BOX_ROW", 32, reinterpret_cast<const guint8 *>(&widget), sizeof(&widget));
});
add(*widget);

View File

@ -133,7 +133,7 @@ void FriendsList::OnActionRemove(Snowflake id) {
break;
}
if (Abaddon::Get().ShowConfirm(str, window)) {
const auto cb = [this, window](DiscordError code) {
const auto cb = [window](DiscordError code) {
if (code == DiscordError::NONE) return;
Gtk::MessageDialog dlg(*window, "Failed to remove user", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -215,7 +215,7 @@ void FriendsListAddComponent::Submit() {
if (hashpos == Glib::ustring::npos) return;
const auto username = text.substr(0, hashpos);
const auto discriminator = text.substr(hashpos + 1);
if (username.size() == 0 || discriminator.size() != 4) return;
if (username.empty() || discriminator.size() != 4) return;
if (discriminator.find_first_not_of("0123456789") != Glib::ustring::npos) return;
m_requesting = true;
@ -229,7 +229,9 @@ void FriendsListAddComponent::Submit() {
m_label.set_text("Failed: "s + GetDiscordErrorDisplayString(code));
}
};
Abaddon::Get().GetDiscordClient().SendFriendRequest(username, std::stoul(discriminator), sigc::track_obj(cb, *this));
Abaddon::Get().GetDiscordClient().SendFriendRequest(username,
static_cast<int>(std::stoul(discriminator)),
sigc::track_obj(cb, *this));
}
bool FriendsListAddComponent::OnKeyPress(GdkEventKey *e) {

View File

@ -1,4 +1,6 @@
#include "lazyimage.hpp"
#include <utility>
#include "abaddon.hpp"
LazyImage::LazyImage(int w, int h, bool use_placeholder)
@ -9,8 +11,8 @@ LazyImage::LazyImage(int w, int h, bool use_placeholder)
signal_draw().connect(sigc::mem_fun(*this, &LazyImage::OnDraw));
}
LazyImage::LazyImage(const std::string &url, int w, int h, bool use_placeholder)
: m_url(url)
LazyImage::LazyImage(std::string url, int w, int h, bool use_placeholder)
: m_url(std::move(url))
, m_width(w)
, m_height(h) {
if (use_placeholder)
@ -27,7 +29,7 @@ void LazyImage::SetURL(const std::string &url) {
}
bool LazyImage::OnDraw(const Cairo::RefPtr<Cairo::Context> &context) {
if (!m_needs_request || m_url == "") return false;
if (!m_needs_request || m_url.empty()) return false;
m_needs_request = false;
if (m_animated) {

View File

@ -5,7 +5,7 @@
class LazyImage : public Gtk::Image {
public:
LazyImage(int w, int h, bool use_placeholder = true);
LazyImage(const std::string &url, int w, int h, bool use_placeholder = true);
LazyImage(std::string url, int w, int h, bool use_placeholder = true);
void SetAnimated(bool is_animated);
void SetURL(const std::string &url);

View File

@ -151,7 +151,7 @@ void MemberList::UpdateMemberList() {
if (!pos_role.has_value()) {
roleless_users.push_back(id);
continue;
};
}
pos_to_role[pos_role->Position] = *pos_role;
pos_to_users[pos_role->Position].push_back(std::move(*user));
@ -161,7 +161,7 @@ void MemberList::UpdateMemberList() {
int num_rows = 0;
const auto guild = *discord.GetGuild(m_guild_id);
auto add_user = [this, &user_to_color, &num_rows, guild](const UserData &data) -> bool {
auto add_user = [this, &num_rows, guild](const UserData &data) -> bool {
if (num_rows++ > MaxMemberListRows) return false;
auto *row = Gtk::manage(new MemberListUserRow(guild, data));
m_id_to_row[data.ID] = row;
@ -170,7 +170,7 @@ void MemberList::UpdateMemberList() {
return true;
};
auto add_role = [this](std::string name) {
auto add_role = [this](const std::string &name) {
auto *role_row = Gtk::manage(new Gtk::ListBoxRow);
auto *role_lbl = Gtk::manage(new Gtk::Label);
@ -215,7 +215,7 @@ void MemberList::UpdateMemberList() {
}
void MemberList::AttachUserMenuHandler(Gtk::ListBoxRow *row, Snowflake id) {
row->signal_button_press_event().connect([this, row, id](GdkEventButton *e) -> bool {
row->signal_button_press_event().connect([this, id](GdkEventButton *e) -> bool {
if (e->type == GDK_BUTTON_PRESS && e->button == GDK_BUTTON_SECONDARY) {
Abaddon::Get().ShowUserMenu(reinterpret_cast<const GdkEvent *>(e), id, m_guild_id);
return true;

View File

@ -66,7 +66,7 @@ int RateLimitIndicator::GetTimeLeft() const {
if (sec_diff <= 0)
return 0;
else
return sec_diff;
return static_cast<int>(sec_diff);
}
int RateLimitIndicator::GetRateLimit() const {

View File

@ -2,10 +2,6 @@
#include "abaddon.hpp"
static const constexpr int Diameter = 8;
static const auto OnlineColor = Gdk::RGBA("#43B581");
static const auto IdleColor = Gdk::RGBA("#FAA61A");
static const auto DNDColor = Gdk::RGBA("#982929");
static const auto OfflineColor = Gdk::RGBA("#808080");
StatusIndicator::StatusIndicator(Snowflake user_id)
: Glib::ObjectBase("statusindicator")
@ -26,9 +22,6 @@ StatusIndicator::StatusIndicator(Snowflake user_id)
CheckStatus();
}
StatusIndicator::~StatusIndicator() {
}
void StatusIndicator::CheckStatus() {
const auto status = Abaddon::Get().GetDiscordClient().GetUserStatus(m_id);
const auto last_status = m_status;
@ -121,7 +114,7 @@ bool StatusIndicator::on_draw(const Cairo::RefPtr<Cairo::Context> &cr) {
const auto color = get_style_context()->get_color(Gtk::STATE_FLAG_NORMAL);
cr->set_source_rgb(color.get_red(), color.get_green(), color.get_blue());
cr->arc(width / 2, height / 2, width / 3, 0.0, 2 * (4 * std::atan(1)));
cr->arc(width / 2.0, height / 2.0, width / 3.0, 0.0, 2 * (4 * std::atan(1)));
cr->close_path();
cr->fill_preserve();
cr->stroke();

View File

@ -6,7 +6,7 @@
class StatusIndicator : public Gtk::Widget {
public:
StatusIndicator(Snowflake user_id);
virtual ~StatusIndicator();
~StatusIndicator() override = default;
protected:
Gtk::SizeRequestMode get_request_mode_vfunc() const override;

View File

@ -10,7 +10,7 @@ public:
protected:
void on_entry_changed();
bool IsCode(std::string str);
static bool IsCode(std::string str);
Gtk::Box m_layout;
Gtk::Button m_ok;

View File

@ -116,5 +116,8 @@ std::vector<UserData> ChannelData::GetDMRecipients() const {
return ret;
}
return std::vector<UserData>();
return {};
}
bool ChannelData::IsText() const noexcept {
return Type == ChannelType::GUILD_TEXT || Type == ChannelType::GUILD_NEWS;
}

View File

@ -94,14 +94,15 @@ struct ChannelData {
friend void from_json(const nlohmann::json &j, ChannelData &m);
void update_from_json(const nlohmann::json &j);
bool NSFW() const;
bool IsDM() const noexcept;
bool IsThread() const noexcept;
bool IsJoinedThread() const;
bool IsCategory() const noexcept;
bool HasIcon() const noexcept;
std::string GetIconURL() const;
std::vector<Snowflake> GetChildIDs() const;
std::optional<PermissionOverwrite> GetOverwrite(Snowflake id) const;
std::vector<UserData> GetDMRecipients() const;
[[nodiscard]] bool NSFW() const;
[[nodiscard]] bool IsDM() const noexcept;
[[nodiscard]] bool IsThread() const noexcept;
[[nodiscard]] bool IsJoinedThread() const;
[[nodiscard]] bool IsCategory() const noexcept;
[[nodiscard]] bool IsText() const noexcept;
[[nodiscard]] bool HasIcon() const noexcept;
[[nodiscard]] std::string GetIconURL() const;
[[nodiscard]] std::vector<Snowflake> GetChildIDs() const;
[[nodiscard]] std::optional<PermissionOverwrite> GetOverwrite(Snowflake id) const;
[[nodiscard]] std::vector<UserData> GetDMRecipients() const;
};

View File

@ -1,8 +1,8 @@
#include "abaddon.hpp"
#include "discord.hpp"
#include "util.hpp"
#include <cassert>
#include <cinttypes>
#include <utility>
using namespace std::string_literals;
@ -68,10 +68,6 @@ bool DiscordClient::IsStoreValid() const {
return m_store.IsValid();
}
const UserSettings &DiscordClient::GetUserSettings() const {
return m_user_settings;
}
std::unordered_set<Snowflake> DiscordClient::GetGuilds() const {
return m_store.GetGuilds();
}
@ -87,7 +83,7 @@ std::vector<Snowflake> DiscordClient::GetUserSortedGuilds() const {
auto guilds = GetGuilds();
for (const auto &entry : m_user_settings.GuildFolders) { // can contain guilds not a part of
for (const auto &id : entry.GuildIDs) {
if (std::find(guilds.begin(), guilds.end(), id) != guilds.end())
if (guilds.find(id) != guilds.end())
folder_order.push_back(id);
}
}
@ -115,19 +111,19 @@ std::vector<Message> DiscordClient::GetMessagesBefore(Snowflake channel_id, Snow
return m_store.GetMessagesBefore(channel_id, message_id, limit);
}
void DiscordClient::FetchInvite(std::string code, sigc::slot<void(std::optional<InviteData>)> callback) {
m_http.MakeGET("/invites/" + code + "?with_counts=true", [this, callback](http::response_type r) {
void DiscordClient::FetchInvite(const std::string &code, const sigc::slot<void(std::optional<InviteData>)> &callback) {
m_http.MakeGET("/invites/" + code + "?with_counts=true", [callback](http::response_type r) {
if (!CheckCode(r)) {
if (r.status_code == 404)
callback(std::nullopt);
return;
};
}
callback(nlohmann::json::parse(r.text).get<InviteData>());
});
}
void DiscordClient::FetchMessagesInChannel(Snowflake id, sigc::slot<void(const std::vector<Message> &)> cb) {
void DiscordClient::FetchMessagesInChannel(Snowflake id, const sigc::slot<void(const std::vector<Message> &)> &cb) {
std::string path = "/channels/" + std::to_string(id) + "/messages?limit=50";
m_http.MakeGET(path, [this, id, cb](const http::response_type &r) {
if (!CheckCode(r)) {
@ -164,9 +160,9 @@ void DiscordClient::FetchMessagesInChannel(Snowflake id, sigc::slot<void(const s
});
}
void DiscordClient::FetchMessagesInChannelBefore(Snowflake channel_id, Snowflake before_id, sigc::slot<void(const std::vector<Message> &)> cb) {
void DiscordClient::FetchMessagesInChannelBefore(Snowflake channel_id, Snowflake before_id, const sigc::slot<void(const std::vector<Message> &)> &cb) {
std::string path = "/channels/" + std::to_string(channel_id) + "/messages?limit=50&before=" + std::to_string(before_id);
m_http.MakeGET(path, [this, channel_id, cb](http::response_type r) {
m_http.MakeGET(path, [this, cb](http::response_type r) {
if (!CheckCode(r)) return;
std::vector<Message> msgs;
@ -210,10 +206,6 @@ std::optional<GuildMember> DiscordClient::GetMember(Snowflake user_id, Snowflake
return m_store.GetGuildMember(guild_id, user_id);
}
std::optional<BanData> DiscordClient::GetBan(Snowflake guild_id, Snowflake user_id) const {
return m_store.GetBan(guild_id, user_id);
}
std::optional<PermissionOverwrite> DiscordClient::GetPermissionOverwrite(Snowflake channel_id, Snowflake id) const {
return m_store.GetPermissionOverwrite(channel_id, id);
}
@ -243,14 +235,14 @@ std::optional<RoleData> DiscordClient::GetMemberHighestRole(Snowflake guild_id,
const auto data = GetMember(user_id, guild_id);
if (!data.has_value()) return std::nullopt;
if (data->Roles.size() == 0) return std::nullopt;
if (data->Roles.empty()) return std::nullopt;
if (data->Roles.size() == 1) return GetRole(data->Roles[0]);
std::vector<RoleData> roles;
for (const auto id : data->Roles)
roles.push_back(*GetRole(id));
return *std::max_element(roles.begin(), roles.end(), [this](const auto &a, const auto &b) -> bool {
return *std::max_element(roles.begin(), roles.end(), [](const auto &a, const auto &b) -> bool {
return a.Position < b.Position;
});
}
@ -281,7 +273,7 @@ std::vector<ChannelData> DiscordClient::GetActiveThreads(Snowflake channel_id) c
return m_store.GetActiveThreads(channel_id);
}
void DiscordClient::GetArchivedPublicThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback) {
void DiscordClient::GetArchivedPublicThreads(Snowflake channel_id, const sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> &callback) {
m_http.MakeGET("/channels/" + std::to_string(channel_id) + "/threads/archived/public", [this, callback](const http::response_type &r) {
if (CheckCode(r)) {
const auto data = nlohmann::json::parse(r.text).get<ArchivedThreadsResponseData>();
@ -294,7 +286,7 @@ void DiscordClient::GetArchivedPublicThreads(Snowflake channel_id, sigc::slot<vo
});
}
void DiscordClient::GetArchivedPrivateThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback) {
void DiscordClient::GetArchivedPrivateThreads(Snowflake channel_id, const sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> &callback) {
m_http.MakeGET("/channels/" + std::to_string(channel_id) + "/users/@me/threads/archived/private", [this, callback](const http::response_type &r) {
if (CheckCode(r)) {
const auto data = nlohmann::json::parse(r.text).get<ArchivedThreadsResponseData>();
@ -411,7 +403,7 @@ bool DiscordClient::CanManageMember(Snowflake guild_id, Snowflake actor, Snowfla
return actor_highest->Position > target_highest->Position;
}
void DiscordClient::ChatMessageCallback(std::string nonce, const http::response_type &response) {
void DiscordClient::ChatMessageCallback(const std::string &nonce, const http::response_type &response) {
if (!CheckCode(response)) {
if (response.status_code == http::TooManyRequests) {
try { // not sure if this body is guaranteed
@ -481,7 +473,7 @@ void DiscordClient::DeleteMessage(Snowflake channel_id, Snowflake id) {
void DiscordClient::EditMessage(Snowflake channel_id, Snowflake id, std::string content) {
std::string path = "/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(id);
MessageEditObject obj;
obj.Content = content;
obj.Content = std::move(content);
nlohmann::json j = obj;
m_http.MakePATCH(path, j.dump(), [](auto) {});
}
@ -516,7 +508,7 @@ void DiscordClient::SendThreadLazyLoad(Snowflake id) {
m_websocket.Send(msg);
}
void DiscordClient::JoinGuild(std::string code) {
void DiscordClient::JoinGuild(const std::string &code) {
m_http.MakePOST("/invites/" + code, "{}", [](auto) {});
}
@ -554,14 +546,10 @@ void DiscordClient::UpdateStatus(PresenceStatus status, bool is_afk, const Activ
m_signal_presence_update.emit(GetUserData(), status);
}
void DiscordClient::CreateDM(Snowflake user_id) {
CreateDM(user_id, [](...) {});
}
void DiscordClient::CreateDM(Snowflake user_id, sigc::slot<void(DiscordError code, Snowflake channel_id)> callback) {
void DiscordClient::CreateDM(Snowflake user_id, const sigc::slot<void(DiscordError code, Snowflake channel_id)> &callback) {
CreateDMObject obj;
obj.Recipients.push_back(user_id);
m_http.MakePOST("/users/@me/channels", nlohmann::json(obj).dump(), [this, callback](const http::response &response) {
m_http.MakePOST("/users/@me/channels", nlohmann::json(obj).dump(), [callback](const http::response &response) {
if (!CheckCode(response)) {
callback(DiscordError::NONE, Snowflake::Invalid);
return;
@ -572,7 +560,7 @@ void DiscordClient::CreateDM(Snowflake user_id, sigc::slot<void(DiscordError cod
}
void DiscordClient::CloseDM(Snowflake channel_id) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id), [this](const http::response &response) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id), [](const http::response &response) {
CheckCode(response);
});
}
@ -617,14 +605,10 @@ void DiscordClient::RemoveReaction(Snowflake id, Glib::ustring param) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(id) + "/reactions/" + param + "/@me", [](auto) {});
}
void DiscordClient::SetGuildName(Snowflake id, const Glib::ustring &name) {
SetGuildName(id, name, [](auto) {});
}
void DiscordClient::SetGuildName(Snowflake id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::SetGuildName(Snowflake id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildObject obj;
obj.Name = name;
m_http.MakePATCH("/guilds/" + std::to_string(id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &r) {
m_http.MakePATCH("/guilds/" + std::to_string(id), nlohmann::json(obj).dump(), [callback](const http::response_type &r) {
if (CheckCode(r))
callback(DiscordError::NONE);
else
@ -632,14 +616,10 @@ void DiscordClient::SetGuildName(Snowflake id, const Glib::ustring &name, sigc::
});
}
void DiscordClient::SetGuildIcon(Snowflake id, const std::string &data) {
SetGuildIcon(id, data, [](auto) {});
}
void DiscordClient::SetGuildIcon(Snowflake id, const std::string &data, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::SetGuildIcon(Snowflake id, const std::string &data, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildObject obj;
obj.IconData = data;
m_http.MakePATCH("/guilds/" + std::to_string(id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &r) {
m_http.MakePATCH("/guilds/" + std::to_string(id), nlohmann::json(obj).dump(), [callback](const http::response_type &r) {
if (CheckCode(r))
callback(DiscordError::NONE);
else
@ -647,12 +627,8 @@ void DiscordClient::SetGuildIcon(Snowflake id, const std::string &data, sigc::sl
});
}
void DiscordClient::UnbanUser(Snowflake guild_id, Snowflake user_id) {
UnbanUser(guild_id, user_id, [](const auto) {});
}
void DiscordClient::UnbanUser(Snowflake guild_id, Snowflake user_id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakeDELETE("/guilds/" + std::to_string(guild_id) + "/bans/" + std::to_string(user_id), [this, callback](const http::response_type &response) {
void DiscordClient::UnbanUser(Snowflake guild_id, Snowflake user_id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakeDELETE("/guilds/" + std::to_string(guild_id) + "/bans/" + std::to_string(user_id), [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -660,12 +636,8 @@ void DiscordClient::UnbanUser(Snowflake guild_id, Snowflake user_id, sigc::slot<
});
}
void DiscordClient::DeleteInvite(const std::string &code) {
DeleteInvite(code, [](const auto) {});
}
void DiscordClient::DeleteInvite(const std::string &code, sigc::slot<void(DiscordError code)> callback) {
m_http.MakeDELETE("/invites/" + code, [this, callback](const http::response_type &response) {
void DiscordClient::DeleteInvite(const std::string &code, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakeDELETE("/invites/" + code, [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -674,21 +646,21 @@ void DiscordClient::DeleteInvite(const std::string &code, sigc::slot<void(Discor
}
void DiscordClient::AddGroupDMRecipient(Snowflake channel_id, Snowflake user_id) {
m_http.MakePUT("/channels/" + std::to_string(channel_id) + "/recipients/" + std::to_string(user_id), "", [this](const http::response_type &response) {
m_http.MakePUT("/channels/" + std::to_string(channel_id) + "/recipients/" + std::to_string(user_id), "", [](const http::response_type &response) {
CheckCode(response);
});
}
void DiscordClient::RemoveGroupDMRecipient(Snowflake channel_id, Snowflake user_id) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/recipients/" + std::to_string(user_id), [this](const http::response_type &response) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/recipients/" + std::to_string(user_id), [](const http::response_type &response) {
CheckCode(response);
});
}
void DiscordClient::ModifyRolePermissions(Snowflake guild_id, Snowflake role_id, Permission permissions, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyRolePermissions(Snowflake guild_id, Snowflake role_id, Permission permissions, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildRoleObject obj;
obj.Permissions = permissions;
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -696,10 +668,10 @@ void DiscordClient::ModifyRolePermissions(Snowflake guild_id, Snowflake role_id,
});
}
void DiscordClient::ModifyRoleName(Snowflake guild_id, Snowflake role_id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyRoleName(Snowflake guild_id, Snowflake role_id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildRoleObject obj;
obj.Name = name;
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -707,10 +679,10 @@ void DiscordClient::ModifyRoleName(Snowflake guild_id, Snowflake role_id, const
});
}
void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, uint32_t color, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, uint32_t color, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildRoleObject obj;
obj.Color = color;
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles/" + std::to_string(role_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -718,7 +690,7 @@ void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, uint3
});
}
void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, Gdk::RGBA color, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, const Gdk::RGBA &color, const sigc::slot<void(DiscordError code)> &callback) {
uint32_t int_color = 0;
int_color |= static_cast<uint32_t>(color.get_blue() * 255.0) << 0;
int_color |= static_cast<uint32_t>(color.get_green() * 255.0) << 8;
@ -726,7 +698,7 @@ void DiscordClient::ModifyRoleColor(Snowflake guild_id, Snowflake role_id, Gdk::
ModifyRoleColor(guild_id, role_id, int_color, callback);
}
void DiscordClient::ModifyRolePosition(Snowflake guild_id, Snowflake role_id, int position, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyRolePosition(Snowflake guild_id, Snowflake role_id, int position, const sigc::slot<void(DiscordError code)> &callback) {
const auto guild = GetGuild(guild_id);
if (!guild.has_value() || !guild->Roles.has_value()) return;
const auto &roles = *guild->Roles;
@ -763,7 +735,7 @@ void DiscordClient::ModifyRolePosition(Snowflake guild_id, Snowflake role_id, in
for (size_t i = range_from; i < range_to; i++)
obj.Positions.push_back({ roles[i].ID, roles[i].Position + dir });
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles", nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/roles", nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -771,11 +743,11 @@ void DiscordClient::ModifyRolePosition(Snowflake guild_id, Snowflake role_id, in
});
}
void DiscordClient::ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildEmojiObject obj;
obj.Name = name;
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/emojis/" + std::to_string(emoji_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/emojis/" + std::to_string(emoji_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -783,8 +755,8 @@ void DiscordClient::ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, cons
});
}
void DiscordClient::DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakeDELETE("/guilds/" + std::to_string(guild_id) + "/emojis/" + std::to_string(emoji_id), [this, callback](const http::response_type &response) {
void DiscordClient::DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakeDELETE("/guilds/" + std::to_string(guild_id) + "/emojis/" + std::to_string(emoji_id), [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -792,14 +764,8 @@ void DiscordClient::DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::sl
});
}
std::optional<GuildApplicationData> DiscordClient::GetGuildApplication(Snowflake guild_id) const {
const auto it = m_guild_join_requests.find(guild_id);
if (it == m_guild_join_requests.end()) return std::nullopt;
return it->second;
}
void DiscordClient::RemoveRelationship(Snowflake id, sigc::slot<void(DiscordError Code)> callback) {
m_http.MakeDELETE("/users/@me/relationships/" + std::to_string(id), [this, callback](const http::response_type &response) {
void DiscordClient::RemoveRelationship(Snowflake id, const sigc::slot<void(DiscordError Code)> &callback) {
m_http.MakeDELETE("/users/@me/relationships/" + std::to_string(id), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -807,11 +773,11 @@ void DiscordClient::RemoveRelationship(Snowflake id, sigc::slot<void(DiscordErro
});
}
void DiscordClient::SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::SendFriendRequest(const Glib::ustring &username, int discriminator, const sigc::slot<void(DiscordError code)> &callback) {
FriendRequestObject obj;
obj.Username = username;
obj.Discriminator = discriminator;
m_http.MakePOST("/users/@me/relationships", nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePOST("/users/@me/relationships", nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -819,8 +785,8 @@ void DiscordClient::SendFriendRequest(const Glib::ustring &username, int discrim
});
}
void DiscordClient::PutRelationship(Snowflake id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePUT("/users/@me/relationships/" + std::to_string(id), "{}", [this, callback](const http::response_type &response) {
void DiscordClient::PutRelationship(Snowflake id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePUT("/users/@me/relationships/" + std::to_string(id), "{}", [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -828,8 +794,8 @@ void DiscordClient::PutRelationship(Snowflake id, sigc::slot<void(DiscordError c
});
}
void DiscordClient::Pin(Snowflake channel_id, Snowflake message_id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePUT("/channels/" + std::to_string(channel_id) + "/pins/" + std::to_string(message_id), "", [this, callback](const http::response_type &response) {
void DiscordClient::Pin(Snowflake channel_id, Snowflake message_id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePUT("/channels/" + std::to_string(channel_id) + "/pins/" + std::to_string(message_id), "", [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -837,8 +803,8 @@ void DiscordClient::Pin(Snowflake channel_id, Snowflake message_id, sigc::slot<v
});
}
void DiscordClient::Unpin(Snowflake channel_id, Snowflake message_id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/pins/" + std::to_string(message_id), [this, callback](const http::response_type &response) {
void DiscordClient::Unpin(Snowflake channel_id, Snowflake message_id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/pins/" + std::to_string(message_id), [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -848,8 +814,8 @@ void DiscordClient::Unpin(Snowflake channel_id, Snowflake message_id, sigc::slot
// i dont know if the location parameter is necessary at all but discord's thread implementation is extremely strange
// so its here just in case
void DiscordClient::LeaveThread(Snowflake channel_id, const std::string &location, sigc::slot<void(DiscordError code)> callback) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/thread-members/@me?location=" + location, [this, callback](const http::response_type &response) {
void DiscordClient::LeaveThread(Snowflake channel_id, const std::string &location, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakeDELETE("/channels/" + std::to_string(channel_id) + "/thread-members/@me?location=" + location, [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -857,11 +823,11 @@ void DiscordClient::LeaveThread(Snowflake channel_id, const std::string &locatio
});
}
void DiscordClient::ArchiveThread(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::ArchiveThread(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback) {
ModifyChannelObject obj;
obj.Archived = true;
obj.Locked = true;
m_http.MakePATCH("/channels/" + std::to_string(channel_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/channels/" + std::to_string(channel_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -869,11 +835,11 @@ void DiscordClient::ArchiveThread(Snowflake channel_id, sigc::slot<void(DiscordE
});
}
void DiscordClient::UnArchiveThread(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::UnArchiveThread(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback) {
ModifyChannelObject obj;
obj.Archived = false;
obj.Locked = false;
m_http.MakePATCH("/channels/" + std::to_string(channel_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/channels/" + std::to_string(channel_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -881,11 +847,11 @@ void DiscordClient::UnArchiveThread(Snowflake channel_id, sigc::slot<void(Discor
});
}
void DiscordClient::MarkChannelAsRead(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::MarkChannelAsRead(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback) {
if (m_unread.find(channel_id) == m_unread.end()) return;
const auto iter = m_last_message_id.find(channel_id);
if (iter == m_last_message_id.end()) return;
m_http.MakePOST("/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(iter->second) + "/ack", "{\"token\":null}", [this, callback](const http::response_type &response) {
m_http.MakePOST("/channels/" + std::to_string(channel_id) + "/messages/" + std::to_string(iter->second) + "/ack", "{\"token\":null}", [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -893,7 +859,7 @@ void DiscordClient::MarkChannelAsRead(Snowflake channel_id, sigc::slot<void(Disc
});
}
void DiscordClient::MarkGuildAsRead(Snowflake guild_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::MarkGuildAsRead(Snowflake guild_id, const sigc::slot<void(DiscordError code)> &callback) {
AckBulkData data;
const auto channels = GetChannelsInGuild(guild_id);
for (const auto &[unread, mention_count] : m_unread) {
@ -908,7 +874,7 @@ void DiscordClient::MarkGuildAsRead(Snowflake guild_id, sigc::slot<void(DiscordE
if (data.ReadStates.empty()) return;
m_http.MakePOST("/read-states/ack-bulk", nlohmann::json(data).dump(), [this, callback](const http::response_type &response) {
m_http.MakePOST("/read-states/ack-bulk", nlohmann::json(data).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -916,14 +882,14 @@ void DiscordClient::MarkGuildAsRead(Snowflake guild_id, sigc::slot<void(DiscordE
});
}
void DiscordClient::MuteChannel(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::MuteChannel(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback) {
const auto channel = GetChannel(channel_id);
if (!channel.has_value()) return;
const auto guild_id_path = channel->GuildID.has_value() ? std::to_string(*channel->GuildID) : "@me"s;
nlohmann::json j;
j["channel_overrides"][std::to_string(channel_id)]["mute_config"] = MuteConfigData { std::nullopt, -1 };
j["channel_overrides"][std::to_string(channel_id)]["muted"] = true;
m_http.MakePATCH("/users/@me/guilds/" + guild_id_path + "/settings", j.dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/users/@me/guilds/" + guild_id_path + "/settings", j.dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -931,13 +897,13 @@ void DiscordClient::MuteChannel(Snowflake channel_id, sigc::slot<void(DiscordErr
});
}
void DiscordClient::UnmuteChannel(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::UnmuteChannel(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback) {
const auto channel = GetChannel(channel_id);
if (!channel.has_value()) return;
const auto guild_id_path = channel->GuildID.has_value() ? std::to_string(*channel->GuildID) : "@me"s;
nlohmann::json j;
j["channel_overrides"][std::to_string(channel_id)]["muted"] = false;
m_http.MakePATCH("/users/@me/guilds/" + guild_id_path + "/settings", j.dump(), [this, callback](const http::response_type &response) {
m_http.MakePATCH("/users/@me/guilds/" + guild_id_path + "/settings", j.dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -945,7 +911,7 @@ void DiscordClient::UnmuteChannel(Snowflake channel_id, sigc::slot<void(DiscordE
});
}
void DiscordClient::MarkAllAsRead(sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::MarkAllAsRead(const sigc::slot<void(DiscordError code)> &callback) {
AckBulkData data;
for (const auto &[unread, mention_count] : m_unread) {
const auto iter = m_last_message_id.find(unread);
@ -957,7 +923,7 @@ void DiscordClient::MarkAllAsRead(sigc::slot<void(DiscordError code)> callback)
if (data.ReadStates.empty()) return;
m_http.MakePOST("/read-states/ack-bulk", nlohmann::json(data).dump(), [this, callback](const http::response_type &response) {
m_http.MakePOST("/read-states/ack-bulk", nlohmann::json(data).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -965,8 +931,8 @@ void DiscordClient::MarkAllAsRead(sigc::slot<void(DiscordError code)> callback)
});
}
void DiscordClient::MuteGuild(Snowflake id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePATCH("/users/@me/guilds/" + std::to_string(id) + "/settings", R"({"muted":true})", [this, callback](const http::response_type &response) {
void DiscordClient::MuteGuild(Snowflake id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePATCH("/users/@me/guilds/" + std::to_string(id) + "/settings", R"({"muted":true})", [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -974,8 +940,8 @@ void DiscordClient::MuteGuild(Snowflake id, sigc::slot<void(DiscordError code)>
});
}
void DiscordClient::UnmuteGuild(Snowflake id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePATCH("/users/@me/guilds/" + std::to_string(id) + "/settings", R"({"muted":false})", [this, callback](const http::response_type &response) {
void DiscordClient::UnmuteGuild(Snowflake id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePATCH("/users/@me/guilds/" + std::to_string(id) + "/settings", R"({"muted":false})", [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -983,8 +949,8 @@ void DiscordClient::UnmuteGuild(Snowflake id, sigc::slot<void(DiscordError code)
});
}
void DiscordClient::MuteThread(Snowflake id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePATCH("/channels/" + std::to_string(id) + "/thread-members/@me/settings", R"({"muted":true})", [this, callback](const http::response_type &response) {
void DiscordClient::MuteThread(Snowflake id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePATCH("/channels/" + std::to_string(id) + "/thread-members/@me/settings", R"({"muted":true})", [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -992,8 +958,8 @@ void DiscordClient::MuteThread(Snowflake id, sigc::slot<void(DiscordError code)>
});
}
void DiscordClient::UnmuteThread(Snowflake id, sigc::slot<void(DiscordError code)> callback) {
m_http.MakePATCH("/channels/" + std::to_string(id) + "/thread-members/@me/settings", R"({"muted":false})", [this, callback](const http::response_type &response) {
void DiscordClient::UnmuteThread(Snowflake id, const sigc::slot<void(DiscordError code)> &callback) {
m_http.MakePATCH("/channels/" + std::to_string(id) + "/thread-members/@me/settings", R"({"muted":false})", [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -1001,7 +967,7 @@ void DiscordClient::UnmuteThread(Snowflake id, sigc::slot<void(DiscordError code
});
}
void DiscordClient::FetchPinned(Snowflake id, sigc::slot<void(std::vector<Message>, DiscordError code)> callback) {
void DiscordClient::FetchPinned(Snowflake id, const sigc::slot<void(std::vector<Message>, DiscordError code)> &callback) {
// return from db if we know the pins have already been requested
if (m_channels_pinned_requested.find(id) != m_channels_pinned_requested.end()) {
callback(m_store.GetPinnedMessages(id), DiscordError::NONE);
@ -1019,7 +985,7 @@ void DiscordClient::FetchPinned(Snowflake id, sigc::slot<void(std::vector<Messag
std::sort(data.begin(), data.end(), [](const Message &a, const Message &b) { return a.ID < b.ID; });
for (auto &msg : data)
StoreMessageData(msg);
callback(std::move(data), DiscordError::NONE);
callback(data, DiscordError::NONE);
});
}
@ -1040,7 +1006,7 @@ std::vector<BanData> DiscordClient::GetBansInGuild(Snowflake guild_id) {
return m_store.GetBans(guild_id);
}
void DiscordClient::FetchGuildBan(Snowflake guild_id, Snowflake user_id, sigc::slot<void(BanData)> callback) {
void DiscordClient::FetchGuildBan(Snowflake guild_id, Snowflake user_id, const sigc::slot<void(BanData)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/bans/" + std::to_string(user_id), [this, callback, guild_id](const http::response_type &response) {
if (!CheckCode(response)) return;
auto ban = nlohmann::json::parse(response.text).get<BanData>();
@ -1050,7 +1016,7 @@ void DiscordClient::FetchGuildBan(Snowflake guild_id, Snowflake user_id, sigc::s
});
}
void DiscordClient::FetchGuildBans(Snowflake guild_id, sigc::slot<void(std::vector<BanData>)> callback) {
void DiscordClient::FetchGuildBans(Snowflake guild_id, const sigc::slot<void(std::vector<BanData>)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/bans", [this, callback, guild_id](const http::response_type &response) {
if (!CheckCode(response)) return;
auto bans = nlohmann::json::parse(response.text).get<std::vector<BanData>>();
@ -1064,8 +1030,8 @@ void DiscordClient::FetchGuildBans(Snowflake guild_id, sigc::slot<void(std::vect
});
}
void DiscordClient::FetchGuildInvites(Snowflake guild_id, sigc::slot<void(std::vector<InviteData>)> callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/invites", [this, callback, guild_id](const http::response_type &response) {
void DiscordClient::FetchGuildInvites(Snowflake guild_id, const sigc::slot<void(std::vector<InviteData>)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/invites", [this, callback](const http::response_type &response) {
// store?
if (!CheckCode(response)) return;
auto invites = nlohmann::json::parse(response.text).get<std::vector<InviteData>>();
@ -1080,7 +1046,7 @@ void DiscordClient::FetchGuildInvites(Snowflake guild_id, sigc::slot<void(std::v
});
}
void DiscordClient::FetchAuditLog(Snowflake guild_id, sigc::slot<void(AuditLogData)> callback) {
void DiscordClient::FetchAuditLog(Snowflake guild_id, const sigc::slot<void(AuditLogData)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/audit-logs", [this, callback](const http::response &response) {
if (!CheckCode(response)) return;
auto data = nlohmann::json::parse(response.text).get<AuditLogData>();
@ -1094,7 +1060,7 @@ void DiscordClient::FetchAuditLog(Snowflake guild_id, sigc::slot<void(AuditLogDa
});
}
void DiscordClient::FetchGuildEmojis(Snowflake guild_id, sigc::slot<void(std::vector<EmojiData>)> callback) {
void DiscordClient::FetchGuildEmojis(Snowflake guild_id, const sigc::slot<void(std::vector<EmojiData>)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/emojis", [this, callback](const http::response_type &response) {
if (!CheckCode(response)) return;
auto emojis = nlohmann::json::parse(response.text).get<std::vector<EmojiData>>();
@ -1102,19 +1068,19 @@ void DiscordClient::FetchGuildEmojis(Snowflake guild_id, sigc::slot<void(std::ve
for (const auto &emoji : emojis)
m_store.SetEmoji(emoji.ID, emoji);
m_store.EndTransaction();
callback(std::move(emojis));
callback(emojis);
});
}
void DiscordClient::FetchUserProfile(Snowflake user_id, sigc::slot<void(UserProfileData)> callback) {
m_http.MakeGET("/users/" + std::to_string(user_id) + "/profile", [this, callback](const http::response_type &response) {
void DiscordClient::FetchUserProfile(Snowflake user_id, const sigc::slot<void(UserProfileData)> &callback) {
m_http.MakeGET("/users/" + std::to_string(user_id) + "/profile", [callback](const http::response_type &response) {
if (!CheckCode(response)) return;
callback(nlohmann::json::parse(response.text).get<UserProfileData>());
});
}
void DiscordClient::FetchUserNote(Snowflake user_id, sigc::slot<void(std::string note)> callback) {
m_http.MakeGET("/users/@me/notes/" + std::to_string(user_id), [this, callback](const http::response_type &response) {
void DiscordClient::FetchUserNote(Snowflake user_id, const sigc::slot<void(std::string note)> &callback) {
m_http.MakeGET("/users/@me/notes/" + std::to_string(user_id), [callback](const http::response_type &response) {
if (response.status_code == 404) return;
if (!CheckCode(response)) return;
const auto note = nlohmann::json::parse(response.text).get<UserNoteObject>().Note;
@ -1123,14 +1089,10 @@ void DiscordClient::FetchUserNote(Snowflake user_id, sigc::slot<void(std::string
});
}
void DiscordClient::SetUserNote(Snowflake user_id, std::string note) {
SetUserNote(user_id, note, [](auto) {});
}
void DiscordClient::SetUserNote(Snowflake user_id, std::string note, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::SetUserNote(Snowflake user_id, std::string note, const sigc::slot<void(DiscordError code)> &callback) {
UserSetNoteObject obj;
obj.Note = note;
m_http.MakePUT("/users/@me/notes/" + std::to_string(user_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
obj.Note = std::move(note);
m_http.MakePUT("/users/@me/notes/" + std::to_string(user_id), nlohmann::json(obj).dump(), [callback](const http::response_type &response) {
if (CheckCode(response, 204))
callback(DiscordError::NONE);
else
@ -1138,7 +1100,7 @@ void DiscordClient::SetUserNote(Snowflake user_id, std::string note, sigc::slot<
});
}
void DiscordClient::FetchUserRelationships(Snowflake user_id, sigc::slot<void(std::vector<UserData>)> callback) {
void DiscordClient::FetchUserRelationships(Snowflake user_id, const sigc::slot<void(std::vector<UserData>)> &callback) {
m_http.MakeGET("/users/" + std::to_string(user_id) + "/relationships", [this, callback](const http::response_type &response) {
if (!CheckCode(response)) return;
RelationshipsData data = nlohmann::json::parse(response.text);
@ -1148,26 +1110,26 @@ void DiscordClient::FetchUserRelationships(Snowflake user_id, sigc::slot<void(st
});
}
bool DiscordClient::IsVerificationRequired(Snowflake guild_id) {
bool DiscordClient::IsVerificationRequired(Snowflake guild_id) const {
const auto member = GetMember(GetUserData().ID, guild_id);
if (member.has_value() && member->IsPending.has_value())
return *member->IsPending;
return false;
}
void DiscordClient::GetVerificationGateInfo(Snowflake guild_id, sigc::slot<void(std::optional<VerificationGateInfoObject>)> callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/member-verification", [this, callback](const http::response_type &response) {
void DiscordClient::GetVerificationGateInfo(Snowflake guild_id, const sigc::slot<void(std::optional<VerificationGateInfoObject>)> &callback) {
m_http.MakeGET("/guilds/" + std::to_string(guild_id) + "/member-verification", [callback](const http::response_type &response) {
if (!CheckCode(response)) return;
if (response.status_code == 204) callback(std::nullopt);
callback(nlohmann::json::parse(response.text).get<VerificationGateInfoObject>());
});
}
void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, sigc::slot<void(DiscordError code)> callback) {
void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot<void(DiscordError code)> &callback) {
if (info.VerificationFields.has_value())
for (auto &field : *info.VerificationFields)
field.Response = true;
m_http.MakePUT("/guilds/" + std::to_string(guild_id) + "/requests/@me", nlohmann::json(info).dump(), [this, callback](const http::response_type &response) {
m_http.MakePUT("/guilds/" + std::to_string(guild_id) + "/requests/@me", nlohmann::json(info).dump(), [callback](const http::response_type &response) {
if (CheckCode(response))
callback(DiscordError::NONE);
else
@ -1175,14 +1137,14 @@ void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateI
});
}
void DiscordClient::UpdateToken(std::string token) {
void DiscordClient::UpdateToken(const std::string &token) {
if (!IsStarted()) {
m_token = token;
m_http.SetAuth(token);
}
}
void DiscordClient::SetUserAgent(std::string agent) {
void DiscordClient::SetUserAgent(const std::string &agent) {
m_http.SetUserAgent(agent);
m_websocket.SetUserAgent(agent);
}
@ -1483,7 +1445,7 @@ void DiscordClient::HandleGatewayHello(const GatewayMessage &msg) {
HelloMessageData d = msg.Data;
m_heartbeat_msec = d.HeartbeatInterval;
m_heartbeat_waiter.revive();
m_heartbeat_thread = std::thread(std::bind(&DiscordClient::HeartbeatThread, this));
m_heartbeat_thread = std::thread([this] { HeartbeatThread(); });
m_signal_connected.emit(); // socket is connected before this but emitting here should b fine
m_reconnecting = false; // maybe should go elsewhere?
if (m_wants_resume) {
@ -1736,7 +1698,7 @@ void DiscordClient::HandleGatewayGuildRoleCreate(const GatewayMessage &msg) {
void DiscordClient::HandleGatewayGuildRoleDelete(const GatewayMessage &msg) {
GuildRoleDeleteObject data = msg.Data;
auto guild = *m_store.GetGuild(data.GuildID);
const auto pred = [this, id = data.RoleID](const RoleData &role) -> bool {
const auto pred = [id = data.RoleID](const RoleData &role) -> bool {
return role.ID == id;
};
guild.Roles->erase(std::remove_if(guild.Roles->begin(), guild.Roles->end(), pred), guild.Roles->end());
@ -1826,12 +1788,12 @@ void DiscordClient::HandleGatewayInviteCreate(const GatewayMessage &msg) {
invite.CreatedAt = std::move(data.CreatedAt);
invite.Channel = *m_store.GetChannel(data.ChannelID);
invite.Inviter = std::move(data.Inviter);
invite.IsTemporary = std::move(data.IsTemporary);
invite.MaxAge = std::move(data.MaxAge);
invite.MaxUses = std::move(data.MaxUses);
invite.IsTemporary = data.IsTemporary;
invite.MaxAge = data.MaxAge;
invite.MaxUses = data.MaxUses;
invite.TargetUser = std::move(data.TargetUser);
invite.TargetUserType = std::move(data.TargetUserType);
invite.Uses = std::move(data.Uses);
invite.TargetUserType = data.TargetUserType;
invite.Uses = data.Uses;
if (data.GuildID.has_value())
invite.Guild = m_store.GetGuild(*data.GuildID);
m_signal_invite_create.emit(invite);
@ -1893,7 +1855,7 @@ void DiscordClient::HandleGatewayRelationshipAdd(const GatewayMessage &msg) {
RelationshipAddData data = msg.Data;
m_store.SetUser(data.ID, data.User);
m_user_relationships[data.ID] = data.Type;
m_signal_relationship_add.emit(std::move(data));
m_signal_relationship_add.emit(data);
}
// remarkably this doesnt actually mean a thread was created
@ -2168,7 +2130,7 @@ void DiscordClient::HandleGatewayGuildMemberListUpdate(const GatewayMessage &msg
has_sync = true;
for (const auto &item : *op.Items) {
if (item->Type == "member") {
auto member = static_cast<const GuildMemberListUpdateMessage::MemberItem *>(item.get());
auto member = dynamic_cast<const GuildMemberListUpdateMessage::MemberItem *>(item.get());
m_store.SetUser(member->User.ID, member->User);
AddUserToGuild(member->User.ID, data.GuildID);
m_store.SetGuildMember(data.GuildID, member->User.ID, member->GetAsMemberData());
@ -2187,7 +2149,7 @@ void DiscordClient::HandleGatewayGuildMemberListUpdate(const GatewayMessage &msg
}
} else if (op.Op == "UPDATE") {
if (op.OpItem.has_value() && op.OpItem.value()->Type == "member") {
const auto &m = static_cast<const GuildMemberListUpdateMessage::MemberItem *>(op.OpItem.value().get())->GetAsMemberData();
const auto &m = dynamic_cast<const GuildMemberListUpdateMessage::MemberItem *>(op.OpItem.value().get())->GetAsMemberData();
m_store.SetGuildMember(data.GuildID, m.User->ID, m);
m_signal_guild_member_update.emit(data.GuildID, m.User->ID); // cheeky
}
@ -2472,12 +2434,6 @@ void DiscordClient::HandleReadyGuildSettings(const ReadyEventData &data) {
}
}
void DiscordClient::HandleUserGuildSettingsUpdateForDMs(const UserGuildSettingsUpdateData &data) {
const auto channels = GetPrivateChannels();
std::set<Snowflake> now_muted_channels;
const auto now = Snowflake::FromNow();
}
void DiscordClient::LoadEventMap() {
m_event_map["READY"] = GatewayEvent::READY;
m_event_map["MESSAGE_CREATE"] = GatewayEvent::MESSAGE_CREATE;

View File

@ -55,7 +55,6 @@ public:
std::unordered_set<Snowflake> GetGuilds() const;
const UserData &GetUserData() const;
const UserSettings &GetUserSettings() const;
std::vector<Snowflake> GetUserSortedGuilds() const;
std::vector<Message> GetMessagesForChannel(Snowflake id, size_t limit = 50) const;
std::vector<Message> GetMessagesBefore(Snowflake channel_id, Snowflake message_id, size_t limit = 50) const;
@ -63,8 +62,8 @@ public:
EPremiumType GetSelfPremiumType() const;
void FetchMessagesInChannel(Snowflake id, sigc::slot<void(const std::vector<Message> &)> cb);
void FetchMessagesInChannelBefore(Snowflake channel_id, Snowflake before_id, sigc::slot<void(const std::vector<Message> &)> cb);
void FetchMessagesInChannel(Snowflake id, const sigc::slot<void(const std::vector<Message> &)> &cb);
void FetchMessagesInChannelBefore(Snowflake channel_id, Snowflake before_id, const sigc::slot<void(const std::vector<Message> &)> &cb);
std::optional<Message> GetMessage(Snowflake id) const;
std::optional<ChannelData> GetChannel(Snowflake id) const;
std::optional<EmojiData> GetEmoji(Snowflake id) const;
@ -73,15 +72,14 @@ public:
std::optional<RoleData> GetRole(Snowflake id) const;
std::optional<GuildData> GetGuild(Snowflake id) const;
std::optional<GuildMember> GetMember(Snowflake user_id, Snowflake guild_id) const;
std::optional<BanData> GetBan(Snowflake guild_id, Snowflake user_id) const;
Snowflake GetMemberHoistedRole(Snowflake guild_id, Snowflake user_id, bool with_color = false) const;
std::optional<RoleData> GetMemberHighestRole(Snowflake guild_id, Snowflake user_id) const;
std::set<Snowflake> GetUsersInGuild(Snowflake id) const;
std::set<Snowflake> GetChannelsInGuild(Snowflake id) const;
std::vector<Snowflake> GetUsersInThread(Snowflake id) const;
std::vector<ChannelData> GetActiveThreads(Snowflake channel_id) const;
void GetArchivedPublicThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback);
void GetArchivedPrivateThreads(Snowflake channel_id, sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> callback);
void GetArchivedPublicThreads(Snowflake channel_id, const sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> &callback);
void GetArchivedPrivateThreads(Snowflake channel_id, const sigc::slot<void(DiscordError, const ArchivedThreadsResponseData &)> &callback);
std::vector<Snowflake> GetChildChannelIDs(Snowflake parent_id) const;
// get ids of given list of members for who we do not have the member data
@ -104,7 +102,7 @@ public:
Permission ComputeOverwrites(Permission base, Snowflake member_id, Snowflake channel_id) const;
bool CanManageMember(Snowflake guild_id, Snowflake actor, Snowflake target) const; // kick, ban, edit nickname (cant think of a better name)
void ChatMessageCallback(std::string nonce, const http::response_type &response);
void ChatMessageCallback(const std::string &nonce, const http::response_type &response);
void SendChatMessage(const std::string &content, Snowflake channel);
void SendChatMessage(const std::string &content, Snowflake channel, Snowflake referenced_message);
@ -112,53 +110,47 @@ public:
void EditMessage(Snowflake channel_id, Snowflake id, std::string content);
void SendLazyLoad(Snowflake id);
void SendThreadLazyLoad(Snowflake id);
void JoinGuild(std::string code);
void JoinGuild(const std::string &code);
void LeaveGuild(Snowflake id);
void KickUser(Snowflake user_id, Snowflake guild_id);
void BanUser(Snowflake user_id, Snowflake guild_id); // todo: reason, delete messages
void UpdateStatus(PresenceStatus status, bool is_afk);
void UpdateStatus(PresenceStatus status, bool is_afk, const ActivityData &obj);
void CreateDM(Snowflake user_id);
void CreateDM(Snowflake user_id, sigc::slot<void(DiscordError code, Snowflake channel_id)> callback);
void CreateDM(Snowflake user_id, const sigc::slot<void(DiscordError code, Snowflake channel_id)> &callback);
void CloseDM(Snowflake channel_id);
std::optional<Snowflake> FindDM(Snowflake user_id); // wont find group dms
void AddReaction(Snowflake id, Glib::ustring param);
void RemoveReaction(Snowflake id, Glib::ustring param);
void SetGuildName(Snowflake id, const Glib::ustring &name);
void SetGuildName(Snowflake id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback);
void SetGuildIcon(Snowflake id, const std::string &data);
void SetGuildIcon(Snowflake id, const std::string &data, sigc::slot<void(DiscordError code)> callback);
void UnbanUser(Snowflake guild_id, Snowflake user_id);
void UnbanUser(Snowflake guild_id, Snowflake user_id, sigc::slot<void(DiscordError code)> callback);
void DeleteInvite(const std::string &code);
void DeleteInvite(const std::string &code, sigc::slot<void(DiscordError code)> callback);
void SetGuildName(Snowflake id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback);
void SetGuildIcon(Snowflake id, const std::string &data, const sigc::slot<void(DiscordError code)> &callback);
void UnbanUser(Snowflake guild_id, Snowflake user_id, const sigc::slot<void(DiscordError code)> &callback);
void DeleteInvite(const std::string &code, const sigc::slot<void(DiscordError code)> &callback);
void AddGroupDMRecipient(Snowflake channel_id, Snowflake user_id);
void RemoveGroupDMRecipient(Snowflake channel_id, Snowflake user_id);
void ModifyRolePermissions(Snowflake guild_id, Snowflake role_id, Permission permissions, sigc::slot<void(DiscordError code)> callback);
void ModifyRoleName(Snowflake guild_id, Snowflake role_id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback);
void ModifyRoleColor(Snowflake guild_id, Snowflake role_id, uint32_t color, sigc::slot<void(DiscordError code)> callback);
void ModifyRoleColor(Snowflake guild_id, Snowflake role_id, Gdk::RGBA color, sigc::slot<void(DiscordError code)> callback);
void ModifyRolePosition(Snowflake guild_id, Snowflake role_id, int position, sigc::slot<void(DiscordError code)> callback);
void ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, sigc::slot<void(DiscordError code)> callback);
void DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::slot<void(DiscordError code)> callback);
std::optional<GuildApplicationData> GetGuildApplication(Snowflake guild_id) const;
void RemoveRelationship(Snowflake id, sigc::slot<void(DiscordError code)> callback);
void SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(DiscordError code)> callback);
void PutRelationship(Snowflake id, sigc::slot<void(DiscordError code)> callback); // send fr by id, accept incoming
void Pin(Snowflake channel_id, Snowflake message_id, sigc::slot<void(DiscordError code)> callback);
void Unpin(Snowflake channel_id, Snowflake message_id, sigc::slot<void(DiscordError code)> callback);
void LeaveThread(Snowflake channel_id, const std::string &location, sigc::slot<void(DiscordError code)> callback);
void ArchiveThread(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback);
void UnArchiveThread(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback);
void MarkChannelAsRead(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback);
void MarkGuildAsRead(Snowflake guild_id, sigc::slot<void(DiscordError code)> callback);
void MuteChannel(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback);
void UnmuteChannel(Snowflake channel_id, sigc::slot<void(DiscordError code)> callback);
void MarkAllAsRead(sigc::slot<void(DiscordError code)> callback);
void MuteGuild(Snowflake id, sigc::slot<void(DiscordError code)> callback);
void UnmuteGuild(Snowflake id, sigc::slot<void(DiscordError code)> callback);
void MuteThread(Snowflake id, sigc::slot<void(DiscordError code)> callback);
void UnmuteThread(Snowflake id, sigc::slot<void(DiscordError code)> callback);
void ModifyRolePermissions(Snowflake guild_id, Snowflake role_id, Permission permissions, const sigc::slot<void(DiscordError code)> &callback);
void ModifyRoleName(Snowflake guild_id, Snowflake role_id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback);
void ModifyRoleColor(Snowflake guild_id, Snowflake role_id, uint32_t color, const sigc::slot<void(DiscordError code)> &callback);
void ModifyRoleColor(Snowflake guild_id, Snowflake role_id, const Gdk::RGBA &color, const sigc::slot<void(DiscordError code)> &callback);
void ModifyRolePosition(Snowflake guild_id, Snowflake role_id, int position, const sigc::slot<void(DiscordError code)> &callback);
void ModifyEmojiName(Snowflake guild_id, Snowflake emoji_id, const Glib::ustring &name, const sigc::slot<void(DiscordError code)> &callback);
void DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, const sigc::slot<void(DiscordError code)> &callback);
void RemoveRelationship(Snowflake id, const sigc::slot<void(DiscordError code)> &callback);
void SendFriendRequest(const Glib::ustring &username, int discriminator, const sigc::slot<void(DiscordError code)> &callback);
void PutRelationship(Snowflake id, const sigc::slot<void(DiscordError code)> &callback); // send fr by id, accept incoming
void Pin(Snowflake channel_id, Snowflake message_id, const sigc::slot<void(DiscordError code)> &callback);
void Unpin(Snowflake channel_id, Snowflake message_id, const sigc::slot<void(DiscordError code)> &callback);
void LeaveThread(Snowflake channel_id, const std::string &location, const sigc::slot<void(DiscordError code)> &callback);
void ArchiveThread(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback);
void UnArchiveThread(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback);
void MarkChannelAsRead(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback);
void MarkGuildAsRead(Snowflake guild_id, const sigc::slot<void(DiscordError code)> &callback);
void MuteChannel(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback);
void UnmuteChannel(Snowflake channel_id, const sigc::slot<void(DiscordError code)> &callback);
void MarkAllAsRead(const sigc::slot<void(DiscordError code)> &callback);
void MuteGuild(Snowflake id, const sigc::slot<void(DiscordError code)> &callback);
void UnmuteGuild(Snowflake id, const sigc::slot<void(DiscordError code)> &callback);
void MuteThread(Snowflake id, const sigc::slot<void(DiscordError code)> &callback);
void UnmuteThread(Snowflake id, const sigc::slot<void(DiscordError code)> &callback);
bool CanModifyRole(Snowflake guild_id, Snowflake role_id) const;
bool CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const;
@ -177,7 +169,7 @@ public:
// real client doesn't seem to use the single role endpoints so neither do we
template<typename Iter>
auto SetMemberRoles(Snowflake guild_id, Snowflake user_id, Iter begin, Iter end, sigc::slot<void(DiscordError code)> callback) {
auto SetMemberRoles(Snowflake guild_id, Snowflake user_id, Iter begin, Iter end, const sigc::slot<void(DiscordError code)> &callback) {
ModifyGuildMemberObject obj;
obj.Roles = { begin, end };
m_http.MakePATCH("/guilds/" + std::to_string(guild_id) + "/members/" + std::to_string(user_id), nlohmann::json(obj).dump(), [this, callback](const http::response_type &response) {
@ -190,30 +182,29 @@ public:
// FetchGuildBans fetches all bans+reasons via api, this func fetches stored bans (so usually just GUILD_BAN_ADD data)
std::vector<BanData> GetBansInGuild(Snowflake guild_id);
void FetchGuildBan(Snowflake guild_id, Snowflake user_id, sigc::slot<void(BanData)> callback);
void FetchGuildBans(Snowflake guild_id, sigc::slot<void(std::vector<BanData>)> callback);
void FetchGuildBan(Snowflake guild_id, Snowflake user_id, const sigc::slot<void(BanData)> &callback);
void FetchGuildBans(Snowflake guild_id, const sigc::slot<void(std::vector<BanData>)> &callback);
void FetchInvite(std::string code, sigc::slot<void(std::optional<InviteData>)> callback);
void FetchGuildInvites(Snowflake guild_id, sigc::slot<void(std::vector<InviteData>)> callback);
void FetchInvite(const std::string &code, const sigc::slot<void(std::optional<InviteData>)> &callback);
void FetchGuildInvites(Snowflake guild_id, const sigc::slot<void(std::vector<InviteData>)> &callback);
void FetchAuditLog(Snowflake guild_id, sigc::slot<void(AuditLogData)> callback);
void FetchAuditLog(Snowflake guild_id, const sigc::slot<void(AuditLogData)> &callback);
void FetchGuildEmojis(Snowflake guild_id, sigc::slot<void(std::vector<EmojiData>)> callback);
void FetchGuildEmojis(Snowflake guild_id, const sigc::slot<void(std::vector<EmojiData>)> &callback);
void FetchUserProfile(Snowflake user_id, sigc::slot<void(UserProfileData)> callback);
void FetchUserNote(Snowflake user_id, sigc::slot<void(std::string note)> callback);
void SetUserNote(Snowflake user_id, std::string note);
void SetUserNote(Snowflake user_id, std::string note, sigc::slot<void(DiscordError code)> callback);
void FetchUserRelationships(Snowflake user_id, sigc::slot<void(std::vector<UserData>)> callback);
void FetchUserProfile(Snowflake user_id, const sigc::slot<void(UserProfileData)> &callback);
void FetchUserNote(Snowflake user_id, const sigc::slot<void(std::string note)> &callback);
void SetUserNote(Snowflake user_id, std::string note, const sigc::slot<void(DiscordError code)> &callback);
void FetchUserRelationships(Snowflake user_id, const sigc::slot<void(std::vector<UserData>)> &callback);
void FetchPinned(Snowflake id, sigc::slot<void(std::vector<Message>, DiscordError code)> callback);
void FetchPinned(Snowflake id, const sigc::slot<void(std::vector<Message>, DiscordError code)> &callback);
bool IsVerificationRequired(Snowflake guild_id);
void GetVerificationGateInfo(Snowflake guild_id, sigc::slot<void(std::optional<VerificationGateInfoObject>)> callback);
void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, sigc::slot<void(DiscordError code)> callback);
bool IsVerificationRequired(Snowflake guild_id) const;
void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot<void(std::optional<VerificationGateInfoObject>)> &callback);
void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot<void(DiscordError code)> &callback);
void UpdateToken(std::string token);
void SetUserAgent(std::string agent);
void UpdateToken(const std::string &token);
void SetUserAgent(const std::string &agent);
bool IsChannelMuted(Snowflake id) const noexcept;
bool IsGuildMuted(Snowflake id) const noexcept;
@ -233,8 +224,8 @@ private:
std::vector<uint8_t> m_decompress_buf;
z_stream m_zstream;
std::string GetAPIURL();
std::string GetGatewayURL();
static std::string GetAPIURL();
static std::string GetGatewayURL();
static DiscordError GetCodeFromResponse(const http::response_type &response);
@ -296,16 +287,14 @@ private:
void HandleSocketOpen();
void HandleSocketClose(uint16_t code);
bool CheckCode(const http::response_type &r);
bool CheckCode(const http::response_type &r, int expected);
static bool CheckCode(const http::response_type &r);
static bool CheckCode(const http::response_type &r, int expected);
void StoreMessageData(Message &msg);
void HandleReadyReadState(const ReadyEventData &data);
void HandleReadyGuildSettings(const ReadyEventData &data);
void HandleUserGuildSettingsUpdateForDMs(const UserGuildSettingsUpdateData &data);
std::string m_token;
void AddUserToGuild(Snowflake user_id, Snowflake guild_id);

View File

@ -16,7 +16,7 @@ void to_json(nlohmann::json &j, const EmojiData &m) {
j["id"] = m.ID;
else
j["id"] = nullptr;
if (m.Name != "")
if (!m.Name.empty())
j["name"] = m.Name;
else
j["name"] = nullptr;

View File

@ -77,7 +77,7 @@ void GuildData::update_from_json(const nlohmann::json &j) {
JS_RD("owner_id", OwnerID);
std::string tmp;
JS_RD("permissions", tmp);
if (tmp != "")
if (!tmp.empty())
Permissions = std::stoull(tmp);
JS_RD("region", VoiceRegion);
JS_RD("afk_channel_id", AFKChannelID);
@ -128,66 +128,17 @@ bool GuildData::HasFeature(const std::string &search_feature) {
}
bool GuildData::HasIcon() const {
return Icon != "";
return !Icon.empty();
}
bool GuildData::HasAnimatedIcon() const {
return HasIcon() && Icon[0] == 'a' && Icon[1] == '_';
}
std::string GuildData::GetIconURL(std::string ext, std::string size) const {
std::string GuildData::GetIconURL(const std::string &ext, const std::string &size) const {
return "https://cdn.discordapp.com/icons/" + std::to_string(ID) + "/" + Icon + "." + ext + "?size=" + size;
}
std::vector<Snowflake> GuildData::GetSortedChannels(Snowflake ignore) const {
std::vector<Snowflake> ret;
const auto &discord = Abaddon::Get().GetDiscordClient();
auto channels = discord.GetChannelsInGuild(ID);
std::unordered_map<Snowflake, std::vector<ChannelData>> category_to_channels;
std::map<int, std::vector<ChannelData>> position_to_categories;
std::map<int, std::vector<ChannelData>> orphan_channels;
for (const auto &channel_id : channels) {
const auto data = discord.GetChannel(channel_id);
if (!data->ParentID.has_value() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
orphan_channels[*data->Position].push_back(*data);
else if (data->ParentID.has_value() && (data->Type == ChannelType::GUILD_TEXT || data->Type == ChannelType::GUILD_NEWS))
category_to_channels[*data->ParentID].push_back(*data);
else if (data->Type == ChannelType::GUILD_CATEGORY)
position_to_categories[*data->Position].push_back(*data);
}
for (auto &[pos, channels] : orphan_channels) {
std::sort(channels.begin(), channels.end(), [&](const ChannelData &a, const ChannelData &b) -> bool {
return a.ID < b.ID;
});
for (const auto &chan : channels)
ret.push_back(chan.ID);
}
for (auto &[pos, categories] : position_to_categories) {
std::sort(categories.begin(), categories.end(), [&](const ChannelData &a, const ChannelData &b) -> bool {
return a.ID < b.ID;
});
for (const auto &category : categories) {
ret.push_back(category.ID);
if (ignore == category.ID) continue; // stupid hack to save me some time
auto it = category_to_channels.find(category.ID);
if (it == category_to_channels.end()) continue;
auto &channels = it->second;
std::sort(channels.begin(), channels.end(), [&](const ChannelData &a, const ChannelData &b) -> bool {
return a.Position < b.Position;
});
for (auto &channel : channels) {
ret.push_back(channel.ID);
}
}
}
return ret;
}
void from_json(const nlohmann::json &j, GuildApplicationData &m) {
JS_D("user_id", m.UserID);
JS_D("guild_id", m.GuildID);

View File

@ -94,6 +94,5 @@ struct GuildData {
bool HasFeature(const std::string &feature);
bool HasIcon() const;
bool HasAnimatedIcon() const;
std::string GetIconURL(std::string ext = "png", std::string size = "32") const;
std::vector<Snowflake> GetSortedChannels(Snowflake ignore = Snowflake::Invalid) const;
std::string GetIconURL(const std::string &ext = "png", const std::string &size = "32") const;
};

View File

@ -1,5 +1,7 @@
#include "httpclient.hpp"
#include <utility>
//#define USE_LOCAL_PROXY
HTTPClient::HTTPClient() {
m_dispatcher.connect(sigc::mem_fun(*this, &HTTPClient::RunCallbacks));
@ -10,19 +12,19 @@ void HTTPClient::SetBase(const std::string &url) {
}
void HTTPClient::SetUserAgent(std::string agent) {
m_agent = agent;
m_agent = std::move(agent);
}
void HTTPClient::SetAuth(std::string auth) {
m_authorization = auth;
m_authorization = std::move(auth);
}
void HTTPClient::MakeDELETE(const std::string &path, std::function<void(http::response_type r)> cb) {
void HTTPClient::MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb) {
printf("DELETE %s\n", path.c_str());
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
http::request req(http::REQUEST_DELETE, m_api_base + path);
req.set_header("Authorization", m_authorization);
req.set_user_agent(m_agent != "" ? m_agent : "Abaddon");
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
#ifdef USE_LOCAL_PROXY
req.set_proxy("http://127.0.0.1:8888");
req.set_verify_ssl(false);
@ -34,13 +36,13 @@ void HTTPClient::MakeDELETE(const std::string &path, std::function<void(http::re
}));
}
void HTTPClient::MakePATCH(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb) {
void HTTPClient::MakePATCH(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb) {
printf("PATCH %s\n", path.c_str());
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
http::request req(http::REQUEST_PATCH, m_api_base + path);
req.set_header("Authorization", m_authorization);
req.set_header("Content-Type", "application/json");
req.set_user_agent(m_agent != "" ? m_agent : "Abaddon");
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
req.set_body(payload);
#ifdef USE_LOCAL_PROXY
req.set_proxy("http://127.0.0.1:8888");
@ -53,13 +55,13 @@ void HTTPClient::MakePATCH(const std::string &path, const std::string &payload,
}));
}
void HTTPClient::MakePOST(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb) {
void HTTPClient::MakePOST(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb) {
printf("POST %s\n", path.c_str());
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
http::request req(http::REQUEST_POST, m_api_base + path);
req.set_header("Authorization", m_authorization);
req.set_header("Content-Type", "application/json");
req.set_user_agent(m_agent != "" ? m_agent : "Abaddon");
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
req.set_body(payload);
#ifdef USE_LOCAL_PROXY
req.set_proxy("http://127.0.0.1:8888");
@ -72,14 +74,14 @@ void HTTPClient::MakePOST(const std::string &path, const std::string &payload, s
}));
}
void HTTPClient::MakePUT(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb) {
void HTTPClient::MakePUT(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb) {
printf("PUT %s\n", path.c_str());
m_futures.push_back(std::async(std::launch::async, [this, path, cb, payload] {
http::request req(http::REQUEST_PUT, m_api_base + path);
req.set_header("Authorization", m_authorization);
if (payload != "")
if (!payload.empty())
req.set_header("Content-Type", "application/json");
req.set_user_agent(m_agent != "" ? m_agent : "Abaddon");
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
req.set_body(payload);
#ifdef USE_LOCAL_PROXY
req.set_proxy("http://127.0.0.1:8888");
@ -92,13 +94,13 @@ void HTTPClient::MakePUT(const std::string &path, const std::string &payload, st
}));
}
void HTTPClient::MakeGET(const std::string &path, std::function<void(http::response_type r)> cb) {
void HTTPClient::MakeGET(const std::string &path, const std::function<void(http::response_type r)> &cb) {
printf("GET %s\n", path.c_str());
m_futures.push_back(std::async(std::launch::async, [this, path, cb] {
http::request req(http::REQUEST_GET, m_api_base + path);
req.set_header("Authorization", m_authorization);
req.set_header("Content-Type", "application/json");
req.set_user_agent(m_agent != "" ? m_agent : "Abaddon");
req.set_user_agent(!m_agent.empty() ? m_agent : "Abaddon");
#ifdef USE_LOCAL_PROXY
req.set_proxy("http://127.0.0.1:8888");
req.set_verify_ssl(false);
@ -126,11 +128,11 @@ void HTTPClient::RunCallbacks() {
m_mutex.unlock();
}
void HTTPClient::OnResponse(const http::response_type &r, std::function<void(http::response_type r)> cb) {
void HTTPClient::OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb) {
CleanupFutures();
try {
m_mutex.lock();
m_queue.push([this, r, cb] { cb(r); });
m_queue.push([r, cb] { cb(r); });
m_dispatcher.emit();
m_mutex.unlock();
} catch (const std::exception &e) {

View File

@ -17,14 +17,14 @@ public:
void SetUserAgent(std::string agent);
void SetAuth(std::string auth);
void MakeDELETE(const std::string &path, std::function<void(http::response_type r)> cb);
void MakeGET(const std::string &path, std::function<void(http::response_type r)> cb);
void MakePATCH(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb);
void MakePOST(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb);
void MakePUT(const std::string &path, const std::string &payload, std::function<void(http::response_type r)> cb);
void MakeDELETE(const std::string &path, const std::function<void(http::response_type r)> &cb);
void MakeGET(const std::string &path, const std::function<void(http::response_type r)> &cb);
void MakePATCH(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
void MakePOST(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
void MakePUT(const std::string &path, const std::string &payload, const std::function<void(http::response_type r)> &cb);
private:
void OnResponse(const http::response_type &r, std::function<void(http::response_type r)> cb);
void OnResponse(const http::response_type &r, const std::function<void(http::response_type r)> &cb);
void CleanupFutures();
mutable std::mutex m_mutex;

View File

@ -141,8 +141,8 @@ inline void json_update_optional_nullable_default(const ::nlohmann::json &j, con
} while (0)
// set a json value from a std::optional only if it has a value
#define JS_IF(k, v) \
do { \
if (v.has_value()) \
j[k] = *v; \
#define JS_IF(k, v) \
do { \
if ((v).has_value()) \
j[k] = *(v); \
} while (0)

View File

@ -19,7 +19,7 @@ std::vector<RoleData> GuildMember::GetSortedRoles() const {
for (const auto role_id : Roles) {
const auto role = Abaddon::Get().GetDiscordClient().GetRole(role_id);
if (!role.has_value()) continue;
roles.push_back(std::move(*role));
roles.push_back(*role);
}
std::sort(roles.begin(), roles.end(), [](const RoleData &a, const RoleData &b) {

View File

@ -20,7 +20,7 @@ struct GuildMember {
// undocuemtned moment !!!1
std::optional<std::string> Avatar;
std::vector<RoleData> GetSortedRoles() const;
[[nodiscard]] std::vector<RoleData> GetSortedRoles() const;
void update_from_json(const nlohmann::json &j);
friend void from_json(const nlohmann::json &j, GuildMember &m);

View File

@ -176,7 +176,7 @@ void to_json(nlohmann::json &j, const MessageApplicationData &m) {
j["id"] = m.ID;
JS_IF("cover_image", m.CoverImage);
j["description"] = m.Description;
if (m.Icon == "")
if (m.Icon.empty())
j["icon"] = nullptr;
else
j["icon"] = m.Icon;
@ -230,7 +230,7 @@ void Message::from_json_edited(const nlohmann::json &j) {
JS_O("content", Content);
JS_O("timestamp", Timestamp);
JS_ON("edited_timestamp", EditedTimestamp);
if (EditedTimestamp.size() > 0)
if (!EditedTimestamp.empty())
SetEdited();
JS_O("tts", IsTTS);
JS_O("mention_everyone", DoesMentionEveryone);

View File

@ -209,10 +209,10 @@ struct Message {
void SetDeleted();
void SetEdited();
bool IsDeleted() const;
bool IsEdited() const;
[[nodiscard]] bool IsDeleted() const;
[[nodiscard]] bool IsEdited() const;
bool DoesMention(Snowflake id) const noexcept;
[[nodiscard]] bool DoesMention(Snowflake id) const noexcept;
private:
bool m_deleted = false;

View File

@ -251,7 +251,7 @@ void to_json(nlohmann::json &j, const IdentifyProperties &m) {
j["referring_domain_current"] = m.ReferringDomainCurrent;
j["release_channel"] = m.ReleaseChannel;
j["client_build_number"] = m.ClientBuildNumber;
if (m.ClientEventSource == "")
if (m.ClientEventSource.empty())
j["client_event_source"] = nullptr;
else
j["client_event_source"] = m.ClientEventSource;
@ -290,7 +290,7 @@ void to_json(nlohmann::json &j, const CreateMessageObject &m) {
}
void to_json(nlohmann::json &j, const MessageEditObject &m) {
if (m.Content.size() > 0)
if (!m.Content.empty())
j["content"] = m.Content;
// todo EmbedData to_json

View File

@ -197,7 +197,7 @@ struct GuildMemberListUpdateMessage {
std::string HoistedRole; // null
bool IsDefeaned;
GuildMember GetAsMemberData() const;
[[nodiscard]] GuildMember GetAsMemberData() const;
friend void from_json(const nlohmann::json &j, MemberItem &m);

View File

@ -16,8 +16,8 @@ struct RoleData {
bool IsManaged;
bool IsMentionable;
bool HasColor() const noexcept;
Glib::ustring GetEscapedName() const;
[[nodiscard]] bool HasColor() const noexcept;
[[nodiscard]] Glib::ustring GetEscapedName() const;
friend void from_json(const nlohmann::json &j, RoleData &m);
};

View File

@ -2,7 +2,6 @@
#include "util.hpp"
#include <chrono>
#include <ctime>
#include <glibmm.h>
#include <iomanip>
constexpr static uint64_t DiscordEpochSeconds = 1420070400;
@ -26,7 +25,7 @@ Snowflake::Snowflake(const Glib::ustring &str) {
m_num = std::strtoull(str.c_str(), nullptr, 10);
else
m_num = Invalid;
};
}
Snowflake Snowflake::FromNow() {
using namespace std::chrono;
@ -57,7 +56,7 @@ bool Snowflake::IsValid() const {
Glib::ustring Snowflake::GetLocalTimestamp() const {
const time_t secs_since_epoch = (m_num / SecondsInterval) + DiscordEpochSeconds;
const std::tm tm = *localtime(&secs_since_epoch);
std::array<char, 256> tmp;
std::array<char, 256> tmp {};
std::strftime(tmp.data(), sizeof(tmp), "%X %x", &tm);
return tmp.data();
}

View File

@ -12,8 +12,8 @@ struct Snowflake {
static Snowflake FromNow(); // not thread safe
static Snowflake FromISO8601(std::string_view ts);
bool IsValid() const;
Glib::ustring GetLocalTimestamp() const;
[[nodiscard]] bool IsValid() const;
[[nodiscard]] Glib::ustring GetLocalTimestamp() const;
bool operator==(const Snowflake &s) const noexcept {
return m_num == s.m_num;

View File

@ -22,15 +22,6 @@ void from_json(const nlohmann::json &j, StickerData &m) {
JS_D("format_type", m.FormatType);
}
std::string StickerData::GetURL() const {
if (!AssetHash.has_value()) return "";
if (FormatType == StickerFormatType::PNG || FormatType == StickerFormatType::APNG)
return "https://media.discordapp.net/stickers/" + std::to_string(ID) + "/" + *AssetHash + ".png?size=256";
else if (FormatType == StickerFormatType::LOTTIE)
return "https://media.discordapp.net/stickers/" + std::to_string(ID) + "/" + *AssetHash + ".json";
return "";
}
void to_json(nlohmann::json &j, const StickerItem &m) {
j["id"] = m.ID;
j["name"] = m.Name;

View File

@ -24,8 +24,6 @@ struct StickerData {
friend void to_json(nlohmann::json &j, const StickerData &m);
friend void from_json(const nlohmann::json &j, StickerData &m);
std::string GetURL() const;
};
struct StickerItem {
@ -36,5 +34,5 @@ struct StickerItem {
friend void to_json(nlohmann::json &j, const StickerItem &m);
friend void from_json(const nlohmann::json &j, StickerItem &m);
std::string GetURL() const;
[[nodiscard]] std::string GetURL() const;
};

View File

@ -1001,7 +1001,7 @@ std::optional<RoleData> Store::GetRole(Snowflake id) const {
return role;
}
RoleData Store::GetRoleBound(std::unique_ptr<Statement> &s) const {
RoleData Store::GetRoleBound(std::unique_ptr<Statement> &s) {
RoleData r;
s->Get(0, r.ID);
@ -2249,11 +2249,11 @@ int Store::Statement::Bind(int index, Snowflake id) {
int Store::Statement::Bind(int index, const char *str, size_t len) {
if (len == -1) len = strlen(str);
return m_db->SetError(sqlite3_bind_blob(m_stmt, index, str, len, SQLITE_TRANSIENT));
return m_db->SetError(sqlite3_bind_blob(m_stmt, index, str, static_cast<int>(len), SQLITE_TRANSIENT));
}
int Store::Statement::Bind(int index, const std::string &str) {
return m_db->SetError(sqlite3_bind_blob(m_stmt, index, str.c_str(), str.size(), SQLITE_TRANSIENT));
return m_db->SetError(sqlite3_bind_blob(m_stmt, index, str.c_str(), static_cast<int>(str.size()), SQLITE_TRANSIENT));
}
int Store::Statement::Bind(int index) {

View File

@ -101,7 +101,7 @@ private:
~Statement();
Statement &operator=(Statement &other) = delete;
bool OK() const;
[[nodiscard]] bool OK() const;
int Bind(int index, Snowflake id);
int Bind(int index, const char *str, size_t len = -1);
@ -224,7 +224,7 @@ private:
*first++ = id.get<T>();
}
bool IsNull(int index) const;
[[nodiscard]] bool IsNull(int index) const;
int Step();
bool Insert();
bool FetchOne();
@ -238,7 +238,7 @@ private:
};
Message GetMessageBound(std::unique_ptr<Statement> &stmt) const;
RoleData GetRoleBound(std::unique_ptr<Statement> &stmt) const;
static RoleData GetRoleBound(std::unique_ptr<Statement> &stmt);
void SetMessageInteractionPair(Snowflake message_id, const MessageInteractionData &interaction);

View File

@ -29,7 +29,7 @@ bool UserData::HasAnimatedAvatar(const std::optional<Snowflake> &guild_id) const
return HasAnimatedAvatar();
}
std::string UserData::GetAvatarURL(Snowflake guild_id, std::string ext, std::string size) const {
std::string UserData::GetAvatarURL(Snowflake guild_id, const std::string &ext, std::string size) const {
const auto member = Abaddon::Get().GetDiscordClient().GetMember(ID, guild_id);
if (member.has_value() && member->Avatar.has_value()) {
if (ext == "gif" && !(member->Avatar.value()[0] == 'a' && member->Avatar.value()[1] == '_'))
@ -43,14 +43,14 @@ std::string UserData::GetAvatarURL(Snowflake guild_id, std::string ext, std::str
}
}
std::string UserData::GetAvatarURL(const std::optional<Snowflake> &guild_id, std::string ext, std::string size) const {
std::string UserData::GetAvatarURL(const std::optional<Snowflake> &guild_id, const std::string &ext, std::string size) const {
if (guild_id.has_value())
return GetAvatarURL(*guild_id, ext, size);
else
return GetAvatarURL(ext, size);
}
std::string UserData::GetAvatarURL(std::string ext, std::string size) const {
std::string UserData::GetAvatarURL(const std::string &ext, std::string size) const {
if (HasAvatar())
return "https://cdn.discordapp.com/avatars/" + std::to_string(ID) + "/" + Avatar + "." + ext + "?size=" + size;
else
@ -107,7 +107,7 @@ void to_json(nlohmann::json &j, const UserData &m) {
j["id"] = m.ID;
j["username"] = m.Username;
j["discriminator"] = m.Discriminator;
if (m.Avatar == "")
if (m.Avatar.empty())
j["avatar"] = nullptr;
else
j["avatar"] = m.Avatar;

View File

@ -60,22 +60,22 @@ struct UserData {
friend void to_json(nlohmann::json &j, const UserData &m);
void update_from_json(const nlohmann::json &j);
bool IsDeleted() const;
bool HasAvatar() const;
bool HasAnimatedAvatar() const noexcept;
bool HasAnimatedAvatar(Snowflake guild_id) const;
bool HasAnimatedAvatar(const std::optional<Snowflake> &guild_id) const;
std::string GetAvatarURL(Snowflake guild_id, std::string ext = "png", std::string size = "32") const;
std::string GetAvatarURL(const std::optional<Snowflake> &guild_id, std::string ext = "png", std::string size = "32") const;
std::string GetAvatarURL(std::string ext = "png", std::string size = "32") const;
std::string GetDefaultAvatarURL() const;
Snowflake GetHoistedRole(Snowflake guild_id, bool with_color = false) const;
std::string GetMention() const;
std::string GetEscapedName() const;
std::string GetEscapedBoldName() const;
std::string GetEscapedString() const;
[[nodiscard]] bool IsDeleted() const;
[[nodiscard]] bool HasAvatar() const;
[[nodiscard]] bool HasAnimatedAvatar() const noexcept;
[[nodiscard]] bool HasAnimatedAvatar(Snowflake guild_id) const;
[[nodiscard]] bool HasAnimatedAvatar(const std::optional<Snowflake> &guild_id) const;
[[nodiscard]] std::string GetAvatarURL(Snowflake guild_id, const std::string &ext = "png", std::string size = "32") const;
[[nodiscard]] std::string GetAvatarURL(const std::optional<Snowflake> &guild_id, const std::string &ext = "png", std::string size = "32") const;
[[nodiscard]] std::string GetAvatarURL(const std::string &ext = "png", std::string size = "32") const;
[[nodiscard]] std::string GetDefaultAvatarURL() const;
[[nodiscard]] Snowflake GetHoistedRole(Snowflake guild_id, bool with_color = false) const;
[[nodiscard]] std::string GetMention() const;
[[nodiscard]] std::string GetEscapedName() const;
[[nodiscard]] std::string GetEscapedBoldName() const;
[[nodiscard]] std::string GetEscapedString() const;
template<bool with_at>
inline std::string GetEscapedBoldString() const {
[[nodiscard]] inline std::string GetEscapedBoldString() const {
if constexpr (with_at)
return "<b>@" + Glib::Markup::escape_text(Username) + "</b>#" + Discriminator;
else

View File

@ -1,18 +1,18 @@
#include "websocket.hpp"
#include <functional>
#include <utility>
Websocket::Websocket() {}
Websocket::Websocket() = default;
void Websocket::StartConnection(std::string url) {
void Websocket::StartConnection(const std::string &url) {
m_websocket.disableAutomaticReconnection();
m_websocket.setUrl(url);
m_websocket.setOnMessageCallback(std::bind(&Websocket::OnMessage, this, std::placeholders::_1));
m_websocket.setOnMessageCallback([this](auto &&msg) { OnMessage(std::forward<decltype(msg)>(msg)); });
m_websocket.setExtraHeaders(ix::WebSocketHttpHeaders { { "User-Agent", m_agent } }); // idk if this actually works
m_websocket.start();
}
void Websocket::SetUserAgent(std::string agent) {
m_agent = agent;
m_agent = std::move(agent);
}
bool Websocket::GetPrintMessages() const noexcept {
@ -31,11 +31,6 @@ void Websocket::Stop(uint16_t code) {
m_websocket.stop(code);
}
bool Websocket::IsOpen() const {
auto state = m_websocket.getReadyState();
return state == ix::ReadyState::Open;
}
void Websocket::Send(const std::string &str) {
if (m_print_messages)
printf("sending %s\n", str.c_str());

View File

@ -9,7 +9,7 @@
class Websocket {
public:
Websocket();
void StartConnection(std::string url);
void StartConnection(const std::string &url);
void SetUserAgent(std::string agent);
@ -20,7 +20,6 @@ public:
void Send(const nlohmann::json &j);
void Stop();
void Stop(uint16_t code);
bool IsOpen() const;
private:
void OnMessage(const ix::WebSocketMessagePtr &msg);

View File

@ -1,8 +1,9 @@
#include "emojis.hpp"
#include <sstream>
#include <utility>
EmojiResource::EmojiResource(std::string filepath)
: m_filepath(filepath) {}
: m_filepath(std::move(filepath)) {}
bool EmojiResource::Load() {
m_fp = std::fopen(m_filepath.c_str(), "rb");
@ -31,7 +32,7 @@ bool EmojiResource::Load() {
std::fread(&surrogates_count, 4, 1, m_fp);
std::string surrogates(surrogates_count, '\0');
std::fread(surrogates.data(), surrogates_count, 1, m_fp);
m_patterns.push_back(surrogates);
m_patterns.emplace_back(surrogates);
int data_size, data_offset;
std::fread(&data_size, 4, 1, m_fp);
@ -52,7 +53,7 @@ bool EmojiResource::Load() {
Glib::RefPtr<Gdk::Pixbuf> EmojiResource::GetPixBuf(const Glib::ustring &pattern) {
const auto it = m_index.find(pattern);
if (it == m_index.end()) return Glib::RefPtr<Gdk::Pixbuf>();
if (it == m_index.end()) return {};
const int pos = it->second.first;
const int len = it->second.second;
std::fseek(m_fp, pos, SEEK_SET);
@ -86,17 +87,17 @@ void EmojiResource::ReplaceEmojis(Glib::RefPtr<Gtk::TextBuffer> buf, int size) {
else
break;
}
searchpos = r + pattern.size();
searchpos = static_cast<int>(r + pattern.size());
const auto start_it = buf->get_iter_at_offset(r);
const auto end_it = buf->get_iter_at_offset(r + pattern.size());
const auto start_it = buf->get_iter_at_offset(static_cast<int>(r));
const auto end_it = buf->get_iter_at_offset(static_cast<int>(r + pattern.size()));
auto it = buf->erase(start_it, end_it);
buf->insert_pixbuf(it, pixbuf);
int alen = text.size();
int alen = static_cast<int>(text.size());
text = get_text();
int blen = text.size();
int blen = static_cast<int>(text.size());
searchpos -= (alen - blen);
}
}
@ -109,10 +110,6 @@ std::string EmojiResource::GetShortCodeForPattern(const Glib::ustring &pattern)
return "";
}
const std::vector<Glib::ustring> &EmojiResource::GetPatterns() const {
return m_patterns;
}
const std::map<std::string, std::string> &EmojiResource::GetShortCodes() const {
return m_shortcode_index;
}

View File

@ -12,7 +12,6 @@ public:
EmojiResource(std::string filepath);
bool Load();
Glib::RefPtr<Gdk::Pixbuf> GetPixBuf(const Glib::ustring &pattern);
const std::vector<Glib::ustring> &GetPatterns() const;
const std::map<std::string, std::string> &GetShortCodes() const;
void ReplaceEmojis(Glib::RefPtr<Gtk::TextBuffer> buf, int size = 24);
std::string GetShortCodeForPattern(const Glib::ustring &pattern);

View File

@ -1,10 +1,12 @@
#include "abaddon.hpp"
#include "filecache.hpp"
#include <utility>
#include "MurmurHash3.h"
std::string GetCachedName(std::string str) {
std::string GetCachedName(const std::string &str) {
uint32_t out;
MurmurHash3_x86_32(str.c_str(), str.size(), 0, &out);
MurmurHash3_x86_32(str.c_str(), static_cast<int>(str.size()), 0, &out);
return std::to_string(out);
}
@ -35,15 +37,15 @@ void Cache::ClearCache() {
std::filesystem::remove_all(path);
}
void Cache::RespondFromPath(std::filesystem::path path, callback_type cb) {
void Cache::RespondFromPath(const std::filesystem::path &path, const callback_type &cb) {
cb(path.string());
}
void Cache::GetFileFromURL(std::string url, callback_type cb) {
void Cache::GetFileFromURL(const std::string &url, const callback_type &cb) {
auto cache_path = m_tmp_path / GetCachedName(url);
if (std::filesystem::exists(cache_path)) {
m_mutex.lock();
m_futures.push_back(std::async(std::launch::async, [this, cache_path, cb]() { RespondFromPath(cache_path, cb); }));
m_futures.push_back(std::async(std::launch::async, [cache_path, cb]() { RespondFromPath(cache_path, cb); }));
m_mutex.unlock();
return;
}
@ -58,7 +60,7 @@ void Cache::GetFileFromURL(std::string url, callback_type cb) {
}
}
std::string Cache::GetPathIfCached(std::string url) {
std::string Cache::GetPathIfCached(const std::string &url) {
auto cache_path = m_tmp_path / GetCachedName(url);
if (std::filesystem::exists(cache_path)) {
return cache_path.string();
@ -94,13 +96,13 @@ void Cache::OnResponse(const std::string &url) {
void Cache::OnFetchComplete(const std::string &url) {
m_mutex.lock();
m_futures.push_back(std::async(std::launch::async, std::bind(&Cache::OnResponse, this, url)));
m_futures.push_back(std::async(std::launch::async, [this, url] { OnResponse(url); }));
m_mutex.unlock();
}
FileCacheWorkerThread::FileCacheWorkerThread() {
m_multi_handle = curl_multi_init();
m_thread = std::thread(std::bind(&FileCacheWorkerThread::loop, this));
m_thread = std::thread([this] { loop(); });
}
FileCacheWorkerThread::~FileCacheWorkerThread() {
@ -116,7 +118,7 @@ void FileCacheWorkerThread::set_file_path(const std::filesystem::path &path) {
void FileCacheWorkerThread::add_image(const std::string &string, callback_type callback) {
m_queue_mutex.lock();
m_queue.push({ string, callback });
m_queue.push({ string, std::move(callback) });
m_cv.notify_one();
m_queue_mutex.unlock();
}
@ -130,15 +132,14 @@ void FileCacheWorkerThread::stop() {
}
void FileCacheWorkerThread::loop() {
timeval timeout;
timeval timeout {};
timeout.tv_sec = 1;
timeout.tv_usec = 0;
while (!m_stop) {
if (m_handles.size() == 0) {
if (m_handles.empty()) {
std::unique_lock<std::mutex> lock(m_queue_mutex);
int s = m_queue.size();
if (s == 0)
if (m_queue.empty())
m_cv.wait(lock);
}
@ -146,7 +147,7 @@ void FileCacheWorkerThread::loop() {
if (m_handles.size() < concurrency) {
std::optional<QueueEntry> entry;
m_queue_mutex.lock();
if (m_queue.size() > 0) {
if (!m_queue.empty()) {
entry = std::move(m_queue.front());
m_queue.pop();
}

View File

@ -59,13 +59,13 @@ public:
~Cache();
using callback_type = std::function<void(std::string)>;
void GetFileFromURL(std::string url, callback_type cb);
std::string GetPathIfCached(std::string url);
void GetFileFromURL(const std::string &url, const callback_type &cb);
std::string GetPathIfCached(const std::string &url);
void ClearCache();
private:
void CleanupFutures();
void RespondFromPath(std::filesystem::path path, callback_type cb);
static void RespondFromPath(const std::filesystem::path &path, const callback_type &cb);
void OnResponse(const std::string &url);
void OnFetchComplete(const std::string &url);

View File

@ -1,8 +1,10 @@
#include "http.hpp"
#include <utility>
namespace http {
request::request(EMethod method, const std::string &url)
: m_url(url) {
request::request(EMethod method, std::string url)
: m_url(std::move(url)) {
switch (method) {
case REQUEST_GET:
m_method = "GET";

View File

@ -97,7 +97,7 @@ struct response {
};
struct request {
request(EMethod method, const std::string &url);
request(EMethod method, std::string url);
~request();
void set_verify_ssl(bool verify);

View File

@ -1,4 +1,6 @@
#include "imgmanager.hpp"
#include <utility>
#include "util.hpp"
#include "abaddon.hpp"
@ -6,17 +8,13 @@ ImageManager::ImageManager() {
m_cb_dispatcher.connect(sigc::mem_fun(*this, &ImageManager::RunCallbacks));
}
Cache &ImageManager::GetCache() {
return m_cache;
}
void ImageManager::ClearCache() {
m_cache.ClearCache();
}
Glib::RefPtr<Gdk::Pixbuf> ImageManager::ReadFileToPixbuf(std::string path) {
const auto &data = ReadWholeFile(path);
if (data.size() == 0) return Glib::RefPtr<Gdk::Pixbuf>(nullptr);
const auto &data = ReadWholeFile(std::move(path));
if (data.empty()) return Glib::RefPtr<Gdk::Pixbuf>(nullptr);
auto loader = Gdk::PixbufLoader::create();
loader->signal_size_prepared().connect([&loader](int w, int h) {
int cw, ch;
@ -29,8 +27,8 @@ Glib::RefPtr<Gdk::Pixbuf> ImageManager::ReadFileToPixbuf(std::string path) {
}
Glib::RefPtr<Gdk::PixbufAnimation> ImageManager::ReadFileToPixbufAnimation(std::string path, int w, int h) {
const auto &data = ReadWholeFile(path);
if (data.size() == 0) return Glib::RefPtr<Gdk::PixbufAnimation>(nullptr);
const auto &data = ReadWholeFile(std::move(path));
if (data.empty()) return Glib::RefPtr<Gdk::PixbufAnimation>(nullptr);
auto loader = Gdk::PixbufLoader::create();
loader->signal_size_prepared().connect([&loader, w, h](int, int) {
loader->set_size(w, h);
@ -40,10 +38,10 @@ Glib::RefPtr<Gdk::PixbufAnimation> ImageManager::ReadFileToPixbufAnimation(std::
return loader->get_animation();
}
void ImageManager::LoadFromURL(std::string url, callback_type cb) {
void ImageManager::LoadFromURL(const std::string &url, const callback_type &cb) {
sigc::signal<void(Glib::RefPtr<Gdk::Pixbuf>)> signal;
signal.connect(cb);
m_cache.GetFileFromURL(url, [this, url, signal](std::string path) {
m_cache.GetFileFromURL(url, [this, url, signal](const std::string &path) {
try {
auto buf = ReadFileToPixbuf(path);
if (!buf)
@ -60,10 +58,10 @@ void ImageManager::LoadFromURL(std::string url, callback_type cb) {
});
}
void ImageManager::LoadAnimationFromURL(std::string url, int w, int h, callback_anim_type cb) {
void ImageManager::LoadAnimationFromURL(const std::string &url, int w, int h, const callback_anim_type &cb) {
sigc::signal<void(Glib::RefPtr<Gdk::PixbufAnimation>)> signal;
signal.connect(cb);
m_cache.GetFileFromURL(url, [this, url, signal, w, h](std::string path) {
m_cache.GetFileFromURL(url, [this, url, signal, w, h](const std::string &path) {
try {
auto buf = ReadFileToPixbufAnimation(path, w, h);
if (!buf)
@ -80,7 +78,7 @@ void ImageManager::LoadAnimationFromURL(std::string url, int w, int h, callback_
});
}
void ImageManager::Prefetch(std::string url) {
void ImageManager::Prefetch(const std::string &url) {
m_cache.GetFileFromURL(url, [](const auto &) {});
}
@ -91,22 +89,6 @@ void ImageManager::RunCallbacks() {
m_cb_mutex.unlock();
}
Glib::RefPtr<Gdk::Pixbuf> ImageManager::GetFromURLIfCached(std::string url) {
std::string path = m_cache.GetPathIfCached(url);
if (path != "")
return ReadFileToPixbuf(path);
return Glib::RefPtr<Gdk::Pixbuf>(nullptr);
}
Glib::RefPtr<Gdk::PixbufAnimation> ImageManager::GetAnimationFromURLIfCached(std::string url, int w, int h) {
std::string path = m_cache.GetPathIfCached(url);
if (path != "")
return ReadFileToPixbufAnimation(path, w, h);
return Glib::RefPtr<Gdk::PixbufAnimation>(nullptr);
}
Glib::RefPtr<Gdk::Pixbuf> ImageManager::GetPlaceholder(int size) {
std::string name = "/placeholder" + std::to_string(size);
if (m_pixs.find(name) != m_pixs.end())

View File

@ -13,19 +13,16 @@ public:
using callback_anim_type = sigc::slot<void(Glib::RefPtr<Gdk::PixbufAnimation>)>;
using callback_type = sigc::slot<void(Glib::RefPtr<Gdk::Pixbuf>)>;
Cache &GetCache();
void ClearCache();
void LoadFromURL(std::string url, callback_type cb);
void LoadFromURL(const std::string &url, const callback_type &cb);
// animations need dimensions before loading since there is no (easy) way to scale a PixbufAnimation
void LoadAnimationFromURL(std::string url, int w, int h, callback_anim_type cb);
void Prefetch(std::string url);
Glib::RefPtr<Gdk::Pixbuf> GetFromURLIfCached(std::string url);
Glib::RefPtr<Gdk::PixbufAnimation> GetAnimationFromURLIfCached(std::string url, int w, int h);
void LoadAnimationFromURL(const std::string &url, int w, int h, const callback_anim_type &cb);
void Prefetch(const std::string &url);
Glib::RefPtr<Gdk::Pixbuf> GetPlaceholder(int size);
private:
Glib::RefPtr<Gdk::Pixbuf> ReadFileToPixbuf(std::string path);
Glib::RefPtr<Gdk::PixbufAnimation> ReadFileToPixbufAnimation(std::string path, int w, int h);
static Glib::RefPtr<Gdk::Pixbuf> ReadFileToPixbuf(std::string path);
static Glib::RefPtr<Gdk::PixbufAnimation> ReadFileToPixbufAnimation(std::string path, int w, int h);
mutable std::mutex m_load_mutex;
void RunCallbacks();

View File

@ -46,7 +46,7 @@ public:
SettingsManager(const std::string &filename);
void Close();
bool IsValid() const;
[[nodiscard]] bool IsValid() const;
Settings &GetSettings();
private:

View File

@ -1,33 +1,15 @@
#include "util.hpp"
#include <array>
#include <filesystem>
#include <array>
Semaphore::Semaphore(int count)
: m_count(count) {}
void Semaphore::notify() {
std::unique_lock<std::mutex> lock(m_mutex);
m_count++;
lock.unlock();
m_cv.notify_one();
}
void Semaphore::wait() {
std::unique_lock<std::mutex> lock(m_mutex);
while (m_count == 0)
m_cv.wait(lock);
m_count--;
}
void LaunchBrowser(Glib::ustring url) {
void LaunchBrowser(const Glib::ustring &url) {
GError *err = nullptr;
if (!gtk_show_uri_on_window(nullptr, url.c_str(), GDK_CURRENT_TIME, &err))
printf("failed to open uri: %s\n", err->message);
}
void GetImageDimensions(int inw, int inh, int &outw, int &outh, int clampw, int clamph) {
const auto frac = static_cast<float>(inw) / inh;
const auto frac = static_cast<float>(inw) / static_cast<float>(inh);
outw = inw;
outh = inh;
@ -43,7 +25,7 @@ void GetImageDimensions(int inw, int inh, int &outw, int &outh, int clampw, int
}
}
std::vector<uint8_t> ReadWholeFile(std::string path) {
std::vector<uint8_t> ReadWholeFile(const std::string &path) {
std::vector<uint8_t> ret;
FILE *fp = std::fopen(path.c_str(), "rb");
if (fp == nullptr)
@ -74,7 +56,7 @@ int GetTimezoneOffset() {
std::time_t local_secs = std::mktime(tptr);
tptr = std::gmtime(&secs);
std::time_t gmt_secs = std::mktime(tptr);
return local_secs - gmt_secs;
return static_cast<int>(local_secs - gmt_secs);
}
std::string FormatISO8601(const std::string &in, int extra_offset, const std::string &fmt) {
@ -82,7 +64,7 @@ std::string FormatISO8601(const std::string &in, int extra_offset, const std::st
float milli;
std::sscanf(in.c_str(), "%d-%d-%dT%d:%d:%d%f+%d:%d",
&yr, &mon, &day, &hr, &min, &sec, &milli, &tzhr, &tzmin);
std::tm tm;
std::tm tm {};
tm.tm_year = yr - 1900;
tm.tm_mon = mon - 1;
tm.tm_mday = day;
@ -95,7 +77,7 @@ std::string FormatISO8601(const std::string &in, int extra_offset, const std::st
int offset = GetTimezoneOffset();
tm.tm_sec += offset + extra_offset;
mktime(&tm);
std::array<char, 512> tmp;
std::array<char, 512> tmp {};
std::strftime(tmp.data(), sizeof(tmp), fmt.c_str(), &tm);
return tmp.data();
}
@ -144,13 +126,9 @@ Gdk::RGBA IntToRGBA(int color) {
return ret;
}
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu) {
AddWidgetMenuHandler(widget, menu, []() {});
}
// so widgets can modify the menu before it is displayed
// maybe theres a better way to do this idk
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu, sigc::slot<void()> pre_callback) {
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu, const sigc::slot<void()> &pre_callback) {
sigc::signal<void()> signal;
signal.connect(pre_callback);
widget->signal_button_press_event().connect([&menu, signal](GdkEventButton *ev) -> bool {
@ -169,7 +147,7 @@ std::vector<std::string> StringSplit(const std::string &str, const char *delim)
std::vector<std::string> parts;
char *token = std::strtok(const_cast<char *>(str.c_str()), delim);
while (token != nullptr) {
parts.push_back(token);
parts.emplace_back(token);
token = std::strtok(nullptr, delim);
}
return parts;
@ -178,7 +156,7 @@ std::vector<std::string> StringSplit(const std::string &str, const char *delim)
std::string GetExtension(std::string url) {
url = StringSplit(url, "?")[0];
url = StringSplit(url, "/").back();
return url.find(".") != std::string::npos ? url.substr(url.find_last_of(".")) : "";
return url.find('.') != std::string::npos ? url.substr(url.find_last_of('.')) : "";
}
bool IsURLViewableImage(const std::string &url) {

View File

@ -31,28 +31,15 @@ bool IsFile(std::string_view path);
uint64_t TimeToEpoch(int year, int month, int day, int hour, int minute, int seconds);
} // namespace util
class Semaphore {
public:
Semaphore(int count = 0);
void notify();
void wait();
private:
std::mutex m_mutex;
std::condition_variable m_cv;
int m_count;
};
void LaunchBrowser(Glib::ustring url);
void LaunchBrowser(const Glib::ustring &url);
void GetImageDimensions(int inw, int inh, int &outw, int &outh, int clampw = 400, int clamph = 300);
std::string IntToCSSColor(int color);
Gdk::RGBA IntToRGBA(int color);
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu);
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu, sigc::slot<void()> pre_callback);
void AddWidgetMenuHandler(Gtk::Widget *widget, Gtk::Menu &menu, const sigc::slot<void()> &pre_callback);
std::vector<std::string> StringSplit(const std::string &str, const char *delim);
std::string GetExtension(std::string url);
bool IsURLViewableImage(const std::string &url);
std::vector<uint8_t> ReadWholeFile(std::string path);
std::vector<uint8_t> ReadWholeFile(const std::string &path);
std::string HumanReadableBytes(uint64_t bytes);
std::string FormatISO8601(const std::string &in, int extra_offset = 0, const std::string &fmt = "%x %X");
void AddPointerCursor(Gtk::Widget &widget);

View File

@ -30,7 +30,7 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
auto &discord = Abaddon::Get().GetDiscordClient();
auto guild = *discord.GetGuild(GuildID);
for (const auto &entry : data.Entries) {
if (entry.TargetID == "") continue;
if (entry.TargetID.empty()) continue;
auto expander = Gtk::manage(new Gtk::Expander);
auto label = Gtk::manage(new Gtk::Label);
@ -56,7 +56,7 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
if (entry.Changes.has_value())
for (const auto &change : *entry.Changes) {
if (change.Key == "icon_hash") {
extra_markup.push_back("Set the server icon");
extra_markup.emplace_back("Set the server icon");
} else if (change.Key == "name") {
auto new_name = change.NewValue;
if (new_name.has_value())
@ -64,7 +64,7 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(new_name->get<std::string>()) +
"</b>");
else
extra_markup.push_back("Set the server name");
extra_markup.emplace_back("Set the server name");
}
}
} break;
@ -82,8 +82,8 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(change.NewValue->get<std::string>()) +
"</b>");
else if (change.Key == "nsfw" && change.NewValue.has_value())
extra_markup.push_back((*change.NewValue ? "Marked" : "Unmarked") +
" the channel as NSFW"s);
extra_markup.emplace_back((*change.NewValue ? "Marked" : "Unmarked") +
" the channel as NSFW"s);
}
} break;
@ -119,16 +119,16 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(change.NewValue->get<std::string>()) +
"</b>");
else
extra_markup.push_back("Cleared the topic");
extra_markup.emplace_back("Cleared the topic");
} else if (change.Key == "nsfw" && change.NewValue.has_value()) {
extra_markup.push_back((*change.NewValue ? "Marked" : "Unmarked") + " the channel as NSFW"s);
extra_markup.emplace_back((*change.NewValue ? "Marked" : "Unmarked") + " the channel as NSFW"s);
} else if (change.Key == "rate_limit_per_user" && change.NewValue.has_value()) {
const int secs = change.NewValue->get<int>();
if (secs == 0)
extra_markup.push_back("Disabled slowmode");
extra_markup.emplace_back("Disabled slowmode");
else
extra_markup.push_back("Set slowmode to <b>" +
std::to_string(secs) + " seconds</b>");
extra_markup.emplace_back("Set slowmode to <b>" +
std::to_string(secs) + " seconds</b>");
}
}
} break;
@ -186,9 +186,9 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
" pruned <b>" +
*entry.Options->MembersRemoved +
"</b> members";
extra_markup.push_back("For <b>" +
*entry.Options->DeleteMemberDays +
" days</b> of inactivity");
extra_markup.emplace_back("For <b>" +
*entry.Options->DeleteMemberDays +
" days</b> of inactivity");
} break;
case AuditLogActionType::MEMBER_BAN_ADD: {
const auto target_user = discord.GetUser(entry.TargetID);
@ -213,13 +213,11 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
if (entry.Changes.has_value())
for (const auto &change : *entry.Changes) {
if (change.Key == "deaf" && change.NewValue.has_value())
extra_markup.push_back(
(change.NewValue->get<bool>() ? "<b>Deafened</b>"s : "<b>Undeafened</b>"s) +
" them");
extra_markup.emplace_back((change.NewValue->get<bool>() ? "<b>Deafened</b>"s : "<b>Undeafened</b>"s) +
" them");
else if (change.Key == "mute" && change.NewValue.has_value())
extra_markup.push_back(
(change.NewValue->get<bool>() ? "<b>Muted</b>"s : "<b>Unmuted</b>"s) +
" them");
extra_markup.emplace_back((change.NewValue->get<bool>() ? "<b>Muted</b>"s : "<b>Unmuted</b>"s) +
" them");
else if (change.Key == "nick" && change.NewValue.has_value())
extra_markup.push_back("Set their nickname to <b>" +
Glib::Markup::escape_text(change.NewValue->get<std::string>()) +
@ -289,17 +287,17 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
} else if (change.Key == "color" && change.NewValue.has_value()) {
const auto col = change.NewValue->get<int>();
if (col == 0)
extra_markup.push_back("Removed the color");
extra_markup.emplace_back("Removed the color");
else
extra_markup.push_back("Set the color to <b>" +
IntToCSSColor(col) +
"</b>");
extra_markup.emplace_back("Set the color to <b>" +
IntToCSSColor(col) +
"</b>");
} else if (change.Key == "permissions") {
extra_markup.push_back("Updated the permissions");
extra_markup.emplace_back("Updated the permissions");
} else if (change.Key == "mentionable" && change.NewValue.has_value()) {
extra_markup.push_back(change.NewValue->get<bool>() ? "Mentionable" : "Not mentionable");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Mentionable" : "Not mentionable");
} else if (change.Key == "hoist" && change.NewValue.has_value()) {
extra_markup.push_back(change.NewValue->get<bool>() ? "Not hoisted" : "Hoisted");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Not hoisted" : "Hoisted");
}
}
} break;
@ -324,13 +322,13 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
} else if (change.Key == "max_uses" && change.NewValue.has_value()) {
const auto uses = change.NewValue->get<int>();
if (uses == 0)
extra_markup.push_back("Which has <b>unlimited</b> uses");
extra_markup.emplace_back("Which has <b>unlimited</b> uses");
else
extra_markup.push_back("Which has <b>" + std::to_string(uses) + "</b> uses");
extra_markup.emplace_back("Which has <b>" + std::to_string(uses) + "</b> uses");
} else if (change.Key == "temporary" && change.NewValue.has_value()) {
extra_markup.push_back("With temporary <b>"s +
(change.NewValue->get<bool>() ? "on" : "off") +
"</b>");
extra_markup.emplace_back("With temporary <b>"s +
(change.NewValue->get<bool>() ? "on" : "off") +
"</b>");
} // no max_age cuz fuck time
}
} break;
@ -378,7 +376,7 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(change.NewValue->get<std::string>()) +
"</b>");
} else if (change.Key == "avatar_hash") {
extra_markup.push_back("Changed the avatar");
extra_markup.emplace_back("Changed the avatar");
} else if (change.Key == "channel_id" && change.NewValue.has_value()) {
const auto channel = discord.GetChannel(change.NewValue->get<Snowflake>());
if (channel.has_value()) {
@ -386,7 +384,7 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(*channel->Name) +
"</b>");
} else {
extra_markup.push_back("Changed the channel");
extra_markup.emplace_back("Changed the channel");
}
}
}
@ -552,18 +550,18 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
if (change.Key == "name")
extra_markup.push_back("Set the name to <b>" + Glib::Markup::escape_text(change.NewValue->get<std::string>()) + "</b>");
else if (change.Key == "archived")
extra_markup.push_back(change.NewValue->get<bool>() ? "Archived the thread" : "Unarchived the thread");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Archived the thread" : "Unarchived the thread");
else if (change.Key == "auto_archive_duration")
extra_markup.push_back("Set auto archive duration to <b>"s + std::to_string(change.NewValue->get<int>()) + " minutes</b>"s);
extra_markup.emplace_back("Set auto archive duration to <b>"s + std::to_string(change.NewValue->get<int>()) + " minutes</b>"s);
else if (change.Key == "rate_limit_per_user" && change.NewValue.has_value()) {
const int secs = change.NewValue->get<int>();
if (secs == 0)
extra_markup.push_back("Disabled slowmode");
extra_markup.emplace_back("Disabled slowmode");
else
extra_markup.push_back("Set slowmode to <b>" +
std::to_string(secs) + " seconds</b>");
extra_markup.emplace_back("Set slowmode to <b>" +
std::to_string(secs) + " seconds</b>");
} else if (change.Key == "locked")
extra_markup.push_back(change.NewValue->get<bool>() ? "Locked the thread, restricting it to only be unarchived by moderators" : "Unlocked the thread, allowing it to be unarchived by non-moderators");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Locked the thread, restricting it to only be unarchived by moderators" : "Unlocked the thread, allowing it to be unarchived by non-moderators");
}
}
} break;
@ -584,19 +582,19 @@ void GuildSettingsAuditLogPane::OnAuditLogFetch(const AuditLogData &data) {
Glib::Markup::escape_text(change.NewValue->get<std::string>()) +
"</b>");
else if (change.Key == "auto_archive_duration")
extra_markup.push_back("Set auto archive duration to <b>"s + std::to_string(change.NewValue->get<int>()) + " minutes</b>"s);
extra_markup.emplace_back("Set auto archive duration to <b>"s + std::to_string(change.NewValue->get<int>()) + " minutes</b>"s);
else if (change.Key == "rate_limit_per_user" && change.NewValue.has_value()) {
const int secs = change.NewValue->get<int>();
if (secs == 0)
extra_markup.push_back("Disabled slowmode");
extra_markup.emplace_back("Disabled slowmode");
else
extra_markup.push_back("Set slowmode to <b>" +
std::to_string(secs) +
" seconds</b>");
extra_markup.emplace_back("Set slowmode to <b>" +
std::to_string(secs) +
" seconds</b>");
} else if (change.Key == "locked")
extra_markup.push_back(change.NewValue->get<bool>() ? "Locked the thread, restricting it to only be unarchived by moderators" : "Unlocked the thread, allowing it to be unarchived by non-moderators");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Locked the thread, restricting it to only be unarchived by moderators" : "Unlocked the thread, allowing it to be unarchived by non-moderators");
else if (change.Key == "archived")
extra_markup.push_back(change.NewValue->get<bool>() ? "Archived the thread" : "Unarchived the thread");
extra_markup.emplace_back(change.NewValue->get<bool>() ? "Archived the thread" : "Unarchived the thread");
}
} break;
case AuditLogActionType::THREAD_DELETE: {

View File

@ -94,7 +94,7 @@ void GuildSettingsBansPane::OnMenuUnban() {
auto selected_row = *m_view.get_selection()->get_selected();
if (selected_row) {
Snowflake id = selected_row[m_columns.m_col_id];
auto cb = [this](DiscordError code) {
auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to unban user", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -119,7 +119,7 @@ bool GuildSettingsBansPane::OnTreeButtonPress(GdkEventButton *event) {
m_menu_unban.set_sensitive(can_ban);
auto selection = m_view.get_selection();
Gtk::TreeModel::Path path;
if (m_view.get_path_at_pos(event->x, event->y, path)) {
if (m_view.get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
m_view.get_selection()->select(path);
m_menu.popup_at_pointer(reinterpret_cast<GdkEvent *>(event));
}

View File

@ -52,7 +52,7 @@ GuildSettingsEmojisPane::GuildSettingsEmojisPane(Snowflake guild_id)
m_filter->set_visible_func([this](const Gtk::TreeModel::const_iterator &iter) -> bool {
const auto text = m_search.get_text();
if (text == "") return true;
if (text.empty()) return true;
return StringContainsCaseless((*iter)[m_columns.m_col_name], text);
});
m_view.set_enable_search(false);
@ -71,12 +71,12 @@ GuildSettingsEmojisPane::GuildSettingsEmojisPane(Snowflake guild_id)
column->pack_start(*renderer);
column->add_attribute(renderer->property_text(), m_columns.m_col_name);
renderer->property_editable() = true;
renderer->signal_edited().connect([this, renderer, column](const Glib::ustring &path, const Glib::ustring &text) {
renderer->signal_edited().connect([this](const Glib::ustring &path, const Glib::ustring &text) {
std::string new_str;
int size = 0;
for (const auto ch : text) {
if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9') || ch == '_')
new_str += ch;
new_str += static_cast<char>(ch);
else if (ch == ' ')
new_str += '_';
if (++size == 32) break;
@ -174,7 +174,7 @@ void GuildSettingsEmojisPane::OnFetchEmojis(std::vector<EmojiData> emojis) {
}
void GuildSettingsEmojisPane::OnEditName(Snowflake id, const std::string &name) {
const auto cb = [this](DiscordError code) {
const auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to set emoji name", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -197,7 +197,7 @@ void GuildSettingsEmojisPane::OnMenuDelete() {
const auto id = static_cast<Snowflake>(selected_row[m_columns.m_col_id]);
if (auto *window = dynamic_cast<Gtk::Window *>(get_toplevel()))
if (Abaddon::Get().ShowConfirm("Are you sure you want to delete " + name + "?", window)) {
const auto cb = [this](DiscordError code) {
const auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to delete emoji", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -234,7 +234,7 @@ bool GuildSettingsEmojisPane::OnTreeButtonPress(GdkEventButton *event) {
auto selection = m_view.get_selection();
Gtk::TreeModel::Path path;
if (m_view.get_path_at_pos(event->x, event->y, path)) {
if (m_view.get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
m_view.get_selection()->select(path);
m_menu.popup_at_pointer(reinterpret_cast<GdkEvent *>(event));
}

View File

@ -60,7 +60,7 @@ GuildSettingsInfoPane::GuildSettingsInfoPane(Snowflake id)
guild_icon_url = guild.GetIconURL("gif", "512");
else
guild_icon_url = guild.GetIconURL("png", "512");
m_guild_icon_ev.signal_button_press_event().connect([this, guild_icon_url](GdkEventButton *event) -> bool {
m_guild_icon_ev.signal_button_press_event().connect([guild_icon_url](GdkEventButton *event) -> bool {
if (event->type == GDK_BUTTON_PRESS)
if (event->button == GDK_BUTTON_PRIMARY)
LaunchBrowser(guild_icon_url);
@ -114,7 +114,7 @@ void GuildSettingsInfoPane::UpdateGuildIconFromData(const std::vector<uint8_t> &
auto encoded = "data:" + mime + ";base64," + Glib::Base64::encode(std::string(data.begin(), data.end()));
auto &discord = Abaddon::Get().GetDiscordClient();
auto cb = [this](DiscordError code) {
auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to set guild icon", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -160,7 +160,7 @@ void GuildSettingsInfoPane::UpdateGuildIconPicker() {
loader->write(data.data(), data.size());
loader->close();
UpdateGuildIconFromPixbuf(loader->get_pixbuf());
} catch (const std::exception &) {};
} catch (const std::exception &) {}
}
});
@ -209,7 +209,7 @@ void GuildSettingsInfoPane::UpdateGuildIconClipboard() {
UpdateGuildIconFromPixbuf(pb);
return;
} catch (const std::exception &) {};
} catch (const std::exception &) {}
}
if (cb->wait_is_image_available()) {

View File

@ -96,7 +96,7 @@ void GuildSettingsInvitesPane::OnMenuDelete() {
auto selected_row = *m_view.get_selection()->get_selected();
if (selected_row) {
auto code = static_cast<Glib::ustring>(selected_row[m_columns.m_col_code]);
auto cb = [this](DiscordError code) {
auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to delete invite", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -115,7 +115,7 @@ bool GuildSettingsInvitesPane::OnTreeButtonPress(GdkEventButton *event) {
m_menu_delete.set_sensitive(can_manage);
auto selection = m_view.get_selection();
Gtk::TreeModel::Path path;
if (m_view.get_path_at_pos(event->x, event->y, path)) {
if (m_view.get_path_at_pos(static_cast<int>(event->x), static_cast<int>(event->y), path)) {
m_view.get_selection()->select(path);
m_menu.popup_at_pointer(reinterpret_cast<GdkEvent *>(event));
}

View File

@ -64,7 +64,7 @@ GuildSettingsMembersPaneMembers::GuildSettingsMembersPaneMembers(Snowflake id)
m_list.set_filter_func([this](Gtk::ListBoxRow *row_) -> bool {
const auto search_term = m_search.get_text();
if (search_term.size() == 0) return true;
if (search_term.empty()) return true;
if (auto *row = dynamic_cast<GuildSettingsMembersListItem *>(row_))
return StringContainsCaseless(row->DisplayTerm, m_search.get_text());
return true;
@ -208,12 +208,12 @@ void GuildSettingsMembersPaneInfo::SetUser(Snowflake user_id) {
m_id.set_text("User ID: " + std::to_string(user_id));
m_created.set_text("Account created: " + user_id.GetLocalTimestamp());
if (member.JoinedAt != "")
if (!member.JoinedAt.empty())
m_joined.set_text("Joined server: " + FormatISO8601(member.JoinedAt));
else
m_joined.set_text("Joined server: Unknown");
m_nickname.set_text("Nickname: " + member.Nickname);
m_nickname.set_visible(member.Nickname != "");
m_nickname.set_visible(!member.Nickname.empty());
if (member.PremiumSince.has_value()) {
m_boosting.set_text("Boosting since " + FormatISO8601(*member.PremiumSince));
m_boosting.show();
@ -244,7 +244,7 @@ GuildSettingsMembersPaneRoles::GuildSettingsMembersPaneRoles(Snowflake guild_id)
}
}
m_list.set_sort_func([this](Gtk::ListBoxRow *a, Gtk::ListBoxRow *b) -> int {
m_list.set_sort_func([](Gtk::ListBoxRow *a, Gtk::ListBoxRow *b) -> int {
auto *rowa = dynamic_cast<GuildSettingsMembersPaneRolesItem *>(a);
auto *rowb = dynamic_cast<GuildSettingsMembersPaneRolesItem *>(b);
return rowb->Position - rowa->Position;
@ -319,8 +319,8 @@ void GuildSettingsMembersPaneRoles::OnRoleToggle(Snowflake role_id, bool new_set
// hack to prevent cb from being called if SetRoles is called before callback completion
sigc::signal<void, bool> tmp;
m_update_connection.push_back(tmp.connect(std::move(cb)));
const auto tmp_cb = [this, tmp = std::move(tmp)](DiscordError code) { tmp.emit(code == DiscordError::NONE); };
m_update_connection.emplace_back(tmp.connect(std::move(cb)));
const auto tmp_cb = [tmp = std::move(tmp)](DiscordError code) { tmp.emit(code == DiscordError::NONE); };
discord.SetMemberRoles(GuildID, UserID, m_set_role_ids.begin(), m_set_role_ids.end(), sigc::track_obj(tmp_cb, *this));
}

View File

@ -61,14 +61,14 @@ GuildSettingsRolesPaneRoles::GuildSettingsRolesPaneRoles(Snowflake guild_id)
if (static_cast<size_t>(new_index) == num_rows) return true; // trying to move row below @everyone
// make sure it wont modify a neighbor role u dont have perms to modify
if (!discord.CanModifyRole(GuildID, row->RoleID)) return false;
const auto cb = [this](DiscordError code) {
const auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to set role position", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER_ON_PARENT);
dlg.run();
}
};
discord.ModifyRolePosition(GuildID, row->RoleID, new_pos, sigc::track_obj(cb, *this));
discord.ModifyRolePosition(GuildID, row->RoleID, static_cast<int>(new_pos), sigc::track_obj(cb, *this));
return true;
}
return false;
@ -95,7 +95,7 @@ GuildSettingsRolesPaneRoles::GuildSettingsRolesPaneRoles(Snowflake guild_id)
}
}
m_list.set_sort_func([this](Gtk::ListBoxRow *rowa_, Gtk::ListBoxRow *rowb_) -> int {
m_list.set_sort_func([](Gtk::ListBoxRow *rowa_, Gtk::ListBoxRow *rowb_) -> int {
auto *rowa = dynamic_cast<GuildSettingsRolesPaneRolesListItem *>(rowa_);
auto *rowb = dynamic_cast<GuildSettingsRolesPaneRolesListItem *>(rowb_);
return rowb->Position - rowa->Position;
@ -104,7 +104,7 @@ GuildSettingsRolesPaneRoles::GuildSettingsRolesPaneRoles(Snowflake guild_id)
m_list.set_filter_func([this](Gtk::ListBoxRow *row_) -> bool {
const auto search_term = m_search.get_text();
if (search_term.size() == 0) return true;
if (search_term.empty()) return true;
if (auto *row = dynamic_cast<GuildSettingsRolesPaneRolesListItem *>(row_))
return StringContainsCaseless(row->DisplayTerm, m_search.get_text());
return true;
@ -380,8 +380,8 @@ void GuildSettingsRolesPaneInfo::OnPermissionToggle(Permission perm, bool new_se
m_perms &= ~perm;
sigc::signal<void, bool> tmp;
m_update_connections.push_back(tmp.connect(std::move(cb)));
const auto tmp_cb = [this, tmp = std::move(tmp)](DiscordError code) { tmp.emit(code == DiscordError::NONE); };
m_update_connections.emplace_back(tmp.connect(std::move(cb)));
const auto tmp_cb = [tmp = std::move(tmp)](DiscordError code) { tmp.emit(code == DiscordError::NONE); };
discord.ModifyRolePermissions(GuildID, RoleID, m_perms, sigc::track_obj(tmp_cb, *this));
}

View File

@ -84,7 +84,7 @@ MainWindow::MainWindow()
m_signal_action_set_status.emit();
});
m_menu_file_clear_cache.signal_activate().connect([this] {
m_menu_file_clear_cache.signal_activate().connect([] {
Abaddon::Get().GetImageManager().ClearCache();
});
@ -115,7 +115,7 @@ MainWindow::MainWindow()
}
});
m_menu_view_mark_all_as_read.signal_activate().connect([this] {
m_menu_view_mark_all_as_read.signal_activate().connect([] {
Abaddon::Get().GetDiscordClient().MarkAllAsRead(NOOP_CALLBACK);
});
@ -231,7 +231,7 @@ void MainWindow::UpdateChatPrependHistory(const std::vector<Message> &msgs) {
m_chat.AddNewHistory(msgs); // given vector should be sorted ascending
}
void MainWindow::InsertChatInput(std::string text) {
void MainWindow::InsertChatInput(const std::string &text) {
m_chat.InsertChatInput(text);
}
@ -260,7 +260,7 @@ void MainWindow::OnDiscordSubmenuPopup(const Gdk::Rectangle *flipped_rect, const
const bool discord_active = Abaddon::Get().GetDiscordClient().IsStarted();
std::string token = Abaddon::Get().GetDiscordToken();
m_menu_discord_connect.set_sensitive(token.size() > 0 && !discord_active);
m_menu_discord_connect.set_sensitive(!token.empty() && !discord_active);
m_menu_discord_disconnect.set_sensitive(discord_active);
m_menu_discord_join_guild.set_sensitive(discord_active);
m_menu_discord_set_token.set_sensitive(!discord_active);

View File

@ -19,7 +19,7 @@ public:
void UpdateChatMessageDeleted(Snowflake id, Snowflake channel_id);
void UpdateChatMessageUpdated(Snowflake id, Snowflake channel_id);
void UpdateChatPrependHistory(const std::vector<Message> &msgs);
void InsertChatInput(std::string text);
void InsertChatInput(const std::string &text);
Snowflake GetChatOldestListedMessage();
void UpdateChatReactionAdd(Snowflake id, const Glib::ustring &param);
void UpdateChatReactionRemove(Snowflake id, const Glib::ustring &param);

View File

@ -39,8 +39,8 @@ ConnectionItem::ConnectionItem(const ConnectionData &conn)
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 (!url.empty()) {
auto cb = [url](GdkEventButton *event) -> bool {
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) {
LaunchBrowser(url);
return true;
@ -102,7 +102,7 @@ void ConnectionsContainer::SetConnections(const std::vector<ConnectionData> &con
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);
attach(*widget, static_cast<int>(i % 2), static_cast<int>(i / 2), 1, 1);
}
set_halign(Gtk::ALIGN_FILL);
@ -185,7 +185,7 @@ ProfileUserInfoPane::ProfileUserInfoPane(Snowflake ID)
m_created.get_style_context()->add_class("profile-info-created");
m_note.signal_update_note().connect([this](const Glib::ustring &note) {
auto cb = [this](DiscordError code) {
auto cb = [](DiscordError code) {
if (code != DiscordError::NONE) {
Gtk::MessageDialog dlg("Failed to set note", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
dlg.set_position(Gtk::WIN_POS_CENTER);
@ -196,7 +196,7 @@ ProfileUserInfoPane::ProfileUserInfoPane(Snowflake ID)
});
auto &discord = Abaddon::Get().GetDiscordClient();
auto note_update_cb = [this](Snowflake id, std::string note) {
auto note_update_cb = [this](Snowflake id, const std::string &note) {
if (id == UserID)
m_note.SetNote(note);
};
@ -225,7 +225,7 @@ ProfileUserInfoPane::ProfileUserInfoPane(Snowflake ID)
}
void ProfileUserInfoPane::SetProfile(const UserProfileData &data) {
if (data.User.Bio.has_value() && *data.User.Bio != "") {
if (data.User.Bio.has_value() && !data.User.Bio->empty()) {
m_bio.SetBio(*data.User.Bio);
m_bio.show();
} else {

View File

@ -34,7 +34,7 @@ ProfileWindow::ProfileWindow(Snowflake user_id)
if (user.HasAvatar())
AddPointerCursor(m_avatar_ev);
m_avatar_ev.signal_button_press_event().connect([this, user](GdkEventButton *event) -> bool {
m_avatar_ev.signal_button_press_event().connect([user](GdkEventButton *event) -> bool {
if (event->type == GDK_BUTTON_PRESS && event->button == GDK_BUTTON_PRIMARY) {
if (user.HasAnimatedAvatar())
LaunchBrowser(user.GetAvatarURL("gif", "512"));

View File

@ -62,7 +62,7 @@ ThreadsWindow::ThreadsWindow(const ChannelData &channel)
add(m_box);
}
bool ThreadsWindow::ListFilterFunc(Gtk::ListBoxRow *row_) {
bool ThreadsWindow::ListFilterFunc(Gtk::ListBoxRow *row_) const {
if (auto *row = dynamic_cast<ThreadListRow *>(row_))
return (m_filter_mode == FILTER_PUBLIC && (row->Type == ChannelType::GUILD_PUBLIC_THREAD || row->Type == ChannelType::GUILD_NEWS_THREAD)) ||
(m_filter_mode == FILTER_PRIVATE && row->Type == ChannelType::GUILD_PRIVATE_THREAD);

View File

@ -43,7 +43,7 @@ public:
private:
// this filtering is rather cringe but idk what a better alternative would be
bool ListFilterFunc(Gtk::ListBoxRow *row_);
bool ListFilterFunc(Gtk::ListBoxRow *row_) const;
enum FilterMode {
FILTER_PUBLIC = 0,