summary refs log tree commit diff
path: root/src/timeline
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-21 12:09:23 +0300
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2018-07-21 12:09:23 +0300
commit9d718fccf46f8d8c94d4fe7409c42cf082e3b4f4 (patch)
treee732794238d45aa419e83d04c5899a2d925921b8 /src/timeline
parentUse a smaller icon size in the sidebar (diff)
downloadnheko-9d718fccf46f8d8c94d4fe7409c42cf082e3b4f4.tar.xz
Clear timeline widgets when they exceed a certain limit (#158)
That's a fix to deal with long running sessions which will end
up taking more & more memory given enough time.
Diffstat (limited to 'src/timeline')
-rw-r--r--src/timeline/TimelineView.cpp44
-rw-r--r--src/timeline/TimelineView.h3
2 files changed, 45 insertions, 2 deletions
diff --git a/src/timeline/TimelineView.cpp b/src/timeline/TimelineView.cpp
index 61a507b3..95cde0f4 100644
--- a/src/timeline/TimelineView.cpp
+++ b/src/timeline/TimelineView.cpp
@@ -38,6 +38,10 @@
 
 using TimelineEvent = mtx::events::collections::TimelineEvents;
 
+//! Maximum number of widgets to keep in the timeline layout.
+constexpr int MAX_RETAINED_WIDGETS = 100;
+constexpr int MIN_SCROLLBAR_HANDLE = 60;
+
 //! Retrieve the timestamp of the event represented by the given widget.
 QDateTime
 getDate(QWidget *widget)
@@ -481,8 +485,7 @@ TimelineView::addEvents(const mtx::responses::Timeline &timeline)
 void
 TimelineView::init()
 {
-        QSettings settings;
-        local_user_ = settings.value("auth/user_id").toString();
+        local_user_ = utils::localUser();
 
         QIcon icon;
         icon.addFile(":/icons/icons/ui/angle-arrow-down.png");
@@ -965,6 +968,19 @@ TimelineView::showEvent(QShowEvent *event)
         QWidget::showEvent(event);
 }
 
+void
+TimelineView::hideEvent(QHideEvent *event)
+{
+        const auto handleHeight = scroll_area_->verticalScrollBar()->sizeHint().height();
+        const auto widgetsNum   = scroll_layout_->count();
+
+        // Remove widgets from the timeline to reduce the memory footprint.
+        if (handleHeight < MIN_SCROLLBAR_HANDLE && widgetsNum > MAX_RETAINED_WIDGETS)
+                clearTimeline();
+
+        QWidget::hideEvent(event);
+}
+
 bool
 TimelineView::event(QEvent *event)
 {
@@ -975,6 +991,30 @@ TimelineView::event(QEvent *event)
 }
 
 void
+TimelineView::clearTimeline()
+{
+        // Delete all widgets.
+        QLayoutItem *item;
+        while ((item = scroll_layout_->takeAt(0)) != nullptr) {
+                delete item->widget();
+                delete item;
+        }
+
+        // The next call to /messages will be without a prev token.
+        prev_batch_token_.clear();
+        eventIds_.clear();
+
+        // Clear queues with pending messages to be rendered.
+        bottomMessages_.clear();
+        topMessages_.clear();
+
+        firstSender_.clear();
+        lastSender_.clear();
+
+        scroll_layout_->addStretch(1);
+}
+
+void
 TimelineView::toggleScrollDownButton()
 {
         const int maxScroll     = scroll_area_->verticalScrollBar()->maximum();
diff --git a/src/timeline/TimelineView.h b/src/timeline/TimelineView.h
index 5c42415a..d622b698 100644
--- a/src/timeline/TimelineView.h
+++ b/src/timeline/TimelineView.h
@@ -161,6 +161,7 @@ signals:
 protected:
         void paintEvent(QPaintEvent *event) override;
         void showEvent(QShowEvent *event) override;
+        void hideEvent(QHideEvent *event) override;
         bool event(QEvent *event) override;
 
 private:
@@ -271,6 +272,8 @@ private:
 
         //! Store the event id associated with the given widget.
         void saveEventId(QWidget *widget);
+        //! Remove all widgets from the timeline layout.
+        void clearTimeline();
 
         QVBoxLayout *top_layout_;
         QVBoxLayout *scroll_layout_;