client: Optionally ensure backlog on buffer show
authorShane Synan <digitalcircuit36939@gmail.com>
Sun, 28 Jun 2020 05:41:00 +0000 (01:41 -0400)
committerManuel Nickschas <sputnick@quassel-irc.org>
Sun, 4 Oct 2020 16:19:48 +0000 (18:19 +0200)
Add a default-enabled option to ensure backlog is available when
showing a buffer, using the same logic as scrolling up in a buffer
whenever switching to a buffer.  No additional messages will be
fetched if the scrollbar is already visible.

This makes using Quassel without any initial backlog fetching more
convenient, as you don't need to scroll upon clicking every buffer.

Note: if all loaded messages are filtered out, nothing will appear to
be visible on the first showing, and more backlog will be fetched the
next time the buffer is shown (or if scrolled, like before).  This
happens with Quassel today already, anyways, but implementing
"fetch until visible" be a good future improvement, mirroring what
Quasseldroid does.

src/client/backlogsettings.cpp
src/client/backlogsettings.h
src/qtui/bufferwidget.cpp
src/qtui/bufferwidget.h
src/qtui/chatview.cpp
src/qtui/chatview.h
src/qtui/settingspages/backlogsettingspage.ui

index 0b66cb4..d6a25f7 100644 (file)
@@ -44,6 +44,17 @@ void BacklogSettings::setDynamicBacklogAmount(int amount)
     return setLocalValue("DynamicBacklogAmount", amount);
 }
 
+bool BacklogSettings::ensureBacklogOnBufferShow() const
+{
+    // This settings key is also used within BufferWidget::BufferWidget()
+    return localValue("EnsureBacklogOnBufferShow", true).toBool();
+}
+
+void BacklogSettings::setEnsureBacklogOnBufferShow(bool enabled)
+{
+    return setLocalValue("EnsureBacklogOnBufferShow", enabled);
+}
+
 int BacklogSettings::fixedBacklogAmount() const
 {
     return localValue("FixedBacklogAmount", 500).toInt();
index 1410bdb..aee0376 100644 (file)
@@ -37,6 +37,19 @@ public:
     int dynamicBacklogAmount() const;
     void setDynamicBacklogAmount(int amount);
 
+    /**
+     * Gets if a buffer should fetch backlog upon show to provide a scrollable amount of backlog
+     *
+     * @return True if showing a buffer without scrollbar visible fetches backlog, otherwise false
+     */
+    bool ensureBacklogOnBufferShow() const;
+    /**
+     * Sets if a buffer should fetch backlog upon show to provide a scrollable amount of backlog
+     *
+     * @param enabled True if showing a buffer without scrollbar fetches backlog, otherwise false
+     */
+    void setEnsureBacklogOnBufferShow(bool enabled);
+
     int fixedBacklogAmount() const;
     void setFixedBacklogAmount(int amount);
 
index ceb2806..db209a3 100644 (file)
@@ -27,6 +27,7 @@
 
 #include "action.h"
 #include "actioncollection.h"
+#include "backlogsettings.h"
 #include "chatline.h"
 #include "chatview.h"
 #include "chatviewsearchbar.h"
@@ -83,6 +84,9 @@ BufferWidget::BufferWidget(QWidget* parent)
     ChatViewSettings s;
     s.initAndNotify("AutoMarkerLine", this, &BufferWidget::setAutoMarkerLine, true);
     s.initAndNotify("AutoMarkerLineOnLostFocus", this, &BufferWidget::setAutoMarkerLineOnLostFocus, true);
+
+    BacklogSettings backlogSettings;
+    backlogSettings.initAndNotify("EnsureBacklogOnBufferShow", this, &BufferWidget::setEnsureBacklogOnBufferShow);
 }
 
 BufferWidget::~BufferWidget()
@@ -101,6 +105,11 @@ void BufferWidget::setAutoMarkerLineOnLostFocus(const QVariant& v)
     _autoMarkerLineOnLostFocus = v.toBool();
 }
 
+void BufferWidget::setEnsureBacklogOnBufferShow(const QVariant& v)
+{
+    _ensureBacklogOnBufferShow = v.toBool();
+}
+
 AbstractChatView* BufferWidget::createChatView(BufferId id)
 {
     ChatView* chatView;
@@ -132,6 +141,10 @@ void BufferWidget::showChatView(BufferId id)
         Q_ASSERT(view);
         ui.stackedWidget->setCurrentWidget(view);
         _chatViewSearchController->setScene(view->scene());
+        if (_ensureBacklogOnBufferShow) {
+            // Try to ensure some messages are visible
+            view->requestBacklogForScroll();
+        }
     }
 }
 
