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 }