From 02966c1d1a668b2382de899008e6fefb42da4bbb Mon Sep 17 00:00:00 2001 From: Shane Synan Date: Sun, 28 Jun 2020 01:41:00 -0400 Subject: [PATCH] client: Optionally ensure backlog on buffer show 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 | 11 +++++++++ src/client/backlogsettings.h | 13 +++++++++++ src/qtui/bufferwidget.cpp | 13 +++++++++++ src/qtui/bufferwidget.h | 8 +++++++ src/qtui/chatview.cpp | 23 +++++++++++++++---- src/qtui/chatview.h | 11 +++++++++ src/qtui/settingspages/backlogsettingspage.ui | 18 ++++++++++++++- 7 files changed, 92 insertions(+), 5 deletions(-) diff --git a/src/client/backlogsettings.cpp b/src/client/backlogsettings.cpp index 0b66cb4d..d6a25f73 100644 --- a/src/client/backlogsettings.cpp +++ b/src/client/backlogsettings.cpp @@ -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(); diff --git a/src/client/backlogsettings.h b/src/client/backlogsettings.h index 1410bdb0..aee0376d 100644 --- a/src/client/backlogsettings.h +++ b/src/client/backlogsettings.h @@ -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); diff --git a/src/qtui/bufferwidget.cpp b/src/qtui/bufferwidget.cpp index ceb2806d..db209a31 100644 --- a/src/qtui/bufferwidget.cpp +++ b/src/qtui/bufferwidget.cpp @@ -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(); + } } } diff --git a/src/qtui/bufferwidget.h b/src/qtui/bufferwidget.h index 2a48c11d..14e91960 100644 --- a/src/qtui/bufferwidget.h +++ b/src/qtui/bufferwidget.h @@ -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 }; diff --git a/src/qtui/chatview.cpp b/src/qtui/chatview.cpp index 3074882d..f8fb5866 100644 --- a/src/qtui/chatview.cpp +++ b/src/qtui/chatview.cpp @@ -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 diff --git a/src/qtui/chatview.h b/src/qtui/chatview.h index a4fd8840..69bc2cdd 100644 --- a/src/qtui/chatview.h +++ b/src/qtui/chatview.h @@ -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(); diff --git a/src/qtui/settingspages/backlogsettingspage.ui b/src/qtui/settingspages/backlogsettingspage.ui index 8405f1dd..dd15894a 100644 --- a/src/qtui/settingspages/backlogsettingspage.ui +++ b/src/qtui/settingspages/backlogsettingspage.ui @@ -7,7 +7,7 @@ 0 0 446 - 325 + 329 @@ -60,6 +60,22 @@ + + + + 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. + + + Fetch backlog if needed when switching chats + + + EnsureBacklogOnBufferShow + + + true + + + -- 2.20.1