Spectral/qml/form/RoomListForm.qml

255 lines
8.7 KiB
QML
Raw Normal View History

2018-07-12 01:44:41 +00:00
import QtQuick 2.9
import QtQuick.Controls 2.2
import QtQuick.Layouts 1.3
2018-02-23 14:39:14 +00:00
import QtGraphicalEffects 1.0
2018-07-12 01:44:41 +00:00
import QtQuick.Controls.Material 2.2
import QtQml.Models 2.3
import Matrique 0.1
import SortFilterProxyModel 0.2
import MatriqueSettings 0.1
2018-02-23 14:39:14 +00:00
import "qrc:/qml/component"
Item {
property alias listModel: roomListProxyModel.sourceModel
property alias rawCurrentIndex: listView.currentIndex
readonly property int currentIndex: roomListProxyModel.mapToSource(listView.currentIndex)
readonly property var currentRoom: currentIndex != -1 ? listModel.roomAt(currentIndex) : null
readonly property bool mini: MatriqueSettings.miniMode // Used as an indicator of whether the listform should be displayed as "Mini mode".
signal enterRoom()
2018-02-23 14:39:14 +00:00
ColumnLayout {
anchors.fill: parent
spacing: 0
Rectangle {
2018-02-23 14:39:14 +00:00
z: 10
Layout.fillWidth: true
Layout.preferredHeight: 80
color: Qt.tint(Material.accent, "#20FFFFFF")
2018-02-23 14:39:14 +00:00
TextField {
id: searchField
width: parent.width - 18
2018-02-23 14:39:14 +00:00
height: 36
2018-08-19 06:32:18 +00:00
color: "white"
leftPadding: mini ? 4 : 32
2018-02-23 14:39:14 +00:00
topPadding: 0
bottomPadding: 0
anchors.centerIn: parent
2018-02-23 14:39:14 +00:00
background: Row {
2018-08-19 06:32:18 +00:00
visible: !parent.text
MaterialIcon {
icon: "\ue8b6"
color: "white"
2018-02-23 14:39:14 +00:00
width: mini ? parent.width : parent.height
height: parent.height
2018-02-23 14:39:14 +00:00
}
Label {
2018-02-23 14:39:14 +00:00
height: parent.height
visible: !mini
text: "Search"
2018-02-23 14:39:14 +00:00
color: "white"
font.pointSize: 12
horizontalAlignment: Text.AlignHCenter
verticalAlignment: Text.AlignVCenter
}
}
2018-02-23 14:39:14 +00:00
}
}
Rectangle {
2018-02-23 14:39:14 +00:00
Layout.fillWidth: true
Layout.fillHeight: true
color: Material.theme == Material.Light ? "#eaeaea" : "#242424"
2018-03-01 11:56:02 +00:00
Label {
z: 10
text: mini ? "Empty" : "Here? No, not here."
anchors.centerIn: parent
visible: listView.count === 0
2018-02-23 14:39:14 +00:00
}
SortFilterProxyModel {
id: roomListProxyModel
filters: RegExpFilter {
roleName: "name"
pattern: searchField.text
caseSensitivity: Qt.CaseInsensitive
}
2018-08-17 04:55:57 +00:00
proxyRoles: ExpressionRole {
name: "display"
expression: {
switch (category) {
case 1: return "Invited"
case 2: return "Favorites"
case 3: return "Rooms"
case 4: return "People"
case 5: return "Low Priorities"
}
}
}
sorters: [
2018-08-17 07:58:08 +00:00
RoleSorter { roleName: "category" },
RoleSorter {
roleName: "unreadCount"
sortOrder: Qt.DescendingOrder
},
StringSorter { roleName: "name" }
]
}
2018-02-23 14:39:14 +00:00
ListView {
id: listView
anchors.fill: parent
2018-02-23 14:39:14 +00:00
model: roomListProxyModel
2018-02-23 14:39:14 +00:00
highlight: Rectangle {
color: Material.accent
opacity: 0.2
}
highlightMoveDuration: 250
highlightResizeDuration: 0
2018-02-23 14:39:14 +00:00
2018-07-08 12:54:06 +00:00
currentIndex: -1
boundsBehavior: Flickable.DragOverBounds
2018-02-23 14:39:14 +00:00
ScrollBar.vertical: ScrollBar { id: scrollBar }
delegate: ItemDelegate {
width: parent.width
height: 80
AutoMouseArea {
anchors.fill: parent
onPressed: listView.currentIndex = index
onSecondaryClicked: roomListMenu.popup()
onPrimaryClicked: category === RoomType.Invited ? inviteDialog.open() : enterRoom()
}
ToolTip.visible: mini && hovered
ToolTip.text: name
Rectangle {
width: 4
height: parent.height
color: Qt.tint(Material.accent, "#20FFFFFF")
visible: unreadCount > 0
}
contentItem: RowLayout {
anchors.fill: parent
anchors.margins: 16
spacing: 16
ImageStatus {
Layout.preferredWidth: height
Layout.fillHeight: true
source: avatar ? "image://mxc/" + avatar : ""
displayText: name
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
visible: parent.width > 80
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name || "No Name"
font.pointSize: 16
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: lastEvent || topic
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
}
}
2018-08-17 04:55:57 +00:00
section.property: "display"
section.criteria: ViewSection.FullString
section.delegate: Label {
width: parent.width
height: 24
text: section
color: "grey"
2018-07-20 04:14:02 +00:00
leftPadding: mini ? undefined : 16
2018-07-14 11:24:20 +00:00
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
2018-07-20 04:14:02 +00:00
horizontalAlignment: mini ? Text.AlignHCenter : undefined
background: Rectangle {
2018-08-17 04:55:57 +00:00
anchors.fill: parent
2018-07-20 04:14:02 +00:00
color: Material.theme == Material.Light ? "#dbdbdb" : "#363636"
}
}
2018-08-07 15:41:18 +00:00
2018-08-17 04:55:57 +00:00
Dialog {
id: inviteDialog
parent: ApplicationWindow.overlay
x: (window.width - width) / 2
y: (window.height - height) / 2
width: 360
title: "Action Required"
modal: true
standardButtons: Dialog.Ok | Dialog.Cancel
contentItem: Label { text: "Accept this invitation?" }
onAccepted: currentRoom.acceptInvitation()
onRejected: currentRoom.forget()
2018-08-17 04:55:57 +00:00
}
2018-08-07 15:41:18 +00:00
Menu {
id: roomListMenu
MenuItem {
text: "Favourite"
checkable: true
checked: currentRoom && currentRoom.isFavourite
onTriggered: currentRoom.isFavourite ? currentRoom.removeTag("m.favourite") : currentRoom.addTag("m.favourite", "1")
}
MenuItem {
text: "Deprioritize"
checkable: true
checked: currentRoom && currentRoom.isLowPriority
onTriggered: currentRoom.isLowPriority ? currentRoom.removeTag("m.lowpriority") : currentRoom.addTag("m.lowpriority", "1")
}
MenuSeparator {}
MenuItem {
text: "Mark as Read"
onTriggered: currentRoom.markAllMessagesAsRead()
}
MenuItem {
text: "Leave Room"
onTriggered: currentRoom.forget()
2018-08-07 15:41:18 +00:00
}
}
2018-02-23 14:39:14 +00:00
}
}
}
}