mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-22 19:08:58 +03:00
Load the initial cache data without blocking the UI
This commit is contained in:
parent
c123bada94
commit
c59cd0e80b
5 changed files with 52 additions and 37 deletions
|
@ -277,6 +277,7 @@ qt5_wrap_cpp(MOC_HEADERS
|
||||||
include/ui/ThemeManager.h
|
include/ui/ThemeManager.h
|
||||||
|
|
||||||
include/AvatarProvider.h
|
include/AvatarProvider.h
|
||||||
|
include/Cache.h
|
||||||
include/ChatPage.h
|
include/ChatPage.h
|
||||||
include/CommunitiesListItem.h
|
include/CommunitiesListItem.h
|
||||||
include/CommunitiesList.h
|
include/CommunitiesList.h
|
||||||
|
|
|
@ -18,11 +18,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <QMap>
|
||||||
#include <json.hpp>
|
#include <json.hpp>
|
||||||
#include <lmdb++.h>
|
#include <lmdb++.h>
|
||||||
#include <mtx/responses.hpp>
|
#include <mtx/responses.hpp>
|
||||||
|
|
||||||
class RoomState;
|
#include "RoomState.h"
|
||||||
|
|
||||||
//! Used to uniquely identify a list of read receipts.
|
//! Used to uniquely identify a list of read receipts.
|
||||||
struct ReadReceiptKey
|
struct ReadReceiptKey
|
||||||
|
@ -44,17 +45,19 @@ from_json(const json &j, ReadReceiptKey &key)
|
||||||
key.room_id = j.at("room_id").get<std::string>();
|
key.room_id = j.at("room_id").get<std::string>();
|
||||||
}
|
}
|
||||||
|
|
||||||
class Cache
|
class Cache : public QObject
|
||||||
{
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Cache(const QString &userId);
|
Cache(const QString &userId, QObject *parent = nullptr);
|
||||||
|
|
||||||
void setState(const QString &nextBatchToken,
|
void setState(const QString &nextBatchToken,
|
||||||
const QMap<QString, QSharedPointer<RoomState>> &states);
|
const QMap<QString, QSharedPointer<RoomState>> &states);
|
||||||
bool isInitialized() const;
|
bool isInitialized() const;
|
||||||
|
|
||||||
QString nextBatchToken() const;
|
QString nextBatchToken() const;
|
||||||
QMap<QString, RoomState> states();
|
void states();
|
||||||
|
|
||||||
using Invites = std::map<std::string, mtx::responses::InvitedRoom>;
|
using Invites = std::map<std::string, mtx::responses::InvitedRoom>;
|
||||||
Invites invites();
|
Invites invites();
|
||||||
|
@ -86,6 +89,9 @@ public:
|
||||||
QByteArray image(const QString &url) const;
|
QByteArray image(const QString &url) const;
|
||||||
void saveImage(const QString &url, const QByteArray &data);
|
void saveImage(const QString &url, const QByteArray &data);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void statesLoaded(QMap<QString, RoomState> states);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setNextBatchToken(lmdb::txn &txn, const QString &token);
|
void setNextBatchToken(lmdb::txn &txn, const QString &token);
|
||||||
void insertRoomState(lmdb::txn &txn,
|
void insertRoomState(lmdb::txn &txn,
|
||||||
|
|
|
@ -77,6 +77,8 @@ private:
|
||||||
QString userAvatar_;
|
QString userAvatar_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(RoomState)
|
||||||
|
|
||||||
template<class Collection>
|
template<class Collection>
|
||||||
void
|
void
|
||||||
RoomState::updateFromEvents(const std::vector<Collection> &collection)
|
RoomState::updateFromEvents(const std::vector<Collection> &collection)
|
||||||
|
|
|
@ -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 CachedReceipts = std::multimap<uint64_t, std::string, std::greater<uint64_t>>;
|
||||||
using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
|
using Receipts = std::map<std::string, std::map<std::string, uint64_t>>;
|
||||||
|
|
||||||
Cache::Cache(const QString &userId)
|
Cache::Cache(const QString &userId, QObject *parent)
|
||||||
: env_{nullptr}
|
: QObject{parent}
|
||||||
|
, env_{nullptr}
|
||||||
, stateDb_{0}
|
, stateDb_{0}
|
||||||
, roomDb_{0}
|
, roomDb_{0}
|
||||||
, invitesDb_{0}
|
, invitesDb_{0}
|
||||||
|
@ -248,7 +249,7 @@ Cache::removeInvite(const QString &room_id)
|
||||||
txn.commit();
|
txn.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QString, RoomState>
|
void
|
||||||
Cache::states()
|
Cache::states()
|
||||||
{
|
{
|
||||||
QMap<QString, RoomState> states;
|
QMap<QString, RoomState> states;
|
||||||
|
@ -301,7 +302,7 @@ Cache::states()
|
||||||
|
|
||||||
txn.commit();
|
txn.commit();
|
||||||
|
|
||||||
return states;
|
emit statesLoaded(states);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -648,46 +648,51 @@ ChatPage::loadStateFromCache()
|
||||||
qDebug() << "Restored nextBatchToken" << cache_->nextBatchToken();
|
qDebug() << "Restored nextBatchToken" << cache_->nextBatchToken();
|
||||||
client_->setNextBatchToken(cache_->nextBatchToken());
|
client_->setNextBatchToken(cache_->nextBatchToken());
|
||||||
|
|
||||||
// Fetch all the joined room's state.
|
qRegisterMetaType<QMap<QString, RoomState>>();
|
||||||
auto rooms = cache_->states();
|
|
||||||
|
|
||||||
for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) {
|
QtConcurrent::run(cache_.data(), &Cache::states);
|
||||||
auto roomState = QSharedPointer<RoomState>(new RoomState(it.value()));
|
|
||||||
|
|
||||||
// Clean up and prepare state for use.
|
connect(cache_.data(), &Cache::statesLoaded, this, [this](QMap<QString, RoomState> rooms) {
|
||||||
roomState->removeLeaveMemberships();
|
qDebug() << "Cache data loaded";
|
||||||
roomState->resolveName();
|
|
||||||
roomState->resolveAvatar();
|
|
||||||
|
|
||||||
// Save the current room state.
|
for (auto it = rooms.constBegin(); it != rooms.constEnd(); ++it) {
|
||||||
roomStates_.insert(it.key(), roomState);
|
auto roomState = QSharedPointer<RoomState>(new RoomState(it.value()));
|
||||||
|
|
||||||
// Create or restore the settings for this room.
|
// Clean up and prepare state for use.
|
||||||
roomSettings_.insert(it.key(),
|
roomState->removeLeaveMemberships();
|
||||||
QSharedPointer<RoomSettings>(new RoomSettings(it.key())));
|
roomState->resolveName();
|
||||||
|
roomState->resolveAvatar();
|
||||||
|
|
||||||
// Resolve user avatars.
|
// Save the current room state.
|
||||||
for (const auto membership : roomState->memberships) {
|
roomStates_.insert(it.key(), roomState);
|
||||||
updateUserDisplayName(membership.second);
|
|
||||||
updateUserAvatarUrl(membership.second);
|
// 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.
|
// Initializing empty timelines.
|
||||||
view_manager_->initialize(rooms.keys());
|
view_manager_->initialize(rooms.keys());
|
||||||
|
|
||||||
// Initialize room list from the restored state and settings.
|
// Initialize room list from the restored state and settings.
|
||||||
room_list_->setInitialRooms(roomSettings_, roomStates_);
|
room_list_->setInitialRooms(roomSettings_, roomStates_);
|
||||||
room_list_->syncInvites(cache_->invites());
|
room_list_->syncInvites(cache_->invites());
|
||||||
|
|
||||||
// Check periodically if the timelines have been loaded.
|
// Check periodically if the timelines have been loaded.
|
||||||
consensusTimer_->start(CONSENSUS_TIMEOUT);
|
consensusTimer_->start(CONSENSUS_TIMEOUT);
|
||||||
|
|
||||||
// Show the content if consensus can't be achieved.
|
// Show the content if consensus can't be achieved.
|
||||||
showContentTimer_->start(SHOW_CONTENT_TIMEOUT);
|
showContentTimer_->start(SHOW_CONTENT_TIMEOUT);
|
||||||
|
|
||||||
// Start receiving events.
|
// Start receiving events.
|
||||||
client_->sync();
|
client_->sync();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Reference in a new issue