From 4070b755445cc95d5e151d07aeedf84d6f3fe15b Mon Sep 17 00:00:00 2001 From: miruka Date: Sun, 17 Jan 2021 13:46:44 -0400 Subject: [PATCH] RoomHeader: add message selection info and actions When messages are selected in the timeline, change the chat header's mode to show how many messages are selected and offer copy, remove and deselect buttons. --- docs/TODO.md | 1 - src/gui/Pages/Chat/RoomHeader.qml | 132 +++++++++++++++++------- src/gui/Pages/Chat/RoomHeaderButton.qml | 17 +++ src/icons/thin/room-header-copy.svg | 3 + src/icons/thin/room-header-deselect.svg | 3 + src/icons/thin/room-header-remove.svg | 3 + 6 files changed, 118 insertions(+), 41 deletions(-) create mode 100644 src/gui/Pages/Chat/RoomHeaderButton.qml create mode 100644 src/icons/thin/room-header-copy.svg create mode 100644 src/icons/thin/room-header-deselect.svg create mode 100644 src/icons/thin/room-header-remove.svg diff --git a/docs/TODO.md b/docs/TODO.md index 3ba8285e..7a674112 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -190,7 +190,6 @@ - Option to export-logout-login-import to fix one-time key problems - Cross-signing -- Display read receipts on events (who/how many people have read an event) - Fully read markers - Methods of signing in that aren't handled yet: diff --git a/src/gui/Pages/Chat/RoomHeader.qml b/src/gui/Pages/Chat/RoomHeader.qml index 09e7ae1b..0a493ac4 100644 --- a/src/gui/Pages/Chat/RoomHeader.qml +++ b/src/gui/Pages/Chat/RoomHeader.qml @@ -6,15 +6,16 @@ import QtQuick.Layouts 1.12 import "../../Base" Rectangle { - readonly property bool showLeftButton: - mainUI.mainPane.collapse || mainUI.mainPane.forceCollapse - - readonly property bool showRightButton: - chat.roomPane && - (chat.roomPane.collapse || chat.roomPane.forceCollapse) + id: root readonly property bool center: - showLeftButton || window.settings.Chat.always_center_header + goToMainPaneButton.show || window.settings.Chat.always_center_header + + readonly property HListView eventList: chatPage.eventList.eventList + readonly property int selected: + eventList.selectedCount === 1 && eventList.selectedText ? + 0 : + eventList.selectedCount implicitHeight: theme.baseElementsHeight color: theme.chat.roomHeader.background @@ -23,24 +24,20 @@ Rectangle { id: row anchors.fill: parent - HButton { + RoomHeaderButton { id: goToMainPaneButton + show: mainUI.mainPane.collapse || mainUI.mainPane.forceCollapse padded: false - visible: Layout.preferredWidth > 0 backgroundColor: "transparent" icon.name: "go-back-to-main-pane" toolTip.text: qsTr("Go back to main pane") - onClicked: mainUI.mainPane.toggleFocus() - Layout.preferredWidth: showLeftButton ? avatar.width : 0 - Layout.fillHeight: true - - Behavior on Layout.preferredWidth { HNumberAnimation {} } + Layout.preferredWidth: show ? avatar.width : 0 } HSpacer { - visible: center + visible: root.center } HRoomAvatar { @@ -55,26 +52,34 @@ Rectangle { } HLabel { - id: nameLabel - text: chat.roomInfo.display_name || qsTr("Empty room") - color: theme.chat.roomHeader.name + id: mainLabel + text: + root.selected === 0 ? + chat.roomInfo.display_name || qsTr("Empty room") : + root.selected === 1 ? + qsTr("%1 selected message").arg(root.selected) : + qsTr("%1 selected messages").arg(root.selected) + + color: theme.chat.roomHeader.name elide: Text.ElideRight verticalAlignment: Text.AlignVCenter leftPadding: theme.spacing rightPadding: leftPadding + // FIXME: these dirty manual calculations Layout.preferredWidth: Math.min( implicitWidth, row.width - - row.spacing - - (showLeftButton ? row.spacing : 0) - - (showRightButton ? row.spacing : 0) - goToMainPaneButton.width - avatar.width - encryptionStatusButton.width - + copyButton.width - + removeButton.width - + deselectButton.width - goToRoomPaneButton.width ) + Layout.fillWidth: ! topicLabel.text Layout.fillHeight: true HoverHandler { id: nameHover } @@ -82,28 +87,29 @@ Rectangle { HLabel { id: topicLabel - text: chat.roomInfo.topic + text: root.selected ? "" : chat.roomInfo.topic textFormat: Text.StyledText font.pixelSize: theme.fontSize.small color: theme.chat.roomHeader.topic elide: Text.ElideRight verticalAlignment: Text.AlignVCenter - rightPadding: nameLabel.rightPadding + rightPadding: mainLabel.rightPadding - Layout.preferredWidth: Math.min( + Layout.preferredWidth: ! text ? 0 : Math.min( implicitWidth, row.width - - row.spacing - - (showLeftButton ? row.spacing : 0) - - (showRightButton ? row.spacing : 0) - goToMainPaneButton.width - avatar.width - - nameLabel.width - + mainLabel.width - encryptionStatusButton.width - + copyButton.width - + removeButton.width - + deselectButton.width - goToRoomPaneButton.width ) - Layout.fillWidth: ! center + + Layout.fillWidth: text && ! root.center Layout.fillHeight: true HoverHandler { id: topicHover } @@ -118,7 +124,7 @@ Rectangle { HToolTip { readonly property string name: - nameLabel.truncated ? + mainLabel.truncated ? (`${chat.roomInfo.display_name}`) : "" readonly property string topic: @@ -129,10 +135,10 @@ Rectangle { text: name && topic ? (`${name}
${topic}`) : (name || topic) } - HButton { + RoomHeaderButton { id: encryptionStatusButton + show: chat.roomInfo.encrypted && ! root.selected padded: false - visible: Layout.preferredWidth > 0 backgroundColor: "transparent" icon.name: @@ -153,28 +159,74 @@ Rectangle { onClicked: toolTip.instantToggle() - Layout.preferredWidth: chat.roomInfo.encrypted ? avatar.width : 0 + Layout.preferredWidth: show ? avatar.width : 0 Layout.fillHeight: true + } - Behavior on Layout.preferredWidth { HNumberAnimation {} } + RoomHeaderButton { + id: copyButton + show: root.selected + icon.name: "room-header-copy" + toolTip.text: qsTr("Copy messages") + toolTip.onClosed: toolTip.text = qsTr("Copy messages") + + onClicked: { + root.eventList.copySelectedDelegates() + toolTip.text = qsTr("Copied messages") + toolTip.instantShow(2000) + } + } + + RoomHeaderButton { + id: removeButton + + readonly property var events: + root.eventList.redactableCheckedEvents + + show: root.selected + enabled: events.length > 0 + icon.name: "room-header-remove" + toolTip.text: qsTr("Remove messages") + + onClicked: utils.makePopup( + "Popups/RedactPopup.qml", + window, + { + preferUserId: chat.userId, + roomId: chat.roomId, + eventSenderAndIds: events.map(ev => [ev.sender_id, ev.id]), + onlyOwnMessageWarning: + ! chat.roomInfo.can_redact_all && + events.length < root.selected + }, + ) + } + + RoomHeaderButton { + id: deselectButton + show: root.selected + icon.name: "room-header-deselect" + toolTip.text: qsTr("Deselect messages") + onClicked: root.eventList.checked = [] } HSpacer { - visible: center + visible: root.center } - HButton { + RoomHeaderButton { id: goToRoomPaneButton + show: + chat.roomPane && + (chat.roomPane.collapse || chat.roomPane.forceCollapse) + padded: false - visible: Layout.preferredWidth > 0 backgroundColor: "transparent" icon.name: "go-to-room-pane" toolTip.text: qsTr("Go to room pane") - onClicked: chat.roomPane.toggleFocus() - Layout.preferredWidth: showRightButton ? avatar.width : 0 - Layout.fillHeight: true + Layout.preferredWidth: show ? avatar.width : 0 } } } diff --git a/src/gui/Pages/Chat/RoomHeaderButton.qml b/src/gui/Pages/Chat/RoomHeaderButton.qml new file mode 100644 index 00000000..11dce3b6 --- /dev/null +++ b/src/gui/Pages/Chat/RoomHeaderButton.qml @@ -0,0 +1,17 @@ +// Copyright Mirage authors & contributors +// SPDX-License-Identifier: LGPL-3.0-or-later + +import QtQuick 2.12 +import QtQuick.Layouts 1.12 +import "../../Base" + +HButton { + property bool show: true + + visible: Layout.preferredWidth > 0 + + Layout.preferredWidth: show ? implicitWidth : 0 + Layout.fillHeight: true + + Behavior on Layout.preferredWidth { HNumberAnimation {} } +} diff --git a/src/icons/thin/room-header-copy.svg b/src/icons/thin/room-header-copy.svg new file mode 100644 index 00000000..fc3a9c39 --- /dev/null +++ b/src/icons/thin/room-header-copy.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/thin/room-header-deselect.svg b/src/icons/thin/room-header-deselect.svg new file mode 100644 index 00000000..e4728028 --- /dev/null +++ b/src/icons/thin/room-header-deselect.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/icons/thin/room-header-remove.svg b/src/icons/thin/room-header-remove.svg new file mode 100644 index 00000000..d8b94628 --- /dev/null +++ b/src/icons/thin/room-header-remove.svg @@ -0,0 +1,3 @@ + + +