2020-08-17 06:40:03 +00:00
|
|
|
#include <gtkmm.h>
|
|
|
|
#include <memory>
|
2020-08-19 05:07:55 +00:00
|
|
|
#include <string>
|
2020-08-20 01:08:57 +00:00
|
|
|
#include <algorithm>
|
2020-08-19 05:07:55 +00:00
|
|
|
#include "discord/discord.hpp"
|
|
|
|
#include "dialogs/token.hpp"
|
2020-08-31 02:55:36 +00:00
|
|
|
#include "dialogs/editmessage.hpp"
|
2020-09-21 22:47:34 +00:00
|
|
|
#include "dialogs/joinguild.hpp"
|
2020-10-12 04:36:18 +00:00
|
|
|
#include "dialogs/confirm.hpp"
|
2020-11-01 07:53:37 +00:00
|
|
|
#include "dialogs/setstatus.hpp"
|
2020-08-17 06:40:03 +00:00
|
|
|
#include "abaddon.hpp"
|
|
|
|
|
|
|
|
#ifdef _WIN32
|
|
|
|
#pragma comment(lib, "crypt32.lib")
|
|
|
|
#endif
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
Abaddon::Abaddon()
|
2020-10-24 23:42:06 +00:00
|
|
|
: m_settings("abaddon.ini")
|
|
|
|
, m_emojis("res/emojis.bin") {
|
2020-08-19 05:07:55 +00:00
|
|
|
LoadFromSettings();
|
2020-09-07 03:34:29 +00:00
|
|
|
|
|
|
|
m_discord.signal_gateway_ready().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnReady));
|
|
|
|
m_discord.signal_channel_list_refresh().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnChannelListRefresh));
|
|
|
|
m_discord.signal_message_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageCreate));
|
|
|
|
m_discord.signal_message_delete().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageDelete));
|
|
|
|
m_discord.signal_message_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnMessageUpdate));
|
|
|
|
m_discord.signal_guild_member_list_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildMemberListUpdate));
|
2020-09-21 22:47:34 +00:00
|
|
|
m_discord.signal_guild_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildCreate));
|
|
|
|
m_discord.signal_guild_delete().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildDelete));
|
2020-10-20 00:35:10 +00:00
|
|
|
m_discord.signal_channel_delete().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnChannelDelete));
|
|
|
|
m_discord.signal_channel_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnChannelUpdate));
|
|
|
|
m_discord.signal_channel_create().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnChannelCreate));
|
2020-11-01 04:01:48 +00:00
|
|
|
m_discord.signal_guild_update().connect(sigc::mem_fun(*this, &Abaddon::DiscordOnGuildUpdate));
|
2020-08-19 05:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Abaddon::~Abaddon() {
|
|
|
|
m_settings.Close();
|
|
|
|
m_discord.Stop();
|
|
|
|
}
|
|
|
|
|
2020-09-07 04:27:41 +00:00
|
|
|
Abaddon &Abaddon::Get() {
|
|
|
|
static Abaddon instance;
|
|
|
|
return instance;
|
|
|
|
}
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
int Abaddon::StartGTK() {
|
2020-08-17 06:40:03 +00:00
|
|
|
m_gtk_app = Gtk::Application::create("com.github.lorpus.abaddon");
|
|
|
|
|
2020-09-03 04:47:49 +00:00
|
|
|
// tmp css stuff
|
|
|
|
m_css_provider = Gtk::CssProvider::create();
|
2020-09-04 05:37:39 +00:00
|
|
|
m_css_provider->signal_parsing_error().connect([this](const Glib::RefPtr<const Gtk::CssSection> §ion, const Glib::Error &error) {
|
|
|
|
Gtk::MessageDialog dlg(*m_main_window, "main.css failed parsing (" + error.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
dlg.run();
|
|
|
|
});
|
2020-09-03 04:47:49 +00:00
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
m_main_window = std::make_unique<MainWindow>();
|
2020-09-03 06:32:28 +00:00
|
|
|
m_main_window->set_title(APP_TITLE);
|
2020-08-19 05:07:55 +00:00
|
|
|
m_main_window->show();
|
2020-08-19 06:05:26 +00:00
|
|
|
m_main_window->UpdateComponents();
|
2020-08-17 06:40:03 +00:00
|
|
|
|
2020-11-08 05:44:26 +00:00
|
|
|
// crashes for some stupid reason if i put it somewhere else
|
|
|
|
m_user_menu = Gtk::manage(new Gtk::Menu);
|
|
|
|
m_user_menu_insert_mention = Gtk::manage(new Gtk::MenuItem("Insert Mention"));
|
|
|
|
m_user_menu_ban = Gtk::manage(new Gtk::MenuItem("Ban"));
|
|
|
|
m_user_menu_kick = Gtk::manage(new Gtk::MenuItem("Kick"));
|
|
|
|
m_user_menu_copy_id = Gtk::manage(new Gtk::MenuItem("Copy ID"));
|
|
|
|
m_user_menu_insert_mention->signal_activate().connect(sigc::mem_fun(*this, &Abaddon::on_user_menu_insert_mention));
|
|
|
|
m_user_menu_ban->signal_activate().connect(sigc::mem_fun(*this, &Abaddon::on_user_menu_ban));
|
|
|
|
m_user_menu_kick->signal_activate().connect(sigc::mem_fun(*this, &Abaddon::on_user_menu_kick));
|
|
|
|
m_user_menu_copy_id->signal_activate().connect(sigc::mem_fun(*this, &Abaddon::on_user_menu_copy_id));
|
|
|
|
m_user_menu->append(*m_user_menu_insert_mention);
|
|
|
|
m_user_menu->append(*m_user_menu_ban);
|
|
|
|
m_user_menu->append(*m_user_menu_kick);
|
|
|
|
m_user_menu->append(*m_user_menu_copy_id);
|
|
|
|
m_user_menu->show_all();
|
|
|
|
|
2020-09-07 06:45:46 +00:00
|
|
|
m_main_window->signal_action_connect().connect(sigc::mem_fun(*this, &Abaddon::ActionConnect));
|
|
|
|
m_main_window->signal_action_disconnect().connect(sigc::mem_fun(*this, &Abaddon::ActionDisconnect));
|
|
|
|
m_main_window->signal_action_set_token().connect(sigc::mem_fun(*this, &Abaddon::ActionSetToken));
|
|
|
|
m_main_window->signal_action_reload_css().connect(sigc::mem_fun(*this, &Abaddon::ActionReloadCSS));
|
2020-09-21 22:47:34 +00:00
|
|
|
m_main_window->signal_action_join_guild().connect(sigc::mem_fun(*this, &Abaddon::ActionJoinGuildDialog));
|
2020-11-01 07:53:37 +00:00
|
|
|
m_main_window->signal_action_set_status().connect(sigc::mem_fun(*this, &Abaddon::ActionSetStatus));
|
2020-09-07 06:45:46 +00:00
|
|
|
|
2020-11-08 05:44:26 +00:00
|
|
|
m_main_window->signal_action_show_user_menu().connect(sigc::mem_fun(*this, &Abaddon::ShowUserMenu));
|
|
|
|
|
2020-11-01 04:13:52 +00:00
|
|
|
m_main_window->GetChannelList()->signal_action_channel_item_select().connect(sigc::mem_fun(*this, &Abaddon::ActionChannelOpened));
|
2020-09-07 06:45:46 +00:00
|
|
|
m_main_window->GetChannelList()->signal_action_guild_move_up().connect(sigc::mem_fun(*this, &Abaddon::ActionMoveGuildUp));
|
|
|
|
m_main_window->GetChannelList()->signal_action_guild_move_down().connect(sigc::mem_fun(*this, &Abaddon::ActionMoveGuildDown));
|
2020-09-21 22:47:34 +00:00
|
|
|
m_main_window->GetChannelList()->signal_action_guild_leave().connect(sigc::mem_fun(*this, &Abaddon::ActionLeaveGuild));
|
2020-09-07 06:45:46 +00:00
|
|
|
|
|
|
|
m_main_window->GetChatWindow()->signal_action_message_delete().connect(sigc::mem_fun(*this, &Abaddon::ActionChatDeleteMessage));
|
|
|
|
m_main_window->GetChatWindow()->signal_action_message_edit().connect(sigc::mem_fun(*this, &Abaddon::ActionChatEditMessage));
|
|
|
|
m_main_window->GetChatWindow()->signal_action_chat_submit().connect(sigc::mem_fun(*this, &Abaddon::ActionChatInputSubmit));
|
|
|
|
m_main_window->GetChatWindow()->signal_action_chat_load_history().connect(sigc::mem_fun(*this, &Abaddon::ActionChatLoadHistory));
|
2020-11-01 04:13:52 +00:00
|
|
|
m_main_window->GetChatWindow()->signal_action_channel_click().connect(sigc::mem_fun(*this, &Abaddon::ActionChannelOpened));
|
2020-10-11 05:56:30 +00:00
|
|
|
m_main_window->GetChatWindow()->signal_action_insert_mention().connect(sigc::mem_fun(*this, &Abaddon::ActionInsertMention));
|
2020-09-07 06:45:46 +00:00
|
|
|
|
2020-09-04 05:37:39 +00:00
|
|
|
ActionReloadCSS();
|
|
|
|
|
2020-08-17 06:40:03 +00:00
|
|
|
m_gtk_app->signal_shutdown().connect([&]() {
|
2020-08-19 05:07:55 +00:00
|
|
|
StopDiscord();
|
2020-08-17 06:40:03 +00:00
|
|
|
});
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
if (!m_settings.IsValid()) {
|
|
|
|
Gtk::MessageDialog dlg(*m_main_window, "The settings file could not be created!", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
dlg.run();
|
|
|
|
}
|
2020-08-17 06:40:03 +00:00
|
|
|
|
2020-10-24 23:42:06 +00:00
|
|
|
if (!m_emojis.Load()) {
|
|
|
|
Gtk::MessageDialog dlg(*m_main_window, "The emoji file couldn't be loaded!", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
dlg.run();
|
|
|
|
}
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
return m_gtk_app->run(*m_main_window);
|
|
|
|
}
|
2020-08-17 06:40:03 +00:00
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
void Abaddon::LoadFromSettings() {
|
2020-10-04 06:28:48 +00:00
|
|
|
std::string token = m_settings.GetSettingString("discord", "token");
|
2020-08-19 05:07:55 +00:00
|
|
|
if (token.size()) {
|
|
|
|
m_discord_token = token;
|
2020-08-20 01:08:57 +00:00
|
|
|
m_discord.UpdateToken(m_discord_token);
|
2020-08-19 05:07:55 +00:00
|
|
|
}
|
2020-08-17 06:40:03 +00:00
|
|
|
}
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
void Abaddon::StartDiscord() {
|
2020-08-17 06:40:03 +00:00
|
|
|
m_discord.Start();
|
|
|
|
}
|
|
|
|
|
2020-08-19 05:07:55 +00:00
|
|
|
void Abaddon::StopDiscord() {
|
|
|
|
m_discord.Stop();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool Abaddon::IsDiscordActive() const {
|
|
|
|
return m_discord.IsStarted();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::string Abaddon::GetDiscordToken() const {
|
|
|
|
return m_discord_token;
|
|
|
|
}
|
|
|
|
|
2020-09-21 22:47:34 +00:00
|
|
|
DiscordClient &Abaddon::GetDiscordClient() {
|
|
|
|
std::scoped_lock<std::mutex> guard(m_mutex);
|
|
|
|
return m_discord;
|
|
|
|
}
|
|
|
|
|
2020-08-19 05:13:36 +00:00
|
|
|
const DiscordClient &Abaddon::GetDiscordClient() const {
|
|
|
|
std::scoped_lock<std::mutex> guard(m_mutex);
|
|
|
|
return m_discord;
|
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnReady() {
|
2020-08-19 06:05:26 +00:00
|
|
|
m_main_window->UpdateComponents();
|
2020-08-19 05:13:36 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnChannelListRefresh() {
|
2020-08-20 01:08:57 +00:00
|
|
|
m_main_window->UpdateChannelListing();
|
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnMessageCreate(Snowflake id) {
|
2020-08-21 04:42:46 +00:00
|
|
|
m_main_window->UpdateChatNewMessage(id);
|
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnMessageDelete(Snowflake id, Snowflake channel_id) {
|
2020-08-29 05:14:07 +00:00
|
|
|
m_main_window->UpdateChatMessageDeleted(id, channel_id);
|
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnMessageUpdate(Snowflake id, Snowflake channel_id) {
|
2020-09-20 05:12:54 +00:00
|
|
|
m_main_window->UpdateChatMessageUpdated(id, channel_id);
|
2020-08-31 00:24:02 +00:00
|
|
|
}
|
|
|
|
|
2020-09-07 03:34:29 +00:00
|
|
|
void Abaddon::DiscordOnGuildMemberListUpdate(Snowflake guild_id) {
|
2020-09-05 04:55:06 +00:00
|
|
|
m_main_window->UpdateMembers();
|
|
|
|
}
|
|
|
|
|
2020-09-21 22:47:34 +00:00
|
|
|
void Abaddon::DiscordOnGuildCreate(Snowflake guild_id) {
|
2020-10-14 03:56:00 +00:00
|
|
|
m_main_window->UpdateChannelsNewGuild(guild_id);
|
2020-09-21 22:47:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::DiscordOnGuildDelete(Snowflake guild_id) {
|
2020-10-14 03:56:00 +00:00
|
|
|
m_main_window->UpdateChannelsRemoveGuild(guild_id);
|
2020-09-21 22:47:34 +00:00
|
|
|
}
|
|
|
|
|
2020-10-20 00:35:10 +00:00
|
|
|
void Abaddon::DiscordOnChannelDelete(Snowflake channel_id) {
|
|
|
|
m_main_window->UpdateChannelsRemoveChannel(channel_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::DiscordOnChannelUpdate(Snowflake channel_id) {
|
|
|
|
m_main_window->UpdateChannelsUpdateChannel(channel_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::DiscordOnChannelCreate(Snowflake channel_id) {
|
|
|
|
m_main_window->UpdateChannelsCreateChannel(channel_id);
|
|
|
|
}
|
|
|
|
|
2020-11-01 04:01:48 +00:00
|
|
|
void Abaddon::DiscordOnGuildUpdate(Snowflake guild_id) {
|
|
|
|
m_main_window->UpdateChannelsUpdateGuild(guild_id);
|
|
|
|
}
|
|
|
|
|
2020-10-04 06:28:48 +00:00
|
|
|
const SettingsManager &Abaddon::GetSettings() const {
|
|
|
|
return m_settings;
|
|
|
|
}
|
|
|
|
|
2020-11-08 05:44:26 +00:00
|
|
|
void Abaddon::ShowUserMenu(const GdkEvent *event, Snowflake id, Snowflake guild_id) {
|
|
|
|
m_shown_user_menu_id = id;
|
|
|
|
m_shown_user_menu_guild_id = guild_id;
|
|
|
|
|
|
|
|
const auto me = m_discord.GetUserData().ID;
|
|
|
|
const bool has_kick = m_discord.HasGuildPermission(me, guild_id, Permission::KICK_MEMBERS);
|
|
|
|
const bool has_ban = m_discord.HasGuildPermission(me, guild_id, Permission::BAN_MEMBERS);
|
|
|
|
const bool can_manage = m_discord.CanManageMember(guild_id, me, id);
|
|
|
|
|
|
|
|
m_user_menu_kick->set_sensitive(has_kick && can_manage);
|
|
|
|
m_user_menu_ban->set_sensitive(has_ban && can_manage);
|
|
|
|
|
|
|
|
m_user_menu->popup_at_pointer(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::on_user_menu_insert_mention() {
|
|
|
|
ActionInsertMention(m_shown_user_menu_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::on_user_menu_ban() {
|
|
|
|
ActionBanMember(m_shown_user_menu_id, m_shown_user_menu_guild_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::on_user_menu_kick() {
|
|
|
|
ActionKickMember(m_shown_user_menu_id, m_shown_user_menu_guild_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::on_user_menu_copy_id() {
|
|
|
|
Gtk::Clipboard::get()->set_text(std::to_string(m_shown_user_menu_id));
|
|
|
|
}
|
|
|
|
|
2020-08-17 06:40:03 +00:00
|
|
|
void Abaddon::ActionConnect() {
|
|
|
|
if (!m_discord.IsStarted())
|
2020-08-19 05:07:55 +00:00
|
|
|
StartDiscord();
|
2020-08-19 06:05:26 +00:00
|
|
|
m_main_window->UpdateComponents();
|
2020-08-19 05:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::ActionDisconnect() {
|
|
|
|
if (m_discord.IsStarted())
|
|
|
|
StopDiscord();
|
2020-09-07 06:45:46 +00:00
|
|
|
m_channels_history_loaded.clear();
|
|
|
|
m_channels_history_loading.clear();
|
|
|
|
m_channels_requested.clear();
|
|
|
|
m_oldest_listed_message.clear();
|
2020-09-03 06:32:28 +00:00
|
|
|
m_main_window->set_title(APP_TITLE);
|
2020-08-19 06:05:26 +00:00
|
|
|
m_main_window->UpdateComponents();
|
2020-08-19 05:07:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::ActionSetToken() {
|
|
|
|
TokenDialog dlg(*m_main_window);
|
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK) {
|
|
|
|
m_discord_token = dlg.GetToken();
|
2020-08-20 01:08:57 +00:00
|
|
|
m_discord.UpdateToken(m_discord_token);
|
2020-08-19 06:05:26 +00:00
|
|
|
m_main_window->UpdateComponents();
|
2020-08-19 05:07:55 +00:00
|
|
|
m_settings.SetSetting("discord", "token", m_discord_token);
|
|
|
|
}
|
2020-08-17 06:40:03 +00:00
|
|
|
}
|
|
|
|
|
2020-09-21 22:47:34 +00:00
|
|
|
void Abaddon::ActionJoinGuildDialog() {
|
|
|
|
JoinGuildDialog dlg(*m_main_window);
|
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK) {
|
|
|
|
auto code = dlg.GetCode();
|
|
|
|
m_discord.JoinGuild(code);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-20 01:08:57 +00:00
|
|
|
void Abaddon::ActionMoveGuildUp(Snowflake id) {
|
2020-08-26 02:10:39 +00:00
|
|
|
auto order = m_discord.GetUserSortedGuilds();
|
|
|
|
// get iter to target
|
|
|
|
decltype(order)::iterator target_iter;
|
|
|
|
for (auto it = order.begin(); it != order.end(); it++) {
|
2020-09-07 01:28:07 +00:00
|
|
|
if (*it == id) {
|
2020-08-26 02:10:39 +00:00
|
|
|
target_iter = it;
|
|
|
|
break;
|
|
|
|
}
|
2020-08-20 01:08:57 +00:00
|
|
|
}
|
|
|
|
|
2020-08-26 02:10:39 +00:00
|
|
|
decltype(order)::iterator left = target_iter - 1;
|
|
|
|
std::swap(*left, *target_iter);
|
2020-08-20 01:08:57 +00:00
|
|
|
|
2020-09-07 01:28:07 +00:00
|
|
|
m_discord.UpdateSettingsGuildPositions(order);
|
2020-08-20 01:08:57 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::ActionMoveGuildDown(Snowflake id) {
|
2020-08-26 02:10:39 +00:00
|
|
|
auto order = m_discord.GetUserSortedGuilds();
|
|
|
|
// get iter to target
|
|
|
|
decltype(order)::iterator target_iter;
|
|
|
|
for (auto it = order.begin(); it != order.end(); it++) {
|
2020-09-07 01:28:07 +00:00
|
|
|
if (*it == id) {
|
2020-08-26 02:10:39 +00:00
|
|
|
target_iter = it;
|
|
|
|
break;
|
|
|
|
}
|
2020-08-20 01:08:57 +00:00
|
|
|
}
|
|
|
|
|
2020-08-26 02:10:39 +00:00
|
|
|
decltype(order)::iterator right = target_iter + 1;
|
|
|
|
std::swap(*right, *target_iter);
|
|
|
|
|
2020-09-07 01:28:07 +00:00
|
|
|
m_discord.UpdateSettingsGuildPositions(order);
|
2020-08-26 02:10:39 +00:00
|
|
|
}
|
2020-08-20 01:08:57 +00:00
|
|
|
|
2020-11-01 04:13:52 +00:00
|
|
|
void Abaddon::ActionChannelOpened(Snowflake id) {
|
2020-09-12 07:17:34 +00:00
|
|
|
if (id == m_main_window->GetChatActiveChannel()) return;
|
|
|
|
|
2020-09-03 06:32:28 +00:00
|
|
|
auto *channel = m_discord.GetChannel(id);
|
2020-09-05 05:04:28 +00:00
|
|
|
if (channel->Type != ChannelType::DM && channel->Type != ChannelType::GROUP_DM)
|
|
|
|
m_discord.SendLazyLoad(id);
|
|
|
|
|
2020-11-01 22:15:34 +00:00
|
|
|
if (channel->Type == ChannelType::GUILD_TEXT || channel->Type == ChannelType::GUILD_NEWS)
|
2020-09-05 04:55:06 +00:00
|
|
|
m_main_window->set_title(std::string(APP_TITLE) + " - #" + channel->Name);
|
|
|
|
else {
|
|
|
|
std::string display;
|
|
|
|
if (channel->Recipients.size() > 1)
|
|
|
|
display = std::to_string(channel->Recipients.size()) + " users";
|
|
|
|
else
|
|
|
|
display = channel->Recipients[0].Username;
|
|
|
|
m_main_window->set_title(std::string(APP_TITLE) + " - " + display);
|
|
|
|
}
|
2020-08-20 07:19:16 +00:00
|
|
|
m_main_window->UpdateChatActiveChannel(id);
|
|
|
|
if (m_channels_requested.find(id) == m_channels_requested.end()) {
|
2020-09-04 04:48:38 +00:00
|
|
|
m_discord.FetchMessagesInChannel(id, [this, id](const std::vector<Snowflake> &msgs) {
|
2020-10-06 01:37:07 +00:00
|
|
|
if (msgs.size() > 0)
|
2020-09-04 04:48:38 +00:00
|
|
|
m_oldest_listed_message[id] = msgs.back();
|
2020-08-28 22:21:08 +00:00
|
|
|
|
2020-10-06 01:37:07 +00:00
|
|
|
m_main_window->UpdateChatWindowContents();
|
2020-08-20 07:19:16 +00:00
|
|
|
m_channels_requested.insert(id);
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
m_main_window->UpdateChatWindowContents();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-28 22:21:08 +00:00
|
|
|
void Abaddon::ActionChatLoadHistory(Snowflake id) {
|
|
|
|
if (m_channels_history_loaded.find(id) != m_channels_history_loaded.end())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (m_channels_history_loading.find(id) != m_channels_history_loading.end())
|
|
|
|
return;
|
|
|
|
|
2020-09-14 04:17:58 +00:00
|
|
|
Snowflake before_id = m_main_window->GetChatOldestListedMessage();
|
|
|
|
auto knownset = m_discord.GetMessagesForChannel(id);
|
|
|
|
std::vector<Snowflake> knownvec(knownset.begin(), knownset.end());
|
|
|
|
std::sort(knownvec.begin(), knownvec.end());
|
|
|
|
auto latest = std::find_if(knownvec.begin(), knownvec.end(), [&before_id](Snowflake x) -> bool { return x == before_id; });
|
|
|
|
int distance = std::distance(knownvec.begin(), latest);
|
|
|
|
|
|
|
|
if (distance >= 50) {
|
|
|
|
m_main_window->UpdateChatPrependHistory(std::vector<Snowflake>(knownvec.begin() + distance - 50, knownvec.begin() + distance));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2020-08-28 22:21:08 +00:00
|
|
|
m_channels_history_loading.insert(id);
|
|
|
|
|
2020-09-04 04:48:38 +00:00
|
|
|
m_discord.FetchMessagesInChannelBefore(id, m_oldest_listed_message[id], [this, id](const std::vector<Snowflake> &msgs) {
|
2020-08-28 22:21:08 +00:00
|
|
|
m_channels_history_loading.erase(id);
|
|
|
|
|
|
|
|
if (msgs.size() == 0) {
|
|
|
|
m_channels_history_loaded.insert(id);
|
|
|
|
} else {
|
2020-09-04 04:48:38 +00:00
|
|
|
m_oldest_listed_message[id] = msgs.back();
|
2020-08-28 22:21:08 +00:00
|
|
|
m_main_window->UpdateChatPrependHistory(msgs);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2020-08-22 02:25:23 +00:00
|
|
|
void Abaddon::ActionChatInputSubmit(std::string msg, Snowflake channel) {
|
2020-09-04 05:03:43 +00:00
|
|
|
if (msg.substr(0, 7) == "/shrug " || msg == "/shrug")
|
|
|
|
msg = msg.substr(6) + "\xC2\xAF\x5C\x5F\x28\xE3\x83\x84\x29\x5F\x2F\xC2\xAF"; // this is important
|
2020-08-22 02:25:23 +00:00
|
|
|
m_discord.SendChatMessage(msg, channel);
|
|
|
|
}
|
|
|
|
|
2020-08-30 06:00:56 +00:00
|
|
|
void Abaddon::ActionChatDeleteMessage(Snowflake channel_id, Snowflake id) {
|
|
|
|
m_discord.DeleteMessage(channel_id, id);
|
|
|
|
}
|
|
|
|
|
2020-08-31 02:55:36 +00:00
|
|
|
void Abaddon::ActionChatEditMessage(Snowflake channel_id, Snowflake id) {
|
|
|
|
EditMessageDialog dlg(*m_main_window);
|
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK) {
|
|
|
|
auto new_content = dlg.GetContent();
|
|
|
|
m_discord.EditMessage(channel_id, id, new_content);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-09-06 06:25:19 +00:00
|
|
|
void Abaddon::ActionInsertMention(Snowflake id) {
|
|
|
|
m_main_window->InsertChatInput("<@" + std::to_string(id) + ">");
|
|
|
|
}
|
|
|
|
|
2020-09-21 22:47:34 +00:00
|
|
|
void Abaddon::ActionLeaveGuild(Snowflake id) {
|
2020-10-12 04:36:18 +00:00
|
|
|
ConfirmDialog dlg(*m_main_window);
|
2020-10-12 22:17:53 +00:00
|
|
|
const auto *guild = m_discord.GetGuild(id);
|
|
|
|
if (guild != nullptr)
|
|
|
|
dlg.SetConfirmText("Are you sure you want to leave " + guild->Name + "?");
|
2020-10-12 04:36:18 +00:00
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK)
|
|
|
|
m_discord.LeaveGuild(id);
|
2020-09-21 22:47:34 +00:00
|
|
|
}
|
|
|
|
|
2020-10-12 22:17:53 +00:00
|
|
|
void Abaddon::ActionKickMember(Snowflake user_id, Snowflake guild_id) {
|
|
|
|
ConfirmDialog dlg(*m_main_window);
|
|
|
|
const auto *user = m_discord.GetUser(user_id);
|
|
|
|
if (user != nullptr)
|
|
|
|
dlg.SetConfirmText("Are you sure you want to kick " + user->Username + "#" + user->Discriminator + "?");
|
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK)
|
|
|
|
m_discord.KickUser(user_id, guild_id);
|
|
|
|
}
|
|
|
|
|
|
|
|
void Abaddon::ActionBanMember(Snowflake user_id, Snowflake guild_id) {
|
|
|
|
ConfirmDialog dlg(*m_main_window);
|
|
|
|
const auto *user = m_discord.GetUser(user_id);
|
|
|
|
if (user != nullptr)
|
|
|
|
dlg.SetConfirmText("Are you sure you want to ban " + user->Username + "#" + user->Discriminator + "?");
|
|
|
|
auto response = dlg.run();
|
|
|
|
if (response == Gtk::RESPONSE_OK)
|
|
|
|
m_discord.BanUser(user_id, guild_id);
|
|
|
|
}
|
|
|
|
|
2020-11-01 07:53:37 +00:00
|
|
|
void Abaddon::ActionSetStatus() {
|
|
|
|
SetStatusDialog dlg(*m_main_window);
|
|
|
|
const auto response = dlg.run();
|
|
|
|
if (response != Gtk::RESPONSE_OK || !m_discord.IsStarted()) return;
|
|
|
|
const auto status = dlg.GetStatusType();
|
|
|
|
const auto activity_type = dlg.GetActivityType();
|
|
|
|
const auto activity_name = dlg.GetActivityName();
|
|
|
|
Activity activity;
|
|
|
|
activity.Name = activity_name;
|
|
|
|
activity.Type = activity_type;
|
|
|
|
m_discord.UpdateStatus(status, false, activity);
|
|
|
|
}
|
|
|
|
|
2020-09-03 04:47:49 +00:00
|
|
|
void Abaddon::ActionReloadCSS() {
|
2020-09-04 05:37:39 +00:00
|
|
|
try {
|
|
|
|
Gtk::StyleContext::remove_provider_for_screen(Gdk::Screen::get_default(), m_css_provider);
|
|
|
|
m_css_provider->load_from_path("./css/main.css");
|
|
|
|
Gtk::StyleContext::add_provider_for_screen(Gdk::Screen::get_default(), m_css_provider, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
|
|
|
|
} catch (Glib::Error &e) {
|
|
|
|
Gtk::MessageDialog dlg(*m_main_window, "main.css failed to load (" + e.what() + ")", false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_OK, true);
|
|
|
|
dlg.run();
|
|
|
|
}
|
2020-09-03 04:47:49 +00:00
|
|
|
}
|
|
|
|
|
2020-09-12 07:17:34 +00:00
|
|
|
ImageManager &Abaddon::GetImageManager() {
|
|
|
|
return m_img_mgr;
|
2020-09-10 22:28:42 +00:00
|
|
|
}
|
|
|
|
|
2020-10-24 23:42:06 +00:00
|
|
|
EmojiResource &Abaddon::GetEmojis() {
|
|
|
|
return m_emojis;
|
|
|
|
}
|
|
|
|
|
2020-08-17 06:40:03 +00:00
|
|
|
int main(int argc, char **argv) {
|
2020-08-20 07:19:16 +00:00
|
|
|
Gtk::Main::init_gtkmm_internals(); // why???
|
2020-09-07 04:27:41 +00:00
|
|
|
return Abaddon::Get().StartGTK();
|
2020-08-17 06:40:03 +00:00
|
|
|
}
|