diff --git a/src/qml/RosterPage.qml b/src/qml/RosterPage.qml index c0aca3c..fca6173 100644 --- a/src/qml/RosterPage.qml +++ b/src/qml/RosterPage.qml @@ -1,162 +1,164 @@ /* * Kaidan - A user-friendly XMPP client for every device! * * Copyright (C) 2016-2020 Kaidan developers and contributors * (see the LICENSE file for a full list of copyright authors) * * Kaidan is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * In addition, as a special exception, the author of Kaidan gives * permission to link the code of its release with the OpenSSL * project's "OpenSSL" library (or with modified versions of it that * use the same license as the "OpenSSL" library), and distribute the * linked executables. You must obey the GNU General Public License in * all respects for all of the code used other than "OpenSSL". If you * modify this file, you may extend this exception to your version of * the file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Kaidan is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaidan. If not, see . */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 as Controls import org.kde.kirigami 2.8 as Kirigami import im.kaidan.kaidan 1.0 import "elements" Kirigami.ScrollablePage { id: root title: { Kaidan.connectionState === Enums.StateConnecting ? qsTr("Connecting…") : Kaidan.connectionState === Enums.StateDisconnected ? qsTr("Offline") : qsTr("Contacts") } leftPadding: 0 topPadding: 0 rightPadding: 0 bottomPadding: 0 RosterAddContactSheet { id: addContactSheet jid: "" } mainAction: Kirigami.Action { text: qsTr("Add new contact") icon.name: "contact-new" onTriggered: { if (addContactSheet.sheetOpen) addContactSheet.close() else addContactSheet.open() } } rightAction: Kirigami.Action { id: searchAction text: qsTr("Search contacts") checkable: true icon.name: "search" onTriggered: { if (checked) { searchField.forceActiveFocus() searchField.selectAll() } } shortcut: "Ctrl+F" } header: Item { height: searchField.visible ? searchField.height : 0 clip: true Behavior on height { SmoothedAnimation { velocity: 200 } } Kirigami.SearchField { id: searchField focusSequence: "" width: parent.width height: Kirigami.Units.gridUnit * 2 visible: searchAction.checked onVisibleChanged: text = "" onTextChanged: filterModel.setFilterFixedString(text.toLowerCase()) } } TableView { width: root.width model: RosterFilterProxyModel { id: filterModel sourceModel: Kaidan.rosterModel } columnWidthProvider: function (column) { return root.width } + rowHeightProvider: function (row) { return Kirigami.Units.gridUnit * 3.5 } delegate: RosterListItem { id: rosterItem width: root.width + height: Kirigami.Units.gridUnit * 3.5 name: model.name ? model.name : model.jid jid: model.jid lastMessage: model.lastMessage presenceType: Kaidan.presenceCache.getPresenceType(model.jid) statusMsg: Kaidan.presenceCache.getStatusText(model.jid) unreadMessages: model.unreadMessages avatarImagePath: Kaidan.avatarStorage.getAvatarUrl(model.jid) backgroundColor: { if (!Kirigami.Settings.isMobile && Kaidan.messageModel.chatPartner === model.jid) { Kirigami.Theme.highlightColor } else { Kirigami.Theme.backgroundColor } } onClicked: { searchAction.checked = false // We need to cache the chatName, because changing the chatPartner in the // message model will in some cases also update the roster model. That // will then remove this item and readd an updated version of it, so // model.* won't work anymore after this. var chatName = model.name ? model.name : model.jid Kaidan.messageModel.chatPartner = model.jid pageStack.push(chatPage, { "chatName": chatName }) } function newPresenceArrived(jid) { if (jid === model.jid) { rosterItem.presenceType = Kaidan.presenceCache.getPresenceType(model.jid) rosterItem.statusMsg = Kaidan.presenceCache.getStatusText(model.jid) } } function xmppUriReceived(uri) { // 'xmpp:' has length of 5 addContactSheet.jid = uri.substr(5) addContactSheet.open() } Component.onCompleted: { Kaidan.presenceCache.presenceChanged.connect(newPresenceArrived) Kaidan.xmppUriReceived.connect(xmppUriReceived) } Component.onDestruction: { Kaidan.presenceCache.presenceChanged.disconnect(newPresenceArrived) Kaidan.xmppUriReceived.disconnect(xmppUriReceived) } } } } diff --git a/src/qml/elements/RosterListItem.qml b/src/qml/elements/RosterListItem.qml index c89bde5..d031223 100644 --- a/src/qml/elements/RosterListItem.qml +++ b/src/qml/elements/RosterListItem.qml @@ -1,154 +1,153 @@ /* * Kaidan - A user-friendly XMPP client for every device! * * Copyright (C) 2016-2020 Kaidan developers and contributors * (see the LICENSE file for a full list of copyright authors) * * Kaidan is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * In addition, as a special exception, the author of Kaidan gives * permission to link the code of its release with the OpenSSL * project's "OpenSSL" library (or with modified versions of it that * use the same license as the "OpenSSL" library), and distribute the * linked executables. You must obey the GNU General Public License in * all respects for all of the code used other than "OpenSSL". If you * modify this file, you may extend this exception to your version of * the file, but you are not obligated to do so. If you do not wish to * do so, delete this exception statement from your version. * * Kaidan is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Kaidan. If not, see . */ import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 as Controls import QtGraphicalEffects 1.12 import org.kde.kirigami 2.8 as Kirigami import im.kaidan.kaidan 1.0 Kirigami.SwipeListItem { id: listItem property string name property string jid property string lastMessage property int unreadMessages property string avatarImagePath property int presenceType property string statusMsg topPadding: 0 leftPadding: 0 bottomPadding: 0 - height: Kirigami.Units.gridUnit * 3.5 RowLayout { spacing: Kirigami.Units.gridUnit * 0.5 // left border: presence Rectangle { id: presenceIndicator visible: presenceType !== Enums.PresInvisible width: Kirigami.Units.gridUnit * 0.3 height: parent.height color: Utils.presenceTypeToColor(presenceType) } // left: avatar Item { id: avatarSpace Layout.preferredHeight: parent.height - Kirigami.Units.gridUnit * 0.8 Layout.preferredWidth: parent.height - Kirigami.Units.gridUnit * 0.8 Avatar { id: avatar anchors.fill: parent avatarUrl: avatarImagePath name: listItem.name width: height } } // right side ColumnLayout { spacing: Kirigami.Units.smallSpacing Layout.fillWidth: true // contact name RowLayout { Kirigami.Heading { text: name textFormat: Text.PlainText elide: Text.ElideRight maximumLineCount: 1 level: 3 Layout.fillWidth: true Layout.maximumHeight: Kirigami.Units.gridUnit * 1.5 } // muted-icon Kirigami.Icon { id: muteIcon source: "audio-volume-muted-symbolic" width: 16 height: 16 visible: Kaidan.notificationsMuted(jid) } Item { Layout.fillWidth: true } } // bottom RowLayout { Layout.fillWidth: true Controls.Label { Layout.fillWidth: true elide: Text.ElideRight maximumLineCount: 1 text: { presenceType === Enums.PresError ? // error presence type qsTr("Error: Please check the JID.") : Utils.removeNewLinesFromString(lastMessage) } textFormat: Text.PlainText font.pixelSize: Kirigami.Units.gridUnit * 0.8 } } } // unread message counter MessageCounter { id: counter visible: unreadMessages > 0 counter: unreadMessages muted: Kaidan.notificationsMuted(jid) Layout.preferredHeight: Kirigami.Units.gridUnit * 1.25 Layout.preferredWidth: Kirigami.Units.gridUnit * 1.25 } } function handleNotificationsMuted(mutedContact) { counter.muted = Kaidan.notificationsMuted(jid) muteIcon.visible = Kaidan.notificationsMuted(jid) } Component.onCompleted: { Kaidan.notificationsMutedChanged.connect(handleNotificationsMuted) } Component.onDestruction: { Kaidan.notificationsMutedChanged.disconnect(handleNotificationsMuted) } }