Add support for stickers

Fix #130
This commit is contained in:
Carl Schwan
2020-12-29 14:28:32 +00:00
parent 9ba0a755e4
commit 5c8d916752
4 changed files with 57 additions and 31 deletions

View File

@@ -17,6 +17,8 @@ import NeoChat.Dialog 1.0
import NeoChat.Menu.Timeline 1.0 import NeoChat.Menu.Timeline 1.0
Image { Image {
id: img
readonly property bool isAnimated: contentType === "image/gif" readonly property bool isAnimated: contentType === "image/gif"
property bool openOnFinished: false property bool openOnFinished: false
@@ -26,8 +28,7 @@ Image {
// readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info // readonly property var info: isThumbnail ? content.info.thumbnail_info : content.info
readonly property var info: content.info readonly property var info: content.info
readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId readonly property string mediaId: isThumbnail ? content.thumbnailMediaId : content.mediaId
property bool readonly: false
id: img
source: "image://mxc/" + mediaId source: "image://mxc/" + mediaId
@@ -36,34 +37,12 @@ Image {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
Control { ToolTip.text: display
anchors.bottom: parent.bottom ToolTip.visible: hoverHandler.hovered
anchors.bottomMargin: 8
anchors.right: parent.right
anchors.rightMargin: 8
horizontalPadding: 8 HoverHandler {
verticalPadding: 4 id: hoverHandler
enabled: img.readonly
contentItem: RowLayout {
Label {
text: Qt.formatTime(time)
color: "white"
font.pixelSize: 12
}
Label {
text: author.displayName
color: "white"
font.pixelSize: 12
}
}
background: Rectangle {
radius: 2
color: "black"
opacity: 0.3
}
} }
Rectangle { Rectangle {
@@ -87,6 +66,8 @@ Image {
MouseArea { MouseArea {
id: messageMouseArea id: messageMouseArea
enabled: !img.readonly
anchors.fill: parent anchors.fill: parent
acceptedButtons: Qt.LeftButton | Qt.RightButton acceptedButtons: Qt.LeftButton | Qt.RightButton

View File

@@ -318,7 +318,7 @@ Kirigami.ScrollablePage {
ReactionDelegate { ReactionDelegate {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 0 Layout.topMargin: 0
Layout.bottomMargin: Kirigami.Units.largeSpacing * 2 Layout.bottomMargin: Kirigami.Units.largeSpacing
} }
] ]
} }
@@ -362,7 +362,35 @@ Kirigami.ScrollablePage {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 0 Layout.topMargin: 0
Layout.maximumHeight: 320 Layout.maximumHeight: 320
Layout.bottomMargin: 8 Layout.bottomMargin: Kirigami.Units.largeSpacing
}
]
}
}
}
DelegateChoice {
roleValue: "sticker"
delegate: TimelineContainer {
width: messageListView.width
innerObject: MessageDelegate {
Layout.fillWidth: true
onReplyClicked: goToEvent(eventID)
onReplyToMessageClicked: replyToMessage(replyUser, replyContent, eventId);
innerObject: [
ImageDelegate {
readonly: true
Layout.maximumWidth: parent.width / 2
Layout.minimumWidth: 320
Layout.preferredHeight: info.h / info.w * width
},
ReactionDelegate {
Layout.fillWidth: true
Layout.topMargin: 0
Layout.maximumHeight: 320
Layout.bottomMargin: Kirigami.Units.largeSpacing
} }
] ]
} }
@@ -443,6 +471,7 @@ Kirigami.ScrollablePage {
} }
} }
DelegateChoice { DelegateChoice {
roleValue: "other" roleValue: "other"
delegate: Item {} delegate: Item {}

View File

@@ -11,6 +11,7 @@
#include <events/redactionevent.h> #include <events/redactionevent.h>
#include <events/roomavatarevent.h> #include <events/roomavatarevent.h>
#include <events/roommemberevent.h> #include <events/roommemberevent.h>
#include <events/stickerevent.h>
#include <events/simplestateevents.h> #include <events/simplestateevents.h>
#include <user.h> #include <user.h>
@@ -324,6 +325,7 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
auto reason = evt.redactedBecause()->reason(); auto reason = evt.redactedBecause()->reason();
return (reason.isEmpty()) ? i18n("<i>[This message was deleted]</i>") : i18n("<i>[This message was deleted: %1]</i>").arg(evt.redactedBecause()->reason()); return (reason.isEmpty()) ? i18n("<i>[This message was deleted]</i>") : i18n("<i>[This message was deleted: %1]</i>").arg(evt.redactedBecause()->reason());
} }
return m_currentRoom->eventToString(evt, Qt::RichText); return m_currentRoom->eventToString(evt, Qt::RichText);
} }
@@ -357,6 +359,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return "message"; return "message";
} }
if (is<const StickerEvent>(evt)) {
return "sticker";
}
if (evt.isStateEvent()) { if (evt.isStateEvent()) {
return "state"; return "state";
} }
@@ -393,6 +398,10 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
// content JSON stored in EventContent::Base // content JSON stored in EventContent::Base
return e->hasFileContent() ? QVariant::fromValue(e->content()->originalJson) : QVariant(); return e->hasFileContent() ? QVariant::fromValue(e->content()->originalJson) : QVariant();
}; };
if (auto e = eventCast<const StickerEvent>(&evt)) {
return QVariant::fromValue(e->image().originalJson);
}
} }
if (role == HighlightRole) { if (role == HighlightRole) {
@@ -454,6 +463,9 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return QVariant::fromValue(m_currentRoom->fileTransferInfo(e->id())); return QVariant::fromValue(m_currentRoom->fileTransferInfo(e->id()));
} }
} }
if (auto e = eventCast<const StickerEvent>(&evt)) {
return QVariant::fromValue(m_currentRoom->fileTransferInfo(e->id()));
}
} }
if (role == AnnotationRole) { if (role == AnnotationRole) {

View File

@@ -27,6 +27,7 @@
#include "events/roomcanonicalaliasevent.h" #include "events/roomcanonicalaliasevent.h"
#include "events/roommessageevent.h" #include "events/roommessageevent.h"
#include "events/roompowerlevelsevent.h" #include "events/roompowerlevelsevent.h"
#include "events/stickerevent.h"
#include "events/typingevent.h" #include "events/typingevent.h"
#include "jobs/downloadfilejob.h" #include "jobs/downloadfilejob.h"
#include "neochatconfig.h" #include "neochatconfig.h"
@@ -345,6 +346,9 @@ QString NeoChatRoom::eventToString(const RoomEvent &evt, Qt::TextFormat format,
} }
return plainBody; return plainBody;
}, },
[](const StickerEvent &e) {
return e.body();
},
[this](const RoomMemberEvent &e) { [this](const RoomMemberEvent &e) {
// FIXME: Rewind to the name that was at the time of this event // FIXME: Rewind to the name that was at the time of this event
auto subjectName = this->user(e.userId())->displayname(); auto subjectName = this->user(e.userId())->displayname();