diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-09-21 18:47:34 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-09-21 18:47:34 -0400 |
commit | 3b4edbfa16861b5013663396e1af827ba889e9df (patch) | |
tree | 51686baf5997c32a3e3aac0aa20368c404f6f3f1 /dialogs | |
parent | 23b32f8de957204597308f2c1823d5e89f632610 (diff) | |
download | abaddon-portaudio-3b4edbfa16861b5013663396e1af827ba889e9df.tar.gz abaddon-portaudio-3b4edbfa16861b5013663396e1af827ba889e9df.zip |
join/leave guild
Diffstat (limited to 'dialogs')
-rw-r--r-- | dialogs/joinguild.cpp | 98 | ||||
-rw-r--r-- | dialogs/joinguild.hpp | 31 |
2 files changed, 129 insertions, 0 deletions
diff --git a/dialogs/joinguild.cpp b/dialogs/joinguild.cpp new file mode 100644 index 0000000..ad9630b --- /dev/null +++ b/dialogs/joinguild.cpp @@ -0,0 +1,98 @@ +#include "joinguild.hpp" +#include "../abaddon.hpp" +#include <nlohmann/json.hpp> +#include <regex> + +JoinGuildDialog::JoinGuildDialog(Gtk::Window &parent) + : Gtk::Dialog("Join Server", parent, true) + , m_layout(Gtk::ORIENTATION_VERTICAL) + , m_ok("OK") + , m_cancel("Cancel") + , m_info("Enter code") { + set_default_size(300, 50); + + Glib::signal_idle().connect(sigc::mem_fun(*this, &JoinGuildDialog::on_idle_slot)); + + m_entry.signal_changed().connect(sigc::mem_fun(*this, &JoinGuildDialog::on_entry_changed)); + + m_ok.set_sensitive(false); + + m_ok.signal_clicked().connect([&]() { + m_code = m_entry.get_text(); + response(Gtk::RESPONSE_OK); + }); + + m_cancel.signal_clicked().connect([&]() { + response(Gtk::RESPONSE_CANCEL); + }); + + m_entry.set_hexpand(true); + m_layout.add(m_entry); + m_lower.set_hexpand(true); + m_lower.pack_start(m_info); + m_info.set_halign(Gtk::ALIGN_START); + m_lower.pack_start(m_ok, Gtk::PACK_SHRINK); + m_lower.pack_start(m_cancel, Gtk::PACK_SHRINK); + m_ok.set_halign(Gtk::ALIGN_END); + m_cancel.set_halign(Gtk::ALIGN_END); + m_layout.add(m_lower); + get_content_area()->add(m_layout); + + show_all_children(); +} + +void JoinGuildDialog::on_entry_changed() { + std::string s = m_entry.get_text(); + std::regex invite_regex(R"~(discord\.(gg|com)\/([a-zA-Z0-9]+)$)~", std::regex_constants::ECMAScript); + std::smatch match; + bool full_url = std::regex_search(s, match, invite_regex); + if (full_url || IsCode(s)) { + m_code = full_url ? match[2].str() : s; + m_needs_request = true; + m_ok.set_sensitive(false); + } else { + m_ok.set_sensitive(false); + } +} + +void JoinGuildDialog::CheckCode() { + // clang-format off + Abaddon::Get().GetDiscordClient().FetchInviteData( + m_code, + [this](Invite invite) { + m_ok.set_sensitive(true); + if (invite.Members != -1) + m_info.set_text(invite.Guild.Name + " (" + std::to_string(invite.Members) + " members)"); + else + m_info.set_text(invite.Guild.Name); + }, + [this](bool not_found) { + m_ok.set_sensitive(false); + if (not_found) + m_info.set_text("Invalid invite"); + else + m_info.set_text("HTTP error (try again)"); + } + ); + // clang-format on +} + +bool JoinGuildDialog::IsCode(std::string str) { + return str.length() >= 2 && std::all_of(str.begin(), str.end(), [](char c) -> bool { return std::isalnum(c); }); +} + +std::string JoinGuildDialog::GetCode() { + return m_code; +} + +static const constexpr int RateLimitMS = 1500; +bool JoinGuildDialog::on_idle_slot() { + const auto now = std::chrono::steady_clock::now(); + if (m_needs_request && ((now - m_last_req_time) > std::chrono::milliseconds(RateLimitMS))) { + m_needs_request = false; + m_last_req_time = now; + CheckCode(); + } + + return true; +} diff --git a/dialogs/joinguild.hpp b/dialogs/joinguild.hpp new file mode 100644 index 0000000..109d010 --- /dev/null +++ b/dialogs/joinguild.hpp @@ -0,0 +1,31 @@ +#pragma once +#include <gtkmm.h> +#include <string> +#include <chrono> + +class JoinGuildDialog : public Gtk::Dialog { +public: + JoinGuildDialog(Gtk::Window &parent); + std::string GetCode(); + +protected: + void on_entry_changed(); + bool IsCode(std::string str); + + Gtk::Box m_layout; + Gtk::Button m_ok; + Gtk::Button m_cancel; + Gtk::Box m_lower; + Gtk::Label m_info; + Gtk::Entry m_entry; + + void CheckCode(); + + // needs a rate limit cuz if u hit it u get ip banned from /invites for a long time :( + bool m_needs_request = false; + std::chrono::time_point<std::chrono::steady_clock> m_last_req_time; + bool on_idle_slot(); + +private: + std::string m_code; +}; |