Redesign room list

Use KirigamiAddons.Delegated.RoundedItemDelegate
This commit is contained in:
Carl Schwan
2023-06-17 22:48:25 +02:00
parent 7f459cb90f
commit 8f81629ac1
10 changed files with 186 additions and 282 deletions

View File

@@ -338,7 +338,7 @@ QVariant RoomListModel::data(const QModelIndex &index, int role) const
if (role == AvatarImageRole) { if (role == AvatarImageRole) {
return room->avatar(128); return room->avatar(128);
} }
if (role == IdRole) { if (role == RoomIdRole) {
return room->id(); return room->id();
} }
if (role == IsSpaceRole) { if (role == IsSpaceRole) {
@@ -379,7 +379,7 @@ QHash<int, QByteArray> RoomListModel::roleNames() const
roles[CategoryVisibleRole] = "categoryVisible"; roles[CategoryVisibleRole] = "categoryVisible";
roles[SubtitleTextRole] = "subtitleText"; roles[SubtitleTextRole] = "subtitleText";
roles[IsSpaceRole] = "isSpace"; roles[IsSpaceRole] = "isSpace";
roles[IdRole] = "id"; roles[RoomIdRole] = "roomId";
roles[IsChildSpaceRole] = "isChildSpace"; roles[IsChildSpaceRole] = "isChildSpace";
return roles; return roles;
} }

View File

@@ -72,7 +72,7 @@ public:
CategoryVisibleRole, /**< If the room's category is visible. */ CategoryVisibleRole, /**< If the room's category is visible. */
SubtitleTextRole, /**< The text to show as the room subtitle. */ SubtitleTextRole, /**< The text to show as the room subtitle. */
AvatarImageRole, /**< The room avatar as an image. */ AvatarImageRole, /**< The room avatar as an image. */
IdRole, /**< The room matrix ID. */ RoomIdRole, /**< The room matrix ID. */
IsSpaceRole, /**< Whether the room is a space. */ IsSpaceRole, /**< Whether the room is a space. */
IsChildSpaceRole, /**< Whether this space is a child of a different space. */ IsChildSpaceRole, /**< Whether this space is a child of a different space. */
}; };

View File

@@ -87,7 +87,8 @@ bool SortFilterRoomListModel::filterAcceptsRow(int source_row, const QModelIndex
return acceptRoom; return acceptRoom;
} else { } else {
const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false); const auto &rooms = SpaceHierarchyCache::instance().getRoomListForSpace(m_activeSpaceId, false);
return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::IdRole).toString()) != rooms.end() return std::find(rooms.begin(), rooms.end(), sourceModel()->data(sourceModel()->index(source_row, 0), RoomListModel::RoomIdRole).toString())
!= rooms.end()
&& acceptRoom; && acceptRoom;
} }
} }

View File

