mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
Merge branch 'dev' of github-amnezia:amnezia-vpn/amnezia-client into HEAD
This commit is contained in:
@@ -460,6 +460,7 @@ ErrorCode SubscriptionController::updateServiceFromGateway(const QString &server
|
||||
|
||||
if (apiV2->nameOverriddenByUser) {
|
||||
newApiV2->name = apiV2->name;
|
||||
newApiV2->displayName = apiV2->displayName;
|
||||
newApiV2->nameOverriddenByUser = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,9 +6,7 @@
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/utilities.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/utils/serverConfigUtils.h"
|
||||
#include "version.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
@@ -67,13 +65,15 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
bool isApiConfig = false;
|
||||
|
||||
const auto kind = m_serversRepository->serverKind(serverId);
|
||||
const QString primaryDns = m_appSettingsRepository->primaryDns();
|
||||
const QString secondaryDns = m_appSettingsRepository->secondaryDns();
|
||||
switch (kind) {
|
||||
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
|
||||
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
dns = cfg->getDnsPair(m_appSettingsRepository->useAmneziaDns(), primaryDns, secondaryDns);
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
@@ -83,7 +83,7 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
dns = cfg->getDnsPair(primaryDns, secondaryDns);
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
@@ -93,7 +93,7 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
dns = cfg->getDnsPair(primaryDns, secondaryDns);
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
break;
|
||||
@@ -105,7 +105,7 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
if (!cfg.has_value()) return ErrorCode::InternalError;
|
||||
container = cfg->defaultContainer;
|
||||
containerConfigModel = cfg->containerConfig(container);
|
||||
dns = { cfg->dns1, cfg->dns2 };
|
||||
dns = cfg->getDnsPair(primaryDns, secondaryDns);
|
||||
hostName = cfg->hostName;
|
||||
description = cfg->description;
|
||||
configVersion = serverConfigUtils::ConfigSource::AmneziaGateway;
|
||||
@@ -123,16 +123,6 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
|
||||
if (!isContainerSupported(container)) {
|
||||
return ErrorCode::NotSupportedOnThisPlatform;
|
||||
}
|
||||
if (dns.first.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.first)) {
|
||||
if (m_appSettingsRepository->useAmneziaDns()) {
|
||||
dns.first = protocols::dns::amneziaDnsIp;
|
||||
} else {
|
||||
dns.first = m_appSettingsRepository->primaryDns();
|
||||
}
|
||||
}
|
||||
if (dns.second.isEmpty() || !NetworkUtilities::checkIPv4Format(dns.second)) {
|
||||
dns.second = m_appSettingsRepository->secondaryDns();
|
||||
}
|
||||
|
||||
vpnConfiguration = createConnectionConfiguration(dns, isApiConfig, hostName, description, configVersion,
|
||||
containerConfigModel, container);
|
||||
|
||||
@@ -178,7 +178,8 @@ void CoreController::initControllers()
|
||||
#ifdef Q_OS_WINDOWS
|
||||
m_ikev2ConfigModel,
|
||||
#endif
|
||||
m_sftpConfigModel, m_socks5ConfigModel, m_mtProxyConfigModel, m_telemtConfigModel, this);
|
||||
m_sftpConfigModel, m_socks5ConfigModel, m_mtProxyConfigModel, m_telemtConfigModel,
|
||||
m_connectionController, this);
|
||||
setQmlContextProperty("InstallController", m_installUiController);
|
||||
|
||||
m_importController = new ImportUiController(m_importCoreController, this);
|
||||
@@ -220,7 +221,8 @@ void CoreController::initControllers()
|
||||
|
||||
m_subscriptionUiController = new SubscriptionUiController(m_serversController, m_apiServicesModel, m_servicesCatalogController, m_subscriptionController,
|
||||
m_apiSubscriptionPlansModel, m_apiBenefitsModel, m_apiAccountInfoModel,
|
||||
m_apiCountryModel, m_apiDevicesModel, m_settingsController, this);
|
||||
m_apiCountryModel, m_apiDevicesModel, m_settingsController,
|
||||
m_connectionController, this);
|
||||
setQmlContextProperty("SubscriptionUiController", m_subscriptionUiController);
|
||||
|
||||
m_apiNewsUiController = new ApiNewsUiController(m_newsModel, m_newsController, this);
|
||||
@@ -342,9 +344,6 @@ void CoreController::openConnectionByIndex(int serverIndex)
|
||||
if (serverId.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (m_serversModel) {
|
||||
m_serversModel->setProcessedServerIndex(serverIndex);
|
||||
}
|
||||
if (m_serversController) {
|
||||
m_serversController->setDefaultServer(serverId);
|
||||
}
|
||||
|
||||
@@ -125,9 +125,9 @@ void CoreSignalHandlers::initInstallControllerHandler()
|
||||
{
|
||||
connect(m_coreController->m_installController, &InstallController::serverIsBusy, m_coreController->m_installUiController, &InstallUiController::serverIsBusy);
|
||||
connect(m_coreController->m_installUiController, &InstallUiController::cancelInstallation, m_coreController->m_installController, &InstallController::cancelInstallation);
|
||||
connect(m_coreController->m_serversUiController, &ServersUiController::processedServerIndexChanged,
|
||||
m_coreController->m_installUiController, [this](int serverIndex) {
|
||||
if (serverIndex >= 0) {
|
||||
connect(m_coreController->m_serversUiController, &ServersUiController::processedServerIdChanged,
|
||||
m_coreController->m_installUiController, [this](const QString &serverId) {
|
||||
if (!serverId.isEmpty()) {
|
||||
m_coreController->m_installUiController->clearProcessedServerCredentials();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -120,9 +120,14 @@ ErrorCode InstallController::setupContainer(const ServerCredentials &credentials
|
||||
return e;
|
||||
qDebug().noquote() << "InstallController::setupContainer prepareHostWorker finished";
|
||||
|
||||
amnezia::ScriptVars removeContainerVars =
|
||||
amnezia::genBaseVars(credentials, container, QString(), QString());
|
||||
if (!isUpdate) {
|
||||
removeContainerVars.append({ { "$REMOVE_CONTAINER_DATA", QStringLiteral("1") } });
|
||||
}
|
||||
sshSession.runScript(credentials,
|
||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
||||
amnezia::genBaseVars(credentials, container, QString(), QString())));
|
||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
||||
removeContainerVars));
|
||||
qDebug().noquote() << "InstallController::setupContainer removeContainer finished";
|
||||
|
||||
qDebug().noquote() << "buildContainerWorker start";
|
||||
@@ -242,9 +247,9 @@ void InstallController::clearCachedProfile(const QString &serverId, DockerContai
|
||||
return;
|
||||
}
|
||||
|
||||
adminConfig->clearCachedClientProfile(container);
|
||||
const ContainerConfig containerConfigModel = adminConfig->containerConfig(container);
|
||||
|
||||
adminConfig->clearCachedClientProfile(container);
|
||||
m_serversRepository->editServer(serverId, adminConfig->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
|
||||
|
||||
emit clientRevocationRequested(serverId, containerConfigModel, container);
|
||||
@@ -975,10 +980,12 @@ ErrorCode InstallController::removeContainer(const QString &serverId, DockerCont
|
||||
return ErrorCode::InternalError;
|
||||
}
|
||||
SshSession sshSession(this);
|
||||
amnezia::ScriptVars removeContainerVars =
|
||||
amnezia::genBaseVars(credentials, container, QString(), QString());
|
||||
removeContainerVars.append({ { "$REMOVE_CONTAINER_DATA", QStringLiteral("1") } });
|
||||
ErrorCode errorCode = sshSession.runScript(
|
||||
credentials,
|
||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container),
|
||||
amnezia::genBaseVars(credentials, container, QString(), QString())));
|
||||
sshSession.replaceVars(amnezia::scriptData(SharedScriptType::remove_container), removeContainerVars));
|
||||
|
||||
if (errorCode == ErrorCode::NoError) {
|
||||
QMap<DockerContainer, ContainerConfig> containers = adminConfig->containers;
|
||||
|
||||
@@ -44,6 +44,7 @@ bool ServersController::renameServer(const QString &serverId, const QString &nam
|
||||
auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
cfg->displayName = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
@@ -51,6 +52,7 @@ bool ServersController::renameServer(const QString &serverId, const QString &nam
|
||||
auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
cfg->displayName = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
@@ -58,6 +60,7 @@ bool ServersController::renameServer(const QString &serverId, const QString &nam
|
||||
auto cfg = m_serversRepository->nativeConfig(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->description = name;
|
||||
cfg->displayName = name;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
}
|
||||
@@ -67,6 +70,7 @@ bool ServersController::renameServer(const QString &serverId, const QString &nam
|
||||
auto cfg = m_serversRepository->apiV2Config(serverId);
|
||||
if (!cfg.has_value()) return false;
|
||||
cfg->name = name;
|
||||
cfg->displayName = name;
|
||||
cfg->nameOverriddenByUser = true;
|
||||
m_serversRepository->editServer(serverId, cfg->toJson(), kind);
|
||||
return true;
|
||||
|
||||
@@ -217,6 +217,11 @@ void SettingsController::toggleAutoStart(bool enable)
|
||||
|
||||
bool SettingsController::isStartMinimizedEnabled() const
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
if (!isAutoStartEnabled()) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
return m_appSettingsRepository->isStartMinimized();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
const QLatin1String kInstallerRemoteFileNamePattern("AmneziaVPN_%1_windows_x64.exe");
|
||||
const QString kInstallerLocalPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN_installer.exe";
|
||||
#elif defined(Q_OS_MACOS)
|
||||
#elif defined(Q_OS_MACOS) && !defined(MACOS_NE)
|
||||
const QLatin1String kInstallerRemoteFileNamePattern("AmneziaVPN_%1_macos_x64.pkg");
|
||||
const QString kInstallerLocalPath = QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/AmneziaVPN.pkg";
|
||||
#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
||||
@@ -184,7 +184,7 @@ void UpdateController::setupNetworkErrorHandling(QNetworkReply* reply, const QSt
|
||||
logger.error() << QString("Network error occurred while fetching %1: %2 %3")
|
||||
.arg(operation, reply->errorString(), QString::number(error));
|
||||
});
|
||||
|
||||
|
||||
QObject::connect(reply, &QNetworkReply::sslErrors, [operation](const QList<QSslError> &errors) {
|
||||
QStringList errorStrings;
|
||||
for (const QSslError &err : errors) {
|
||||
@@ -196,21 +196,13 @@ void UpdateController::setupNetworkErrorHandling(QNetworkReply* reply, const QSt
|
||||
|
||||
void UpdateController::handleNetworkError(QNetworkReply* reply, const QString& operation)
|
||||
{
|
||||
if (reply->error() == QNetworkReply::NetworkError::OperationCanceledError
|
||||
|| reply->error() == QNetworkReply::NetworkError::TimeoutError) {
|
||||
logger.error() << errorString(ErrorCode::ApiConfigTimeoutError);
|
||||
} else {
|
||||
QString err = reply->errorString();
|
||||
logger.error() << "Network error code:" << QString::number(static_cast<int>(reply->error()));
|
||||
logger.error() << "Error message:" << err;
|
||||
logger.error() << "HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
logger.error() << errorString(ErrorCode::ApiConfigDownloadError);
|
||||
}
|
||||
logger.error() << "Network error code:" << QString::number(static_cast<int>(reply->error()));
|
||||
logger.error() << "HTTP status:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
|
||||
}
|
||||
|
||||
QString UpdateController::composeDownloadUrl() const
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
const QString fileName = QString(kInstallerRemoteFileNamePattern).arg(m_version);
|
||||
return m_baseUrl + "/" + fileName;
|
||||
#else
|
||||
@@ -220,7 +212,7 @@ QString UpdateController::composeDownloadUrl() const
|
||||
|
||||
void UpdateController::runInstaller()
|
||||
{
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
if (m_downloadUrl.isEmpty()) {
|
||||
logger.error() << "Download URL is empty";
|
||||
return;
|
||||
@@ -252,7 +244,7 @@ void UpdateController::runInstaller()
|
||||
|
||||
#if defined(Q_OS_WINDOWS)
|
||||
runWindowsInstaller(kInstallerLocalPath);
|
||||
#elif defined(Q_OS_MACOS)
|
||||
#elif defined(Q_OS_MACOS) && !defined(MACOS_NE)
|
||||
runMacInstaller(kInstallerLocalPath);
|
||||
#elif defined(Q_OS_LINUX) && !defined(Q_OS_ANDROID)
|
||||
runLinuxInstaller(kInstallerLocalPath);
|
||||
@@ -292,7 +284,7 @@ int UpdateController::runWindowsInstaller(const QString &installerPath)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(Q_OS_MACOS)
|
||||
#if defined(Q_OS_MACOS) && !defined(MACOS_NE)
|
||||
int UpdateController::runMacInstaller(const QString &installerPath)
|
||||
{
|
||||
// Create temporary directory for extraction
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
#include "socks5Installer.h"
|
||||
|
||||
#include "core/models/protocols/socks5ProxyProtocolConfig.h"
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/selfhosted/sshSession.h"
|
||||
#include "core/utils/utilities.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
using namespace amnezia;
|
||||
using namespace ProtocolUtils;
|
||||
|
||||
@@ -33,10 +35,29 @@ ContainerConfig Socks5Installer::generateConfig(DockerContainer container, int p
|
||||
ErrorCode Socks5Installer::extractConfigFromContainer(DockerContainer container, const ServerCredentials &credentials,
|
||||
SshSession* sshSession, ContainerConfig &config)
|
||||
{
|
||||
Q_UNUSED(container);
|
||||
Q_UNUSED(credentials);
|
||||
Q_UNUSED(sshSession);
|
||||
Q_UNUSED(config);
|
||||
if (container != DockerContainer::Socks5Proxy || !sshSession) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
Socks5ProxyProtocolConfig *socks5Config = config.getSocks5ProxyProtocolConfig();
|
||||
if (!socks5Config) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
ErrorCode readError = ErrorCode::NoError;
|
||||
const QByteArray configRaw = sshSession->getTextFileFromContainer(
|
||||
container, credentials, QString::fromUtf8(protocols::socks5Proxy::proxyConfigPath), readError);
|
||||
if (readError != ErrorCode::NoError || configRaw.trimmed().isEmpty()) {
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
const QString proxyConfig = QString::fromUtf8(configRaw);
|
||||
static const QRegularExpression usernameAndPasswordRegExp(QStringLiteral("users (\\w+):CL:(\\w+)"));
|
||||
const QRegularExpressionMatch usernameAndPasswordMatch = usernameAndPasswordRegExp.match(proxyConfig);
|
||||
if (usernameAndPasswordMatch.hasMatch()) {
|
||||
socks5Config->userName = usernameAndPasswordMatch.captured(1);
|
||||
socks5Config->password = usernameAndPasswordMatch.captured(2);
|
||||
}
|
||||
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/models/api/apiConfig.h"
|
||||
#include "core/models/api/authData.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
@@ -67,6 +68,20 @@ ContainerConfig ApiV2ServerConfig::containerConfig(DockerContainer container) co
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
QPair<QString, QString> ApiV2ServerConfig::getDnsPair(const QString &primaryDns, const QString &secondaryDns) const
|
||||
{
|
||||
QString d1 = dns1;
|
||||
QString d2 = dns2;
|
||||
|
||||
if (d1.isEmpty() || !NetworkUtilities::checkIPv4Format(d1)) {
|
||||
d1 = primaryDns;
|
||||
}
|
||||
if (d2.isEmpty() || !NetworkUtilities::checkIPv4Format(d2)) {
|
||||
d2 = secondaryDns;
|
||||
}
|
||||
return { d1, d2 };
|
||||
}
|
||||
|
||||
QJsonObject ApiV2ServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
@@ -43,6 +44,9 @@ struct ApiV2ServerConfig {
|
||||
bool isExternalPremium() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
|
||||
QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static ApiV2ServerConfig fromJson(const QJsonObject& json);
|
||||
};
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
#include "core/utils/constants/configKeys.h"
|
||||
#include "core/utils/constants/protocolConstants.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
@@ -28,6 +29,20 @@ ContainerConfig NativeServerConfig::containerConfig(DockerContainer container) c
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
QPair<QString, QString> NativeServerConfig::getDnsPair(const QString &primaryDns, const QString &secondaryDns) const
|
||||
{
|
||||
QString d1 = dns1;
|
||||
QString d2 = dns2;
|
||||
|
||||
if (d1.isEmpty() || !NetworkUtilities::checkIPv4Format(d1)) {
|
||||
d1 = primaryDns;
|
||||
}
|
||||
if (d2.isEmpty() || !NetworkUtilities::checkIPv4Format(d2)) {
|
||||
d2 = secondaryDns;
|
||||
}
|
||||
return { d1, d2 };
|
||||
}
|
||||
|
||||
QJsonObject NativeServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
@@ -25,6 +26,9 @@ struct NativeServerConfig {
|
||||
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
|
||||
QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static NativeServerConfig fromJson(const QJsonObject& json);
|
||||
};
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include "core/utils/containerEnum.h"
|
||||
#include "core/utils/containers/containerUtils.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
|
||||
namespace amnezia
|
||||
{
|
||||
@@ -42,6 +43,21 @@ ContainerConfig SelfHostedUserServerConfig::containerConfig(DockerContainer cont
|
||||
return containers.value(container);
|
||||
}
|
||||
|
||||
QPair<QString, QString> SelfHostedUserServerConfig::getDnsPair(const QString &primaryDns,
|
||||
const QString &secondaryDns) const
|
||||
{
|
||||
QString d1 = dns1;
|
||||
QString d2 = dns2;
|
||||
|
||||
if (d1.isEmpty() || !NetworkUtilities::checkIPv4Format(d1)) {
|
||||
d1 = primaryDns;
|
||||
}
|
||||
if (d2.isEmpty() || !NetworkUtilities::checkIPv4Format(d2)) {
|
||||
d2 = secondaryDns;
|
||||
}
|
||||
return { d1, d2 };
|
||||
}
|
||||
|
||||
QJsonObject SelfHostedUserServerConfig::toJson() const
|
||||
{
|
||||
QJsonObject obj;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <optional>
|
||||
|
||||
#include "core/utils/containerEnum.h"
|
||||
@@ -30,6 +31,9 @@ struct SelfHostedUserServerConfig {
|
||||
std::optional<ServerCredentials> credentials() const;
|
||||
bool hasContainers() const;
|
||||
ContainerConfig containerConfig(DockerContainer container) const;
|
||||
|
||||
QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const;
|
||||
|
||||
QJsonObject toJson() const;
|
||||
static SelfHostedUserServerConfig fromJson(const QJsonObject &json);
|
||||
};
|
||||
|
||||
@@ -295,6 +295,8 @@ amnezia::ScriptVars amnezia::genMtProxyVars(const ContainerConfig &containerConf
|
||||
|
||||
vars.append({{"$MTPROXY_PORT", c.port.isEmpty() ? QString(protocols::mtProxy::defaultPort) : c.port}});
|
||||
vars.append({{"$MTPROXY_SECRET", c.secret}});
|
||||
vars.append({{"$MTPROXY_REGENERATE_SECRET",
|
||||
c.secret.isEmpty() ? QStringLiteral("1") : QStringLiteral("0")}});
|
||||
vars.append({{"$MTPROXY_TAG", c.tag}});
|
||||
vars.append({{"$MTPROXY_TRANSPORT_MODE",
|
||||
c.transportMode.isEmpty() ? QString(protocols::mtProxy::transportModeStandard)
|
||||
@@ -350,6 +352,8 @@ amnezia::ScriptVars amnezia::genTelemtVars(const ContainerConfig &containerConfi
|
||||
vars.append({ { "$TELEMT_TOML_TLS", faketls ? QLatin1String("true") : QLatin1String("false") } });
|
||||
vars.append({ { "$TELEMT_PORT", c.port.isEmpty() ? QString(protocols::telemt::defaultPort) : c.port } });
|
||||
vars.append({ { "$TELEMT_SECRET", c.secret } });
|
||||
vars.append({ { "$TELEMT_REGENERATE_SECRET",
|
||||
c.secret.isEmpty() ? QStringLiteral("1") : QStringLiteral("0") } });
|
||||
vars.append({ { "$TELEMT_TAG", c.tag } });
|
||||
QString tlsDomain = c.tlsDomain;
|
||||
if (tlsDomain.isEmpty()) {
|
||||
|
||||
+6
-2
@@ -1,13 +1,12 @@
|
||||
#include <QDebug>
|
||||
#include <QTimer>
|
||||
#include <libssh/libssh.h>
|
||||
|
||||
#include "amneziaApplication.h"
|
||||
#include "core/utils/osSignalHandler.h"
|
||||
#include "core/utils/migrations.h"
|
||||
#include "version.h"
|
||||
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include "Windows.h"
|
||||
#endif
|
||||
@@ -47,6 +46,11 @@ int main(int argc, char *argv[])
|
||||
AmneziaApplication app(argc, argv);
|
||||
OsSignalHandler::setup();
|
||||
|
||||
ssh_init();
|
||||
QObject::connect(&app, &QCoreApplication::aboutToQuit, []() {
|
||||
ssh_finalize();
|
||||
});
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) && !defined(MACOS_NE)
|
||||
if (isAnotherInstanceRunning()) {
|
||||
QTimer::singleShot(1000, &app, [&]() { app.quit(); });
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
curl -s https://core.telegram.org/getProxySecret -o /data/proxy-secret
|
||||
curl -s https://core.telegram.org/getProxyConfig -o /data/proxy-multi.conf
|
||||
|
||||
# Determine secret: env var -> saved file -> generate new
|
||||
if [ -n "$MTPROXY_SECRET" ]; then
|
||||
# Determine secret: regenerate (fresh install) -> env var -> saved file -> generate new
|
||||
if [ "$MTPROXY_REGENERATE_SECRET" = "1" ]; then
|
||||
SECRET=$(openssl rand -hex 16)
|
||||
elif [ -n "$MTPROXY_SECRET" ]; then
|
||||
SECRET="$MTPROXY_SECRET"
|
||||
elif [ -f /data/secret ]; then
|
||||
SECRET=$(cat /data/secret)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
sudo docker stop $CONTAINER_NAME;\
|
||||
sudo docker rm -fv $CONTAINER_NAME;\
|
||||
sudo docker rmi $CONTAINER_NAME
|
||||
sudo docker rmi $CONTAINER_NAME;\
|
||||
test "$REMOVE_CONTAINER_DATA" = "1" && sudo docker volume rm -f ${CONTAINER_NAME}-data 2>/dev/null || true
|
||||
|
||||
@@ -4,8 +4,10 @@
|
||||
echo "[*] Amnezia Telemt: configure script start"
|
||||
mkdir -p /data/tlsfront
|
||||
|
||||
# Secret: substituted $TELEMT_SECRET -> saved file -> openssl (same rules as MTProxy configure)
|
||||
if [ -n "$TELEMT_SECRET" ]; then
|
||||
# Secret: regenerate (fresh install) -> env var -> saved file -> openssl
|
||||
if [ "$TELEMT_REGENERATE_SECRET" = "1" ]; then
|
||||
SECRET=$(openssl rand -hex 16)
|
||||
elif [ -n "$TELEMT_SECRET" ]; then
|
||||
SECRET="$TELEMT_SECRET"
|
||||
elif [ -f /data/secret ]; then
|
||||
SECRET=$(cat /data/secret)
|
||||
|
||||
@@ -38,7 +38,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,7 +41,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -146,7 +146,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -133,6 +133,8 @@ private slots:
|
||||
void testStartMinimizedSignals() {
|
||||
QSignalSpy startMinimizedChangedSpy(m_coreController->m_settingsUiController, &SettingsUiController::startMinimizedChanged);
|
||||
|
||||
m_coreController->m_settingsUiController->toggleAutoStart(true);
|
||||
|
||||
bool initialStartMinimized = m_coreController->m_settingsController->isStartMinimizedEnabled();
|
||||
|
||||
m_coreController->m_settingsUiController->toggleStartMinimized(!initialStartMinimized);
|
||||
@@ -140,6 +142,21 @@ private slots:
|
||||
QVERIFY2(m_coreController->m_settingsController->isStartMinimizedEnabled() == !initialStartMinimized, "Start minimized state should be updated in SettingsController");
|
||||
QVERIFY2(m_coreController->m_settingsUiController->isStartMinimizedEnabled() == !initialStartMinimized, "Start minimized state should be available in SettingsUiController");
|
||||
QVERIFY2(m_coreController->m_appSettingsRepository->isStartMinimized() == !initialStartMinimized, "Start minimized state should be available in SecureAppSettingsRepository");
|
||||
|
||||
m_coreController->m_settingsUiController->toggleAutoStart(false);
|
||||
}
|
||||
|
||||
void testAutoStartDisablesStartMinimizedUi() {
|
||||
QSignalSpy startMinimizedChangedSpy(m_coreController->m_settingsUiController, &SettingsUiController::startMinimizedChanged);
|
||||
|
||||
m_coreController->m_settingsUiController->toggleAutoStart(true);
|
||||
m_coreController->m_settingsUiController->toggleStartMinimized(true);
|
||||
QVERIFY2(m_coreController->m_settingsUiController->isStartMinimizedEnabled(), "Start minimized should be enabled with autostart");
|
||||
|
||||
m_coreController->m_settingsUiController->toggleAutoStart(false);
|
||||
QVERIFY2(startMinimizedChangedSpy.count() >= 1, "startMinimizedChanged signal should be emitted when autostart is disabled");
|
||||
QVERIFY2(!m_coreController->m_settingsUiController->isStartMinimizedEnabled(), "Start minimized should be disabled when autostart is disabled");
|
||||
QVERIFY2(!m_coreController->m_appSettingsRepository->isStartMinimized(), "Start minimized setting should be cleared when autostart is disabled");
|
||||
}
|
||||
|
||||
void testAutoConnectSignals() {
|
||||
|
||||
@@ -38,7 +38,7 @@ private slots:
|
||||
m_settings->clearSettings();
|
||||
m_coreController->m_serversRepository->invalidateCache();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,18 +23,6 @@ using namespace amnezia;
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace {
|
||||
int defaultServerRow(const QVector<ServerDescription> &descriptions, const QString &defaultServerId)
|
||||
{
|
||||
for (int i = 0; i < descriptions.size(); ++i) {
|
||||
if (descriptions.at(i).serverId == defaultServerId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
class TestUiServersModelAndController : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -131,7 +119,7 @@ private slots:
|
||||
void init() {
|
||||
m_settings->clearSettings();
|
||||
if (m_coreController->m_serversModel) {
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), -1);
|
||||
m_coreController->m_serversModel->updateModel(QVector<ServerDescription>(), QString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -274,7 +262,7 @@ private slots:
|
||||
QVector<ServerDescription> descriptionsNoDns = m_coreController->m_serversController->buildServerDescriptions(
|
||||
m_coreController->m_appSettingsRepository->useAmneziaDns());
|
||||
const QString defIdNoDns = m_coreController->m_serversRepository->defaultServerId();
|
||||
m_coreController->m_serversModel->updateModel(descriptionsNoDns, defaultServerRow(descriptionsNoDns, defIdNoDns));
|
||||
m_coreController->m_serversModel->updateModel(descriptionsNoDns, defIdNoDns);
|
||||
|
||||
QString descNoDns = m_coreController->m_serversModel->data(
|
||||
m_coreController->m_serversModel->index(0, 0), ServersModel::ServerDescriptionRole).toString();
|
||||
@@ -293,7 +281,7 @@ private slots:
|
||||
QVector<ServerDescription> descriptionsWithDns = m_coreController->m_serversController->buildServerDescriptions(
|
||||
m_coreController->m_appSettingsRepository->useAmneziaDns());
|
||||
const QString defIdWithDns = m_coreController->m_serversRepository->defaultServerId();
|
||||
m_coreController->m_serversModel->updateModel(descriptionsWithDns, defaultServerRow(descriptionsWithDns, defIdWithDns));
|
||||
m_coreController->m_serversModel->updateModel(descriptionsWithDns, defIdWithDns);
|
||||
|
||||
QString descWithDns = m_coreController->m_serversModel->data(
|
||||
m_coreController->m_serversModel->index(0, 0), ServersModel::ServerDescriptionRole).toString();
|
||||
|
||||
@@ -65,6 +65,7 @@ SubscriptionUiController::SubscriptionUiController(ServersController* serversCon
|
||||
ApiCountryModel* apiCountryModel,
|
||||
ApiDevicesModel* apiDevicesModel,
|
||||
SettingsController* settingsController,
|
||||
ConnectionController* connectionController,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
m_serversController(serversController),
|
||||
@@ -76,13 +77,29 @@ SubscriptionUiController::SubscriptionUiController(ServersController* serversCon
|
||||
m_apiAccountInfoModel(apiAccountInfoModel),
|
||||
m_apiCountryModel(apiCountryModel),
|
||||
m_apiDevicesModel(apiDevicesModel),
|
||||
m_settingsController(settingsController)
|
||||
m_settingsController(settingsController),
|
||||
m_connectionController(connectionController)
|
||||
{
|
||||
connect(m_apiServicesModel, &ApiServicesModel::serviceSelectionChanged, this, [this]() {
|
||||
ApiServicesModel::ApiServicesData selectedServiceData = m_apiServicesModel->selectedServiceData();
|
||||
m_apiSubscriptionPlansModel->updateModel(selectedServiceData.subscriptionPlansJson);
|
||||
m_apiBenefitsModel->updateModel(selectedServiceData.benefits);
|
||||
});
|
||||
|
||||
connect(this, &SubscriptionUiController::installServerFromApiFinished, this,
|
||||
[this](const QString &, int preferredDefaultServerIndex) {
|
||||
if (m_connectionController->isConnected()) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int selectedServerIndex = preferredDefaultServerIndex >= 0
|
||||
? preferredDefaultServerIndex
|
||||
: (m_serversController->getServersCount() - 1);
|
||||
const QString serverId = m_serversController->getServerId(selectedServerIndex);
|
||||
if (!serverId.isEmpty()) {
|
||||
m_serversController->setDefaultServer(serverId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
bool SubscriptionUiController::exportVpnKey(const QString &serverId, const QString &fileName)
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include "core/controllers/serversController.h"
|
||||
#include "core/controllers/settingsController.h"
|
||||
#include "core/controllers/connectionController.h"
|
||||
#include "core/controllers/api/servicesCatalogController.h"
|
||||
#include "core/controllers/api/subscriptionController.h"
|
||||
#include "ui/models/api/apiSubscriptionPlansModel.h"
|
||||
@@ -28,6 +29,7 @@ public:
|
||||
ApiCountryModel* apiCountryModel,
|
||||
ApiDevicesModel* apiDevicesModel,
|
||||
SettingsController* settingsController,
|
||||
ConnectionController* connectionController,
|
||||
QObject *parent = nullptr);
|
||||
|
||||
Q_PROPERTY(QList<QString> qrCodes READ getQrCodes NOTIFY vpnKeyExportReady)
|
||||
@@ -104,6 +106,7 @@ private:
|
||||
ApiCountryModel* m_apiCountryModel;
|
||||
ApiDevicesModel* m_apiDevicesModel;
|
||||
SettingsController* m_settingsController;
|
||||
ConnectionController* m_connectionController;
|
||||
};
|
||||
|
||||
#endif // SUBSCRIPTIONUICONTROLLER_H
|
||||
|
||||
@@ -44,7 +44,6 @@ signals:
|
||||
void connectionStateChanged();
|
||||
|
||||
void connectionErrorOccurred(ErrorCode errorCode);
|
||||
void reconnectWithUpdatedContainer(const QString &message);
|
||||
|
||||
void connectButtonClicked();
|
||||
void preparingConfig();
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include "core/utils/api/apiUtils.h"
|
||||
#include "core/controllers/selfhosted/installController.h"
|
||||
#include "core/controllers/connectionController.h"
|
||||
#include "core/utils/networkUtilities.h"
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/protocols/protocolUtils.h"
|
||||
@@ -51,6 +52,7 @@ InstallUiController::InstallUiController(InstallController *installController,
|
||||
Socks5ProxyConfigModel *socks5ConfigModel,
|
||||
MtProxyConfigModel* mtConfigModel,
|
||||
TelemtConfigModel *telemtConfigModel,
|
||||
ConnectionController *connectionController,
|
||||
QObject *parent)
|
||||
: QObject(parent),
|
||||
m_installController(installController),
|
||||
@@ -69,7 +71,8 @@ InstallUiController::InstallUiController(InstallController *installController,
|
||||
m_sftpConfigModel(sftpConfigModel),
|
||||
m_socks5ConfigModel(socks5ConfigModel),
|
||||
m_mtProxyConfigModel(mtConfigModel),
|
||||
m_telemtConfigModel(telemtConfigModel)
|
||||
m_telemtConfigModel(telemtConfigModel),
|
||||
m_connectionController(connectionController)
|
||||
{
|
||||
connect(m_installController, &InstallController::configValidated, this, &InstallUiController::configValidated);
|
||||
connect(m_installController, &InstallController::validationErrorOccurred, this, [this](ErrorCode errorCode) {
|
||||
@@ -133,6 +136,10 @@ void InstallUiController::install(DockerContainer container, int port, Transport
|
||||
finishMessage += tr("\nAdded containers that were already installed on the server");
|
||||
}
|
||||
|
||||
if (!m_connectionController->isConnected()) {
|
||||
m_serversController->setDefaultServer(newServerId);
|
||||
}
|
||||
|
||||
emit installServerFinished(finishMessage);
|
||||
} else {
|
||||
const auto adminBefore = m_serversController->selfHostedAdminConfig(serverId);
|
||||
@@ -172,7 +179,12 @@ void InstallUiController::install(DockerContainer container, int port, Transport
|
||||
"All installed containers have been added to the application");
|
||||
}
|
||||
|
||||
emit installContainerFinished(finishMessage, ContainerUtils::containerService(container) == ServiceType::Other);
|
||||
const bool isServiceInstall = ContainerUtils::containerService(container) == ServiceType::Other;
|
||||
if (!m_connectionController->isConnected() && !isServiceInstall) {
|
||||
m_serversController->setDefaultContainer(serverId, container);
|
||||
}
|
||||
|
||||
emit installContainerFinished(finishMessage, isServiceInstall);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,15 +293,7 @@ void InstallUiController::updateContainer(const QString &serverId, int container
|
||||
m_serversController->getContainerConfig(serverId, container);
|
||||
m_protocolModel->updateModel(updatedConfig);
|
||||
updateProtocolConfigModel(serverId, static_cast<int>(container), static_cast<int>(protocolTypeCopy));
|
||||
|
||||
const auto defaultContainer =
|
||||
m_serversController->getDefaultContainer(serverId);
|
||||
if ((serverId == m_serversController->getDefaultServerId())
|
||||
&& (container == defaultContainer)) {
|
||||
emit currentContainerUpdated();
|
||||
} else {
|
||||
emit updateContainerFinished(tr("Settings updated successfully"), closePage);
|
||||
}
|
||||
emit updateContainerFinished(tr("Settings updated successfully"), closePage);
|
||||
} else {
|
||||
emit installationErrorOccurred(errorCode);
|
||||
}
|
||||
@@ -313,13 +317,7 @@ void InstallUiController::updateContainer(const QString &serverId, int container
|
||||
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container);
|
||||
m_protocolModel->updateModel(updatedConfig);
|
||||
updateProtocolConfigModel(serverId, static_cast<int>(container), static_cast<int>(protocolType));
|
||||
|
||||
const auto defaultContainer = m_serversController->getDefaultContainer(serverId);
|
||||
if ((serverId == m_serversController->getDefaultServerId()) && (container == defaultContainer)) {
|
||||
emit currentContainerUpdated();
|
||||
} else {
|
||||
emit updateContainerFinished(tr("Settings updated successfully"), closePage);
|
||||
}
|
||||
emit updateContainerFinished(tr("Settings updated successfully"), closePage);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -551,6 +549,12 @@ void InstallUiController::setEncryptedPassphrase(QString passphrase)
|
||||
void InstallUiController::addEmptyServer()
|
||||
{
|
||||
m_installController->addEmptyServer(m_processedServerCredentials);
|
||||
if (!m_connectionController->isConnected()) {
|
||||
const QString newServerId = m_serversController->getServerId(m_serversController->getServersCount() - 1);
|
||||
if (!newServerId.isEmpty()) {
|
||||
m_serversController->setDefaultServer(newServerId);
|
||||
}
|
||||
}
|
||||
emit installServerFinished(tr("Server added successfully"));
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "core/utils/protocolEnum.h"
|
||||
#include "core/controllers/serversController.h"
|
||||
#include "core/controllers/settingsController.h"
|
||||
#include "core/controllers/connectionController.h"
|
||||
#include "core/controllers/selfhosted/usersController.h"
|
||||
#include "core/controllers/selfhosted/installController.h"
|
||||
#include "core/utils/errorCodes.h"
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
Socks5ProxyConfigModel* socks5ConfigModel,
|
||||
MtProxyConfigModel* mtConfigModel,
|
||||
TelemtConfigModel* telemtConfigModel,
|
||||
ConnectionController* connectionController,
|
||||
QObject *parent = nullptr);
|
||||
~InstallUiController();
|
||||
|
||||
@@ -127,8 +129,6 @@ signals:
|
||||
void serverIsBusy(const bool isBusy);
|
||||
void cancelInstallation();
|
||||
|
||||
void currentContainerUpdated();
|
||||
|
||||
void cachedProfileCleared(const QString &message);
|
||||
void apiConfigRemoved(const QString &message);
|
||||
|
||||
@@ -155,6 +155,7 @@ private:
|
||||
Socks5ProxyConfigModel* m_socks5ConfigModel;
|
||||
MtProxyConfigModel* m_mtProxyConfigModel;
|
||||
TelemtConfigModel* m_telemtConfigModel;
|
||||
ConnectionController* m_connectionController;
|
||||
|
||||
ServerCredentials m_processedServerCredentials;
|
||||
|
||||
|
||||
@@ -31,6 +31,12 @@ bool descriptionsHaveGatewayServers(const QVector<ServerDescription> &list)
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const ServerDescription &emptyServerDescription()
|
||||
{
|
||||
static const ServerDescription s_emptyDescription;
|
||||
return s_emptyDescription;
|
||||
}
|
||||
} // namespace
|
||||
ServersUiController::ServersUiController(ServersController* serversController,
|
||||
SettingsController* settingsController,
|
||||
@@ -100,8 +106,6 @@ void ServersUiController::setDefaultServer(const QString &serverId)
|
||||
return;
|
||||
}
|
||||
m_serversController->setDefaultServer(serverId);
|
||||
updateModel();
|
||||
emit defaultServerIdChanged(serverId);
|
||||
}
|
||||
|
||||
void ServersUiController::setDefaultContainer(const QString &serverId, int containerIndex)
|
||||
@@ -120,12 +124,12 @@ void ServersUiController::toggleAmneziaDns(bool enabled)
|
||||
updateModel();
|
||||
}
|
||||
|
||||
void ServersUiController::onDefaultServerChanged(const QString &/*defaultServerId*/)
|
||||
void ServersUiController::onDefaultServerChanged(const QString &defaultServerId)
|
||||
{
|
||||
updateModel();
|
||||
setProcessedServerId(m_serversController->getDefaultServerId());
|
||||
m_serversModel->setDefaultServerId(defaultServerId);
|
||||
updateDefaultServerContainersModel();
|
||||
emit defaultServerIdChanged(m_serversController->getDefaultServerId());
|
||||
|
||||
emit defaultServerIdChanged(defaultServerId);
|
||||
}
|
||||
|
||||
void ServersUiController::updateModel()
|
||||
@@ -136,27 +140,21 @@ void ServersUiController::updateModel()
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
const bool hadServersFromGatewayBefore = descriptionsHaveGatewayServers(m_orderedServerDescriptions);
|
||||
const bool hasServersFromGatewayNow = descriptionsHaveGatewayServers(descriptions);
|
||||
const int listCount = descriptions.size();
|
||||
const int defaultRowInDescriptions = rowForServerId(descriptions, defaultServerId);
|
||||
|
||||
m_orderedServerDescriptions = descriptions;
|
||||
|
||||
if (listCount == 0) {
|
||||
setProcessedServerId(QString());
|
||||
} else if (m_processedServerIndex >= listCount) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
if (m_orderedServerDescriptions.isEmpty()) {
|
||||
if (!m_processedServerId.isEmpty()) {
|
||||
setProcessedServerId(QString());
|
||||
}
|
||||
} else if (!m_processedServerId.isEmpty()) {
|
||||
const int row = rowForServerId(m_orderedServerDescriptions, m_processedServerId);
|
||||
if (row < 0) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
} else {
|
||||
setProcessedServerId(m_processedServerId);
|
||||
setProcessedServerId(QString());
|
||||
}
|
||||
} else if (defaultRowInDescriptions >= 0) {
|
||||
setProcessedServerId(defaultServerId);
|
||||
}
|
||||
|
||||
m_serversModel->updateModel(m_orderedServerDescriptions, defaultRowInDescriptions);
|
||||
m_serversModel->updateModel(m_orderedServerDescriptions, defaultServerId);
|
||||
|
||||
updateContainersModel();
|
||||
updateDefaultServerContainersModel();
|
||||
@@ -166,7 +164,6 @@ void ServersUiController::updateModel()
|
||||
}
|
||||
|
||||
emit defaultServerIdChanged(defaultServerId);
|
||||
emit defaultServerIndexChanged(defaultServerIndex());
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerId() const
|
||||
@@ -176,60 +173,35 @@ QString ServersUiController::getDefaultServerId() const
|
||||
|
||||
QString ServersUiController::getDefaultServerName() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.serverName;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
return serverName(getDefaultServerId());
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDefaultContainerName() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return ContainerUtils::containerHumanNames().value(description.defaultContainer);
|
||||
}
|
||||
const auto &description = serverDescriptionById(getDefaultServerId());
|
||||
if (description.serverId.isEmpty()) {
|
||||
return QString();
|
||||
}
|
||||
return QString();
|
||||
return ContainerUtils::containerHumanNames().value(description.defaultContainer);
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDescriptionCollapsed() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.collapsedServerDescription;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
return serverDescriptionById(getDefaultServerId()).collapsedServerDescription;
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerImagePathCollapsed() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
if (!description.isApiV2 || description.apiServerCountryCode.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(description.apiServerCountryCode.toUpper());
|
||||
}
|
||||
const auto &description = serverDescriptionById(getDefaultServerId());
|
||||
if (!description.isApiV2 || description.apiServerCountryCode.isEmpty()) {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
return QString("qrc:/countriesFlags/images/flagKit/%1.svg").arg(description.apiServerCountryCode.toUpper());
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDescriptionExpanded() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.expandedServerDescription;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
return serverDescriptionById(getDefaultServerId()).expandedServerDescription;
|
||||
}
|
||||
|
||||
bool ServersUiController::isDefaultServerDefaultContainerHasSplitTunneling() const
|
||||
@@ -281,15 +253,75 @@ bool ServersUiController::isDefaultServerDefaultContainerHasSplitTunneling() con
|
||||
|
||||
bool ServersUiController::isDefaultServerFromApi() const
|
||||
{
|
||||
const QString defaultServerId = m_serversController->getDefaultServerId();
|
||||
return isServerFromApi(getDefaultServerId());
|
||||
}
|
||||
|
||||
bool ServersUiController::hasServerWithWriteAccess() const
|
||||
{
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == defaultServerId) {
|
||||
return description.isApiV2;
|
||||
if (description.hasWriteAccess) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString ServersUiController::serverName(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).serverName;
|
||||
}
|
||||
|
||||
QString ServersUiController::serverHostName(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).hostName;
|
||||
}
|
||||
|
||||
int ServersUiController::serverDefaultContainer(const QString &serverId) const
|
||||
{
|
||||
const auto &description = serverDescriptionById(serverId);
|
||||
return description.serverId.isEmpty() ? -1 : static_cast<int>(description.defaultContainer);
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerFromApi(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).isServerFromGatewayApi;
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerCountrySelectionAvailable(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).isCountrySelectionAvailable;
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerHasWriteAccess(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).hasWriteAccess;
|
||||
}
|
||||
|
||||
bool ServersUiController::serverHasInstalledContainers(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).hasInstalledVpnContainers;
|
||||
}
|
||||
|
||||
QString ServersUiController::serverAdEndpoint(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).adEndpoint;
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerRenewalAvailable(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).isRenewalAvailable;
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerSubscriptionExpired(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).isSubscriptionExpired;
|
||||
}
|
||||
|
||||
bool ServersUiController::isServerSubscriptionExpiringSoon(const QString &serverId) const
|
||||
{
|
||||
return serverDescriptionById(serverId).isSubscriptionExpiringSoon;
|
||||
}
|
||||
|
||||
int ServersUiController::getProcessedContainerIndex() const
|
||||
{
|
||||
return m_processedContainerIndex;
|
||||
@@ -311,27 +343,17 @@ QString ServersUiController::getProcessedServerId() const
|
||||
|
||||
void ServersUiController::setProcessedServerId(const QString &serverId)
|
||||
{
|
||||
const int index = serverId.isEmpty() ? -1 : serverIndexForId(serverId);
|
||||
if (!serverId.isEmpty() && index < 0) {
|
||||
return;
|
||||
}
|
||||
const int newIndex = serverId.isEmpty() ? -1 : serverIndexForId(serverId);
|
||||
const QString normalizedServerId = newIndex >= 0 ? serverId : QString();
|
||||
|
||||
if (m_processedServerIndex != index || m_processedServerId != serverId) {
|
||||
m_processedServerIndex = index;
|
||||
m_processedServerId = serverId;
|
||||
m_serversModel->setProcessedServerIndex(index);
|
||||
if (m_processedServerId != normalizedServerId) {
|
||||
m_processedServerId = normalizedServerId;
|
||||
|
||||
if (index >= 0) {
|
||||
if (newIndex >= 0) {
|
||||
updateContainersModel();
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == serverId) {
|
||||
setProcessedContainerIndex(static_cast<int>(description.defaultContainer));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId != serverId) {
|
||||
if (description.serverId != normalizedServerId) {
|
||||
continue;
|
||||
}
|
||||
if (description.isApiV2) {
|
||||
@@ -345,45 +367,12 @@ void ServersUiController::setProcessedServerId(const QString &serverId)
|
||||
}
|
||||
|
||||
emit processedServerIdChanged(m_processedServerId);
|
||||
emit processedServerIndexChanged(m_processedServerIndex);
|
||||
}
|
||||
}
|
||||
|
||||
int ServersUiController::getProcessedServerIndex() const
|
||||
{
|
||||
return m_processedServerIndex;
|
||||
}
|
||||
|
||||
void ServersUiController::setProcessedServerIndex(int index)
|
||||
{
|
||||
if (index < 0) {
|
||||
setProcessedServerId(QString());
|
||||
return;
|
||||
}
|
||||
const QString id = getServerId(index);
|
||||
if (!id.isEmpty()) {
|
||||
setProcessedServerId(id);
|
||||
}
|
||||
}
|
||||
|
||||
int ServersUiController::defaultServerIndex() const
|
||||
{
|
||||
return rowForServerId(m_orderedServerDescriptions, getDefaultServerId());
|
||||
}
|
||||
|
||||
bool ServersUiController::processedServerIsPremium() const
|
||||
{
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == m_processedServerId) {
|
||||
return description.isPremium;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const ServerCredentials ServersUiController::getProcessedServerCredentials() const
|
||||
{
|
||||
return m_serversController->getServerCredentials(m_processedServerId);
|
||||
return processedServerDescription().isPremium;
|
||||
}
|
||||
|
||||
bool ServersUiController::isDefaultServerCurrentlyProcessed() const
|
||||
@@ -393,18 +382,22 @@ bool ServersUiController::isDefaultServerCurrentlyProcessed() const
|
||||
|
||||
bool ServersUiController::isProcessedServerHasWriteAccess() const
|
||||
{
|
||||
ServerCredentials credentials = m_serversController->getServerCredentials(m_processedServerId);
|
||||
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
|
||||
return isServerHasWriteAccess(m_processedServerId);
|
||||
}
|
||||
|
||||
QString ServersUiController::getDefaultServerDescription(const QString &serverId) const
|
||||
const ServerDescription &ServersUiController::processedServerDescription() const
|
||||
{
|
||||
return serverDescriptionById(m_processedServerId);
|
||||
}
|
||||
|
||||
const ServerDescription &ServersUiController::serverDescriptionById(const QString &serverId) const
|
||||
{
|
||||
for (const auto &description : m_orderedServerDescriptions) {
|
||||
if (description.serverId == serverId) {
|
||||
return description.baseDescription;
|
||||
return description;
|
||||
}
|
||||
}
|
||||
return QString();
|
||||
return emptyServerDescription();
|
||||
}
|
||||
|
||||
bool ServersUiController::hasServersFromGatewayApi() const
|
||||
@@ -467,6 +460,11 @@ int ServersUiController::getServerIndexById(const QString &serverId) const
|
||||
return rowForServerId(m_orderedServerDescriptions, serverId);
|
||||
}
|
||||
|
||||
int ServersUiController::getServersCount() const
|
||||
{
|
||||
return m_orderedServerDescriptions.size();
|
||||
}
|
||||
|
||||
void ServersUiController::updateContainersModel()
|
||||
{
|
||||
if (m_processedServerId.isEmpty()) {
|
||||
|
||||
@@ -19,7 +19,6 @@ class ServersUiController : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
Q_PROPERTY(QString defaultServerId READ getDefaultServerId NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(int defaultServerIndex READ defaultServerIndex NOTIFY defaultServerIndexChanged)
|
||||
|
||||
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerIdChanged)
|
||||
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerIdChanged)
|
||||
@@ -30,9 +29,8 @@ class ServersUiController : public QObject
|
||||
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIdChanged)
|
||||
|
||||
Q_PROPERTY(QString processedServerId READ getProcessedServerId WRITE setProcessedServerId NOTIFY processedServerIdChanged)
|
||||
Q_PROPERTY(int processedServerIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||
Q_PROPERTY(int processedContainerIndex READ getProcessedContainerIndex WRITE setProcessedContainerIndex NOTIFY processedContainerIndexChanged)
|
||||
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerIndexChanged)
|
||||
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerIdChanged)
|
||||
|
||||
Q_PROPERTY(bool hasServersFromGatewayApi READ hasServersFromGatewayApi NOTIFY hasServersFromGatewayApiChanged)
|
||||
|
||||
@@ -72,20 +70,27 @@ public slots:
|
||||
QString getDefaultServerDescriptionExpanded() const;
|
||||
bool isDefaultServerDefaultContainerHasSplitTunneling() const;
|
||||
bool isDefaultServerFromApi() const;
|
||||
bool hasServerWithWriteAccess() const;
|
||||
|
||||
QString serverName(const QString &serverId) const;
|
||||
QString serverHostName(const QString &serverId) const;
|
||||
int serverDefaultContainer(const QString &serverId) const;
|
||||
bool isServerFromApi(const QString &serverId) const;
|
||||
bool isServerCountrySelectionAvailable(const QString &serverId) const;
|
||||
bool isServerHasWriteAccess(const QString &serverId) const;
|
||||
bool serverHasInstalledContainers(const QString &serverId) const;
|
||||
QString serverAdEndpoint(const QString &serverId) const;
|
||||
bool isServerRenewalAvailable(const QString &serverId) const;
|
||||
bool isServerSubscriptionExpired(const QString &serverId) const;
|
||||
bool isServerSubscriptionExpiringSoon(const QString &serverId) const;
|
||||
|
||||
QString getProcessedServerId() const;
|
||||
void setProcessedServerId(const QString &serverId);
|
||||
|
||||
int getProcessedServerIndex() const;
|
||||
void setProcessedServerIndex(int index);
|
||||
|
||||
int defaultServerIndex() const;
|
||||
|
||||
int getProcessedContainerIndex() const;
|
||||
void setProcessedContainerIndex(int index);
|
||||
bool processedServerIsPremium() const;
|
||||
|
||||
const ServerCredentials getProcessedServerCredentials() const;
|
||||
bool isDefaultServerCurrentlyProcessed() const;
|
||||
bool isProcessedServerHasWriteAccess() const;
|
||||
|
||||
@@ -97,15 +102,14 @@ public slots:
|
||||
|
||||
QString getServerId(int index) const;
|
||||
int getServerIndexById(const QString &serverId) const;
|
||||
int getServersCount() const;
|
||||
QStringList getAllInstalledServicesName(int serverIndex) const;
|
||||
|
||||
signals:
|
||||
void errorOccurred(const QString &errorMessage);
|
||||
void finished(const QString &message);
|
||||
void defaultServerIdChanged(const QString &serverId);
|
||||
void defaultServerIndexChanged(int index);
|
||||
void processedServerIdChanged(const QString &serverId);
|
||||
void processedServerIndexChanged(int index);
|
||||
void processedContainerIndexChanged(int index);
|
||||
void hasServersFromGatewayApiChanged();
|
||||
void updateApiCountryModel();
|
||||
@@ -115,7 +119,8 @@ public:
|
||||
void updateModel();
|
||||
|
||||
private:
|
||||
QString getDefaultServerDescription(const QString &serverId) const;
|
||||
const ServerDescription &serverDescriptionById(const QString &serverId) const;
|
||||
const ServerDescription &processedServerDescription() const;
|
||||
int serverIndexForId(const QString &serverId) const;
|
||||
bool listHasServersFromGatewayApi() const;
|
||||
|
||||
@@ -130,7 +135,6 @@ private:
|
||||
|
||||
QVector<amnezia::ServerDescription> m_orderedServerDescriptions;
|
||||
|
||||
int m_processedServerIndex = -1;
|
||||
QString m_processedServerId;
|
||||
int m_processedContainerIndex = -1;
|
||||
};
|
||||
|
||||
@@ -164,6 +164,7 @@ void SettingsUiController::restoreAppConfigFromData(const QByteArray &data)
|
||||
emit amneziaDnsToggled(amneziaDnsEnabled);
|
||||
|
||||
emit restoreBackupFinished();
|
||||
emit startMinimizedChanged();
|
||||
} else {
|
||||
emit errorOccurred(errorCode);
|
||||
}
|
||||
@@ -177,6 +178,7 @@ QString SettingsUiController::getAppVersion()
|
||||
void SettingsUiController::clearSettings()
|
||||
{
|
||||
m_settingsController->clearSettings();
|
||||
emit startMinimizedChanged();
|
||||
emit resetLanguageToSystem();
|
||||
|
||||
emit changeSettingsFinished(tr("All settings have been reset to default values"));
|
||||
@@ -204,6 +206,9 @@ bool SettingsUiController::isAutoStartEnabled()
|
||||
void SettingsUiController::toggleAutoStart(bool enable)
|
||||
{
|
||||
m_settingsController->toggleAutoStart(enable);
|
||||
if (!enable) {
|
||||
emit startMinimizedChanged();
|
||||
}
|
||||
}
|
||||
|
||||
bool SettingsUiController::isStartMinimizedEnabled()
|
||||
|
||||
@@ -20,20 +20,25 @@
|
||||
|
||||
using namespace amnezia;
|
||||
|
||||
namespace {
|
||||
int rowForServerId(const QVector<ServerDescription> &descriptions, const QString &serverId)
|
||||
{
|
||||
if (serverId.isEmpty()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (int i = 0; i < descriptions.size(); ++i) {
|
||||
if (descriptions.at(i).serverId == serverId) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
ServersModel::ServersModel(QObject *parent) : QAbstractListModel(parent)
|
||||
{
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
|
||||
|
||||
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
|
||||
if (serverIndex < 0 || serverIndex >= m_descriptions.size()) {
|
||||
return;
|
||||
}
|
||||
auto defaultContainer = m_descriptions.at(serverIndex).defaultContainer;
|
||||
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
|
||||
emit ServersModel::defaultServerNameChanged();
|
||||
});
|
||||
|
||||
connect(this, &ServersModel::processedServerIndexChanged, this, &ServersModel::processedServerChanged);
|
||||
}
|
||||
|
||||
int ServersModel::rowCount(const QModelIndex &parent) const
|
||||
@@ -56,52 +61,22 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
|
||||
return row.serverName;
|
||||
case ServerDescriptionRole:
|
||||
return configVersion ? row.baseDescription : (row.baseDescription + row.hostName);
|
||||
case CollapsedServerDescriptionRole:
|
||||
return row.collapsedServerDescription;
|
||||
case ExpandedServerDescriptionRole:
|
||||
return row.expandedServerDescription;
|
||||
case HostNameRole:
|
||||
return row.hostName;
|
||||
case CredentialsRole:
|
||||
return QVariant::fromValue(serverCredentials(index.row()));
|
||||
case ServerIdRole:
|
||||
return row.serverId;
|
||||
case CredentialsLoginRole:
|
||||
return serverCredentials(index.row()).userName;
|
||||
case IsDefaultRole:
|
||||
return index.row() == m_defaultServerIndex;
|
||||
case IsCurrentlyProcessedRole:
|
||||
return index.row() == m_processedServerIndex;
|
||||
return row.serverId == m_defaultServerId;
|
||||
case HasWriteAccessRole:
|
||||
return row.hasWriteAccess;
|
||||
case ContainsAmneziaDnsRole:
|
||||
return row.primaryDnsIsAmnezia;
|
||||
case DefaultContainerRole:
|
||||
return QVariant::fromValue(row.defaultContainer);
|
||||
case HasInstalledContainers:
|
||||
return row.hasInstalledVpnContainers;
|
||||
case IsServerFromTelegramApiRole:
|
||||
return false;
|
||||
case IsServerFromGatewayApiRole:
|
||||
return row.isServerFromGatewayApi;
|
||||
case ApiConfigRole:
|
||||
return QVariant();
|
||||
case IsCountrySelectionAvailableRole:
|
||||
return row.isCountrySelectionAvailable;
|
||||
case ApiAvailableCountriesRole:
|
||||
return row.apiAvailableCountries;
|
||||
case ApiServerCountryCodeRole:
|
||||
return row.apiServerCountryCode;
|
||||
case HasAmneziaDns:
|
||||
return row.primaryDnsIsAmnezia;
|
||||
case IsAdVisibleRole:
|
||||
return row.isAdVisible;
|
||||
case AdHeaderRole:
|
||||
return row.adHeader;
|
||||
case AdDescriptionRole:
|
||||
return row.adDescription;
|
||||
case AdEndpointRole:
|
||||
return row.adEndpoint;
|
||||
case IsRenewalAvailableRole:
|
||||
return row.isRenewalAvailable;
|
||||
case IsSubscriptionExpiredRole:
|
||||
return row.isSubscriptionExpired;
|
||||
case IsSubscriptionExpiringSoonRole:
|
||||
@@ -117,68 +92,32 @@ QVariant ServersModel::data(const int index, int role) const
|
||||
return data(modelIndex, role);
|
||||
}
|
||||
|
||||
void ServersModel::updateModel(const QVector<ServerDescription> &descriptions, int defaultServerIndex)
|
||||
void ServersModel::updateModel(const QVector<ServerDescription> &descriptions,
|
||||
const QString &defaultServerId)
|
||||
{
|
||||
beginResetModel();
|
||||
m_descriptions = descriptions;
|
||||
m_defaultServerIndex = defaultServerIndex;
|
||||
m_defaultServerId = defaultServerId;
|
||||
endResetModel();
|
||||
emit defaultServerIndexChanged(m_defaultServerIndex);
|
||||
emit processedServerChanged();
|
||||
}
|
||||
|
||||
const int ServersModel::getDefaultServerIndex()
|
||||
void ServersModel::setDefaultServerId(const QString &serverId)
|
||||
{
|
||||
return m_defaultServerIndex;
|
||||
}
|
||||
|
||||
const int ServersModel::getServersCount()
|
||||
{
|
||||
return m_descriptions.size();
|
||||
}
|
||||
|
||||
bool ServersModel::hasServerWithWriteAccess()
|
||||
{
|
||||
for (size_t i = 0; i < getServersCount(); i++) {
|
||||
if (qvariant_cast<bool>(data(static_cast<int>(i), HasWriteAccessRole))) {
|
||||
return true;
|
||||
}
|
||||
if (m_defaultServerId == serverId) {
|
||||
return;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServersModel::setProcessedServerIndex(const int index)
|
||||
{
|
||||
if (m_processedServerIndex != index) {
|
||||
m_processedServerIndex = index;
|
||||
emit processedServerIndexChanged(m_processedServerIndex);
|
||||
const int oldIndex = rowForServerId(m_descriptions, m_defaultServerId);
|
||||
const int newIndex = rowForServerId(m_descriptions, serverId);
|
||||
m_defaultServerId = serverId;
|
||||
|
||||
const QVector<int> roles = { IsDefaultRole };
|
||||
if (oldIndex >= 0 && oldIndex < m_descriptions.size()) {
|
||||
emit dataChanged(this->index(oldIndex), this->index(oldIndex), roles);
|
||||
}
|
||||
if (newIndex >= 0 && newIndex < m_descriptions.size()) {
|
||||
emit dataChanged(this->index(newIndex), this->index(newIndex), roles);
|
||||
}
|
||||
}
|
||||
|
||||
const ServerCredentials ServersModel::getProcessedServerCredentials()
|
||||
{
|
||||
return serverCredentials(m_processedServerIndex);
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerCurrentlyProcessed()
|
||||
{
|
||||
return m_defaultServerIndex == m_processedServerIndex;
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerFromApi()
|
||||
{
|
||||
return data(m_defaultServerIndex, IsServerFromTelegramApiRole).toBool()
|
||||
|| data(m_defaultServerIndex, IsServerFromGatewayApiRole).toBool();
|
||||
}
|
||||
|
||||
bool ServersModel::isProcessedServerHasWriteAccess()
|
||||
{
|
||||
return qvariant_cast<bool>(data(m_processedServerIndex, HasWriteAccessRole));
|
||||
}
|
||||
|
||||
bool ServersModel::isDefaultServerHasWriteAccess()
|
||||
{
|
||||
return qvariant_cast<bool>(data(m_defaultServerIndex, HasWriteAccessRole));
|
||||
}
|
||||
|
||||
QHash<int, QByteArray> ServersModel::roleNames() const
|
||||
@@ -187,41 +126,22 @@ QHash<int, QByteArray> ServersModel::roleNames() const
|
||||
|
||||
roles[NameRole] = "name";
|
||||
roles[ServerDescriptionRole] = "serverDescription";
|
||||
roles[CollapsedServerDescriptionRole] = "collapsedServerDescription";
|
||||
roles[ExpandedServerDescriptionRole] = "expandedServerDescription";
|
||||
|
||||
roles[HostNameRole] = "hostName";
|
||||
roles[ServerIdRole] = "serverId";
|
||||
|
||||
roles[CredentialsRole] = "credentials";
|
||||
roles[CredentialsLoginRole] = "credentialsLogin";
|
||||
|
||||
roles[IsDefaultRole] = "isDefault";
|
||||
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
|
||||
|
||||
roles[HasWriteAccessRole] = "hasWriteAccess";
|
||||
|
||||
roles[ContainsAmneziaDnsRole] = "containsAmneziaDns";
|
||||
|
||||
roles[DefaultContainerRole] = "defaultContainer";
|
||||
roles[HasInstalledContainers] = "hasInstalledContainers";
|
||||
|
||||
roles[IsServerFromTelegramApiRole] = "isServerFromTelegramApi";
|
||||
roles[IsServerFromGatewayApiRole] = "isServerFromGatewayApi";
|
||||
roles[ApiConfigRole] = "apiConfig";
|
||||
roles[IsCountrySelectionAvailableRole] = "isCountrySelectionAvailable";
|
||||
roles[ApiAvailableCountriesRole] = "apiAvailableCountries";
|
||||
roles[ApiServerCountryCodeRole] = "apiServerCountryCode";
|
||||
|
||||
roles[IsAdVisibleRole] = "isAdVisible";
|
||||
roles[AdHeaderRole] = "adHeader";
|
||||
roles[AdDescriptionRole] = "adDescription";
|
||||
roles[AdEndpointRole] = "adEndpoint";
|
||||
roles[IsRenewalAvailableRole] = "isRenewalAvailable";
|
||||
roles[IsSubscriptionExpiredRole] = "isSubscriptionExpired";
|
||||
roles[IsSubscriptionExpiringSoonRole] = "isSubscriptionExpiringSoon";
|
||||
|
||||
roles[HasAmneziaDns] = "hasAmneziaDns";
|
||||
|
||||
return roles;
|
||||
}
|
||||
|
||||
@@ -233,40 +153,3 @@ ServerCredentials ServersModel::serverCredentials(int index) const
|
||||
return m_descriptions.at(index).selfHostedSshCredentials;
|
||||
}
|
||||
|
||||
bool ServersModel::isServerFromApi(const int serverIndex)
|
||||
{
|
||||
return data(serverIndex, IsServerFromTelegramApiRole).toBool()
|
||||
|| data(serverIndex, IsServerFromGatewayApiRole).toBool();
|
||||
}
|
||||
|
||||
QVariant ServersModel::getDefaultServerData(const QString roleString)
|
||||
{
|
||||
auto roles = roleNames();
|
||||
for (auto it = roles.begin(); it != roles.end(); it++) {
|
||||
if (QString(it.value()) == roleString) {
|
||||
return data(m_defaultServerIndex, it.key());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
QVariant ServersModel::getProcessedServerData(const QString &roleString)
|
||||
{
|
||||
auto roles = roleNames();
|
||||
for (auto it = roles.begin(); it != roles.end(); it++) {
|
||||
if (QString(it.value()) == roleString) {
|
||||
return data(m_processedServerIndex, it.key());
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
bool ServersModel::serverHasInstalledContainers(const int serverIndex) const
|
||||
{
|
||||
if (serverIndex < 0 || serverIndex >= m_descriptions.size()) {
|
||||
return false;
|
||||
}
|
||||
return m_descriptions.at(serverIndex).hasInstalledVpnContainers;
|
||||
}
|
||||
|
||||
@@ -14,39 +14,22 @@ public:
|
||||
enum Roles {
|
||||
NameRole = Qt::UserRole + 1,
|
||||
ServerDescriptionRole,
|
||||
CollapsedServerDescriptionRole,
|
||||
ExpandedServerDescriptionRole,
|
||||
HostNameRole,
|
||||
ServerIdRole,
|
||||
|
||||
CredentialsRole,
|
||||
CredentialsLoginRole,
|
||||
|
||||
IsDefaultRole,
|
||||
IsCurrentlyProcessedRole,
|
||||
|
||||
HasWriteAccessRole,
|
||||
|
||||
ContainsAmneziaDnsRole,
|
||||
|
||||
DefaultContainerRole,
|
||||
|
||||
HasInstalledContainers,
|
||||
|
||||
IsServerFromTelegramApiRole,
|
||||
IsServerFromGatewayApiRole,
|
||||
ApiConfigRole,
|
||||
IsCountrySelectionAvailableRole,
|
||||
ApiAvailableCountriesRole,
|
||||
ApiServerCountryCodeRole,
|
||||
IsAdVisibleRole,
|
||||
AdHeaderRole,
|
||||
AdDescriptionRole,
|
||||
AdEndpointRole,
|
||||
IsRenewalAvailableRole,
|
||||
IsSubscriptionExpiredRole,
|
||||
IsSubscriptionExpiringSoonRole,
|
||||
|
||||
HasAmneziaDns
|
||||
};
|
||||
|
||||
ServersModel(QObject *parent = nullptr);
|
||||
@@ -56,52 +39,19 @@ public:
|
||||
QVariant data(const int index, int role = Qt::DisplayRole) const;
|
||||
|
||||
public slots:
|
||||
const int getDefaultServerIndex();
|
||||
bool isDefaultServerCurrentlyProcessed();
|
||||
bool isDefaultServerFromApi();
|
||||
|
||||
bool isProcessedServerHasWriteAccess();
|
||||
bool isDefaultServerHasWriteAccess();
|
||||
bool hasServerWithWriteAccess();
|
||||
|
||||
const int getServersCount();
|
||||
|
||||
void setProcessedServerIndex(const int index);
|
||||
|
||||
const ServerCredentials getProcessedServerCredentials();
|
||||
QVariant getProcessedServerData(const QString &roleString);
|
||||
|
||||
QVariant getDefaultServerData(const QString roleString);
|
||||
|
||||
bool isServerFromApi(const int serverIndex);
|
||||
|
||||
void updateModel(const QVector<amnezia::ServerDescription> &descriptions, int defaultServerIndex);
|
||||
void updateModel(const QVector<amnezia::ServerDescription> &descriptions,
|
||||
const QString &defaultServerId);
|
||||
void setDefaultServerId(const QString &serverId);
|
||||
|
||||
protected:
|
||||
QHash<int, QByteArray> roleNames() const override;
|
||||
|
||||
signals:
|
||||
void processedServerIndexChanged(const int index);
|
||||
void processedServerChanged();
|
||||
|
||||
void defaultServerIndexChanged(const int index);
|
||||
void defaultServerNameChanged();
|
||||
void defaultServerDescriptionChanged();
|
||||
|
||||
void defaultServerDefaultContainerChanged(const int containerIndex);
|
||||
|
||||
void updateApiCountryModel();
|
||||
void updateApiServicesModel();
|
||||
|
||||
private:
|
||||
ServerCredentials serverCredentials(int index) const;
|
||||
|
||||
bool serverHasInstalledContainers(const int serverIndex) const;
|
||||
|
||||
QVector<amnezia::ServerDescription> m_descriptions;
|
||||
|
||||
int m_defaultServerIndex = -1;
|
||||
int m_processedServerIndex = -1;
|
||||
QString m_defaultServerId;
|
||||
};
|
||||
|
||||
#endif // SERVERSMODEL_H
|
||||
|
||||
@@ -51,11 +51,11 @@ Rectangle {
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: {
|
||||
Qt.openUrlExternally(ServersModel.getDefaultServerData("adEndpoint"))
|
||||
Qt.openUrlExternally(ServersUiController.serverAdEndpoint(ServersUiController.defaultServerId))
|
||||
}
|
||||
|
||||
Keys.onReturnPressed: {
|
||||
Qt.openUrlExternally(ServersModel.getDefaultServerData("adEndpoint"))
|
||||
Qt.openUrlExternally(ServersUiController.serverAdEndpoint(ServersUiController.defaultServerId))
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@@ -144,7 +144,7 @@ Rectangle {
|
||||
|
||||
onClicked: function() {
|
||||
root.forceActiveFocus()
|
||||
Qt.openUrlExternally(ServersModel.getDefaultServerData("adEndpoint"))
|
||||
Qt.openUrlExternally(ServersUiController.serverAdEndpoint(ServersUiController.defaultServerId))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,7 +182,6 @@ Button {
|
||||
}
|
||||
|
||||
onClicked: {
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ConnectionController.connectButtonClicked()
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,6 @@ Item {
|
||||
|
||||
onButtonStartChanged: {
|
||||
if (buttonStart) {
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ConnectionController.connectButtonClicked()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ ListViewType {
|
||||
showImage: !isInstalled
|
||||
|
||||
checkable: isInstalled && !ConnectionController.isConnected
|
||||
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
|
||||
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId)
|
||||
|
||||
onClicked: {
|
||||
if (ConnectionController.isConnected && isInstalled) {
|
||||
@@ -58,7 +58,7 @@ ListViewType {
|
||||
|
||||
if (checked) {
|
||||
containersDropDown.closeTriggered()
|
||||
ServersUiController.setDefaultContainer(ServersUiController.getServerId(ServersUiController.defaultServerIndex), proxyDefaultServerContainersModel.mapToSource(index))
|
||||
ServersUiController.setDefaultContainer(ServersUiController.defaultServerId, proxyDefaultServerContainersModel.mapToSource(index))
|
||||
} else {
|
||||
ServersUiController.processedContainerIndex = proxyDefaultServerContainersModel.mapToSource(index)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
|
||||
|
||||
@@ -46,7 +46,7 @@ DrawerType2 {
|
||||
}
|
||||
|
||||
if (serverName.textField.text !== root.serverNameText) {
|
||||
ServersUiController.editServerName(ServersUiController.getServerId(ServersUiController.processedServerIndex), serverName.textField.text);
|
||||
ServersUiController.editServerName(ServersUiController.processedServerId, serverName.textField.text);
|
||||
}
|
||||
root.closeTriggered()
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import "../Config"
|
||||
ListViewType {
|
||||
id: root
|
||||
|
||||
property int selectedIndex: ServersUiController.defaultServerIndex
|
||||
property int selectedIndex: ServersUiController.getServerIndexById(ServersUiController.defaultServerId)
|
||||
|
||||
anchors.top: serversMenuHeader.bottom
|
||||
anchors.right: parent.right
|
||||
@@ -29,8 +29,8 @@ ListViewType {
|
||||
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
function onDefaultServerIndexChanged() {
|
||||
root.selectedIndex = ServersUiController.defaultServerIndex
|
||||
function onDefaultServerIdChanged() {
|
||||
root.selectedIndex = ServersUiController.getServerIndexById(ServersUiController.defaultServerId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,14 +106,14 @@ ListViewType {
|
||||
z: 1
|
||||
|
||||
onClicked: function() {
|
||||
ServersUiController.processedServerIndex = index
|
||||
ServersUiController.setProcessedServerId(serverId)
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
if (ServersUiController.isServerFromApi(ServersUiController.processedServerId)) {
|
||||
if (ServersUiController.isServerCountrySelectionAvailable(ServersUiController.processedServerId)) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
|
||||
@@ -34,25 +34,25 @@ ListViewType {
|
||||
if (isVpnContainer) {
|
||||
// var isThirdPartyConfig = root.model.data(index, ContainersModel.IsThirdPartyConfigRole)
|
||||
if (isThirdPartyConfig) {
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.processedServerId, containerIndex)
|
||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if (isIpsec) {
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.processedServerId, containerIndex)
|
||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||
} else if (isDns) {
|
||||
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
||||
} else if (isMtProxy) {
|
||||
MtProxyConfigModel.updateModel(config)
|
||||
PageController.goToPage(PageEnum.PageServiceMtProxySettings)
|
||||
PageController.goToPage(PageEnum.PageServiceMtProxySettings, false)
|
||||
} else if (isTelemt) {
|
||||
TelemtConfigModel.updateModel(config)
|
||||
PageController.goToPage(PageEnum.PageServiceTelemtSettings)
|
||||
PageController.goToPage(PageEnum.PageServiceTelemtSettings, false)
|
||||
} else {
|
||||
InstallController.updateProtocols(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
InstallController.updateProtocols(ServersUiController.processedServerId, containerIndex)
|
||||
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ DrawerType2 {
|
||||
property bool isRenewalAvailable: false
|
||||
|
||||
onOpened: {
|
||||
isRenewalAvailable = ServersModel.getDefaultServerData("isRenewalAvailable") && !ApiAccountInfoModel.data("isInAppPurchase")
|
||||
isRenewalAvailable = ServersUiController.isServerRenewalAvailable(ServersUiController.defaultServerId) && !ApiAccountInfoModel.data("isInAppPurchase")
|
||||
}
|
||||
|
||||
expandedStateContent: ColumnLayout {
|
||||
@@ -43,7 +43,7 @@ DrawerType2 {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
text: ServersModel.getDefaultServerData("name") + qsTr(" subscription has expired")
|
||||
text: ServersUiController.serverName(ServersUiController.defaultServerId) + qsTr(" subscription has expired")
|
||||
horizontalAlignment: Text.AlignLeft
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ DrawerType2 {
|
||||
textColor: AmneziaStyle.color.midnightBlack
|
||||
|
||||
clickedFunc: function() {
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.getServerId(ServersUiController.defaultServerIndex))
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.defaultServerId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ DrawerType2 {
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.defaultServerIndex), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.defaultServerId, false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (result) {
|
||||
root.closeTriggered()
|
||||
|
||||
@@ -12,6 +12,8 @@ Item {
|
||||
property int headerTextMaximumLineCount: 2
|
||||
property int headerTextElide: Qt.ElideRight
|
||||
property string descriptionText
|
||||
property string descriptionLinkText
|
||||
property string descriptionLinkUrl
|
||||
property alias headerRow: headerRow
|
||||
|
||||
implicitWidth: content.implicitWidth
|
||||
@@ -43,5 +45,26 @@ Item {
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
visible: root.descriptionText !== ""
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
id: descriptionLink
|
||||
Layout.topMargin: 16
|
||||
Layout.fillWidth: true
|
||||
text: root.descriptionLinkText !== "" && root.descriptionLinkUrl !== ""
|
||||
? ("<a href=\"" + root.descriptionLinkUrl + "\" style=\"color: " + AmneziaStyle.color.goldenApricotString + ";\">" + root.descriptionLinkText + "</a>")
|
||||
: ""
|
||||
textFormat: Text.RichText
|
||||
visible: root.descriptionLinkText !== ""
|
||||
|
||||
onLinkActivated: function(link) {
|
||||
Qt.openUrlExternally(link)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
acceptedButtons: Qt.NoButton
|
||||
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -344,14 +344,14 @@ PageType {
|
||||
Keys.onReturnPressed: this.clicked()
|
||||
|
||||
onClicked: {
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId)
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersModel.getProcessedServerData("isCountrySelectionAvailable")) {
|
||||
if (ServersUiController.isServerFromApi(ServersUiController.processedServerId)) {
|
||||
if (ServersUiController.isServerCountrySelectionAvailable(ServersUiController.processedServerId)) {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiAvailableCountries)
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
@@ -420,13 +420,13 @@ PageType {
|
||||
|
||||
target: ServersUiController
|
||||
|
||||
function onDefaultServerIndexChanged() {
|
||||
function onDefaultServerIdChanged() {
|
||||
updateContainersModelFilters()
|
||||
}
|
||||
}
|
||||
|
||||
function updateContainersModelFilters() {
|
||||
if (ServersModel.isDefaultServerHasWriteAccess()) {
|
||||
if (ServersUiController.isServerHasWriteAccess(ServersUiController.defaultServerId)) {
|
||||
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
|
||||
} else {
|
||||
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
|
||||
|
||||
@@ -435,13 +435,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
}
|
||||
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
@@ -555,13 +555,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
|
||||
}
|
||||
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
@@ -428,13 +428,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
|
||||
@@ -184,7 +184,7 @@ PageType {
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
|
||||
@@ -123,13 +123,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
}
|
||||
var noButtonFunction = function() {}
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
|
||||
@@ -123,13 +123,13 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
|
||||
@@ -107,7 +107,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -274,7 +274,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
@@ -207,7 +207,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) saveButton.forceActiveFocus()
|
||||
|
||||
@@ -737,7 +737,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -90,7 +90,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -206,7 +206,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -203,7 +203,7 @@ PageType {
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change settings while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove AmneziaDNS from running server"))
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {}
|
||||
|
||||
@@ -20,15 +20,10 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
color: AmneziaStyle.color.onyxBlack
|
||||
}
|
||||
|
||||
property int containerStatus: 1
|
||||
property bool isUpdating: false
|
||||
property bool isCheckingStatus: false
|
||||
property bool isFetchingSecret: false
|
||||
property bool previousEnabled: true
|
||||
property int previousContainerStatus: 1
|
||||
|
||||
@@ -50,7 +45,7 @@ PageType {
|
||||
|
||||
onSavedTransportModeChanged: {
|
||||
if (savedTransportMode === "faketls") {
|
||||
root.syncedSecretTabIndex = 2
|
||||
root.syncedSecretTabIndex = 1
|
||||
} else if (savedTransportMode !== "") {
|
||||
root.syncedSecretTabIndex = 0
|
||||
}
|
||||
@@ -68,9 +63,96 @@ PageType {
|
||||
|
||||
readonly property bool mtProxyNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
||||
|
||||
readonly property bool navigationBlockedWhileBusy: isUpdating || diagLoading
|
||||
property bool remoteOperationBusy: false
|
||||
readonly property bool operationInProgress: isCheckingStatus || isFetchingSecret || isUpdating || diagLoading
|
||||
readonly property bool pageBusy: operationInProgress || remoteOperationBusy
|
||||
readonly property bool navigationBlockedWhileBusy: pageBusy
|
||||
|
||||
property bool pageOpenHandled: false
|
||||
property bool busyIndicatorShown: false
|
||||
|
||||
function syncPageBusyIndicator() {
|
||||
if (!root.pageOpenHandled) {
|
||||
return
|
||||
}
|
||||
var wantBusy = root.pageBusy
|
||||
if (wantBusy === root.busyIndicatorShown) {
|
||||
return
|
||||
}
|
||||
root.busyIndicatorShown = wantBusy
|
||||
PageController.showBusyIndicator(wantBusy)
|
||||
}
|
||||
|
||||
onPageBusyChanged: syncPageBusyIndicator()
|
||||
|
||||
function mtProxyDomainToHex(domain) {
|
||||
var hex = ""
|
||||
for (var i = 0; i < domain.length; i++) {
|
||||
var code = domain.charCodeAt(i).toString(16)
|
||||
hex += (code.length < 2 ? "0" : "") + code
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
function mtProxyClientSecret(baseHex32, mode, tlsDomain) {
|
||||
if (baseHex32 === "") {
|
||||
return ""
|
||||
}
|
||||
if (mode === "faketls") {
|
||||
return "ee" + baseHex32 + mtProxyDomainToHex(tlsDomain)
|
||||
}
|
||||
return "dd" + baseHex32
|
||||
}
|
||||
|
||||
function mtProxyClientSecretForTabIndex(baseHex32, tabIndex, tlsDomain, defaultTlsDomain) {
|
||||
var domain = tlsDomain !== "" ? tlsDomain : defaultTlsDomain
|
||||
if (tabIndex === 1) {
|
||||
return mtProxyClientSecret(baseHex32, "faketls", domain)
|
||||
}
|
||||
return mtProxyClientSecret(baseHex32, "standard", domain)
|
||||
}
|
||||
|
||||
property bool containerStatusRefreshCallPending: false
|
||||
|
||||
function mtProxyRequestContainerStatusRefresh() {
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
syncPageBusyIndicator()
|
||||
return
|
||||
}
|
||||
isCheckingStatus = true
|
||||
syncPageBusyIndicator()
|
||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
|
||||
function mtProxyScheduleContainerStatusRefresh() {
|
||||
if (containerStatusRefreshCallPending) {
|
||||
return
|
||||
}
|
||||
containerStatusRefreshCallPending = true
|
||||
Qt.callLater(function () {
|
||||
containerStatusRefreshCallPending = false
|
||||
root.mtProxyRequestContainerStatusRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
function mtProxyOnPageShown() {
|
||||
if (root.pageOpenHandled) {
|
||||
return
|
||||
}
|
||||
root.pageOpenHandled = true
|
||||
|
||||
PageController.disableControls(navigationBlockedWhileBusy)
|
||||
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
} else {
|
||||
isCheckingStatus = true
|
||||
}
|
||||
syncPageBusyIndicator()
|
||||
root.mtProxyScheduleContainerStatusRefresh()
|
||||
}
|
||||
|
||||
// Hex values that exist in last loaded / last successfully saved config — show link panel only for these.
|
||||
property var mtProxyPersistedAdditionalHex: []
|
||||
|
||||
function mtProxyRefreshPersistedAdditionalSecrets() {
|
||||
@@ -92,19 +174,15 @@ PageType {
|
||||
return false
|
||||
}
|
||||
|
||||
// Rejects garbage like "123123123123"; only dotted IPv4 shape (≤3 digits per octet, ≤4 octets).
|
||||
readonly property var natIpv4InputFormat: /^(\d{1,3}\.){0,3}\d{0,3}$/
|
||||
|
||||
// Defer SSH/updateContainer so QML control handlers return before nested event loops run;
|
||||
// avoids "Object destroyed while one of its QML signal handlers is in progress".
|
||||
function mtProxyScheduleUpdate(closePage) {
|
||||
var cp = closePage === undefined ? false : closePage
|
||||
Qt.callLater(function () {
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.MtProxy, cp)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.MtProxy, cp)
|
||||
})
|
||||
}
|
||||
|
||||
// Optional IPv4: show invalid while typing only when the string looks complete (four octets), so partial entry is not nagged.
|
||||
function natIpv4FieldShowInvalidError(text) {
|
||||
var t = text ? String(text).replace(/^\s+|\s+$/g, '') : ""
|
||||
if (t === "")
|
||||
@@ -167,15 +245,9 @@ PageType {
|
||||
root.mtProxyRefreshPersistedAdditionalSecrets()
|
||||
})
|
||||
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
return
|
||||
}
|
||||
isCheckingStatus = true
|
||||
InstallController.refreshContainerStatus(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
Qt.callLater(root.mtProxyOnPageShown)
|
||||
}
|
||||
|
||||
// Block back navigation and Escape (via PageStart.isControlsDisabled) while SSH/update or diagnostics refresh runs.
|
||||
onNavigationBlockedWhileBusyChanged: {
|
||||
if (root.visible) {
|
||||
PageController.disableControls(navigationBlockedWhileBusy)
|
||||
@@ -184,10 +256,16 @@ PageType {
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
root.pageOpenHandled = false
|
||||
containerStatusRefreshCallPending = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
busyIndicatorShown = false
|
||||
PageController.disableControls(false)
|
||||
PageController.showBusyIndicator(false)
|
||||
diagLoading = false
|
||||
} else {
|
||||
PageController.disableControls(navigationBlockedWhileBusy)
|
||||
root.mtProxyOnPageShown()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,8 +277,7 @@ PageType {
|
||||
return
|
||||
}
|
||||
if (NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = true
|
||||
InstallController.refreshContainerStatus(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
root.mtProxyScheduleContainerStatusRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -208,10 +285,15 @@ PageType {
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onServerIsBusy(busy) {
|
||||
remoteOperationBusy = busy
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished(message, closePage) {
|
||||
if (!root.visible) {
|
||||
isUpdating = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isUpdating = false
|
||||
@@ -227,9 +309,11 @@ PageType {
|
||||
if (!root.visible) {
|
||||
isUpdating = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isUpdating = false
|
||||
isFetchingSecret = false
|
||||
containerStatus = previousContainerStatus
|
||||
MtProxyConfigModel.setEnabled(previousEnabled)
|
||||
MtProxyConfigModel.setPort(previousPort)
|
||||
@@ -254,6 +338,7 @@ PageType {
|
||||
}
|
||||
if (enabled && pendingUpdateAfterEnable) {
|
||||
pendingUpdateAfterEnable = false
|
||||
isUpdating = true
|
||||
root.mtProxyScheduleUpdate(false)
|
||||
return
|
||||
}
|
||||
@@ -266,9 +351,9 @@ PageType {
|
||||
function onContainerStatusRefreshed(status) {
|
||||
if (!root.visible) {
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isCheckingStatus = false
|
||||
containerStatus = status
|
||||
|
||||
root.savedTransportMode = MtProxyConfigModel.getTransportMode()
|
||||
@@ -276,10 +361,17 @@ PageType {
|
||||
root.savedPublicHost = MtProxyConfigModel.getPublicHost()
|
||||
if (status === 1) {
|
||||
MtProxyConfigModel.setEnabled(true)
|
||||
InstallController.fetchContainerSecret(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
} else if (status === 2) {
|
||||
MtProxyConfigModel.setEnabled(false)
|
||||
isFetchingSecret = true
|
||||
isCheckingStatus = false
|
||||
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
} else {
|
||||
isFetchingSecret = false
|
||||
isCheckingStatus = false
|
||||
if (status === 2) {
|
||||
MtProxyConfigModel.setEnabled(false)
|
||||
}
|
||||
}
|
||||
syncPageBusyIndicator()
|
||||
}
|
||||
|
||||
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
||||
@@ -296,20 +388,35 @@ PageType {
|
||||
|
||||
function onContainerSecretFetched(secret) {
|
||||
if (!root.visible) {
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isFetchingSecret = false
|
||||
syncPageBusyIndicator()
|
||||
MtProxyConfigModel.validateAndSetSecret(secret)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentLayer
|
||||
anchors.fill: parent
|
||||
enabled: !root.pageBusy
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
||||
anchors.topMargin: 20 + PageController.safeAreaTopMargin
|
||||
|
||||
onFocusChanged: {
|
||||
if (this.activeFocus) connectionListView.positionViewAtBeginning()
|
||||
if (this.activeFocus) {
|
||||
if (mainTabBar.currentIndex === 0) {
|
||||
connectionListView.positionViewAtBeginning()
|
||||
} else {
|
||||
settingsListView.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,57 +425,62 @@ PageType {
|
||||
anchors.top: backButton.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 8
|
||||
spacing: 0
|
||||
|
||||
BaseHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
headerText: qsTr("MTProxy settings")
|
||||
descriptionLinkText: qsTr("Read more about this settings")
|
||||
descriptionLinkUrl: "https://core.telegram.org/proxy"
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 0
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
text: qsTr("Read more about this settings")
|
||||
textColor: AmneziaStyle.color.goldenApricot
|
||||
clickedFunction: function () {
|
||||
Qt.openUrlExternally("https://core.telegram.org/proxy")
|
||||
Layout.topMargin: 8
|
||||
visible: root.mtProxyNetworkBlocked
|
||||
text: qsTr("No internet connection. Connect to the internet to change MTProxy settings.")
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: mainTabBar
|
||||
anchors.top: pageHeader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
width: parent.width
|
||||
|
||||
background: Rectangle {
|
||||
color: AmneziaStyle.color.transparent
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color: AmneziaStyle.color.slateGray
|
||||
}
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: mainTabBar
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 4
|
||||
|
||||
background: Rectangle {
|
||||
color: AmneziaStyle.color.transparent
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color: AmneziaStyle.color.slateGray
|
||||
}
|
||||
}
|
||||
|
||||
TabButtonType {
|
||||
text: qsTr("Connection")
|
||||
isSelected: mainTabBar.currentIndex === 0
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Settings")
|
||||
isSelected: mainTabBar.currentIndex === 1
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Connection")
|
||||
isSelected: mainTabBar.currentIndex === 0
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Settings")
|
||||
isSelected: mainTabBar.currentIndex === 1
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: tabContent
|
||||
anchors.top: pageHeader.bottom
|
||||
anchors.top: mainTabBar.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
@@ -382,35 +494,11 @@ PageType {
|
||||
width: connectionListView.width
|
||||
spacing: 0
|
||||
|
||||
function domainToHex(domain) {
|
||||
var hex = ""
|
||||
for (var i = 0; i < domain.length; i++) {
|
||||
var code = domain.charCodeAt(i).toString(16)
|
||||
hex += (code.length < 2 ? "0" : "") + code
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
function secretForMode(mode) {
|
||||
if (mode === "faketls") {
|
||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : MtProxyConfigModel.defaultTlsDomain()
|
||||
return "ee" + secret + domainToHex(domain)
|
||||
} else if (mode === "padded") {
|
||||
return "dd" + secret
|
||||
}
|
||||
return secret
|
||||
}
|
||||
|
||||
property int secretTabIndex: root.syncedSecretTabIndex
|
||||
|
||||
function activeSecret() {
|
||||
if (root.syncedSecretTabIndex === 0) {
|
||||
return secretForMode("standard")
|
||||
}
|
||||
if (root.syncedSecretTabIndex === 1) {
|
||||
return secretForMode("padded")
|
||||
}
|
||||
return secretForMode("faketls")
|
||||
return root.mtProxyClientSecretForTabIndex(secret, root.syncedSecretTabIndex,
|
||||
root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain())
|
||||
}
|
||||
|
||||
function effectiveSecret() {
|
||||
@@ -418,7 +506,7 @@ PageType {
|
||||
}
|
||||
|
||||
function effectiveHost() {
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersModel.getProcessedServerData("hostName")
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
}
|
||||
|
||||
function tmeLink() {
|
||||
@@ -720,7 +808,7 @@ PageType {
|
||||
Layout.bottomMargin: 24
|
||||
Layout.leftMargin: 0
|
||||
Layout.rightMargin: 16
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
text: qsTr("Delete MTProxy")
|
||||
textColor: AmneziaStyle.color.vibrantRed
|
||||
clickedFunction: function () {
|
||||
@@ -730,7 +818,7 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, function () {
|
||||
})
|
||||
@@ -754,37 +842,13 @@ PageType {
|
||||
width: settingsListView.width
|
||||
spacing: 0
|
||||
|
||||
function mtProxyDomainToHex(domain) {
|
||||
var hex = ""
|
||||
for (var i = 0; i < domain.length; i++) {
|
||||
var code = domain.charCodeAt(i).toString(16)
|
||||
hex += (code.length < 2 ? "0" : "") + code
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
function mtProxySecretForBaseHex(baseHex, mode) {
|
||||
if (mode === "faketls") {
|
||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : MtProxyConfigModel.defaultTlsDomain()
|
||||
return "ee" + baseHex + mtProxyDomainToHex(domain)
|
||||
} else if (mode === "padded") {
|
||||
return "dd" + baseHex
|
||||
}
|
||||
return baseHex
|
||||
}
|
||||
|
||||
function mtProxyActiveSecretForBaseHex(baseHex) {
|
||||
if (root.syncedSecretTabIndex === 0) {
|
||||
return mtProxySecretForBaseHex(baseHex, "standard")
|
||||
}
|
||||
if (root.syncedSecretTabIndex === 1) {
|
||||
return mtProxySecretForBaseHex(baseHex, "padded")
|
||||
}
|
||||
return mtProxySecretForBaseHex(baseHex, "faketls")
|
||||
return root.mtProxyClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
|
||||
root.savedTlsDomain, MtProxyConfigModel.defaultTlsDomain())
|
||||
}
|
||||
|
||||
function mtProxyEffectiveHostForLinks() {
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersModel.getProcessedServerData("hostName")
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
}
|
||||
|
||||
function mtProxyTmeLinkForAdditional(baseHex) {
|
||||
@@ -804,7 +868,7 @@ PageType {
|
||||
Layout.bottomMargin: 16
|
||||
text: qsTr("Enable MTProxy")
|
||||
checked: isEnabled
|
||||
enabled: !isCheckingStatus && containerStatus !== 0 && containerStatus !== 3 && !isUpdating
|
||||
enabled: containerStatus !== 0 && containerStatus !== 3 && !root.pageBusy
|
||||
&& !root.mtProxyNetworkBlocked
|
||||
onToggled: function () {
|
||||
if (checked !== isEnabled) {
|
||||
@@ -815,9 +879,9 @@ PageType {
|
||||
isUpdating = true
|
||||
if (checked) {
|
||||
root.pendingUpdateAfterEnable = true
|
||||
InstallController.setContainerEnabled(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, true)
|
||||
InstallController.setContainerEnabled(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, true)
|
||||
} else {
|
||||
InstallController.setContainerEnabled(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, false)
|
||||
InstallController.setContainerEnabled(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -843,19 +907,20 @@ PageType {
|
||||
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
text: secret !== "" ? secret : qsTr("Not generated")
|
||||
text: secret !== "" ? mtProxyActiveSecretForBaseHex(secret) : qsTr("Not generated")
|
||||
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
||||
elide: Text.ElideMiddle
|
||||
wrapMode: Text.WrapAnywhere
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
implicitWidth: 36
|
||||
implicitHeight: 36
|
||||
hoverEnabled: true
|
||||
image: "qrc:/images/controls/refresh-cw.svg"
|
||||
imageColor: AmneziaStyle.color.paleGray
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
onClicked: {
|
||||
var secretSnapshot = secret
|
||||
showQuestionDrawer(
|
||||
@@ -889,7 +954,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 4
|
||||
headerText: qsTr("Public host / IP")
|
||||
textField.placeholderText: ServersModel.getProcessedServerData("hostName")
|
||||
textField.placeholderText: ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
textField.text: publicHost
|
||||
textField.maximumLength: 253
|
||||
textField.validator: PublicHostInputValidator {
|
||||
@@ -936,7 +1001,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 12
|
||||
visible: publicHostTextField.textField.text !== "" &&
|
||||
publicHostTextField.textField.text !== ServersModel.getProcessedServerData("hostName")
|
||||
publicHostTextField.textField.text !== ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
text: qsTr("⚠ This overrides the server IP in connection links. Make sure this host/domain points to your server.")
|
||||
color: AmneziaStyle.color.goldenApricot
|
||||
font.pixelSize: 12
|
||||
@@ -1098,6 +1163,7 @@ PageType {
|
||||
clickedFunction: function () {
|
||||
transportMode = (index === 0) ? "standard" : "faketls"
|
||||
MtProxyConfigModel.setTransportMode(transportMode)
|
||||
root.syncedSecretTabIndex = transportMode === "faketls" ? 1 : 0
|
||||
transportModeDropDown.closeTriggered()
|
||||
}
|
||||
}
|
||||
@@ -1281,11 +1347,14 @@ PageType {
|
||||
implicitWidth: 32
|
||||
implicitHeight: 32
|
||||
hoverEnabled: true
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
image: "qrc:/images/controls/trash.svg"
|
||||
imageColor: AmneziaStyle.color.vibrantRed
|
||||
onClicked: {
|
||||
MtProxyConfigModel.removeAdditionalSecret(index)
|
||||
if (containerStatus === 1) {
|
||||
root.mtProxyScheduleUpdate(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1628,7 +1697,7 @@ PageType {
|
||||
enabled: !diagLoading
|
||||
onClicked: {
|
||||
diagLoading = true
|
||||
InstallController.refreshContainerDiagnostics(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, parseInt(port))
|
||||
InstallController.refreshContainerDiagnostics(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, parseInt(port))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1754,7 +1823,7 @@ PageType {
|
||||
Layout.bottomMargin: 32
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
enabled: !root.mtProxyNetworkBlocked
|
||||
text: qsTr("Save")
|
||||
clickedFunc: function () {
|
||||
@@ -1852,34 +1921,5 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: isCheckingStatus || isUpdating || root.mtProxyNetworkBlocked
|
||||
color: AmneziaStyle.color.midnightBlack
|
||||
opacity: 0.6
|
||||
z: 1
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
}
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
visible: isCheckingStatus || isUpdating
|
||||
running: isCheckingStatus || isUpdating
|
||||
width: 48
|
||||
height: 48
|
||||
}
|
||||
CaptionTextType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 24
|
||||
anchors.rightMargin: 24
|
||||
visible: root.mtProxyNetworkBlocked && !isCheckingStatus && !isUpdating
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("No internet connection. Connect to the internet to change MTProxy settings.")
|
||||
color: AmneziaStyle.color.paleGray
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,7 +73,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("Host")
|
||||
descriptionText: ServersModel.getProcessedServerData("hostName")
|
||||
descriptionText: ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
@@ -173,7 +173,7 @@ PageType {
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.mountSftpDrive(ServersUiController.getServerId(ServersUiController.processedServerIndex), port, password, username)
|
||||
InstallController.mountSftpDrive(ServersUiController.processedServerId, port, password, username)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ PageType {
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
text: qsTr("Host")
|
||||
descriptionText: ServersModel.getProcessedServerData("hostName")
|
||||
descriptionText: ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
|
||||
descriptionOnTop: true
|
||||
|
||||
@@ -285,7 +285,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Socks5Proxy)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Socks5Proxy)
|
||||
tempPort = portTextField.textField.text
|
||||
tempUsername = usernameTextField.textField.text
|
||||
tempPassword = passwordTextField.textField.text
|
||||
|
||||
@@ -18,15 +18,10 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
z: -1
|
||||
color: AmneziaStyle.color.onyxBlack
|
||||
}
|
||||
|
||||
property int containerStatus: 1
|
||||
property bool isUpdating: false
|
||||
property bool isCheckingStatus: false
|
||||
property bool isFetchingSecret: false
|
||||
property bool previousEnabled: true
|
||||
property int previousContainerStatus: 1
|
||||
|
||||
@@ -40,6 +35,7 @@ PageType {
|
||||
property bool previousNatEnabled: false
|
||||
property string previousNatInternalIp: ""
|
||||
property string previousNatExternalIp: ""
|
||||
property string previousSecret: ""
|
||||
|
||||
property string savedTransportMode: ""
|
||||
property string savedTlsDomain: ""
|
||||
@@ -47,7 +43,7 @@ PageType {
|
||||
|
||||
onSavedTransportModeChanged: {
|
||||
if (savedTransportMode === "faketls") {
|
||||
root.syncedSecretTabIndex = 2
|
||||
root.syncedSecretTabIndex = 1
|
||||
} else if (savedTransportMode !== "") {
|
||||
root.syncedSecretTabIndex = 0
|
||||
}
|
||||
@@ -64,13 +60,101 @@ PageType {
|
||||
property string diagStatsEndpoint: ""
|
||||
|
||||
readonly property bool telemtNetworkBlocked: !NetworkReachabilityController.hasInternetAccess
|
||||
readonly property bool navigationBlockedWhileBusy: isUpdating || diagLoading
|
||||
|
||||
// Defer SSH/updateContainer so QML control handlers return before nested event loops run.
|
||||
property bool remoteOperationBusy: false
|
||||
readonly property bool operationInProgress: isCheckingStatus || isFetchingSecret || isUpdating || diagLoading
|
||||
readonly property bool pageBusy: operationInProgress || remoteOperationBusy
|
||||
readonly property bool navigationBlockedWhileBusy: pageBusy
|
||||
|
||||
property bool pageOpenHandled: false
|
||||
property bool busyIndicatorShown: false
|
||||
|
||||
function syncPageBusyIndicator() {
|
||||
if (!root.pageOpenHandled) {
|
||||
return
|
||||
}
|
||||
var wantBusy = root.pageBusy
|
||||
if (wantBusy === root.busyIndicatorShown) {
|
||||
return
|
||||
}
|
||||
root.busyIndicatorShown = wantBusy
|
||||
PageController.showBusyIndicator(wantBusy)
|
||||
}
|
||||
|
||||
onPageBusyChanged: syncPageBusyIndicator()
|
||||
|
||||
function telemtDomainToHex(domain) {
|
||||
var hex = ""
|
||||
for (var i = 0; i < domain.length; i++) {
|
||||
var code = domain.charCodeAt(i).toString(16)
|
||||
hex += (code.length < 2 ? "0" : "") + code
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
function telemtClientSecret(baseHex32, mode, tlsDomain) {
|
||||
if (baseHex32 === "") {
|
||||
return ""
|
||||
}
|
||||
if (mode === "faketls") {
|
||||
return "ee" + baseHex32 + telemtDomainToHex(tlsDomain)
|
||||
}
|
||||
return "dd" + baseHex32
|
||||
}
|
||||
|
||||
function telemtClientSecretForTabIndex(baseHex32, tabIndex, tlsDomain, defaultTlsDomain) {
|
||||
var domain = tlsDomain !== "" ? tlsDomain : defaultTlsDomain
|
||||
if (tabIndex === 1) {
|
||||
return telemtClientSecret(baseHex32, "faketls", domain)
|
||||
}
|
||||
return telemtClientSecret(baseHex32, "standard", domain)
|
||||
}
|
||||
|
||||
property bool containerStatusRefreshCallPending: false
|
||||
|
||||
function telemtRequestContainerStatusRefresh() {
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
syncPageBusyIndicator()
|
||||
return
|
||||
}
|
||||
isCheckingStatus = true
|
||||
syncPageBusyIndicator()
|
||||
InstallController.refreshContainerStatus(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
|
||||
function telemtScheduleContainerStatusRefresh() {
|
||||
if (containerStatusRefreshCallPending) {
|
||||
return
|
||||
}
|
||||
containerStatusRefreshCallPending = true
|
||||
Qt.callLater(function () {
|
||||
containerStatusRefreshCallPending = false
|
||||
root.telemtRequestContainerStatusRefresh()
|
||||
})
|
||||
}
|
||||
|
||||
function telemtOnPageShown() {
|
||||
if (root.pageOpenHandled) {
|
||||
return
|
||||
}
|
||||
root.pageOpenHandled = true
|
||||
|
||||
PageController.disableControls(navigationBlockedWhileBusy)
|
||||
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
} else {
|
||||
isCheckingStatus = true
|
||||
}
|
||||
syncPageBusyIndicator()
|
||||
root.telemtScheduleContainerStatusRefresh()
|
||||
}
|
||||
|
||||
function telemtScheduleUpdate(closePage) {
|
||||
var cp = closePage === undefined ? false : closePage
|
||||
Qt.callLater(function () {
|
||||
InstallController.updateContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, ProtocolEnum.Telemt, cp)
|
||||
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Telemt, cp)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -105,12 +189,7 @@ PageType {
|
||||
root.savedTlsDomain = TelemtConfigModel.getTlsDomain()
|
||||
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
||||
|
||||
if (!NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = false
|
||||
return
|
||||
}
|
||||
isCheckingStatus = true
|
||||
InstallController.refreshContainerStatus(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
Qt.callLater(root.telemtOnPageShown)
|
||||
}
|
||||
|
||||
onNavigationBlockedWhileBusyChanged: {
|
||||
@@ -121,10 +200,16 @@ PageType {
|
||||
|
||||
onVisibleChanged: {
|
||||
if (!visible) {
|
||||
root.pageOpenHandled = false
|
||||
containerStatusRefreshCallPending = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
busyIndicatorShown = false
|
||||
PageController.disableControls(false)
|
||||
PageController.showBusyIndicator(false)
|
||||
diagLoading = false
|
||||
} else {
|
||||
PageController.disableControls(navigationBlockedWhileBusy)
|
||||
root.telemtOnPageShown()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -136,8 +221,7 @@ PageType {
|
||||
return
|
||||
}
|
||||
if (NetworkReachabilityController.hasInternetAccess) {
|
||||
isCheckingStatus = true
|
||||
InstallController.refreshContainerStatus(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
root.telemtScheduleContainerStatusRefresh()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -145,10 +229,15 @@ PageType {
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onServerIsBusy(busy) {
|
||||
remoteOperationBusy = busy
|
||||
}
|
||||
|
||||
function onUpdateContainerFinished(message, closePage) {
|
||||
if (!root.visible) {
|
||||
isUpdating = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isUpdating = false
|
||||
@@ -166,9 +255,11 @@ PageType {
|
||||
if (!root.visible) {
|
||||
isUpdating = false
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isUpdating = false
|
||||
isFetchingSecret = false
|
||||
containerStatus = previousContainerStatus
|
||||
TelemtConfigModel.setEnabled(previousEnabled)
|
||||
TelemtConfigModel.setPort(previousPort)
|
||||
@@ -181,6 +272,9 @@ PageType {
|
||||
TelemtConfigModel.setNatEnabled(previousNatEnabled)
|
||||
TelemtConfigModel.setNatInternalIp(previousNatInternalIp)
|
||||
TelemtConfigModel.setNatExternalIp(previousNatExternalIp)
|
||||
if (previousSecret !== "") {
|
||||
TelemtConfigModel.setSecret(previousSecret)
|
||||
}
|
||||
}
|
||||
|
||||
function onSetContainerEnabledFinished(enabled) {
|
||||
@@ -190,6 +284,7 @@ PageType {
|
||||
}
|
||||
if (enabled && pendingUpdateAfterEnable) {
|
||||
pendingUpdateAfterEnable = false
|
||||
isUpdating = true
|
||||
root.telemtScheduleUpdate(false)
|
||||
return
|
||||
}
|
||||
@@ -202,9 +297,9 @@ PageType {
|
||||
function onContainerStatusRefreshed(status) {
|
||||
if (!root.visible) {
|
||||
isCheckingStatus = false
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isCheckingStatus = false
|
||||
containerStatus = status
|
||||
|
||||
root.savedTransportMode = TelemtConfigModel.getTransportMode()
|
||||
@@ -212,10 +307,17 @@ PageType {
|
||||
root.savedPublicHost = TelemtConfigModel.getPublicHost()
|
||||
if (status === 1) {
|
||||
TelemtConfigModel.setEnabled(true)
|
||||
InstallController.fetchContainerSecret(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
} else if (status === 2) {
|
||||
TelemtConfigModel.setEnabled(false)
|
||||
isFetchingSecret = true
|
||||
isCheckingStatus = false
|
||||
InstallController.fetchContainerSecret(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
} else {
|
||||
isFetchingSecret = false
|
||||
isCheckingStatus = false
|
||||
if (status === 2) {
|
||||
TelemtConfigModel.setEnabled(false)
|
||||
}
|
||||
}
|
||||
syncPageBusyIndicator()
|
||||
}
|
||||
|
||||
function onContainerDiagnosticsRefreshed(portReachable, upstreamReachable, clientsConnected, lastConfigRefresh, statsEndpoint) {
|
||||
@@ -232,20 +334,35 @@ PageType {
|
||||
|
||||
function onContainerSecretFetched(secret) {
|
||||
if (!root.visible) {
|
||||
isFetchingSecret = false
|
||||
return
|
||||
}
|
||||
isFetchingSecret = false
|
||||
syncPageBusyIndicator()
|
||||
TelemtConfigModel.validateAndSetSecret(secret)
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contentLayer
|
||||
anchors.fill: parent
|
||||
enabled: !root.pageBusy
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
||||
anchors.topMargin: 20 + PageController.safeAreaTopMargin
|
||||
|
||||
onFocusChanged: {
|
||||
if (this.activeFocus) connectionListView.positionViewAtBeginning()
|
||||
if (this.activeFocus) {
|
||||
if (mainTabBar.currentIndex === 0) {
|
||||
connectionListView.positionViewAtBeginning()
|
||||
} else {
|
||||
settingsListView.positionViewAtBeginning()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -254,57 +371,62 @@ PageType {
|
||||
anchors.top: backButton.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 8
|
||||
spacing: 0
|
||||
|
||||
BaseHeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
Layout.topMargin: 8
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
headerText: qsTr("Telemt settings")
|
||||
descriptionLinkText: qsTr("Read more about this settings")
|
||||
descriptionLinkUrl: "https://github.com/telemt/telemt"
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 0
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
text: qsTr("Read more about this settings")
|
||||
textColor: AmneziaStyle.color.goldenApricot
|
||||
clickedFunction: function () {
|
||||
Qt.openUrlExternally("https://github.com/telemt/telemt")
|
||||
Layout.topMargin: 8
|
||||
visible: root.telemtNetworkBlocked
|
||||
text: qsTr("No internet connection. Connect to the internet to change Telemt settings.")
|
||||
color: AmneziaStyle.color.mutedGray
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: mainTabBar
|
||||
anchors.top: pageHeader.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
width: parent.width
|
||||
|
||||
background: Rectangle {
|
||||
color: AmneziaStyle.color.transparent
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color: AmneziaStyle.color.slateGray
|
||||
}
|
||||
}
|
||||
|
||||
TabBar {
|
||||
id: mainTabBar
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 4
|
||||
|
||||
background: Rectangle {
|
||||
color: AmneziaStyle.color.transparent
|
||||
Rectangle {
|
||||
width: parent.width
|
||||
height: 1
|
||||
anchors.bottom: parent.bottom
|
||||
color: AmneziaStyle.color.slateGray
|
||||
}
|
||||
}
|
||||
|
||||
TabButtonType {
|
||||
text: qsTr("Connection")
|
||||
isSelected: mainTabBar.currentIndex === 0
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Settings")
|
||||
isSelected: mainTabBar.currentIndex === 1
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Connection")
|
||||
isSelected: mainTabBar.currentIndex === 0
|
||||
}
|
||||
TabButtonType {
|
||||
text: qsTr("Settings")
|
||||
isSelected: mainTabBar.currentIndex === 1
|
||||
}
|
||||
}
|
||||
|
||||
StackLayout {
|
||||
id: tabContent
|
||||
anchors.top: pageHeader.bottom
|
||||
anchors.top: mainTabBar.bottom
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
@@ -318,36 +440,11 @@ PageType {
|
||||
width: connectionListView.width
|
||||
spacing: 0
|
||||
|
||||
function domainToHex(domain) {
|
||||
var hex = ""
|
||||
for (var i = 0; i < domain.length; i++) {
|
||||
var code = domain.charCodeAt(i).toString(16)
|
||||
hex += (code.length < 2 ? "0" : "") + code
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
||||
function secretForMode(mode) {
|
||||
if (mode === "faketls") {
|
||||
var domain = root.savedTlsDomain !== "" ? root.savedTlsDomain : TelemtConfigModel.defaultTlsDomain()
|
||||
return "ee" + secret + domainToHex(domain)
|
||||
} else if (mode === "padded") {
|
||||
return "dd" + secret
|
||||
}
|
||||
// Telemt default (secure MTProto, not FakeTLS): Telegram proxy links require dd + hex secret
|
||||
return "dd" + secret
|
||||
}
|
||||
|
||||
property int secretTabIndex: root.syncedSecretTabIndex
|
||||
|
||||
function activeSecret() {
|
||||
if (root.syncedSecretTabIndex === 0) {
|
||||
return secretForMode("standard")
|
||||
}
|
||||
if (root.syncedSecretTabIndex === 1) {
|
||||
return secretForMode("padded")
|
||||
}
|
||||
return secretForMode("faketls")
|
||||
return root.telemtClientSecretForTabIndex(secret, root.syncedSecretTabIndex,
|
||||
root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain())
|
||||
}
|
||||
|
||||
function effectiveSecret() {
|
||||
@@ -355,7 +452,7 @@ PageType {
|
||||
}
|
||||
|
||||
function effectiveHost() {
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersModel.getProcessedServerData("hostName")
|
||||
return root.savedPublicHost !== "" ? root.savedPublicHost : ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
}
|
||||
|
||||
function tmeLink() {
|
||||
@@ -657,7 +754,7 @@ PageType {
|
||||
Layout.bottomMargin: 24
|
||||
Layout.leftMargin: 0
|
||||
Layout.rightMargin: 16
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
text: qsTr("Delete Telemt")
|
||||
textColor: AmneziaStyle.color.vibrantRed
|
||||
clickedFunction: function () {
|
||||
@@ -667,7 +764,7 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
var yesButtonFunction = function () {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, function () {
|
||||
})
|
||||
@@ -690,6 +787,11 @@ PageType {
|
||||
width: settingsListView.width
|
||||
spacing: 0
|
||||
|
||||
function telemtActiveSecretForBaseHex(baseHex) {
|
||||
return root.telemtClientSecretForTabIndex(baseHex, root.syncedSecretTabIndex,
|
||||
root.savedTlsDomain, TelemtConfigModel.defaultTlsDomain())
|
||||
}
|
||||
|
||||
SwitcherType {
|
||||
id: enableTelemtSwitch
|
||||
Layout.fillWidth: true
|
||||
@@ -699,18 +801,20 @@ PageType {
|
||||
Layout.bottomMargin: 16
|
||||
text: qsTr("Enable Telemt")
|
||||
checked: isEnabled
|
||||
enabled: !isCheckingStatus && containerStatus !== 0 && containerStatus !== 3 && !isUpdating
|
||||
enabled: containerStatus !== 0 && containerStatus !== 3 && !root.pageBusy
|
||||
&& !root.telemtNetworkBlocked
|
||||
onToggled: function () {
|
||||
if (checked !== isEnabled) {
|
||||
previousEnabled = isEnabled
|
||||
previousContainerStatus = containerStatus
|
||||
root.previousSecret = secret
|
||||
isEnabled = checked
|
||||
isUpdating = true
|
||||
if (checked) {
|
||||
root.pendingUpdateAfterEnable = true
|
||||
InstallController.setContainerEnabled(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, true)
|
||||
InstallController.setContainerEnabled(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, true)
|
||||
} else {
|
||||
InstallController.setContainerEnabled(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, false)
|
||||
InstallController.setContainerEnabled(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, false)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -736,26 +840,29 @@ PageType {
|
||||
|
||||
CaptionTextType {
|
||||
Layout.fillWidth: true
|
||||
text: secret !== "" ? secret : qsTr("Not generated")
|
||||
text: secret !== "" ? telemtActiveSecretForBaseHex(secret) : qsTr("Not generated")
|
||||
color: secret !== "" ? AmneziaStyle.color.paleGray : AmneziaStyle.color.mutedGray
|
||||
elide: Text.ElideMiddle
|
||||
wrapMode: Text.WrapAnywhere
|
||||
font.pixelSize: 14
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
Layout.alignment: Qt.AlignTop
|
||||
implicitWidth: 36
|
||||
implicitHeight: 36
|
||||
hoverEnabled: true
|
||||
image: "qrc:/images/controls/refresh-cw.svg"
|
||||
imageColor: AmneziaStyle.color.paleGray
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
onClicked: {
|
||||
var secretSnapshot = secret
|
||||
showQuestionDrawer(
|
||||
qsTr("Generate new secret?"),
|
||||
qsTr("All existing connection links will stop working. Users will need new links."),
|
||||
qsTr("Generate"),
|
||||
qsTr("Cancel"),
|
||||
function () {
|
||||
root.previousSecret = secretSnapshot
|
||||
if (containerStatus === 1) {
|
||||
isUpdating = true
|
||||
TelemtConfigModel.generateSecret()
|
||||
@@ -780,7 +887,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 4
|
||||
headerText: qsTr("Public host / IP")
|
||||
textField.placeholderText: ServersModel.getProcessedServerData("hostName")
|
||||
textField.placeholderText: ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
textField.text: publicHost
|
||||
textField.onEditingFinished: {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
@@ -809,7 +916,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.bottomMargin: 12
|
||||
visible: publicHostTextField.textField.text !== "" &&
|
||||
publicHostTextField.textField.text !== ServersModel.getProcessedServerData("hostName")
|
||||
publicHostTextField.textField.text !== ServersUiController.serverHostName(ServersUiController.processedServerId)
|
||||
text: qsTr("⚠ This overrides the server IP in connection links. Make sure this host/domain points to your server.")
|
||||
color: AmneziaStyle.color.goldenApricot
|
||||
font.pixelSize: 12
|
||||
@@ -926,6 +1033,7 @@ PageType {
|
||||
clickedFunction: function () {
|
||||
transportMode = (index === 0) ? "standard" : "faketls"
|
||||
TelemtConfigModel.setTransportMode(transportMode)
|
||||
root.syncedSecretTabIndex = transportMode === "faketls" ? 1 : 0
|
||||
transportModeDropDown.closeTriggered()
|
||||
}
|
||||
}
|
||||
@@ -1240,7 +1348,7 @@ PageType {
|
||||
enabled: !diagLoading
|
||||
onClicked: {
|
||||
diagLoading = true
|
||||
InstallController.refreshContainerDiagnostics(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, parseInt(port))
|
||||
InstallController.refreshContainerDiagnostics(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, parseInt(port))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1366,7 +1474,7 @@ PageType {
|
||||
Layout.bottomMargin: 32
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
visible: ServersModel.isProcessedServerHasWriteAccess()
|
||||
visible: ServersUiController.isProcessedServerHasWriteAccess()
|
||||
text: qsTr("Save")
|
||||
clickedFunc: function () {
|
||||
var portValue = portTextField.textField.text === ""
|
||||
@@ -1406,6 +1514,7 @@ PageType {
|
||||
previousNatEnabled = natEnabled
|
||||
previousNatInternalIp = natInternalIp
|
||||
previousNatExternalIp = natExternalIp
|
||||
root.previousSecret = secret
|
||||
isUpdating = true
|
||||
root.telemtScheduleUpdate(false)
|
||||
}
|
||||
@@ -1414,34 +1523,5 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: isCheckingStatus || isUpdating || root.telemtNetworkBlocked
|
||||
color: AmneziaStyle.color.midnightBlack
|
||||
opacity: 0.6
|
||||
z: 1
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
}
|
||||
BusyIndicator {
|
||||
anchors.centerIn: parent
|
||||
visible: isCheckingStatus || isUpdating
|
||||
running: isCheckingStatus || isUpdating
|
||||
width: 48
|
||||
height: 48
|
||||
}
|
||||
CaptionTextType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.leftMargin: 24
|
||||
anchors.rightMargin: 24
|
||||
visible: root.telemtNetworkBlocked && !isCheckingStatus && !isUpdating
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
text: qsTr("No internet connection. Connect to the internet to change Telemt settings.")
|
||||
color: AmneziaStyle.color.paleGray
|
||||
wrapMode: Text.WordWrap
|
||||
font.pixelSize: 14
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ PageType {
|
||||
property bool isInAppPurchase: false
|
||||
|
||||
function updateSubscriptionState() {
|
||||
root.subscriptionExpired = ServersModel.getProcessedServerData("isSubscriptionExpired")
|
||||
root.subscriptionExpiringSoon = ServersModel.getProcessedServerData("isSubscriptionExpiringSoon")
|
||||
root.subscriptionExpired = ServersUiController.isServerSubscriptionExpired(ServersUiController.processedServerId)
|
||||
root.subscriptionExpiringSoon = ServersUiController.isServerSubscriptionExpiringSoon(ServersUiController.processedServerId)
|
||||
root.isSubscriptionRenewalAvailable = ApiAccountInfoModel.data("isSubscriptionRenewalAvailable")
|
||||
root.isInAppPurchase = ApiAccountInfoModel.data("isInAppPurchase")
|
||||
}
|
||||
@@ -35,14 +35,22 @@ PageType {
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerChanged() {
|
||||
function onProcessedServerIdChanged() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
root.updateSubscriptionState()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onModelReset() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ApiAccountInfoModel
|
||||
|
||||
@@ -58,8 +66,8 @@ PageType {
|
||||
sourceModel: ServersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
roleName: "serverId"
|
||||
value: ServersUiController.processedServerId
|
||||
}
|
||||
]
|
||||
|
||||
@@ -108,7 +116,7 @@ PageType {
|
||||
|
||||
actionButtonFunction: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
@@ -148,7 +156,7 @@ PageType {
|
||||
text: qsTr("Renew subscription")
|
||||
|
||||
clickedFunc: function() {
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.processedServerId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +208,7 @@ PageType {
|
||||
PageController.showBusyIndicator(true)
|
||||
var prevIndex = ApiCountryModel.currentIndex
|
||||
ApiCountryModel.currentIndex = index
|
||||
if (!SubscriptionUiController.updateServiceFromGateway(ServersUiController.getServerId(ServersUiController.processedServerIndex), countryCode, countryName)) {
|
||||
if (!SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, countryCode, countryName)) {
|
||||
ApiCountryModel.currentIndex = prevIndex
|
||||
}
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
@@ -82,7 +82,7 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
var serverId = ServersUiController.getServerId(ServersUiController.processedServerIndex)
|
||||
var serverId = ServersUiController.processedServerId
|
||||
Qt.callLater(deactivateExternalDevice, serverId, supportTag, countryCode)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
|
||||
@@ -191,7 +191,7 @@ PageType {
|
||||
}
|
||||
if (fileName !== "") {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.exportNativeConfig(ServersUiController.getServerId(ServersUiController.processedServerIndex), countryCode, fileName)
|
||||
let result = SubscriptionUiController.exportNativeConfig(ServersUiController.processedServerId, countryCode, fileName)
|
||||
|
||||
PageController.showBusyIndicator(false)
|
||||
if (result) {
|
||||
@@ -202,9 +202,9 @@ PageType {
|
||||
|
||||
function revokeConfig(countryCode) {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.revokeNativeConfig(ServersUiController.getServerId(ServersUiController.processedServerIndex), countryCode)
|
||||
let result = SubscriptionUiController.revokeNativeConfig(ServersUiController.processedServerId, countryCode)
|
||||
if (result) {
|
||||
SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), true)
|
||||
SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, true)
|
||||
}
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
|
||||
@@ -76,10 +76,18 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIdChanged() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onProcessedServerChanged() {
|
||||
function onModelReset() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
@@ -91,8 +99,8 @@ PageType {
|
||||
sourceModel: ServersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
roleName: "serverId"
|
||||
value: ServersUiController.processedServerId
|
||||
}
|
||||
]
|
||||
|
||||
@@ -131,7 +139,7 @@ PageType {
|
||||
|
||||
actionButtonImage: "qrc:/images/controls/edit-3.svg"
|
||||
|
||||
headerText: root.processedServer.name
|
||||
headerText: root.processedServer != null ? root.processedServer.name : ""
|
||||
|
||||
actionButtonFunction: function() {
|
||||
serverNameEditDrawer.openTriggered()
|
||||
@@ -186,7 +194,7 @@ PageType {
|
||||
textColor: AmneziaStyle.color.midnightBlack
|
||||
|
||||
clickedFunc: function() {
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.processedServerId)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -246,7 +254,7 @@ PageType {
|
||||
text: qsTr("Renew subscription")
|
||||
|
||||
clickedFunc: function() {
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.getRenewalLink(ServersUiController.processedServerId)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,8 +266,8 @@ PageType {
|
||||
SwitcherType {
|
||||
id: switcher
|
||||
|
||||
readonly property bool isVlessProtocol: SubscriptionUiController.isVlessProtocol(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
readonly property bool isProtocolSwitchBlocked: ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
readonly property bool isVlessProtocol: SubscriptionUiController.isVlessProtocol(ServersUiController.processedServerId)
|
||||
readonly property bool isProtocolSwitchBlocked: ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
@@ -277,8 +285,8 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot change protocol during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.setCurrentProtocol(ServersUiController.getServerId(ServersUiController.processedServerIndex), switcher.isVlessProtocol ? "awg" : "vless")
|
||||
SubscriptionUiController.updateServiceFromGateway(ServersUiController.getServerId(ServersUiController.processedServerIndex), "", "", true)
|
||||
SubscriptionUiController.setCurrentProtocol(ServersUiController.processedServerId, switcher.isVlessProtocol ? "awg" : "vless")
|
||||
SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, "", "", true)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -326,7 +334,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsApiSubscriptionKey)
|
||||
PageController.showBusyIndicator(true)
|
||||
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.processedServerId)
|
||||
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
@@ -432,7 +440,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot reload API config during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.updateServiceFromGateway(ServersUiController.getServerId(ServersUiController.processedServerIndex), "", "", true)
|
||||
SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, "", "", true)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -470,8 +478,8 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot unlink device during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
if (SubscriptionUiController.deactivateDevice(ServersUiController.getServerId(ServersUiController.processedServerIndex))) {
|
||||
SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), true)
|
||||
if (SubscriptionUiController.deactivateDevice(ServersUiController.processedServerId)) {
|
||||
SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, true)
|
||||
}
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
@@ -507,7 +515,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.removeServer(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.removeServer(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -526,6 +534,6 @@ PageType {
|
||||
anchors.fill: parent
|
||||
expandedHeight: parent.height * 0.35
|
||||
|
||||
serverNameText: root.processedServer.name
|
||||
serverNameText: root.processedServer != null ? root.processedServer.name : ""
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,18 @@ PageType {
|
||||
|
||||
property var processedServer
|
||||
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIdChanged() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onProcessedServerChanged() {
|
||||
function onModelReset() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
@@ -36,8 +44,8 @@ PageType {
|
||||
sourceModel: ServersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
roleName: "serverId"
|
||||
value: ServersUiController.processedServerId
|
||||
}
|
||||
]
|
||||
|
||||
@@ -48,7 +56,7 @@ PageType {
|
||||
|
||||
Component.onCompleted: {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
|
||||
@@ -119,7 +127,7 @@ PageType {
|
||||
|
||||
if (fileName !== "") {
|
||||
PageController.showBusyIndicator(true)
|
||||
let ok = SubscriptionUiController.exportVpnKey(ServersUiController.getServerId(ServersUiController.processedServerIndex), fileName)
|
||||
let ok = SubscriptionUiController.exportVpnKey(ServersUiController.processedServerId, fileName)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (ok) {
|
||||
PageController.showNotificationMessage(qsTr("Config file saved"))
|
||||
@@ -144,7 +152,7 @@ PageType {
|
||||
|
||||
clickedFunc: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.prepareVpnKeyExport(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
vpnKeyDrawer.openTriggered()
|
||||
}
|
||||
|
||||
@@ -154,10 +154,10 @@ PageType {
|
||||
text: qsTr("Start minimized")
|
||||
descriptionText: qsTr("Launch application minimized (works with autostart option turned on)")
|
||||
|
||||
enabled: switcherAutoStart.checked
|
||||
enabled: SettingsController.isAutoStartEnabled()
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
|
||||
checked: SettingsController.startMinimized
|
||||
checked: SettingsController.isAutoStartEnabled() && SettingsController.startMinimized
|
||||
onToggled: function() {
|
||||
if (checked !== SettingsController.startMinimized) {
|
||||
SettingsController.toggleStartMinimized(checked)
|
||||
|
||||
@@ -37,7 +37,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
property var isServerFromApi: ServersModel.isServerFromApi(ServersUiController.defaultServerIndex)
|
||||
property var isServerFromApi: ServersUiController.isDefaultServerFromApi
|
||||
|
||||
enabled: !isServerFromApi
|
||||
|
||||
|
||||
@@ -59,7 +59,7 @@ PageType {
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIndexChanged() {
|
||||
function onProcessedServerIdChanged() {
|
||||
root.isServerWithWriteAccess = ServersUiController.isProcessedServerHasWriteAccess()
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ PageType {
|
||||
readonly property var tColor: AmneziaStyle.color.paleGray
|
||||
readonly property var clickedHandler: function() {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.scanServerForInstalledContainers(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
InstallController.scanServerForInstalledContainers(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -134,7 +134,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot reboot server during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.rebootServer(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
InstallController.rebootServer(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -164,7 +164,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove server during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.removeServer(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
InstallController.removeServer(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
@@ -194,7 +194,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot clear server from Amnezia software during active connection"))
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeAllContainers(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
InstallController.removeAllContainers(ServersUiController.processedServerId)
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
@@ -208,7 +208,7 @@ PageType {
|
||||
QtObject {
|
||||
id: reset
|
||||
|
||||
property bool isVisible: ServersModel.getProcessedServerData("isServerFromTelegramApi")
|
||||
property bool isVisible: ServersUiController.isServerFromApi(ServersUiController.processedServerId)
|
||||
readonly property string title: qsTr("Reset API config")
|
||||
readonly property string description: ""
|
||||
readonly property var tColor: AmneziaStyle.color.vibrantRed
|
||||
@@ -223,7 +223,7 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Cannot reset API config during active connection"))
|
||||
} else {
|
||||
PageController.showBusyIndicator(true)
|
||||
SubscriptionUiController.removeApiConfig(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
SubscriptionUiController.removeApiConfig(ServersUiController.processedServerId)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,18 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIdChanged() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onProcessedServerChanged() {
|
||||
function onModelReset() {
|
||||
root.processedServer = proxyServersModel.get(0)
|
||||
}
|
||||
}
|
||||
@@ -46,8 +54,8 @@ PageType {
|
||||
sourceModel: ServersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
roleName: "serverId"
|
||||
value: ServersUiController.processedServerId
|
||||
}
|
||||
]
|
||||
|
||||
@@ -80,11 +88,14 @@ PageType {
|
||||
|
||||
actionButtonImage: "qrc:/images/controls/edit-3.svg"
|
||||
|
||||
headerText: root.processedServer.name
|
||||
headerText: root.processedServer != null ? root.processedServer.name : ""
|
||||
descriptionText: {
|
||||
if (root.processedServer.isServerFromTelegramApi) {
|
||||
if (root.processedServer == null) {
|
||||
return ""
|
||||
}
|
||||
if (ServersUiController.isServerFromApi(ServersUiController.processedServerId)) {
|
||||
return root.processedServer.serverDescription
|
||||
} else if (root.processedServer.hasWriteAccess) {
|
||||
} else if (ServersUiController.isProcessedServerHasWriteAccess()) {
|
||||
return root.processedServer.credentialsLogin + " · " + root.processedServer.hostName
|
||||
} else {
|
||||
return root.processedServer.hostName
|
||||
@@ -104,7 +115,7 @@ PageType {
|
||||
anchors.fill: parent
|
||||
expandedHeight: root.height * 0.35
|
||||
|
||||
serverNameText: root.processedServer.name
|
||||
serverNameText: root.processedServer != null ? root.processedServer.name : ""
|
||||
}
|
||||
|
||||
TabBar {
|
||||
@@ -112,8 +123,8 @@ PageType {
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
currentIndex: (ServersModel.getProcessedServerData("isServerFromTelegramApi")
|
||||
&& !ServersModel.getProcessedServerData("hasInstalledContainers")) ?
|
||||
currentIndex: (ServersUiController.isServerFromApi(ServersUiController.processedServerId)
|
||||
&& !ServersUiController.serverHasInstalledContainers(ServersUiController.processedServerId)) ?
|
||||
root.pageSettingsServerData : root.pageSettingsServerProtocols
|
||||
|
||||
background: Rectangle {
|
||||
|
||||
@@ -76,7 +76,7 @@ PageType {
|
||||
|
||||
clickedFunction: function() {
|
||||
if (isClientProtocolExists) {
|
||||
InstallController.openClientSettings(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, protocolIndex)
|
||||
InstallController.openClientSettings(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, protocolIndex)
|
||||
PageController.goToPage(clientProtocolPage);
|
||||
} else {
|
||||
PageController.showNotificationMessage(qsTr("Click the \"connect\" button to create a connection configuration"))
|
||||
@@ -104,7 +104,7 @@ PageType {
|
||||
visible: delegateContent.isServerSettingsVisible
|
||||
|
||||
clickedFunction: function() {
|
||||
InstallController.openServerSettings(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex, protocolIndex)
|
||||
InstallController.openServerSettings(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, protocolIndex)
|
||||
PageController.goToPage(serverProtocolPage);
|
||||
}
|
||||
|
||||
@@ -140,14 +140,14 @@ PageType {
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ConnectionController.isConnected && ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
if (ConnectionController.isConnected && ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
var message = qsTr("Unable to clear %1 profile while there is an active connection").arg(ContainersModel.getProcessedContainerName())
|
||||
PageController.showNotificationMessage(message)
|
||||
return
|
||||
}
|
||||
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.clearCachedProfile(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.clearCachedProfile(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
|
||||
@@ -186,12 +186,12 @@ PageType {
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
if (ServersUiController.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
&& ServersModel.getDefaultServerData("defaultContainer") === ServersUiController.processedContainerIndex) {
|
||||
&& ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove active container"))
|
||||
} else
|
||||
{
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), ServersUiController.processedContainerIndex)
|
||||
InstallController.removeContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex)
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
|
||||
@@ -32,7 +32,7 @@ PageType {
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIndexChanged() {
|
||||
function onProcessedServerIdChanged() {
|
||||
settingsContainersListView.updateContainersModelFilters()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ PageType {
|
||||
Connections {
|
||||
target: ServersUiController
|
||||
|
||||
function onProcessedServerIndexChanged() {
|
||||
function onProcessedServerIdChanged() {
|
||||
settingsContainersListView.updateContainersModelFilters()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ PageType {
|
||||
servicesNameString += servicesName[i] + " · "
|
||||
}
|
||||
|
||||
if (ServersModel.isServerFromApi(index)) {
|
||||
if (ServersUiController.isServerFromApi(serverId)) {
|
||||
return servicesNameString + serverDescription
|
||||
} else {
|
||||
return servicesNameString + hostName
|
||||
@@ -86,11 +86,11 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
ServersUiController.setProcessedServerIndex(index)
|
||||
ServersUiController.setProcessedServerId(serverId)
|
||||
|
||||
if (ServersModel.getProcessedServerData("isServerFromGatewayApi")) {
|
||||
if (ServersUiController.isServerFromApi(ServersUiController.processedServerId)) {
|
||||
PageController.showBusyIndicator(true)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.getServerId(ServersUiController.processedServerIndex), false)
|
||||
let result = SubscriptionUiController.getAccountInfo(ServersUiController.processedServerId, false)
|
||||
PageController.showBusyIndicator(false)
|
||||
if (!result) {
|
||||
return
|
||||
|
||||
@@ -20,7 +20,7 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
property var isServerFromTelegramApi: ServersModel.getDefaultServerData("isServerFromTelegramApi")
|
||||
property var isServerFromTelegramApi: ServersUiController.isServerFromApi(ServersUiController.defaultServerId)
|
||||
|
||||
property bool pageEnabled
|
||||
|
||||
|
||||
@@ -121,7 +121,7 @@ PageType {
|
||||
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textField.text
|
||||
|
||||
InstallController.setProcessedServerCredentials(_hostname, _username, _secretData)
|
||||
ServersUiController.setProcessedServerIndex(-1)
|
||||
ServersUiController.setProcessedServerId("")
|
||||
|
||||
PageController.showBusyIndicator(true)
|
||||
var isConnectionOpened = InstallController.checkSshConnection()
|
||||
|
||||
@@ -165,7 +165,7 @@ PageType {
|
||||
InstallController.install(listView.dockerContainer,
|
||||
listView.containerDefaultPort,
|
||||
listView.containerDefaultTransportProto,
|
||||
ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
ServersUiController.processedServerId)
|
||||
} else {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardProtocols)
|
||||
}
|
||||
|
||||
@@ -15,22 +15,21 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
Component.onCompleted: PageController.disableTabBar(true)
|
||||
Component.onCompleted: {
|
||||
root.installingContainerIndex = ServersUiController.processedContainerIndex
|
||||
PageController.disableTabBar(true)
|
||||
}
|
||||
Component.onDestruction: PageController.disableTabBar(false)
|
||||
|
||||
property bool isTimerRunning: true
|
||||
property string progressBarText: qsTr("Usually it takes no more than 5 minutes")
|
||||
property bool isCancelButtonVisible: false
|
||||
property int installingContainerIndex: -1
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
|
||||
var containerIndex = ServersUiController.processedContainerIndex
|
||||
if (!ConnectionController.isConnected && !ContainersModel.isServiceContainer(containerIndex)) {
|
||||
ServersUiController.setDefaultContainer(ServersUiController.getServerId(ServersUiController.processedServerIndex), containerIndex)
|
||||
}
|
||||
|
||||
PageController.closePage() // close installing page
|
||||
PageController.closePage() // close protocol settings page
|
||||
|
||||
@@ -46,18 +45,13 @@ PageType {
|
||||
}
|
||||
|
||||
function onInstallServerFinished(finishedMessage) {
|
||||
if (!ConnectionController.isConnected) {
|
||||
ServersUiController.setDefaultServerAtIndex(ServersModel.getServersCount() - 1);
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
}
|
||||
|
||||
PageController.goToPageHome()
|
||||
PageController.showNotificationMessage(finishedMessage)
|
||||
}
|
||||
|
||||
function onServerAlreadyExists(serverIndex) {
|
||||
PageController.goToStartPage()
|
||||
ServersUiController.setProcessedServerIndex(serverIndex)
|
||||
ServersUiController.setProcessedServerId(ServersUiController.getServerId(serverIndex))
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo, false)
|
||||
|
||||
PageController.showErrorMessage(qsTr("The server has already been added to the application"))
|
||||
@@ -83,8 +77,8 @@ PageType {
|
||||
sourceModel: ContainersModel
|
||||
filters: [
|
||||
ValueFilter {
|
||||
roleName: "isCurrentlyProcessed"
|
||||
value: true
|
||||
roleName: "dockerContainer"
|
||||
value: root.installingContainerIndex
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ PageType {
|
||||
}
|
||||
|
||||
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
|
||||
InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex, ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex, ServersUiController.processedServerId)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ PageType {
|
||||
var configFileName
|
||||
|
||||
var containerIndex = ServersUiController.processedContainerIndex
|
||||
var serverId = ServersUiController.getServerId(ServersUiController.processedServerIndex)
|
||||
var serverId = ServersUiController.processedServerId
|
||||
|
||||
switch (type) {
|
||||
case PageShare.ConfigType.AmneziaConnection: {
|
||||
@@ -249,7 +249,7 @@ PageType {
|
||||
onClicked: {
|
||||
accessTypeSelector.currentIndex = 1
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.updateClientManagementModel(ServersUiController.getServerId(ServersUiController.processedServerIndex),
|
||||
ExportController.updateClientManagementModel(ServersUiController.processedServerId,
|
||||
ServersUiController.processedContainerIndex)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
@@ -332,8 +332,10 @@ PageType {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
if (ServersModel.isDefaultServerHasWriteAccess() && ServersModel.getDefaultServerData("hasInstalledContainers")) {
|
||||
serverSelectorListView.selectedIndex = proxyServersModel.mapFromSource(ServersUiController.defaultServerIndex)
|
||||
if (ServersUiController.isServerHasWriteAccess(ServersUiController.defaultServerId)
|
||||
&& ServersUiController.serverHasInstalledContainers(ServersUiController.defaultServerId)) {
|
||||
serverSelectorListView.selectedIndex =
|
||||
proxyServersModel.mapFromSource(ServersUiController.getServerIndexById(ServersUiController.defaultServerId))
|
||||
} else {
|
||||
serverSelectorListView.selectedIndex = 0
|
||||
}
|
||||
@@ -344,7 +346,7 @@ PageType {
|
||||
|
||||
function handler() {
|
||||
serverSelector.text = selectedText
|
||||
ServersUiController.setProcessedServerIndex(proxyServersModel.mapToSource(selectedIndex))
|
||||
ServersUiController.setProcessedServerId(ServersUiController.getServerId(proxyServersModel.mapToSource(selectedIndex)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -394,7 +396,7 @@ PageType {
|
||||
target: serverSelector
|
||||
|
||||
function onServerSelectorIndexChanged() {
|
||||
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
|
||||
var defaultContainer = proxyContainersModel.mapFromSource(ServersUiController.serverDefaultContainer(ServersUiController.processedServerId))
|
||||
containerSelectorListView.selectedIndex = defaultContainer
|
||||
containerSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
|
||||
containerSelectorListView.triggerCurrentItem()
|
||||
@@ -417,7 +419,7 @@ PageType {
|
||||
|
||||
if (accessTypeSelector.currentIndex === 1) {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.updateClientManagementModel(ServersUiController.getServerId(ServersUiController.processedServerIndex),
|
||||
ExportController.updateClientManagementModel(ServersUiController.processedServerId,
|
||||
ServersUiController.processedContainerIndex)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
@@ -793,7 +795,7 @@ PageType {
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.renameClient(proxyClientManagementModel.mapToSource(index),
|
||||
clientNameEditor.textField.text,
|
||||
ServersUiController.getServerId(ServersUiController.processedServerIndex),
|
||||
ServersUiController.processedServerId,
|
||||
ServersUiController.processedContainerIndex)
|
||||
PageController.showBusyIndicator(false)
|
||||
Qt.callLater(function(){ clientsListView.freezeFilter = false })
|
||||
@@ -829,14 +831,14 @@ PageType {
|
||||
clientInfoDrawer.closeTriggered()
|
||||
PageController.showBusyIndicator(true)
|
||||
ExportController.revokeConfig(proxyClientManagementModel.mapToSource(index),
|
||||
ServersUiController.getServerId(ServersUiController.processedServerIndex),
|
||||
ServersUiController.processedServerId,
|
||||
ServersUiController.processedContainerIndex)
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
}
|
||||
|
||||
var isActiveConfigForCurrentClient = ServersModel.isDefaultServerCurrentlyProcessed()
|
||||
&& ServersModel.getDefaultServerData("defaultContainer") === ContainersModel.getProcessedContainerIndex()
|
||||
var isActiveConfigForCurrentClient = ServersUiController.isDefaultServerCurrentlyProcessed()
|
||||
&& ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex
|
||||
|
||||
if ((ConnectionController.isConnectionInProgress || ConnectionController.isConnected)
|
||||
&& isActiveConfigForCurrentClient) {
|
||||
|
||||
@@ -118,14 +118,14 @@ PageType {
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
serverSelectorListView.currentIndex = ServersModel.isDefaultServerHasWriteAccess() ?
|
||||
proxyServersModel.mapFromSource(ServersUiController.defaultServerIndex) : 0
|
||||
serverSelectorListView.currentIndex = ServersUiController.isServerHasWriteAccess(ServersUiController.defaultServerId) ?
|
||||
proxyServersModel.mapFromSource(ServersUiController.getServerIndexById(ServersUiController.defaultServerId)) : 0
|
||||
serverSelectorListView.triggerCurrentItem()
|
||||
}
|
||||
|
||||
function handler() {
|
||||
serverSelector.text = selectedText
|
||||
ServersUiController.setProcessedServerIndex(proxyServersModel.mapToSource(selectedIndex))
|
||||
ServersUiController.setProcessedServerId(ServersUiController.getServerId(proxyServersModel.mapToSource(selectedIndex)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -155,7 +155,7 @@ PageType {
|
||||
ExportController.exportErrorOccurred(qsTr("Access error!"))
|
||||
return
|
||||
} else {
|
||||
ExportController.generateFullAccessConfig(ServersUiController.getServerId(ServersUiController.processedServerIndex))
|
||||
ExportController.generateFullAccessConfig(ServersUiController.processedServerId)
|
||||
}
|
||||
|
||||
PageController.showBusyIndicator(false)
|
||||
|
||||
@@ -144,7 +144,7 @@ PageType {
|
||||
}
|
||||
|
||||
function onRemoveServerFinished(finishedMessage) {
|
||||
if (!ServersModel.getServersCount()) {
|
||||
if (!ServersUiController.getServersCount()) {
|
||||
PageController.goToPageHome()
|
||||
} else {
|
||||
PageController.goToStartPage()
|
||||
@@ -156,22 +156,11 @@ PageType {
|
||||
function onNoInstalledContainers() {
|
||||
PageController.setTriggeredByConnectButton(true)
|
||||
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId)
|
||||
PageController.goToPage(PageEnum.PageSetupWizardEasy)
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
objectName: "connectionControllerConnections"
|
||||
|
||||
target: ConnectionController
|
||||
|
||||
function onReconnectWithUpdatedContainer(message) {
|
||||
PageController.showNotificationMessage(message)
|
||||
PageController.closePage()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
objectName: "importControllerConnections"
|
||||
|
||||
@@ -227,7 +216,7 @@ PageType {
|
||||
}
|
||||
|
||||
function onApiServerRemoved(message) {
|
||||
if (!ServersModel.getServersCount()) {
|
||||
if (!ServersUiController.getServersCount()) {
|
||||
PageController.goToPageHome()
|
||||
} else {
|
||||
PageController.goToStartPage()
|
||||
@@ -237,15 +226,6 @@ PageType {
|
||||
}
|
||||
|
||||
function onInstallServerFromApiFinished(message, preferredDefaultIndex) {
|
||||
if (!ConnectionController.isConnected) {
|
||||
if (preferredDefaultIndex !== undefined && preferredDefaultIndex >= 0) {
|
||||
ServersUiController.setDefaultServerAtIndex(preferredDefaultIndex)
|
||||
} else {
|
||||
ServersUiController.setDefaultServerAtIndex(ServersModel.getServersCount() - 1);
|
||||
}
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
}
|
||||
|
||||
PageController.goToPageHome()
|
||||
PageController.showNotificationMessage(message)
|
||||
}
|
||||
@@ -286,7 +266,7 @@ PageType {
|
||||
} else {
|
||||
tabBar.visible = true
|
||||
pagePath = PageController.getPagePath(PageEnum.PageHome)
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId)
|
||||
}
|
||||
|
||||
tabBarStackView.push(pagePath, { "objectName" : pagePath })
|
||||
@@ -360,7 +340,7 @@ PageType {
|
||||
image: "qrc:/images/controls/home.svg"
|
||||
clickedFunc: function () {
|
||||
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
|
||||
ServersUiController.setProcessedServerIndex(ServersUiController.defaultServerIndex)
|
||||
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId)
|
||||
tabBar.currentIndex = 0
|
||||
}
|
||||
}
|
||||
@@ -374,15 +354,15 @@ PageType {
|
||||
|
||||
function onModelReset() {
|
||||
if (!SettingsController.isOnTv()) {
|
||||
var hasServerWithWriteAccess = ServersModel.hasServerWithWriteAccess()
|
||||
var hasServerWithWriteAccess = ServersUiController.hasServerWithWriteAccess()
|
||||
shareTabButton.visible = hasServerWithWriteAccess
|
||||
shareTabButton.width = hasServerWithWriteAccess ? undefined : 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visible: !SettingsController.isOnTv() && ServersModel.hasServerWithWriteAccess()
|
||||
width: !SettingsController.isOnTv() && ServersModel.hasServerWithWriteAccess() ? undefined : 0
|
||||
visible: !SettingsController.isOnTv() && ServersUiController.hasServerWithWriteAccess()
|
||||
width: !SettingsController.isOnTv() && ServersUiController.hasServerWithWriteAccess() ? undefined : 0
|
||||
|
||||
isSelected: tabBar.currentIndex === 1
|
||||
image: "qrc:/images/controls/share-2.svg"
|
||||
|
||||
@@ -124,7 +124,7 @@ void Autostart::setAutostart(bool autostart) {
|
||||
if (file.open(QIODevice::ReadWrite)) {
|
||||
QTextStream stream(&file);
|
||||
stream << "[Desktop Entry]" << Qt::endl;
|
||||
stream << "Exec=AmneziaVPN" << Qt::endl;
|
||||
stream << "Exec=" << appPath() << Qt::endl;
|
||||
stream << "Type=Application" << Qt::endl;
|
||||
stream << "Name=AmneziaVPN" << Qt::endl;
|
||||
stream << "Comment=Client of your self-hosted VPN" << Qt::endl;
|
||||
|
||||
Reference in New Issue
Block a user