kdeconnect-kde/smsapp/qml/ConversationDisplay.qml
Nicolas Fella 8523fc0f86 [smsapp] Simplify device handling
The current device id is de-facto a global value

Store it in a singleton instead of passing it between our components
2022-05-31 16:50:53 +00:00

181 lines
5.7 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 conversationId
property bool isMultitarget
property string initialMessage
property string invalidId: "-1"
property bool isInitalized: false
property var conversationModel: ConversationModel {
deviceId: AppData.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
}
}