index 2a48c11..14e9196 100644 (file)
@@ -64,6 +64,13 @@ private slots:
 
     void setAutoMarkerLine(const QVariant&);
     void setAutoMarkerLineOnLostFocus(const QVariant&);
+    /**
+     * Sets the local cache of whether or not a buffer should fetch backlog upon show to provide a
+     * scrollable amount of backlog
+     *
+     * @seealso BacklogSettings::setEnsureBacklogOnBufferShow()
+     */
+    void setEnsureBacklogOnBufferShow(const QVariant&);
 
 private:
     Ui::BufferWidget ui;
@@ -73,4 +80,5 @@ private:
 
     bool _autoMarkerLine;
     bool _autoMarkerLineOnLostFocus;
+    bool _ensureBacklogOnBufferShow; ///< If a buffer fetches backlog upon show until scrollable
 };
index 3074882..f8fb586 100644 (file)
@@ -100,8 +100,7 @@ bool ChatView::event(QEvent* event)
         case Qt::Key_Down:
         case Qt::Key_PageUp:
         case Qt::Key_PageDown:
-            if (!verticalScrollBar()->isVisible()) {
-                scene()->requestBacklog();
+            if (requestBacklogForScroll()) {
                 return true;
             }
         default:
@@ -145,8 +144,7 @@ bool ChatView::event(QEvent* event)
     if (event->type() == QEvent::Wheel
         || (event->type() == QEvent::TouchBegin && ((QTouchEvent*)event)->device()->type() == QTouchDevice::TouchScreen)
         || event->type() == QEvent::TouchUpdate) {
-        if (!verticalScrollBar()->isVisible()) {
-            scene()->requestBacklog();
+        if (requestBacklogForScroll()) {
             return true;
         }
     }
@@ -409,6 +407,23 @@ void ChatView::setHasCache(ChatLine* line, bool hasCache)
         _linesWithCache.remove(line);
 }
 
+bool ChatView::requestBacklogForScroll()
+{
+    if (!verticalScrollBar()->isVisible()) {
+        // Not able to scroll, fetch backlog
+        //
+        // Future improvement: continue fetching backlog in chunks until the scrollbar is visible,
+        // or the beginning of the buffer has been reached.
+        scene()->requestBacklog();
+        // Backlog has been requested
+        return true;
+    }
+    else {
+        // Scrollbar already visible, no backlog requested
+        return false;
+    }
+}
+
 void ChatView::checkChatLineCaches()
 {
     qreal top = mapToScene(viewport()->rect().topLeft()).y() - 10;  // some grace area to avoid premature cleaning
index a4fd884..69bc2cd 100644 (file)
@@ -79,6 +79,17 @@ public:
      */
     void setHasCache(ChatLine* line, bool hasCache = true);
 
+    /**
+     * Requests backlog if the scrollbar is not currently visible
+     *
+     * Use this whenever trying to scroll the backlog to try to ensure some text is visible.  If the
+     * backlog does not have additional messages or those messages are filtered out, the scrollbar
+     * might remain invisible.
+     *
+     * @return True if the scrollbar isn't visible and a backlog request was made, otherwise false
+     */
+    bool requestBacklogForScroll();
+
 public slots:
     inline virtual void clear() {}
     void zoomIn();
index 8405f1d..dd15894 100644 (file)
@@ -7,7 +7,7 @@
     <x>0</x>
     <y>0</y>
     <width>446</width>
-    <height>325</height>
+    <height>329</height>
    </rect>
   </property>
   <property name="windowTitle">
      </item>
     </layout>
    </item>
+   <item>
+    <widget class="QCheckBox" name="ensureBacklogOnBufferShow">
+     <property name="toolTip">
+      <string>When switching to a chat, more backlog will be fetched if no messages are shown yet or the scrollbar isn't visible.  Useful when not fetching any initial backlog.</string>
+     </property>
+     <property name="text">
+      <string>Fetch backlog if needed when switching chats</string>
+     </property>
+     <property name="settingsKey" stdset="0">
+      <string notr="true">EnsureBacklogOnBufferShow</string>
+     </property>
+     <property name="defaultValue" stdset="0">
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
    <item>
     <widget class="Line" name="line">
      <property name="orientation">