From 1142fe266344011b2529f3423071253b20d2f724 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Thu, 4 Mar 2021 22:59:10 +0100 Subject: [PATCH 1/4] Use overlay buttons for message actions --- resources/qml/EncryptionIndicator.qml | 30 ++---- resources/qml/MessageView.qml | 108 ++++++++++++++++++++++ resources/qml/TimelineRow.qml | 66 +++---------- resources/qml/delegates/NoticeMessage.qml | 2 - 4 files changed, 127 insertions(+), 79 deletions(-) diff --git a/resources/qml/EncryptionIndicator.qml b/resources/qml/EncryptionIndicator.qml index 00efe9e4..f2f9dec2 100644 --- a/resources/qml/EncryptionIndicator.qml +++ b/resources/qml/EncryptionIndicator.qml @@ -2,40 +2,24 @@ import QtQuick 2.12 import QtQuick.Controls 2.1 import im.nheko 1.0 -Rectangle { - id: indicator +Image { + id: stateImg property bool encrypted: false - function getEncryptionImage() { + width: 16 + height: 16 + source: { if (encrypted) return "image://colorimage/:/icons/icons/ui/lock.png?" + colors.buttonText; else return "image://colorimage/:/icons/icons/ui/unlock.png?#dd3d3d"; } - - function getEncryptionTooltip() { - if (encrypted) - return qsTr("Encrypted"); - else - return qsTr("This message is not encrypted!"); - } - - color: "transparent" - width: 16 - height: 16 - ToolTip.visible: ma.hovered && indicator.visible - ToolTip.text: getEncryptionTooltip() + ToolTip.visible: ma.hovered + ToolTip.text: encrypted ? qsTr("Encrypted") : qsTr("This message is not encrypted!") HoverHandler { id: ma } - Image { - id: stateImg - - anchors.fill: parent - source: getEncryptionImage() - } - } diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 0503f467..6c8a4917 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -1,4 +1,5 @@ import "./delegates" +import "./emoji" import QtGraphicalEffects 1.0 import QtQuick 2.12 import QtQuick.Controls 2.3 @@ -29,6 +30,95 @@ ScrollView { } + Rectangle { + //closePolicy: Popup.NoAutoClose + + id: messageActions + + property Item attached: null + property alias model: row.model + // use comma to update on scroll + property var attachedPos: chat.contentY, attached ? chat.mapFromItem(attached, attached ? attached.width - width : 0, -height) : null + property int padding: 4 + + visible: Settings.buttonsInTimeline && !!attached && (attached.hovered || messageActionHover.hovered) + x: attached ? attachedPos.x : 0 + y: attached ? attachedPos.y : 0 + z: 10 + height: row.implicitHeight + padding * 2 + width: row.implicitWidth + padding * 2 + color: colors.window + border.color: colors.buttonText + border.width: 1 + radius: padding + + HoverHandler { + id: messageActionHover + grabPermissions: PointerHandler.CanTakeOverFromAnything + } + + Row { + id: row + + property var model + + anchors.centerIn: parent + spacing: messageActions.padding + + ImageButton { + id: editButton + + visible: !!row.model && row.model.isEditable + buttonTextColor: colors.buttonText + width: 16 + hoverEnabled: true + image: ":/icons/icons/ui/edit.png" + ToolTip.visible: hovered + ToolTip.text: row.model && row.model.isEditable ? qsTr("Edit") : qsTr("Edited") + onClicked: { + if (row.model.isEditable) + chat.model.editAction(row.model.id); + + } + } + + EmojiButton { + id: reactButton + + width: 16 + hoverEnabled: true + ToolTip.visible: hovered + ToolTip.text: qsTr("React") + emojiPicker: emojiPopup + event_id: row.model ? row.model.id : "" + } + + ImageButton { + id: replyButton + + width: 16 + hoverEnabled: true + image: ":/icons/icons/ui/mail-reply.png" + ToolTip.visible: hovered + ToolTip.text: qsTr("Reply") + onClicked: chat.model.replyAction(row.model.id) + } + + ImageButton { + id: optionsButton + + width: 16 + hoverEnabled: true + image: ":/icons/icons/ui/vertical-ellipsis.png" + ToolTip.visible: hovered + ToolTip.text: qsTr("Options") + onClicked: messageContextMenu.show(row.model.id, row.model.type, row.model.isEncrypted, row.model.isEditable, optionsButton) + } + + } + + } + ScrollHelper { flickable: parent anchors.fill: parent @@ -203,7 +293,25 @@ ScrollView { TimelineRow { id: timelinerow + property alias hovered: hoverHandler.hovered + y: section.visible && section.active ? section.y + section.height : 0 + + HoverHandler { + id: hoverHandler + + enabled: !Settings.mobileMode + + onHoveredChanged: { + if (hovered) { + if (!messageActionHover.hovered) { + messageActions.attached = timelinerow; + messageActions.model = model; + } + } + } + } + } Connections { diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index b731d29d..8f58ea72 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -79,68 +79,26 @@ Item { encrypted: model.isEncrypted Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 - width: 16 + Layout.preferredWidth: 16 } - ImageButton { - id: editButton - - visible: (Settings.buttonsInTimeline && model.isEditable) || model.isEdited - buttonTextColor: chat.model.edit == model.id ? colors.highlight : colors.buttonText + Image { + visible: model.isEdited Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 + Layout.preferredWidth: 16 + height: 16 width: 16 - hoverEnabled: true - image: ":/icons/icons/ui/edit.png" - ToolTip.visible: hovered - ToolTip.text: model.isEditable ? qsTr("Edit") : qsTr("Edited") - onClicked: { - if (model.isEditable) - chat.model.editAction(model.id); + sourceSize.width: 16 + sourceSize.height: 16 + source: "image://colorimage/:/icons/icons/ui/edit.png?" + colors.buttonText + ToolTip.visible: editHovered.hovered + ToolTip.text: qsTr("Edited") + HoverHandler { + id: editHovered } - } - EmojiButton { - id: reactButton - - visible: Settings.buttonsInTimeline - Layout.alignment: Qt.AlignRight | Qt.AlignTop - Layout.preferredHeight: 16 - width: 16 - hoverEnabled: true - ToolTip.visible: hovered - ToolTip.text: qsTr("React") - emojiPicker: emojiPopup - event_id: model.id - } - - ImageButton { - id: replyButton - - visible: Settings.buttonsInTimeline - Layout.alignment: Qt.AlignRight | Qt.AlignTop - Layout.preferredHeight: 16 - width: 16 - hoverEnabled: true - image: ":/icons/icons/ui/mail-reply.png" - ToolTip.visible: hovered - ToolTip.text: qsTr("Reply") - onClicked: chat.model.replyAction(model.id) - } - - ImageButton { - id: optionsButton - - visible: Settings.buttonsInTimeline - Layout.alignment: Qt.AlignRight | Qt.AlignTop - Layout.preferredHeight: 16 - width: 16 - hoverEnabled: true - image: ":/icons/icons/ui/vertical-ellipsis.png" - ToolTip.visible: hovered - ToolTip.text: qsTr("Options") - onClicked: messageContextMenu.show(model.id, model.type, model.isEncrypted, model.isEditable, optionsButton) } Label { diff --git a/resources/qml/delegates/NoticeMessage.qml b/resources/qml/delegates/NoticeMessage.qml index c38cb555..4da644e2 100644 --- a/resources/qml/delegates/NoticeMessage.qml +++ b/resources/qml/delegates/NoticeMessage.qml @@ -1,6 +1,4 @@ TextMessage { font.italic: true color: colors.buttonText - height: isReply ? Math.min(timelineRoot.height / 8, implicitHeight) : undefined - clip: isReply } From e1c96569c1b4946c26b19c9c96183b74cb627590 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 5 Mar 2021 16:47:20 +0100 Subject: [PATCH 2/4] Fix janky hoverhandling for text messages Add a 1px border to get more hover enter events... --- resources/qml/MessageView.qml | 2 +- resources/qml/TimelineRow.qml | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 6c8a4917..a46fdda0 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -54,6 +54,7 @@ ScrollView { HoverHandler { id: messageActionHover + grabPermissions: PointerHandler.CanTakeOverFromAnything } @@ -301,7 +302,6 @@ ScrollView { id: hoverHandler enabled: !Settings.mobileMode - onHoveredChanged: { if (hovered) { if (!messageActionHover.hovered) { diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 8f58ea72..57d5d0ef 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -35,6 +35,7 @@ Item { RowLayout { id: row + anchors.rightMargin: 1 anchors.leftMargin: avatarSize + 16 anchors.left: parent.left anchors.right: parent.right @@ -43,6 +44,8 @@ Item { Layout.fillWidth: true Layout.alignment: Qt.AlignTop spacing: 4 + Layout.topMargin: 1 + Layout.bottomMargin: 1 // fancy reply, if this is a reply Reply { From 2685eec6c7c7f05a5454a8100dd04d3abf565794 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 5 Mar 2021 17:22:42 +0100 Subject: [PATCH 3/4] Mark message currently being edited --- resources/qml/TimelineRow.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 57d5d0ef..9d46e7ae 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -86,7 +86,7 @@ Item { } Image { - visible: model.isEdited + visible: model.isEdited || model.id == chat.model.edit Layout.alignment: Qt.AlignRight | Qt.AlignTop Layout.preferredHeight: 16 Layout.preferredWidth: 16 @@ -94,7 +94,7 @@ Item { width: 16 sourceSize.width: 16 sourceSize.height: 16 - source: "image://colorimage/:/icons/icons/ui/edit.png?" + colors.buttonText + source: "image://colorimage/:/icons/icons/ui/edit.png?" + ((model.id == chat.model.edit) ? colors.highlight : colors.buttonText) ToolTip.visible: editHovered.hovered ToolTip.text: qsTr("Edited") From e5cff644606008210a6443acc083aecb56be5c92 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Fri, 5 Mar 2021 17:44:49 +0100 Subject: [PATCH 4/4] Use short format for time --- resources/qml/TimelineRow.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 9d46e7ae..cea2da40 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -106,7 +106,7 @@ Item { Label { Layout.alignment: Qt.AlignRight | Qt.AlignTop - text: model.timestamp.toLocaleTimeString("HH:mm") + text: model.timestamp.toLocaleTimeString(Locale.ShortFormat) width: Math.max(implicitWidth, text.length * fontMetrics.maximumCharacterWidth) color: inactiveColors.text ToolTip.visible: ma.hovered