Load replied-to message when it isn't in the timeline already
This commit is contained in:
@@ -27,6 +27,12 @@ QQC2.ItemDelegate {
|
|||||||
signal openExternally()
|
signal openExternally()
|
||||||
signal replyClicked(string eventID)
|
signal replyClicked(string eventID)
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
if (model.isReply && model.reply === undefined) {
|
||||||
|
messageEventModel.loadReply(sortedMessageEventModel.mapToSource(sortedMessageEventModel.index(model.index, 0)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
topPadding: 0
|
topPadding: 0
|
||||||
bottomPadding: 0
|
bottomPadding: 0
|
||||||
background: null
|
background: null
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "neochatconfig.h"
|
#include "neochatconfig.h"
|
||||||
#include <connection.h>
|
#include <connection.h>
|
||||||
|
#include <csapi/rooms.h>
|
||||||
#include <events/reactionevent.h>
|
#include <events/reactionevent.h>
|
||||||
#include <events/redactionevent.h>
|
#include <events/redactionevent.h>
|
||||||
#include <events/roomavatarevent.h>
|
#include <events/roomavatarevent.h>
|
||||||
@@ -41,7 +42,9 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
|
|||||||
roles[FileMimetypeIcon] = "fileMimetypeIcon";
|
roles[FileMimetypeIcon] = "fileMimetypeIcon";
|
||||||
roles[AnnotationRole] = "annotation";
|
roles[AnnotationRole] = "annotation";
|
||||||
roles[EventResolvedTypeRole] = "eventResolvedType";
|
roles[EventResolvedTypeRole] = "eventResolvedType";
|
||||||
|
roles[IsReplyRole] = "isReply";
|
||||||
roles[ReplyRole] = "reply";
|
roles[ReplyRole] = "reply";
|
||||||
|
roles[ReplyIdRole] = "replyId";
|
||||||
roles[UserMarkerRole] = "userMarker";
|
roles[UserMarkerRole] = "userMarker";
|
||||||
roles[ShowAuthorRole] = "showAuthor";
|
roles[ShowAuthorRole] = "showAuthor";
|
||||||
roles[ShowSectionRole] = "showSection";
|
roles[ShowSectionRole] = "showSection";
|
||||||
@@ -642,19 +645,35 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
|||||||
return variantList;
|
return variantList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (role == IsReplyRole) {
|
||||||
|
return !evt.contentJson()["m.relates_to"].toObject()["m.in_reply_to"].toObject()["event_id"].toString().isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (role == ReplyIdRole) {
|
||||||
|
return evt.contentJson()["m.relates_to"].toObject()["m.in_reply_to"].toObject()["event_id"].toString();
|
||||||
|
}
|
||||||
|
|
||||||
if (role == ReplyRole) {
|
if (role == ReplyRole) {
|
||||||
const QString &replyEventId = evt.contentJson()["m.relates_to"].toObject()["m.in_reply_to"].toObject()["event_id"].toString();
|
const QString &replyEventId = evt.contentJson()["m.relates_to"].toObject()["m.in_reply_to"].toObject()["event_id"].toString();
|
||||||
if (replyEventId.isEmpty()) {
|
if (replyEventId.isEmpty()) {
|
||||||
return {};
|
return {};
|
||||||
};
|
};
|
||||||
const auto replyIt = m_currentRoom->findInTimeline(replyEventId);
|
const auto replyIt = m_currentRoom->findInTimeline(replyEventId);
|
||||||
if (replyIt == m_currentRoom->historyEdge()) {
|
const RoomEvent *replyPtr = replyIt != m_currentRoom->historyEdge() ? &**replyIt : nullptr;
|
||||||
|
if (!replyPtr) {
|
||||||
|
for (const auto &e : m_extraEvents) {
|
||||||
|
if (e->id() == replyEventId) {
|
||||||
|
replyPtr = e.get();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!replyPtr) {
|
||||||
return {};
|
return {};
|
||||||
};
|
}
|
||||||
const auto &replyEvt = **replyIt;
|
|
||||||
|
|
||||||
QString type;
|
QString type;
|
||||||
if (auto e = eventCast<const RoomMessageEvent>(&replyEvt)) {
|
if (auto e = eventCast<const RoomMessageEvent>(replyPtr)) {
|
||||||
switch (e->msgtype()) {
|
switch (e->msgtype()) {
|
||||||
case MessageEventType::Emote:
|
case MessageEventType::Emote:
|
||||||
type = "emote";
|
type = "emote";
|
||||||
@@ -679,29 +698,29 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
|
|||||||
type = "message";
|
type = "message";
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (is<const StickerEvent>(replyEvt)) {
|
} else if (is<const StickerEvent>(*replyPtr)) {
|
||||||
type = "sticker";
|
type = "sticker";
|
||||||
} else {
|
} else {
|
||||||
type = "other";
|
type = "other";
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant content;
|
QVariant content;
|
||||||
if (auto e = eventCast<const RoomMessageEvent>(&replyEvt)) {
|
if (auto e = eventCast<const RoomMessageEvent>(replyPtr)) {
|
||||||
// Cannot use e.contentJson() here because some
|
// Cannot use e.contentJson() here because some
|
||||||
// EventContent classes inject values into the copy of the
|
// EventContent classes inject values into the copy of the
|
||||||
// content JSON stored in EventContent::Base
|
// content JSON stored in EventContent::Base
|
||||||
content = e->hasFileContent() ? QVariant::fromValue(e->content()->originalJson) : QVariant();
|
content = e->hasFileContent() ? QVariant::fromValue(e->content()->originalJson) : QVariant();
|
||||||
};
|
};
|
||||||
|
|
||||||
if (auto e = eventCast<const StickerEvent>(&replyEvt)) {
|
if (auto e = eventCast<const StickerEvent>(replyPtr)) {
|
||||||
content = QVariant::fromValue(e->image().originalJson);
|
content = QVariant::fromValue(e->image().originalJson);
|
||||||
}
|
}
|
||||||
|
|
||||||
return QVariantMap{{"eventId", replyEventId},
|
return QVariantMap{{"eventId", replyEventId},
|
||||||
{"display", m_currentRoom->eventToString(replyEvt, Qt::RichText)},
|
{"display", m_currentRoom->eventToString(*replyPtr, Qt::RichText)},
|
||||||
{"content", content},
|
{"content", content},
|
||||||
{"type", type},
|
{"type", type},
|
||||||
{"author", userAtEvent(static_cast<NeoChatUser *>(m_currentRoom->user(replyEvt.senderId())), m_currentRoom, evt)}};
|
{"author", userAtEvent(static_cast<NeoChatUser *>(m_currentRoom->user(replyPtr->senderId())), m_currentRoom, evt)}};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == ShowAuthorRole) {
|
if (role == ShowAuthorRole) {
|
||||||
@@ -851,3 +870,13 @@ QVariant MessageEventModel::getLatestMessageFromIndex(const int baseline)
|
|||||||
}
|
}
|
||||||
return replyResponse;
|
return replyResponse;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MessageEventModel::loadReply(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
auto job = m_currentRoom->connection()->callApi<GetOneRoomEventJob>(m_currentRoom->id(), data(index, ReplyIdRole).toString());
|
||||||
|
QPersistentModelIndex persistentIndex(index);
|
||||||
|
connect(job, &BaseJob::success, this, [this, job, persistentIndex] {
|
||||||
|
m_extraEvents.push_back(fromJson<event_ptr_tt<RoomEvent>>(job->jsonData()));
|
||||||
|
Q_EMIT dataChanged(persistentIndex, persistentIndex, {ReplyRole});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|||||||
@@ -33,7 +33,9 @@ public:
|
|||||||
MimeTypeRole,
|
MimeTypeRole,
|
||||||
FileMimetypeIcon,
|
FileMimetypeIcon,
|
||||||
|
|
||||||
|
IsReplyRole,
|
||||||
ReplyRole,
|
ReplyRole,
|
||||||
|
ReplyIdRole,
|
||||||
|
|
||||||
ShowAuthorRole,
|
ShowAuthorRole,
|
||||||
ShowSectionRole,
|
ShowSectionRole,
|
||||||
@@ -64,6 +66,7 @@ public:
|
|||||||
Q_INVOKABLE [[nodiscard]] int eventIDToIndex(const QString &eventID) const;
|
Q_INVOKABLE [[nodiscard]] int eventIDToIndex(const QString &eventID) const;
|
||||||
Q_INVOKABLE [[nodiscard]] QVariant getLastLocalUserMessageEventId();
|
Q_INVOKABLE [[nodiscard]] QVariant getLastLocalUserMessageEventId();
|
||||||
Q_INVOKABLE [[nodiscard]] QVariant getLatestMessageFromIndex(const int baseline);
|
Q_INVOKABLE [[nodiscard]] QVariant getLatestMessageFromIndex(const int baseline);
|
||||||
|
Q_INVOKABLE void loadReply(const QModelIndex &row);
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
int refreshEvent(const QString &eventId);
|
int refreshEvent(const QString &eventId);
|
||||||
@@ -88,6 +91,8 @@ private:
|
|||||||
int refreshEventRoles(const QString &eventId, const QVector<int> &roles = {});
|
int refreshEventRoles(const QString &eventId, const QVector<int> &roles = {});
|
||||||
void moveReadMarker(const QString &toEventId);
|
void moveReadMarker(const QString &toEventId);
|
||||||
|
|
||||||
|
std::vector<event_ptr_tt<RoomEvent>> m_extraEvents;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void roomChanged();
|
void roomChanged();
|
||||||
void fancyEffectsReasonFound(const QString &fancyEffect);
|
void fancyEffectsReasonFound(const QString &fancyEffect);
|
||||||
|
|||||||
Reference in New Issue
Block a user