@@ -8,7 +8,7 @@
SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent) SortFilterSpaceListModel::SortFilterSpaceListModel(QObject *parent)
: QSortFilterProxyModel{parent} : QSortFilterProxyModel{parent}
{ {
setSortRole(RoomListModel::IdRole); setSortRole(RoomListModel::RoomIdRole);
sort(0); sort(0);
invalidateFilter(); invalidateFilter();
connect(this, &QAbstractProxyModel::sourceModelChanged, this, [this]() { connect(this, &QAbstractProxyModel::sourceModelChanged, this, [this]() {
@@ -33,8 +33,8 @@ bool SortFilterSpaceListModel::filterAcceptsRow(int source_row, const QModelInde
bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const bool SortFilterSpaceListModel::lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const
{ {
const auto idLeft = sourceModel()->data(source_left, RoomListModel::IdRole).toString(); const auto idLeft = sourceModel()->data(source_left, RoomListModel::RoomIdRole).toString();
const auto idRight = sourceModel()->data(source_right, RoomListModel::IdRole).toString(); const auto idRight = sourceModel()->data(source_right, RoomListModel::RoomIdRole).toString();
return idLeft < idRight; return idLeft < idRight;
} }

View File

@@ -6,185 +6,32 @@ import QtQuick 2.15
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import QtQuick.Controls 2.15 as QQC2 import QtQuick.Controls 2.15 as QQC2
import QtQuick.Templates 2.15 as T import QtQuick.Templates 2.15 as T
import org.kde.kirigami 2.19 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
T.TabButton { Delegates.RoundedItemDelegate {
id: control id: root
/** required property url source
* @brief This property specifies the index of this tab within the tab bar.
*/ signal contextMenuRequested()
readonly property int tabIndex: {
let tabIdx = 0 padding: Kirigami.Units.largeSpacing
for (let i = 0; i < parent.children.length; ++i) {
if (parent.children[i] === this) { QQC2.ToolTip.visible: hovered
return tabIdx QQC2.ToolTip.text: text
} QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
// Checking for AbstractButtons because any AbstractButton can act as a tab
if (parent.children[i] instanceof T.AbstractButton) { onPressAndHold: root.contextMenuRequested()
++tabIdx
} TapHandler {
} acceptedButtons: Qt.RightButton
return -1 acceptedDevices: PointerDevice.Mouse
onTapped: root.contextMenuRequested()
} }
/** contentItem: Kirigami.Avatar {
* @brief This property sets whether the icon colors should be masked with a single color. source: root.source
* name: root.text
* default: ``true``
*
* @since KDE Frameworks 5.96
*/
property bool recolorIcon: true
property color foregroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
property color highlightForegroundColor: Qt.rgba(Kirigami.Theme.textColor.r, Kirigami.Theme.textColor.g, Kirigami.Theme.textColor.b, 0.85)
property color highlightBarColor: Kirigami.Theme.highlightColor
property color pressedColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.3)
property color hoverSelectColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.2)
property color checkedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.7)
property color pressedBorderColor: Qt.rgba(highlightBarColor.r, highlightBarColor.g, highlightBarColor.b, 0.9)
property url source
property string name
implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset,
implicitContentWidth + leftPadding + rightPadding)
implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset,
implicitContentHeight + topPadding + bottomPadding)
display: T.AbstractButton.TextUnderIcon
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Kirigami.Theme.inherit: false
// not using the hover handler built into control, since it seems to misbehave and
// permanently report hovered after a touch event
HoverHandler {
id: hoverHandler
}
padding: Kirigami.Units.smallSpacing
spacing: Kirigami.Units.smallSpacing
icon.height: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
icon.width: control.display === T.AbstractButton.TextBesideIcon ? Kirigami.Units.iconSizes.small : Kirigami.Units.iconSizes.smallMedium
icon.color: control.checked ? control.highlightForegroundColor : control.foregroundColor
background: Rectangle {
Kirigami.Theme.colorSet: Kirigami.Theme.Button
Kirigami.Theme.inherit: false
implicitHeight: (control.display === T.AbstractButton.TextBesideIcon) ? 0 : (Kirigami.Units.gridUnit * 3 + Kirigami.Units.smallSpacing * 2)
color: "transparent"
Rectangle {
width: parent.width - Kirigami.Units.largeSpacing
height: parent.height - Kirigami.Units.largeSpacing
anchors.centerIn: parent
radius: Kirigami.Units.smallSpacing
color: control.down ? pressedColor : (control.checked || hoverHandler.hovered ? hoverSelectColor : "transparent")
border.color: control.checked ? checkedBorderColor : (control.down ? pressedBorderColor : color)
border.width: 1
Behavior on color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
Behavior on border.color { ColorAnimation { duration: Kirigami.Units.shortDuration } }
}
}
contentItem: GridLayout {
id: gridLayout
columnSpacing: 0
rowSpacing: (label.visible && label.lineCount > 1) ? 0 : control.spacing
// if this is a row or a column
columns: control.display !== T.AbstractButton.TextBesideIcon ? 1 : 2
property real verticalMargins: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.largeSpacing : 0
Kirigami.Avatar {
id: icon
source: control.source
name: control.name
Layout.topMargin: gridLayout.verticalMargins
Layout.bottomMargin: gridLayout.verticalMargins
Layout.leftMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
Layout.rightMargin: (control.display === T.AbstractButton.TextBesideIcon) ? Kirigami.Units.gridUnit : 0
Layout.alignment: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Qt.AlignVCenter | Qt.AlignRight;
} else {
// column layout
return Qt.AlignHCenter | ((!label.visible || label.lineCount > 1) ? Qt.AlignVCenter : Qt.AlignBottom);
}
}
Layout.preferredWidth: Kirigami.Units.iconSizes.medium
Layout.preferredHeight: Kirigami.Units.iconSizes.medium
}
QQC2.Label {
id: label
Kirigami.MnemonicData.enabled: control.enabled && control.visible
Kirigami.MnemonicData.controlType: Kirigami.MnemonicData.MenuItem
Kirigami.MnemonicData.label: control.text
text: Kirigami.MnemonicData.richTextLabel
horizontalAlignment: (control.display === T.AbstractButton.TextBesideIcon) ? Text.AlignLeft : Text.AlignHCenter
visible: control.display !== T.AbstractButton.IconOnly
wrapMode: Text.Wrap
elide: Text.ElideMiddle
color: control.checked ? control.highlightForegroundColor : control.foregroundColor
font.bold: control.checked
font.family: Kirigami.Theme.smallFont.family
font.pointSize: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Kirigami.Theme.defaultFont.pointSize;
} else {
// column layout
return icon.visible ? Kirigami.Theme.smallFont.pointSize : Kirigami.Theme.defaultFont.pointSize * 1.20; // 1.20 is equivalent to level 2 heading
}
}
Behavior on color { ColorAnimation {} }
Behavior on opacity { NumberAnimation {} }
Layout.topMargin: gridLayout.verticalMargins
Layout.bottomMargin: gridLayout.verticalMargins
Layout.alignment: {
if (control.display === T.AbstractButton.TextBesideIcon) {
// row layout
return Qt.AlignVCenter | Qt.AlignLeft;
} else {
// column layout
return icon.visible ? Qt.AlignHCenter | Qt.AlignTop : Qt.AlignCenter;
}
}
// Work around bold text changing implicit size
Layout.preferredWidth: boldMetrics.implicitWidth
Layout.preferredHeight: boldMetrics.implicitHeight * label.lineCount
Layout.fillWidth: true
QQC2.Label {
id: boldMetrics
visible: false
text: parent.text
font.bold: true
font.family: Kirigami.Theme.smallFont.family
font.pointSize: Kirigami.Theme.smallFont.pointSize
horizontalAlignment: Text.AlignHCenter
wrapMode: QQC2.Label.Wrap
elide: Text.ElideMiddle
}
}
} }
} }

