1
Fork 0
mirror of https://github.com/redstrate/Astra.git synced 2025-04-20 03:37:47 +00:00
astra/launcher/include/syncmanager.h
Joshua Goins 807cf0e062 Improve character sync error handling, and the sync itself
Ported from libQuotient's invokeLogin to our own custom one, so we can
avoid the initial sync until login. Then, make sure we find the room
*after* the sync, not before it.

Also since I wiped the media cache from my server, I hit a crash since
it tried to open an invalid ZIP file. Now we can handle that.
2024-11-09 15:47:34 -05:00

116 lines
3.1 KiB
C++

// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
#pragma once
#include <QObject>
#include <Quotient/accountregistry.h>
#include <Quotient/connection.h>
#include <qcorotask.h>
/**
* @brief Handles setting up the connection to Matrix and all of the fun things needed to do for that.
* Does NOT handle the actual synchronization process, see @c CharacterSync.
*/
class SyncManager : public QObject
{
Q_OBJECT
Q_PROPERTY(bool connected READ connected NOTIFY connectedChanged)
Q_PROPERTY(QString userId READ userId NOTIFY userIdChanged)
Q_PROPERTY(Quotient::Connection *connection READ connection NOTIFY connectionChanged)
public:
explicit SyncManager(QObject *parent = nullptr);
/**
* @brief Log in to a connection
* @param matrixId user id in the form @user:server.tld
* @param password
*/
Q_INVOKABLE void login(const QString &matrixId, const QString &password);
/**
* @brief Log out of the connection
*/
Q_INVOKABLE void logout();
/**
* @brief Run a single sync. We're not syncing constantly, since we typically don't need it and it consumes a lot of data.
*/
Q_INVOKABLE QCoro::Task<> sync();
/**
* @return Whether there is a connection to the server.
*/
bool connected() const;
/**
* @return The currently logged in user.
*/
QString userId() const;
/**
* @return The LibQuotient connection.
*/
Quotient::Connection *connection() const;
/**
* @return If we're ready to begin downloading or uploading data
*/
bool isReady() const;
struct PreviousCharacterData {
QString mxcUri;
QString hostname;
QMap<QString, QString> fileHashes;
};
/**
* @return The currently uploaded character data, or nullopt if there's none for @p id.
*/
QCoro::Task<std::optional<PreviousCharacterData>> getUploadedCharacterData(const QString &id);
/**
* @brief Uploads character data for @p id from @p path.
* @return True if uploaded successfuly, false otherwise.
*/
QCoro::Task<bool> uploadCharacterArchive(const QString &id, const QString &path, const QMap<QString, QString> &fileHashes);
/**
* @brief Downloads the character data archive from @p mxcUri and extracts it in @p destPath.
*/
QCoro::Task<bool> downloadCharacterArchive(const QString &mxcUri, const QString &destPath);
/**
* @brief Checks if there's a lock.
*/
QCoro::Task<std::optional<QString>> checkLock();
/**
* @brief Sets the sync to the device's hostname.
*/
QCoro::Task<> setLock();
/**
* @brief Breaks the current sync lock.
*/
QCoro::Task<> breakLock();
Q_SIGNALS:
void connectedChanged();
void userIdChanged();
void connectionChanged();
void isReadyChanged();
void loginError(const QString &message);
private:
void invokeLogin();
QString roomId() const;
void setRoomId(const QString &roomId);
QCoro::Task<> findRoom();
Quotient::AccountRegistry m_accountRegistry;
Quotient::Room *m_currentRoom = nullptr;
};