forked from OpenGamers/abaddon
refactor send message params into one struct
This commit is contained in:
parent
caa551a469
commit
4456c8771d
@ -743,17 +743,22 @@ void Abaddon::ActionChatLoadHistory(Snowflake id) {
|
||||
});
|
||||
}
|
||||
|
||||
void Abaddon::ActionChatInputSubmit(std::string msg, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message) {
|
||||
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
|
||||
static void ChatMessageSentCallback(const ChatSubmitParams &data) {
|
||||
printf("completed for %s\n", data.Message.c_str());
|
||||
for (const auto &attachment : data.Attachments) {
|
||||
puts(attachment.Path.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (!channel.IsValid()) return;
|
||||
if (!m_discord.HasChannelPermission(m_discord.GetUserData().ID, channel, Permission::VIEW_CHANNEL)) return;
|
||||
void Abaddon::ActionChatInputSubmit(ChatSubmitParams data) {
|
||||
if (data.Message.substr(0, 7) == "/shrug " || data.Message == "/shrug")
|
||||
data.Message = data.Message.substr(6) + "\xC2\xAF\x5C\x5F\x28\xE3\x83\x84\x29\x5F\x2F\xC2\xAF"; // this is important
|
||||
|
||||
if (referenced_message.IsValid())
|
||||
m_discord.SendChatMessage(msg, attachment_paths, channel, referenced_message);
|
||||
else
|
||||
m_discord.SendChatMessage(msg, attachment_paths, channel);
|
||||
if (!m_discord.HasChannelPermission(m_discord.GetUserData().ID, data.ChannelID, Permission::VIEW_CHANNEL)) return;
|
||||
|
||||
m_discord.SendChatMessage(data, [data](DiscordError code) {
|
||||
ChatMessageSentCallback(data);
|
||||
});
|
||||
}
|
||||
|
||||
void Abaddon::ActionChatEditMessage(Snowflake channel_id, Snowflake id) {
|
||||
|
@ -36,7 +36,7 @@ public:
|
||||
void ActionSetToken();
|
||||
void ActionJoinGuildDialog();
|
||||
void ActionChannelOpened(Snowflake id, bool expand_to = true);
|
||||
void ActionChatInputSubmit(std::string msg, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message);
|
||||
void ActionChatInputSubmit(ChatSubmitParams data);
|
||||
void ActionChatLoadHistory(Snowflake id);
|
||||
void ActionChatEditMessage(Snowflake channel_id, Snowflake id);
|
||||
void ActionInsertMention(Snowflake id);
|
||||
|
@ -152,10 +152,10 @@ bool ChatInputAttachmentContainer::AddImage(const Glib::RefPtr<Gdk::Pixbuf> &pb)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::vector<std::string> ChatInputAttachmentContainer::GetFilePaths() const {
|
||||
std::vector<std::string> ret;
|
||||
std::vector<ChatSubmitParams::Attachment> ChatInputAttachmentContainer::GetAttachments() const {
|
||||
std::vector<ChatSubmitParams::Attachment> ret;
|
||||
for (auto *x : m_attachments)
|
||||
ret.push_back(x->GetPath());
|
||||
ret.push_back({ x->GetPath(), x->GetType() });
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -165,7 +165,8 @@ ChatInputAttachmentContainer::type_signal_emptied ChatInputAttachmentContainer::
|
||||
|
||||
ChatInputAttachmentItem::ChatInputAttachmentItem(std::string path, const Glib::RefPtr<Gdk::Pixbuf> &pb)
|
||||
: m_path(std::move(path))
|
||||
, m_img(Gtk::make_managed<Gtk::Image>()) {
|
||||
, m_img(Gtk::make_managed<Gtk::Image>())
|
||||
, m_type(ChatSubmitParams::PastedImage) {
|
||||
get_style_context()->add_class("attachment-item");
|
||||
|
||||
int outw, outh;
|
||||
@ -184,6 +185,10 @@ std::string ChatInputAttachmentItem::GetPath() const {
|
||||
return m_path;
|
||||
}
|
||||
|
||||
ChatSubmitParams::AttachmentType ChatInputAttachmentItem::GetType() const {
|
||||
return m_type;
|
||||
}
|
||||
|
||||
void ChatInputAttachmentItem::SetupMenu() {
|
||||
m_menu_remove.set_label("Remove");
|
||||
m_menu_remove.signal_activate().connect([this] {
|
||||
@ -215,8 +220,11 @@ ChatInput::ChatInput()
|
||||
m_signal_escape.emit();
|
||||
});
|
||||
m_input.signal_submit().connect([this](const Glib::ustring &input) -> bool {
|
||||
const auto attachments = m_attachments.GetFilePaths();
|
||||
bool b = m_signal_submit.emit(input, attachments);
|
||||
ChatSubmitParams data;
|
||||
data.Message = input;
|
||||
data.Attachments = m_attachments.GetAttachments();
|
||||
|
||||
bool b = m_signal_submit.emit(data);
|
||||
if (b) {
|
||||
m_attachments_revealer.set_reveal_child(false);
|
||||
m_attachments.ClearNoPurge();
|
||||
|
@ -1,5 +1,6 @@
|
||||
#pragma once
|
||||
#include <gtkmm.h>
|
||||
#include "discord/chatsubmitparams.hpp"
|
||||
#include "discord/permissions.hpp"
|
||||
|
||||
class ChatInputAttachmentItem : public Gtk::EventBox {
|
||||
@ -7,6 +8,7 @@ public:
|
||||
ChatInputAttachmentItem(std::string path, const Glib::RefPtr<Gdk::Pixbuf> &pb);
|
||||
|
||||
[[nodiscard]] std::string GetPath() const;
|
||||
[[nodiscard]] ChatSubmitParams::AttachmentType GetType() const;
|
||||
|
||||
private:
|
||||
void SetupMenu();
|
||||
@ -18,6 +20,7 @@ private:
|
||||
Gtk::Image *m_img = nullptr;
|
||||
|
||||
std::string m_path;
|
||||
ChatSubmitParams::AttachmentType m_type;
|
||||
|
||||
private:
|
||||
using type_signal_remove = sigc::signal<void>;
|
||||
@ -35,7 +38,7 @@ public:
|
||||
void Clear();
|
||||
void ClearNoPurge();
|
||||
bool AddImage(const Glib::RefPtr<Gdk::Pixbuf> &pb);
|
||||
[[nodiscard]] std::vector<std::string> GetFilePaths() const;
|
||||
[[nodiscard]] std::vector<ChatSubmitParams::Attachment> GetAttachments() const;
|
||||
|
||||
private:
|
||||
std::set<ChatInputAttachmentItem *> m_attachments;
|
||||
@ -96,9 +99,7 @@ private:
|
||||
ChatInputText m_input;
|
||||
|
||||
public:
|
||||
// text, attachments -> request sent
|
||||
// maybe this should be reduced to a single struct, its bound to get more complicated (application commands?)
|
||||
using type_signal_submit = sigc::signal<bool, Glib::ustring, std::vector<std::string>>;
|
||||
using type_signal_submit = sigc::signal<bool, ChatSubmitParams>;
|
||||
using type_signal_escape = sigc::signal<void>;
|
||||
using type_signal_check_permission = sigc::signal<bool, Permission>;
|
||||
|
||||
|
@ -212,15 +212,18 @@ Snowflake ChatWindow::GetActiveChannel() const {
|
||||
return m_active_channel;
|
||||
}
|
||||
|
||||
bool ChatWindow::OnInputSubmit(const Glib::ustring &text, const std::vector<std::string> &attachment_paths) {
|
||||
bool ChatWindow::OnInputSubmit(ChatSubmitParams data) {
|
||||
if (!m_rate_limit_indicator->CanSpeak())
|
||||
return false;
|
||||
|
||||
if (text.empty() && attachment_paths.empty())
|
||||
if (data.Message.empty() && data.Attachments.empty())
|
||||
return false;
|
||||
|
||||
data.ChannelID = m_active_channel;
|
||||
data.InReplyToID = m_replying_to;
|
||||
|
||||
if (m_active_channel.IsValid())
|
||||
m_signal_action_chat_submit.emit(text, attachment_paths, m_active_channel, m_replying_to); // m_replying_to is checked for invalid in the handler
|
||||
m_signal_action_chat_submit.emit(data); // m_replying_to is checked for invalid in the handler
|
||||
if (m_is_replying)
|
||||
StopReplying();
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <string>
|
||||
#include <set>
|
||||
#include "discord/discord.hpp"
|
||||
#include "discord/chatsubmitparams.hpp"
|
||||
#include "completer.hpp"
|
||||
#include "state.hpp"
|
||||
|
||||
@ -55,7 +56,7 @@ protected:
|
||||
|
||||
Snowflake m_active_channel;
|
||||
|
||||
bool OnInputSubmit(const Glib::ustring &text, const std::vector<std::string> &attachment_paths);
|
||||
bool OnInputSubmit(ChatSubmitParams data);
|
||||
|
||||
bool OnKeyPressEvent(GdkEventKey *e);
|
||||
void OnScrollEdgeOvershot(Gtk::PositionType pos);
|
||||
@ -84,7 +85,7 @@ protected:
|
||||
|
||||
public:
|
||||
using type_signal_action_message_edit = sigc::signal<void, Snowflake, Snowflake>;
|
||||
using type_signal_action_chat_submit = sigc::signal<void, std::string, std::vector<std::string>, Snowflake, Snowflake>;
|
||||
using type_signal_action_chat_submit = sigc::signal<void, ChatSubmitParams>;
|
||||
using type_signal_action_chat_load_history = sigc::signal<void, Snowflake>;
|
||||
using type_signal_action_channel_click = sigc::signal<void, Snowflake, bool>;
|
||||
using type_signal_action_insert_mention = sigc::signal<void, Snowflake>;
|
||||
|
22
src/discord/chatsubmitparams.hpp
Normal file
22
src/discord/chatsubmitparams.hpp
Normal file
@ -0,0 +1,22 @@
|
||||
#pragma once
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <glibmm/ustring.h>
|
||||
#include "discord/snowflake.hpp"
|
||||
|
||||
struct ChatSubmitParams {
|
||||
enum AttachmentType {
|
||||
PastedImage,
|
||||
ExtantFile,
|
||||
};
|
||||
|
||||
struct Attachment {
|
||||
std::string Path;
|
||||
AttachmentType Type;
|
||||
};
|
||||
|
||||
Snowflake ChannelID;
|
||||
Snowflake InReplyToID;
|
||||
Glib::ustring Message;
|
||||
std::vector<Attachment> Attachments;
|
||||
};
|
@ -413,7 +413,7 @@ bool DiscordClient::CanManageMember(Snowflake guild_id, Snowflake actor, Snowfla
|
||||
return actor_highest->Position > target_highest->Position;
|
||||
}
|
||||
|
||||
void DiscordClient::ChatMessageCallback(const std::string &nonce, const http::response_type &response) {
|
||||
void DiscordClient::ChatMessageCallback(const std::string &nonce, const http::response_type &response, const sigc::slot<void(DiscordError)> &callback) {
|
||||
if (!CheckCode(response)) {
|
||||
if (response.status_code == http::TooManyRequests) {
|
||||
try { // not sure if this body is guaranteed
|
||||
@ -425,75 +425,79 @@ void DiscordClient::ChatMessageCallback(const std::string &nonce, const http::re
|
||||
} else {
|
||||
m_signal_message_send_fail.emit(nonce, 0);
|
||||
}
|
||||
|
||||
// todo actually callback with correct error code (not necessary rn)
|
||||
callback(DiscordError::GENERIC);
|
||||
} else {
|
||||
callback(DiscordError::NONE);
|
||||
}
|
||||
}
|
||||
|
||||
void DiscordClient::SendChatMessageAttachments(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message) {
|
||||
void DiscordClient::SendChatMessageNoAttachments(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError)> &callback) {
|
||||
const auto nonce = std::to_string(Snowflake::FromNow());
|
||||
CreateMessageObject obj;
|
||||
obj.Content = content;
|
||||
obj.Nonce = nonce;
|
||||
if (referenced_message.IsValid())
|
||||
obj.MessageReference.emplace().MessageID = referenced_message;
|
||||
|
||||
auto req = m_http.CreateRequest(http::REQUEST_POST, "/channels/" + std::to_string(channel) + "/messages");
|
||||
req.make_form();
|
||||
req.add_field("payload_json", nlohmann::json(obj).dump().c_str(), CURL_ZERO_TERMINATED);
|
||||
for (size_t i = 0; i < attachment_paths.size(); i++) {
|
||||
const auto field_name = "files[" + std::to_string(i) + "]";
|
||||
req.add_file(field_name, attachment_paths.at(i), "unknown.png");
|
||||
}
|
||||
m_http.Execute(std::move(req), [this, attachment_paths, nonce](const http::response_type &res) {
|
||||
for (const auto &path : attachment_paths) {
|
||||
std::error_code ec;
|
||||
std::filesystem::remove(path, ec);
|
||||
}
|
||||
ChatMessageCallback(nonce, res);
|
||||
});
|
||||
}
|
||||
|
||||
void DiscordClient::SendChatMessageText(const std::string &content, Snowflake channel, Snowflake referenced_message) {
|
||||
// @([^@#]{1,32})#(\\d{4})
|
||||
const auto nonce = std::to_string(Snowflake::FromNow());
|
||||
CreateMessageObject obj;
|
||||
obj.Content = content;
|
||||
obj.Content = params.Message;
|
||||
obj.Nonce = nonce;
|
||||
if (referenced_message.IsValid())
|
||||
obj.MessageReference.emplace().MessageID = referenced_message;
|
||||
m_http.MakePOST("/channels/" + std::to_string(channel) + "/messages", nlohmann::json(obj).dump(), sigc::bind<0>(sigc::mem_fun(*this, &DiscordClient::ChatMessageCallback), nonce));
|
||||
// dummy data so the content can be shown while waiting for MESSAGE_CREATE
|
||||
if (params.InReplyToID.IsValid())
|
||||
obj.MessageReference.emplace().MessageID = params.InReplyToID;
|
||||
|
||||
m_http.MakePOST("/channels/" + std::to_string(params.ChannelID) + "/messages",
|
||||
nlohmann::json(obj).dump(),
|
||||
[this, nonce, callback](const http::response_type &r) {
|
||||
ChatMessageCallback(nonce, r, callback);
|
||||
});
|
||||
|
||||
// dummy preview data
|
||||
Message tmp;
|
||||
tmp.Content = content;
|
||||
tmp.Content = params.Message;
|
||||
tmp.ID = nonce;
|
||||
tmp.ChannelID = channel;
|
||||
tmp.ChannelID = params.ChannelID;
|
||||
tmp.Author = GetUserData();
|
||||
tmp.IsTTS = false;
|
||||
tmp.DoesMentionEveryone = false;
|
||||
tmp.Type = MessageType::DEFAULT;
|
||||
tmp.IsPinned = false;
|
||||
tmp.Timestamp = "2000-01-01T00:00:00.000000+00:00";
|
||||
tmp.Nonce = obj.Nonce;
|
||||
tmp.Nonce = nonce;
|
||||
tmp.IsPending = true;
|
||||
|
||||
m_store.SetMessage(tmp.ID, tmp);
|
||||
m_signal_message_sent.emit(tmp);
|
||||
m_signal_message_create.emit(tmp);
|
||||
}
|
||||
|
||||
void DiscordClient::SendChatMessage(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel) {
|
||||
if (attachment_paths.empty())
|
||||
SendChatMessageText(content, channel);
|
||||
else {
|
||||
puts("attach");
|
||||
SendChatMessageAttachments(content, attachment_paths, channel, Snowflake::Invalid);
|
||||
void DiscordClient::SendChatMessageAttachments(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError)> &callback) {
|
||||
const auto nonce = std::to_string(Snowflake::FromNow());
|
||||
|
||||
CreateMessageObject obj;
|
||||
obj.Content = params.Message;
|
||||
obj.Nonce = nonce;
|
||||
if (params.InReplyToID.IsValid())
|
||||
obj.MessageReference.emplace().MessageID = params.InReplyToID;
|
||||
|
||||
auto req = m_http.CreateRequest(http::REQUEST_POST, "/channels/" + std::to_string(params.ChannelID) + "/messages");
|
||||
req.make_form();
|
||||
req.add_field("payload_json", nlohmann::json(obj).dump().c_str(), CURL_ZERO_TERMINATED);
|
||||
for (size_t i = 0; i < params.Attachments.size(); i++) {
|
||||
const auto field_name = "files[" + std::to_string(i) + "]";
|
||||
req.add_file(field_name, params.Attachments.at(i).Path, "unknown.png");
|
||||
}
|
||||
m_http.Execute(std::move(req), [this, params, nonce, callback](const http::response_type &res) {
|
||||
for (const auto &attachment : params.Attachments) {
|
||||
if (attachment.Type == ChatSubmitParams::AttachmentType::PastedImage) {
|
||||
std::error_code ec;
|
||||
std::filesystem::remove(attachment.Path, ec);
|
||||
}
|
||||
}
|
||||
ChatMessageCallback(nonce, res, callback);
|
||||
});
|
||||
}
|
||||
|
||||
void DiscordClient::SendChatMessage(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message) {
|
||||
if (attachment_paths.empty())
|
||||
SendChatMessageText(content, channel, referenced_message);
|
||||
else {
|
||||
puts("attach");
|
||||
SendChatMessageAttachments(content, attachment_paths, channel, referenced_message);
|
||||
}
|
||||
void DiscordClient::SendChatMessage(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError)> &callback) {
|
||||
if (params.Attachments.empty())
|
||||
SendChatMessageNoAttachments(params, callback);
|
||||
else
|
||||
SendChatMessageAttachments(params, callback);
|
||||
}
|
||||
|
||||
void DiscordClient::DeleteMessage(Snowflake channel_id, Snowflake id) {
|
||||
@ -1302,6 +1306,7 @@ void DiscordClient::HandleGatewayMessage(std::string str) {
|
||||
HandleGatewayInvalidSession(m);
|
||||
} break;
|
||||
case GatewayOp::Dispatch: {
|
||||
puts(m.Type.c_str());
|
||||
auto iter = m_event_map.find(m.Type);
|
||||
if (iter == m_event_map.end()) {
|
||||
printf("Unknown event %s\n", m.Type.c_str());
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "httpclient.hpp"
|
||||
#include "objects.hpp"
|
||||
#include "store.hpp"
|
||||
#include "chatsubmitparams.hpp"
|
||||
#include <sigc++/sigc++.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
#include <thread>
|
||||
@ -103,10 +104,11 @@ public:
|
||||
Permission ComputeOverwrites(Permission base, Snowflake member_id, Snowflake channel_id) const;
|
||||
bool CanManageMember(Snowflake guild_id, Snowflake actor, Snowflake target) const; // kick, ban, edit nickname (cant think of a better name)
|
||||
|
||||
void ChatMessageCallback(const std::string &nonce, const http::response_type &response);
|
||||
void ChatMessageCallback(const std::string &nonce, const http::response_type &response, const sigc::slot<void(DiscordError code)> &callback);
|
||||
void SendChatMessageNoAttachments(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError code)> &callback);
|
||||
void SendChatMessageAttachments(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError code)> &callback);
|
||||
|
||||
void SendChatMessage(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel);
|
||||
void SendChatMessage(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message);
|
||||
void SendChatMessage(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError code)> &callback);
|
||||
void DeleteMessage(Snowflake channel_id, Snowflake id);
|
||||
void EditMessage(Snowflake channel_id, Snowflake id, std::string content);
|
||||
void SendLazyLoad(Snowflake id);
|
||||
@ -224,9 +226,6 @@ private:
|
||||
std::vector<uint8_t> m_decompress_buf;
|
||||
z_stream m_zstream;
|
||||
|
||||
void SendChatMessageAttachments(const std::string &content, const std::vector<std::string> &attachment_paths, Snowflake channel, Snowflake referenced_message = Snowflake::Invalid);
|
||||
void SendChatMessageText(const std::string &content, Snowflake channel, Snowflake referenced_message = Snowflake::Invalid);
|
||||
|
||||
static std::string GetAPIURL();
|
||||
static std::string GetGatewayURL();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user