Redesign room list
Use KirigamiAddons.Delegated.RoundedItemDelegate
This commit is contained in:
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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. */
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>());
|
||||||
|
|||||||
Reference in New Issue
Block a user