summary refs log tree commit diff
path: root/src/ChatPage.cc
diff options
context:
space:
mode:
authorKonstantinos Sideris <sideris.konstantin@gmail.com>2017-12-04 18:41:19 +0200
committerKonstantinos Sideris <sideris.konstantin@gmail.com>2017-12-04 18:41:19 +0200
commita605e4486f4b9d90d668d6d1844ba5f0d58bbc26 (patch)
treec82001904cb120d975361edb38a62b5b77fa0644 /src/ChatPage.cc
parentRun tests only with gcc (diff)
downloadnheko-a605e4486f4b9d90d668d6d1844ba5f0d58bbc26.tar.xz
Migrate to matrix-structs for event and response parsing
Diffstat (limited to 'src/ChatPage.cc')
-rw-r--r--src/ChatPage.cc280
1 files changed, 103 insertions, 177 deletions
diff --git a/src/ChatPage.cc b/src/ChatPage.cc
index bbed7359..ab5aa263 100644
--- a/src/ChatPage.cc
+++ b/src/ChatPage.cc
@@ -32,7 +32,6 @@
 #include "RoomState.h"
 #include "SideBarActions.h"
 #include "Splitter.h"
-#include "Sync.h"
 #include "TextInputWidget.h"
 #include "Theme.h"
 #include "TopRoomBar.h"
@@ -44,8 +43,6 @@
 constexpr int MAX_INITIAL_SYNC_FAILURES = 5;
 constexpr int SYNC_RETRY_TIMEOUT        = 10000;
 
-namespace events = matrix::events;
-
 ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
   : QWidget(parent)
   , client_(client)
@@ -219,15 +216,13 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
                         view_manager_->queueAudioMessage(roomid, filename, url);
                 });
 
-        connect(client_.data(),
-                SIGNAL(roomAvatarRetrieved(const QString &, const QPixmap &)),
-                this,
-                SLOT(updateTopBarAvatar(const QString &, const QPixmap &)));
+        connect(
+          client_.data(), &MatrixClient::roomAvatarRetrieved, this, &ChatPage::updateTopBarAvatar);
 
         connect(client_.data(),
-                SIGNAL(initialSyncCompleted(const SyncResponse &)),
+                &MatrixClient::initialSyncCompleted,
                 this,
-                SLOT(initialSyncCompleted(const SyncResponse &)));
+                &ChatPage::initialSyncCompleted);
         connect(client_.data(), &MatrixClient::initialSyncFailed, this, [=](const QString &msg) {
                 if (client_->getHomeServer().isEmpty()) {
                         deleteConfigs();
@@ -251,29 +246,17 @@ ChatPage::ChatPage(QSharedPointer<MatrixClient> client, QWidget *parent)
 
                 client_->initialSync();
         });
-        connect(client_.data(),
-                SIGNAL(syncCompleted(const SyncResponse &)),
-                this,
-                SLOT(syncCompleted(const SyncResponse &)));
-        connect(client_.data(),
-                SIGNAL(syncFailed(const QString &)),
-                this,
-                SLOT(syncFailed(const QString &)));
+        connect(client_.data(), &MatrixClient::syncCompleted, this, &ChatPage::syncCompleted);
+        connect(client_.data(), &MatrixClient::syncFailed, this, &ChatPage::syncFailed);
         connect(client_.data(),
                 &MatrixClient::getOwnProfileResponse,
                 this,
                 &ChatPage::updateOwnProfileInfo);
-        connect(client_.data(),
-                SIGNAL(ownAvatarRetrieved(const QPixmap &)),
-                this,
-                SLOT(setOwnAvatar(const QPixmap &)));
+        connect(client_.data(), &MatrixClient::ownAvatarRetrieved, this, &ChatPage::setOwnAvatar);
         connect(client_.data(), &MatrixClient::joinedRoom, this, [=]() {
                 emit showNotification("You joined the room.");
         });
-        connect(client_.data(),
-                SIGNAL(leftRoom(const QString &)),
-                this,
-                SLOT(removeRoom(const QString &)));
+        connect(client_.data(), &MatrixClient::leftRoom, this, &ChatPage::removeRoom);
 
         showContentTimer_ = new QTimer(this);
         showContentTimer_->setSingleShot(true);
@@ -383,32 +366,34 @@ ChatPage::syncFailed(const QString &msg)
 }
 
 void
