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)
}
}