summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2020-08-29 22:45:27 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2020-08-29 22:45:27 -0400
commit08e9d2f0efa0f90b27b1aefe4d319296964dcfdb (patch)
tree2f32a432854470225cda5827eb683c8f5de348f1 /components
parenta921ee42f9b5e6c658fe7fd29e14ab4814dc286b (diff)
downloadabaddon-portaudio-08e9d2f0efa0f90b27b1aefe4d319296964dcfdb.tar.gz
abaddon-portaudio-08e9d2f0efa0f90b27b1aefe4d319296964dcfdb.zip
rework chat components to make more sense
Diffstat (limited to 'components')
-rw-r--r--components/chatmessage.cpp45
-rw-r--r--components/chatmessage.hpp32
-rw-r--r--components/chatwindow.cpp95
-rw-r--r--components/chatwindow.hpp4
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;