Warning, /network/kdeconnect-kde/smsapp/qml/ConversationList.qml is written in an unsupported language. File is not indexed.
0001 /**
0002 * SPDX-FileCopyrightText: 2018 Aleix Pol Gonzalez <aleixpol@kde.org>
0003 * SPDX-FileCopyrightText: 2018 Nicolas Fella <nicolas.fella@gmx.de>
0004 * SPDX-FileCopyrightText: 2018 Simon Redman <simon@ergotech.com>
0005 *
0006 * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0007 */
0008
0009 import QtQuick
0010 import QtQuick.Controls
0011 import QtQuick.Layouts
0012 import org.kde.people
0013 import org.kde.kirigami as Kirigami
0014 import org.kde.kirigami.delegates as KirigamiDelegates
0015 import org.kde.kdeconnect
0016 import org.kde.kdeconnect.sms
0017
0018 Kirigami.ScrollablePage
0019 {
0020 id: page
0021 ToolTip {
0022 id: noDevicesWarning
0023 visible: !page.deviceConnected
0024 timeout: -1
0025 text: "⚠️ " + i18nd("kdeconnect-sms", "No devices available") + " ⚠️"
0026
0027 MouseArea {
0028 // Detect mouseover and show another tooltip with more information
0029 anchors.fill: parent
0030 hoverEnabled: true
0031
0032 ToolTip.visible: containsMouse
0033 ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
0034 // TODO: Wrap text if line is too long for the screen
0035 ToolTip.text: i18nd("kdeconnect-sms", "No new messages can be sent or received, but you can browse cached content")
0036 }
0037 }
0038
0039 ColumnLayout {
0040 id: loadingMessage
0041 visible: deviceConnected && view.count == 0 && currentSearchText.length == 0
0042 anchors.centerIn: parent
0043
0044 BusyIndicator {
0045 visible: loadingMessage.visible
0046 running: loadingMessage.visible
0047 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
0048 }
0049
0050 Label {
0051 text: i18nd("kdeconnect-sms", "Loading conversations from device. If this takes a long time, please wake up your device and then click Refresh.")
0052 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
0053 Layout.preferredWidth: page.width / 2
0054 horizontalAlignment: Text.AlignHCenter
0055 wrapMode: Text.Wrap
0056 }
0057
0058 Label {
0059 text: i18nd("kdeconnect-sms", "Tip: If you plug in your device, it should not go into doze mode and should load quickly.")
0060 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
0061 Layout.preferredWidth: page.width / 2
0062 horizontalAlignment: Text.AlignHCenter
0063 wrapMode: Text.Wrap
0064 }
0065
0066 Button {
0067 text: i18nd("kdeconnect-sms", "Refresh")
0068 icon.name: "view-refresh"
0069 Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
0070 onClicked: {
0071 conversationListModel.refresh();
0072 }
0073 }
0074 }
0075
0076 property string initialMessage : AppData.initialMessage
0077
0078 header: Kirigami.InlineMessage {
0079 Layout.fillWidth: true
0080 visible: page.initialMessage.length > 0
0081 text: i18nd("kdeconnect-sms", "Choose recipient")
0082
0083 actions: [
0084 Kirigami.Action {
0085 icon.name: "dialog-cancel"
0086 text: i18nd("kdeconnect-sms", "Cancel")
0087 onTriggered: initialMessage = ""
0088 }
0089 ]
0090 }
0091
0092 property int devicesCount
0093
0094 readonly property bool deviceConnected: devicesCount > 0
0095 property string currentSearchText
0096
0097 Component {
0098 id: chatView
0099 ConversationDisplay {
0100 deviceConnected: page.deviceConnected
0101 }
0102 }
0103
0104 titleDelegate: RowLayout {
0105 id: headerLayout
0106 width: parent.width
0107 Keys.forwardTo: [filter]
0108 Kirigami.SearchField {
0109 /**
0110 * Used as the filter of the list of messages
0111 */
0112 id: filter
0113 placeholderText: i18nd("kdeconnect-sms", "Search or start conversation...")
0114 Layout.fillWidth: true
0115 Layout.fillHeight: true
0116 onTextChanged: {
0117 currentSearchText = filter.text;
0118 if (filter.text != "") {
0119 view.model.setConversationsFilterRole(ConversationListModel.AddressesRole)
0120 } else {
0121 view.model.setConversationsFilterRole(ConversationListModel.ConversationIdRole)
0122 }
0123 view.model.setFilterFixedString(SmsHelper.canonicalizePhoneNumber(filter.text))
0124
0125 view.currentIndex = 0
0126 filter.forceActiveFocus();
0127 }
0128 Keys.onReturnPressed: {
0129 event.accepted = true
0130 view.currentItem.startChat()
0131 }
0132 Keys.onEscapePressed: {
0133 event.accepted = filter.text != ""
0134 filter.text = ""
0135 }
0136 Shortcut {
0137 sequence: "Ctrl+F"
0138 onActivated: filter.forceActiveFocus()
0139 }
0140 }
0141
0142 Button {
0143 id: newButton
0144 icon.name: "list-add"
0145 text: i18nd("kdeconnect-sms", "New")
0146 visible: true
0147 enabled: SmsHelper.isAddressValid(filter.text) && deviceConnected
0148 ToolTip.visible: hovered
0149 ToolTip.delay: Qt.styleHints.mousePressAndHoldInterval
0150 ToolTip.text: i18nd("kdeconnect-sms", "Start new conversation")
0151
0152 onClicked: {
0153 // We have to disable the filter temporarily in order to avoid getting key inputs accidently while processing the request
0154 filter.enabled = false
0155
0156 // If the address entered by the user already exists then ignore adding new contact
0157 if (!view.model.doesAddressExists(filter.text) && SmsHelper.isAddressValid(filter.text)) {
0158 conversationListModel.createConversationForAddress(filter.text)
0159 view.currentIndex = 0
0160 }
0161 filter.enabled = true
0162 }
0163
0164 Shortcut {
0165 sequence: "Ctrl+N"
0166 onActivated: newButton.clicked()
0167 }
0168 }
0169 }
0170
0171 property alias conversationListModel: conversationListModel
0172
0173 ListView {
0174 id: view
0175 currentIndex: 0
0176
0177 model: QSortFilterProxyModel {
0178 sortOrder: Qt.DescendingOrder
0179 filterCaseSensitivity: Qt.CaseInsensitive
0180 sourceModel: ConversationListModel {
0181 id: conversationListModel
0182 deviceId: AppData.deviceId
0183 }
0184 }
0185
0186 Keys.forwardTo: [headerItem]
0187
0188 delegate: KirigamiDelegates.SubtitleDelegate
0189 {
0190 id: listItem
0191 icon.name: decoration
0192 text: displayNames
0193 subtitle: toolTip
0194 width: view.width
0195
0196 property var thumbnail: attachmentPreview
0197
0198 function startChat() {
0199 view.currentItem.forceActiveFocus();
0200 applicationWindow().pageStack.push(chatView, {
0201 addresses: addresses,
0202 conversationId: model.conversationId,
0203 isMultitarget: isMultitarget,
0204 initialMessage: page.initialMessage})
0205 initialMessage = ""
0206 }
0207
0208 onClicked: {
0209 view.currentIndex = index
0210 startChat();
0211 }
0212
0213 Kirigami.Icon {
0214 id: thumbnailItem
0215 source: {
0216 if (!listItem.thumbnail) {
0217 return undefined
0218 }
0219 if (listItem.thumbnail.hasOwnProperty) {
0220 if (listItem.thumbnail.hasOwnProperty("name") && listItem.thumbnail.name !== "")
0221 return listItem.thumbnail.name;
0222 if (listItem.thumbnail.hasOwnProperty("source"))
0223 return listItem.thumbnail.source;
0224 }
0225 return listItem.thumbnail;
0226 }
0227 property int size: Kirigami.Units.iconSizes.huge
0228 Layout.minimumHeight: size
0229 Layout.maximumHeight: size
0230 Layout.minimumWidth: size
0231 selected: (listItem.highlighted || listItem.checked || listItem.pressed)
0232 opacity: 1
0233 visible: source != undefined
0234 }
0235
0236 // Keep the currently-open chat highlighted even if this element is not focused
0237 highlighted: ListView.isCurrentItem
0238 }
0239
0240 Component.onCompleted: {
0241 currentIndex = -1
0242 focus = true
0243 }
0244
0245 Kirigami.PlaceholderMessage {
0246 anchors.centerIn: parent
0247 width: parent.width - (Kirigami.Units.largeSpacing * 4)
0248 visible: deviceConnected && view.count == 0 && currentSearchText.length != 0
0249 text: i18ndc("kdeconnect-sms", "Placeholder message text when no messages are found", "No matches")
0250 }
0251 }
0252 }