Spectral/imports/Spectral/Panel/RoomListPanel.qml

373 lines
11 KiB
QML
Raw Normal View History

2018-12-07 01:18:42 +00:00
import QtQuick 2.12
2018-12-22 14:25:03 +00:00
import QtQuick.Controls 2.12
2018-12-22 14:25:03 +00:00
import QtQuick.Layouts 1.12
import QtQuick.Controls.Material 2.12
import Spectral.Component 2.0
2019-04-30 03:05:35 +00:00
import Spectral.Dialog 2.0
import Spectral.Menu 2.0
2018-11-17 09:32:38 +00:00
import Spectral.Effect 2.0
import Spectral 0.1
import Spectral.Setting 0.1
import SortFilterProxyModel 0.2
2018-12-16 02:47:58 +00:00
Item {
property var connection: null
readonly property var user: connection ? connection.localUser : null
property int filter: 0
property var enteredRoom: null
signal enterRoom(var room)
signal leaveRoom(var room)
id: root
RoomListModel {
id: roomListModel
connection: root.connection
onNewMessage: if (!window.active && MSettings.showNotification) notificationsManager.postNotification(roomId, eventId, roomName, senderName, text, icon)
}
SortFilterProxyModel {
id: sortedRoomListModel
sourceModel: roomListModel
proxyRoles: ExpressionRole {
name: "display"
expression: {
switch (category) {
case 1: return "Invited"
case 2: return "Favorites"
case 3: return "People"
case 4: return "Rooms"
case 5: return "Low Priority"
}
}
}
sorters: [
RoleSorter { roleName: "category" },
ExpressionSorter {
expression: {
return modelLeft.highlightCount > 0;
}
},
ExpressionSorter {
expression: {
return modelLeft.notificationCount > 0;
}
},
RoleSorter {
roleName: "lastActiveTime"
sortOrder: Qt.DescendingOrder
}
]
filters: [
ExpressionFilter {
expression: joinState != "upgraded"
},
RegExpFilter {
roleName: "name"
pattern: searchField.text
caseSensitivity: Qt.CaseInsensitive
},
ExpressionFilter {
enabled: filter === 1
expression: unreadCount > 0
},
ExpressionFilter {
enabled: filter === 2
expression: category === 1 || category === 2 || category === 3
},
ExpressionFilter {
enabled: filter === 3
expression: category === 4 || category === 5
}
]
}
2019-05-01 05:34:47 +00:00
Shortcut {
sequence: "Ctrl+F"
onActivated: searchField.forceActiveFocus()
}
ColumnLayout {
anchors.fill: parent
spacing: 0
Control {
Layout.fillWidth: true
Layout.preferredHeight: 64
2018-11-17 09:32:38 +00:00
id: roomListHeader
topPadding: 12
bottomPadding: 12
leftPadding: 12
rightPadding: 18
contentItem: RowLayout {
ToolButton {
Layout.preferredWidth: height
Layout.fillHeight: true
visible: !searchField.active
contentItem: MaterialIcon {
icon: {
switch (filter) {
case 0: return "\ue8b6"
case 1: return "\ue7f5"
case 2: return "\ue7ff"
case 3: return "\ue7fc"
}
}
}
Menu {
id: filterMenu
MenuItem {
text: "All"
onClicked: filter = 0
}
MenuSeparator {}
MenuItem {
text: "New"
onClicked: filter = 1
}
MenuItem {
text: "People"
onClicked: filter = 2
}
MenuItem {
text: "Group"
onClicked: filter = 3
2018-11-17 09:32:38 +00:00
}
}
onClicked: filterMenu.popup()
}
ToolButton {
Layout.preferredWidth: height
Layout.fillHeight: true
visible: searchField.active
contentItem: MaterialIcon { icon: "\ue5cd" }
onClicked: searchField.clear()
}
AutoTextField {
readonly property bool active: text
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
id: searchField
placeholderText: "Search..."
2018-12-16 02:47:58 +00:00
color: MPalette.lighter
}
Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
2018-11-17 09:32:38 +00:00
Layout.alignment: Qt.AlignRight
visible: !searchField.active
2019-01-04 12:17:26 +00:00
source: root.user ? root.user.avatarMediaId : null
hint: root.user ? root.user.displayName : "?"
2019-04-30 09:02:00 +00:00
RippleEffect {
anchors.fill: parent
2019-04-30 09:02:00 +00:00
circular: true
onClicked: accountDetailDialog.createObject(ApplicationWindow.overlay).open()
}
}
}
background: Rectangle {
color: Material.background
opacity: listView.atYBeginning ? 0 : 1
layer.enabled: true
layer.effect: ElevationEffect {
elevation: 2
}
}
}
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
id: listView
spacing: 0
clip: true
model: sortedRoomListModel
boundsBehavior: Flickable.DragOverBounds
ScrollBar.vertical: ScrollBar {}
delegate: Item {
width: listView.width
height: 64
Rectangle {
anchors.fill: parent
2018-11-18 06:29:09 +00:00
visible: currentRoom === enteredRoom
color: Material.accent
opacity: 0.1
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
spacing: 12
Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
source: avatar
hint: name || "No Name"
}
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name || "No Name"
2018-12-16 02:47:58 +00:00
color: MPalette.foreground
2018-11-18 23:29:55 +00:00
font.pixelSize: 16
font.bold: unreadCount >= 0
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: (lastEvent == "" ? topic : lastEvent).replace(/(\r\n\t|\n|\r\t)/gm," ")
2018-12-16 02:47:58 +00:00
color: MPalette.lighter
2018-11-18 23:29:55 +00:00
font.pixelSize: 13
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
}
2019-03-03 11:09:12 +00:00
Label {
visible: notificationCount > 0 && highlightCount == 0
color: "white"
text: notificationCount
leftPadding: 12
rightPadding: 12
topPadding: 4
bottomPadding: 4
font.bold: true
background: Rectangle {
radius: height / 2
color: MPalette.lighter
}
}
Label {
visible: highlightCount > 0
color: "white"
text: highlightCount
leftPadding: 12
rightPadding: 12
topPadding: 4
bottomPadding: 4
font.bold: true
background: Rectangle {
radius: height / 2
color: MPalette.accent
}
}
}
RippleEffect {
anchors.fill: parent
onPrimaryClicked: {
if (category === RoomType.Invited) {
2019-04-30 03:05:35 +00:00
acceptInvitationDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom}).open()
} else {
if (enteredRoom) {
enteredRoom.displayed = false
leaveRoom(enteredRoom)
}
currentRoom.displayed = true
enterRoom(currentRoom)
enteredRoom = currentRoom
}
}
2019-04-30 03:05:35 +00:00
onSecondaryClicked: roomListContextMenu.createObject(ApplicationWindow.overlay, {"room": currentRoom}).popup()
}
2018-12-15 14:29:51 +00:00
2019-04-30 03:05:35 +00:00
Component {
id: roomListContextMenu
2018-12-15 14:29:51 +00:00
2019-04-30 03:05:35 +00:00
RoomListContextMenu {}
2018-12-15 14:29:51 +00:00
}
}
section.property: "display"
section.criteria: ViewSection.FullString
section.delegate: Label {
width: parent.width
height: 24
text: section
2018-12-16 02:47:58 +00:00
color: MPalette.lighter
leftPadding: 16
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
}
}
2019-04-30 03:05:35 +00:00
Component {
id: acceptInvitationDialog
2019-04-30 03:05:35 +00:00
AcceptInvitationDialog {}
}
}