diff --git a/imports/Spectral/Component/Emoji/EmojiPicker.qml b/imports/Spectral/Component/Emoji/EmojiPicker.qml index e7674f5..aa64a7b 100644 --- a/imports/Spectral/Component/Emoji/EmojiPicker.qml +++ b/imports/Spectral/Component/Emoji/EmojiPicker.qml @@ -39,10 +39,6 @@ Popup { text: modelData.unicode } - hoverEnabled: true - ToolTip.text: modelData.shortname - ToolTip.visible: hovered - onClicked: textArea.insert(textArea.cursorPosition, modelData.unicode) } @@ -82,10 +78,6 @@ Popup { text: label } - hoverEnabled: true - ToolTip.text: category - ToolTip.visible: hovered - onClicked: emojiCategory = category } } diff --git a/imports/Spectral/Effect/RippleEffect.qml b/imports/Spectral/Effect/RippleEffect.qml index 970a39c..4432e21 100644 --- a/imports/Spectral/Effect/RippleEffect.qml +++ b/imports/Spectral/Effect/RippleEffect.qml @@ -40,7 +40,7 @@ AutoMouseArea { QtObject { id: __private - property int startRadius: circular ? width/10 : width/6 + property int startRadius: 0 property int endRadius property bool showFocus: true diff --git a/imports/Spectral/Panel/RoomListPanel.qml b/imports/Spectral/Panel/RoomListPanel.qml index 83a1d72..f1cb284 100644 --- a/imports/Spectral/Panel/RoomListPanel.qml +++ b/imports/Spectral/Panel/RoomListPanel.qml @@ -142,6 +142,8 @@ Rectangle { RippleEffect { anchors.fill: parent + + onClicked: stackView.push(userPage) } } @@ -215,18 +217,223 @@ Rectangle { } } + Component { + id: userPage + + ScrollView { + readonly property string title: "User Info" + + id: main + + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff + + ColumnLayout { + width: main.width + spacing: 0 + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Matrix ID" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.user.id + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Name" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.user.name + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Avatar" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.user.avatarMediaId + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Server" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.controller.connection.accessToken + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Device" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.controller.connection.deviceId + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + + ItemDelegate { + Layout.fillWidth: true + + padding: 24 + + contentItem: ColumnLayout { + spacing: 0 + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: "Token" + font.pointSize: 12 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + + Label { + Layout.fillWidth: true + Layout.fillHeight: true + + text: root.controller.connection.accessToken + color: "#5B7480" + font.pointSize: 9.75 + elide: Text.ElideRight + wrapMode: Text.NoWrap + } + } + } + } + } + } + Component { id: settingsPage ScrollView { readonly property string title: "Settings" + id: main + ScrollBar.horizontal.policy: ScrollBar.AlwaysOff padding: 16 ColumnLayout { - width: parent.width + width: main.width spacing: 0 Switch { @@ -538,8 +745,6 @@ Rectangle { Layout.fillHeight: true Layout.alignment: Qt.AlignHCenter - visible: parent.width > 64 - Label { Layout.fillWidth: true Layout.fillHeight: true diff --git a/imports/Spectral/Panel/RoomPanel.qml b/imports/Spectral/Panel/RoomPanel.qml index d3e5a79..430d6dd 100644 --- a/imports/Spectral/Panel/RoomPanel.qml +++ b/imports/Spectral/Panel/RoomPanel.qml @@ -1,40 +1,331 @@ import QtQuick 2.9 +import QtQuick.Controls 2.2 +import QtQuick.Layouts 1.3 +import QtQuick.Controls.Material 2.2 -RoomPanelForm { - roomHeader.paintable: currentRoom ? currentRoom.paintable : null - roomHeader.topic: currentRoom ? (currentRoom.topic).replace(/(\r\n\t|\n|\r\t)/gm,"") : "" - roomHeader.atTop: messageListView.atYBeginning - roomHeader.onClicked: roomDrawer.open() +import Spectral.Component 2.0 +import Spectral.Component.Emoji 2.0 +import Spectral.Component.Timeline 2.0 +import Spectral.Menu 2.0 +import Spectral.Effect 2.0 - sortedMessageEventModel.onModelReset: { - if (currentRoom) { - var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex()) - messageListView.currentIndex = lastScrollPosition - if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20) - currentRoom.getPreviousContent(100) - } +import Spectral 0.1 +import Spectral.Setting 0.1 +import SortFilterProxyModel 0.2 + +import "qrc:/js/md.js" as Markdown +import "qrc:/js/util.js" as Util + +Item { + property var currentRoom: null + + id: root + + MessageEventModel { + id: messageEventModel + room: currentRoom } - messageListView { - property int largestVisibleIndex: messageListView.count > 0 ? messageListView.indexAt(messageListView.contentX, messageListView.contentY + messageListView.height - 1) : -1 + RoomDrawer { + width: Math.min(root.width * 0.7, 480) + height: root.height - onContentYChanged: { - if(currentRoom && messageListView.contentY - 5000 < messageListView.originY) - currentRoom.getPreviousContent(50); + id: roomDrawer + + room: currentRoom + } + + Label { + anchors.centerIn: parent + visible: !currentRoom + text: "Please choose a room." + } + + Image { + anchors.fill: parent + + visible: currentRoom + + source: MSettings.darkTheme ? "qrc:/assets/img/roompanel-dark.svg" : "qrc:/assets/img/roompanel.svg" + fillMode: Image.PreserveAspectCrop + } + + ColumnLayout { + anchors.fill: parent + spacing: 0 + + visible: currentRoom + + RoomHeader { + Layout.fillWidth: true + Layout.preferredHeight: 64 + z: 10 + + id: roomHeader + + paintable: currentRoom ? currentRoom.paintable : null + topic: currentRoom ? (currentRoom.topic).replace(/(\r\n\t|\n|\r\t)/gm,"") : "" + atTop: messageListView.atYBeginning + + onClicked: roomDrawer.open() } - onMovementEnded: currentRoom.saveViewport(sortedMessageEventModel.mapToSource(messageListView.indexAt(messageListView.contentX, messageListView.contentY)), sortedMessageEventModel.mapToSource(largestVisibleIndex)) + AutoListView { + Layout.fillWidth: true + Layout.maximumWidth: 960 + Layout.fillHeight: true + Layout.leftMargin: 16 + Layout.rightMargin: 16 + Layout.alignment: Qt.AlignHCenter - displaced: Transition { - NumberAnimation { - property: "y"; duration: 200 - easing.type: Easing.OutQuad + id: messageListView + + displayMarginBeginning: 100 + displayMarginEnd: 100 + verticalLayoutDirection: ListView.BottomToTop + spacing: 4 + + boundsBehavior: Flickable.DragOverBounds + + model: SortFilterProxyModel { + id: sortedMessageEventModel + + sourceModel: messageEventModel + + filters: ExpressionFilter { + expression: marks !== 0x08 && marks !== 0x10 && eventType !== "other" + } + + onModelReset: { + if (currentRoom) { + var lastScrollPosition = sortedMessageEventModel.mapFromSource(currentRoom.savedTopVisibleIndex()) + messageListView.currentIndex = lastScrollPosition + if (messageListView.contentY < messageListView.originY + 10 || currentRoom.timelineSize < 20) + currentRoom.getPreviousContent(100) + } + } + } + + property int largestVisibleIndex: count > 0 ? indexAt(contentX, contentY + height - 1) : -1 + + onContentYChanged: { + if(currentRoom && contentY - 5000 < originY) + currentRoom.getPreviousContent(50); + } + + onMovementEnded: currentRoom.saveViewport(sortedMessageEventModel.mapToSource(indexAt(contentX, contentY)), sortedMessageEventModel.mapToSource(largestVisibleIndex)) + + displaced: Transition { + NumberAnimation { + property: "y"; duration: 200 + easing.type: Easing.OutQuad + } + } + + delegate: ColumnLayout { + width: parent.width + + id: delegateColumn + + spacing: 4 + + SectionDelegate { + Layout.alignment: Qt.AlignHCenter + Layout.margins: 4 + + visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 + } + + MessageDelegate { + visible: eventType === "notice" || eventType === "message" + || eventType === "image" || eventType === "video" + || eventType === "audio" || eventType === "file" + } + + StateDelegate { + Layout.maximumWidth: parent.width + Layout.alignment: Qt.AlignHCenter + + visible: eventType === "emote" || eventType === "state" + } + + Label { + Layout.alignment: Qt.AlignHCenter + + visible: eventType === "other" + + text: display + color: "grey" + font.italic: true + } + + RowLayout { + Layout.fillWidth: true + Layout.alignment: Qt.AlignHCenter + + visible: readMarker === true + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 2 + + color: Material.accent + } + + Label { + text: "And Now" + color: Material.accent + verticalAlignment: Text.AlignVCenter + } + + Rectangle { + Layout.fillWidth: true + Layout.preferredHeight: 2 + + color: Material.accent + } + } + } + + RoundButton { + width: 64 + height: 64 + anchors.right: parent.right + anchors.top: parent.top + + id: goBottomFab + + visible: currentRoom && currentRoom.hasUnreadMessages + + contentItem: MaterialIcon { + anchors.fill: parent + + icon: "\ue316" + color: "white" + } + + Material.background: Material.accent + + onClicked: goToEvent(currentRoom.readMarkerEventId) + } + + RoundButton { + width: 64 + height: 64 + anchors.right: parent.right + anchors.bottom: parent.bottom + + id: goTopFab + + visible: !messageListView.atYEnd + + contentItem: MaterialIcon { + anchors.fill: parent + + icon: "\ue313" + color: "white" + } + + Material.background: Material.accent + + onClicked: messageListView.positionViewAtBeginning() + } + + MessageContextMenu { + id: messageContextMenu + } + + Popup { + property string sourceText + + x: (window.width - width) / 2 + y: (window.height - height) / 2 + width: 480 + + id: sourceDialog + + parent: ApplicationWindow.overlay + + modal: true + + padding: 16 + + closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside + + contentItem: ScrollView { + TextArea { + readOnly: true + selectByMouse: true + + text: sourceDialog.sourceText + } + } + } + + Popup { + property alias listModel: readMarkerListView.model + + x: (window.width - width) / 2 + y: (window.height - height) / 2 + width: 320 + + id: readMarkerDialog + + parent: ApplicationWindow.overlay + + modal: true + padding: 16 + + closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside + + contentItem: AutoListView { + implicitHeight: Math.min(window.height - 64, + readMarkerListView.contentHeight) + + id: readMarkerListView + + clip: true + boundsBehavior: Flickable.DragOverBounds + + delegate: ItemDelegate { + width: parent.width + height: 48 + + RowLayout { + anchors.fill: parent + anchors.margins: 8 + spacing: 12 + + ImageItem { + Layout.preferredWidth: height + Layout.fillHeight: true + + source: modelData.paintable + hint: modelData.displayName + } + + Label { + Layout.fillWidth: true + + text: modelData.displayName + } + } + } + + ScrollBar.vertical: ScrollBar {} + } } } - } - goBottomFab.onClicked: goToEvent(currentRoom.readMarkerEventId) - goTopFab.onClicked: messageListView.positionViewAtBeginning() + RoomPanelInput { + Layout.fillWidth: true + Layout.margins: 16 + Layout.maximumWidth: 960 + Layout.alignment: Qt.AlignHCenter + + id: roomPanelInput + } + } function goToEvent(eventID) { var index = messageEventModel.eventIDToIndex(eventID) diff --git a/imports/Spectral/Panel/RoomPanelForm.ui.qml b/imports/Spectral/Panel/RoomPanelForm.ui.qml deleted file mode 100644 index 3d37a87..0000000 --- a/imports/Spectral/Panel/RoomPanelForm.ui.qml +++ /dev/null @@ -1,309 +0,0 @@ -import QtQuick 2.9 -import QtQuick.Controls 2.2 -import QtQuick.Layouts 1.3 -import QtQuick.Controls.Material 2.2 - -import Spectral.Component 2.0 -import Spectral.Component.Emoji 2.0 -import Spectral.Component.Timeline 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/md.js" as Markdown -import "qrc:/js/util.js" as Util - -Item { - property var currentRoom: null - - property alias roomHeader: roomHeader - property alias messageListView: messageListView - property alias goTopFab: goTopFab - property alias goBottomFab: goBottomFab - property alias messageEventModel: messageEventModel - property alias sortedMessageEventModel: sortedMessageEventModel - property alias roomDrawer: roomDrawer - - id: root - - MessageEventModel { - id: messageEventModel - room: currentRoom - } - - RoomDrawer { - width: Math.min(root.width * 0.7, 480) - height: root.height - - id: roomDrawer - - room: currentRoom - } - - Label { - anchors.centerIn: parent - visible: !currentRoom - text: "Please choose a room." - } - - Image { - anchors.fill: parent - - visible: currentRoom - - source: MSettings.darkTheme ? "qrc:/assets/img/roompanel-dark.svg" : "qrc:/assets/img/roompanel.svg" - fillMode: Image.PreserveAspectCrop - } - - ColumnLayout { - anchors.fill: parent - spacing: 0 - - visible: currentRoom - - RoomHeader { - Layout.fillWidth: true - Layout.preferredHeight: 64 - z: 10 - - id: roomHeader - } - - AutoListView { - Layout.fillWidth: true - Layout.maximumWidth: 960 - Layout.fillHeight: true - Layout.leftMargin: 16 - Layout.rightMargin: 16 - Layout.alignment: Qt.AlignHCenter - - id: messageListView - - displayMarginBeginning: 100 - displayMarginEnd: 100 - verticalLayoutDirection: ListView.BottomToTop - spacing: 4 - - boundsBehavior: Flickable.DragOverBounds - - model: SortFilterProxyModel { - id: sortedMessageEventModel - - sourceModel: messageEventModel - - filters: ExpressionFilter { - expression: marks !== 0x08 && marks !== 0x10 && eventType !== "other" - } - } - - delegate: ColumnLayout { - width: parent.width - - id: delegateColumn - - spacing: 4 - - SectionDelegate { - Layout.alignment: Qt.AlignHCenter - Layout.margins: 4 - - visible: section !== aboveSection || Math.abs(time - aboveTime) > 600000 - } - - MessageDelegate { - visible: eventType === "notice" || eventType === "message" - || eventType === "image" || eventType === "video" - || eventType === "audio" || eventType === "file" - } - - StateDelegate { - Layout.maximumWidth: parent.width - Layout.alignment: Qt.AlignHCenter - - visible: eventType === "emote" || eventType === "state" - } - - Label { - Layout.alignment: Qt.AlignHCenter - - visible: eventType === "other" - - text: display - color: "grey" - font.italic: true - } - - RowLayout { - Layout.fillWidth: true - Layout.alignment: Qt.AlignHCenter - - visible: readMarker === true - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 2 - - color: Material.accent - } - - Label { - text: "And Now" - color: Material.accent - verticalAlignment: Text.AlignVCenter - } - - Rectangle { - Layout.fillWidth: true - Layout.preferredHeight: 2 - - color: Material.accent - } - } - } - - RoundButton { - width: 64 - height: 64 - anchors.right: parent.right - anchors.top: parent.top - - id: goBottomFab - - visible: currentRoom && currentRoom.hasUnreadMessages - - contentItem: MaterialIcon { - anchors.fill: parent - - icon: "\ue316" - color: "white" - } - - Material.background: Material.accent - } - - RoundButton { - width: 64 - height: 64 - anchors.right: parent.right - anchors.bottom: parent.bottom - - id: goTopFab - - visible: !messageListView.atYEnd - - contentItem: MaterialIcon { - anchors.fill: parent - - icon: "\ue313" - color: "white" - } - - Material.background: Material.accent - } - - MessageContextMenu { - id: messageContextMenu - } - - Popup { - property string sourceText - - x: (window.width - width) / 2 - y: (window.height - height) / 2 - width: 480 - - id: sourceDialog - - parent: ApplicationWindow.overlay - - modal: true - - padding: 16 - - closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside - - contentItem: ScrollView { - TextArea { - readOnly: true - selectByMouse: true - - text: sourceDialog.sourceText - } - } - } - - Popup { - property alias listModel: readMarkerListView.model - - x: (window.width - width) / 2 - y: (window.height - height) / 2 - width: 320 - - id: readMarkerDialog - - parent: ApplicationWindow.overlay - - modal: true - padding: 16 - - closePolicy: Dialog.CloseOnEscape | Dialog.CloseOnPressOutside - - contentItem: AutoListView { - implicitHeight: Math.min(window.height - 64, - readMarkerListView.contentHeight) - - id: readMarkerListView - - clip: true - boundsBehavior: Flickable.DragOverBounds - - delegate: ItemDelegate { - width: parent.width - height: 48 - - RowLayout { - anchors.fill: parent - anchors.margins: 8 - spacing: 12 - - ImageItem { - Layout.preferredWidth: height - Layout.fillHeight: true - - source: modelData.paintable - hint: modelData.displayName - } - - Label { - Layout.fillWidth: true - - text: modelData.displayName - } - } - } - - ScrollBar.vertical: ScrollBar { - } - } - } - } - - RoomPanelInput { - Layout.fillWidth: true - Layout.margins: 16 - Layout.maximumWidth: 960 - Layout.alignment: Qt.AlignHCenter - - id: roomPanelInput - } - } -} - - -/*##^## Designer { - D{i:0;autoSize:true;height:480;width:640} -} - ##^##*/ diff --git a/imports/Spectral/Panel/RoomPanelInput.qml b/imports/Spectral/Panel/RoomPanelInput.qml index 0af6030..2450b48 100644 --- a/imports/Spectral/Panel/RoomPanelInput.qml +++ b/imports/Spectral/Panel/RoomPanelInput.qml @@ -142,6 +142,7 @@ Control { property real progress: 0 Layout.fillWidth: true + Layout.minimumHeight: 48 id: inputField @@ -185,9 +186,13 @@ Control { onTriggered: currentRoom.sendTypingNotification(true) } - ToolTip.visible: currentRoom - && currentRoom.hasUsersTyping - ToolTip.text: currentRoom ? currentRoom.usersTyping : "" + ToolTip { + visible: currentRoom + && currentRoom.hasUsersTyping + text: currentRoom ? currentRoom.usersTyping : "" + + Material.foreground: "white" + } Keys.onReturnPressed: { if (event.modifiers & Qt.ShiftModifier) { diff --git a/include/libqmatrixclient b/include/libqmatrixclient index 3478e69..6f18091 160000 --- a/include/libqmatrixclient +++ b/include/libqmatrixclient @@ -1 +1 @@ -Subproject commit 3478e691df49b9c0938220db57b03a9c6fcbec8d +Subproject commit 6f18091a48530399908fbc6ebcb0697bae970abb diff --git a/res.qrc b/res.qrc index 224dd11..7b3a6aa 100644 --- a/res.qrc +++ b/res.qrc @@ -31,7 +31,6 @@ imports/Spectral/Panel/RoomDrawer.qml imports/Spectral/Panel/RoomListPanel.qml imports/Spectral/Panel/RoomPanel.qml - imports/Spectral/Panel/RoomPanelForm.ui.qml imports/Spectral/Panel/RoomHeader.qml imports/Spectral/Component/ScrollHelper.qml imports/Spectral/Component/AutoListView.qml diff --git a/src/main.cpp b/src/main.cpp index 804373f..fe6cc3e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -23,7 +23,9 @@ using namespace QMatrixClient; int main(int argc, char *argv[]) { +#if defined(Q_OS_WIN) QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling); +#endif QApplication app(argc, argv);