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:
parent
426faa2673
commit
4070b75544
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
17
src/gui/Pages/Chat/RoomHeaderButton.qml
Normal file
17
src/gui/Pages/Chat/RoomHeaderButton.qml
Normal 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 {} }
|
||||
}
|
3
src/icons/thin/room-header-copy.svg
Normal file
3
src/icons/thin/room-header-copy.svg
Normal 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 |
3
src/icons/thin/room-header-deselect.svg
Normal file
3
src/icons/thin/room-header-deselect.svg
Normal 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 |
3
src/icons/thin/room-header-remove.svg
Normal file
3
src/icons/thin/room-header-remove.svg
Normal 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 |
Loading…
Reference in New Issue
Block a user