update rate limit indicator on failed message send

this happens when you start the client while already rate-limited
This commit is contained in:
ouwou 2021-04-14 02:11:36 -04:00
parent 9a7a468607
commit 9733ae54c3
8 changed files with 45 additions and 5 deletions

View File

@ -365,7 +365,7 @@ void ChatWindow::ScrollToBottom() {
x->set_value(x->get_upper());
}
void ChatWindow::OnMessageSendFail(const std::string &nonce) {
void ChatWindow::OnMessageSendFail(const std::string &nonce, float retry_after) {
for (auto [id, widget] : m_id_to_widget) {
if (auto *container = dynamic_cast<ChatMessageItemContainer *>(widget); container->Nonce == nonce) {
container->SetFailed();

View File

@ -54,7 +54,7 @@ protected:
void ScrollToBottom();
bool m_should_scroll_to_bottom = true;
void OnMessageSendFail(const std::string &nonce);
void OnMessageSendFail(const std::string &nonce, float retry_after);
Gtk::Box *m_main;
Gtk::ListBox *m_list;

View File

@ -25,6 +25,7 @@ RateLimitIndicator::RateLimitIndicator()
}
Abaddon::Get().GetDiscordClient().signal_message_create().connect(sigc::mem_fun(*this, &RateLimitIndicator::OnMessageCreate));
Abaddon::Get().GetDiscordClient().signal_message_send_fail().connect(sigc::mem_fun(*this, &RateLimitIndicator::OnMessageSendFail));
}
void RateLimitIndicator::SetActiveChannel(Snowflake id) {
@ -109,3 +110,15 @@ void RateLimitIndicator::OnMessageCreate(const Message &message) {
UpdateIndicator();
}
}
void RateLimitIndicator::OnMessageSendFail(const std::string &nonce, float retry_after) {
if (retry_after != 0) { // failed to rate limit
const auto msg = Abaddon::Get().GetDiscordClient().GetMessage(nonce);
const auto channel_id = msg->ChannelID;
const auto channel = *Abaddon::Get().GetDiscordClient().GetChannel(channel_id);
const auto rate_limit = *channel.RateLimitPerUser;
const auto sent_time = std::chrono::steady_clock::now() - std::chrono::duration<int>(rate_limit - std::lroundf(retry_after + 0.5f)); // + 0.5 will ceil it
m_times[channel_id] = sent_time;
UpdateIndicator();
}
}

View File

@ -17,6 +17,7 @@ private:
int GetRateLimit() const;
bool UpdateIndicator();
void OnMessageCreate(const Message &message);
void OnMessageSendFail(const std::string &nonce, float rate_limit);
Gtk::Image m_img;
Gtk::Label m_label;

View File

@ -353,7 +353,16 @@ bool DiscordClient::CanManageMember(Snowflake guild_id, Snowflake actor, Snowfla
void DiscordClient::ChatMessageCallback(std::string nonce, const http::response_type &response) {
if (!CheckCode(response)) {
m_signal_message_send_fail.emit(nonce);
if (response.status_code == http::TooManyRequests) {
try { // not sure if this body is guaranteed
RateLimitedResponse r = nlohmann::json::parse(response.text);
m_signal_message_send_fail.emit(nonce, r.RetryAfter);
} catch (...) {
m_signal_message_send_fail.emit(nonce, 0);
}
} else {
m_signal_message_send_fail.emit(nonce, 0);
}
}
}

View File

@ -313,8 +313,8 @@ public:
typedef sigc::signal<void, GuildJoinRequestUpdateData> type_signal_guild_join_request_update;
typedef sigc::signal<void, GuildJoinRequestDeleteData> type_signal_guild_join_request_delete;
typedef sigc::signal<void, Message> type_signal_message_sent;
typedef sigc::signal<void, std::string> type_signal_message_send_fail;
typedef sigc::signal<void, bool, GatewayCloseCode> type_signal_disconnected; // bool true if reconnecting
typedef sigc::signal<void, std::string /* nonce */, float /* retry_after */> type_signal_message_send_fail; // retry after param will be 0 if it failed for a reason that isnt slowmode
typedef sigc::signal<void, bool, GatewayCloseCode> type_signal_disconnected; // bool true if reconnecting
typedef sigc::signal<void> type_signal_connected;
type_signal_gateway_ready signal_gateway_ready();

View File

@ -444,3 +444,10 @@ void to_json(nlohmann::json &j, const VerificationGateInfoObject &m) {
JS_IF("version", m.Version);
JS_IF("enabled", m.Enabled);
}
void from_json(const nlohmann::json &j, RateLimitedResponse &m) {
JS_D("code", m.Code);
JS_D("global", m.Global);
JS_O("message", m.Message);
JS_D("retry_after", m.RetryAfter);
}

View File

@ -615,3 +615,13 @@ struct VerificationGateInfoObject {
friend void from_json(const nlohmann::json &j, VerificationGateInfoObject &m);
friend void to_json(nlohmann::json &j, const VerificationGateInfoObject &m);
};
// not sure what the structure for this really is
struct RateLimitedResponse {
int Code;
bool Global;
std::optional<std::string> Message;
float RetryAfter;
friend void from_json(const nlohmann::json &j, RateLimitedResponse &m);
};