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
|