From d19017f87b991479e2f312404500937bf68087b1 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Sat, 22 Feb 2025 14:42:09 +0700 Subject: [PATCH] chore: minor ui fixes --- client/amnezia_application.cpp | 10 ++++++++++ client/amnezia_application.h | 7 +++---- client/core/api/apiDefs.h | 1 + client/core/api/apiUtils.cpp | 12 ++++++++---- client/core/controllers/gatewayController.cpp | 12 +++++++----- .../ui/controllers/api/apiConfigsController.cpp | 17 ++++++++++++++--- .../ui/controllers/api/apiConfigsController.h | 4 ++++ .../controllers/api/apiSettingsController.cpp | 15 ++++++++++++++- .../ui/controllers/api/apiSettingsController.h | 2 +- client/ui/models/api/apiCountryModel.cpp | 9 ++++++++- client/ui/qml/Components/ServersListView.qml | 2 +- client/ui/qml/Pages2/PageHome.qml | 2 +- .../PageSettingsApiAvailableCountries.qml | 2 +- .../qml/Pages2/PageSettingsApiNativeConfigs.qml | 10 +++++----- .../ui/qml/Pages2/PageSettingsApiServerInfo.qml | 12 +++++++++++- .../ui/qml/Pages2/PageSettingsServersList.qml | 2 +- 16 files changed, 90 insertions(+), 29 deletions(-) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 8dea8c0a..f32d525a 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -202,3 +202,13 @@ QQmlApplicationEngine *AmneziaApplication::qmlEngine() const { return m_engine; } + +QNetworkAccessManager *AmneziaApplication::networkManager() +{ + return m_nam; +} + +QClipboard *AmneziaApplication::getClipboard() +{ + return this->clipboard(); +} diff --git a/client/amnezia_application.h b/client/amnezia_application.h index b967f160..ea5f6f52 100644 --- a/client/amnezia_application.h +++ b/client/amnezia_application.h @@ -11,6 +11,7 @@ #else #include #endif +#include #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 {}; diff --git a/client/core/api/apiDefs.h b/client/core/api/apiDefs.h index 2892f90b..41dd80ba 100644 --- a/client/core/api/apiDefs.h +++ b/client/core/api/apiDefs.h @@ -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"); diff --git a/client/core/api/apiUtils.cpp b/client/core/api/apiUtils.cpp index 088fdba1..6166c512 100644 --- a/client/core/api/apiUtils.cpp +++ b/client/core/api/apiUtils.cpp @@ -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; } } diff --git a/client/core/controllers/gatewayController.cpp b/client/core/controllers/gatewayController.cpp index d7a4b018..41fe61f8 100644 --- a/client/core/controllers/gatewayController.cpp +++ b/client/core/controllers/gatewayController.cpp @@ -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 &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; diff --git a/client/ui/controllers/api/apiConfigsController.cpp b/client/ui/controllers/api/apiConfigsController.cpp index 8c6d53c2..0fe304c2 100644 --- a/client/ui/controllers/api/apiConfigsController.cpp +++ b/client/ui/controllers/api/apiConfigsController.cpp @@ -1,13 +1,13 @@ #include "apiConfigsController.h" #include +#include #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; +} diff --git a/client/ui/controllers/api/apiConfigsController.h b/client/ui/controllers/api/apiConfigsController.h index f8354942..26b02978 100644 --- a/client/ui/controllers/api/apiConfigsController.h +++ b/client/ui/controllers/api/apiConfigsController.h @@ -16,12 +16,14 @@ public: Q_PROPERTY(QList 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 getQrCodes(); int getQrCodesCount(); + QString getVpnKey(); QList m_qrCodes; + QString m_vpnKey; QSharedPointer m_serversModel; QSharedPointer m_apiServicesModel; diff --git a/client/ui/controllers/api/apiSettingsController.cpp b/client/ui/controllers/api/apiSettingsController.cpp index 5f436436..53b6e5a8 100644 --- a/client/ui/controllers/api/apiSettingsController.cpp +++ b/client/ui/controllers/api/apiSettingsController.cpp @@ -1,5 +1,8 @@ #include "apiSettingsController.h" +#include +#include + #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; } diff --git a/client/ui/controllers/api/apiSettingsController.h b/client/ui/controllers/api/apiSettingsController.h index 5374e899..e12e232a 100644 --- a/client/ui/controllers/api/apiSettingsController.h +++ b/client/ui/controllers/api/apiSettingsController.h @@ -17,7 +17,7 @@ public: ~ApiSettingsController(); public slots: - bool getAccountInfo(); + bool getAccountInfo(bool reload); void updateApiCountryModel(); signals: diff --git a/client/ui/models/api/apiCountryModel.cpp b/client/ui/models/api/apiCountryModel.cpp index a43184b4..4ded6fed 100644 --- a/client/ui/models/api/apiCountryModel.cpp +++ b/client/ui/models/api/apiCountryModel.cpp @@ -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(); diff --git a/client/ui/qml/Components/ServersListView.qml b/client/ui/qml/Components/ServersListView.qml index 3a6792ac..d0567a8c 100644 --- a/client/ui/qml/Components/ServersListView.qml +++ b/client/ui/qml/Components/ServersListView.qml @@ -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 diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index d189044d..f7233a89 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -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 diff --git a/client/ui/qml/Pages2/PageSettingsApiAvailableCountries.qml b/client/ui/qml/Pages2/PageSettingsApiAvailableCountries.qml index dfbc70b4..f70b646b 100644 --- a/client/ui/qml/Pages2/PageSettingsApiAvailableCountries.qml +++ b/client/ui/qml/Pages2/PageSettingsApiAvailableCountries.qml @@ -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 diff --git a/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml b/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml index b2ab2c05..7fa2b8f4 100644 --- a/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml +++ b/client/ui/qml/Pages2/PageSettingsApiNativeConfigs.qml @@ -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() { } diff --git a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml index befe7370..7080ad26 100644 --- a/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml +++ b/client/ui/qml/Pages2/PageSettingsApiServerInfo.qml @@ -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) } diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml index fcfcd114..554b6cbb 100644 --- a/client/ui/qml/Pages2/PageSettingsServersList.qml +++ b/client/ui/qml/Pages2/PageSettingsServersList.qml @@ -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