mirror of
https://github.com/uowuo/abaddon.git
synced 2024-09-20 06:51:51 +00:00
add upload progress bar
This commit is contained in:
parent
5c7631e713
commit
41776fbd02
|
@ -323,3 +323,18 @@
|
|||
.channel-tab-switcher tab > button:hover {
|
||||
background-color: alpha(#ff0000, 0.5);
|
||||
}
|
||||
|
||||
.message-progress {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.message-progress trough {
|
||||
border: none;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
.message-progress progress {
|
||||
border: none;
|
||||
background-color: #dd3300;
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@
|
|||
#endif
|
||||
|
||||
ChatWindow::ChatWindow() {
|
||||
Abaddon::Get().GetDiscordClient().signal_message_send_fail().connect(sigc::mem_fun(*this, &ChatWindow::OnMessageSendFail));
|
||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||
discord.signal_message_send_fail().connect(sigc::mem_fun(*this, &ChatWindow::OnMessageSendFail));
|
||||
|
||||
m_main = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL));
|
||||
m_chat = Gtk::manage(new ChatList);
|
||||
|
@ -59,11 +60,11 @@ ChatWindow::ChatWindow() {
|
|||
m_input->show();
|
||||
|
||||
m_completer.SetBuffer(m_input->GetBuffer());
|
||||
m_completer.SetGetChannelID([this]() -> auto {
|
||||
m_completer.SetGetChannelID([this]() {
|
||||
return m_active_channel;
|
||||
});
|
||||
|
||||
m_completer.SetGetRecentAuthors([this]() -> auto {
|
||||
m_completer.SetGetRecentAuthors([this]() {
|
||||
return m_chat->GetRecentAuthors();
|
||||
});
|
||||
|
||||
|
@ -109,6 +110,10 @@ ChatWindow::ChatWindow() {
|
|||
m_main->add(m_completer);
|
||||
m_main->add(*m_input);
|
||||
m_main->add(*m_meta);
|
||||
m_main->add(m_progress);
|
||||
|
||||
m_progress.show();
|
||||
|
||||
m_main->show();
|
||||
}
|
||||
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "discord/chatsubmitparams.hpp"
|
||||
#include "completer.hpp"
|
||||
#include "state.hpp"
|
||||
#include "progressbar.hpp"
|
||||
|
||||
#ifdef WITH_LIBHANDY
|
||||
class ChannelTabSwitcherHandy;
|
||||
|
@ -79,6 +80,7 @@ protected:
|
|||
ChatInputIndicator *m_input_indicator;
|
||||
RateLimitIndicator *m_rate_limit_indicator;
|
||||
Gtk::Box *m_meta;
|
||||
MessageUploadProgressBar m_progress;
|
||||
|
||||
#ifdef WITH_LIBHANDY
|
||||
ChannelTabSwitcherHandy *m_tab_switcher;
|
||||
|
|
24
src/components/progressbar.cpp
Normal file
24
src/components/progressbar.cpp
Normal file
|
@ -0,0 +1,24 @@
|
|||
#include "progressbar.hpp"
|
||||
#include "abaddon.hpp"
|
||||
|
||||
MessageUploadProgressBar::MessageUploadProgressBar() {
|
||||
get_style_context()->add_class("message-progress");
|
||||
auto &discord = Abaddon::Get().GetDiscordClient();
|
||||
discord.signal_message_progress().connect([this](const std::string &nonce, float percent) {
|
||||
if (nonce == m_last_nonce) {
|
||||
set_fraction(percent);
|
||||
}
|
||||
});
|
||||
discord.signal_message_send_fail().connect([this](const std::string &nonce, float) {
|
||||
if (nonce == m_last_nonce)
|
||||
set_fraction(0.0);
|
||||
});
|
||||
discord.signal_message_create().connect([this](const Message &msg) {
|
||||
if (msg.IsPending) {
|
||||
m_last_nonce = *msg.Nonce;
|
||||
} else if (msg.Nonce.has_value() && (*msg.Nonce == m_last_nonce)) {
|
||||
m_last_nonce = "";
|
||||
set_fraction(0.0);
|
||||
}
|
||||
});
|
||||
}
|
11
src/components/progressbar.hpp
Normal file
11
src/components/progressbar.hpp
Normal file
|
@ -0,0 +1,11 @@
|
|||
#pragma once
|
||||
#include <gtkmm/progressbar.h>
|
||||
#include <string>
|
||||
|
||||
class MessageUploadProgressBar : public Gtk::ProgressBar {
|
||||
public:
|
||||
MessageUploadProgressBar();
|
||||
|
||||
private:
|
||||
std::string m_last_nonce;
|
||||
};
|
|
@ -476,6 +476,15 @@ void DiscordClient::SendChatMessageAttachments(const ChatSubmitParams ¶ms, c
|
|||
obj.MessageReference.emplace().MessageID = params.InReplyToID;
|
||||
|
||||
auto req = m_http.CreateRequest(http::REQUEST_POST, "/channels/" + std::to_string(params.ChannelID) + "/messages");
|
||||
req.set_progress_callback([this, nonce](curl_off_t ultotal, curl_off_t ulnow) {
|
||||
m_generic_mutex.lock();
|
||||
m_generic_queue.push(sigc::bind(
|
||||
sigc::mem_fun(m_signal_message_progress, decltype(m_signal_message_progress)::emit),
|
||||
nonce,
|
||||
static_cast<float>(ulnow) / static_cast<float>(ultotal)));
|
||||
m_generic_dispatch.emit();
|
||||
m_generic_mutex.unlock();
|
||||
});
|
||||
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++) {
|
||||
|
@ -490,6 +499,23 @@ void DiscordClient::SendChatMessageAttachments(const ChatSubmitParams ¶ms, c
|
|||
}
|
||||
ChatMessageCallback(nonce, res, callback);
|
||||
});
|
||||
|
||||
// dummy preview data
|
||||
Message tmp;
|
||||
tmp.Content = params.Message;
|
||||
tmp.ID = nonce;
|
||||
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 = nonce;
|
||||
tmp.IsPending = true;
|
||||
|
||||
m_store.SetMessage(tmp.ID, tmp);
|
||||
m_signal_message_create.emit(tmp);
|
||||
}
|
||||
|
||||
void DiscordClient::SendChatMessage(const ChatSubmitParams ¶ms, const sigc::slot<void(DiscordError)> &callback) {
|
||||
|
@ -2568,6 +2594,10 @@ DiscordClient::type_signal_connected DiscordClient::signal_connected() {
|
|||
return m_signal_connected;
|
||||
}
|
||||
|
||||
DiscordClient::type_signal_message_progress DiscordClient::signal_message_progress() {
|
||||
return m_signal_message_progress;
|
||||
}
|
||||
|
||||
DiscordClient::type_signal_role_update DiscordClient::signal_role_update() {
|
||||
return m_signal_role_update;
|
||||
}
|
||||
|
|
|
@ -404,6 +404,7 @@ public:
|
|||
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;
|
||||
typedef sigc::signal<void, std::string, float> type_signal_message_progress;
|
||||
|
||||
type_signal_gateway_ready signal_gateway_ready();
|
||||
type_signal_message_create signal_message_create();
|
||||
|
@ -457,6 +458,7 @@ public:
|
|||
type_signal_message_send_fail signal_message_send_fail();
|
||||
type_signal_disconnected signal_disconnected();
|
||||
type_signal_connected signal_connected();
|
||||
type_signal_message_progress signal_message_progress();
|
||||
|
||||
protected:
|
||||
type_signal_gateway_ready m_signal_gateway_ready;
|
||||
|
@ -511,4 +513,5 @@ protected:
|
|||
type_signal_message_send_fail m_signal_message_send_fail;
|
||||
type_signal_disconnected m_signal_disconnected;
|
||||
type_signal_connected m_signal_connected;
|
||||
type_signal_message_progress m_signal_message_progress;
|
||||
};
|
||||
|
|
23
src/http.cpp
23
src/http.cpp
|
@ -36,8 +36,11 @@ request::request(request &&other) noexcept
|
|||
, m_header_list(std::exchange(other.m_header_list, nullptr))
|
||||
, m_error_buf(other.m_error_buf)
|
||||
, m_form(std::exchange(other.m_form, nullptr))
|
||||
, m_read_streams(std::move(other.m_read_streams)) {
|
||||
// i think this is correct???
|
||||
, m_read_streams(std::move(other.m_read_streams))
|
||||
, m_progress_callback(std::move(other.m_progress_callback)) {
|
||||
if (m_progress_callback) {
|
||||
curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, this);
|
||||
}
|
||||
}
|
||||
|
||||
request::~request() {
|
||||
|
@ -59,6 +62,22 @@ const char *request::get_method() const {
|
|||
return m_method;
|
||||
}
|
||||
|
||||
size_t http_req_xferinfofunc(void *clientp, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal, curl_off_t ulnow) {
|
||||
if (ultotal > 0) {
|
||||
auto *req = reinterpret_cast<request *>(clientp);
|
||||
req->m_progress_callback(ultotal, ulnow);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void request::set_progress_callback(std::function<void(curl_off_t, curl_off_t)> func) {
|
||||
m_progress_callback = std::move(func);
|
||||
curl_easy_setopt(m_curl, CURLOPT_NOPROGRESS, 0L);
|
||||
curl_easy_setopt(m_curl, CURLOPT_XFERINFOFUNCTION, http_req_xferinfofunc);
|
||||
curl_easy_setopt(m_curl, CURLOPT_XFERINFODATA, this);
|
||||
}
|
||||
|
||||
void request::set_verify_ssl(bool verify) {
|
||||
curl_easy_setopt(m_curl, CURLOPT_SSL_VERIFYPEER, verify ? 1L : 0L);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <curl/curl.h>
|
||||
|
@ -109,6 +110,7 @@ struct request {
|
|||
const std::string &get_url() const;
|
||||
const char *get_method() const;
|
||||
|
||||
void set_progress_callback(std::function<void(curl_off_t, curl_off_t)> func);
|
||||
void set_verify_ssl(bool verify);
|
||||
void set_proxy(const std::string &proxy);
|
||||
void set_header(const std::string &name, const std::string &value);
|
||||
|
@ -129,8 +131,11 @@ private:
|
|||
curl_slist *m_header_list = nullptr;
|
||||
std::array<char, CURL_ERROR_SIZE> m_error_buf = { 0 };
|
||||
curl_mime *m_form = nullptr;
|
||||
std::function<void(curl_off_t, curl_off_t)> m_progress_callback;
|
||||
|
||||
std::set<Glib::RefPtr<Gio::FileInputStream>> m_read_streams;
|
||||
|
||||
friend size_t http_req_xferinfofunc(void *, curl_off_t, curl_off_t, curl_off_t, curl_off_t);
|
||||
};
|
||||
|
||||
using response_type = response;
|
||||
|
|
Loading…
Reference in New Issue
Block a user