From a48e46dd315c66c196626f280cedbf4f0fa52355 Mon Sep 17 00:00:00 2001 From: Kitsune Ral Date: Wed, 25 May 2016 20:00:28 +0900 Subject: Load a different set of event lists depending on the join state (and actually introduce EventList class) This makes loading of room events more compliant with the spec, not trying to load from keys that are not supposed to be there. As a result of refactoring along the way, a dedicated QList subclass is made that remembers the JSON key it should load from and actually load itself from a QJsonArray. --- jobs/syncjob.cpp | 87 +++++++++++++++++++++++++++++--------------------------- jobs/syncjob.h | 18 +++++++++--- 2 files changed, 59 insertions(+), 46 deletions(-) (limited to 'jobs') diff --git a/jobs/syncjob.cpp b/jobs/syncjob.cpp index cd60e2c1..6b8ec510 100644 --- a/jobs/syncjob.cpp +++ b/jobs/syncjob.cpp @@ -24,8 +24,6 @@ #include #include -#include - #include "../room.h" #include "../connectiondata.h" #include "../events/event.h" @@ -43,8 +41,6 @@ class SyncJob::Private QString nextBatch; QList roomData; - - void parseEvents(QString roomId, const QJsonObject& room, JoinState joinState); }; SyncJob::SyncJob(ConnectionData* connection, QString since) @@ -120,57 +116,64 @@ void SyncJob::parseJson(const QJsonDocument& data) // TODO: account_data QJsonObject rooms = json.value("rooms").toObject(); - QJsonObject joinRooms = rooms.value("join").toObject(); - for( const QString& roomId: joinRooms.keys() ) + const struct { QString jsonKey; JoinState enumVal; } roomStates[] { - d->parseEvents(roomId, joinRooms.value(roomId).toObject(), JoinState::Join); - } - - QJsonObject inviteRooms = rooms.value("invite").toObject(); - for( const QString& roomId: inviteRooms.keys() ) + { "join", JoinState::Join }, + { "invite", JoinState::Invite }, + { "leave", JoinState::Leave } + }; + for (auto roomState: roomStates) { - d->parseEvents(roomId, inviteRooms.value(roomId).toObject(), JoinState::Invite); + const QJsonObject rs = rooms.value(roomState.jsonKey).toObject(); + d->roomData.reserve(rs.size()); + for( auto r = rs.begin(); r != rs.end(); ++r ) + { + d->roomData.push_back({r.key(), r.value().toObject(), roomState.enumVal}); + } } - QJsonObject leaveRooms = rooms.value("leave").toObject(); - for( const QString& roomId: leaveRooms.keys() ) - { - d->parseEvents(roomId, leaveRooms.value(roomId).toObject(), JoinState::Leave); - } emitResult(); } -SyncRoomData::SyncRoomData(QString roomId_, const QJsonObject& room_, JoinState joinState_) - : roomId(roomId_), joinState(joinState_) +void SyncRoomData::EventList::fromJson(const QJsonObject& roomContents) { - const QList *> > eventLists = { - { "state", &state }, - { "timeline", &timeline }, - { "ephemeral", &ephemeral }, - { "account_data", &accountData } - }; + auto l = eventListFromJson(roomContents[jsonKey].toObject()["events"].toArray()); + swap(l); +} - for (auto elist: eventLists) { - QJsonArray array = room_.value(elist.first).toObject().value("events").toArray(); - for( QJsonValue val: array ) - { - if ( Event* event = Event::fromJson(val.toObject()) ) - elist.second->append(event); - } +SyncRoomData::SyncRoomData(QString roomId_, const QJsonObject& room_, JoinState joinState_) + : roomId(roomId_) + , joinState(joinState_) + , state("state") + , timeline("timeline") + , ephemeral("ephemeral") + , accountData("account_data") + , inviteState("invite_state") +{ + switch (joinState) { + case JoinState::Invite: + inviteState.fromJson(room_); + break; + case JoinState::Join: + state.fromJson(room_); + timeline.fromJson(room_); + ephemeral.fromJson(room_); + accountData.fromJson(room_); + break; + case JoinState::Leave: + state.fromJson(room_); + timeline.fromJson(room_); + break; + default: + qWarning() << "SyncRoomData: Unknown JoinState value, ignoring:" << int(joinState); } QJsonObject timeline = room_.value("timeline").toObject(); timelineLimited = timeline.value("limited").toBool(); timelinePrevBatch = timeline.value("prev_batch").toString(); - QJsonObject unread = room_.value("unread_notifications").toObject(); - highlightCount = unread.value("highlight_count").toInt(); - notificationCount = unread.value("notification_count").toInt(); - qDebug() << "Highlights: " << highlightCount << " Notifications:" << notificationCount; + QJsonObject unread = room_.value("unread_notifications").toObject(); + highlightCount = unread.value("highlight_count").toInt(); + notificationCount = unread.value("notification_count").toInt(); + qDebug() << "Highlights: " << highlightCount << " Notifications:" << notificationCount; } - -void SyncJob::Private::parseEvents(QString roomId, const QJsonObject& room, JoinState joinState) -{ - roomData.append(SyncRoomData{roomId, room, joinState}); -} - diff --git a/jobs/syncjob.h b/jobs/syncjob.h index 507d46eb..abbef23a 100644 --- a/jobs/syncjob.h +++ b/jobs/syncjob.h @@ -30,12 +30,22 @@ namespace QMatrixClient class SyncRoomData { public: + class EventList : public QList + { + private: + QString jsonKey; + public: + explicit EventList(QString k) : jsonKey(k) { } + void fromJson(const QJsonObject& roomContents); + }; + QString roomId; JoinState joinState; - QList state; - QList timeline; - QList ephemeral; - QList accountData; + EventList state; + EventList timeline; + EventList ephemeral; + EventList accountData; + EventList inviteState; bool timelineLimited; QString timelinePrevBatch; -- cgit v1.2.3