kdeconnect-kde/smsapp/qml/ConversationDisplay.qml
Simon Redman 2c35c1af51 [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
2018-12-12 22:50:50 -07:00

148 lines
5.1 KiB
QML

/**
* Copyright (C) 2018 Aleix Pol Gonzalez <aleixpol@kde.org>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License or (at your option) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
import QtQuick 2.1
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.1
import org.kde.people 1.0
import org.kde.kirigami 2.4 as Kirigami
import org.kde.kdeconnect.sms 1.0
Kirigami.ScrollablePage
{
id: page
property alias personUri: person.personUri
readonly property QtObject person: PersonData {
id: person
}
property QtObject device
property int conversationId
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)
message.text = ""
}
ListView {
id: viewport
model: QSortFilterProxyModel {
id: model
sortOrder: Qt.AscendingOrder
sortRole: ConversationModel.DateRole
sourceModel: ConversationModel {
deviceId: device.id()
threadId: page.conversationId
}
}
spacing: Kirigami.Units.largeSpacing
delegate: ChatMessage {
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
}
}
}
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 {
enabled: page.device
ScrollView {
Layout.maximumHeight: page.height / 3
Layout.fillWidth: true
Layout.fillHeight: true
clip: true
TextArea {
id: message
Layout.fillWidth: true
wrapMode: TextEdit.Wrap
placeholderText: i18n("Say hi...")
Keys.onPressed: {
if ((event.key == Qt.Key_Return) && !(event.modifiers & Qt.ShiftModifier)) {
sendMessage()
event.accepted = true
}
}
}
}
Button {
text: "Send"
onClicked: {
sendMessage()
}
}
}
}