diff options
author | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2018-01-21 21:43:21 +0200 |
---|---|---|
committer | Konstantinos Sideris <sideris.konstantin@gmail.com> | 2018-01-21 21:43:21 +0200 |
commit | c59cd0e80bcbf1e37b7d6b021275d4c8f90f1914 (patch) | |
tree | e809690d042aca74c620b09f4a9f471cbe2240a3 | |
parent | Refactor avatar fetching in one function (diff) | |
download | nheko-c59cd0e80bcbf1e37b7d6b021275d4c8f90f1914.tar.xz |
Load the initial cache data without blocking the UI
-rw-r--r-- | CMakeLists.txt | 1 | ||||
-rw-r--r-- | include/Cache.h | 14 | ||||
-rw-r--r-- | include/RoomState.h | 2 | ||||
-rw-r--r-- | src/Cache.cc | 9 | ||||
-rw-r--r-- | src/ChatPage.cc | 63 |
5 files changed, 52 insertions, 37 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index b8450a98..9091a0b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -277,6 +277,7 @@ qt5_wrap_cpp(MOC_HEADERS include/ui/ThemeManager.h include/AvatarProvider.h + include/Cache.h include/ChatPage.h include/CommunitiesListItem.h include/CommunitiesList.h diff --git a/include/Cache.h b/include/Cache.h index 7a626e12..e8d797dd 100644 --- a/include/Cache.h +++ b/include/Cache.h @@ -18,11 +18,12 @@ #pragma once #include <QDir> +#include <QMap> #include <json.hpp> #include <lmdb++.h> #include <mtx/responses.hpp> -class RoomState; +#include "RoomState.h" //! Used to uniquely identify a list of read receipts. struct ReadReceiptKey @@ -44,17 +45,19 @@ from_json(const json &j, ReadReceiptKey &key) key.room_id = j.at("room_id").get<std::string>(); } -class Cache +class Cache : public QObject { + Q_OBJECT + public: - Cache(const QString &userId); + Cache(const QString &userId, QObject *parent = nullptr); void setState(const QString &nextBatchToken, const QMap<QString, QSharedPointer<RoomState>> &states); bool isInitialized() const; QString nextBatchToken() const; - QMap<QString, RoomState> states(); + void states(); using Invites = std::map<std::string, mtx::responses::InvitedRoom>; Invites invites(); @@ -86,6 +89,9 @@ public: QByteArray image(const QString &url) const; void saveImage(const QString &url, const QByteArray &data); +signals: + void statesLoaded(QMap<QString, RoomState> states); + private: void setNextBatchToken(lmdb::txn &txn, const QString &token); void insertRoomState(lmdb::txn &txn, diff --git a/include/RoomState.h b/include/RoomState.h index 0e91410c..6f335263 100644 --- a/include/RoomState.h +++ b/include/RoomState.h @@ -77,6 +77,8 @@ private: QString userAvatar_; }; +Q_DECLARE_METATYPE(RoomState) + template<class Collection> void RoomState::updateFromEvents(const std::vector<Collection> &collection) diff --git a/src/Cache.cc b/src/Cache.cc index fd6a5ee9..32176369 100644 --- a/src/Cache.cc +++ b/src/Cache.cc @@ -33,8 +33,9 @@ static const lmdb::val CACHE_FORMAT_VERSION_KEY("cache_format_version"); using CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>; using Receipts = std::map<std::string, std::map<std::string, uint64_t>>; -Cache::Cache(const QString &userId) - : env_{nullptr} +Cache::Cache(const QString &userId, QObject *parent) + : QObject{parent} + , env_{nullptr} , stateDb_{0} , roomDb_{0} , invitesDb_{0} @@ -248,7 +249,7 @@ Cache::removeInvite(const QString &room_id) txn.commit(); } -QMap<QString, RoomState> +void Cache::states() { QMap<QString, RoomState> states; @@ -301,7 +302,7 @@ Cache::states() txn.commit(); - return states; + emit statesLoaded(states); } void diff --git a/src/ChatPage.cc b/src/ChatPage.cc index 596f72dc..225434e6 100644 --- a/src/ChatPage.cc +++ b/src/ChatPage.cc @@ -648,46 +648,51 @@ ChatPage::loadStateFromCache() qDebug() << "Restored nextBatchToken" << cache_->nextBatchToken(); client_->setNextBatchToken(cache_->nextBatchToken()); - // Fetch all the joined room's state. - auto rooms = cache_->states(); + qRegisterMetaType<QMap<QString, RoomState>>(); - for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) { - auto roomState = QSharedPointer<RoomState>(new RoomState(it.value())); + QtConcurrent::run(cache_.data(), &Cache::states); - // Clean up and prepare state for use. - roomState->removeLeaveMemberships(); - roomState->resolveName(); - roomState->resolveAvatar(); + connect(cache_.data(), &Cache::statesLoaded, this, [this](QMap<QString, RoomState> rooms) { + qDebug() << "Cache data loaded"; - // Save the current room state. - roomStates_.insert(it.key(), roomState); + for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) { + auto roomState = QSharedPointer<RoomState>(new RoomState(it.value())); - // Create or restore the settings for this room. - roomSettings_.insert(it.key(), - QSharedPointer<RoomSettings>(new RoomSettings(it.key()))); + // Clean up and prepare state for use. + roomState->removeLeaveMemberships(); + roomState->resolveName(); + roomState->resolveAvatar(); - // Resolve user avatars. - for (const auto membership : roomState->memberships) { - updateUserDisplayName(membership.second); - updateUserAvatarUrl(membership.second); + // Save the current room state. + roomStates_.insert(it.key(), roomState); + + // Create or restore the settings for this room. + roomSettings_.insert( + it.key(), QSharedPointer<RoomSettings>(new RoomSettings(it.key()))); + + // Resolve user avatars. + for (const auto membership : roomState->memberships) { + updateUserDisplayName(membership.second); + updateUserAvatarUrl(membership.second); + } } - } - // Initializing empty timelines. - view_manager_->initialize(rooms.keys()); + // Initializing empty timelines. + view_manager_->initialize(rooms.keys()); - // Initialize room list from the restored state and settings. - room_list_->setInitialRooms(roomSettings_, roomStates_); - room_list_->syncInvites(cache_->invites()); + // Initialize room list from the restored state and settings. + room_list_->setInitialRooms(roomSettings_, roomStates_); + room_list_->syncInvites(cache_->invites()); - // Check periodically if the timelines have been loaded. - consensusTimer_->start(CONSENSUS_TIMEOUT); + // Check periodically if the timelines have been loaded. + consensusTimer_->start(CONSENSUS_TIMEOUT); - // Show the content if consensus can't be achieved. - showContentTimer_->start(SHOW_CONTENT_TIMEOUT); + // Show the content if consensus can't be achieved. + showContentTimer_->start(SHOW_CONTENT_TIMEOUT); - // Start receiving events. - client_->sync(); + // Start receiving events. + client_->sync(); + }); } void |