-ChatPage::syncCompleted(const SyncResponse &response)
+ChatPage::syncCompleted(const mtx::responses::Sync &response)
 {
-        updateJoinedRooms(response.rooms().join());
-        removeLeftRooms(response.rooms().leave());
+        updateJoinedRooms(response.rooms.join);
+        removeLeftRooms(response.rooms.leave);
 
-        auto stateDiff = generateMembershipDifference(response.rooms().join(), state_manager_);
-        QtConcurrent::run(cache_.data(), &Cache::setState, response.nextBatch(), stateDiff);
+        const auto nextBatchToken = QString::fromStdString(response.next_batch);
+
+        auto stateDiff = generateMembershipDifference(response.rooms.join, state_manager_);
+        QtConcurrent::run(cache_.data(), &Cache::setState, nextBatchToken, stateDiff);
 
         room_list_->sync(state_manager_, settingsManager_);
-        view_manager_->sync(response.rooms());
+        view_manager_->sync(response.rooms);
 
-        client_->setNextBatchToken(response.nextBatch());
+        client_->setNextBatchToken(nextBatchToken);
         client_->sync();
 }
 
 void
-ChatPage::initialSyncCompleted(const SyncResponse &response)
+ChatPage::initialSyncCompleted(const mtx::responses::Sync &response)
 {
-        auto joined = response.rooms().join();
+        auto joined = response.rooms.join;
 
-        for (auto it = joined.constBegin(); it != joined.constEnd(); ++it) {
+        for (auto it = joined.cbegin(); it != joined.cend(); ++it) {
                 RoomState room_state;
 
                 // Build the current state from the timeline and state events.
-                room_state.updateFromEvents(it.value().state().events());
-                room_state.updateFromEvents(it.value().timeline().events());
+                room_state.updateFromEvents(it->second.state.events);
+                room_state.updateFromEvents(it->second.timeline.events);
 
                 // Remove redundant memberships.
                 room_state.removeLeaveMemberships();
@@ -417,27 +402,32 @@ ChatPage::initialSyncCompleted(const SyncResponse &response)
                 room_state.resolveName();
                 room_state.resolveAvatar();
 
-                state_manager_.insert(it.key(), room_state);
-                settingsManager_.insert(it.key(),
-                                        QSharedPointer<RoomSettings>(new RoomSettings(it.key())));
+                const auto room_id = QString::fromStdString(it->first);
+
+                state_manager_.insert(room_id, room_state);
+                settingsManager_.insert(room_id,
+                                        QSharedPointer<RoomSettings>(new RoomSettings(room_id)));
 
                 for (const auto membership : room_state.memberships) {
-                        updateUserDisplayName(membership);
-                        updateUserAvatarUrl(membership);
+                        updateUserDisplayName(membership.second);
+                        updateUserAvatarUrl(membership.second);
                 }
 
                 QApplication::processEvents();
         }
 
-        QtConcurrent::run(cache_.data(), &Cache::setState, response.nextBatch(), state_manager_);
+        QtConcurrent::run(cache_.data(),
+                          &Cache::setState,
+                          QString::fromStdString(response.next_batch),
+                          state_manager_);
 
         // Populate timelines with messages.
-        view_manager_->initialize(response.rooms());
+        view_manager_->initialize(response.rooms);
 
         // Initialize room list.
         room_list_->setInitialRooms(settingsManager_, state_manager_);
 
-        client_->setNextBatchToken(response.nextBatch());
+        client_->setNextBatchToken(QString::fromStdString(response.next_batch));
         client_->sync();
 
         emit contentLoaded();
@@ -527,8 +517,8 @@ ChatPage::loadStateFromCache()
 
                 // Resolve user avatars.
                 for (const auto membership : room_state.memberships) {
-                        updateUserDisplayName(membership);
-                        updateUserAvatarUrl(membership);
+                        updateUserDisplayName(membership.second);
+                        updateUserAvatarUrl(membership.second);
                 }
         }
 
@@ -579,7 +569,8 @@ ChatPage::showQuickSwitcher()
         QMap<QString, QString> rooms;
 
         for (auto it = state_manager_.constBegin(); it != state_manager_.constEnd(); ++it) {
-                QString deambiguator = it.value().canonical_alias.content().alias();
+                QString deambiguator =
+                  QString::fromStdString(it.value().canonical_alias.content.alias);
                 if (deambiguator == "")
                         deambiguator = it.key();
                 rooms.insert(it.value().getName() + " (" + deambiguator + ")", it.key());
@@ -623,7 +614,7 @@ ChatPage::removeRoom(const QString &room_id)
 }
 
 void
-ChatPage::updateTypingUsers(const QString &roomid, const QList<QString> &user_ids)
+ChatPage::updateTypingUsers(const QString &roomid, const std::vector<std::string> &user_ids)
 {
         QStringList users;
 
@@ -631,9 +622,12 @@ ChatPage::updateTypingUsers(const QString &roomid, const QList<QString> &user_id
         QString user_id = settings.value("auth/user_id").toString();
 
         for (const auto uid : user_ids) {
-                if (uid == user_id)
+                auto user = QString::fromStdString(uid);
+
+                if (user == user_id)
                         continue;
-                users.append(TimelineViewManager::displayName(uid));
+
+                users.append(TimelineViewManager::displayName(user));
         }
 
         users.sort();
@@ -646,186 +640,118 @@ ChatPage::updateTypingUsers(const QString &roomid, const QList<QString> &user_id
 }
 
 void
-ChatPage::updateUserMetadata(const QJsonArray &events)
-{
-        events::EventType ty;
-
-        for (const auto &event : events) {
-                try {
-                        ty = events::extractEventType(event.toObject());
-                } catch (const DeserializationException &e) {
-                        qWarning() << e.what() << event;
-                        continue;
-                }
-
-                if (!events::isStateEvent(ty))
-                        continue;
-
-                try {
-                        switch (ty) {
-                        case events::EventType::RoomMember: {
-                                events::StateEvent<events::MemberEventContent> member;
-                                member.deserialize(event);
-
-                                updateUserAvatarUrl(member);
-                                updateUserDisplayName(member);
-
-                                break;
-                        }
-                        default: {
-                                continue;
-                        }
-                        }
-                } catch (const DeserializationException &e) {
-                        qWarning() << e.what() << event;
-                        continue;
-                }
-        }
-}
-
-void
-ChatPage::updateUserAvatarUrl(const events::StateEvent<events::MemberEventContent> &membership)
+ChatPage::updateUserAvatarUrl(const mtx::events::StateEvent<mtx::events::state::Member> &membership)
 {
-        auto uid = membership.sender();
-        auto url = membership.content().avatarUrl();
+        auto uid = QString::fromStdString(membership.sender);
+        auto url = QString::fromStdString(membership.content.avatar_url);
 
-        if (!url.toString().isEmpty())
+        if (!url.isEmpty())
                 AvatarProvider::setAvatarUrl(uid, url);
 }
 
 void
-ChatPage::updateUserDisplayName(const events::StateEvent<events::MemberEventContent> &membership)
+ChatPage::updateUserDisplayName(
+  const mtx::events::StateEvent<mtx::events::state::Member> &membership)
 {
-        auto displayName = membership.content().displayName();
+        auto displayName = QString::fromStdString(membership.content.display_name);
+        auto stateKey    = QString::fromStdString(membership.state_key);
 
         if (!displayName.isEmpty())
-                TimelineViewManager::DISPLAY_NAMES.insert(membership.stateKey(), displayName);
+                TimelineViewManager::DISPLAY_NAMES.insert(stateKey, displayName);
 }
 
 void
-ChatPage::removeLeftRooms(const QMap<QString, LeftRoom> &rooms)
+ChatPage::removeLeftRooms(const std::map<std::string, mtx::responses::LeftRoom> &rooms)
 {
-        for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) {
-                if (state_manager_.contains(it.key()))
-                        removeRoom(it.key());
+        for (auto it = rooms.cbegin(); it != rooms.cend(); ++it) {
+                const auto room_id = QString::fromStdString(it->first);
+
+                if (state_manager_.contains(room_id))
+                        removeRoom(room_id);
         }
 }
 
 void
-ChatPage::updateJoinedRooms(const QMap<QString, JoinedRoom> &rooms)
+ChatPage::updateJoinedRooms(const std::map<std::string, mtx::responses::JoinedRoom> &rooms)
 {
-        for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) {
-                updateTypingUsers(it.key(), it.value().typingUserIDs());
+        for (auto it = rooms.cbegin(); it != rooms.cend(); ++it) {
+                const auto roomid = QString::fromStdString(it->first);
+
+                updateTypingUsers(roomid, it->second.ephemeral.typing);
 
-                const auto newStateEvents    = it.value().state().events();
-                const auto newTimelineEvents = it.value().timeline().events();
+                const auto newStateEvents    = it->second.state;
+                const auto newTimelineEvents = it->second.timeline;
 
                 // Merge the new updates for rooms that we are tracking.
-                if (state_manager_.contains(it.key())) {
-                        auto oldState = &state_manager_[it.key()];
-                        oldState->updateFromEvents(newStateEvents);
-                        oldState->updateFromEvents(newTimelineEvents);
+                if (state_manager_.contains(roomid)) {
+                        auto oldState = &state_manager_[roomid];
+                        oldState->updateFromEvents(newStateEvents.events);
+                        oldState->updateFromEvents(newTimelineEvents.events);
                         oldState->resolveName();
                         oldState->resolveAvatar();
                 } else {
                         // Build the current state from the timeline and state events.
                         RoomState room_state;
-                        room_state.updateFromEvents(newStateEvents);
-                        room_state.updateFromEvents(newTimelineEvents);
+                        room_state.updateFromEvents(newStateEvents.events);
+                        room_state.updateFromEvents(newTimelineEvents.events);
 
                         // Resolve room name and avatar. e.g in case of one-to-one chats.
                         room_state.resolveName();
                         room_state.resolveAvatar();
 
-                        state_manager_.insert(it.key(), room_state);
+                        state_manager_.insert(roomid, room_state);
 
                         settingsManager_.insert(
-                          it.key(), QSharedPointer<RoomSettings>(new RoomSettings(it.key())));
+                          roomid, QSharedPointer<RoomSettings>(new RoomSettings(roomid)));
 
-                        view_manager_->addRoom(it.value(), it.key());
+                        view_manager_->addRoom(it->second, roomid);
                 }
 
-                updateUserMetadata(newStateEvents);
-                updateUserMetadata(newTimelineEvents);
+                updateUserMetadata(newStateEvents.events);
+                updateUserMetadata(newTimelineEvents.events);
 
-                if (it.key() == current_room_)
-                        changeTopRoomInfo(it.key());
+                if (roomid == current_room_)
+                        changeTopRoomInfo(roomid);
 
                 QApplication::processEvents();
         }
 }
 
 QMap<QString, RoomState>
-ChatPage::generateMembershipDifference(const QMap<QString, JoinedRoom> &rooms,
-                                       const QMap<QString, RoomState> &states) const
+ChatPage::generateMembershipDifference(
+  const std::map<std::string, mtx::responses::JoinedRoom> &rooms,
+  const QMap<QString, RoomState> &states) const
 {
         QMap<QString, RoomState> stateDiff;
 
-        for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) {
-                if (!states.contains(it.key()))
+        for (auto it = rooms.cbegin(); it != rooms.cend(); ++it) {
+                const auto room_id = QString::fromStdString(it->first);
+
+                if (!states.contains(room_id))
                         continue;
 
-                auto events = it.value().state().events();
+                auto all_memberships     = getMemberships(it->second.state.events);
+                auto timelineMemberships = getMemberships(it->second.timeline.events);
 
-                for (auto event : it.value().timeline().events())
-                        events.append(event);
+                // We have to process first the state events and then the timeline.
+                for (auto mm = timelineMemberships.cbegin(); mm != timelineMemberships.cend(); ++mm)
+                        all_memberships.emplace(mm->first, mm->second);
 
                 RoomState local;
-                local.aliases            = states[it.key()].aliases;
-                local.avatar             = states[it.key()].avatar;
-                local.canonical_alias    = states[it.key()].canonical_alias;
-                local.history_visibility = states[it.key()].history_visibility;
-                local.join_rules         = states[it.key()].join_rules;
-                local.name               = states[it.key()].name;
-                local.power_levels       = states[it.key()].power_levels;
-                local.topic              = states[it.key()].topic;
-                local.memberships        = getMemberships(events);
-
-                stateDiff.insert(it.key(), local);
+                local.aliases            = states[room_id].aliases;
+                local.avatar             = states[room_id].avatar;
+                local.canonical_alias    = states[room_id].canonical_alias;
+                local.history_visibility = states[room_id].history_visibility;
+                local.join_rules         = states[room_id].join_rules;
+                local.name               = states[room_id].name;
+                local.power_levels       = states[room_id].power_levels;
+                local.topic              = states[room_id].topic;
+                local.memberships        = all_memberships;
+
+                stateDiff.insert(room_id, local);
         }
 
         return stateDiff;
 }
 
-using Memberships = QMap<QString, matrix::events::StateEvent<events::MemberEventContent>>;
-
-Memberships
-ChatPage::getMemberships(const QJsonArray &events) const
-{
-        Memberships memberships;
-
-        events::EventType ty;
-
-        for (const auto &event : events) {
-                try {
-                        ty = events::extractEventType(event.toObject());
-                } catch (const DeserializationException &e) {
-                        qWarning() << e.what() << event;
-                        continue;
-                }
-
-                if (!events::isStateEvent(ty))
-                        continue;
-
-                try {
-                        switch (ty) {
-                        case events::EventType::RoomMember: {
-                                events::StateEvent<events::MemberEventContent> member;
-                                member.deserialize(event);
-                                memberships.insert(member.stateKey(), member);
-                                break;
-                        }
-                        default: {
-                                continue;
-                        }
-                        }
-                } catch (const DeserializationException &e) {
-                        qWarning() << e.what() << event;
-                        continue;
-                }
-        }
-
-        return memberships;
-}
-
 ChatPage::~ChatPage() {}