First attempt.

This commit is contained in:
Black
2020-02-12 00:37:35 -08:00
parent 29e6933b4f
commit 5c4d0a969d
17 changed files with 561 additions and 1663 deletions

View File

@@ -1,434 +1,141 @@
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Controls 2.12 as Controls
import QtQuick.Layouts 1.12
import QtQuick.Controls.Material 2.12
import Spectral.Component 2.0
import Spectral.Dialog 2.0
import Spectral.Menu 2.0
import Spectral.Effect 2.0
import Spectral 0.1
import Spectral.Setting 0.1
import org.kde.kirigami 2.4 as Kirigami
import SortFilterProxyModel 0.2
Item {
property var connection: null
readonly property var user: connection ? connection.localUser : null
import Spectral.Component 2.0
import Spectral 0.1
property int filter: 0
property var enteredRoom: null
Kirigami.ScrollablePage {
property var roomListModel
property var enteredRoom
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)
}
Binding {
target: trayIcon
property: "notificationCount"
value: roomListModel.notificationCount
}
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"
}
}
title: "Spectral"
actions {
main: Kirigami.Action {
iconName: "document-edit"
}
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 === 0
expression: category !== 5 && notificationCount > 0 || currentRoom === enteredRoom
},
ExpressionFilter {
enabled: filter === 1
expression: category === 1 || category === 3
},
ExpressionFilter {
enabled: filter === 2
expression: category !== 3
}
]
contextualActions: []
}
Shortcut {
sequence: "Ctrl+F"
onActivated: searchField.forceActiveFocus()
}
ListView {
id: messageListView
ColumnLayout {
anchors.fill: parent
spacing: 0
model: SortFilterProxyModel {
id: sortedRoomListModel
Control {
Layout.fillWidth: true
Layout.preferredHeight: 64
sourceModel: roomListModel
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: "\ue8b6"
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"
}
}
}
ToolButton {
Layout.preferredWidth: height
Layout.fillHeight: true
visible: searchField.active
contentItem: MaterialIcon { icon: "\ue5cd" }
onClicked: searchField.clear()
sorters: [
RoleSorter { roleName: "category" },
ExpressionSorter {
expression: {
return modelLeft.highlightCount > 0;
}
},
ExpressionSorter {
expression: {
return modelLeft.notificationCount > 0;
}
},
RoleSorter {
roleName: "lastActiveTime"
sortOrder: Qt.DescendingOrder
}
]
AutoTextField {
readonly property bool active: text
Layout.fillWidth: true
Layout.alignment: Qt.AlignVCenter
id: searchField
placeholderText: "Search..."
color: MPalette.lighter
filters: [
ExpressionFilter {
expression: joinState != "upgraded"
}
]
}
delegate: Kirigami.SwipeListItem {
padding: Kirigami.Units.largeSpacing
actions: [
Kirigami.Action {
text:"Action for buttons"
iconName: "bookmarks"
onTriggered: print("Action 1 clicked")
},
Kirigami.Action {
text:"Action 2"
iconName: "folder"
enabled: false
}
]
contentItem: RowLayout {
spacing: Kirigami.Units.largeSpacing
Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
Layout.alignment: Qt.AlignRight
visible: !searchField.active
source: root.user ? root.user.avatarMediaId : null
hint: root.user ? root.user.displayName : "?"
RippleEffect {
anchors.fill: parent
circular: true
onClicked: accountDetailDialog.createObject(ApplicationWindow.overlay).open()
}
}
}
background: Rectangle {
color: Material.background
layer.enabled: true
layer.effect: ElevationEffect {
elevation: 2
}
}
}
AutoListView {
Layout.fillWidth: true
Layout.fillHeight: true
id: listView
z: -1
spacing: 0
model: sortedRoomListModel
boundsBehavior: Flickable.DragOverBounds
ScrollBar.vertical: ScrollBar {}
delegate: Item {
width: listView.width
height: 64
Rectangle {
anchors.fill: parent
visible: currentRoom === enteredRoom
color: Material.accent
opacity: 0.1
source: avatar
hint: name || "No Name"
}
RowLayout {
anchors.fill: parent
anchors.margins: 12
ColumnLayout {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
spacing: 12
spacing: Kirigami.Units.smallSpacing
Avatar {
Layout.preferredWidth: height
Layout.fillHeight: true
source: avatar
hint: name || "No Name"
}
ColumnLayout {
Controls.Label {
Layout.fillWidth: true
Layout.fillHeight: true
Layout.alignment: Qt.AlignHCenter
Label {
Layout.fillWidth: true
Layout.fillHeight: true
text: name || "No Name"
color: MPalette.foreground
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," ")
color: MPalette.lighter
font.pixelSize: 13
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
text: name || "No Name"
font.pixelSize: 16
font.bold: unreadCount >= 0
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
Label {
visible: notificationCount > 0 && highlightCount == 0
color: MPalette.background
text: notificationCount
leftPadding: 12
rightPadding: 12
topPadding: 4
bottomPadding: 4
font.bold: true
Controls.Label {
Layout.fillWidth: true
Layout.fillHeight: true
background: Rectangle {
radius: height / 2
color: MPalette.lighter
}
text: (lastEvent == "" ? topic : lastEvent).replace(/(\r\n\t|\n|\r\t)/gm," ")
font.pixelSize: 13
elide: Text.ElideRight
wrapMode: Text.NoWrap
}
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
}
}
}
AutoMouseArea {
anchors.fill: parent
onPrimaryClicked: {
if (category === RoomType.Invited) {
acceptInvitationDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom}).open()
} else {
joinRoom(currentRoom)
}
}
onSecondaryClicked: roomListContextMenu.createObject(parent, {"room": currentRoom}).popup()
}
Component {
id: roomListContextMenu
RoomListContextMenu {}
}
}
section.property: "display"
section.criteria: ViewSection.FullString
section.delegate: Label {
width: parent.width
height: 24
text: section
color: MPalette.lighter
leftPadding: 16
elide: Text.ElideRight
verticalAlignment: Text.AlignVCenter
}
ColumnLayout {
anchors.centerIn: parent
visible: sortedRoomListModel.count == 0
MaterialIcon {
Layout.alignment: Qt.AlignHCenter
icon: "\ue5ca"
font.pixelSize: 48
color: MPalette.lighter
onClicked: {
if (enteredRoom) {
leaveRoom(enteredRoom)
}
Label {
Layout.alignment: Qt.AlignHCenter
enteredRoom = currentRoom
text: "You're all caught up!"
color: MPalette.foreground
}
enterRoom(enteredRoom)
}
}
Control {
Layout.fillWidth: true
Layout.preferredHeight: 48
Layout.margins: 16
padding: 8
contentItem: RowLayout {
id: tabBar
MaterialIcon {
Layout.fillWidth: true
icon: "\ue7f5"
color: filter == 0 ? MPalette.accent : MPalette.lighter
MouseArea {
anchors.fill: parent
onClicked: filter = 0
}
}
MaterialIcon {
Layout.fillWidth: true
icon: "\ue7ff"
color: filter == 1 ? MPalette.accent : MPalette.lighter
MouseArea {
anchors.fill: parent
onClicked: filter = 1
}
}
MaterialIcon {
Layout.fillWidth: true
icon: "\ue7fc"
color: filter == 2 ? MPalette.accent : MPalette.lighter
MouseArea {
anchors.fill: parent
onClicked: filter = 2
}
}
}
background: AutoRectangle {
color: MPalette.background
radius: 24
topLeftRadius: 8
topRightRadius: 8
topLeftVisible: true
topRightVisible: true
bottomLeftVisible: false
bottomRightVisible: false
layer.enabled: true
layer.effect: ElevationEffect {
elevation: 1
}
}
}
}
Component {
id: acceptInvitationDialog
AcceptInvitationDialog {}
}
function joinRoom(room) {
if (enteredRoom) {
leaveRoom(enteredRoom)
enteredRoom.displayed = false
}
enterRoom(room)
enteredRoom = room
room.displayed = true
}
}