chore: minor ui fixes

This commit is contained in:
vladimir.kuznetsov 2025-02-22 14:42:09 +07:00
parent 6a424e9858
commit d19017f87b
16 changed files with 90 additions and 29 deletions

View file

@ -202,3 +202,13 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const
{
return m_engine;
}
QNetworkAccessManager *AmneziaApplication::networkManager()
{
return m_nam;
}
QClipboard *AmneziaApplication::getClipboard()
{
return this->clipboard();
}

View file

@ -11,6 +11,7 @@
#else
#include <QApplication>
#endif
#include <QClipboard>
#include "core/controllers/coreController.h"
#include "settings.h"
@ -41,10 +42,8 @@ public:
#endif
QQmlApplicationEngine *qmlEngine() const;
QNetworkAccessManager *manager()
{
return m_nam;
}
QNetworkAccessManager *networkManager();
QClipboard *getClipboard();
private:
QQmlApplicationEngine *m_engine {};

View file

@ -24,6 +24,7 @@ namespace apiDefs
constexpr QLatin1String apiConfig("api_config");
constexpr QLatin1String stackType("stack_type");
constexpr QLatin1String serviceType("service_type");
constexpr QLatin1String vpnKey("vpn_key");

View file

@ -27,15 +27,19 @@ apiDefs::ConfigType apiUtils::getConfigType(const QJsonObject &serverConfigObjec
case apiDefs::ConfigSource::Telegram: {
};
case apiDefs::ConfigSource::AmneziaGateway: {
constexpr QLatin1String premium("prem");
constexpr QLatin1String free("free");
constexpr QLatin1String stackPremium("prem");
constexpr QLatin1String stackFree("free");
constexpr QLatin1String servicePremium("amnezia-premium");
constexpr QLatin1String serviceFree("amnezia-free");
auto apiConfigObject = serverConfigObject.value(apiDefs::key::apiConfig).toObject();
auto stackType = apiConfigObject.value(apiDefs::key::stackType).toString();
auto serviceType = apiConfigObject.value(apiDefs::key::serviceType).toString();
if (stackType == premium) {
if (serviceType == servicePremium || stackType == stackPremium) {
return apiDefs::ConfigType::AmneziaPremiumV2;
} else if (stackType == free) {
} else if (serviceType == serviceFree || stackType == stackFree) {
return apiDefs::ConfigType::AmneziaFreeV3;
}
}

View file

@ -47,7 +47,7 @@ ErrorCode GatewayController::get(const QString &endpoint, QByteArray &responseBo
request.setUrl(QString(endpoint).arg(m_gatewayEndpoint));
QNetworkReply *reply;
reply = amnApp->manager()->get(request);
reply = amnApp->networkManager()->get(request);
QEventLoop wait;
QObject::connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
@ -61,7 +61,7 @@ ErrorCode GatewayController::get(const QString &endpoint, QByteArray &responseBo
if (sslErrors.isEmpty() && shouldBypassProxy(reply, responseBody, false)) {
auto requestFunction = [&request, &responseBody](const QString &url) {
request.setUrl(url);
return amnApp->manager()->get(request);
return amnApp->networkManager()->get(request);
};
auto replyProcessingFunction = [&responseBody, &reply, &sslErrors, this](QNetworkReply *nestedReply,
@ -137,7 +137,7 @@ ErrorCode GatewayController::post(const QString &endpoint, const QJsonObject api
requestBody[configKey::keyPayload] = QString(encryptedKeyPayload.toBase64());
requestBody[configKey::apiPayload] = QString(encryptedApiPayload.toBase64());
QNetworkReply *reply = amnApp->manager()->post(request, QJsonDocument(requestBody).toJson());
QNetworkReply *reply = amnApp->networkManager()->post(request, QJsonDocument(requestBody).toJson());
QEventLoop wait;
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
@ -151,7 +151,7 @@ ErrorCode GatewayController::post(const QString &endpoint, const QJsonObject api
if (sslErrors.isEmpty() && shouldBypassProxy(reply, encryptedResponseBody, false)) {
auto requestFunction = [&request, &encryptedResponseBody, &requestBody](const QString &url) {
request.setUrl(url);
return amnApp->manager()->post(request, QJsonDocument(requestBody).toJson());
return amnApp->networkManager()->post(request, QJsonDocument(requestBody).toJson());
};
auto replyProcessingFunction = [&encryptedResponseBody, &reply, &sslErrors, &key, &iv, &salt,
@ -205,7 +205,7 @@ QStringList GatewayController::getProxyUrls()
for (const auto &proxyStorageUrl : proxyStorageUrl) {
request.setUrl(proxyStorageUrl);
reply = amnApp->manager()->get(request);
reply = amnApp->networkManager()->get(request);
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
connect(reply, &QNetworkReply::sslErrors, [this, &sslErrors](const QList<QSslError> &errors) { sslErrors = errors; });
@ -256,6 +256,8 @@ QStringList GatewayController::getProxyUrls()
bool GatewayController::shouldBypassProxy(QNetworkReply *reply, const QByteArray &responseBody, bool checkEncryption, const QByteArray &key,
const QByteArray &iv, const QByteArray &salt)
{
qDebug() << reply->error();
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError || reply->error() == QNetworkReply::NetworkError::TimeoutError) {
qDebug() << "Timeout occurred";
return true;

View file

@ -1,13 +1,13 @@
#include "apiConfigsController.h"
#include <QEventLoop>
#include <QClipboard>
#include "amnezia_application.h"
#include "configurators/wireguard_configurator.h"
#include "core/api/apiDefs.h"
#include "core/api/apiUtils.h"
#include "core/controllers/gatewayController.h"
#include "core/networkUtilities.h"
#include "core/qrCodeUtils.h"
#include "ui/controllers/systemController.h"
#include "version.h"
@ -76,7 +76,6 @@ bool ApiConfigsController::exportNativeConfig(const QString &serverCountryCode,
apiPayload[configKey::serverCountryCode] = serverCountryCode;
apiPayload[configKey::serviceType] = apiConfigObject.value(configKey::serviceType);
apiPayload[configKey::authData] = serverConfigObject.value(configKey::authData);
apiPayload[configKey::uuid] = m_settings->getInstallationUuid(true);
QByteArray responseBody;
ErrorCode errorCode = gatewayController.post(QString("%1v1/native_config"), apiPayload, responseBody);
@ -124,6 +123,7 @@ void ApiConfigsController::prepareVpnKeyExport()
auto apiConfigObject = serverConfigObject.value(configKey::apiConfig).toObject();
auto vpnKey = apiConfigObject.value(apiDefs::key::vpnKey).toString();
m_vpnKey = vpnKey;
vpnKey.replace("vpn://", "");
@ -132,6 +132,12 @@ void ApiConfigsController::prepareVpnKeyExport()
emit vpnKeyExportReady();
}
void ApiConfigsController::copyVpnKeyToClipboard()
{
auto clipboard = amnApp->getClipboard();
clipboard->setText(m_vpnKey);
}
bool ApiConfigsController::fillAvailableServices()
{
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), apiDefs::requestTimeoutMsecs);
@ -288,7 +294,7 @@ bool ApiConfigsController::updateServiceFromTelegram(const int serverIndex)
QByteArray requestBody = QJsonDocument(apiPayload).toJson();
QNetworkReply *reply = amnApp->manager()->post(request, requestBody);
QNetworkReply *reply = amnApp->networkManager()->post(request, requestBody);
QEventLoop wait;
connect(reply, &QNetworkReply::finished, &wait, &QEventLoop::quit);
@ -477,3 +483,8 @@ int ApiConfigsController::getQrCodesCount()
{
return m_qrCodes.size();
}
QString ApiConfigsController::getVpnKey()
{
return m_vpnKey;
}

View file

@ -16,12 +16,14 @@ public:
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY vpnKeyExportReady)
Q_PROPERTY(int qrCodesCount READ getQrCodesCount NOTIFY vpnKeyExportReady)
Q_PROPERTY(QString vpnKey READ getVpnKey NOTIFY vpnKeyExportReady)
public slots:
bool exportNativeConfig(const QString &serverCountryCode, const QString &fileName);
bool revokeNativeConfig(const QString &serverCountryCode);
// bool exportVpnKey(const QString &fileName);
void prepareVpnKeyExport();
void copyVpnKeyToClipboard();
bool fillAvailableServices();
bool importServiceFromGateway();
@ -58,8 +60,10 @@ private:
QList<QString> getQrCodes();
int getQrCodesCount();
QString getVpnKey();
QList<QString> m_qrCodes;
QString m_vpnKey;
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ApiServicesModel> m_apiServicesModel;

View file

@ -1,5 +1,8 @@
#include "apiSettingsController.h"
#include <QEventLoop>
#include <QTimer>
#include "core/api/apiUtils.h"
#include "core/controllers/gatewayController.h"
@ -35,8 +38,14 @@ ApiSettingsController::~ApiSettingsController()
{
}
bool ApiSettingsController::getAccountInfo()
bool ApiSettingsController::getAccountInfo(bool reload)
{
if (reload) {
QEventLoop wait;
QTimer::singleShot(1000, &wait, &QEventLoop::quit);
wait.exec();
}
GatewayController gatewayController(m_settings->getGatewayEndpoint(), m_settings->isDevGatewayEnv(), requestTimeoutMsecs);
auto processedIndex = m_serversModel->getProcessedServerIndex();
@ -62,6 +71,10 @@ bool ApiSettingsController::getAccountInfo()
QJsonObject accountInfo = QJsonDocument::fromJson(responseBody).object();
m_apiAccountInfoModel->updateModel(accountInfo, serverConfig);
if (reload) {
updateApiCountryModel();
}
return true;
}

View file

@ -17,7 +17,7 @@ public:
~ApiSettingsController();
public slots:
bool getAccountInfo();
bool getAccountInfo(bool reload);
void updateApiCountryModel();
signals:

View file

@ -8,6 +8,8 @@
namespace
{
Logger logger("ApiCountryModel");
constexpr QLatin1String countryConfig("country_config");
}
ApiCountryModel::ApiCountryModel(QObject *parent) : QAbstractListModel(parent)
@ -27,7 +29,7 @@ QVariant ApiCountryModel::data(const QModelIndex &index, int role) const
CountryInfo countryInfo = m_countries.at(index.row());
IssuedConfigInfo issuedConfigInfo = m_issuedConfigs.value(countryInfo.countryCode);
bool isIssued = !issuedConfigInfo.lastDownloaded.isEmpty();
bool isIssued = issuedConfigInfo.sourceType == countryConfig;
switch (role) {
case CountryCodeRole: {
@ -73,10 +75,15 @@ void ApiCountryModel::updateIssuedConfigsInfo(const QJsonArray &issuedConfigs)
{
beginResetModel();
m_issuedConfigs.clear();
for (int i = 0; i < issuedConfigs.size(); i++) {
IssuedConfigInfo issuedConfigInfo;
QJsonObject issuedConfigObject = issuedConfigs.at(i).toObject();
if (issuedConfigObject.value(apiDefs::key::sourceType).toString() != countryConfig) {
continue;
}
issuedConfigInfo.installationUuid = issuedConfigObject.value(apiDefs::key::installationUuid).toString();
issuedConfigInfo.workerLastUpdated = issuedConfigObject.value(apiDefs::key::workerLastUpdated).toString();
issuedConfigInfo.lastDownloaded = issuedConfigObject.value(apiDefs::key::lastDownloaded).toString();

View file

@ -116,7 +116,7 @@ ListView {
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
} else {
PageController.showBusyIndicator(true)
let result = ApiSettingsController.getAccountInfo()
let result = ApiSettingsController.getAccountInfo(false)
PageController.showBusyIndicator(false)
if (!result) {
return

View file

@ -303,7 +303,7 @@ PageType {
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
} else {
PageController.showBusyIndicator(true)
let result = ApiSettingsController.getAccountInfo()
let result = ApiSettingsController.getAccountInfo(false)
PageController.showBusyIndicator(false)
if (!result) {
return

View file

@ -93,7 +93,7 @@ PageType {
actionButtonFunction: function() {
PageController.showBusyIndicator(true)
let result = ApiSettingsController.getAccountInfo()
let result = ApiSettingsController.getAccountInfo(false)
PageController.showBusyIndicator(false)
if (!result) {
return

View file

@ -54,7 +54,6 @@ PageType {
width: listView.width
LabelWithButtonType {
id: telegramButton
Layout.fillWidth: true
Layout.topMargin: 6
@ -67,8 +66,9 @@ PageType {
moreOptionsDrawer.countryName = countryName
moreOptionsDrawer.countryCode = countryCode
moreOptionsDrawer.openTriggered()
} else {
issueConfig(countryCode)
}
issueConfig(countryCode)
}
}
@ -166,11 +166,10 @@ PageType {
PageController.showBusyIndicator(true)
let result = ApiConfigsController.exportNativeConfig(countryCode, fileName)
if (result) {
ApiSettingsController.getAccountInfo()
ApiSettingsController.getAccountInfo(true)
}
PageController.showBusyIndicator(false)
if (result) {
PageController.showNotificationMessage(qsTr("Config file saved"))
}
@ -181,7 +180,7 @@ PageType {
PageController.showBusyIndicator(true)
let result = ApiConfigsController.revokeNativeConfig(countryCode)
if (result) {
ApiSettingsController.getAccountInfo()
ApiSettingsController.getAccountInfo(true)
}
PageController.showBusyIndicator(false)
@ -202,6 +201,7 @@ PageType {
} else {
revokeConfig(countryCode)
}
moreOptionsDrawer.closeTriggered()
}
var noButtonFunction = function() {
}

View file

@ -128,7 +128,17 @@ PageType {
width: listView.width
spacing: 0
Connections {
target: ApiAccountInfoModel
function onModelReset() {
delegateItem.rightText = ApiAccountInfoModel.data(contentKey)
}
}
LabelWithImageType {
id: delegateItem
Layout.fillWidth: true
Layout.margins: 16
@ -290,7 +300,7 @@ PageType {
} else {
PageController.showBusyIndicator(true)
if (ApiConfigsController.deactivateDevice()) {
ApiSettingsController.getAccountInfo()
ApiSettingsController.getAccountInfo(true)
}
PageController.showBusyIndicator(false)
}

View file

@ -96,7 +96,7 @@ PageType {
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
PageController.showBusyIndicator(true)
let result = ApiSettingsController.getAccountInfo()
let result = ApiSettingsController.getAccountInfo(false)
PageController.showBusyIndicator(false)
if (!result) {
return