Refactor PollHandler

Refactor PollHandler to make it more reliable. This ended up with much more code than I expected as the original intent was just to stop a crash when switching rooms.
- Using a event string was flaky, changing to using an event reference is more reliable.
- Since we're only creating them from NeoChatRoom there is no need to to be able to set properties from QML so only read properties.
- Pass from the MessageEventModel rather than an invokable method.
- Create a basic test suite
- Create properties in PollHandler to remove the need to use content in PollDelegate, this means content is no longer a required role.
This commit is contained in:
James Graham
2024-01-02 21:22:08 +00:00
parent 7ad362225f
commit 356e8eefe0
10 changed files with 259 additions and 116 deletions

View File

@@ -20,6 +20,7 @@
#include "enums/delegatetype.h"
#include "eventhandler.h"
#include "events/pollevent.h"
#include "models/reactionmodel.h"
using namespace Quotient;
@@ -34,7 +35,6 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[TimeStringRole] = "timeString";
roles[SectionRole] = "section";
roles[AuthorRole] = "author";
roles[ContentRole] = "content";
roles[HighlightRole] = "isHighlighted";
roles[SpecialMarksRole] = "marks";
roles[ProgressInfoRole] = "progressInfo";
@@ -65,6 +65,7 @@ QHash<int, QByteArray> MessageEventModel::roleNames() const
roles[LatitudeRole] = "latitude";
roles[LongitudeRole] = "longitude";
roles[AssetRole] = "asset";
roles[PollHandlerRole] = "pollHandler";
return roles;
}
@@ -101,6 +102,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
if (const auto &roomMessageEvent = &*event->viewAs<RoomMessageEvent>()) {
createEventObjects(roomMessageEvent);
}
if (event->event()->is<PollStartEvent>()) {
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event->event()));
}
}
if (m_currentRoom->timelineSize() < 10 && !room->allHistoryLoaded()) {
@@ -151,6 +155,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
}
}
}
if (event->is<PollStartEvent>()) {
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event.get()));
}
}
m_initialized = true;
beginInsertRows({}, timelineBaseIndex(), timelineBaseIndex() + int(events.size()) - 1);
@@ -160,6 +167,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
if (const auto &roomMessageEvent = dynamic_cast<RoomMessageEvent *>(event.get())) {
createEventObjects(roomMessageEvent);
}
if (event->is<PollStartEvent>()) {
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(event.get()));
}
}
if (rowCount() > 0) {
rowBelowInserted = rowCount() - 1; // See #312
@@ -231,6 +241,9 @@ void MessageEventModel::setRoom(NeoChatRoom *room)
if (const auto &event = dynamic_cast<const RoomMessageEvent *>(&**eventIt)) {
createEventObjects(event);
}
if (eventIt->event()->is<PollStartEvent>()) {
m_currentRoom->createPollHandler(eventCast<const PollStartEvent>(eventIt->event()));
}
}
refreshEventRoles(eventId, {ReactionRole, ShowReactionsRole, Qt::DisplayRole});
});
@@ -485,28 +498,6 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return eventHandler.getAuthor(isPending);
}
if (role == ContentRole) {
if (evt.isRedacted()) {
auto reason = evt.redactedBecause()->reason();
return (reason.isEmpty()) ? i18n("[REDACTED]") : i18n("[REDACTED: %1]").arg(evt.redactedBecause()->reason());
}
if (auto e = eventCast<const RoomMessageEvent>(&evt)) {
if (e->msgtype() == Quotient::MessageEventType::Location) {
return e->contentJson();
}
// Cannot use e.contentJson() here because some
// EventContent classes inject values into the copy of the
// content JSON stored in EventContent::Base
return e->hasFileContent() ? QVariant::fromValue(e->content()->originalJson) : QVariant();
};
if (auto e = eventCast<const StickerEvent>(&evt)) {
return QVariant::fromValue(e->image().originalJson);
}
return evt.contentJson();
}
if (role == HighlightRole) {
return eventHandler.isHighlighted();
}
@@ -702,6 +693,10 @@ QVariant MessageEventModel::data(const QModelIndex &idx, int role) const
return row < static_cast<int>(m_currentRoom->pendingEvents().size());
}
if (role == PollHandlerRole) {
return QVariant::fromValue<PollHandler *>(m_currentRoom->poll(evt.id()));
}
return {};
}

View File

@@ -9,6 +9,7 @@
#include "linkpreviewer.h"
#include "neochatroom.h"
#include "pollhandler.h"
class ReactionModel;
@@ -45,7 +46,6 @@ public:
TimeStringRole, /**< The timestamp for when the event was sent as a string (in QLocale::ShortFormat). */
SectionRole, /**< The date of the event as a string. */
AuthorRole, /**< The author of the event. */
ContentRole, /**< The full message content. */
HighlightRole, /**< Whether the event should be highlighted. */
SpecialMarksRole, /**< Whether the event is hidden or not. */
ProgressInfoRole, /**< Progress info when downloading files. */
@@ -83,6 +83,7 @@ public:
LatitudeRole, /**< Latitude for a location event. */
LongitudeRole, /**< Longitude for a location event. */
AssetRole, /**< Type of location event, e.g. self pin of the user location. */
PollHandlerRole, /**< The PollHandler for the event, if any. */
LastRole, // Keep this last
};
Q_ENUM(EventRoles)