Fix getting content models for old events in a search model

Fix getting content models for old events in a search model by allowing for calling using the event. This gets past the intial checks and the content model itself can load the event from the server.

Requires network/neochat!2110 to fix the showauthor issue
This commit is contained in:
James Graham
2025-01-12 15:14:48 +00:00
parent 1d532a1fc1
commit 8a86159fd7
3 changed files with 55 additions and 17 deletions

View File

@@ -120,11 +120,7 @@ QVariant MessageModel::data(const QModelIndex &idx, int role) const
}
if (role == ContentModelRole) {
auto evtOrTxnId = event->get().id();
if (evtOrTxnId.isEmpty()) {
evtOrTxnId = event->get().transactionId();
}
return QVariant::fromValue<MessageContentModel *>(m_room->contentModelForEvent(evtOrTxnId));
return QVariant::fromValue<MessageContentModel *>(m_room->contentModelForEvent(&event->get()));
}
if (role == GenericDisplayRole) {

View File

@@ -1740,28 +1740,42 @@ NeochatRoomMember *NeoChatRoom::qmlSafeMember(const QString &memberId)
return m_memberObjects[memberId].get();
}
MessageContentModel *NeoChatRoom::contentModelForEvent(const QString &evtOrTxnId)
MessageContentModel *NeoChatRoom::contentModelForEvent(const QString &eventId)
{
const auto event = getEvent(evtOrTxnId);
if (event.first == nullptr) {
if (eventId.isEmpty()) {
return nullptr;
}
if (!m_eventContentModels.contains(eventId)) {
return m_eventContentModels.emplace(eventId, std::make_unique<MessageContentModel>(this, eventId)).first->second.get();
}
return m_eventContentModels[eventId].get();
}
MessageContentModel *NeoChatRoom::contentModelForEvent(const Quotient::RoomEvent *event)
{
const auto roomMessageEvent = eventCast<const Quotient::RoomMessageEvent>(event);
if (roomMessageEvent == nullptr) {
// If for some reason a model is there remove.
if (m_eventContentModels.contains(evtOrTxnId)) {
m_eventContentModels.erase(evtOrTxnId);
if (m_eventContentModels.contains(event->id())) {
m_eventContentModels.erase(event->id());
}
if (m_eventContentModels.contains(event->transactionId())) {
m_eventContentModels.erase(event->transactionId());
}
return nullptr;
}
if (event.first->isStateEvent() || event.first->matrixType() == u"org.matrix.msc3672.beacon_info"_s) {
if (event->isStateEvent() || event->matrixType() == u"org.matrix.msc3672.beacon_info"_s) {
return nullptr;
}
auto eventId = event.first->id();
const auto txnId = event.first->transactionId();
auto eventId = event->id();
const auto txnId = event->transactionId();
if (!m_eventContentModels.contains(eventId) && !m_eventContentModels.contains(txnId)) {
if (eventId.isEmpty()) {
eventId = txnId;
}
return m_eventContentModels.emplace(eventId, std::make_unique<MessageContentModel>(this, eventId, false, event.second)).first->second.get();
return m_eventContentModels.emplace(eventId, std::make_unique<MessageContentModel>(this, eventId.isEmpty() ? txnId : eventId, false, eventId.isEmpty()))
.first->second.get();
}
if (!eventId.isEmpty() && m_eventContentModels.contains(eventId)) {

View File

@@ -3,6 +3,7 @@
#pragma once
#include <Quotient/events/roomevent.h>
#include <Quotient/room.h>
#include <QCache>
@@ -589,8 +590,35 @@ public:
NeochatRoomMember *qmlSafeMember(const QString &memberId);
/**
* @brief Returns the content model for the given event ID.
*
* A model is created is one doesn't exist. Will return nullptr if evtOrTxnId
* is empty.
*
* @warning If a non-empty ID is given it is assumed to be a valid Quotient::RoomMessageEvent
* event ID. The caller must ensure that the ID is a real event. A model will be
* returned unconditionally.
*
* @warning Do NOT use for pending events as this function has no way to differentiate.
*/
MessageContentModel *contentModelForEvent(const QString &evtOrTxnId);
/**
* @brief Returns the content model for the given event.
*
* A model is created is one doesn't exist. Will return nullptr if event is:
* - nullptr
* - not a Quotient::RoomMessageEvent (e.g a state event)
*
* @note This method is preferred to the version using just an event ID as it
* can perform some basic checks. If a copy of the event is not available,
* you may have to use the version that takes an event ID.
*
* @note This version must be used for pending events as it can differentiate.
*/
MessageContentModel *contentModelForEvent(const Quotient::RoomEvent *event);
/**
* @brief Returns the thread model for the given thread root event ID.
*