From 599a768459074559abed2a57fad789b0d8e48f9d Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Tue, 30 Mar 2021 22:31:13 -0400 Subject: [PATCH] remove old messages when new ones come in to save resources --- abaddon.cpp | 7 +------ abaddon.hpp | 3 +-- components/chatmessage.cpp | 8 ++++++++ components/chatmessage.hpp | 3 +++ components/chatwindow.cpp | 29 +++++++++++++++++++++-------- components/chatwindow.hpp | 3 ++- 6 files changed, 36 insertions(+), 17 deletions(-) diff --git a/abaddon.cpp b/abaddon.cpp index 233b22e..587350a 100644 --- a/abaddon.cpp +++ b/abaddon.cpp @@ -410,7 +410,6 @@ void Abaddon::ActionDisconnect() { m_channels_history_loaded.clear(); m_channels_history_loading.clear(); m_channels_requested.clear(); - m_oldest_listed_message.clear(); m_main_window->set_title(APP_TITLE); m_main_window->UpdateComponents(); } @@ -455,9 +454,6 @@ void Abaddon::ActionChannelOpened(Snowflake id) { m_main_window->UpdateChatActiveChannel(id); if (m_channels_requested.find(id) == m_channels_requested.end()) { m_discord.FetchMessagesInChannel(id, [this, id](const std::vector &msgs) { - if (msgs.size() > 0) - m_oldest_listed_message[id] = msgs.back(); - m_main_window->UpdateChatWindowContents(); m_channels_requested.insert(id); }); @@ -495,13 +491,12 @@ void Abaddon::ActionChatLoadHistory(Snowflake id) { m_channels_history_loading.insert(id); - m_discord.FetchMessagesInChannelBefore(id, m_oldest_listed_message[id], [this, id](const std::vector &msgs) { + m_discord.FetchMessagesInChannelBefore(id, before_id, [this, id](const std::vector &msgs) { m_channels_history_loading.erase(id); if (msgs.size() == 0) { m_channels_history_loaded.insert(id); } else { - m_oldest_listed_message[id] = msgs.back(); m_main_window->UpdateChatPrependHistory(msgs); } }); diff --git a/abaddon.hpp b/abaddon.hpp index 8415bb7..16f1cf9 100644 --- a/abaddon.hpp +++ b/abaddon.hpp @@ -116,10 +116,9 @@ private: DiscordClient m_discord; std::string m_discord_token; - // todo make these map snowflake to attribs + std::unordered_set m_channels_requested; std::unordered_set m_channels_history_loaded; - std::unordered_map m_oldest_listed_message; std::unordered_set m_channels_history_loading; ImageManager m_img_mgr; diff --git a/components/chatmessage.cpp b/components/chatmessage.cpp index 96facf7..ebf29d1 100644 --- a/components/chatmessage.cpp +++ b/components/chatmessage.cpp @@ -1148,6 +1148,10 @@ void ChatMessageHeader::UpdateNameColor() { m_author->set_markup(md); } +std::vector ChatMessageHeader::GetChildContent() { + return m_content_widgets; +} + void ChatMessageHeader::AttachUserMenuHandler(Gtk::Widget &widget) { widget.signal_button_press_event().connect([this](GdkEventButton *ev) -> bool { if (ev->type == GDK_BUTTON_PRESS && ev->button == GDK_BUTTON_SECONDARY) { @@ -1177,6 +1181,10 @@ ChatMessageHeader::type_signal_action_open_user_menu ChatMessageHeader::signal_a } void ChatMessageHeader::AddContent(Gtk::Widget *widget, bool prepend) { + m_content_widgets.push_back(widget); + widget->signal_unmap().connect([this, widget]() { + m_content_widgets.erase(std::remove(m_content_widgets.begin(), m_content_widgets.end(), widget), m_content_widgets.end()); + }); m_content_box->add(*widget); if (prepend) m_content_box->reorder_child(*widget, 1); diff --git a/components/chatmessage.hpp b/components/chatmessage.hpp index 56f6f5f..d4c36a5 100644 --- a/components/chatmessage.hpp +++ b/components/chatmessage.hpp @@ -110,12 +110,15 @@ public: ChatMessageHeader(const Message *data); void AddContent(Gtk::Widget *widget, bool prepend); void UpdateNameColor(); + std::vector GetChildContent(); protected: void AttachUserMenuHandler(Gtk::Widget &widget); bool on_author_button_press(GdkEventButton *ev); + std::vector m_content_widgets; + Gtk::Box *m_main_box; Gtk::Box *m_content_box; Gtk::EventBox *m_content_box_ev; diff --git a/components/chatwindow.cpp b/components/chatwindow.cpp index bc14021..b0ec0e3 100644 --- a/components/chatwindow.cpp +++ b/components/chatwindow.cpp @@ -110,6 +110,7 @@ void ChatWindow::SetMessages(const std::set &msgs) { } m_num_rows = 0; + m_num_messages = 0; m_id_to_widget.clear(); for (const auto &id : msgs) { @@ -159,14 +160,7 @@ void ChatWindow::InsertChatInput(std::string text) { } Snowflake ChatWindow::GetOldestListedMessage() { - Snowflake m; - - for (const auto &[id, widget] : m_id_to_widget) { - if (id < m) - m = id; - } - - return m; + return m_id_to_widget.begin()->first; } void ChatWindow::UpdateReactions(Snowflake id) { @@ -203,6 +197,7 @@ ChatMessageItemContainer *ChatWindow::CreateMessageComponent(Snowflake id) { return container; } +constexpr static int MaxMessagesForCull = 50; // this has to be 50 cuz that magic number is used in a couple other places and i dont feel like replacing them void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) { const auto &client = Abaddon::Get().GetDiscordClient(); if (!client.IsStarted()) return; // e.g. load channel and then dc @@ -222,6 +217,24 @@ void ChatWindow::ProcessNewMessage(Snowflake id, bool prepend) { should_attach = true; } + m_num_messages++; + + if (m_should_scroll_to_bottom && !prepend) + while (m_num_messages > MaxMessagesForCull) { + auto first_it = m_id_to_widget.begin(); + ChatMessageHeader *header = dynamic_cast(first_it->second->get_ancestor(Gtk::ListBoxRow::get_type())); + if (header != nullptr) { + if (header->GetChildContent().size() == 1) + delete header; + else + delete first_it->second; + } else + delete first_it->second; + m_id_to_widget.erase(first_it); + m_num_rows--; + m_num_messages--; + } + ChatMessageHeader *header; if (should_attach) { header = last_row; diff --git a/components/chatwindow.hpp b/components/chatwindow.hpp index ba03b16..9947a87 100644 --- a/components/chatwindow.hpp +++ b/components/chatwindow.hpp @@ -36,8 +36,9 @@ protected: void StartReplying(Snowflake message_id); void StopReplying(); + int m_num_messages = 0; int m_num_rows = 0; - std::unordered_map m_id_to_widget; + std::map m_id_to_widget; Snowflake m_active_channel;