From 4ee7025ab09b606a2556bf9f42c1218d7fd72843 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 17 Jun 2022 02:46:55 -0400 Subject: add file upload via dnd + rework http --- src/components/chatinput.cpp | 92 +++++++++++++++++++++++++++++++++++-------- src/components/chatinput.hpp | 19 ++++++--- src/components/chatwindow.cpp | 4 ++ src/components/chatwindow.hpp | 1 + 4 files changed, 94 insertions(+), 22 deletions(-) (limited to 'src/components') diff --git a/src/components/chatinput.cpp b/src/components/chatinput.cpp index 5a6e71e..269a2ac 100644 --- a/src/components/chatinput.cpp +++ b/src/components/chatinput.cpp @@ -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 &pb) return false; } - auto *item = Gtk::make_managed(path, pb); + auto *item = Gtk::make_managed(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 &file) { + if (m_attachments.size() == 10) return false; + + auto *item = Gtk::make_managed(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 &pb) std::vector ChatInputAttachmentContainer::GetAttachments() const { std::vector 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 &pb) - : m_path(std::move(path)) +ChatInputAttachmentItem::ChatInputAttachmentItem(const Glib::RefPtr &file) + : m_file(file) + , m_img(Gtk::make_managed(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 &file, const Glib::RefPtr &pb) + : m_file(file) , m_img(Gtk::make_managed()) - , 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 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 &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; } diff --git a/src/components/chatinput.hpp b/src/components/chatinput.hpp index 254f96f..865b23e 100644 --- a/src/components/chatinput.hpp +++ b/src/components/chatinput.hpp @@ -5,10 +5,14 @@ class ChatInputAttachmentItem : public Gtk::EventBox { public: - ChatInputAttachmentItem(std::string path, const Glib::RefPtr &pb); + ChatInputAttachmentItem(const Glib::RefPtr &file); + ChatInputAttachmentItem(const Glib::RefPtr &file, const Glib::RefPtr &pb); - [[nodiscard]] std::string GetPath() const; + [[nodiscard]] Glib::RefPtr 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 m_file; ChatSubmitParams::AttachmentType m_type; + std::string m_filename; private: - using type_signal_remove = sigc::signal; + using type_signal_item_removed = sigc::signal; - 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 &pb); + bool AddFile(const Glib::RefPtr &file); [[nodiscard]] std::vector GetAttachments() const; private: @@ -92,6 +98,7 @@ public: void InsertText(const Glib::ustring &text); Glib::RefPtr GetBuffer(); bool ProcessKeyPress(GdkEventKey *event); + void AddAttachment(const Glib::RefPtr &file); private: Gtk::Revealer m_attachments_revealer; diff --git a/src/components/chatwindow.cpp b/src/components/chatwindow.cpp index 3e1885b..d9d490b 100644 --- a/src/components/chatwindow.cpp +++ b/src/components/chatwindow.cpp @@ -170,6 +170,10 @@ void ChatWindow::SetTopic(const std::string &text) { m_topic.set_visible(text.length() > 0); } +void ChatWindow::AddAttachment(const Glib::RefPtr &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) diff --git a/src/components/chatwindow.hpp b/src/components/chatwindow.hpp index ecbf666..917456b 100644 --- a/src/components/chatwindow.hpp +++ b/src/components/chatwindow.hpp @@ -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 &file); #ifdef WITH_LIBHANDY void OpenNewTab(Snowflake id); -- cgit v1.2.3