diff --git a/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml b/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml index f3a53c517..544dab3d1 100644 --- a/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml +++ b/imports/Spectral/Menu/Timeline/MessageDelegateContextMenu.qml @@ -1,38 +1,76 @@ +/** + * SPDX-FileCopyrightText: 2019 Black Hat + * SPDX-FileCopyrightText: 2020 Carl Schwan + * + * SPDX-LicenseIdentifier: GPL-3.0-only + */ import QtQuick 2.12 -import QtQuick.Controls 2.12 +import QtQuick.Controls 2.12 as QQC2 +import QtQuick.Layouts 1.12 +import org.kde.kirigami 2.13 as Kirigami import Spectral.Dialog 2.0 -Menu { - readonly property string selectedText: contentLabel.selectedText - - signal viewSource() - signal reply() - signal redact() - +Kirigami.OverlaySheet { id: root - Item { - width: parent.width - height: 32 + required property var author; + required property string message; + signal viewSource() + signal reply(var author, string message) + signal remove() + + parent: applicationWindow().overlay + + leftPadding: 0 + rightPadding: 0 + + ColumnLayout { + spacing: 0 + QQC2.Control { + leftPadding: Kirigami.Units.largeSpacing + rightPadding: Kirigami.Units.largeSpacing + Layout.fillWidth: true + implicitHeight: headerLayout.implicitHeight + contentItem: RowLayout { + id: headerLayout + Layout.fillWidth: true + spacing: Kirigami.Units.largeSpacing + Kirigami.Avatar { + source: author.avatarMediaId ? "image://mxc/" + author.avatarMediaId : "" + Layout.preferredWidth: Kirigami.Units.iconSizes.large + Layout.preferredHeight: Kirigami.Units.iconSizes.large + Layout.alignment: Qt.AlignTop + } + ColumnLayout { + Layout.fillWidth: true + Kirigami.Heading { + level: 3 + Layout.fillWidth: true + text: author.displayName + } + QQC2.Label { + text: message + Layout.fillWidth: true + } + } + } + } Row { - anchors.centerIn: parent - spacing: 0 - Repeater { model: ["👍", "👎️", "😄", "🎉", "🚀", "👀"] - - delegate: ItemDelegate { + delegate: QQC2.ItemDelegate { width: 32 height: 32 - contentItem: Label { + contentItem: QQC2.Label { horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter font.pixelSize: 16 + font.family: "emoji" text: modelData } @@ -40,27 +78,34 @@ Menu { } } } + Kirigami.BasicListItem { + action: Kirigami.Action { + text: i18n("Reply") + icon.name: "reply" + onTriggered: reply(author, message) + } + } + Kirigami.BasicListItem { + action: Kirigami.Action { + text: i18n("Remove") + icon.name: "edit-delete-remove" + icon.color: "red" + onTriggered: remove() + } + } + Kirigami.BasicListItem { + action: Kirigami.Action { + text: i18n("Copy") + icon.name: "copy" + onTriggered: Clibpoard.setText(message) + } + } + Kirigami.BasicListItem { + action: Kirigami.Action { + text: i18n("View Source") + icon.name: "code-context" + onTriggered: viewSource() + } + } } - - MenuSeparator {} - - MenuItem { - text: "View Source" - - onTriggered: viewSource() - } - - MenuItem { - text: "Reply" - - onTriggered: reply() - } - - MenuItem { - text: "Redact" - - onTriggered: redact() - } - - onClosed: destroy() } diff --git a/qml/ChatTextInput.qml b/qml/ChatTextInput.qml index 8fe756670..204de11f0 100644 --- a/qml/ChatTextInput.qml +++ b/qml/ChatTextInput.qml @@ -16,10 +16,9 @@ Control { property alias isReply: replyItem.visible property bool isReaction: false - property var replyModel - readonly property var replyUser: replyModel ? replyModel.author : null - readonly property string replyEventID: replyModel ? replyModel.eventId : "" - readonly property string replyContent: replyModel ? replyModel.display : "" + property var replyUser + property string replyEventID + property string replyContent property alias isAutoCompleting: autoCompleteListView.visible property var autoCompleteModel @@ -75,10 +74,7 @@ Control { Label { Layout.alignment: Qt.AlignVCenter - text: replyUser ? replyUser.displayName : "No name" - color: "white" - font.weight: Font.Medium rightPadding: 8 } } @@ -417,6 +413,7 @@ Control { messageEventType = RoomMessageEvent.Notice } + console.log(replyContent, replyUser, replyEventID, messageEventType); currentRoom.postArbitaryMessage(text, messageEventType, replyEventID) } } @@ -444,7 +441,9 @@ Control { function clearReply() { isReply = false - replyModel = null + replyUser = null; + replyContent = ""; + replyEventID = "" } function focus() { diff --git a/qml/RoomPage.qml b/qml/RoomPage.qml index d1c48e3f7..d6540c306 100644 --- a/qml/RoomPage.qml +++ b/qml/RoomPage.qml @@ -105,6 +105,7 @@ Kirigami.ScrollablePage { id: messageListView spacing: Kirigami.Units.smallSpacing + clip: true displayMarginBeginning: 100 displayMarginEnd: 100 @@ -152,6 +153,7 @@ Kirigami.ScrollablePage { // } delegate: DelegateChooser { + id: timelineDelegateChooser role: "eventType" DelegateChoice { @@ -182,11 +184,16 @@ Kirigami.ScrollablePage { roleValue: "message" delegate: TimelineContainer { width: messageListView.width - + MouseArea { + acceptedButtons: Qt.RightButton + anchors.fill: parent + onClicked: openMessageContext(author, display, eventId, toolTip); + } innerObject: MessageDelegate { Layout.fillWidth: true Layout.maximumWidth: messageListView.width + innerObject: TextDelegate { Layout.fillWidth: true } @@ -292,4 +299,42 @@ Kirigami.ScrollablePage { } background: Item {} + + function openMessageContext(author, message, eventId, toolTip, model) { + const contextMenu = messageDelegateContextMenu.createObject(root, { + 'author': author, + 'message': message + }); + contextMenu.viewSource.connect(function() { + messageSourceDialog.createObject(root, { + 'sourceText': toolTip, + }).open(); + contextMenu.close(); + }); + contextMenu.reply.connect(function(replyUser, replyContent) { + chatTextInput.replyUser = replyUser; + chatTextInput.replyEventID = eventId; + chatTextInput.replyContent = replyContent; + chatTextInput.isReply = true; + chatTextInput.focus(); + contextMenu.close(); + }) + contextMenu.remove.connect(function() { + currentRoom.redactEvent(eventId); + contextMenu.close(); + }) + contextMenu.open() + } + + Component { + id: messageDelegateContextMenu + + MessageDelegateContextMenu {} + } + + Component { + id: messageSourceDialog + + MessageSourceDialog {} + } }