Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
abd653ef1c
|
|||
|
9db9ed67d8
|
|||
|
990457042a
|
|||
|
2a5e66d68c
|
@@ -107,10 +107,10 @@ Rectangle
|
||||
function showVideoPopup(index)
|
||||
{
|
||||
imagesModel.setItem(index)
|
||||
imageDetailsPopup.author = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorRole)
|
||||
imageDetailsPopup.authorUrl = searchModel.data(searchModel.index(index,0), VideoSearchModel.AuthorUrlRole)
|
||||
imageDetailsPopup.uuid = searchModel.data(searchModel.index(index,0), VideoSearchModel.UuidRole)
|
||||
imageDetailsPopup.thumbnail = searchModel.data(searchModel.index(index,0), VideoSearchModel.ThumbnailRole)
|
||||
imageDetailsPopup.author = searchModel.data(searchModel.index(index,0), ImageSearchModel.AuthorRole)
|
||||
imageDetailsPopup.authorUrl = searchModel.data(searchModel.index(index,0), ImageSearchModel.AuthorUrlRole)
|
||||
imageDetailsPopup.uuid = searchModel.data(searchModel.index(index,0), ImageSearchModel.UuidRole)
|
||||
imageDetailsPopup.thumbnail = searchModel.data(searchModel.index(index,0), ImageSearchModel.ThumbnailRole)
|
||||
imageDetailsPopup.modelIndex = index
|
||||
imageDetailsPopup.model = searchModel.itemModel
|
||||
imageDetailsPopup.opacity = 1
|
||||
|
||||
@@ -56,6 +56,9 @@ qt_add_qml_module(
|
||||
common/shaderpack.h
|
||||
packcompiler.h
|
||||
packcompiler.cpp
|
||||
SOURCES common/userservices.h
|
||||
SOURCES common/userservices.cpp
|
||||
SOURCES common/qwallet.h common/qwallet.cpp
|
||||
)
|
||||
|
||||
target_compile_definitions(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#include "coreservices.h"
|
||||
#include "logging.h"
|
||||
|
||||
QNetworkAccessManager *CoreServices::s_networkAccessManager = new QNetworkAccessManager();
|
||||
QNetworkAccessManager *CoreServices::s_networkAccessManager = nullptr;
|
||||
QMutex CoreServices::s_networkAccessMutex;
|
||||
QSharedPointer<QNetworkAccessManager> CoreServices::s_networkAccessPointer;
|
||||
|
||||
@@ -11,7 +11,7 @@ auto CoreServices::networkAccessManager() -> QWeakPointer<QNetworkAccessManager>
|
||||
|
||||
if(!s_networkAccessPointer)
|
||||
{
|
||||
s_networkAccessManager = new QNetworkAccessManager;
|
||||
s_networkAccessManager = new QNetworkAccessManager(QCoreApplication::instance());
|
||||
s_networkAccessManager->setAutoDeleteReplies(true);
|
||||
|
||||
QObject::connect(
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef EXCEPTIONS_H
|
||||
#define EXCEPTIONS_H
|
||||
#include <QString>
|
||||
@@ -13,20 +31,22 @@ struct KOMPLEX_EXPORT Exception : std::exception
|
||||
const quint16 errorCode;
|
||||
};
|
||||
|
||||
struct NetworkException : Exception
|
||||
struct KOMPLEX_EXPORT NetworkException : Exception
|
||||
{
|
||||
NetworkException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
};
|
||||
struct FileException : Exception
|
||||
struct KOMPLEX_EXPORT FileException : Exception
|
||||
{
|
||||
FileException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
};
|
||||
struct SqlException : Exception
|
||||
struct KOMPLEX_EXPORT SqlException : Exception
|
||||
{
|
||||
SqlException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
};
|
||||
|
||||
|
||||
struct KOMPLEX_EXPORT WalletException : Exception
|
||||
{
|
||||
WalletException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
};
|
||||
struct KOMPLEX_EXPORT ShaderCompilerException : Exception
|
||||
{
|
||||
ShaderCompilerException(const QString &message, qsizetype errorCode = 0) : Exception(message, errorCode) {}
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef IMAGECACHE_H
|
||||
#define IMAGECACHE_H
|
||||
|
||||
|
||||
@@ -37,42 +37,44 @@
|
||||
#ifdef KOMPLEX_LOCAL_DEV
|
||||
#define KOMPLEX_API_HOST "https://komplexapi.hlab"
|
||||
#else
|
||||
#define KOMPLEX_API_HOST "https://api.komplex.dev"
|
||||
inline const QString KOMPLEX_API_HOST = QStringLiteral("https://api.komplex.dev");
|
||||
#endif
|
||||
|
||||
#define KOMPLEX_API_VERSION "v2"
|
||||
inline const QString KOMPLEX_API_VERSION = QStringLiteral("v2");
|
||||
|
||||
#define KOMPLEX_ENDPOINT_IMAGES_SEARCH "images/search"
|
||||
#define KOMPLEX_ENDPOINT_IMAGES_FEATURED "featured/images"
|
||||
#define KOMPLEX_ENDPOINT_IMAGES_ITEM "images/item"
|
||||
inline const QString KOMPLEX_ENDPOINT_IMAGES_SEARCH = QStringLiteral("images/search");
|
||||
inline const QString KOMPLEX_ENDPOINT_IMAGES_FEATURED = QStringLiteral("featured/images");
|
||||
inline const QString KOMPLEX_ENDPOINT_IMAGES_ITEM = QStringLiteral("images/item");
|
||||
|
||||
#define KOMPLEX_ENDPOINT_VIDEOS_SEARCH "videos/search"
|
||||
#define KOMPLEX_ENDPOINT_VIDEOS_FEATURED "featured/videos"
|
||||
#define KOMPLEX_ENDPOINT_VIDEOS_ITEM "videos/item"
|
||||
inline const QString KOMPLEX_ENDPOINT_VIDEOS_SEARCH = QStringLiteral("videos/search");
|
||||
inline const QString KOMPLEX_ENDPOINT_VIDEOS_FEATURED = QStringLiteral("featured/videos");
|
||||
inline const QString KOMPLEX_ENDPOINT_VIDEOS_ITEM = QStringLiteral("videos/item");
|
||||
|
||||
#define KOMPLEX_ENDPOINT_SHADERS_SEARCH "shaders/search"
|
||||
#define KOMPLEX_ENDPOINT_SHADERS_FEATURED "shaders/featured"
|
||||
#define KOMPLEX_ENDPOINT_SHADERS_ITEM "shaders/item"
|
||||
#define KOMPLEX_ENDPOINT_SHADERS_NEWEST "shaders/newest"
|
||||
inline const QString KOMPLEX_ENDPOINT_SHADERS_SEARCH = QStringLiteral("shaders/search");
|
||||
inline const QString KOMPLEX_ENDPOINT_SHADERS_FEATURED = QStringLiteral("shaders/featured");
|
||||
inline const QString KOMPLEX_ENDPOINT_SHADERS_ITEM = QStringLiteral("shaders/item");
|
||||
inline const QString KOMPLEX_ENDPOINT_SHADERS_NEWEST = QStringLiteral("shaders/newest");
|
||||
|
||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_SEARCH "cubemaps/search"
|
||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_FEATURED "cubemaps/featured"
|
||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_ITEM "cubemaps/item"
|
||||
#define KOMPLEX_ENDPOINT_CUBEMAPS_NEWEST "cubemaps/newest"
|
||||
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_SEARCH = QStringLiteral("cubemaps/search");
|
||||
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_FEATURED = QStringLiteral("cubemaps/featured");
|
||||
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_ITEM = QStringLiteral("cubemaps/item");
|
||||
inline const QString KOMPLEX_ENDPOINT_CUBEMAPS_NEWEST = QStringLiteral("cubemaps/newest");
|
||||
|
||||
#define KOMPLEX_ENDPOINT_PACKS_SEARCH "packs/search"
|
||||
#define KOMPLEX_ENDPOINT_PACKS_FEATURED "packs/featured"
|
||||
#define KOMPLEX_ENDPOINT_PACKS_ITEM "packs/item"
|
||||
#define KOMPLEX_ENDPOINT_PACKS_NEWEST "packs/newest"
|
||||
inline const QString KOMPLEX_ENDPOINT_PACKS_SEARCH = QStringLiteral("packs/search");
|
||||
inline const QString KOMPLEX_ENDPOINT_PACKS_FEATURED = QStringLiteral("packs/featured");
|
||||
inline const QString KOMPLEX_ENDPOINT_PACKS_ITEM = QStringLiteral("packs/item");
|
||||
inline const QString KOMPLEX_ENDPOINT_PACKS_NEWEST = QStringLiteral("packs/newest");
|
||||
|
||||
inline static qsizetype nullsize = std::numeric_limits<qsizetype>::min();
|
||||
inline static std::chrono::milliseconds KOMPLEX_RATE_LIMIT(500);
|
||||
inline static QString KOMPLEX_KEYCHAIN_PASSWORD_KEY = QStringLiteral
|
||||
inline const QString KOMPLEX_ENDPOINT_USER_AUTH = QStringLiteral("user/auth");
|
||||
|
||||
inline const qsizetype nullsize = std::numeric_limits<qsizetype>::min();
|
||||
inline const std::chrono::milliseconds KOMPLEX_RATE_LIMIT(500);
|
||||
inline const QString KOMPLEX_KEYCHAIN_PASSWORD_KEY = QStringLiteral
|
||||
(
|
||||
"com.digitalartifex.komplex.keychain.password"
|
||||
);
|
||||
|
||||
inline static QString KOMPLEX_KEYCHAIN_TOKEN_KEY = QStringLiteral
|
||||
inline const QString KOMPLEX_KEYCHAIN_TOKEN_KEY = QStringLiteral
|
||||
(
|
||||
"com.digitalartifex.komplex.keychain.token"
|
||||
);
|
||||
|
||||
@@ -0,0 +1,135 @@
|
||||
#include "qwallet.h"
|
||||
#include "../3rdparty/qtkeychain/qtkeychain/keychain.h"
|
||||
|
||||
auto QWallet::read(const QString &service, const QString &key) const -> QFuture<QByteArray>
|
||||
{
|
||||
return QtConcurrent::run
|
||||
(
|
||||
[this, service(service), key(key)]() -> QByteArray
|
||||
{
|
||||
QEventLoop loop;
|
||||
QByteArray value;
|
||||
|
||||
auto readCredentialJob = new QKeychain::ReadPasswordJob(service);
|
||||
readCredentialJob->setAutoDelete(true);
|
||||
readCredentialJob->setKey(key);
|
||||
|
||||
QObject::connect
|
||||
(
|
||||
readCredentialJob,
|
||||
&QKeychain::ReadPasswordJob::finished,
|
||||
this,
|
||||
[this, key, &loop, &value](QKeychain::Job *job)
|
||||
{
|
||||
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||
if (j->error() == QKeychain::NoError)
|
||||
{
|
||||
value = j->binaryData();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_errorString = qPrintable(j->errorString());
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
loop.quit();
|
||||
}
|
||||
);
|
||||
|
||||
readCredentialJob->start();
|
||||
loop.exec();
|
||||
|
||||
return value;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
auto QWallet::write(const QString &service, const QString &key, const QByteArray &value) -> QFuture<void>
|
||||
{
|
||||
return QtConcurrent::run
|
||||
(
|
||||
[this, service(service), key(key), value(value)]() -> void
|
||||
{
|
||||
QEventLoop loop;
|
||||
bool success;
|
||||
|
||||
auto writeCredentialJob = new QKeychain::WritePasswordJob(service);
|
||||
writeCredentialJob->setAutoDelete(true);
|
||||
writeCredentialJob->setKey(key);
|
||||
writeCredentialJob->setBinaryData(value);
|
||||
|
||||
QObject::connect
|
||||
(
|
||||
writeCredentialJob,
|
||||
&QKeychain::WritePasswordJob::finished,
|
||||
this,
|
||||
[this, key, &loop, &success](QKeychain::Job *job)
|
||||
{
|
||||
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||
if (j->error() != QKeychain::NoError)
|
||||
{
|
||||
setErrorString(qPrintable(j->errorString()));
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
loop.quit();
|
||||
}
|
||||
);
|
||||
|
||||
writeCredentialJob->start();
|
||||
loop.exec();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
auto QWallet::remove(const QString &service, const QString &key) -> QFuture<void>
|
||||
{
|
||||
return QtConcurrent::run
|
||||
(
|
||||
[this, service(service), key(key)]() -> void
|
||||
{
|
||||
QEventLoop loop;
|
||||
bool value;
|
||||
|
||||
auto deleteCredentialJob = new QKeychain::DeletePasswordJob(service);
|
||||
deleteCredentialJob->setAutoDelete(true);
|
||||
deleteCredentialJob->setKey(key);
|
||||
|
||||
QObject::connect
|
||||
(
|
||||
deleteCredentialJob,
|
||||
&QKeychain::DeletePasswordJob::finished,
|
||||
this,
|
||||
[this, key, &loop, &value](QKeychain::Job *job)
|
||||
{
|
||||
auto j = static_cast<QKeychain::ReadPasswordJob*>(job);
|
||||
if (j->error() != QKeychain::NoError)
|
||||
{
|
||||
m_errorString = qPrintable(j->errorString());
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
loop.quit();
|
||||
}
|
||||
);
|
||||
|
||||
deleteCredentialJob->start();
|
||||
loop.exec();
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
QWallet::QWallet(QObject *parent) : QObject(parent)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QWallet::~QWallet()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
auto QWallet::errorString() const -> const QString &
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef QWALLET_H
|
||||
#define QWALLET_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QFuture>
|
||||
#include <QEventLoop>
|
||||
#include <QtConcurrent/QtConcurrentRun>
|
||||
|
||||
#include "komplex_global.h"
|
||||
|
||||
/**
|
||||
* @brief The QWallet class
|
||||
* QWallet is a QFuture wrapper for QtKeychain to make interaction with the keychain easier
|
||||
*/
|
||||
class KOMPLEX_EXPORT QWallet : QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QWallet(QObject *parent = nullptr);
|
||||
~QWallet();
|
||||
|
||||
/**
|
||||
* @brief read
|
||||
* Reads the provided key from the system keychain/wallet
|
||||
* @param service
|
||||
* Service name of the application making the request
|
||||
* @param key
|
||||
* Key to read
|
||||
* @return
|
||||
* QFuture for the binary value
|
||||
*/
|
||||
[[nodiscard]]
|
||||
auto read(const QString &service, const QString &key) const -> QFuture<QByteArray>;
|
||||
|
||||
/**
|
||||
* @brief write
|
||||
* Writes the provided value to the system kaychain/wallet
|
||||
* @param service
|
||||
* Service name of the application making the request
|
||||
* @param key
|
||||
* Key to read
|
||||
* @param value
|
||||
* Binary data to store
|
||||
* @return
|
||||
* QFuture
|
||||
*/
|
||||
[[nodiscard]]
|
||||
auto write(const QString &service, const QString &key, const QByteArray &value) -> QFuture<void>;
|
||||
|
||||
/**
|
||||
* @brief write
|
||||
* Removes the provided value from the system kaychain/wallet
|
||||
* @param service
|
||||
* Service name of the application making the request
|
||||
* @param key
|
||||
* Key to read
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]]
|
||||
auto remove(const QString &service, const QString &key) -> QFuture<void>;
|
||||
|
||||
/**
|
||||
* @brief errorString
|
||||
* String describing the last encountered error.
|
||||
* @return
|
||||
*/
|
||||
[[nodiscard]]
|
||||
auto errorString() const -> const QString &;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief setErrorString
|
||||
* Sets the error string
|
||||
* @param errorString
|
||||
*/
|
||||
auto setErrorString(const QString &errorString) const -> void;
|
||||
|
||||
mutable QString m_errorString;
|
||||
};
|
||||
|
||||
#endif // QWALLET_H
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef SHADERPACK_H
|
||||
#define SHADERPACK_H
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef SHADERTOYMETADATA_H
|
||||
#define SHADERTOYMETADATA_H
|
||||
#include <QObject>
|
||||
|
||||
@@ -0,0 +1,148 @@
|
||||
#include "userservices.h"
|
||||
#include "coreservices.h"
|
||||
|
||||
UserServices::UserServices(QObject *parent) : QObject(parent)
|
||||
{
|
||||
m_wallet = new QWallet(this);
|
||||
}
|
||||
|
||||
UserServices::~UserServices()
|
||||
{
|
||||
}
|
||||
|
||||
auto UserServices::setUserCredentials(const UserCredentials &credentials) -> void
|
||||
{
|
||||
s_userCredentials = credentials;
|
||||
Q_EMIT userCredentialsChanged();
|
||||
}
|
||||
|
||||
auto UserServices::errorString() const -> const QString &
|
||||
{
|
||||
return m_errorString;
|
||||
}
|
||||
|
||||
auto UserServices::setErrorString(const QString &errorString) -> void
|
||||
{
|
||||
if (m_errorString == errorString)
|
||||
return;
|
||||
m_errorString = errorString;
|
||||
emit errorStringChanged();
|
||||
}
|
||||
|
||||
auto UserServices::instance() const -> QWeakPointer<UserServices>
|
||||
{
|
||||
if(!s_pointer)
|
||||
{
|
||||
s_instance = new UserServices(QCoreApplication::instance());
|
||||
s_pointer = QSharedPointer<UserServices>
|
||||
(
|
||||
s_instance,
|
||||
&UserServices::deleteLater
|
||||
);
|
||||
}
|
||||
|
||||
return s_pointer.toWeakRef();
|
||||
}
|
||||
|
||||
auto UserServices::userCredentials() -> const UserCredentials &
|
||||
{
|
||||
return s_userCredentials;
|
||||
}
|
||||
|
||||
auto UserServices::login(const QString &username, const QByteArray &password) -> QFuture<UserCredentials>
|
||||
{
|
||||
return QtConcurrent::run
|
||||
(
|
||||
[this, username = std::move(username), password = std::move(password)] () -> UserCredentials
|
||||
{
|
||||
QSharedPointer<QNetworkAccessManager> manager = CoreServices::networkAccessManager().toStrongRef();
|
||||
|
||||
if(!manager)
|
||||
{
|
||||
Q_EMIT loginFailed();
|
||||
return {};
|
||||
}
|
||||
|
||||
QNetworkRequest request
|
||||
(
|
||||
QUrl
|
||||
(
|
||||
QStringLiteral("%1/%2/%3").arg
|
||||
(
|
||||
KOMPLEX_API_HOST,
|
||||
KOMPLEX_API_VERSION,
|
||||
KOMPLEX_ENDPOINT_USER_AUTH
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
QJsonObject loginRootObject
|
||||
{
|
||||
{
|
||||
QString("username"),
|
||||
QJsonValue::fromVariant(username.toUtf8())
|
||||
},
|
||||
{
|
||||
QString("password"),
|
||||
QJsonValue::fromVariant(password.toBase64())
|
||||
}
|
||||
};
|
||||
|
||||
QJsonDocument loginDocument(loginRootObject);
|
||||
|
||||
QNetworkReply *reply = manager->post(request, loginDocument.toJson(QJsonDocument::Compact));
|
||||
|
||||
while(!reply->isFinished())
|
||||
{
|
||||
std::chrono::milliseconds(10);
|
||||
}
|
||||
|
||||
if(reply->error() != QNetworkReply::NoError)
|
||||
{
|
||||
setErrorString(reply->errorString());
|
||||
throw std::exception();
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
|
||||
QJsonParseError parseError;
|
||||
QJsonDocument document = QJsonDocument::fromJson(data, &parseError);
|
||||
|
||||
if(parseError.error != QJsonParseError::NoError)
|
||||
{
|
||||
setErrorString(parseError.errorString());
|
||||
}
|
||||
|
||||
QJsonObject rootObject;
|
||||
|
||||
if(!rootObject.value("success").toBool())
|
||||
{
|
||||
QJsonObject dataObject = rootObject.value(QStringLiteral("data")).toObject();
|
||||
|
||||
setErrorString
|
||||
(
|
||||
QStringLiteral("Login failure (%1): %2").arg
|
||||
(
|
||||
dataObject.value(QStringLiteral("errorCode")).toString(),
|
||||
dataObject.value(QStringLiteral("message")).toString()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
UserCredentials credentials
|
||||
{
|
||||
.username = username.toUtf8(),
|
||||
.sessionToken = rootObject.value
|
||||
(
|
||||
QStringLiteral("jwt")
|
||||
).toString().toUtf8(),
|
||||
.expiry = QDateTime::currentDateTime()
|
||||
};
|
||||
|
||||
setUserCredentials(credentials);
|
||||
|
||||
Q_EMIT loginComplete();
|
||||
return credentials;
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QObject>
|
||||
#include <QDateTime>
|
||||
#include <QSharedPointer>
|
||||
#include <QFuture>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include "komplex_global.h"
|
||||
#include "qwallet.h"
|
||||
|
||||
struct UserCredentials
|
||||
{
|
||||
QByteArray username;
|
||||
QByteArray sessionToken;
|
||||
QDateTime expiry;
|
||||
|
||||
UserCredentials &operator = (const UserCredentials &other)
|
||||
{
|
||||
username = other.username;
|
||||
sessionToken = other.sessionToken;
|
||||
expiry = other.expiry;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool isValid()
|
||||
{
|
||||
return !username.isEmpty() && username.isValidUtf8() &&
|
||||
!sessionToken.isEmpty() && sessionToken.isValidUtf8();
|
||||
}
|
||||
};
|
||||
|
||||
class KOMPLEX_EXPORT UserServices : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
auto instance() const -> QWeakPointer<UserServices>;
|
||||
static auto userCredentials() -> const UserCredentials &;
|
||||
auto login(const QString &username, const QByteArray &password) -> QFuture<UserCredentials>;
|
||||
|
||||
auto errorString() const -> const QString &;
|
||||
|
||||
signals:
|
||||
auto loginComplete() -> void;
|
||||
auto loginFailed() -> void;
|
||||
auto userCredentialsChanged() -> void;
|
||||
|
||||
auto errorStringChanged() -> void;
|
||||
|
||||
private:
|
||||
inline static UserServices *s_instance = nullptr;
|
||||
inline static QSharedPointer<UserServices> s_pointer;
|
||||
|
||||
explicit UserServices(QObject *parent);
|
||||
~UserServices();
|
||||
|
||||
auto setUserCredentials(const UserCredentials &credentials) -> void;
|
||||
auto setErrorString(const QString &errorString) -> void;
|
||||
|
||||
QWallet *m_wallet = nullptr;
|
||||
QString m_errorString;
|
||||
inline static UserCredentials s_userCredentials;
|
||||
Q_PROPERTY(UserCredentials userCredentials READ userCredentials NOTIFY userCredentialsChanged FINAL)
|
||||
Q_PROPERTY(QString errorString READ errorString WRITE setErrorString NOTIFY errorStringChanged FINAL)
|
||||
};
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef VIDEOCACHE_H
|
||||
#define VIDEOCACHE_H
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef DOWNLOADMANAGER_H
|
||||
#define DOWNLOADMANAGER_H
|
||||
|
||||
|
||||
@@ -1,3 +1,21 @@
|
||||
/*
|
||||
* Komplex Wallpaper Engine
|
||||
* Copyright (C) 2026 @DigitalArtifex
|
||||
* https://digitalartifex.dev - https://github.com/DigitalArtifex
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>
|
||||
*/
|
||||
#ifndef PACKCOMPILER_H
|
||||
#define PACKCOMPILER_H
|
||||
|
||||
|
||||
Reference in New Issue
Block a user