From 2c35c1af518d78079a8bdf8ece3856572cb7f8ce Mon Sep 17 00:00:00 2001 From: Simon Redman Date: Wed, 12 Dec 2018 22:50:08 -0700 Subject: [PATCH] [SMS App] Allow scrolling up to load and display older messages Summary: Scroll up to show older messages Newly received messages will not force the view to the bottom unless the new message is being added "very close" to the visible area Test Plan: Message History: - Open conversation - Scroll/Drag up to load older messages New Message: - Open conversation - Scroll to bottom - Verify that a newly-received or newly-sent message is added to the GUI - Scroll up - Verify that sending/receiving a message does not disturb the view - Scroll back to verify that the new message was indeed added to the list Reviewers: #kde_connect, apol Reviewed By: #kde_connect, apol Subscribers: apol, nicolasfella, kdeconnect Tags: #kde_connect Maniphest Tasks: T9556 Differential Revision: https://phabricator.kde.org/D15979 --- plugins/sms/smsplugin.cpp | 2 -- smsapp/qml/ConversationDisplay.qml | 56 +++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 6 deletions(-) diff --git a/plugins/sms/smsplugin.cpp b/plugins/sms/smsplugin.cpp index fa3cc605b..d5b5956d0 100644 --- a/plugins/sms/smsplugin.cpp +++ b/plugins/sms/smsplugin.cpp @@ -81,8 +81,6 @@ void SmsPlugin::requestConversation (const qint64& conversationID) const np.set("threadID", conversationID); sendPacket(np); - - return; } void SmsPlugin::forwardToTelepathy(const ConversationMessage& message) diff --git a/smsapp/qml/ConversationDisplay.qml b/smsapp/qml/ConversationDisplay.qml index 9bf834ddb..30e67dbd9 100644 --- a/smsapp/qml/ConversationDisplay.qml +++ b/smsapp/qml/ConversationDisplay.qml @@ -38,6 +38,19 @@ Kirigami.ScrollablePage property string phoneNumber title: person.person && person.person.name ? person.person.name : phoneNumber + /** + * Build a chat message which is representative of all chat messages + * + * In other words, one which I can use to get a reasonable height guess + */ + ChatMessage { + id: genericMessage + messageBody: "Generic Message Body" + dateTime: new Date('2000-0-0') + visible: false + enabled: false + } + function sendMessage() { console.log("sending sms", page.phoneNumber) model.sourceModel.sendReplyToConversation(message.text) @@ -45,6 +58,7 @@ Kirigami.ScrollablePage } ListView { + id: viewport model: QSortFilterProxyModel { id: model sortOrder: Qt.AscendingOrder @@ -61,12 +75,46 @@ Kirigami.ScrollablePage messageBody: model.display sentByMe: model.fromMe dateTime: new Date(model.date) + + ListView.onAdd: { + if (index == viewport.count - 1) + // This message is being inserted at the newest position + // We want to scroll to show it if the user is "almost" looking at it + + // Define some fudge area. If the message is being drawn offscreen but within + // this distance, we move to show it anyway. + // Selected to be genericMessage.height because that value scales for different + // font sizes / DPI / etc. -- Better ideas are welcome! + // Double the value works nicely + var offscreenFudge = 2 * genericMessage.height + + var viewportYBottom = viewport.contentY + viewport.height + + if (y < viewportYBottom + genericMessage.height) { + viewport.currentIndex = index + } + } } - // Set the view to start at the bottom of the page and track new elements if it was not manually scrolled up - currentIndex: atYEnd ? - count - 1 : - currentIndex + onMovementEnded: { + // Unset the highlightRangeMode if it was set previously + highlightRangeMode = ListView.ApplyRange + highlightMoveDuration: -1 // "Re-enable" the highlight animation + + if (atYBeginning) { + // "Lock" the view to the message currently at the beginning of the view + // This prevents the view from snapping to the top of the messages we are about to request + currentIndex = 0 // Index 0 is the beginning of the view + preferredHighlightBegin = visibleArea.yPosition + preferredHighlightEnd = preferredHighlightBegin + currentItem.height + highlightRangeMode = ListView.StrictlyEnforceRange + + highlightMoveDuration = 1 // This is not ideal: I would like to disable the highlight animation altogether + + // Get more messages + model.sourceModel.requestMoreMessages() + } + } } footer: RowLayout {