smsapp/conversation list: Fix formatting issues and refactor code

Preview icon and subtitle formatting were not optimal (shifted and
not eliding properly).  Refactor the delegate into a ItemDelegate
with a proper content item.

In addition, clean up some redundancy and generally refactor the
qml properties/items.
This commit is contained in:
Mike Noe 2024-03-17 08:41:42 -04:00 committed by Albert Vaca Cintora
parent 10b6d172c4
commit 34eb9ceaa7

View file

@ -9,18 +9,16 @@
import QtQuick import QtQuick
import QtQuick.Controls import QtQuick.Controls
import QtQuick.Layouts import QtQuick.Layouts
import org.kde.people
import org.kde.kirigami as Kirigami import org.kde.kirigami as Kirigami
import org.kde.kirigami.delegates as KirigamiDelegates import org.kde.kirigami.delegates as KirigamiDelegates
import org.kde.kdeconnect
import org.kde.kdeconnect.sms import org.kde.kdeconnect.sms
Kirigami.ScrollablePage Kirigami.ScrollablePage
{ {
id: page id: page
ToolTip { ToolTip {
id: noDevicesWarning visible: !deviceConnected
visible: !page.deviceConnected
timeout: -1 timeout: -1
text: "⚠️ " + i18nd("kdeconnect-sms", "No devices available") + " ⚠️" text: "⚠️ " + i18nd("kdeconnect-sms", "No devices available") + " ⚠️"
@ -31,14 +29,13 @@ Kirigami.ScrollablePage
ToolTip.visible: containsMouse ToolTip.visible: containsMouse
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
// TODO: Wrap text if line is too long for the screen
ToolTip.text: i18nd("kdeconnect-sms", "No new messages can be sent or received, but you can browse cached content") ToolTip.text: i18nd("kdeconnect-sms", "No new messages can be sent or received, but you can browse cached content")
} }
} }
ColumnLayout { ColumnLayout {
id: loadingMessage id: loadingMessage
visible: deviceConnected && view.count == 0 && currentSearchText.length == 0 visible: deviceConnected && view.count === 0 && currentSearchText.length == 0
anchors.centerIn: parent anchors.centerIn: parent
BusyIndicator { BusyIndicator {
@ -74,6 +71,10 @@ Kirigami.ScrollablePage
} }
property string initialMessage : AppData.initialMessage property string initialMessage : AppData.initialMessage
property string currentSearchText
property alias conversationListModel: conversationListModel
property int devicesCount
readonly property bool deviceConnected: devicesCount > 0
header: Kirigami.InlineMessage { header: Kirigami.InlineMessage {
Layout.fillWidth: true Layout.fillWidth: true
@ -89,21 +90,9 @@ Kirigami.ScrollablePage
] ]
} }
property int devicesCount
readonly property bool deviceConnected: devicesCount > 0
property string currentSearchText
Component {
id: chatView
ConversationDisplay {
deviceConnected: page.deviceConnected
}
}
titleDelegate: RowLayout { titleDelegate: RowLayout {
id: headerLayout
Keys.forwardTo: [filter] Keys.forwardTo: [filter]
Kirigami.SearchField { Kirigami.SearchField {
/** /**
* Used as the filter of the list of messages * Used as the filter of the list of messages
@ -113,7 +102,7 @@ Kirigami.ScrollablePage
placeholderText: i18nd("kdeconnect-sms", "Search or start a conversation") placeholderText: i18nd("kdeconnect-sms", "Search or start a conversation")
onTextChanged: { onTextChanged: {
currentSearchText = filter.text; currentSearchText = filter.text;
if (filter.text != "") { if (filter.text !== "") {
view.model.setConversationsFilterRole(ConversationListModel.AddressesRole) view.model.setConversationsFilterRole(ConversationListModel.AddressesRole)
} else { } else {
view.model.setConversationsFilterRole(ConversationListModel.ConversationIdRole) view.model.setConversationsFilterRole(ConversationListModel.ConversationIdRole)
@ -128,7 +117,7 @@ Kirigami.ScrollablePage
view.currentItem.startChat() view.currentItem.startChat()
} }
Keys.onEscapePressed: event => { Keys.onEscapePressed: event => {
event.accepted = filter.text != "" event.accepted = filter.text !== ""
filter.text = "" filter.text = ""
} }
Shortcut { Shortcut {
@ -141,6 +130,7 @@ Kirigami.ScrollablePage
id: newButton id: newButton
icon.name: "list-add" icon.name: "list-add"
enabled: SmsHelper.isAddressValid(filter.text) && deviceConnected enabled: SmsHelper.isAddressValid(filter.text) && deviceConnected
ToolTip.visible: hovered ToolTip.visible: hovered
ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
ToolTip.text: i18nd("kdeconnect-sms", "Start new conversation") ToolTip.text: i18nd("kdeconnect-sms", "Start new conversation")
@ -164,12 +154,15 @@ Kirigami.ScrollablePage
} }
} }
property alias conversationListModel: conversationListModel Component {
id: chatView
ConversationDisplay {
deviceConnected: page.deviceConnected
}
}
ListView { ListView {
id: view id: view
currentIndex: 0
model: QSortFilterProxyModel { model: QSortFilterProxyModel {
sortOrder: Qt.DescendingOrder sortOrder: Qt.DescendingOrder
filterCaseSensitivity: Qt.CaseInsensitive filterCaseSensitivity: Qt.CaseInsensitive
@ -179,60 +172,6 @@ Kirigami.ScrollablePage
} }
} }
Keys.forwardTo: [headerItem]
delegate: KirigamiDelegates.SubtitleDelegate
{
id: listItem
icon.name: decoration
text: displayNames
subtitle: toolTip
width: view.width
property var thumbnail: attachmentPreview
function startChat() {
view.currentItem.forceActiveFocus();
applicationWindow().pageStack.push(chatView, {
addresses: addresses,
conversationId: model.conversationId,
isMultitarget: isMultitarget,
initialMessage: page.initialMessage})
initialMessage = ""
}
onClicked: {
view.currentIndex = index
startChat();
}
Kirigami.Icon {
id: thumbnailItem
source: {
if (!listItem.thumbnail) {
return undefined
}
if (listItem.thumbnail.hasOwnProperty) {
if (listItem.thumbnail.hasOwnProperty("name") && listItem.thumbnail.name !== "")
return listItem.thumbnail.name;
if (listItem.thumbnail.hasOwnProperty("source"))
return listItem.thumbnail.source;
}
return listItem.thumbnail;
}
property int size: Kirigami.Units.iconSizes.huge
Layout.minimumHeight: size
Layout.maximumHeight: size
Layout.minimumWidth: size
selected: (listItem.highlighted || listItem.checked || listItem.pressed)
opacity: 1
visible: source !== undefined
}
// Keep the currently-open chat highlighted even if this element is not focused
highlighted: ListView.isCurrentItem
}
Component.onCompleted: { Component.onCompleted: {
currentIndex = -1 currentIndex = -1
focus = true focus = true
@ -243,8 +182,79 @@ Kirigami.ScrollablePage
// https://invent.kde.org/frameworks/kirigami/-/merge_requests/1482 // https://invent.kde.org/frameworks/kirigami/-/merge_requests/1482
anchors.centerIn: parent anchors.centerIn: parent
width: parent.width - (Kirigami.Units.largeSpacing * 4) width: parent.width - (Kirigami.Units.largeSpacing * 4)
visible: deviceConnected && view.count == 0 && currentSearchText.length != 0 visible: deviceConnected && view.count === 0 && currentSearchText.length != 0
text: i18ndc("kdeconnect-sms", "Placeholder message text when no messages are found", "No matches") text: i18ndc("kdeconnect-sms", "Placeholder message text when no messages are found", "No matches")
} }
Keys.forwardTo: [headerItem]
delegate: ItemDelegate {
id: listItem
text: displayNames
icon.name: decoration
width: view.width
required property string displayNames
required property string toolTip
required property string decoration
required property var attachmentPreview
required property int index
required property var addresses
required property bool isMultitarget
required property int conversationId
// Keep the currently-open chat highlighted even if this element is not focused
highlighted: ListView.isCurrentItem
function startChat() {
view.currentItem.forceActiveFocus();
applicationWindow().pageStack.push(chatView, {
addresses: listItem.addresses,
conversationId: listItem.conversationId,
isMultitarget: listItem.isMultitarget,
initialMessage: page.initialMessage})
initialMessage = ""
}
onClicked: {
view.currentIndex = index
startChat();
}
// Note: Width calcs to account for scrollbar coming and going
contentItem: RowLayout {
spacing: Kirigami.Units.smallSpacing
implicitWidth: view.width - Kirigami.Units.largeSpacing
Kirigami.Icon {
id: thumbnailItem
source: {
if (!listItem.attachmentPreview) {
return undefined
}
if (listItem.attachmentPreview.hasOwnProperty("name") && listItem.attachmentPreview.name !== "")
return listItem.attachmentPreview.name;
if (listItem.attachmentPreview.hasOwnProperty("source"))
return listItem.attachmentPreview.source;
return listItem.attachmentPreview;
}
width: Kirigami.Units.iconSizes.small
height: Kirigami.Units.iconSizes.small
visible: source !== undefined
}
// Set width here to force elide and account for scrollbar
KirigamiDelegates.TitleSubtitle {
title: listItem.text
subtitle: listItem.toolTip
elide: Text.ElideRight
implicitWidth: view.width - Kirigami.Units.largeSpacing*2
}
}
}
} }
} }