add file upload via dnd + rework http

This commit is contained in:
ouwou
2022-06-17 02:46:55 -04:00
parent d0fa308f6e
commit 4ee7025ab0
11 changed files with 146 additions and 33 deletions

View File

@@ -105,8 +105,7 @@ ChatInputAttachmentContainer::ChatInputAttachmentContainer()
void ChatInputAttachmentContainer::Clear() {
for (auto *item : m_attachments) {
std::error_code ec;
std::filesystem::remove(item->GetPath(), ec);
item->RemoveIfTemp();
delete item;
}
m_attachments.clear();
@@ -133,16 +132,36 @@ bool ChatInputAttachmentContainer::AddImage(const Glib::RefPtr<Gdk::Pixbuf> &pb)
return false;
}
auto *item = Gtk::make_managed<ChatInputAttachmentItem>(path, pb);
auto *item = Gtk::make_managed<ChatInputAttachmentItem>(Gio::File::create_for_path(path), pb);
item->show();
item->set_valign(Gtk::ALIGN_CENTER);
m_box.add(*item);
m_attachments.push_back(item);
item->signal_remove().connect([this, item] {
std::error_code ec;
std::filesystem::remove(item->GetPath(), ec);
item->signal_item_removed().connect([this, item] {
item->RemoveIfTemp();
if (auto it = std::find(m_attachments.begin(), m_attachments.end(), item); it != m_attachments.end())
m_attachments.erase(it);
delete item;
if (m_attachments.empty())
m_signal_emptied.emit();
});
return true;
}
bool ChatInputAttachmentContainer::AddFile(const Glib::RefPtr<Gio::File> &file) {
if (m_attachments.size() == 10) return false;
auto *item = Gtk::make_managed<ChatInputAttachmentItem>(file);
item->show();
item->set_valign(Gtk::ALIGN_CENTER);
m_box.add(*item);
m_attachments.push_back(item);
item->signal_item_removed().connect([this, item] {
if (auto it = std::find(m_attachments.begin(), m_attachments.end(), item); it != m_attachments.end())
m_attachments.erase(it);
delete item;
@@ -155,8 +174,11 @@ bool ChatInputAttachmentContainer::AddImage(const Glib::RefPtr<Gdk::Pixbuf> &pb)
std::vector<ChatSubmitParams::Attachment> ChatInputAttachmentContainer::GetAttachments() const {
std::vector<ChatSubmitParams::Attachment> ret;
for (auto *x : m_attachments)
ret.push_back({ x->GetPath(), x->GetType() });
for (auto *x : m_attachments) {
if (!x->GetFile()->query_exists())
puts("bad!");
ret.push_back({ x->GetFile(), x->GetType(), x->GetFilename() });
}
return ret;
}
@@ -164,10 +186,28 @@ ChatInputAttachmentContainer::type_signal_emptied ChatInputAttachmentContainer::
return m_signal_emptied;
}
ChatInputAttachmentItem::ChatInputAttachmentItem(std::string path, const Glib::RefPtr<Gdk::Pixbuf> &pb)
: m_path(std::move(path))
ChatInputAttachmentItem::ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file)
: m_file(file)
, m_img(Gtk::make_managed<Gtk::Image>(Abaddon::Get().GetImageManager().GetPlaceholder(AttachmentItemSize)))
, m_type(ChatSubmitParams::ExtantFile) {
get_style_context()->add_class("attachment-item");
set_size_request(AttachmentItemSize, AttachmentItemSize);
m_box.add(*m_img);
add(m_box);
show_all_children();
SetupMenu();
auto info = m_file->query_info(G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
m_filename = info->get_attribute_string(G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME);
}
ChatInputAttachmentItem::ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file, const Glib::RefPtr<Gdk::Pixbuf> &pb)
: m_file(file)
, m_img(Gtk::make_managed<Gtk::Image>())
, m_type(ChatSubmitParams::PastedImage) {
, m_type(ChatSubmitParams::PastedImage)
, m_filename("unknown.png") {
get_style_context()->add_class("attachment-item");
int outw, outh;
@@ -182,18 +222,31 @@ ChatInputAttachmentItem::ChatInputAttachmentItem(std::string path, const Glib::R
SetupMenu();
}
std::string ChatInputAttachmentItem::GetPath() const {
return m_path;
Glib::RefPtr<Gio::File> ChatInputAttachmentItem::GetFile() const {
return m_file;
}
ChatSubmitParams::AttachmentType ChatInputAttachmentItem::GetType() const {
return m_type;
}
std::string ChatInputAttachmentItem::GetFilename() const {
return m_filename;
}
bool ChatInputAttachmentItem::IsTemp() const noexcept {
return m_type == ChatSubmitParams::PastedImage;
}
void ChatInputAttachmentItem::RemoveIfTemp() {
if (IsTemp())
m_file->remove();
}
void ChatInputAttachmentItem::SetupMenu() {
m_menu_remove.set_label("Remove");
m_menu_remove.signal_activate().connect([this] {
m_signal_remove.emit();
m_signal_item_removed.emit();
});
m_menu.add(m_menu_remove);
@@ -209,8 +262,8 @@ void ChatInputAttachmentItem::SetupMenu() {
});
}
ChatInputAttachmentItem::type_signal_remove ChatInputAttachmentItem::signal_remove() {
return m_signal_remove;
ChatInputAttachmentItem::type_signal_item_removed ChatInputAttachmentItem::signal_item_removed() {
return m_signal_item_removed;
}
ChatInput::ChatInput()
@@ -271,6 +324,13 @@ bool ChatInput::ProcessKeyPress(GdkEventKey *event) {
return m_input.ProcessKeyPress(event);
}
void ChatInput::AddAttachment(const Glib::RefPtr<Gio::File> &file) {
const bool can_attach_files = m_signal_check_permission.emit(Permission::ATTACH_FILES);
if (can_attach_files && m_attachments.AddFile(file))
m_attachments_revealer.set_reveal_child(true);
}
ChatInput::type_signal_submit ChatInput::signal_submit() {
return m_signal_submit;
}

View File

@@ -5,10 +5,14 @@
class ChatInputAttachmentItem : public Gtk::EventBox {
public:
ChatInputAttachmentItem(std::string path, const Glib::RefPtr<Gdk::Pixbuf> &pb);
ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file);
ChatInputAttachmentItem(const Glib::RefPtr<Gio::File> &file, const Glib::RefPtr<Gdk::Pixbuf> &pb);
[[nodiscard]] std::string GetPath() const;
[[nodiscard]] Glib::RefPtr<Gio::File> GetFile() const;
[[nodiscard]] ChatSubmitParams::AttachmentType GetType() const;
[[nodiscard]] std::string GetFilename() const;
[[nodiscard]] bool IsTemp() const noexcept;
void RemoveIfTemp();
private:
void SetupMenu();
@@ -19,16 +23,17 @@ private:
Gtk::Box m_box;
Gtk::Image *m_img = nullptr;
std::string m_path;
Glib::RefPtr<Gio::File> m_file;
ChatSubmitParams::AttachmentType m_type;
std::string m_filename;
private:
using type_signal_remove = sigc::signal<void>;
using type_signal_item_removed = sigc::signal<void>;
type_signal_remove m_signal_remove;
type_signal_item_removed m_signal_item_removed;
public:
type_signal_remove signal_remove();
type_signal_item_removed signal_item_removed();
};
class ChatInputAttachmentContainer : public Gtk::ScrolledWindow {
@@ -38,6 +43,7 @@ public:
void Clear();
void ClearNoPurge();
bool AddImage(const Glib::RefPtr<Gdk::Pixbuf> &pb);
bool AddFile(const Glib::RefPtr<Gio::File> &file);
[[nodiscard]] std::vector<ChatSubmitParams::Attachment> GetAttachments() const;
private:
@@ -92,6 +98,7 @@ public:
void InsertText(const Glib::ustring &text);
Glib::RefPtr<Gtk::TextBuffer> GetBuffer();
bool ProcessKeyPress(GdkEventKey *event);
void AddAttachment(const Glib::RefPtr<Gio::File> &file);
private:
Gtk::Revealer m_attachments_revealer;

View File

@@ -170,6 +170,10 @@ void ChatWindow::SetTopic(const std::string &text) {
m_topic.set_visible(text.length() > 0);
}
void ChatWindow::AddAttachment(const Glib::RefPtr<Gio::File> &file) {
m_input->AddAttachment(file);
}
#ifdef WITH_LIBHANDY
void ChatWindow::OpenNewTab(Snowflake id) {
// open if its the first tab (in which case it really isnt a tab but whatever)

View File

@@ -35,6 +35,7 @@ public:
Snowflake GetOldestListedMessage(); // oldest message that is currently in the ListBox
void UpdateReactions(Snowflake id);
void SetTopic(const std::string &text);
void AddAttachment(const Glib::RefPtr<Gio::File> &file);
#ifdef WITH_LIBHANDY
void OpenNewTab(Snowflake id);