diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-12-11 06:10:41 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2021-12-11 06:10:41 +0100 |
commit | 75b112f0c830dd3a87d1c428a8ad5a8449b8e924 (patch) | |
tree | a04f054b0965e62cefb0527d0368aabb7a879e15 /resources | |
parent | Fix escaped html showing up in playable media message labels (diff) | |
download | nheko-75b112f0c830dd3a87d1c428a8ad5a8449b8e924.tar.xz |
Support pinned messages
fixes #519
Diffstat (limited to 'resources')
-rw-r--r-- | resources/icons/ui/pin-off.svg | 1 | ||||
-rw-r--r-- | resources/icons/ui/pin.svg | 1 | ||||
-rw-r--r-- | resources/qml/MessageView.qml | 7 | ||||
-rw-r--r-- | resources/qml/TopBar.qml | 137 | ||||
-rw-r--r-- | resources/qml/delegates/MessageDelegate.qml | 48 | ||||
-rw-r--r-- | resources/qml/delegates/Reply.qml | 4 | ||||
-rw-r--r-- | resources/res.qrc | 2 |
7 files changed, 187 insertions, 13 deletions
diff --git a/resources/icons/ui/pin-off.svg b/resources/icons/ui/pin-off.svg new file mode 100644 index 00000000..598610ad --- /dev/null +++ b/resources/icons/ui/pin-off.svg @@ -0,0 +1 @@ +<svg width="32" height="32" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="M3.28 2.22a.75.75 0 0 0-1.06 1.06l5.905 5.905L4.81 10.33a1.25 1.25 0 0 0-.476 2.065L7.439 15.5 3 19.94V21h1.06l4.44-4.44 3.105 3.105a1.25 1.25 0 0 0 2.065-.476l1.145-3.313 5.905 5.904a.75.75 0 0 0 1.06-1.06L3.28 2.22Zm10.355 12.476-1.252 3.626-6.705-6.705 3.626-1.252 4.331 4.331Zm6.048-3.876-3.787 1.894 1.118 1.118 3.34-1.67a2.75 2.75 0 0 0 .714-4.404l-4.825-4.826a2.75 2.75 0 0 0-4.405.715l-1.67 3.34 1.118 1.117 1.894-3.787a1.25 1.25 0 0 1 2.002-.325l4.826 4.826a1.25 1.25 0 0 1-.325 2.002Z" fill="#212121"/></svg> diff --git a/resources/icons/ui/pin.svg b/resources/icons/ui/pin.svg new file mode 100644 index 00000000..76d1124d --- /dev/null +++ b/resources/icons/ui/pin.svg @@ -0,0 +1 @@ +<svg width="32" height="32" fill="none" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m16.242 2.932 4.826 4.826a2.75 2.75 0 0 1-.715 4.404l-4.87 2.435a.75.75 0 0 0-.374.426l-1.44 4.166a1.25 1.25 0 0 1-2.065.476L8.5 16.561 4.06 21H3v-1.06l4.44-4.44-3.105-3.104a1.25 1.25 0 0 1 .476-2.066l4.166-1.44a.75.75 0 0 0 .426-.373l2.435-4.87a2.75 2.75 0 0 1 4.405-.715Zm3.766 5.886-4.826-4.826a1.25 1.25 0 0 0-2.002.325l-2.435 4.871a2.25 2.25 0 0 1-1.278 1.12l-3.789 1.31 6.705 6.704 1.308-3.789a2.25 2.25 0 0 1 1.12-1.277l4.872-2.436a1.25 1.25 0 0 0 .325-2.002Z" fill="#212121"/></svg> diff --git a/resources/qml/MessageView.qml b/resources/qml/MessageView.qml index 2acdf839..375b4017 100644 --- a/resources/qml/MessageView.qml +++ b/resources/qml/MessageView.qml @@ -583,6 +583,13 @@ ScrollView { } Platform.MenuItem { + visible: (room ? room.permissions.canChange(MtxEvent.PinnedEvents) : false) + enabled: visible + text: visible && room.pinnedMessages.includes(messageContextMenu.eventId) ? qsTr("Un&pin") : qsTr("&Pin") + onTriggered: visible && room.pinnedMessages.includes(messageContextMenu.eventId) ? room.unpin(messageContextMenu.eventId) : room.pin(messageContextMenu.eventId) + } + + Platform.MenuItem { text: qsTr("Read receip&ts") onTriggered: room.showReadReceipts(messageContextMenu.eventId) } diff --git a/resources/qml/TopBar.qml b/resources/qml/TopBar.qml index 53acdc39..ef12eaf7 100644 --- a/resources/qml/TopBar.qml +++ b/resources/qml/TopBar.qml @@ -8,6 +8,8 @@ import QtQuick.Controls 2.15 import QtQuick.Layouts 1.2 import im.nheko 1.0 +import "./delegates" + Rectangle { id: topBar @@ -28,6 +30,19 @@ Rectangle { TapHandler { onSingleTapped: { + if (eventPoint.position.y > topBar.height - pinnedMessages.height) { + eventPoint.accepted = true + return; + } + if (showBackButton && eventPoint.position.x < Nheko.paddingMedium + backToRoomsButton.width) { + eventPoint.accepted = true + return; + } + if (eventPoint.position.x > topBar.width - Nheko.paddingMedium - roomOptionsButton.width) { + eventPoint.accepted = true + return; + } + if (room) { let p = topBar.mapToItem(roomTopicC, eventPoint.position.x, eventPoint.position.y); let link = roomTopicC.linkAt(p.x, p.y); @@ -46,11 +61,11 @@ Rectangle { HoverHandler { grabPermissions: PointerHandler.TakeOverForbidden | PointerHandler.CanTakeOverFromAnything - //cursorShape: Qt.PointingHandCursor } CursorShape { anchors.fill: parent + anchors.bottomMargin: pinnedMessages.height cursorShape: Qt.PointingHandCursor } @@ -61,6 +76,8 @@ Rectangle { anchors.right: parent.right anchors.margins: Nheko.paddingMedium anchors.verticalCenter: parent.verticalCenter + columnSpacing: Nheko.paddingSmall + rowSpacing: Nheko.paddingSmall ImageButton { id: backToRoomsButton @@ -129,24 +146,54 @@ Rectangle { trust: trustlevel ToolTip.text: { if (!encrypted) - return qsTr("This room is not encrypted!"); + return qsTr("This room is not encrypted!"); switch (trust) { - case Crypto.Verified: + case Crypto.Verified: return qsTr("This room contains only verified devices."); - case Crypto.TOFU: + case Crypto.TOFU: return qsTr("This room contains verified devices and devices which have never changed their master key."); - default: + default: return qsTr("This room contains unverified devices!"); } } } ImageButton { + id: pinButton + + property bool pinsShown: !Settings.hiddenPins.includes(roomId) + + visible: !!room && room.pinnedMessages.length > 0 + Layout.column: 4 + Layout.row: 0 + Layout.rowSpan: 2 + Layout.alignment: Qt.AlignVCenter + Layout.preferredHeight: Nheko.avatarSize - Nheko.paddingMedium + Layout.preferredWidth: Nheko.avatarSize - Nheko.paddingMedium + image: pinsShown ? ":/icons/icons/ui/pin.svg" : ":/icons/icons/ui/pin-off.svg" + ToolTip.visible: hovered + ToolTip.text: qsTr("Show or hide pinned messages") + onClicked: { + var ps = Settings.hiddenPins; + if (pinsShown) { + ps.push(roomId); + } else { + const index = ps.indexOf(roomId); + if (index > -1) { + ps.splice(index, 1); + } + } + Settings.hiddenPins = ps; + } + + } + + ImageButton { id: roomOptionsButton visible: !!room - Layout.column: 4 + Layout.column: 5 Layout.row: 0 Layout.rowSpan: 2 Layout.alignment: Qt.AlignVCenter @@ -185,11 +232,79 @@ Rectangle { } - } + ScrollView { + id: pinnedMessages - CursorShape { - anchors.fill: parent - cursorShape: Qt.PointingHandCursor - } + Layout.row: 2 + Layout.column: 2 + Layout.columnSpan: 1 + + Layout.fillWidth: true + Layout.preferredHeight: Math.min(contentHeight, Nheko.avatarSize * 4) + + visible: !!room && room.pinnedMessages.length > 0 && !Settings.hiddenPins.includes(roomId) + clip: true + + palette: Nheko.colors + ScrollBar.horizontal.visible: false + + ListView { + + spacing: Nheko.paddingSmall + model: room ? room.pinnedMessages : undefined + delegate: RowLayout { + required property string modelData + + width: ListView.view.width + height: implicitHeight + Reply { + property var e: room ? room.getDump(modelData, "") : {} + Layout.fillWidth: true + Layout.preferredHeight: height + + userColor: TimelineManager.userColor(e.userId, Nheko.colors.window) + blurhash: e.blurhash ?? "" + body: e.body ?? "" + formattedBody: e.formattedBody ?? "" + eventId: e.eventId ?? "" + filename: e.filename ?? "" + filesize: e.filesize ?? "" + proportionalHeight: e.proportionalHeight ?? 1 + type: e.type ?? MtxEvent.UnknownMessage + typeString: e.typeString ?? "" + url: e.url ?? "" + originalWidth: e.originalWidth ?? 0 + isOnlyEmoji: e.isOnlyEmoji ?? false + userId: e.userId ?? "" + userName: e.userName ?? "" + encryptionError: e.encryptionError ?? "" + } + + ImageButton { + id: deletePinButton + + Layout.preferredHeight: 16 + Layout.preferredWidth: 16 + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + visible: room.permissions.canChange(MtxEvent.PinnedEvents) + + hoverEnabled: true + image: ":/icons/icons/ui/dismiss.svg" + ToolTip.visible: hovered + ToolTip.text: qsTr("Unpin") + + onClicked: room.unpin(modelData) + } + } + + + ScrollHelper { + flickable: parent + anchors.fill: parent + enabled: !Settings.mobileMode + } + } + } + } } diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index dc88cf24..74f7d011 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -240,6 +240,54 @@ Item { } DelegateChoice { + roleValue: MtxEvent.PinnedEvents + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + formatted: qsTr("%1 changed the pinned messages.").arg(d.userName) + } + + } + + DelegateChoice { + roleValue: MtxEvent.ImagePackInRoom + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + formatted: qsTr("%1 changed the stickers and emotes in this room.").arg(d.userName) + } + + } + + DelegateChoice { + roleValue: MtxEvent.CanonicalAlias + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + formatted: qsTr("%1 changed the addresses for this room.").arg(d.userName) + } + + } + + DelegateChoice { + roleValue: MtxEvent.SpaceParent + + NoticeMessage { + body: formatted + isOnlyEmoji: false + isReply: d.isReply + formatted: qsTr("%1 changed the parent spaces for this room.").arg(d.userName) + } + + } + + DelegateChoice { roleValue: MtxEvent.RoomCreate NoticeMessage { diff --git a/resources/qml/delegates/Reply.qml b/resources/qml/delegates/Reply.qml index 4e973c3d..547044f3 100644 --- a/resources/qml/delegates/Reply.qml +++ b/resources/qml/delegates/Reply.qml @@ -60,7 +60,7 @@ Item { TapHandler { acceptedButtons: Qt.LeftButton - onSingleTapped: chat.model.showEvent(r.eventId) + onSingleTapped: room.showEvent(r.eventId) gesturePolicy: TapHandler.ReleaseWithinBounds } @@ -79,7 +79,7 @@ Item { textFormat: Text.RichText TapHandler { - onSingleTapped: chat.model.openUserProfile(userId) + onSingleTapped: room.openUserProfile(userId) gesturePolicy: TapHandler.ReleaseWithinBounds } diff --git a/resources/res.qrc b/resources/res.qrc index 2ab60e3a..67c35351 100644 --- a/resources/res.qrc +++ b/resources/res.qrc @@ -23,6 +23,8 @@ <file>icons/ui/pause-symbol.svg</file> <file>icons/ui/people.svg</file> <file>icons/ui/picture-in-picture.svg</file> + <file>icons/ui/pin-off.svg</file> + <file>icons/ui/pin.svg</file> <file>icons/ui/place-call.svg</file> <file>icons/ui/play-sign.svg</file> <file>icons/ui/power-off.svg</file> |