diff options
author | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-01-11 14:07:51 +0100 |
---|---|---|
committer | Nicolas Werner <nicolas.werner@hotmail.de> | 2020-01-11 14:07:51 +0100 |
commit | 2b3dc3d8b9d1108c3f6ad226ad65060bd3999033 (patch) | |
tree | 42419bdee5b28c98eaafb44724c64f351a275199 /resources/qml | |
parent | try to make appveyor happy (diff) | |
download | nheko-2b3dc3d8b9d1108c3f6ad226ad65060bd3999033.tar.xz |
Implement fancy reply rendering
This currently assumes the event, that is replied to, is already fetched. If it isn't, it will render an empty reply. In the future we should fetch replies before rendering them.
Diffstat (limited to 'resources/qml')
-rw-r--r-- | resources/qml/TimelineRow.qml | 61 | ||||
-rw-r--r-- | resources/qml/delegates/FileMessage.qml | 6 | ||||
-rw-r--r-- | resources/qml/delegates/ImageMessage.qml | 12 | ||||
-rw-r--r-- | resources/qml/delegates/MessageDelegate.qml | 128 | ||||
-rw-r--r-- | resources/qml/delegates/NoticeMessage.qml | 2 | ||||
-rw-r--r-- | resources/qml/delegates/Placeholder.qml | 2 | ||||
-rw-r--r-- | resources/qml/delegates/PlayableMediaMessage.qml | 16 | ||||
-rw-r--r-- | resources/qml/delegates/TextMessage.qml | 2 |
8 files changed, 145 insertions, 84 deletions
diff --git a/resources/qml/TimelineRow.qml b/resources/qml/TimelineRow.qml index 2c2ed02a..86780413 100644 --- a/resources/qml/TimelineRow.qml +++ b/resources/qml/TimelineRow.qml @@ -14,23 +14,70 @@ RowLayout { anchors.left: parent.left anchors.right: parent.right - height: Math.max(contentItem.height, 16) + //height: Math.max(model.replyTo ? reply.height + contentItem.height + 4 : contentItem.height, 16) Column { Layout.fillWidth: true Layout.alignment: Qt.AlignTop + spacing: 4 - //property var replyTo: model.replyTo + // fancy reply, if this is a reply + Rectangle { + visible: model.replyTo + width: parent.width + height: replyContainer.height + + Rectangle { + id: colorLine + height: replyContainer.height + width: 4 + color: chat.model.userColor(reply.modelData.userId, colors.window) + } + + Column { + id: replyContainer + anchors.left: colorLine.right + anchors.leftMargin: 4 + width: parent.width - 8 + + + Text { + id: userName + text: chat.model.escapeEmoji(reply.modelData.userName) + color: chat.model.userColor(reply.modelData.userId, colors.window) + textFormat: Text.RichText + + MouseArea { + anchors.fill: parent + onClicked: chat.model.openUserProfile(reply.modelData.userId) + cursorShape: Qt.PointingHandCursor + } + } + + MessageDelegate { + id: reply + width: parent.width - //Text { - // property int idx: timelineManager.timeline.idToIndex(replyTo) - // text: "" + (idx != -1 ? timelineManager.timeline.data(timelineManager.timeline.index(idx, 0), 2) : "nothing") - //} + modelData: chat.model.getDump(model.replyTo) + } + } + + color: { var col = chat.model.userColor(reply.modelData.userId, colors.window); col.a = 0.2; return col } + + MouseArea { + anchors.fill: parent + onClicked: chat.positionViewAtIndex(chat.model.idToIndex(model.replyTo), ListView.Contain) + cursorShape: Qt.PointingHandCursor + } + } + + // actual message content MessageDelegate { id: contentItem width: parent.width - height: childrenRect.height + + modelData: model } } diff --git a/resources/qml/delegates/FileMessage.qml b/resources/qml/delegates/FileMessage.qml index 2c911c5e..9a5300bb 100644 --- a/resources/qml/delegates/FileMessage.qml +++ b/resources/qml/delegates/FileMessage.qml @@ -31,7 +31,7 @@ Rectangle { } MouseArea { anchors.fill: parent - onClicked: timelineManager.timeline.saveMedia(model.id) + onClicked: timelineManager.timeline.saveMedia(model.data.id) cursorShape: Qt.PointingHandCursor } } @@ -40,14 +40,14 @@ Rectangle { Text { Layout.fillWidth: true - text: model.body + text: model.data.body textFormat: Text.PlainText elide: Text.ElideRight color: colors.text } Text { Layout.fillWidth: true - text: model.filesize + text: model.data.filesize textFormat: Text.PlainText elide: Text.ElideRight color: colors.text diff --git a/resources/qml/delegates/ImageMessage.qml b/resources/qml/delegates/ImageMessage.qml index 15ce29b7..3393f043 100644 --- a/resources/qml/delegates/ImageMessage.qml +++ b/resources/qml/delegates/ImageMessage.qml @@ -3,26 +3,26 @@ import QtQuick 2.6 import im.nheko 1.0 Item { - property double tempWidth: Math.min(parent ? parent.width : undefined, model.width) - property double tempHeight: tempWidth * model.proportionalHeight + property double tempWidth: Math.min(parent ? parent.width : undefined, model.data.width) + property double tempHeight: tempWidth * model.data.proportionalHeight property bool tooHigh: tempHeight > chat.height - 40 height: tooHigh ? chat.height - 40 : tempHeight - width: tooHigh ? (chat.height - 40) / model.proportionalHeight : tempWidth + width: tooHigh ? (chat.height - 40) / model.data.proportionalHeight : tempWidth Image { id: img anchors.fill: parent - source: model.url.replace("mxc://", "image://MxcImage/") + source: model.data.url.replace("mxc://", "image://MxcImage/") asynchronous: true fillMode: Image.PreserveAspectFit MouseArea { - enabled: model.type == MtxEvent.ImageMessage + enabled: model.data.type == MtxEvent.ImageMessage anchors.fill: parent - onClicked: timelineManager.openImageOverlay(model.url, model.id) + onClicked: timelineManager.openImageOverlay(model.data.url, model.data.id) } } } diff --git a/resources/qml/delegates/MessageDelegate.qml b/resources/qml/delegates/MessageDelegate.qml index 20ec71e5..1716d2d4 100644 --- a/resources/qml/delegates/MessageDelegate.qml +++ b/resources/qml/delegates/MessageDelegate.qml @@ -1,67 +1,81 @@ import QtQuick 2.6 import im.nheko 1.0 -DelegateChooser { - //role: "type" //< not supported in our custom implementation, have to use roleValue - roleValue: model.type - - DelegateChoice { - roleValue: MtxEvent.TextMessage - TextMessage {} - } - DelegateChoice { - roleValue: MtxEvent.NoticeMessage - NoticeMessage {} - } - DelegateChoice { - roleValue: MtxEvent.EmoteMessage - TextMessage {} - } - DelegateChoice { - roleValue: MtxEvent.ImageMessage - ImageMessage {} - } - DelegateChoice { - roleValue: MtxEvent.Sticker - ImageMessage {} - } - DelegateChoice { - roleValue: MtxEvent.FileMessage - FileMessage {} +Item { + // Workaround to have an assignable global property + Item { + id: model + property var data; } - DelegateChoice { - roleValue: MtxEvent.VideoMessage - PlayableMediaMessage {} - } - DelegateChoice { - roleValue: MtxEvent.AudioMessage - PlayableMediaMessage {} - } - DelegateChoice { - roleValue: MtxEvent.Redacted - Pill { - text: qsTr("redacted") + + property alias modelData: model.data + + height: chooser.childrenRect.height + + DelegateChooser { + id: chooser + //role: "type" //< not supported in our custom implementation, have to use roleValue + roleValue: model.data.type + anchors.fill: parent + + DelegateChoice { + roleValue: MtxEvent.TextMessage + TextMessage {} } - } - DelegateChoice { - roleValue: MtxEvent.Encryption - Pill { - text: qsTr("Encryption enabled") + DelegateChoice { + roleValue: MtxEvent.NoticeMessage + NoticeMessage {} } - } - DelegateChoice { - roleValue: MtxEvent.Name - NoticeMessage { - notice: model.roomName ? qsTr("room name changed to: %1").arg(model.roomName) : qsTr("removed room name") + DelegateChoice { + roleValue: MtxEvent.EmoteMessage + TextMessage {} } - } - DelegateChoice { - roleValue: MtxEvent.Topic - NoticeMessage { - notice: model.roomTopic ? qsTr("topic changed to: %1").arg(model.roomTopic) : qsTr("removed topic") + DelegateChoice { + roleValue: MtxEvent.ImageMessage + ImageMessage {} + } + DelegateChoice { + roleValue: MtxEvent.Sticker + ImageMessage {} + } + DelegateChoice { + roleValue: MtxEvent.FileMessage + FileMessage {} + } + DelegateChoice { + roleValue: MtxEvent.VideoMessage + PlayableMediaMessage {} + } + DelegateChoice { + roleValue: MtxEvent.AudioMessage + PlayableMediaMessage {} + } + DelegateChoice { + roleValue: MtxEvent.Redacted + Pill { + text: qsTr("redacted") + } + } + DelegateChoice { + roleValue: MtxEvent.Encryption + Pill { + text: qsTr("Encryption enabled") + } + } + DelegateChoice { + roleValue: MtxEvent.Name + NoticeMessage { + notice: model.data.roomName ? qsTr("room name changed to: %1").arg(model.data.roomName) : qsTr("removed room name") + } + } + DelegateChoice { + roleValue: MtxEvent.Topic + NoticeMessage { + notice: model.data.roomTopic ? qsTr("topic changed to: %1").arg(model.data.roomTopic) : qsTr("removed topic") + } + } + DelegateChoice { + Placeholder {} } - } - DelegateChoice { - Placeholder {} } } diff --git a/resources/qml/delegates/NoticeMessage.qml b/resources/qml/delegates/NoticeMessage.qml index f7467eca..34132bcf 100644 --- a/resources/qml/delegates/NoticeMessage.qml +++ b/resources/qml/delegates/NoticeMessage.qml @@ -1,7 +1,7 @@ import ".." MatrixText { - property string notice: model.formattedBody.replace("<pre>", "<pre style='white-space: pre-wrap'>") + property string notice: model.data.formattedBody.replace("<pre>", "<pre style='white-space: pre-wrap'>") text: notice width: parent ? parent.width : undefined font.italic: true diff --git a/resources/qml/delegates/Placeholder.qml b/resources/qml/delegates/Placeholder.qml index 4c0e68c3..36d7b2bc 100644 --- a/resources/qml/delegates/Placeholder.qml +++ b/resources/qml/delegates/Placeholder.qml @@ -1,7 +1,7 @@ import ".." MatrixText { - text: qsTr("unimplemented event: ") + model.type + text: qsTr("unimplemented event: ") + model.data.type width: parent ? parent.width : undefined color: inactiveColors.text } diff --git a/resources/qml/delegates/PlayableMediaMessage.qml b/resources/qml/delegates/PlayableMediaMessage.qml index b3275462..ebf7487c 100644 --- a/resources/qml/delegates/PlayableMediaMessage.qml +++ b/resources/qml/delegates/PlayableMediaMessage.qml @@ -19,12 +19,12 @@ Rectangle { Rectangle { id: videoContainer - visible: model.type == MtxEvent.VideoMessage - width: Math.min(parent.width, model.width ? model.width : 400) // some media has 0 as size... - height: width*model.proportionalHeight + visible: model.data.type == MtxEvent.VideoMessage + width: Math.min(parent.width, model.data.width ? model.data.width : 400) // some media has 0 as size... + height: width*model.data.proportionalHeight Image { anchors.fill: parent - source: model.thumbnailUrl.replace("mxc://", "image://MxcImage/") + source: model.data.thumbnailUrl.replace("mxc://", "image://MxcImage/") asynchronous: true fillMode: Image.PreserveAspectFit @@ -97,7 +97,7 @@ Rectangle { anchors.fill: parent onClicked: { switch (button.state) { - case "": timelineManager.timeline.cacheMedia(model.id); break; + case "": timelineManager.timeline.cacheMedia(model.data.id); break; case "stopped": media.play(); console.log("play"); button.state = "playing" @@ -120,7 +120,7 @@ Rectangle { Connections { target: timelineManager.timeline onMediaCached: { - if (mxcUrl == model.url) { + if (mxcUrl == model.data.url) { media.source = "file://" + cacheUrl button.state = "stopped" console.log("media loaded: " + mxcUrl + " at " + cacheUrl) @@ -145,14 +145,14 @@ Rectangle { Text { Layout.fillWidth: true - text: model.body + text: model.data.body textFormat: Text.PlainText elide: Text.ElideRight color: colors.text } Text { Layout.fillWidth: true - text: model.filesize + text: model.data.filesize textFormat: Text.PlainText elide: Text.ElideRight color: colors.text diff --git a/resources/qml/delegates/TextMessage.qml b/resources/qml/delegates/TextMessage.qml index f984b32f..92ba560b 100644 --- a/resources/qml/delegates/TextMessage.qml +++ b/resources/qml/delegates/TextMessage.qml @@ -1,6 +1,6 @@ import ".." MatrixText { - text: model.formattedBody.replace("<pre>", "<pre style='white-space: pre-wrap'>") + text: model.data.formattedBody.replace("<pre>", "<pre style='white-space: pre-wrap'>") width: parent ? parent.width : undefined } |