diff options
author | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-08-29 22:45:27 -0400 |
---|---|---|
committer | ouwou <26526779+ouwou@users.noreply.github.com> | 2020-08-29 22:45:27 -0400 |
commit | 08e9d2f0efa0f90b27b1aefe4d319296964dcfdb (patch) | |
tree | 2f32a432854470225cda5827eb683c8f5de348f1 /components | |
parent | a921ee42f9b5e6c658fe7fd29e14ab4814dc286b (diff) | |
download | abaddon-portaudio-08e9d2f0efa0f90b27b1aefe4d319296964dcfdb.tar.gz abaddon-portaudio-08e9d2f0efa0f90b27b1aefe4d319296964dcfdb.zip |
rework chat components to make more sense
Diffstat (limited to 'components')
-rw-r--r-- | components/chatmessage.cpp | 45 | ||||
-rw-r--r-- | components/chatmessage.hpp | 32 | ||||
-rw-r--r-- | components/chatwindow.cpp | 95 | ||||
-rw-r--r-- | components/chatwindow.hpp | 4 |
4 files changed, 80 insertions, 96 deletions
diff --git a/components/chatmessage.cpp b/components/chatmessage.cpp index 048d725..29b2ac6 100644 --- a/components/chatmessage.cpp +++ b/components/chatmessage.cpp @@ -1,20 +1,13 @@ #include "chatmessage.hpp" -ChatMessageTextItem::ChatMessageTextItem(const MessageData *data) { +ChatMessageContainer::ChatMessageContainer(const MessageData *data) { + UserID = data->Author.ID; + m_main_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); - m_sub_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); + m_content_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL)); m_meta_box = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL)); m_author = Gtk::manage(new Gtk::Label); m_timestamp = Gtk::manage(new Gtk::Label); - m_text = Gtk::manage(new Gtk::TextView); - - m_text->set_can_focus(false); - m_text->set_editable(false); - m_text->set_wrap_mode(Gtk::WRAP_WORD_CHAR); - m_text->set_halign(Gtk::ALIGN_FILL); - m_text->set_hexpand(true); - m_text->get_buffer()->set_text(data->Content); - m_text->show(); m_author->set_markup("<span weight=\"bold\">" + Glib::Markup::escape_text(data->Author.Username) + "</span>"); m_author->set_single_line_mode(true); @@ -39,32 +32,38 @@ ChatMessageTextItem::ChatMessageTextItem(const MessageData *data) { m_meta_box->set_can_focus(false); m_meta_box->show(); - m_sub_box->set_can_focus(false); - m_sub_box->show(); + m_content_box->set_can_focus(false); + m_content_box->show(); m_meta_box->add(*m_author); m_meta_box->add(*m_timestamp); - m_sub_box->add(*m_meta_box); - m_sub_box->add(*m_text); - m_main_box->add(*m_sub_box); + m_content_box->add(*m_meta_box); + m_main_box->add(*m_content_box); add(*m_main_box); set_margin_bottom(8); show(); } -void ChatMessageTextItem::AppendNewContent(std::string content) { - auto buf = m_text->get_buffer(); - buf->set_text(buf->get_text() + "\n" + content); +void ChatMessageContainer::AddNewContent(Gtk::Widget *widget, bool prepend) { + if (prepend) + m_content_box->pack_end(*widget); + else + m_content_box->pack_start(*widget); } -void ChatMessageTextItem::PrependNewContent(std::string content) { - auto buf = m_text->get_buffer(); - buf->set_text(content + "\n" + buf->get_text()); +ChatMessageTextItem::ChatMessageTextItem(const MessageData *data) { + set_can_focus(false); + set_editable(false); + set_wrap_mode(Gtk::WRAP_WORD_CHAR); + set_halign(Gtk::ALIGN_FILL); + set_hexpand(true); + get_buffer()->set_text(data->Content); + show(); } void ChatMessageTextItem::MarkAsDeleted() { - auto buf = m_text->get_buffer(); + auto buf = get_buffer(); Gtk::TextBuffer::iterator start, end; buf->get_bounds(start, end); buf->insert_markup(end, "<span color='#ff0000'> [deleted]</span>"); diff --git a/components/chatmessage.hpp b/components/chatmessage.hpp index 8007f68..181ffcd 100644 --- a/components/chatmessage.hpp +++ b/components/chatmessage.hpp @@ -7,7 +7,23 @@ enum class ChatDisplayType { Text, }; -class ChatMessageItem : public Gtk::ListBoxRow { +// contains the username and timestamp, chat items get stuck into its box +class ChatMessageContainer : public Gtk::ListBoxRow { +public: + Snowflake UserID; + + ChatMessageContainer(const MessageData *data); + void AddNewContent(Gtk::Widget *widget, bool prepend = false); + +protected: + Gtk::Box *m_main_box; + Gtk::Box *m_content_box; + Gtk::Box *m_meta_box; + Gtk::Label *m_author; + Gtk::Label *m_timestamp; +}; + +class ChatMessageItem { public: Snowflake ID; ChatDisplayType MessageType; @@ -15,18 +31,10 @@ public: virtual void MarkAsDeleted() = 0; }; -class ChatMessageTextItem : public ChatMessageItem { +class ChatMessageTextItem + : public Gtk::TextView // oh well + , public ChatMessageItem { public: ChatMessageTextItem(const MessageData *data); - void AppendNewContent(std::string content); - void PrependNewContent(std::string content); virtual void MarkAsDeleted(); - -protected: - Gtk::Box *m_main_box; - Gtk::Box *m_sub_box; - Gtk::Box *m_meta_box; - Gtk::Label *m_author; - Gtk::Label *m_timestamp; - Gtk::TextView *m_text; }; diff --git a/components/chatwindow.cpp b/components/chatwindow.cpp index 22765dc..8b477e0 100644 --- a/components/chatwindow.cpp +++ b/components/chatwindow.cpp @@ -88,60 +88,44 @@ ChatDisplayType ChatWindow::GetMessageDisplayType(const MessageData *data) { return ChatDisplayType::Unknown; } -ChatMessageItem *ChatWindow::CreateChatEntryComponentText(const MessageData *data) { - return Gtk::manage(new ChatMessageTextItem(data)); -} - -ChatMessageItem *ChatWindow::CreateChatEntryComponent(const MessageData *data) { - ChatMessageItem *item = nullptr; - switch (GetMessageDisplayType(data)) { - case ChatDisplayType::Text: - item = CreateChatEntryComponentText(data); - break; +void ChatWindow::ProcessMessage(const MessageData *data, bool prepend) { + ChatMessageContainer *last_row = nullptr; + bool should_attach = false; + if (m_num_rows > 0) { + if (prepend) + last_row = dynamic_cast<ChatMessageContainer *>(m_listbox->get_row_at_index(0)); + else + last_row = dynamic_cast<ChatMessageContainer *>(m_listbox->get_row_at_index(m_num_rows - 1)); + if (last_row != nullptr) { // this should always be true tbh + if (last_row->UserID == data->Author.ID) + should_attach = true; + } } - if (item != nullptr) - item->ID = data->ID; + auto type = GetMessageDisplayType(data); - return item; -} + ChatMessageContainer *container; + if (should_attach) { + container = last_row; + } else { + container = Gtk::manage(new ChatMessageContainer(data)); // only accesses timestamp and user + m_num_rows++; + } -void ChatWindow::ProcessMessage(const MessageData *data, bool prepend) { - auto create_new_row = [&]() { - auto *item = CreateChatEntryComponent(data); - if (item != nullptr) { - if (prepend) - m_listbox->prepend(*item); - else - m_listbox->add(*item); - m_num_rows++; - } - }; + // actual content + if (type == ChatDisplayType::Text) { + auto *text = Gtk::manage(new ChatMessageTextItem(data)); + container->AddNewContent(text, prepend); + m_id_to_widget[data->ID] = text; + } - // if the last row's message's author is the same as the new one's, then append the new message content to the last row - if (m_num_rows > 0) { - ChatMessageItem *item; + container->show_all(); + + if (!should_attach) { if (prepend) - item = dynamic_cast<ChatMessageItem *>(m_listbox->get_row_at_index(0)); + m_listbox->prepend(*container); else - item = dynamic_cast<ChatMessageItem *>(m_listbox->get_row_at_index(m_num_rows - 1)); - assert(item != nullptr); - auto *previous_data = m_abaddon->GetDiscordClient().GetMessage(item->ID); - - auto new_type = GetMessageDisplayType(data); - auto old_type = GetMessageDisplayType(previous_data); - - if ((data->Author.ID == previous_data->Author.ID) && (new_type == old_type && new_type == ChatDisplayType::Text)) { - auto *text_item = dynamic_cast<ChatMessageTextItem *>(item); - if (prepend) - text_item->PrependNewContent(data->Content); - else - text_item->AppendNewContent(data->Content); - } else { - create_new_row(); - } - } else { - create_new_row(); + m_listbox->add(*container); } } @@ -245,21 +229,13 @@ void ChatWindow::DeleteMessageInternal() { m_message_delete_queue.pop(); } - ChatMessageItem *row = nullptr; - for (const auto &child : m_listbox->get_children()) { - ChatMessageItem *tmp = dynamic_cast<ChatMessageItem *>(child); - if (tmp == nullptr) continue; - if (tmp->ID == id) { - row = tmp; - break; - } - } - - if (row == nullptr) return; + if (m_id_to_widget.find(id) == m_id_to_widget.end()) + return; // todo actually delete it when it becomes setting - row->MarkAsDeleted(); + auto *item = m_id_to_widget.at(id); + item->MarkAsDeleted(); } void ChatWindow::SetMessagesInternal() { @@ -272,6 +248,7 @@ void ChatWindow::SetMessagesInternal() { } m_num_rows = 0; + m_id_to_widget.clear(); std::unordered_set<const MessageData *> *msgs; { diff --git a/components/chatwindow.hpp b/components/chatwindow.hpp index 7eadab6..5054a85 100644 --- a/components/chatwindow.hpp +++ b/components/chatwindow.hpp @@ -2,6 +2,7 @@ #include <gtkmm.h> #include <queue> #include <mutex> +#include <unordered_map> #include "chatmessage.hpp" #include "../discord/discord.hpp" @@ -27,10 +28,9 @@ protected: void AddNewHistoryInternal(); void DeleteMessageInternal(); ChatDisplayType GetMessageDisplayType(const MessageData *data); - ChatMessageItem *CreateChatEntryComponentText(const MessageData *data); - ChatMessageItem *CreateChatEntryComponent(const MessageData *data); void ProcessMessage(const MessageData *data, bool prepend = false); int m_num_rows = 0; // youd think thered be a Gtk::ListBox::get_row_count or something but nope + std::unordered_map<Snowflake, ChatMessageItem *> m_id_to_widget; bool m_scroll_to_bottom = true; |