diff --git a/abaddon.cpp b/abaddon.cpp index 805e976..888a32c 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -64,13 +64,16 @@ int Abaddon::StartGTK() { 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_open_dm = Gtk::manage(new Gtk::MenuItem("Open DM")); 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_open_dm->signal_activate().connect(sigc::mem_fun(*this, &Abaddon::on_user_menu_open_dm)); 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_open_dm); m_user_menu->append(*m_user_menu_copy_id); m_user_menu->show_all(); @@ -231,6 +234,14 @@ void Abaddon::on_user_menu_copy_id() { Gtk::Clipboard::get()->set_text(std::to_string(m_shown_user_menu_id)); } +void Abaddon::on_user_menu_open_dm() { + const auto existing = m_discord.FindDM(m_shown_user_menu_id); + if (existing.has_value()) + ActionChannelOpened(*existing); + else + m_discord.CreateDM(m_shown_user_menu_id); +} + void Abaddon::ActionConnect() { if (!m_discord.IsStarted()) StartDiscord(); diff --git a/abaddon.hpp b/abaddon.hpp index 6582a30..965f909 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -81,11 +81,13 @@ protected: Gtk::MenuItem *m_user_menu_ban; Gtk::MenuItem *m_user_menu_kick; Gtk::MenuItem *m_user_menu_copy_id; + Gtk::MenuItem *m_user_menu_open_dm; void on_user_menu_insert_mention(); void on_user_menu_ban(); void on_user_menu_kick(); void on_user_menu_copy_id(); + void on_user_menu_open_dm(); private: DiscordClient m_discord; diff --git a/discord/discord.cpp b/discord/discord.cpp index acb98aa..5f3f6e4 100644 --- a/discord/discord.cpp +++ b/discord/discord.cpp @@ -404,6 +404,23 @@ void DiscordClient::UpdateStatus(const std::string &status, bool is_afk, const A m_websocket.Send(nlohmann::json(msg)); } +void DiscordClient::CreateDM(Snowflake user_id) { + // actual client uses an array called recipients + CreateDMObject obj; + obj.Recipients.push_back(user_id); + m_http.MakePOST("/users/@me/channels", nlohmann::json(obj).dump(), [](auto) {}); +} + +std::optional DiscordClient::FindDM(Snowflake user_id) { + const auto &channels = m_store.GetChannels(); + for (const auto &[id, channel] : channels) { + if (channel.Recipients.size() == 1 && channel.Recipients[0].ID == user_id) + return id; + } + + return std::nullopt; +} + void DiscordClient::UpdateToken(std::string token) { if (!IsStarted()) { m_token = token; diff --git a/discord/discord.hpp b/discord/discord.hpp index 0ab1529..ab31df2 100644 --- a/discord/discord.hpp +++ b/discord/discord.hpp @@ -104,6 +104,8 @@ public: void KickUser(Snowflake user_id, Snowflake guild_id); void BanUser(Snowflake user_id, Snowflake guild_id); // todo: reason, delete messages void UpdateStatus(const std::string &status, bool is_afk, const Activity &obj); + void CreateDM(Snowflake user_id); + std::optional FindDM(Snowflake user_id); // wont find group dms void UpdateToken(std::string token); diff --git a/discord/objects.cpp b/discord/objects.cpp index 5299a79..bc0d2e2 100644 --- a/discord/objects.cpp +++ b/discord/objects.cpp @@ -164,3 +164,10 @@ void from_json(const nlohmann::json &j, PresenceUpdateMessage &m) { // JS_D("activities", m.Activities); JS_D("client_status", m.ClientStatus); } + +void to_json(nlohmann::json &j, const CreateDMObject &m) { + std::vector conv; + for (const auto &id : m.Recipients) + conv.push_back(std::to_string(id)); + j["recipients"] = conv; +} diff --git a/discord/objects.hpp b/discord/objects.hpp index fd836b1..453a5f4 100644 --- a/discord/objects.hpp +++ b/discord/objects.hpp @@ -235,3 +235,9 @@ struct PresenceUpdateMessage { friend void from_json(const nlohmann::json &j, PresenceUpdateMessage &m); }; + +struct CreateDMObject { + std::vector Recipients; + + friend void to_json(nlohmann::json &j, const CreateDMObject &m); +};