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 }