summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2021-05-10 02:13:12 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2021-05-10 02:13:12 -0400
commit06ba3acc93ed57cb41e319eb5f7da06d15b72ec2 (patch)
tree13b208f4f0372d1d670fca1e7eb4e374fa1c2971
parent81ae2b3a83e5c9e1f34714f7ba004638b3beeeb0 (diff)
downloadabaddon-portaudio-06ba3acc93ed57cb41e319eb5f7da06d15b72ec2.tar.gz
abaddon-portaudio-06ba3acc93ed57cb41e319eb5f7da06d15b72ec2.zip
friends: send friend requests
-rw-r--r--components/friendslist.cpp40
-rw-r--r--components/friendslist.hpp5
-rw-r--r--discord/discord.cpp19
-rw-r--r--discord/discord.hpp1
-rw-r--r--discord/errors.hpp36
-rw-r--r--discord/objects.cpp5
-rw-r--r--discord/objects.hpp8
7 files changed, 114 insertions, 0 deletions
diff --git a/components/friendslist.cpp b/components/friendslist.cpp
index 014f8ba..4486d97 100644
--- a/components/friendslist.cpp
+++ b/components/friendslist.cpp
@@ -2,6 +2,8 @@
#include "../abaddon.hpp"
#include "lazyimage.hpp"
+using namespace std::string_literals;
+
FriendsList::FriendsList()
: Gtk::Box(Gtk::ORIENTATION_VERTICAL)
, m_filter_mode(FILTER_FRIENDS) {
@@ -167,9 +169,12 @@ FriendsListAddComponent::FriendsListAddComponent()
m_box.add(m_add);
m_box.add(m_status);
+ m_add.signal_clicked().connect(sigc::mem_fun(*this, &FriendsListAddComponent::Submit));
+
m_label.set_halign(Gtk::ALIGN_CENTER);
m_entry.set_placeholder_text("Enter a Username#1234");
+ m_entry.signal_key_press_event().connect(sigc::mem_fun(*this, &FriendsListAddComponent::OnKeyPress), false);
add(m_label);
add(m_box);
@@ -177,6 +182,41 @@ FriendsListAddComponent::FriendsListAddComponent()
show_all_children();
}
+void FriendsListAddComponent::Submit() {
+ if (m_requesting) return;
+
+ auto text = m_entry.get_text();
+ m_label.set_text("Invalid input"); // cheeky !!
+ m_entry.set_text("");
+ const auto hashpos = text.find("#");
+ 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 (discriminator.find_first_not_of("0123456789") != Glib::ustring::npos) return;
+
+ m_requesting = true;
+ m_label.set_text("Hang on...");
+
+ const auto cb = [this](bool success, DiscordError code) {
+ m_requesting = false;
+ if (success) {
+ m_label.set_text("Success!");
+ } else {
+ m_label.set_text("Failed: "s + GetDiscordErrorDisplayString(code));
+ }
+ };
+ Abaddon::Get().GetDiscordClient().SendFriendRequest(username, std::stoul(discriminator), sigc::track_obj(cb, *this));
+}
+
+bool FriendsListAddComponent::OnKeyPress(GdkEventKey *e) {
+ if (e->keyval == GDK_KEY_Return) {
+ Submit();
+ return true;
+ }
+ return false;
+}
+
FriendsListFriendRow::FriendsListFriendRow(RelationshipType type, const UserData &data)
: Name(data.Username + "#" + data.Discriminator)
, Type(type)
diff --git a/components/friendslist.hpp b/components/friendslist.hpp
index 0e5afe3..5582e26 100644
--- a/components/friendslist.hpp
+++ b/components/friendslist.hpp
@@ -7,11 +7,16 @@ public:
FriendsListAddComponent();
private:
+ void Submit();
+ bool OnKeyPress(GdkEventKey *e);
+
Gtk::Label m_label;
Gtk::Label m_status;
Gtk::Entry m_entry;
Gtk::Button m_add;
Gtk::Box m_box;
+
+ bool m_requesting = false;
};
class FriendsListFriendRow;
diff --git a/discord/discord.cpp b/discord/discord.cpp
index e82ba1b..0cf813a 100644
--- a/discord/discord.cpp
+++ b/discord/discord.cpp
@@ -697,6 +697,25 @@ void DiscordClient::RemoveRelationship(Snowflake id, sigc::slot<void(bool succes
});
}
+void DiscordClient::SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(bool success, 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) {
+ if (CheckCode(response, 204)) {
+ callback(true, DiscordError::NONE);
+ } else {
+ auto code = DiscordError::GENERIC;
+ try {
+ // pull me somewhere else?
+ const auto data = nlohmann::json::parse(response.text);
+ data.at("code").get_to(code);
+ } catch (...) {}
+ callback(false, code);
+ }
+ });
+}
+
bool DiscordClient::CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const {
const auto guild = *GetGuild(guild_id);
if (guild.OwnerID == user_id) return true;
diff --git a/discord/discord.hpp b/discord/discord.hpp
index 29e47b0..f3d6d56 100644
--- a/discord/discord.hpp
+++ b/discord/discord.hpp
@@ -139,6 +139,7 @@ public:
void DeleteEmoji(Snowflake guild_id, Snowflake emoji_id, sigc::slot<void(bool success)> callback);
std::optional<GuildApplicationData> GetGuildApplication(Snowflake guild_id) const;
void RemoveRelationship(Snowflake id, sigc::slot<void(bool success)> callback);
+ void SendFriendRequest(const Glib::ustring &username, int discriminator, sigc::slot<void(bool success, DiscordError code)> callback);
bool CanModifyRole(Snowflake guild_id, Snowflake role_id) const;
bool CanModifyRole(Snowflake guild_id, Snowflake role_id, Snowflake user_id) const;
diff --git a/discord/errors.hpp b/discord/errors.hpp
new file mode 100644
index 0000000..4579563
--- /dev/null
+++ b/discord/errors.hpp
@@ -0,0 +1,36 @@
+#pragma once
+
+enum class DiscordError {
+ GENERIC = 0,
+ INVALID_FORM_BODY = 50035,
+ RELATIONSHIP_INCOMING_DISABLED = 80000,
+ RELATIONSHIP_INCOMING_BLOCKED = 80001,
+ RELATIONSHIP_INVALID_USER_BOT = 80002, // this is misspelled in discord's source lul
+ RELATIONSHIP_INVALID_SELF = 80003,
+ RELATIONSHIP_INVALID_DISCORD_TAG = 80004,
+ RELATIONSHIP_ALREADY_FRIENDS = 80007,
+
+ NONE = -1,
+};
+
+constexpr const char *GetDiscordErrorDisplayString(DiscordError error) {
+ switch (error) {
+ case DiscordError::INVALID_FORM_BODY:
+ return "Something's wrong with your input";
+ case DiscordError::RELATIONSHIP_INCOMING_DISABLED:
+ return "This user isn't accepting friend requests";
+ case DiscordError::RELATIONSHIP_INCOMING_BLOCKED:
+ return "You are blocked by this user";
+ case DiscordError::RELATIONSHIP_INVALID_USER_BOT:
+ return "You can't send a request to a bot";
+ case DiscordError::RELATIONSHIP_INVALID_SELF:
+ return "You can't send a request to yourself";
+ case DiscordError::RELATIONSHIP_INVALID_DISCORD_TAG:
+ return "No users with that tag exist";
+ case DiscordError::RELATIONSHIP_ALREADY_FRIENDS:
+ return "You are already friends with that user";
+ case DiscordError::GENERIC:
+ default:
+ return "An error occurred";
+ }
+}
diff --git a/discord/objects.cpp b/discord/objects.cpp
index 0d4ab16..8f95c41 100644
--- a/discord/objects.cpp
+++ b/discord/objects.cpp
@@ -463,3 +463,8 @@ void from_json(const nlohmann::json &j, RelationshipAddData &m) {
JS_D("type", m.Type);
JS_D("user", m.User);
}
+
+void to_json(nlohmann::json &j, const FriendRequestObject &m) {
+ j["username"] = m.Username;
+ j["discriminator"] = m.Discriminator;
+}
diff --git a/discord/objects.hpp b/discord/objects.hpp
index 56191df..f3256f4 100644
--- a/discord/objects.hpp
+++ b/discord/objects.hpp
@@ -19,6 +19,7 @@
#include "ban.hpp"
#include "auditlog.hpp"
#include "relationship.hpp"
+#include "errors.hpp"
// most stuff below should just be objects that get processed and thrown away immediately
@@ -645,3 +646,10 @@ struct RelationshipAddData {
friend void from_json(const nlohmann::json &j, RelationshipAddData &m);
};
+
+struct FriendRequestObject {
+ std::string Username;
+ int Discriminator;
+
+ friend void to_json(nlohmann::json &j, const FriendRequestObject &m);
+};