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.
This commit is contained in:
miruka 2021-01-17 13:46:44 -04:00
parent 426faa2673
commit 4070b75544
6 changed files with 118 additions and 41 deletions

View File

@ -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:

View File

@ -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 ?
(`<b>${chat.roomInfo.display_name}</b>`) : ""
readonly property string topic:
@ -129,10 +135,10 @@ Rectangle {
text: name && topic ? (`${name}<br>${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
}
}
}

View File

@ -0,0 +1,17 @@
// Copyright Mirage authors & contributors <https://github.com/mirukana/mirage>
// 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 {} }
}

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m7 16h10v1h-10zm0-1h10v-1h-10zm15-13v22h-20v-22h3c1.229 0 2.18-1.084 3-2h8c.82.916 1.771 2 3 2zm-11 1c0 .552.448 1 1 1s1-.448 1-1-.448-1-1-1-1 .448-1 1zm9 1h-4l-2 2h-3.898l-2.102-2h-4v18h16zm-13 9h10v-1h-10zm0-2h10v-1h-10z"/>
</svg>

After

Width:  |  Height:  |  Size: 330 B

View File

@ -0,0 +1,3 @@
<svg height="24" viewBox="0 0 24 24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m23 20.168-8.185-8.187 8.185-8.174-2.832-2.807-8.182 8.179-8.176-8.179-2.81 2.81 8.186 8.196-8.186 8.184 2.81 2.81 8.203-8.192 8.18 8.192z"/>
</svg>

After

Width:  |  Height:  |  Size: 246 B

View File

@ -0,0 +1,3 @@
<svg clip-rule="evenodd" fill-rule="evenodd" height="24" width="24" xmlns="http://www.w3.org/2000/svg">
<path d="m5.662 23-5.369-5.365c-.195-.195-.293-.45-.293-.707 0-.256.098-.512.293-.707l14.929-14.928c.195-.194.451-.293.707-.293.255 0 .512.099.707.293l7.071 7.073c.196.195.293.451.293.708 0 .256-.097.511-.293.707l-11.216 11.219h5.514v2zm3.657-2-5.486-5.486-1.419 1.414 4.076 4.072zm6.605-17.581-10.677 10.68 5.658 5.659 10.676-10.682z"/>
</svg>

After

Width:  |  Height:  |  Size: 453 B