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:
parent
10b6d172c4
commit
34eb9ceaa7
1 changed files with 89 additions and 79 deletions
|
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue