kdeconnect-kde/smsapp/qml/ConversationDisplay.qml
Nicolas Fella 8010739a8a [smsapp] Refactor and fix argument handling
Use a singleton instead of context properties for data handling

Fix passing initial message

Make device menu creation more declarative

Fix initial device handling

Update current device when new instance with initial device is requested
2022-05-23 22:10:07 +00:00

183 lines
5.8 KiB
QML

/**
* SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@kde.org>
* SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
* SPDX-FileCopyrightText: 2018 Simon Redman <simon@ergotech.com>
*
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
*/
import QtQuick 2.15
import QtQuick.Controls 2.2 as Controls
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
import QtGraphicalEffects 1.0
Kirigami.ScrollablePage
{
id: page
property bool deviceConnected
property string deviceId
// property QtObject device
property string conversationId
property bool isMultitarget
property string initialMessage
property string invalidId: "-1"
property bool isInitalized: false
property var conversationModel: ConversationModel {
deviceId: page.deviceId
threadId: page.conversationId
addressList: page.addresses
onLoadingFinished: {
page.isInitalized = true
}
}
property var addresses
title: SmsHelper.getTitleForAddresses(addresses)
Component.onCompleted: {
if (initialMessage.length > 0) {
sendingArea.text = initialMessage;
initialMessage = ""
}
if (conversationId == invalidId) {
isInitalized = true
}
}
/**
* 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
name: "Generic Sender"
messageBody: "Generic Message Body"
dateTime: new Date('2000-0-0')
visible: false
enabled: false
}
ListView {
id: viewport
model: QSortFilterProxyModel {
id: model
sortOrder: Qt.AscendingOrder
sortRole: ConversationModel.DateRole
sourceModel: conversationModel
}
spacing: Kirigami.Units.largeSpacing
highlightMoveDuration: 0
Controls.BusyIndicator {
running: !isInitalized
anchors.centerIn: parent
}
header: Item {
height: Kirigami.Units.largeSpacing * 2
}
headerPositioning: ListView.InlineHeader
onContentHeightChanged: {
if (viewport.contentHeight <= 0) {
return
}
if (!isInitalized) {
// If we aren't initialized, we need to request enough messages to fill the view
// In order to do that, request one more message until we have enough
if (viewport.contentHeight < viewport.height) {
console.debug("Requesting another message to fill the screen")
conversationModel.requestMoreMessages(1)
} else {
// Finish initializing: Scroll to the bottom of the view
// View the most-recent message
viewport.forceLayout()
Qt.callLater(viewport.positionViewAtEnd)
isInitalized = true
}
return
}
}
delegate: ChatMessage {
name: model.sender
messageBody: model.display
sentByMe: model.fromMe
dateTime: new Date(model.date)
multiTarget: isMultitarget
attachmentList: model.attachments
width: viewport.width
ListView.onAdd: {
if (!isInitalized) {
return
}
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.highlightMoveDuration = -1
viewport.currentIndex = index
}
}
}
onMessageCopyRequested: {
SmsHelper.copyToClipboard(message)
}
}
onMovementEnded: {
if (!isInitalized) {
return
}
// Unset the highlightRangeMode if it was set previously
highlightRangeMode = ListView.ApplyRange
// If we have scrolled to the last message currently in the view, request some more
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 = 0
// Get more messages
conversationModel.requestMoreMessages()
}
}
}
footer: SendingArea {
id: sendingArea
width: parent.width
addresses: page.addresses
}
}