Remove first row, modify room list panel.
This commit is contained in:
parent
a296fffd91
commit
aaae68a5bf
|
@ -15,13 +15,6 @@ Drawer {
|
||||||
id: roomDrawer
|
id: roomDrawer
|
||||||
|
|
||||||
edge: Qt.RightEdge
|
edge: Qt.RightEdge
|
||||||
interactive: false
|
|
||||||
|
|
||||||
ToolButton {
|
|
||||||
contentItem: MaterialIcon { icon: "\ue5c4" }
|
|
||||||
|
|
||||||
onClicked: roomDrawer.close()
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
|
@ -8,14 +8,10 @@ import Spectral.Setting 0.1
|
||||||
|
|
||||||
import Spectral.Component 2.0
|
import Spectral.Component 2.0
|
||||||
|
|
||||||
Rectangle {
|
Item {
|
||||||
color: MSettings.darkTheme ? "#303030" : "#fafafa"
|
|
||||||
|
|
||||||
AutoMouseArea {
|
AutoMouseArea {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
hoverEnabled: miniMode
|
|
||||||
|
|
||||||
onSecondaryClicked: {
|
onSecondaryClicked: {
|
||||||
roomContextMenu.model = model
|
roomContextMenu.model = model
|
||||||
roomContextMenu.popup()
|
roomContextMenu.popup()
|
||||||
|
@ -30,9 +26,6 @@ Rectangle {
|
||||||
enteredRoom = currentRoom
|
enteredRoom = currentRoom
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolTip.visible: miniMode && containsMouse
|
|
||||||
ToolTip.text: name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
@ -1,15 +1,44 @@
|
||||||
import QtQuick 2.9
|
import QtQuick 2.9
|
||||||
import QtQuick.Controls 2.2
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
|
import QtQuick.Layouts 1.3
|
||||||
|
import QtQuick.Controls.Material 2.2
|
||||||
|
|
||||||
|
import Spectral.Component 2.0
|
||||||
|
import Spectral.Menu 2.0
|
||||||
|
|
||||||
|
import Spectral 0.1
|
||||||
|
import Spectral.Setting 0.1
|
||||||
|
|
||||||
import SortFilterProxyModel 0.2
|
import SortFilterProxyModel 0.2
|
||||||
|
|
||||||
RoomListPanelForm {
|
Rectangle {
|
||||||
model: sortedRoomListModel
|
property var controller: null
|
||||||
|
readonly property var user: controller.connection ? controller.connection.localUser : null
|
||||||
|
|
||||||
|
readonly property int filter: 0
|
||||||
|
property var enteredRoom: null
|
||||||
|
property alias errorControl: errorControl
|
||||||
|
|
||||||
|
signal enterRoom(var room)
|
||||||
|
signal leaveRoom(var room)
|
||||||
|
|
||||||
|
id: root
|
||||||
|
|
||||||
|
color: MSettings.darkTheme ? "#303030" : "#FFFFFF"
|
||||||
|
|
||||||
|
RoomListModel {
|
||||||
|
id: roomListModel
|
||||||
|
|
||||||
|
connection: controller.connection
|
||||||
|
|
||||||
|
onNewMessage: if (!window.active) spectralController.postNotification(roomId, eventId, roomName, senderName, text, icon, iconPath)
|
||||||
|
}
|
||||||
|
|
||||||
SortFilterProxyModel {
|
SortFilterProxyModel {
|
||||||
id: sortedRoomListModel
|
id: sortedRoomListModel
|
||||||
|
|
||||||
sourceModel: listModel
|
sourceModel: roomListModel
|
||||||
|
|
||||||
proxyRoles: ExpressionRole {
|
proxyRoles: ExpressionRole {
|
||||||
name: "display"
|
name: "display"
|
||||||
|
@ -53,9 +82,239 @@ RoomListPanelForm {
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
Shortcut {
|
Drawer {
|
||||||
sequence: StandardKey.Find
|
width: Math.max(root.width, 360)
|
||||||
onActivated: searchField.forceActiveFocus()
|
height: root.height
|
||||||
|
|
||||||
|
id: drawer
|
||||||
|
|
||||||
|
edge: Qt.LeftEdge
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
width: parent.width
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 330
|
||||||
|
|
||||||
|
padding: 24
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
spacing: 4
|
||||||
|
|
||||||
|
ImageItem {
|
||||||
|
Layout.preferredWidth: 200
|
||||||
|
Layout.preferredHeight: 200
|
||||||
|
Layout.margins: 12
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
source: root.user ? root.user.paintable : null
|
||||||
|
hint: root.user ? root.user.displayName : "?"
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
text: root.user ? root.user.displayName : "No Name"
|
||||||
|
color: "white"
|
||||||
|
font.pointSize: 16.5
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
|
||||||
|
text: root.user ? root.user.id : "@example:matrix.org"
|
||||||
|
color: "white"
|
||||||
|
opacity: 0.7
|
||||||
|
font.pointSize: 9.75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle { color: "#455A64" }
|
||||||
|
}
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: AccountListModel {
|
||||||
|
controller: spectralController
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: ItemDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: user.displayName
|
||||||
|
|
||||||
|
onClicked: controller.connection = connection
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: "Exit"
|
||||||
|
|
||||||
|
onClicked: Qt.quit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
spacing: 0
|
||||||
|
|
||||||
|
Control {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.preferredHeight: 64
|
||||||
|
|
||||||
|
topPadding: 12
|
||||||
|
bottomPadding: 12
|
||||||
|
leftPadding: 12
|
||||||
|
rightPadding: 18
|
||||||
|
|
||||||
|
contentItem: RowLayout {
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
contentItem: MaterialIcon {
|
||||||
|
icon: searchField.visible ? "\ue5cd" : "\ue8b6"
|
||||||
|
color: searchField.visible ? "#1D333E" : "#7F7F7F"
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (searchField.visible) searchField.clear()
|
||||||
|
searchField.visible = !searchField.visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoTextField {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
id: searchField
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
topPadding: 0
|
||||||
|
bottomPadding: 0
|
||||||
|
placeholderText: "Search..."
|
||||||
|
|
||||||
|
background: Item {}
|
||||||
|
}
|
||||||
|
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
visible: !searchField.visible
|
||||||
|
|
||||||
|
text: root.user ? root.user.displayName : "No Name"
|
||||||
|
elide: Text.ElideRight
|
||||||
|
wrapMode: Text.NoWrap
|
||||||
|
font.pointSize: 12
|
||||||
|
color: "#7F7F7F"
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageItem {
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
visible: !searchField.visible
|
||||||
|
|
||||||
|
source: root.user ? root.user.paintable : null
|
||||||
|
hint: root.user ? root.user.displayName : "?"
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: drawer.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Control {
|
||||||
|
property string error: ""
|
||||||
|
property string detail: ""
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
id: errorControl
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
|
||||||
|
topPadding: 16
|
||||||
|
bottomPadding: 16
|
||||||
|
leftPadding: 24
|
||||||
|
rightPadding: 24
|
||||||
|
|
||||||
|
contentItem: ColumnLayout {
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: errorControl.error
|
||||||
|
font.pointSize: 12
|
||||||
|
color: "white"
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
Label {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
|
text: errorControl.detail
|
||||||
|
font.pointSize: 10.5
|
||||||
|
color: "white"
|
||||||
|
opacity: 0.6
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
}
|
||||||
|
ItemDelegate {
|
||||||
|
Layout.preferredHeight: 32
|
||||||
|
Layout.alignment: Qt.AlignRight
|
||||||
|
|
||||||
|
text: "Dismiss"
|
||||||
|
Material.foreground: "white"
|
||||||
|
onClicked: errorControl.visible = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle { color: "#273338" }
|
||||||
|
}
|
||||||
|
|
||||||
|
AutoListView {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
id: listView
|
||||||
|
|
||||||
|
spacing: 0
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
model: sortedRoomListModel
|
||||||
|
|
||||||
|
boundsBehavior: Flickable.DragOverBounds
|
||||||
|
|
||||||
|
ScrollBar.vertical: ScrollBar {}
|
||||||
|
|
||||||
|
delegate: RoomListDelegate {
|
||||||
|
width: parent.width
|
||||||
|
height: 64
|
||||||
|
}
|
||||||
|
|
||||||
|
section.property: "display"
|
||||||
|
section.criteria: ViewSection.FullString
|
||||||
|
section.delegate: Label {
|
||||||
|
width: parent.width
|
||||||
|
height: 24
|
||||||
|
|
||||||
|
text: section
|
||||||
|
color: "#5B7480"
|
||||||
|
leftPadding: 16
|
||||||
|
elide: Text.ElideRight
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
RoomContextMenu {
|
||||||
|
id: roomContextMenu
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
Dialog {
|
||||||
|
|
|
@ -1,138 +0,0 @@
|
||||||
import QtQuick 2.9
|
|
||||||
import QtQuick.Controls 2.2
|
|
||||||
import QtQuick.Layouts 1.3
|
|
||||||
import QtGraphicalEffects 1.0
|
|
||||||
import QtQuick.Controls.Material 2.2
|
|
||||||
import QtQml.Models 2.3
|
|
||||||
|
|
||||||
import Spectral.Component 2.0
|
|
||||||
import Spectral.Menu 2.0
|
|
||||||
import Spectral.Effect 2.0
|
|
||||||
|
|
||||||
import Spectral 0.1
|
|
||||||
import Spectral.Setting 0.1
|
|
||||||
import SortFilterProxyModel 0.2
|
|
||||||
|
|
||||||
import "qrc:/js/util.js" as Util
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
property var listModel
|
|
||||||
property int filter: 0
|
|
||||||
property var enteredRoom: null
|
|
||||||
|
|
||||||
property alias searchField: searchField
|
|
||||||
property alias model: listView.model
|
|
||||||
|
|
||||||
property bool miniMode: width == 64
|
|
||||||
|
|
||||||
signal enterRoom(var room)
|
|
||||||
signal leaveRoom(var room)
|
|
||||||
|
|
||||||
color: MSettings.darkTheme ? "#323232" : "#f3f3f3"
|
|
||||||
|
|
||||||
Label {
|
|
||||||
text: miniMode ? "Empty" : "Here? No, not here."
|
|
||||||
anchors.centerIn: parent
|
|
||||||
visible: listView.count === 0
|
|
||||||
}
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: 40
|
|
||||||
Layout.margins: 12
|
|
||||||
|
|
||||||
color: MSettings.darkTheme ? "#303030" : "#fafafa"
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
visible: !miniMode && !searchField.text
|
|
||||||
|
|
||||||
icon: "\ue8b6"
|
|
||||||
color: "grey"
|
|
||||||
}
|
|
||||||
|
|
||||||
ItemDelegate {
|
|
||||||
Layout.preferredWidth: height
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
visible: !miniMode && searchField.text
|
|
||||||
|
|
||||||
contentItem: MaterialIcon {
|
|
||||||
icon: "\ue5cd"
|
|
||||||
color: "grey"
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: searchField.text = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoTextField {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
id: searchField
|
|
||||||
|
|
||||||
topPadding: 0
|
|
||||||
bottomPadding: 0
|
|
||||||
placeholderText: "Search..."
|
|
||||||
|
|
||||||
background: Item {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AutoListView {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
id: listView
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
boundsBehavior: Flickable.DragOverBounds
|
|
||||||
|
|
||||||
ScrollBar.vertical: ScrollBar {
|
|
||||||
}
|
|
||||||
|
|
||||||
delegate: RoomListDelegate {
|
|
||||||
width: parent.width
|
|
||||||
height: 64
|
|
||||||
}
|
|
||||||
|
|
||||||
section.property: "display"
|
|
||||||
section.criteria: ViewSection.FullString
|
|
||||||
section.delegate: Label {
|
|
||||||
width: parent.width
|
|
||||||
height: 24
|
|
||||||
|
|
||||||
text: section
|
|
||||||
color: "grey"
|
|
||||||
leftPadding: miniMode ? undefined : 16
|
|
||||||
elide: Text.ElideRight
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
horizontalAlignment: miniMode ? Text.AlignHCenter : undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
RoomContextMenu {
|
|
||||||
id: roomContextMenu
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*##^## Designer {
|
|
||||||
D{i:0;autoSize:true;height:480;width:640}
|
|
||||||
}
|
|
||||||
##^##*/
|
|
|
@ -55,7 +55,7 @@ Item {
|
||||||
visible: currentRoom
|
visible: currentRoom
|
||||||
|
|
||||||
source: "qrc:/assets/img/roompanel.svg"
|
source: "qrc:/assets/img/roompanel.svg"
|
||||||
fillMode: Image.Pad
|
fillMode: Image.PreserveAspectCrop
|
||||||
}
|
}
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
|
|
|
@ -102,14 +102,6 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
width: currentRoom && currentRoom.hasFileUploading ? parent.width * currentRoom.fileUploadingProgress / 100 : 0
|
|
||||||
height: parent.height
|
|
||||||
|
|
||||||
opacity: 0.2
|
|
||||||
color: Material.accent
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
|
|
||||||
|
@ -169,6 +161,14 @@ Rectangle {
|
||||||
background: Item {
|
background: Item {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
width: currentRoom && currentRoom.hasFileUploading ? parent.width * currentRoom.fileUploadingProgress / 100 : 0
|
||||||
|
height: parent.height
|
||||||
|
|
||||||
|
opacity: 0.2
|
||||||
|
color: Material.accent
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: timeoutTimer
|
id: timeoutTimer
|
||||||
|
|
||||||
|
|
357
qml/main.qml
357
qml/main.qml
|
@ -5,8 +5,10 @@ import QtQuick.Controls.Material 2.2
|
||||||
import Qt.labs.settings 1.0
|
import Qt.labs.settings 1.0
|
||||||
import Qt.labs.platform 1.0 as Platform
|
import Qt.labs.platform 1.0 as Platform
|
||||||
|
|
||||||
|
import Spectral.Panel 2.0
|
||||||
import Spectral.Component 2.0
|
import Spectral.Component 2.0
|
||||||
import Spectral.Page 2.0
|
import Spectral.Page 2.0
|
||||||
|
import Spectral.Effect 2.0
|
||||||
|
|
||||||
import Spectral 0.1
|
import Spectral 0.1
|
||||||
import Spectral.Setting 0.1
|
import Spectral.Setting 0.1
|
||||||
|
@ -14,8 +16,6 @@ import Spectral.Setting 0.1
|
||||||
import "qrc:/js/util.js" as Util
|
import "qrc:/js/util.js" as Util
|
||||||
|
|
||||||
ApplicationWindow {
|
ApplicationWindow {
|
||||||
readonly property var currentConnection: accountListView.currentConnection ? accountListView.currentConnection : null
|
|
||||||
|
|
||||||
Material.theme: MSettings.darkTheme ? Material.Dark : Material.Light
|
Material.theme: MSettings.darkTheme ? Material.Dark : Material.Light
|
||||||
|
|
||||||
width: 960
|
width: 960
|
||||||
|
@ -52,353 +52,50 @@ ApplicationWindow {
|
||||||
quitOnLastWindowClosed: !MSettings.showTray
|
quitOnLastWindowClosed: !MSettings.showTray
|
||||||
|
|
||||||
onNotificationClicked: {
|
onNotificationClicked: {
|
||||||
roomPage.enteredRoom = currentConnection.room(roomId)
|
roomPage.enteredRoom = spectralController.connection.room(roomId)
|
||||||
roomPage.goToEvent(eventId)
|
roomPage.goToEvent(eventId)
|
||||||
showWindow()
|
showWindow()
|
||||||
}
|
}
|
||||||
onErrorOccured: {
|
onErrorOccured: {
|
||||||
errorDialog.error = error
|
roomListForm.errorControl.error = error
|
||||||
errorDialog.detail = detail
|
roomListForm.errorControl.detail = detail
|
||||||
errorDialog.open()
|
roomListForm.errorControl.visible = true
|
||||||
}
|
}
|
||||||
|
onSyncDone: roomListForm.errorControl.visible = false
|
||||||
}
|
}
|
||||||
|
|
||||||
AccountListModel {
|
SplitView {
|
||||||
id: accountListModel
|
anchors.fill: parent
|
||||||
|
|
||||||
|
RoomListPanel {
|
||||||
|
width: window.width * 0.35
|
||||||
|
Layout.minimumWidth: 180
|
||||||
|
|
||||||
|
id: roomListForm
|
||||||
|
|
||||||
|
clip: true
|
||||||
|
|
||||||
controller: spectralController
|
controller: spectralController
|
||||||
|
|
||||||
|
onLeaveRoom: roomForm.saveReadMarker(room)
|
||||||
}
|
}
|
||||||
|
|
||||||
Dialog {
|
RoomPanel {
|
||||||
property string error
|
|
||||||
property string detail
|
|
||||||
|
|
||||||
x: (window.width - width) / 2
|
|
||||||
y: (window.height - height) / 2
|
|
||||||
|
|
||||||
id: errorDialog
|
|
||||||
|
|
||||||
title: error + " Error"
|
|
||||||
contentItem: Label { text: errorDialog.detail }
|
|
||||||
}
|
|
||||||
|
|
||||||
Component {
|
|
||||||
id: loginPage
|
|
||||||
|
|
||||||
Login { controller: spectralController }
|
|
||||||
}
|
|
||||||
|
|
||||||
Room {
|
|
||||||
id: roomPage
|
|
||||||
|
|
||||||
parent: null
|
|
||||||
|
|
||||||
connection: currentConnection
|
|
||||||
}
|
|
||||||
|
|
||||||
Setting {
|
|
||||||
id: settingPage
|
|
||||||
|
|
||||||
parent: null
|
|
||||||
|
|
||||||
listModel: accountListModel
|
|
||||||
}
|
|
||||||
|
|
||||||
RowLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
Rectangle {
|
|
||||||
Layout.preferredWidth: 64
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
id: sideNav
|
|
||||||
|
|
||||||
color: Material.primary
|
|
||||||
|
|
||||||
ColumnLayout {
|
|
||||||
anchors.fill: parent
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
AutoListView {
|
|
||||||
property var currentConnection: null
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.fillHeight: true
|
Layout.minimumWidth: 480
|
||||||
|
|
||||||
id: accountListView
|
id: roomForm
|
||||||
|
|
||||||
model: accountListModel
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
|
|
||||||
delegate: Column {
|
currentRoom: roomListForm.enteredRoom
|
||||||
property bool expanded: accountListView.currentConnection === connection
|
|
||||||
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
width: parent.width
|
|
||||||
height: width
|
|
||||||
|
|
||||||
selected: stackView.currentItem === page && currentConnection === connection
|
|
||||||
|
|
||||||
ImageItem {
|
|
||||||
anchors.fill: parent
|
|
||||||
anchors.margins: 12
|
|
||||||
|
|
||||||
hint: user.displayName
|
|
||||||
source: user.paintable
|
|
||||||
}
|
|
||||||
|
|
||||||
highlightColor: Material.accent
|
|
||||||
|
|
||||||
page: roomPage
|
|
||||||
|
|
||||||
onClicked: {
|
|
||||||
accountListView.currentConnection = connection
|
|
||||||
roomPage.filter = 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Column {
|
|
||||||
width: parent.width
|
|
||||||
height: expanded ? implicitHeight : 0
|
|
||||||
|
|
||||||
spacing: 0
|
|
||||||
clip: true
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
width: parent.width
|
|
||||||
height: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue7f7"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: roomPage.filter = 1
|
|
||||||
}
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
width: parent.width
|
|
||||||
height: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue7fd"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: roomPage.filter = 2
|
|
||||||
}
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
width: parent.width
|
|
||||||
height: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue7fb"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: roomPage.filter = 3
|
|
||||||
}
|
|
||||||
|
|
||||||
Behavior on height {
|
|
||||||
PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue145"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
|
|
||||||
enabled: !addRoomMenu.opened
|
|
||||||
onClicked: addRoomMenu.popup()
|
|
||||||
|
|
||||||
Menu {
|
|
||||||
id: addRoomMenu
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text:"New Room"
|
|
||||||
onTriggered: addRoomDialog.open()
|
|
||||||
|
|
||||||
Dialog {
|
|
||||||
id: addRoomDialog
|
|
||||||
parent: ApplicationWindow.overlay
|
|
||||||
|
|
||||||
x: (window.width - width) / 2
|
|
||||||
y: (window.height - height) / 2
|
|
||||||
width: 360
|
|
||||||
|
|
||||||
title: "New Room"
|
|
||||||
modal: true
|
|
||||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
|
||||||
|
|
||||||
contentItem: Column {
|
|
||||||
AutoTextField {
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
id: addRoomDialogNameTextField
|
|
||||||
|
|
||||||
placeholderText: "Name"
|
|
||||||
}
|
|
||||||
AutoTextField {
|
|
||||||
width: parent.width
|
|
||||||
|
|
||||||
id: addRoomDialogTopicTextField
|
|
||||||
|
|
||||||
placeholderText: "Topic"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: spectralController.createRoom(currentConnection, addRoomDialogNameTextField.text, addRoomDialogTopicTextField.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Join Room"
|
|
||||||
|
|
||||||
onTriggered: joinRoomDialog.open()
|
|
||||||
|
|
||||||
Dialog {
|
|
||||||
x: (window.width - width) / 2
|
|
||||||
y: (window.height - height) / 2
|
|
||||||
width: 360
|
|
||||||
|
|
||||||
id: joinRoomDialog
|
|
||||||
|
|
||||||
parent: ApplicationWindow.overlay
|
|
||||||
|
|
||||||
title: "Input Room Alias or ID"
|
|
||||||
modal: true
|
|
||||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
|
||||||
|
|
||||||
contentItem: AutoTextField {
|
|
||||||
id: joinRoomDialogTextField
|
|
||||||
placeholderText: "#matrix:matrix.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: spectralController.joinRoom(currentConnection, joinRoomDialogTextField.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MenuItem {
|
|
||||||
text: "Direct Chat"
|
|
||||||
|
|
||||||
onTriggered: directChatDialog.open()
|
|
||||||
|
|
||||||
Dialog {
|
|
||||||
x: (window.width - width) / 2
|
|
||||||
y: (window.height - height) / 2
|
|
||||||
width: 360
|
|
||||||
|
|
||||||
id: directChatDialog
|
|
||||||
|
|
||||||
parent: ApplicationWindow.overlay
|
|
||||||
|
|
||||||
title: "Input User ID"
|
|
||||||
modal: true
|
|
||||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
|
||||||
|
|
||||||
contentItem: AutoTextField {
|
|
||||||
id: directChatDialogTextField
|
|
||||||
placeholderText: "@bot:matrix.org"
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: spectralController.createDirectChat(currentConnection, directChatDialogTextField.text)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue8b8"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
page: settingPage
|
|
||||||
}
|
|
||||||
|
|
||||||
SideNavButton {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.preferredHeight: width
|
|
||||||
|
|
||||||
MaterialIcon {
|
|
||||||
anchors.fill: parent
|
|
||||||
|
|
||||||
icon: "\ue8ac"
|
|
||||||
color: "white"
|
|
||||||
}
|
|
||||||
|
|
||||||
onClicked: MSettings.confirmOnExit ? confirmExitDialog.open() : Qt.quit()
|
|
||||||
|
|
||||||
Dialog {
|
|
||||||
x: (window.width - width) / 2
|
|
||||||
y: (window.height - height) / 2
|
|
||||||
width: 360
|
|
||||||
|
|
||||||
id: confirmExitDialog
|
|
||||||
|
|
||||||
parent: ApplicationWindow.overlay
|
|
||||||
|
|
||||||
title: "Exit"
|
|
||||||
modal: true
|
|
||||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
|
||||||
|
|
||||||
contentItem: Column {
|
|
||||||
Label { text: "Exit?" }
|
|
||||||
CheckBox {
|
|
||||||
text: "Do not ask next time"
|
|
||||||
checked: !MSettings.confirmOnExit
|
|
||||||
|
|
||||||
onCheckedChanged: MSettings.confirmOnExit = !checked
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
onAccepted: Qt.quit()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
StackView {
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.fillHeight: true
|
|
||||||
|
|
||||||
id: stackView
|
|
||||||
|
|
||||||
initialItem: roomPage
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
target: imageProvider
|
target: imageProvider
|
||||||
property: "connection"
|
property: "connection"
|
||||||
value: currentConnection
|
value: spectralController.connection
|
||||||
}
|
}
|
||||||
|
|
||||||
function showWindow() {
|
function showWindow() {
|
||||||
|
@ -411,6 +108,10 @@ ApplicationWindow {
|
||||||
window.hide()
|
window.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function showError() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
spectralController.initiated.connect(function() {
|
spectralController.initiated.connect(function() {
|
||||||
if (spectralController.accountCount == 0) stackView.push(loginPage)
|
if (spectralController.accountCount == 0) stackView.push(loginPage)
|
||||||
|
|
1
res.qrc
1
res.qrc
|
@ -38,7 +38,6 @@
|
||||||
<file>imports/Spectral/Panel/qmldir</file>
|
<file>imports/Spectral/Panel/qmldir</file>
|
||||||
<file>imports/Spectral/Panel/RoomDrawer.qml</file>
|
<file>imports/Spectral/Panel/RoomDrawer.qml</file>
|
||||||
<file>imports/Spectral/Panel/RoomListPanel.qml</file>
|
<file>imports/Spectral/Panel/RoomListPanel.qml</file>
|
||||||
<file>imports/Spectral/Panel/RoomListPanelForm.ui.qml</file>
|
|
||||||
<file>imports/Spectral/Panel/RoomPanel.qml</file>
|
<file>imports/Spectral/Panel/RoomPanel.qml</file>
|
||||||
<file>imports/Spectral/Panel/RoomPanelForm.ui.qml</file>
|
<file>imports/Spectral/Panel/RoomPanelForm.ui.qml</file>
|
||||||
<file>imports/Spectral/Panel/RoomHeader.qml</file>
|
<file>imports/Spectral/Panel/RoomHeader.qml</file>
|
||||||
|
|
|
@ -75,7 +75,7 @@ void Controller::loginWithCredentials(QString serverAddr, QString user,
|
||||||
});
|
});
|
||||||
connect(m_connection, &Connection::networkError,
|
connect(m_connection, &Connection::networkError,
|
||||||
[=](QString error, QByteArray detail) {
|
[=](QString error, QByteArray detail) {
|
||||||
emit errorOccured("Network", error);
|
emit errorOccured("Network Error", error);
|
||||||
});
|
});
|
||||||
connect(m_connection, &Connection::loginError,
|
connect(m_connection, &Connection::loginError,
|
||||||
[=](QString error, QByteArray detail) {
|
[=](QString error, QByteArray detail) {
|
||||||
|
@ -110,6 +110,7 @@ void Controller::addConnection(Connection* c) {
|
||||||
m_connections.push_back(c);
|
m_connections.push_back(c);
|
||||||
|
|
||||||
connect(c, &Connection::syncDone, this, [=] {
|
connect(c, &Connection::syncDone, this, [=] {
|
||||||
|
emit syncDone();
|
||||||
c->sync(30000);
|
c->sync(30000);
|
||||||
|
|
||||||
static int counter = 0;
|
static int counter = 0;
|
||||||
|
@ -152,11 +153,12 @@ void Controller::invokeLogin() {
|
||||||
});
|
});
|
||||||
connect(c, &Connection::networkError,
|
connect(c, &Connection::networkError,
|
||||||
[=](QString error, QByteArray detail) {
|
[=](QString error, QByteArray detail) {
|
||||||
emit errorOccured("Network", error);
|
emit errorOccured("Network Error", error);
|
||||||
});
|
});
|
||||||
c->connectWithToken(account.userId(), accessToken, account.deviceId());
|
c->connectWithToken(account.userId(), accessToken, account.deviceId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!m_connections.isEmpty()) setConnection(m_connections[0]);
|
||||||
emit initiated();
|
emit initiated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +186,7 @@ bool Controller::saveAccessToken(const AccountSettings& account,
|
||||||
auto fileDir = QFileInfo(accountTokenFile).dir();
|
auto fileDir = QFileInfo(accountTokenFile).dir();
|
||||||
if (!((fileDir.exists() || fileDir.mkpath(".")) &&
|
if (!((fileDir.exists() || fileDir.mkpath(".")) &&
|
||||||
accountTokenFile.open(QFile::WriteOnly))) {
|
accountTokenFile.open(QFile::WriteOnly))) {
|
||||||
emit errorOccured("Token", "Cannot save access token.");
|
emit errorOccured("I/O Denied", "Cannot save access token.");
|
||||||
} else {
|
} else {
|
||||||
accountTokenFile.write(accessToken);
|
accountTokenFile.write(accessToken);
|
||||||
return true;
|
return true;
|
||||||
|
@ -227,14 +229,6 @@ void Controller::playAudio(QUrl localFile) {
|
||||||
connect(player, &QMediaPlayer::stateChanged, [=] { player->deleteLater(); });
|
connect(player, &QMediaPlayer::stateChanged, [=] { player->deleteLater(); });
|
||||||
}
|
}
|
||||||
|
|
||||||
QColor Controller::color(QString userId) {
|
|
||||||
return QColor(SettingsGroup("UI/Color").value(userId, "#498882").toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::setColor(QString userId, QColor newColor) {
|
|
||||||
SettingsGroup("UI/Color").setValue(userId, newColor.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Controller::postNotification(const QString& roomId, const QString& eventId,
|
void Controller::postNotification(const QString& roomId, const QString& eventId,
|
||||||
const QString& roomName,
|
const QString& roomName,
|
||||||
const QString& senderName,
|
const QString& senderName,
|
||||||
|
|
|
@ -20,6 +20,8 @@ class Controller : public QObject {
|
||||||
connectionDropped)
|
connectionDropped)
|
||||||
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE
|
Q_PROPERTY(bool quitOnLastWindowClosed READ quitOnLastWindowClosed WRITE
|
||||||
setQuitOnLastWindowClosed NOTIFY quitOnLastWindowClosedChanged)
|
setQuitOnLastWindowClosed NOTIFY quitOnLastWindowClosedChanged)
|
||||||
|
Q_PROPERTY(Connection* connection READ connection WRITE setConnection NOTIFY
|
||||||
|
connectionChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit Controller(QObject* parent = nullptr);
|
explicit Controller(QObject* parent = nullptr);
|
||||||
|
@ -47,13 +49,23 @@ class Controller : public QObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_INVOKABLE QColor color(QString userId);
|
Connection* connection() {
|
||||||
Q_INVOKABLE void setColor(QString userId, QColor newColor);
|
if (m_connection.isNull()) return nullptr;
|
||||||
|
return m_connection;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setConnection(Connection* conn) {
|
||||||
|
if (!conn) return;
|
||||||
|
if (conn == m_connection) return;
|
||||||
|
m_connection = conn;
|
||||||
|
emit connectionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QClipboard* m_clipboard = QApplication::clipboard();
|
QClipboard* m_clipboard = QApplication::clipboard();
|
||||||
NotificationsManager notificationsManager;
|
NotificationsManager notificationsManager;
|
||||||
QVector<Connection*> m_connections;
|
QVector<Connection*> m_connections;
|
||||||
|
QPointer<Connection> m_connection;
|
||||||
|
|
||||||
QByteArray loadAccessToken(const AccountSettings& account);
|
QByteArray loadAccessToken(const AccountSettings& account);
|
||||||
bool saveAccessToken(const AccountSettings& account,
|
bool saveAccessToken(const AccountSettings& account,
|
||||||
|
@ -67,11 +79,13 @@ class Controller : public QObject {
|
||||||
signals:
|
signals:
|
||||||
void busyChanged();
|
void busyChanged();
|
||||||
void errorOccured(QString error, QString detail);
|
void errorOccured(QString error, QString detail);
|
||||||
|
void syncDone();
|
||||||
void connectionAdded(Connection* conn);
|
void connectionAdded(Connection* conn);
|
||||||
void connectionDropped(Connection* conn);
|
void connectionDropped(Connection* conn);
|
||||||
void initiated();
|
void initiated();
|
||||||
void notificationClicked(const QString roomId, const QString eventId);
|
void notificationClicked(const QString roomId, const QString eventId);
|
||||||
void quitOnLastWindowClosedChanged();
|
void quitOnLastWindowClosedChanged();
|
||||||
|
void connectionChanged();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void logout(Connection* conn);
|
void logout(Connection* conn);
|
||||||
|
|
Loading…
Reference in New Issue