summaryrefslogtreecommitdiff
path: root/dialogs
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2020-09-21 18:47:34 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2020-09-21 18:47:34 -0400
commit3b4edbfa16861b5013663396e1af827ba889e9df (patch)
tree51686baf5997c32a3e3aac0aa20368c404f6f3f1 /dialogs
parent23b32f8de957204597308f2c1823d5e89f632610 (diff)
downloadabaddon-portaudio-3b4edbfa16861b5013663396e1af827ba889e9df.tar.gz
abaddon-portaudio-3b4edbfa16861b5013663396e1af827ba889e9df.zip
join/leave guild
Diffstat (limited to 'dialogs')
-rw-r--r--dialogs/joinguild.cpp98
-rw-r--r--dialogs/joinguild.hpp31
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;
+};