View File

@@ -308,7 +308,7 @@ QQC2.ScrollView {
x: delegate ? delegate.x + delegate.bubbleX : 0 x: delegate ? delegate.x + delegate.bubbleX : 0
y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0 y: delegate ? delegate.mapToItem(parent, 0, 0).y + delegate.bubbleY - height + Kirigami.Units.smallSpacing : 0
width: delegate.bubbleWidth width: delegate ? delegate.bubbleWidth : Kirigami.Units.gridUnit * 4
showActions: delegate && delegate.hovered showActions: delegate && delegate.hovered
verified: delegate && delegate.verified verified: delegate && delegate.verified

View File

@@ -7,13 +7,14 @@ import QtQuick.Layouts 1.15
import QtQml.Models 2.15 import QtQml.Models 2.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
import './' as RoomList import './' as RoomList
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: root id: root
required property int index required property int index
@@ -29,23 +30,9 @@ Kirigami.BasicListItem {
readonly property bool hasNotifications: notificationCount > 0 readonly property bool hasNotifications: notificationCount > 0
topPadding: Kirigami.Units.largeSpacing height: visible ? implicitHeight : 0
bottomPadding: Kirigami.Units.largeSpacing
visible: root.categoryVisible || root.filterText.length > 0 || Config.mergeRoomList visible: root.categoryVisible || root.filterText.length > 0 || Config.mergeRoomList
highlighted: ListView.view.currentIndex === index
focus: true
icon: undefined
@BASICLISTITEM_BOLD@: root.hasNotifications
label: root.displayName
labelItem.textFormat: Text.PlainText
subtitle: root.subtitleText
subtitleItem {
textFormat: Text.PlainText
visible: !Config.compactRoomList
}
onClicked: RoomManager.enterRoom(root.currentRoom) onClicked: RoomManager.enterRoom(root.currentRoom)
onPressAndHold: createRoomListContextMenu() onPressAndHold: createRoomListContextMenu()
@@ -59,18 +46,54 @@ Kirigami.BasicListItem {
onTapped: createRoomListContextMenu() onTapped: createRoomListContextMenu()
} }
leading: Kirigami.Avatar { contentItem: RowLayout {
source: root.avatar ? "image://mxc/" + root.avatar : "" Kirigami.Avatar {
name: root.displayName source: root.avatar ? "image://mxc/" + root.avatar : ""
implicitWidth: visible ? height : 0 name: root.displayName
visible: Config.showAvatarInRoomDrawer implicitWidth: visible ? height : 0
sourceSize { implicitHeight: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 visible: Config.showAvatarInRoomDrawer
height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing * 2 sourceSize {
} width: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
} height: Kirigami.Units.gridUnit + Kirigami.Units.largeSpacing
}
Layout.topMargin: Kirigami.Units.largeSpacing / 2
Layout.bottomMargin: Kirigami.Units.largeSpacing / 2
}
ColumnLayout {
spacing: 0
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
QQC2.Label {
id: label
text: root.displayName
elide: Text.ElideRight
font.weight: root.hasNotifications ? Font.Bold : Font.Normal
Layout.fillWidth: true
Layout.alignment: subtitle.visible ? Qt.AlignLeft | Qt.AlignBottom : Qt.AlignLeft | Qt.AlignVCenter
}
QQC2.Label {
id: subtitle
text: root.subtitleText
elide: Text.ElideRight
font: Kirigami.Theme.smallFont
opacity: root.hasNotifications ? 0.9 : 0.7
visible: !Config.compactRoomList
textFormat: Text.PlainText
Layout.fillWidth: true
Layout.alignment: visible ? Qt.AlignLeft | Qt.AlignTop : Qt.AlignLeft | Qt.AlignVCenter
}
}
trailing: RowLayout {
Kirigami.Icon { Kirigami.Icon {
source: "notifications-disabled" source: "notifications-disabled"
enabled: false enabled: false
@@ -80,10 +103,12 @@ Kirigami.BasicListItem {
Accessible.name: i18n("Muted room") Accessible.name: i18n("Muted room")
Layout.rightMargin: Kirigami.Units.smallSpacing Layout.rightMargin: Kirigami.Units.smallSpacing
} }
QQC2.Label { QQC2.Label {
id: notificationCountLabel id: notificationCountLabel
text: notificationCount
visible: hasNotifications text: root.notificationCount
visible: root.hasNotifications
color: Kirigami.Theme.textColor color: Kirigami.Theme.textColor
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
background: Rectangle { background: Rectangle {
@@ -103,6 +128,7 @@ Kirigami.BasicListItem {
text: notificationCountLabel.text text: notificationCountLabel.text
} }
} }
QQC2.Button { QQC2.Button {
id: configButton id: configButton
visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList visible: root.hovered && !Kirigami.Settings.isMobile && !Config.compactRoomList

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import '.' import '.'
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -15,12 +16,8 @@ QQC2.Control {
id: root id: root
readonly property real pinnedWidth: Kirigami.Units.gridUnit * 6 readonly property real pinnedWidth: Kirigami.Units.gridUnit * 6
readonly property int buttonDisplayMode: Kirigami.NavigationTabButton.IconOnly
property bool drawerEnabled: true property bool drawerEnabled: true
Kirigami.Theme.colorSet: Kirigami.Theme.Window
Kirigami.Theme.inherit: false
leftPadding: 0 leftPadding: 0
rightPadding: 0 rightPadding: 0
topPadding: 0 topPadding: 0
@@ -28,12 +25,6 @@ QQC2.Control {
property string selectedSpaceId property string selectedSpaceId
background: Rectangle {
color: Kirigami.Theme.backgroundColor
Kirigami.Theme.colorSet: Kirigami.Theme.View
Kirigami.Theme.inherit: false
}
contentItem: Loader { contentItem: Loader {
id: sidebarColumn id: sidebarColumn
active: root.drawerEnabled active: root.drawerEnabled
@@ -56,17 +47,23 @@ QQC2.Control {
width: scrollView.width width: scrollView.width
spacing: 0 spacing: 0
Kirigami.NavigationTabButton { AvatarTabButton {
id: allRoomButton
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: width Layout.preferredHeight: width - Kirigami.Units.smallSpacing
display: Kirigami.NavigationTabButton.IconOnly Layout.maximumHeight: width - Kirigami.Units.smallSpacing
Layout.topMargin: Kirigami.Units.smallSpacing
text: i18n("All Rooms") text: i18n("All Rooms")
icon.name: "globe" source: "globe"
checked: true
contentItem: Kirigami.Icon {
source: "globe"
}
checked: root.selectedSpaceId === ""
onClicked: root.selectedSpaceId = "" onClicked: root.selectedSpaceId = ""
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
} }
Repeater { Repeater {
@@ -79,23 +76,23 @@ QQC2.Control {
Component.onCompleted: root.enabled = count > 0 Component.onCompleted: root.enabled = count > 0
delegate: AvatarTabButton { delegate: AvatarTabButton {
Layout.fillWidth: true id: spaceDelegate
Layout.preferredHeight: width
display: Kirigami.NavigationTabButton.IconOnly
text: model.displayName
source: model.avatar ? ("image://mxc/" + model.avatar) : ""
name: model.displayName
onClicked: root.selectedSpaceId = model.id
QQC2.ToolTip.visible: hovered
QQC2.ToolTip.text: text
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
onPressAndHold: root.createContextMenu(model.currentRoom)
TapHandler { required property string displayName
acceptedButtons: Qt.RightButton required property string avatar
acceptedDevices: PointerDevice.Mouse required property string roomId
onTapped: root.createContextMenu(model.currentRoom) required property var currentRoom
}
Layout.fillWidth: true
Layout.preferredHeight: width - Kirigami.Units.smallSpacing
Layout.maximumHeight: width - Kirigami.Units.smallSpacing
text: displayName
source: avatar ? ("image://mxc/" + avatar) : ""
onClicked: root.selectedSpaceId = roomId
checked: root.selectedSpaceId === roomId
onContextMenuRequested: root.createContextMenu(currentRoom)
} }
} }
} }

View File

@@ -7,6 +7,7 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.20 as Kirigami import org.kde.kirigami 2.20 as Kirigami
import org.kde.kirigamiaddons.delegates 1.0 as Delegates
import org.kde.kitemmodels 1.0 import org.kde.kitemmodels 1.0
import org.kde.neochat 1.0 import org.kde.neochat 1.0
@@ -120,7 +121,7 @@ Kirigami.OverlayDrawer {
property alias userListSearchField: userListSearchField property alias userListSearchField: userListSearchField
spacing: Kirigami.Units.largeSpacing spacing: 0
width: userListView.width width: userListView.width
Loader { Loader {
@@ -133,26 +134,33 @@ Kirigami.OverlayDrawer {
Kirigami.ListSectionHeader { Kirigami.ListSectionHeader {
label: i18n("Options") label: i18n("Options")
activeFocusOnTab: false activeFocusOnTab: false
Layout.fillWidth: true
} }
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: devtoolsButton id: devtoolsButton
icon: "tools" icon.name: "tools"
text: i18n("Open developer tools") text: i18n("Open developer tools")
visible: Config.developerTools visible: Config.developerTools
Layout.fillWidth: true
onClicked: { onClicked: {
applicationWindow().pageStack.layers.push("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")}) applicationWindow().pageStack.layers.push("qrc:/DevtoolsPage.qml", {room: room}, {title: i18n("Developer Tools")})
roomDrawer.close(); roomDrawer.close();
} }
} }
Kirigami.BasicListItem {
Delegates.RoundedItemDelegate {
id: searchButton id: searchButton
icon: "search" icon.name: "search"
text: i18n("Search in this room") text: i18n("Search in this room")
Layout.fillWidth: true
onClicked: { onClicked: {
pageStack.pushDialogLayer("qrc:/SearchPage.qml", { pageStack.pushDialogLayer("qrc:/SearchPage.qml", {
currentRoom: room currentRoom: room
@@ -161,19 +169,22 @@ Kirigami.OverlayDrawer {
}) })
} }
} }
Kirigami.BasicListItem {
Delegates.RoundedItemDelegate {
id: favouriteButton id: favouriteButton
icon: room && room.isFavourite ? "rating" : "rating-unrated" icon.name: room && room.isFavourite ? "rating" : "rating-unrated"
text: room && room.isFavourite ? i18n("Remove room from favorites") : i18n("Make room favorite") text: room && room.isFavourite ? i18n("Remove room from favorites") : i18n("Make room favorite")
onClicked: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0) onClicked: room.isFavourite ? room.removeTag("m.favourite") : room.addTag("m.favourite", 1.0)
Layout.fillWidth: true
} }
Kirigami.BasicListItem { Delegates.RoundedItemDelegate {
id: locationsButton id: locationsButton
icon: "map-flat" icon.name: "map-flat"
text: i18n("Show locations for this room") text: i18n("Show locations for this room")
onClicked: pageStack.pushDialogLayer("qrc:/LocationsPage.qml", { onClicked: pageStack.pushDialogLayer("qrc:/LocationsPage.qml", {
@@ -181,6 +192,8 @@ Kirigami.OverlayDrawer {
}, { }, {
title: i18nc("Locations on a map", "Locations") title: i18nc("Locations on a map", "Locations")
}) })
Layout.fillWidth: true
} }
Kirigami.ListSectionHeader { Kirigami.ListSectionHeader {
@@ -189,6 +202,8 @@ Kirigami.OverlayDrawer {
spacing: 0 spacing: 0
visible: !room.isDirectChat() visible: !room.isDirectChat()
Layout.fillWidth: true
QQC2.ToolButton { QQC2.ToolButton {
id: memberSearchToggle id: memberSearchToggle
checkable: true checkable: true
@@ -255,44 +270,62 @@ Kirigami.OverlayDrawer {
clip: true clip: true
activeFocusOnTab: true activeFocusOnTab: true
delegate: Kirigami.BasicListItem { delegate: Delegates.RoundedItemDelegate {
id: userListItem id: userDelegate
required property string name
required property string userId
required property string avatar
required property int powerLevel
required property string powerLevelString
implicitHeight: Kirigami.Units.gridUnit * 2 implicitHeight: Kirigami.Units.gridUnit * 2
leftPadding: Kirigami.Units.largeSpacing + Kirigami.Units.smallSpacing
label: name text: name
labelItem.textFormat: Text.PlainText
onClicked: { onClicked: {
userDelegate.highlighted = true;
const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, { const popup = userDetailDialog.createObject(QQC2.ApplicationWindow.overlay, {
room: room, room: room,
user: room.getUser(user.id) user: room.getUser(userDelegate.userId)
}) });
popup.closed.connect(function() { popup.closed.connect(() => {
userListItem.highlighted = false userDelegate.highlighted = false;
}) });
if (roomDrawer.modal) { if (roomDrawer.modal) {
roomDrawer.close() roomDrawer.close();
} }
popup.open() popup.open();
} }
leading: Kirigami.Avatar { contentItem: RowLayout {
implicitWidth: height Kirigami.Avatar {
sourceSize.height: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5 implicitWidth: height
sourceSize.width: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5 sourceSize {
source: avatar height: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
name: model.userId width: Kirigami.Units.gridUnit + Kirigami.Units.smallSpacing * 2.5
} }
source: userDelegate.avatar
name: userDelegate.userId
trailing: QQC2.Label { Layout.fillHeight: true
visible: powerLevel > 0 }
text: powerLevelString QQC2.Label {
color: Kirigami.Theme.disabledTextColor text: userDelegate.name
textFormat: Text.PlainText textFormat: Text.PlainText
wrapMode: Text.NoWrap elide: Text.ElideRight
Layout.fillWidth: true
}
QQC2.Label {
visible: userDelegate.powerLevel > 0
text: userDelegate.powerLevelString
color: Kirigami.Theme.disabledTextColor
textFormat: Text.PlainText
}
} }
} }
} }

View File

@@ -61,7 +61,7 @@ RemoteMatches Runner::Match(const QString &searchTerm)
const QString name = m_model.data(m_model.index(i, 0), RoomListModel::DisplayNameRole).toString(); const QString name = m_model.data(m_model.index(i, 0), RoomListModel::DisplayNameRole).toString();
match.iconName = QStringLiteral("org.kde.neochat"); match.iconName = QStringLiteral("org.kde.neochat");
match.id = m_model.data(m_model.index(i, 0), RoomListModel::IdRole).toString(); match.id = m_model.data(m_model.index(i, 0), RoomListModel::RoomIdRole).toString();
match.text = name; match.text = name;
match.relevance = 1; match.relevance = 1;
const RemoteImage remoteImage = serializeImage(m_model.data(m_model.index(i, 0), RoomListModel::AvatarImageRole).value<QImage>()); const RemoteImage remoteImage = serializeImage(m_model.data(m_model.index(i, 0), RoomListModel::AvatarImageRole).value<QImage>());