From 927a0aa01750ef15862ee1066171345ba7ef5385 Mon Sep 17 00:00:00 2001 From: Black Hat Date: Wed, 8 May 2019 21:15:09 +0800 Subject: [PATCH] Some more UI fine tuning in timeline and room list. This is a work-in-progress. --- .../Component/Timeline/FileDelegate.qml | 2 +- .../Component/Timeline/ImageDelegate.qml | 2 +- .../Component/Timeline/MessageDelegate.qml | 300 ++++++++---------- .../Component/Timeline/StateDelegate.qml | 2 +- imports/Spectral/Panel/RoomDrawer.qml | 14 + imports/Spectral/Panel/RoomHeader.qml | 64 ++-- imports/Spectral/Panel/RoomListPanel.qml | 12 +- imports/Spectral/Panel/RoomPanel.qml | 114 ++----- imports/Spectral/Setting/Palette.qml | 2 +- qtquickcontrols2.conf | 2 +- 10 files changed, 203 insertions(+), 311 deletions(-) diff --git a/imports/Spectral/Component/Timeline/FileDelegate.qml b/imports/Spectral/Component/Timeline/FileDelegate.qml index 81dc1b3..8dbaa75 100644 --- a/imports/Spectral/Component/Timeline/FileDelegate.qml +++ b/imports/Spectral/Component/Timeline/FileDelegate.qml @@ -118,7 +118,7 @@ ColumnLayout { } background: Rectangle { - color: MPalette.banner + color: MPalette.background radius: 18 AutoMouseArea { diff --git a/imports/Spectral/Component/Timeline/ImageDelegate.qml b/imports/Spectral/Component/Timeline/ImageDelegate.qml index 3d4b67b..43e8fa2 100644 --- a/imports/Spectral/Component/Timeline/ImageDelegate.qml +++ b/imports/Spectral/Component/Timeline/ImageDelegate.qml @@ -129,7 +129,7 @@ ColumnLayout { antialiasing: true border.width: 4 - border.color: MPalette.banner + border.color: MPalette.background } Rectangle { diff --git a/imports/Spectral/Component/Timeline/MessageDelegate.qml b/imports/Spectral/Component/Timeline/MessageDelegate.qml index 9d1ef6b..9a5a77f 100644 --- a/imports/Spectral/Component/Timeline/MessageDelegate.qml +++ b/imports/Spectral/Component/Timeline/MessageDelegate.qml @@ -11,214 +11,188 @@ import Spectral.Dialog 2.0 import Spectral.Menu.Timeline 2.0 import Spectral.Effect 2.0 -ColumnLayout { +RowLayout { readonly property bool avatarVisible: !sentByMe && (aboveAuthor !== author || aboveSection !== section || aboveEventType === "state" || aboveEventType === "emote" || aboveEventType === "other") readonly property bool sentByMe: author === currentRoom.localUser - property bool replyVisible: replyEventId || "" + readonly property bool darkBackground: !sentByMe + readonly property bool replyVisible: replyEventId || false signal saveFileAs() signal openExternally() - Layout.alignment: sentByMe ? Qt.AlignRight : Qt.AlignLeft - id: root - spacing: 0 + z: -5 - Label { - Layout.leftMargin: 48 + spacing: 4 - text: author.displayName + Avatar { + Layout.preferredWidth: 32 + Layout.preferredHeight: 32 + Layout.alignment: Qt.AlignTop visible: avatarVisible + hint: author.displayName + source: author.avatarMediaId - font.pixelSize: 13 - verticalAlignment: Text.AlignVCenter + Component { + id: userDetailDialog + + UserDetailDialog {} + } + + RippleEffect { + anchors.fill: parent + + circular: true + + onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": author}).open() + } } - RowLayout { - z: -5 + Item { + Layout.preferredWidth: 32 + Layout.preferredHeight: 32 - id: messageRow + visible: !(sentByMe || avatarVisible) + } - spacing: 4 + Control { + Layout.maximumWidth: messageListView.width - (!sentByMe ? 32 + root.spacing : 0) - 48 - Avatar { - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - Layout.alignment: Qt.AlignTop + verticalPadding: 8 + horizontalPadding: 16 - visible: avatarVisible - hint: author.displayName - source: author.avatarMediaId + background: Rectangle { + color: sentByMe ? MPalette.background : eventType === "notice" ? MPalette.primary : MPalette.accent + radius: 18 + antialiasing: true - Component { - id: userDetailDialog - - UserDetailDialog {} - } - - RippleEffect { + AutoMouseArea { anchors.fill: parent - circular: true + id: messageMouseArea - onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": author}).open() - } - } - - Label { - Layout.preferredWidth: 32 - Layout.preferredHeight: 32 - Layout.alignment: Qt.AlignTop - - visible: !(sentByMe || avatarVisible) - - text: Qt.formatDateTime(time, "hh:mm") - color: MPalette.lighter - - font.pixelSize: 10 - horizontalAlignment: Label.AlignHCenter - verticalAlignment: Label.AlignVCenter - } - - Control { - Layout.maximumWidth: messageListView.width - (!sentByMe ? 32 + messageRow.spacing : 0) - 48 - - verticalPadding: 8 - horizontalPadding: 16 - - background: Rectangle { - color: sentByMe ? "#009DC2" : eventType === "notice" ? "#4285F4" : "#673AB7" - radius: 18 - antialiasing: true - - AutoMouseArea { - anchors.fill: parent - - id: messageMouseArea - - onSecondaryClicked: { - var contextMenu = messageDelegateContextMenu.createObject(ApplicationWindow.overlay) - contextMenu.viewSource.connect(function() { - messageSourceDialog.createObject(ApplicationWindow.overlay, {"sourceText": toolTip}).open() - }) - contextMenu.reply.connect(function() { - roomPanelInput.replyUser = author - roomPanelInput.replyEventID = eventId - roomPanelInput.replyContent = contentLabel.selectedText || message - roomPanelInput.isReply = true - roomPanelInput.focus() - }) - contextMenu.redact.connect(function() { - currentRoom.redactEvent(eventId) - }) - contextMenu.popup() - } + onSecondaryClicked: { + var contextMenu = messageDelegateContextMenu.createObject(ApplicationWindow.overlay) + contextMenu.viewSource.connect(function() { + messageSourceDialog.createObject(ApplicationWindow.overlay, {"sourceText": toolTip}).open() + }) + contextMenu.reply.connect(function() { + roomPanelInput.replyUser = author + roomPanelInput.replyEventID = eventId + roomPanelInput.replyContent = contentLabel.selectedText || message + roomPanelInput.isReply = true + roomPanelInput.focus() + }) + contextMenu.redact.connect(function() { + currentRoom.redactEvent(eventId) + }) + contextMenu.popup() + } - Component { - id: messageDelegateContextMenu + Component { + id: messageDelegateContextMenu - MessageDelegateContextMenu {} - } + MessageDelegateContextMenu {} + } - Component { - id: messageSourceDialog + Component { + id: messageSourceDialog - MessageSourceDialog {} - } + MessageSourceDialog {} } } + } - contentItem: ColumnLayout { - RowLayout { + contentItem: ColumnLayout { + RowLayout { + Layout.fillWidth: true + + visible: replyVisible + + Avatar { + Layout.preferredWidth: 28 + Layout.preferredHeight: 28 + Layout.alignment: Qt.AlignTop + + source: replyVisible ? replyAuthor.avatarMediaId : "" + hint: replyVisible ? replyAuthor.displayName : "H" + + RippleEffect { + anchors.fill: parent + + circular: true + + onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open() + } + } + + Control { Layout.fillWidth: true - visible: replyVisible + padding: 0 - Avatar { - Layout.preferredWidth: 28 - Layout.preferredHeight: 28 - Layout.alignment: Qt.AlignTop - - source: replyVisible ? replyAuthor.avatarMediaId : "" - hint: replyVisible ? replyAuthor.displayName : "H" - - RippleEffect { - anchors.fill: parent - - circular: true - - onClicked: userDetailDialog.createObject(ApplicationWindow.overlay, {"room": currentRoom, "user": replyAuthor}).open() - } + background: RippleEffect { + onClicked: goToEvent(replyEventId) } - Control { + contentItem: Label { Layout.fillWidth: true - padding: 0 + visible: replyVisible + color: darkBackground ? "white" : MPalette.lighter + text: "" + (replyDisplay || "") - background: RippleEffect { - onClicked: goToEvent(replyEventId) - } + wrapMode: Label.Wrap + textFormat: Label.RichText + } + } + } - contentItem: Label { - Layout.fillWidth: true + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 1 - visible: replyVisible - color: "white" - text: "" + (replyDisplay || "") + visible: replyVisible + color: darkBackground ? "white" : MPalette.lighter + } - wrapMode: Label.Wrap - textFormat: Label.RichText - } + TextEdit { + Layout.fillWidth: true + + id: contentLabel + + text: "" + display + + color: darkBackground ? "white" : MPalette.foreground + + font.family: window.font.family + font.pixelSize: 14 + selectByMouse: true + readOnly: true + wrapMode: Label.Wrap + selectedTextColor: darkBackground ? MPalette.accent : "white" + selectionColor: darkBackground ? "white" : MPalette.accent + textFormat: Text.RichText + + onLinkActivated: { + if (link.startsWith("https://matrix.to/")) { + var result = link.replace(/\?.*/, "").match("https://matrix.to/#/(!.*:.*)/(\\$.*:.*)") + if (!result || result.length < 3) return + if (result[1] != currentRoom.id) return + if (!result[2]) return + goToEvent(result[2]) + } else { + Qt.openUrlExternally(link) } } - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 1 - - visible: replyVisible - color: "white" - } - - TextEdit { - Layout.fillWidth: true - - id: contentLabel - - text: "" + display - - color: "white" - - font.family: window.font.family - font.pixelSize: 14 - selectByMouse: true - readOnly: true - wrapMode: Label.Wrap - selectedTextColor: Material.accent - selectionColor: "white" - textFormat: Text.RichText - - onLinkActivated: { - if (link.startsWith("https://matrix.to/")) { - var result = link.replace(/\?.*/, "").match("https://matrix.to/#/(!.*:.*)/(\\$.*:.*)") - if (!result || result.length < 3) return - if (result[1] != currentRoom.id) return - if (!result[2]) return - goToEvent(result[2]) - } else { - Qt.openUrlExternally(link) - } - } - - MouseArea { - anchors.fill: parent - acceptedButtons: Qt.NoButton - cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor - } + MouseArea { + anchors.fill: parent + acceptedButtons: Qt.NoButton + cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor } } } diff --git a/imports/Spectral/Component/Timeline/StateDelegate.qml b/imports/Spectral/Component/Timeline/StateDelegate.qml index ca17279..c5ea823 100644 --- a/imports/Spectral/Component/Timeline/StateDelegate.qml +++ b/imports/Spectral/Component/Timeline/StateDelegate.qml @@ -21,7 +21,7 @@ Label { onLinkActivated: Qt.openUrlExternally(link) background: Rectangle { - color: MPalette.banner + color: MPalette.background radius: 4 antialiasing: true } diff --git a/imports/Spectral/Panel/RoomDrawer.qml b/imports/Spectral/Panel/RoomDrawer.qml index 3fc90fb..8d523d3 100644 --- a/imports/Spectral/Panel/RoomDrawer.qml +++ b/imports/Spectral/Panel/RoomDrawer.qml @@ -21,6 +21,12 @@ Drawer { anchors.fill: parent anchors.margins: 24 + Component { + id: fullScreenImage + + FullScreenImage {} + } + RowLayout { Layout.fillWidth: true @@ -32,6 +38,14 @@ Drawer { hint: room ? room.displayName : "No name" source: room ? room.avatarMediaId : null + + RippleEffect { + anchors.fill: parent + + circular: true + + onClicked: fullScreenImage.createObject(parent, {"filename": room.diaplayName, "localPath": room.urlToMxcUrl(room.avatarUrl)}).show() + } } ColumnLayout { diff --git a/imports/Spectral/Panel/RoomHeader.qml b/imports/Spectral/Panel/RoomHeader.qml index 1933426..a682f6c 100644 --- a/imports/Spectral/Panel/RoomHeader.qml +++ b/imports/Spectral/Panel/RoomHeader.qml @@ -9,17 +9,12 @@ import Spectral.Component 2.0 import Spectral.Setting 0.1 Control { - property alias avatar: headerImage.source - property alias topic: headerTopicLabel.text - property bool atTop: false signal clicked() id: header background: Rectangle { - color: Material.background - - opacity: atTop ? 0 : 1 + color: MPalette.background layer.enabled: true layer.effect: ElevationEffect { @@ -29,53 +24,32 @@ Control { RowLayout { anchors.fill: parent - anchors.margins: 12 + anchors.leftMargin: 18 + + Layout.alignment: Qt.AlignVCenter spacing: 12 - Avatar { + Label { + Layout.fillWidth: true + + text: currentRoom ? currentRoom.displayName : "" + color: MPalette.foreground + font.pixelSize: 18 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + ToolButton { Layout.preferredWidth: height Layout.fillHeight: true - id: headerImage - - source: currentRoom.avatarMediaId - hint: currentRoom ? currentRoom.displayName : "No name" - } - - ColumnLayout { - Layout.fillWidth: true - Layout.fillHeight: true - - visible: parent.width > 64 - - Label { - Layout.fillWidth: true - Layout.fillHeight: true - - text: currentRoom ? currentRoom.displayName : "" - color: MPalette.foreground - font.pixelSize: 16 - elide: Text.ElideRight - wrapMode: Text.NoWrap - } - - Label { - Layout.fillWidth: true - Layout.fillHeight: true - - id: headerTopicLabel - + contentItem: MaterialIcon { + icon: "\ue5d4" color: MPalette.lighter - elide: Text.ElideRight - wrapMode: Text.NoWrap } + + onClicked: header.clicked() } } - - RippleEffect { - anchors.fill: parent - - onClicked: header.clicked() - } } diff --git a/imports/Spectral/Panel/RoomListPanel.qml b/imports/Spectral/Panel/RoomListPanel.qml index 003bf85..00cf0b1 100644 --- a/imports/Spectral/Panel/RoomListPanel.qml +++ b/imports/Spectral/Panel/RoomListPanel.qml @@ -237,17 +237,6 @@ Item { opacity: 0.1 } - Rectangle { - width: unreadCount >= 0 ? 4 : 0 - height: parent.height - - color: Material.accent - - Behavior on width { - PropertyAnimation { easing.type: Easing.InOutCubic; duration: 200 } - } - } - RowLayout { anchors.fill: parent anchors.margins: 12 @@ -274,6 +263,7 @@ Item { text: name || "No Name" color: MPalette.foreground font.pixelSize: 16 + font.bold: unreadCount >= 0 elide: Text.ElideRight wrapMode: Text.NoWrap } diff --git a/imports/Spectral/Panel/RoomPanel.qml b/imports/Spectral/Panel/RoomPanel.qml index 0176e5c..78a930a 100644 --- a/imports/Spectral/Panel/RoomPanel.qml +++ b/imports/Spectral/Panel/RoomPanel.qml @@ -62,6 +62,14 @@ Item { fillMode: Image.PreserveAspectCrop } + Rectangle { + anchors.fill: parent + + visible: currentRoom && !MSettings.timelineBackground + + color: MSettings.darkTheme ? "#242424" : "#EBEFF2" + } + ColumnLayout { anchors.fill: parent spacing: 0 @@ -75,10 +83,6 @@ Item { id: roomHeader - avatar: currentRoom ? currentRoom.avatarMediaId : "" - topic: currentRoom ? (currentRoom.topic).replace(/(\r\n\t|\n|\r\t)/gm,"") : "" - atTop: messageListView.atYBeginning - onClicked: roomDrawer.visible ? roomDrawer.close() : roomDrawer.open() } @@ -86,10 +90,12 @@ Item { Layout.fillWidth: true Layout.fillHeight: true Layout.maximumWidth: 960 + Layout.alignment: Qt.AlignHCenter Layout.leftMargin: 16 Layout.rightMargin: 16 Layout.bottomMargin: 16 - Layout.alignment: Qt.AlignHCenter + + width: Math.min(parent.width - 32, 960) spacing: 16 @@ -147,113 +153,47 @@ Item { DelegateChoice { roleValue: "state" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 + delegate: StateDelegate { + anchors.horizontalCenter: parent.horizontalCenter - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - StateDelegate { - Layout.maximumWidth: parent.width - Layout.alignment: Qt.AlignHCenter - } + width: Math.min(implicitWidth, parent.width) } } DelegateChoice { roleValue: "emote" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 + delegate: StateDelegate { + anchors.horizontalCenter: parent.horizontalCenter - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - StateDelegate { - Layout.maximumWidth: parent.width - Layout.alignment: Qt.AlignHCenter - } + width: Math.min(implicitWidth, parent.width) } } DelegateChoice { roleValue: "message" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 - - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - MessageDelegate {} + delegate: MessageDelegate { + anchors.right: sentByMe ? parent.right : undefined } } DelegateChoice { roleValue: "notice" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 - - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - MessageDelegate {} + delegate: MessageDelegate { + anchors.right: sentByMe ? parent.right : undefined } } DelegateChoice { roleValue: "image" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 - - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - ImageDelegate { - Layout.maximumWidth: parent.width - } + delegate: ImageDelegate { + Layout.maximumWidth: parent.width } } DelegateChoice { roleValue: "file" - delegate: ColumnLayout { - width: messageListView.width - spacing: 4 - - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 16 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - FileDelegate { - Layout.maximumWidth: parent.width - } + delegate: FileDelegate { + Layout.maximumWidth: parent.width } } @@ -275,7 +215,7 @@ Item { rightPadding: 24 Material.foreground: MPalette.foreground - Material.background: MPalette.banner + Material.background: MPalette.background text: "Go to read marker" @@ -333,7 +273,7 @@ Item { } background: Rectangle { - color: MPalette.banner + color: MPalette.background radius: height / 2 } } diff --git a/imports/Spectral/Setting/Palette.qml b/imports/Spectral/Setting/Palette.qml index b959905..60489f6 100644 --- a/imports/Spectral/Setting/Palette.qml +++ b/imports/Spectral/Setting/Palette.qml @@ -6,7 +6,7 @@ QtObject { readonly property int theme: MSettings.darkTheme ? Material.Dark : Material.Light readonly property color primary: "#344955" - readonly property color accent: "#673AB7" + readonly property color accent: "#4286F5" readonly property color foreground: MSettings.darkTheme ? "#FFFFFF" : "#1D333E" readonly property color background: MSettings.darkTheme ? "#303030" : "#FFFFFF" readonly property color lighter: MSettings.darkTheme ? "#FFFFFF" : "#5B7480" diff --git a/qtquickcontrols2.conf b/qtquickcontrols2.conf index ecaa6b9..1cc3690 100644 --- a/qtquickcontrols2.conf +++ b/qtquickcontrols2.conf @@ -9,4 +9,4 @@ Style=Material Theme=Light Variant=Dense Primary=#344955 -Accent=#673AB7 +Accent=#4286F5