fix: various fixes (#2693)

* fix: fixed country model update

* fix: fixed context menu crush on ios

* fix: fixed passphrase dialog freeze

* fix: fixed country switch

* fix: fixed start minimized

* fix: fixed black screen after remove container

* refactor: return cloak and ss only for view

* fix: fixed default server change after improt while connected

* fix: divider visibility

* fix: fixed revoke admin user

* fix: fixed language restore after backup

* fix: link hover for tor settings page

* fix: fixed openvpn connecntion status

* fix: fixed free color status

* fix: fixed client config update

* chore: bump version
This commit is contained in:
vkamn
2026-06-04 15:45:53 +01:00
committed by GitHub
parent a9861d18b7
commit f9b106cf5b
61 changed files with 518 additions and 172 deletions
+2 -2
View File
@@ -4,7 +4,7 @@ set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(PROJECT AmneziaVPN) set(PROJECT AmneziaVPN)
set(AMNEZIAVPN_VERSION 4.9.0.1) set(AMNEZIAVPN_VERSION 4.9.0.2)
set(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP ON CACHE BOOL "" FORCE) set(QT_CREATOR_SKIP_PACKAGE_MANAGER_SETUP ON CACHE BOOL "" FORCE)
set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES set(CMAKE_PROJECT_TOP_LEVEL_INCLUDES
@@ -28,7 +28,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
set(RELEASE_DATE "${CURRENT_DATE}") set(RELEASE_DATE "${CURRENT_DATE}")
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH}) set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
set(APP_ANDROID_VERSION_CODE 2122) set(APP_ANDROID_VERSION_CODE 2123)
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set(MZ_PLATFORM_NAME "linux") set(MZ_PLATFORM_NAME "linux")
@@ -49,14 +49,92 @@ void ConnectionController::setConnectionState(Vpn::ConnectionState state)
} }
} }
ErrorCode ConnectionController::prepareConnection(const QString &serverId, ErrorCode ConnectionController::defaultContainerForServer(const QString &serverId, DockerContainer &container) const
QJsonObject& vpnConfiguration,
DockerContainer& container)
{ {
const auto kind = m_serversRepository->serverKind(serverId);
switch (kind) {
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
const auto cfg = m_serversRepository->selfHostedAdminConfig(serverId);
if (!cfg.has_value()) {
return ErrorCode::InternalError;
}
container = cfg->defaultContainer;
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::SelfHostedUser: {
const auto cfg = m_serversRepository->selfHostedUserConfig(serverId);
if (!cfg.has_value()) {
return ErrorCode::InternalError;
}
container = cfg->defaultContainer;
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::Native: {
const auto cfg = m_serversRepository->nativeConfig(serverId);
if (!cfg.has_value()) {
return ErrorCode::InternalError;
}
container = cfg->defaultContainer;
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::AmneziaPremiumV2:
case serverConfigUtils::ConfigType::AmneziaFreeV3:
case serverConfigUtils::ConfigType::ExternalPremium: {
const auto cfg = m_serversRepository->apiV2Config(serverId);
if (!cfg.has_value()) {
return ErrorCode::InternalError;
}
container = cfg->defaultContainer;
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::AmneziaPremiumV1:
case serverConfigUtils::ConfigType::AmneziaFreeV2:
return ErrorCode::LegacyApiV1NotSupportedError;
case serverConfigUtils::ConfigType::Invalid:
default:
return ErrorCode::InternalError;
}
}
ErrorCode ConnectionController::isConnectionSupported(const QString &serverId) const
{
if (serverId.isEmpty()) {
return ErrorCode::InternalError;
}
if (!isServiceReady()) { if (!isServiceReady()) {
return ErrorCode::AmneziaServiceNotRunning; return ErrorCode::AmneziaServiceNotRunning;
} }
if (serverConfigUtils::isLegacyApiSubscription(m_serversRepository->serverKind(serverId))) {
return ErrorCode::LegacyApiV1NotSupportedError;
}
DockerContainer container = DockerContainer::None;
const ErrorCode errorCode = defaultContainerForServer(serverId, container);
if (errorCode != ErrorCode::NoError) {
return errorCode;
}
if (container == DockerContainer::None) {
return ErrorCode::NoInstalledContainersError;
}
if (ContainerUtils::isUnsupportedContainer(container)) {
return ErrorCode::LegacyContainerNotSupportedError;
}
if (!isContainerSupported(container)) {
return ErrorCode::NotSupportedOnThisPlatform;
}
return ErrorCode::NoError;
}
ErrorCode ConnectionController::prepareConnection(const QString &serverId,
QJsonObject& vpnConfiguration,
DockerContainer& container)
{
ContainerConfig containerConfigModel; ContainerConfig containerConfigModel;
QPair<QString, QString> dns; QPair<QString, QString> dns;
QString hostName; QString hostName;
@@ -120,10 +198,6 @@ ErrorCode ConnectionController::prepareConnection(const QString &serverId,
return ErrorCode::InternalError; return ErrorCode::InternalError;
} }
if (!isContainerSupported(container)) {
return ErrorCode::NotSupportedOnThisPlatform;
}
vpnConfiguration = createConnectionConfiguration(dns, isApiConfig, hostName, description, configVersion, vpnConfiguration = createConnectionConfiguration(dns, isApiConfig, hostName, description, configVersion,
containerConfigModel, container); containerConfigModel, container);
@@ -34,6 +34,8 @@ public:
QJsonObject& vpnConfiguration, QJsonObject& vpnConfiguration,
DockerContainer& container); DockerContainer& container);
ErrorCode isConnectionSupported(const QString &serverId) const;
ErrorCode openConnection(const QString &serverId); ErrorCode openConnection(const QString &serverId);
void closeConnection(); void closeConnection();
@@ -73,6 +75,8 @@ signals:
#endif #endif
private: private:
ErrorCode defaultContainerForServer(const QString &serverId, DockerContainer &container) const;
SecureServersRepository* m_serversRepository; SecureServersRepository* m_serversRepository;
SecureAppSettingsRepository* m_appSettingsRepository; SecureAppSettingsRepository* m_appSettingsRepository;
VpnConnection* m_vpnConnection; VpnConnection* m_vpnConnection;
+1 -1
View File
@@ -191,7 +191,7 @@ void CoreController::initControllers()
m_languageUiController = new LanguageUiController(m_settingsController, m_languageModel, this); m_languageUiController = new LanguageUiController(m_settingsController, m_languageModel, this);
setQmlContextProperty("LanguageUiController", m_languageUiController); setQmlContextProperty("LanguageUiController", m_languageUiController);
m_settingsUiController = new SettingsUiController(m_settingsController, m_serversController, m_languageUiController, this); m_settingsUiController = new SettingsUiController(m_settingsController, m_serversController, this);
setQmlContextProperty("SettingsController", m_settingsUiController); setQmlContextProperty("SettingsController", m_settingsUiController);
m_pageController = new PageController(m_serversController, m_settingsController, this); m_pageController = new PageController(m_serversController, m_settingsController, this);
+22 -18
View File
@@ -33,7 +33,6 @@
#include "core/controllers/connectionController.h" #include "core/controllers/connectionController.h"
#include "ui/models/clientManagementModel.h" #include "ui/models/clientManagementModel.h"
#include "ui/controllers/api/apiNewsUiController.h" #include "ui/controllers/api/apiNewsUiController.h"
#include "ui/models/api/apiCountryModel.h"
#include "ui/models/containersModel.h" #include "ui/models/containersModel.h"
#include "core/utils/containerEnum.h" #include "core/utils/containerEnum.h"
@@ -156,15 +155,17 @@ void CoreSignalHandlers::initExportControllerHandler()
void CoreSignalHandlers::initImportControllerHandler() void CoreSignalHandlers::initImportControllerHandler()
{ {
connect(m_coreController->m_importCoreController, &ImportController::importFinished, this, [this]() { connect(m_coreController->m_importCoreController, &ImportController::importFinished, this, [this]() {
if (!m_coreController->m_connectionController->isConnected()) { if (m_coreController->m_connectionUiController->isConnected()) {
int newServerIndex = m_coreController->m_serversController->getServersCount() - 1; return;
const QString serverId = m_coreController->m_serversController->getServerId(newServerIndex); }
if (!serverId.isEmpty()) {
m_coreController->m_serversController->setDefaultServer(serverId); const int newServerIndex = m_coreController->m_serversController->getServersCount() - 1;
} const QString serverId = m_coreController->m_serversController->getServerId(newServerIndex);
if (m_coreController->m_serversUiController) { if (!serverId.isEmpty()) {
m_coreController->m_serversUiController->setProcessedServerId(serverId); m_coreController->m_serversController->setDefaultServer(serverId);
} }
if (m_coreController->m_serversUiController) {
m_coreController->m_serversUiController->setProcessedServerId(serverId);
} }
}); });
} }
@@ -177,16 +178,13 @@ void CoreSignalHandlers::initApiCountryModelUpdateHandler()
return; return;
} }
QJsonArray availableCountries;
QString serverCountryCode;
const auto apiV2 = m_coreController->m_serversRepository->apiV2Config(processedServerId); const auto apiV2 = m_coreController->m_serversRepository->apiV2Config(processedServerId);
if (apiV2.has_value()) { if (!apiV2.has_value()) {
availableCountries = apiV2->apiConfig.availableCountries; return;
serverCountryCode = apiV2->apiConfig.serverCountryCode;
} }
m_coreController->m_apiCountryModel->updateModel(availableCountries, serverCountryCode); m_coreController->m_apiCountryModel->updateModel(apiV2->apiConfig.availableCountries,
apiV2->apiConfig.serverCountryCode);
}); });
} }
@@ -237,13 +235,16 @@ void CoreSignalHandlers::initLanguageHandler()
connect(m_coreController->m_settingsUiController, &SettingsUiController::resetLanguageToSystem, m_coreController->m_languageUiController, [this]() { connect(m_coreController->m_settingsUiController, &SettingsUiController::resetLanguageToSystem, m_coreController->m_languageUiController, [this]() {
m_coreController->m_languageUiController->changeLanguage(m_coreController->m_languageUiController->getSystemLanguageEnum()); m_coreController->m_languageUiController->changeLanguage(m_coreController->m_languageUiController->getSystemLanguageEnum());
}); });
connect(m_coreController->m_settingsUiController, &SettingsUiController::appLanguageChanged, m_coreController->m_languageUiController, [this]() {
m_coreController->m_languageUiController->onAppLanguageChanged(m_coreController->m_settingsController->getAppLanguage());
});
} }
void CoreSignalHandlers::initAutoConnectHandler() void CoreSignalHandlers::initAutoConnectHandler()
{ {
if (m_coreController->m_settingsUiController->isAutoConnectEnabled() if (m_coreController->m_settingsUiController->isAutoConnectEnabled()
&& !m_coreController->m_serversController->getDefaultServerId().isEmpty()) { && !m_coreController->m_serversController->getDefaultServerId().isEmpty()) {
QTimer::singleShot(1000, this, [this]() { m_coreController->m_connectionUiController->openConnection(); }); QTimer::singleShot(1000, this, [this]() { m_coreController->m_connectionUiController->toggleConnection(); });
} }
} }
@@ -348,6 +349,9 @@ void CoreSignalHandlers::initUnsupportedConnectDrawerHandler()
{ {
connect(m_coreController->m_subscriptionUiController, &SubscriptionUiController::unsupportedConnectDrawerRequested, connect(m_coreController->m_subscriptionUiController, &SubscriptionUiController::unsupportedConnectDrawerRequested,
m_coreController->m_pageController, &PageController::unsupportedConnectDrawerRequested); m_coreController->m_pageController, &PageController::unsupportedConnectDrawerRequested);
connect(m_coreController->m_connectionUiController, &ConnectionUiController::unsupportedConnectDrawerRequested,
m_coreController->m_pageController, &PageController::unsupportedConnectDrawerRequested);
} }
void CoreSignalHandlers::initStrictKillSwitchHandler() void CoreSignalHandlers::initStrictKillSwitchHandler()
@@ -152,8 +152,8 @@ ErrorCode InstallController::setupContainer(const ServerCredentials &credentials
return startupContainerWorker(credentials, container, config, sshSession); return startupContainerWorker(credentials, container, config, sshSession);
} }
ErrorCode InstallController::updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ErrorCode InstallController::updateServerConfig(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig,
ContainerConfig &newConfig) ContainerConfig &newConfig)
{ {
if (!isUpdateDockerContainerRequired(container, oldConfig, newConfig)) { if (!isUpdateDockerContainerRequired(container, oldConfig, newConfig)) {
auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId); auto adminConfig = m_serversRepository->selfHostedAdminConfig(serverId);
@@ -185,7 +185,7 @@ ErrorCode InstallController::updateContainer(const QString &serverId, DockerCont
SshSession sshSession(this); SshSession sshSession(this);
bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig); bool reinstallRequired = isReinstallContainerRequired(container, oldConfig, newConfig);
qDebug() << "InstallController::updateContainer for container" << container << "reinstall required is" << reinstallRequired; qDebug() << "InstallController::updateServerConfig for container" << container << "reinstall required is" << reinstallRequired;
bool xrayServerSettingsChanged = false; bool xrayServerSettingsChanged = false;
if (container == DockerContainer::Xray || container == DockerContainer::SSXray) { if (container == DockerContainer::Xray || container == DockerContainer::SSXray) {
@@ -213,11 +213,11 @@ ErrorCode InstallController::updateContainer(const QString &serverId, DockerCont
if (errorCode == ErrorCode::NoError && xrayServerSettingsChanged && !skipXrayInboundSync) { if (errorCode == ErrorCode::NoError && xrayServerSettingsChanged && !skipXrayInboundSync) {
DnsSettings dnsSettings = { m_appSettingsRepository->primaryDns(), m_appSettingsRepository->secondaryDns() }; DnsSettings dnsSettings = { m_appSettingsRepository->primaryDns(), m_appSettingsRepository->secondaryDns() };
XrayConfigurator xrayConfigurator(&sshSession); XrayConfigurator xrayConfigurator(&sshSession);
qDebug() << "InstallController::updateContainer applying Xray server inbound sync, reinstall=" qDebug() << "InstallController::updateServerConfig applying Xray server inbound sync, reinstall="
<< reinstallRequired; << reinstallRequired;
errorCode = xrayConfigurator.applyServerSettingsToRemote(credentials, container, newConfig, dnsSettings, false); errorCode = xrayConfigurator.applyServerSettingsToRemote(credentials, container, newConfig, dnsSettings, false);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
qDebug() << "InstallController::updateContainer Xray inbound sync failed, error=" qDebug() << "InstallController::updateServerConfig Xray inbound sync failed, error="
<< static_cast<int>(errorCode); << static_cast<int>(errorCode);
} }
} }
@@ -236,6 +236,41 @@ ErrorCode InstallController::updateContainer(const QString &serverId, DockerCont
return errorCode; return errorCode;
} }
ErrorCode InstallController::updateClientConfig(const QString &serverId, DockerContainer container, ContainerConfig &newConfig)
{
switch (m_serversRepository->serverKind(serverId)) {
case serverConfigUtils::ConfigType::SelfHostedAdmin: {
auto config = m_serversRepository->selfHostedAdminConfig(serverId);
if (!config.has_value()) {
return ErrorCode::InternalError;
}
config->updateContainerConfig(container, newConfig);
m_serversRepository->editServer(serverId, config->toJson(), serverConfigUtils::ConfigType::SelfHostedAdmin);
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::SelfHostedUser: {
auto config = m_serversRepository->selfHostedUserConfig(serverId);
if (!config.has_value()) {
return ErrorCode::InternalError;
}
config->updateContainerConfig(container, newConfig);
m_serversRepository->editServer(serverId, config->toJson(), serverConfigUtils::ConfigType::SelfHostedUser);
return ErrorCode::NoError;
}
case serverConfigUtils::ConfigType::Native: {
auto config = m_serversRepository->nativeConfig(serverId);
if (!config.has_value()) {
return ErrorCode::InternalError;
}
config->updateContainerConfig(container, newConfig);
m_serversRepository->editServer(serverId, config->toJson(), serverConfigUtils::ConfigType::Native);
return ErrorCode::NoError;
}
default:
return ErrorCode::InternalError;
}
}
void InstallController::clearCachedProfile(const QString &serverId, DockerContainer container) void InstallController::clearCachedProfile(const QString &serverId, DockerContainer container)
{ {
if (ContainerUtils::containerService(container) == ServiceType::Other) { if (ContainerUtils::containerService(container) == ServiceType::Other) {
@@ -1463,7 +1498,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
QString transportProtoStr = containerAndPortMatch.captured(3); QString transportProtoStr = containerAndPortMatch.captured(3);
DockerContainer container = ContainerUtils::containerFromString(name); DockerContainer container = ContainerUtils::containerFromString(name);
if (container == DockerContainer::None) { if (container == DockerContainer::None || ContainerUtils::isUnsupportedContainer(container)) {
continue; continue;
} }
@@ -1488,7 +1523,7 @@ ErrorCode InstallController::getAlreadyInstalledContainers(const ServerCredentia
QString transportProtoStr = torOrDnsRegMatch.captured(3); QString transportProtoStr = torOrDnsRegMatch.captured(3);
DockerContainer container = ContainerUtils::containerFromString(name); DockerContainer container = ContainerUtils::containerFromString(name);
if (container == DockerContainer::None) { if (container == DockerContainer::None || ContainerUtils::isUnsupportedContainer(container)) {
continue; continue;
} }
@@ -34,7 +34,12 @@ public:
~InstallController(); ~InstallController();
ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config, bool isUpdate = false); ErrorCode setupContainer(const ServerCredentials &credentials, DockerContainer container, ContainerConfig &config, bool isUpdate = false);
ErrorCode updateContainer(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
// Updates server-side container settings (admin self-hosted only): reconfigures the container over SSH.
ErrorCode updateServerConfig(const QString &serverId, DockerContainer container, const ContainerConfig &oldConfig, ContainerConfig &newConfig);
// Updates client-local settings only: rewrites the stored container config for any self-hosted/native server. No SSH.
ErrorCode updateClientConfig(const QString &serverId, DockerContainer container, ContainerConfig &newConfig);
ErrorCode rebootServer(const QString &serverId); ErrorCode rebootServer(const QString &serverId);
ErrorCode removeAllContainers(const QString &serverId); ErrorCode removeAllContainers(const QString &serverId);
@@ -29,6 +29,11 @@ ContainerConfig NativeServerConfig::containerConfig(DockerContainer container) c
return containers.value(container); return containers.value(container);
} }
void NativeServerConfig::updateContainerConfig(DockerContainer container, const ContainerConfig &config)
{
containers[container] = config;
}
QPair<QString, QString> NativeServerConfig::getDnsPair(const QString &primaryDns, const QString &secondaryDns) const QPair<QString, QString> NativeServerConfig::getDnsPair(const QString &primaryDns, const QString &secondaryDns) const
{ {
QString d1 = dns1; QString d1 = dns1;
@@ -27,6 +27,8 @@ struct NativeServerConfig {
bool hasContainers() const; bool hasContainers() const;
ContainerConfig containerConfig(DockerContainer container) const; ContainerConfig containerConfig(DockerContainer container) const;
void updateContainerConfig(DockerContainer container, const ContainerConfig &config);
QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const; QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const;
QJsonObject toJson() const; QJsonObject toJson() const;
@@ -43,6 +43,11 @@ ContainerConfig SelfHostedUserServerConfig::containerConfig(DockerContainer cont
return containers.value(container); return containers.value(container);
} }
void SelfHostedUserServerConfig::updateContainerConfig(DockerContainer container, const ContainerConfig &config)
{
containers[container] = config;
}
QPair<QString, QString> SelfHostedUserServerConfig::getDnsPair(const QString &primaryDns, QPair<QString, QString> SelfHostedUserServerConfig::getDnsPair(const QString &primaryDns,
const QString &secondaryDns) const const QString &secondaryDns) const
{ {
@@ -32,6 +32,8 @@ struct SelfHostedUserServerConfig {
bool hasContainers() const; bool hasContainers() const;
ContainerConfig containerConfig(DockerContainer container) const; ContainerConfig containerConfig(DockerContainer container) const;
void updateContainerConfig(DockerContainer container, const ContainerConfig &config);
QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const; QPair<QString, QString> getDnsPair(const QString &primaryDns, const QString &secondaryDns) const;
QJsonObject toJson() const; QJsonObject toJson() const;
+24 -13
View File
@@ -39,33 +39,44 @@ QString OpenVpnProtocol::defaultConfigPath()
return p; return p;
} }
void OpenVpnProtocol::stop() void OpenVpnProtocol::cleanupResources()
{ {
qDebug() << "OpenVpnProtocol::stop()"; if (m_openVpnProcess || openVpnProcessIsRunning()) {
setConnectionState(Vpn::ConnectionState::Disconnecting);
// TODO: need refactoring
// sendTermSignal() will even return true while server connected ???
if ((m_connectionState == Vpn::ConnectionState::Preparing) || (m_connectionState == Vpn::ConnectionState::Connecting)
|| (m_connectionState == Vpn::ConnectionState::Connected)
|| (m_connectionState == Vpn::ConnectionState::Reconnecting)) {
if (!sendTermSignal()) { if (!sendTermSignal()) {
killOpenVpnProcess(); killOpenVpnProcess();
} }
QThread::msleep(10); QThread::msleep(10);
m_managementServer.stop();
} }
m_managementServer.stop();
#if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS) #if defined(Q_OS_WIN) || defined(Q_OS_LINUX) || defined(Q_OS_MACOS)
IpcClient::withInterface([](QSharedPointer<IpcInterfaceReplica> iface) { IpcClient::withInterface([](QSharedPointer<IpcInterfaceReplica> iface) {
QRemoteObjectPendingReply<bool> reply = iface->disableKillSwitch(); QRemoteObjectPendingReply<bool> reply = iface->disableKillSwitch();
if (!reply.waitForFinished(1000) && !reply.returnValue()) { if (!reply.waitForFinished(1000) && !reply.returnValue()) {
qWarning() << "OpenVpnProtocol::stop(): Failed to disable killswitch"; qWarning() << "OpenVpnProtocol::cleanupResources(): Failed to disable killswitch";
} }
}); });
#endif #endif
}
setConnectionState(Vpn::ConnectionState::Disconnected); void OpenVpnProtocol::stop()
{
qDebug() << "OpenVpnProtocol::stop()";
const bool wasActive = m_connectionState == Vpn::ConnectionState::Preparing
|| m_connectionState == Vpn::ConnectionState::Connecting
|| m_connectionState == Vpn::ConnectionState::Connected
|| m_connectionState == Vpn::ConnectionState::Reconnecting;
if (wasActive) {
setConnectionState(Vpn::ConnectionState::Disconnecting);
}
cleanupResources();
if (wasActive || m_connectionState == Vpn::ConnectionState::Disconnecting) {
setConnectionState(Vpn::ConnectionState::Disconnected);
}
} }
ErrorCode OpenVpnProtocol::prepare() ErrorCode OpenVpnProtocol::prepare()
@@ -168,7 +179,7 @@ void OpenVpnProtocol::updateRouteGateway(QString line)
ErrorCode OpenVpnProtocol::start() ErrorCode OpenVpnProtocol::start()
{ {
OpenVpnProtocol::stop(); cleanupResources();
if (!QFileInfo::exists(configPath())) { if (!QFileInfo::exists(configPath())) {
setLastError(ErrorCode::OpenVpnConfigMissing); setLastError(ErrorCode::OpenVpnConfigMissing);
+1
View File
@@ -29,6 +29,7 @@ protected slots:
void onReadyReadDataFromManagementServer(); void onReadyReadDataFromManagementServer();
private: private:
void cleanupResources();
QString configPath() const; QString configPath() const;
bool openVpnProcessIsRunning() const; bool openVpnProcessIsRunning() const;
bool sendTermSignal(); bool sendTermSignal();
+2
View File
@@ -15,6 +15,8 @@ namespace amnezia
Awg2, Awg2,
WireGuard, WireGuard,
OpenVpn, OpenVpn,
Cloak,
ShadowSocks,
Ipsec, Ipsec,
Xray, Xray,
SSXray, SSXray,
@@ -21,6 +21,8 @@ QString ContainerUtils::containerToString(DockerContainer c)
{ {
if (c == DockerContainer::None) if (c == DockerContainer::None)
return "none"; return "none";
if (c == DockerContainer::Cloak)
return "amnezia-openvpn-cloak";
if (c == DockerContainer::Awg) if (c == DockerContainer::Awg)
return "amnezia-awg"; return "amnezia-awg";
if (c == DockerContainer::Awg2) if (c == DockerContainer::Awg2)
@@ -62,6 +64,8 @@ QMap<DockerContainer, QString> ContainerUtils::containerHumanNames()
{ {
return { { DockerContainer::None, "Not installed" }, return { { DockerContainer::None, "Not installed" },
{ DockerContainer::OpenVpn, "OpenVPN" }, { DockerContainer::OpenVpn, "OpenVPN" },
{ DockerContainer::ShadowSocks, "OpenVPN over SS" },
{ DockerContainer::Cloak, "OpenVPN over Cloak" },
{ DockerContainer::WireGuard, "WireGuard" }, { DockerContainer::WireGuard, "WireGuard" },
{ DockerContainer::Awg, "AmneziaWG" }, { DockerContainer::Awg, "AmneziaWG" },
{ DockerContainer::Awg2, "AmneziaWG" }, { DockerContainer::Awg2, "AmneziaWG" },
@@ -83,6 +87,10 @@ QMap<DockerContainer, QString> ContainerUtils::containerDescriptions()
return { { DockerContainer::OpenVpn, return { { DockerContainer::OpenVpn,
QObject::tr("OpenVPN is the most popular VPN protocol, with flexible configuration options. It uses its " QObject::tr("OpenVPN is the most popular VPN protocol, with flexible configuration options. It uses its "
"own security protocol with SSL/TLS for key exchange.") }, "own security protocol with SSL/TLS for key exchange.") },
{ DockerContainer::ShadowSocks,
QObject::tr("This protocol is no longer supported.") },
{ DockerContainer::Cloak,
QObject::tr("This protocol is no longer supported.") },
{ DockerContainer::WireGuard, { DockerContainer::WireGuard,
QObject::tr("WireGuard - popular VPN protocol with high performance, high speed and low power " QObject::tr("WireGuard - popular VPN protocol with high performance, high speed and low power "
"consumption.") }, "consumption.") },
@@ -194,6 +202,9 @@ QMap<DockerContainer, QString> ContainerUtils::containerDetailedDescriptions()
ServiceType ContainerUtils::containerService(DockerContainer c) ServiceType ContainerUtils::containerService(DockerContainer c)
{ {
if (isUnsupportedContainer(c)) {
return ServiceType::Vpn;
}
return ProtocolUtils::protocolService(defaultProtocol(c)); return ProtocolUtils::protocolService(defaultProtocol(c));
} }
@@ -202,6 +213,8 @@ Proto ContainerUtils::defaultProtocol(DockerContainer c)
switch (c) { switch (c) {
case DockerContainer::None: return Proto::Unknown; case DockerContainer::None: return Proto::Unknown;
case DockerContainer::OpenVpn: return Proto::OpenVpn; case DockerContainer::OpenVpn: return Proto::OpenVpn;
case DockerContainer::Cloak:
case DockerContainer::ShadowSocks: return Proto::Unknown;
case DockerContainer::WireGuard: return Proto::WireGuard; case DockerContainer::WireGuard: return Proto::WireGuard;
case DockerContainer::Awg2: return Proto::Awg; case DockerContainer::Awg2: return Proto::Awg;
case DockerContainer::Awg: return Proto::Awg; case DockerContainer::Awg: return Proto::Awg;
@@ -252,6 +265,8 @@ bool ContainerUtils::isSupportedByCurrentPlatform(DockerContainer c)
// macOS build using Network Extension allow OpenVPN for parity with iOS. // macOS build using Network Extension allow OpenVPN for parity with iOS.
switch (c) { switch (c) {
case DockerContainer::OpenVpn: return true; case DockerContainer::OpenVpn: return true;
case DockerContainer::Cloak: return false;
case DockerContainer::ShadowSocks: return false;
case DockerContainer::WireGuard: return true; case DockerContainer::WireGuard: return true;
case DockerContainer::Awg2: return true; case DockerContainer::Awg2: return true;
case DockerContainer::Awg: return true; case DockerContainer::Awg: return true;
@@ -336,6 +351,10 @@ int ContainerUtils::easySetupOrder(DockerContainer container)
bool ContainerUtils::isShareable(DockerContainer container) bool ContainerUtils::isShareable(DockerContainer container)
{ {
if (isUnsupportedContainer(container)) {
return false;
}
switch (container) { switch (container) {
case DockerContainer::TorWebSite: return false; case DockerContainer::TorWebSite: return false;
case DockerContainer::Dns: return false; case DockerContainer::Dns: return false;
@@ -352,6 +371,11 @@ bool ContainerUtils::isAwgContainer(DockerContainer container)
return container == DockerContainer::Awg || container == DockerContainer::Awg2; return container == DockerContainer::Awg || container == DockerContainer::Awg2;
} }
bool ContainerUtils::isUnsupportedContainer(DockerContainer container)
{
return container == DockerContainer::Cloak || container == DockerContainer::ShadowSocks;
}
QJsonObject ContainerUtils::getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig) QJsonObject ContainerUtils::getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig)
{ {
QString protocolConfigString = containerConfig.value(ProtocolUtils::protoToString(protocol)) QString protocolConfigString = containerConfig.value(ProtocolUtils::protoToString(protocol))
@@ -45,6 +45,8 @@ namespace amnezia
bool isAwgContainer(DockerContainer container); bool isAwgContainer(DockerContainer container);
bool isUnsupportedContainer(DockerContainer container);
QJsonObject getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig); QJsonObject getProtocolConfigFromContainer(const Proto protocol, const QJsonObject &containerConfig);
int installPageOrder(DockerContainer container); int installPageOrder(DockerContainer container);
+1
View File
@@ -79,6 +79,7 @@ namespace amnezia
ImportBackupFileUseRestoreInstead = 903, ImportBackupFileUseRestoreInstead = 903,
RestoreBackupInvalidError = 904, RestoreBackupInvalidError = 904,
LegacyApiV1NotSupportedError = 905, LegacyApiV1NotSupportedError = 905,
LegacyContainerNotSupportedError = 906,
// Android errors // Android errors
AndroidError = 1000, AndroidError = 1000,
+1
View File
@@ -69,6 +69,7 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ImportBackupFileUseRestoreInstead): errorMessage = QObject::tr("Backup files cannot be imported here. Use 'Restore from backup' instead."); break; case (ErrorCode::ImportBackupFileUseRestoreInstead): errorMessage = QObject::tr("Backup files cannot be imported here. Use 'Restore from backup' instead."); break;
case (ErrorCode::RestoreBackupInvalidError): errorMessage = QObject::tr("Backup file is corrupted or has invalid format"); break; case (ErrorCode::RestoreBackupInvalidError): errorMessage = QObject::tr("Backup file is corrupted or has invalid format"); break;
case (ErrorCode::LegacyApiV1NotSupportedError): errorMessage = QObject::tr("This legacy Amnezia subscription format is no longer supported"); break; case (ErrorCode::LegacyApiV1NotSupportedError): errorMessage = QObject::tr("This legacy Amnezia subscription format is no longer supported"); break;
case (ErrorCode::LegacyContainerNotSupportedError): errorMessage = QObject::tr("This protocol is no longer supported. Please select another protocol or remove this container from the server settings."); break;
case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break; case (ErrorCode::ImportOpenConfigError): errorMessage = QObject::tr("Unable to open config file"); break;
case (ErrorCode::NoInstalledContainersError): errorMessage = QObject::tr("VPN Protocols is not installed.\n Please install VPN container at first"); break; case (ErrorCode::NoInstalledContainersError): errorMessage = QObject::tr("VPN Protocols is not installed.\n Please install VPN container at first"); break;
@@ -475,8 +475,7 @@ bool SubscriptionUiController::deactivateExternalDevice(const QString &serverId,
void SubscriptionUiController::validateConfig() void SubscriptionUiController::validateConfig()
{ {
const QString serverId = m_serversController->getDefaultServerId(); const QString serverId = m_serversController->getDefaultServerId();
if (!serverId.isEmpty() && m_serversController->isLegacyApiV1Server(serverId)) { if (serverId.isEmpty()) {
emit unsupportedConnectDrawerRequested();
emit configValidated(false); emit configValidated(false);
return; return;
} }
@@ -8,6 +8,8 @@
#include "amneziaApplication.h" #include "amneziaApplication.h"
#include "core/controllers/serversController.h" #include "core/controllers/serversController.h"
#include "core/models/containerConfig.h"
#include "core/utils/containerEnum.h"
ConnectionUiController::ConnectionUiController(ConnectionController* connectionController, ConnectionUiController::ConnectionUiController(ConnectionController* connectionController,
ServersController* serversController, ServersController* serversController,
@@ -33,7 +35,7 @@ void ConnectionUiController::openConnection()
ErrorCode errorCode = m_connectionController->openConnection(serverId); ErrorCode errorCode = m_connectionController->openConnection(serverId);
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
emit connectionErrorOccurred(errorCode); notifyConnectionBlocked(errorCode);
return; return;
} }
} }
@@ -130,10 +132,36 @@ void ConnectionUiController::toggleConnection()
} else if (isConnected()) { } else if (isConnected()) {
closeConnection(); closeConnection();
} else { } else {
const QString serverId = m_serversController->getDefaultServerId();
if (serverId.isEmpty()) {
return;
}
const ErrorCode errorCode = m_connectionController->isConnectionSupported(serverId);
if (errorCode != ErrorCode::NoError) {
notifyConnectionBlocked(errorCode);
return;
}
emit prepareConfig(); emit prepareConfig();
} }
} }
void ConnectionUiController::notifyConnectionBlocked(ErrorCode errorCode)
{
if (errorCode == ErrorCode::LegacyApiV1NotSupportedError) {
emit unsupportedConnectDrawerRequested();
return;
}
if (errorCode == ErrorCode::NoInstalledContainersError) {
emit noInstalledContainers();
return;
}
emit connectionErrorOccurred(errorCode);
}
bool ConnectionUiController::isConnectionInProgress() const bool ConnectionUiController::isConnectionInProgress() const
{ {
return m_isConnectionInProgress; return m_isConnectionInProgress;
@@ -143,3 +171,32 @@ bool ConnectionUiController::isConnected() const
{ {
return m_isConnected; return m_isConnected;
} }
bool ConnectionUiController::isRevokeBlockedDuringActiveConnection(const QString &serverId, int containerIndex,
const QString &clientId) const
{
if (clientId.isEmpty() || (!isConnected() && !isConnectionInProgress())) {
return false;
}
if (m_serversController->getDefaultServerId() != serverId) {
return false;
}
if (static_cast<int>(m_serversController->getDefaultContainer(serverId)) != containerIndex) {
return false;
}
const auto adminConfig = m_serversController->selfHostedAdminConfig(serverId);
if (!adminConfig.has_value()) {
return false;
}
const QString connectionClientId =
adminConfig->containerConfig(static_cast<DockerContainer>(containerIndex)).protocolConfig.clientId();
if (connectionClientId.isEmpty()) {
return false;
}
return connectionClientId == clientId || connectionClientId.contains(clientId);
}
@@ -35,6 +35,8 @@ public slots:
void openConnection(); void openConnection();
void closeConnection(); void closeConnection();
bool isRevokeBlockedDuringActiveConnection(const QString &serverId, int containerIndex, const QString &clientId) const;
ErrorCode getLastConnectionError(); ErrorCode getLastConnectionError();
void onConnectionStateChanged(Vpn::ConnectionState state); void onConnectionStateChanged(Vpn::ConnectionState state);
@@ -48,9 +50,12 @@ signals:
void connectButtonClicked(); void connectButtonClicked();
void preparingConfig(); void preparingConfig();
void prepareConfig(); void prepareConfig();
void unsupportedConnectDrawerRequested();
void noInstalledContainers();
private: private:
Vpn::ConnectionState getCurrentConnectionState(); Vpn::ConnectionState getCurrentConnectionState();
void notifyConnectionBlocked(ErrorCode errorCode);
ConnectionController* m_connectionController; ConnectionController* m_connectionController;
ServersController* m_serversController; ServersController* m_serversController;
@@ -75,13 +75,7 @@ InstallUiController::InstallUiController(InstallController *installController,
m_connectionController(connectionController) m_connectionController(connectionController)
{ {
connect(m_installController, &InstallController::configValidated, this, &InstallUiController::configValidated); connect(m_installController, &InstallController::configValidated, this, &InstallUiController::configValidated);
connect(m_installController, &InstallController::validationErrorOccurred, this, [this](ErrorCode errorCode) { connect(m_installController, &InstallController::validationErrorOccurred, this, &InstallUiController::installationErrorOccurred);
if (errorCode == ErrorCode::NoInstalledContainersError) {
emit noInstalledContainers();
} else {
emit installationErrorOccurred(errorCode);
}
});
} }
InstallUiController::~InstallUiController() InstallUiController::~InstallUiController()
@@ -217,13 +211,11 @@ void InstallUiController::scanServerForInstalledContainers(const QString &server
emit installationErrorOccurred(errorCode); emit installationErrorOccurred(errorCode);
} }
void InstallUiController::updateContainer(const QString &serverId, int containerIndex, int protocolIndex, bool closePage) bool InstallUiController::buildContainerConfigFromModel(int containerIndex, int protocolIndex, ContainerConfig &containerConfig)
{ {
DockerContainer container = static_cast<DockerContainer>(containerIndex); DockerContainer container = static_cast<DockerContainer>(containerIndex);
Proto protocolType = static_cast<Proto>(protocolIndex); Proto protocolType = static_cast<Proto>(protocolIndex);
ContainerConfig containerConfig;
containerConfig.container = container; containerConfig.container = container;
switch (protocolType) { switch (protocolType) {
@@ -271,6 +263,41 @@ void InstallUiController::updateContainer(const QString &serverId, int container
} }
#endif #endif
default: default:
return false;
}
return true;
}
void InstallUiController::updateClientConfig(const QString &serverId, int containerIndex, int protocolIndex, bool closePage)
{
DockerContainer container = static_cast<DockerContainer>(containerIndex);
Proto protocolType = static_cast<Proto>(protocolIndex);
ContainerConfig containerConfig;
if (!buildContainerConfigFromModel(containerIndex, protocolIndex, containerConfig)) {
return;
}
ErrorCode errorCode = m_installController->updateClientConfig(serverId, container, containerConfig);
if (errorCode == ErrorCode::NoError) {
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container);
m_protocolModel->updateModel(updatedConfig);
updateProtocolConfigModel(serverId, static_cast<int>(container), static_cast<int>(protocolType));
emit updateContainerFinished(tr("Settings updated successfully"), closePage);
return;
}
emit installationErrorOccurred(errorCode);
}
void InstallUiController::updateServerConfig(const QString &serverId, int containerIndex, int protocolIndex, bool closePage)
{
DockerContainer container = static_cast<DockerContainer>(containerIndex);
Proto protocolType = static_cast<Proto>(protocolIndex);
ContainerConfig containerConfig;
if (!buildContainerConfigFromModel(containerIndex, protocolIndex, containerConfig)) {
return; return;
} }
ContainerConfig oldContainerConfig = m_serversController->getContainerConfig(serverId, container); ContainerConfig oldContainerConfig = m_serversController->getContainerConfig(serverId, container);
@@ -305,13 +332,13 @@ void InstallUiController::updateContainer(const QString &serverId, int container
QFuture<ErrorCode> future = QFuture<ErrorCode> future =
QtConcurrent::run([installController, serverId, container, oldConfigCopy, QtConcurrent::run([installController, serverId, container, oldConfigCopy,
newConfigCopy]() mutable -> ErrorCode { newConfigCopy]() mutable -> ErrorCode {
return installController->updateContainer(serverId, container, oldConfigCopy, newConfigCopy); return installController->updateServerConfig(serverId, container, oldConfigCopy, newConfigCopy);
}); });
watcher->setFuture(future); watcher->setFuture(future);
return; return;
} }
ErrorCode errorCode = m_installController->updateContainer(serverId, container, oldContainerConfig, containerConfig); ErrorCode errorCode = m_installController->updateServerConfig(serverId, container, oldContainerConfig, containerConfig);
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container); ContainerConfig updatedConfig = m_serversController->getContainerConfig(serverId, container);
@@ -64,7 +64,8 @@ public slots:
void scanServerForInstalledContainers(const QString &serverId); void scanServerForInstalledContainers(const QString &serverId);
void updateContainer(const QString &serverId, int containerIndex, int protocolIndex, bool closePage = true); void updateServerConfig(const QString &serverId, int containerIndex, int protocolIndex, bool closePage = true);
void updateClientConfig(const QString &serverId, int containerIndex, int protocolIndex, bool closePage = true);
void removeServer(const QString &serverId); void removeServer(const QString &serverId);
void rebootServer(const QString &serverId); void rebootServer(const QString &serverId);
@@ -132,7 +133,6 @@ signals:
void cachedProfileCleared(const QString &message); void cachedProfileCleared(const QString &message);
void apiConfigRemoved(const QString &message); void apiConfigRemoved(const QString &message);
void noInstalledContainers();
void configValidated(bool isValid); void configValidated(bool isValid);
private: private:
@@ -162,6 +162,8 @@ private:
QString m_privateKeyPassphrase; QString m_privateKeyPassphrase;
void updateProtocolConfigModel(const QString &serverId, int containerIndex, int protocolIndex); void updateProtocolConfigModel(const QString &serverId, int containerIndex, int protocolIndex);
bool buildContainerConfigFromModel(int containerIndex, int protocolIndex, ContainerConfig &containerConfig);
}; };
#endif // INSTALLUICONTROLLER_H #endif // INSTALLUICONTROLLER_H
+18 -13
View File
@@ -156,7 +156,17 @@ void ServersUiController::updateModel()
m_serversModel->updateModel(m_orderedServerDescriptions, defaultServerId); m_serversModel->updateModel(m_orderedServerDescriptions, defaultServerId);
updateContainersModel(); if (!m_processedServerId.isEmpty()) {
if (isServerFromApi(m_processedServerId)) {
const auto &description = serverDescriptionById(m_processedServerId);
if (description.isApiV2 && description.isCountrySelectionAvailable
&& !description.apiAvailableCountries.isEmpty()) {
emit updateApiCountryModel();
}
} else {
updateContainersModel();
}
}
updateDefaultServerContainersModel(); updateDefaultServerContainersModel();
if (hadServersFromGatewayBefore != hasServersFromGatewayNow) { if (hadServersFromGatewayBefore != hasServersFromGatewayNow) {
@@ -350,19 +360,14 @@ void ServersUiController::setProcessedServerId(const QString &serverId)
m_processedServerId = normalizedServerId; m_processedServerId = normalizedServerId;
if (newIndex >= 0) { if (newIndex >= 0) {
updateContainersModel(); if (isServerFromApi(m_processedServerId)) {
const auto &description = serverDescriptionById(m_processedServerId);
for (const auto &description : m_orderedServerDescriptions) { if (description.isApiV2 && description.isCountrySelectionAvailable
if (description.serverId != normalizedServerId) { && !description.apiAvailableCountries.isEmpty()) {
continue; emit updateApiCountryModel();
} }
if (description.isApiV2) { } else {
if (description.isCountrySelectionAvailable && !description.apiAvailableCountries.isEmpty()) { updateContainersModel();
emit updateApiCountryModel();
}
emit updateApiServicesModel();
}
break;
} }
} }
@@ -113,7 +113,6 @@ signals:
void processedContainerIndexChanged(int index); void processedContainerIndexChanged(int index);
void hasServersFromGatewayApiChanged(); void hasServersFromGatewayApiChanged();
void updateApiCountryModel(); void updateApiCountryModel();
void updateApiServicesModel();
public: public:
void updateModel(); void updateModel();
@@ -22,12 +22,10 @@
SettingsUiController::SettingsUiController(SettingsController* settingsController, SettingsUiController::SettingsUiController(SettingsController* settingsController,
ServersController* serversController, ServersController* serversController,
LanguageUiController* languageUiController,
QObject *parent) QObject *parent)
: QObject(parent), : QObject(parent),
m_settingsController(settingsController), m_settingsController(settingsController),
m_serversController(serversController), m_serversController(serversController)
m_languageUiController(languageUiController)
{ {
#ifdef Q_OS_ANDROID #ifdef Q_OS_ANDROID
connect(AndroidController::instance(), &AndroidController::notificationStateChanged, this, &SettingsUiController::onNotificationStateChanged); connect(AndroidController::instance(), &AndroidController::notificationStateChanged, this, &SettingsUiController::onNotificationStateChanged);
@@ -157,13 +155,13 @@ void SettingsUiController::restoreAppConfigFromData(const QByteArray &data)
{ {
ErrorCode errorCode = m_settingsController->restoreAppConfigFromData(data); ErrorCode errorCode = m_settingsController->restoreAppConfigFromData(data);
if (errorCode == ErrorCode::NoError) { if (errorCode == ErrorCode::NoError) {
emit appLanguageChanged( emit appLanguageChanged();
static_cast<LanguageSettings::AvailableLanguageEnum>(m_languageUiController->getCurrentLanguageIndex()));
bool amneziaDnsEnabled = m_settingsController->isAmneziaDnsEnabled(); bool amneziaDnsEnabled = m_settingsController->isAmneziaDnsEnabled();
emit amneziaDnsToggled(amneziaDnsEnabled); emit amneziaDnsToggled(amneziaDnsEnabled);
emit restoreBackupFinished(); emit restoreBackupFinished();
emit autoStartChanged();
emit startMinimizedChanged(); emit startMinimizedChanged();
} else { } else {
emit errorOccurred(errorCode); emit errorOccurred(errorCode);
@@ -178,6 +176,7 @@ QString SettingsUiController::getAppVersion()
void SettingsUiController::clearSettings() void SettingsUiController::clearSettings()
{ {
m_settingsController->clearSettings(); m_settingsController->clearSettings();
emit autoStartChanged();
emit startMinimizedChanged(); emit startMinimizedChanged();
emit resetLanguageToSystem(); emit resetLanguageToSystem();
@@ -206,9 +205,8 @@ bool SettingsUiController::isAutoStartEnabled()
void SettingsUiController::toggleAutoStart(bool enable) void SettingsUiController::toggleAutoStart(bool enable)
{ {
m_settingsController->toggleAutoStart(enable); m_settingsController->toggleAutoStart(enable);
if (!enable) { emit autoStartChanged();
emit startMinimizedChanged(); emit startMinimizedChanged();
}
} }
bool SettingsUiController::isStartMinimizedEnabled() bool SettingsUiController::isStartMinimizedEnabled()
+3 -5
View File
@@ -5,8 +5,6 @@
#include "core/controllers/settingsController.h" #include "core/controllers/settingsController.h"
#include "core/controllers/serversController.h" #include "core/controllers/serversController.h"
#include "ui/controllers/languageUiController.h"
#include "ui/models/languageModel.h"
#include "core/utils/errorCodes.h" #include "core/utils/errorCodes.h"
#include "core/utils/routeModes.h" #include "core/utils/routeModes.h"
#include "core/utils/commonStructs.h" #include "core/utils/commonStructs.h"
@@ -17,7 +15,6 @@ class SettingsUiController : public QObject
public: public:
explicit SettingsUiController(SettingsController* settingsController, explicit SettingsUiController(SettingsController* settingsController,
ServersController* serversController, ServersController* serversController,
LanguageUiController* languageUiController,
QObject *parent = nullptr); QObject *parent = nullptr);
Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged) Q_PROPERTY(QString primaryDns READ getPrimaryDns WRITE setPrimaryDns NOTIFY primaryDnsChanged)
@@ -32,6 +29,7 @@ public:
Q_PROPERTY(bool isDevGatewayEnv READ isDevGatewayEnv WRITE toggleDevGatewayEnv NOTIFY devGatewayEnvChanged) Q_PROPERTY(bool isDevGatewayEnv READ isDevGatewayEnv WRITE toggleDevGatewayEnv NOTIFY devGatewayEnvChanged)
Q_PROPERTY(bool isHomeAdLabelVisible READ isHomeAdLabelVisible NOTIFY isHomeAdLabelVisibleChanged) Q_PROPERTY(bool isHomeAdLabelVisible READ isHomeAdLabelVisible NOTIFY isHomeAdLabelVisibleChanged)
Q_PROPERTY(bool autoStartEnabled READ isAutoStartEnabled NOTIFY autoStartChanged)
Q_PROPERTY(bool startMinimized READ isStartMinimizedEnabled NOTIFY startMinimizedChanged) Q_PROPERTY(bool startMinimized READ isStartMinimizedEnabled NOTIFY startMinimizedChanged)
public slots: public slots:
@@ -122,7 +120,7 @@ signals:
void loggingDisableByWatcher(); void loggingDisableByWatcher();
void appLanguageChanged(const LanguageSettings::AvailableLanguageEnum language); void appLanguageChanged();
void resetLanguageToSystem(); void resetLanguageToSystem();
void onNotificationStateChanged(); void onNotificationStateChanged();
@@ -135,12 +133,12 @@ signals:
void activityResumed(); void activityResumed();
void isHomeAdLabelVisibleChanged(bool visible); void isHomeAdLabelVisibleChanged(bool visible);
void autoStartChanged();
void startMinimizedChanged(); void startMinimizedChanged();
private: private:
SettingsController* m_settingsController; SettingsController* m_settingsController;
ServersController* m_serversController; ServersController* m_serversController;
LanguageUiController* m_languageUiController;
}; };
#endif #endif
+1 -1
View File
@@ -30,7 +30,7 @@ QVariant ApiAccountInfoModel::data(const QModelIndex &index, int role) const
switch (role) { switch (role) {
case SubscriptionStatusRole: { case SubscriptionStatusRole: {
if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) { if (m_accountInfoData.configType == serverConfigUtils::ConfigType::AmneziaFreeV3) {
return tr("Active"); return QStringLiteral("<p><a style=\"color: #28c840;\">%1</a>").arg(tr("Active"));
} }
return apiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate) return apiUtils::isSubscriptionExpired(m_accountInfoData.subscriptionEndDate)
@@ -27,6 +27,7 @@ QVariant ClientManagementModel::data(const QModelIndex &index, int role) const
auto userData = client.value(configKey::userData).toObject(); auto userData = client.value(configKey::userData).toObject();
switch (role) { switch (role) {
case ClientIdRole: return client.value(configKey::clientId).toString();
case ClientNameRole: return userData.value(configKey::clientName).toString(); case ClientNameRole: return userData.value(configKey::clientName).toString();
case CreationDateRole: return userData.value(configKey::creationDate).toString(); case CreationDateRole: return userData.value(configKey::creationDate).toString();
case LatestHandshakeRole: return userData.value(configKey::latestHandshake).toString(); case LatestHandshakeRole: return userData.value(configKey::latestHandshake).toString();
@@ -62,6 +63,7 @@ void ClientManagementModel::updateClientName(int row, const QString &newName)
QHash<int, QByteArray> ClientManagementModel::roleNames() const QHash<int, QByteArray> ClientManagementModel::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
roles[ClientIdRole] = "clientId";
roles[ClientNameRole] = "clientName"; roles[ClientNameRole] = "clientName";
roles[CreationDateRole] = "creationDate"; roles[CreationDateRole] = "creationDate";
roles[LatestHandshakeRole] = "latestHandshake"; roles[LatestHandshakeRole] = "latestHandshake";
+2 -1
View File
@@ -10,7 +10,8 @@ class ClientManagementModel : public QAbstractListModel
public: public:
enum Roles { enum Roles {
ClientNameRole = Qt::UserRole + 1, ClientIdRole = Qt::UserRole + 1,
ClientNameRole,
CreationDateRole, CreationDateRole,
LatestHandshakeRole, LatestHandshakeRole,
DataReceivedRole, DataReceivedRole,
+4
View File
@@ -23,6 +23,10 @@ public:
Q_INVOKABLE int containerFromString(const QString &container) const { Q_INVOKABLE int containerFromString(const QString &container) const {
return static_cast<int>(amnezia::ContainerUtils::containerFromString(container)); return static_cast<int>(amnezia::ContainerUtils::containerFromString(container));
} }
Q_INVOKABLE bool isUnsupportedContainer(int containerIndex) const {
return amnezia::ContainerUtils::isUnsupportedContainer(static_cast<amnezia::DockerContainer>(containerIndex));
}
}; };
#endif // CONTAINERPROPS_H #endif // CONTAINERPROPS_H
+4 -1
View File
@@ -67,6 +67,7 @@ QVariant ContainersModel::data(const QModelIndex &index, int role) const
case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex); case IsCurrentlyProcessedRole: return container == static_cast<DockerContainer>(m_processedContainerIndex);
case IsSupportedRole: return ContainerUtils::isSupportedByCurrentPlatform(container); case IsSupportedRole: return ContainerUtils::isSupportedByCurrentPlatform(container);
case IsShareableRole: return ContainerUtils::isShareable(container); case IsShareableRole: return ContainerUtils::isShareable(container);
case IsUnsupportedContainerRole: return ContainerUtils::isUnsupportedContainer(container);
case IsVpnContainerRole: return ContainerUtils::containerService(container) == ServiceType::Vpn; case IsVpnContainerRole: return ContainerUtils::containerService(container) == ServiceType::Vpn;
case IsServiceContainerRole: return ContainerUtils::containerService(container) == ServiceType::Other; case IsServiceContainerRole: return ContainerUtils::containerService(container) == ServiceType::Other;
case IsIpsecRole: return container == DockerContainer::Ipsec; case IsIpsecRole: return container == DockerContainer::Ipsec;
@@ -142,7 +143,8 @@ bool ContainersModel::hasInstalledProtocols()
bool ContainersModel::isInstallationAllowed(DockerContainer container) bool ContainersModel::isInstallationAllowed(DockerContainer container)
{ {
return container != DockerContainer::Awg; return container != DockerContainer::Awg
&& !ContainerUtils::isUnsupportedContainer(container);
} }
void ContainersModel::openContainerSettings(int containerIndex) void ContainersModel::openContainerSettings(int containerIndex)
@@ -176,6 +178,7 @@ QHash<int, QByteArray> ContainersModel::roleNames() const
roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed"; roles[IsCurrentlyProcessedRole] = "isCurrentlyProcessed";
roles[IsSupportedRole] = "isSupported"; roles[IsSupportedRole] = "isSupported";
roles[IsShareableRole] = "isShareable"; roles[IsShareableRole] = "isShareable";
roles[IsUnsupportedContainerRole] = "isUnsupportedContainer";
roles[IsInstallationAllowedRole] = "isInstallationAllowed"; roles[IsInstallationAllowedRole] = "isInstallationAllowed";
roles[InstallPageOrderRole] = "installPageOrder"; roles[InstallPageOrderRole] = "installPageOrder";
+2
View File
@@ -39,6 +39,8 @@ public:
IsSupportedRole, IsSupportedRole,
IsShareableRole, IsShareableRole,
IsUnsupportedContainerRole,
InstallPageOrderRole, InstallPageOrderRole,
// Container type check roles // Container type check roles
@@ -56,14 +56,17 @@ ListViewType {
return return
} }
if (checked) { var containerIndex = proxyDefaultServerContainersModel.mapToSource(index)
containersDropDown.closeTriggered()
ServersUiController.setDefaultContainer(ServersUiController.defaultServerId, proxyDefaultServerContainersModel.mapToSource(index)) if (!isInstalled) {
} else { ServersUiController.processedContainerIndex = containerIndex
ServersUiController.processedContainerIndex = proxyDefaultServerContainersModel.mapToSource(index)
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings) PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
containersDropDown.closeTriggered() containersDropDown.closeTriggered()
return
} }
containersDropDown.closeTriggered()
ServersUiController.setDefaultContainer(ServersUiController.defaultServerId, containerIndex)
} }
MouseArea { MouseArea {
@@ -5,7 +5,6 @@ import QtQuick.Layouts
import SortFilterProxyModel 0.2 import SortFilterProxyModel 0.2
import PageEnum 1.0 import PageEnum 1.0
import ContainerProps 1.0
import "../Controls2" import "../Controls2"
import "../Controls2/TextTypes" import "../Controls2/TextTypes"
+30 -9
View File
@@ -6,8 +6,36 @@ Menu {
popupType: Popup.Native popupType: Popup.Native
onAboutToShow: blocker.enabled = true property Item inputBlocker: null
onClosed: blocker.enabled = false
Component {
id: inputBlockerComponent
MouseArea {
anchors.fill: parent
preventStealing: true
}
}
onAboutToShow: {
if (!textObj || !textObj.window) {
return
}
const contentItem = textObj.window.contentItem
if (!inputBlocker) {
inputBlocker = inputBlockerComponent.createObject(contentItem)
} else {
inputBlocker.parent = contentItem
}
}
onClosed: {
if (inputBlocker) {
inputBlocker.destroy()
inputBlocker = null
}
}
MenuItem { MenuItem {
text: qsTr("C&ut") text: qsTr("C&ut")
@@ -31,11 +59,4 @@ Menu {
enabled: textObj.length > 0 enabled: textObj.length > 0
onTriggered: textObj.selectAll() onTriggered: textObj.selectAll()
} }
MouseArea {
id: blocker
z: 2
enabled: false
preventStealing: true
}
} }
+2 -2
View File
@@ -25,8 +25,8 @@ PageType {
filters: [ filters: [
ValueFilter { ValueFilter {
roleName: "isCurrentlyProcessed" roleName: "serverId"
value: true value: ServersUiController.processedServerId
} }
] ]
} }
@@ -440,8 +440,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); InstallController.updateClientConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
} }
var noButtonFunction = function() {} var noButtonFunction = function() {}
@@ -561,7 +561,7 @@ PageType {
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Awg)
} }
var noButtonFunction = function() {} var noButtonFunction = function() {}
@@ -434,7 +434,7 @@ PageType {
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.OpenVpn)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
if (!GC.isMobile()) { if (!GC.isMobile()) {
@@ -128,8 +128,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); InstallController.updateClientConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
} }
var noButtonFunction = function() {} var noButtonFunction = function() {}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
@@ -129,7 +129,7 @@ PageType {
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.WireGuard)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
if (!GC.isMobile()) { if (!GC.isMobile()) {
@@ -112,7 +112,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -279,7 +279,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -213,7 +213,7 @@ PageType {
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling); PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
if (!GC.isMobile()) saveButton.forceActiveFocus() if (!GC.isMobile()) saveButton.forceActiveFocus()
@@ -742,7 +742,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -95,7 +95,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -211,7 +211,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -208,7 +208,7 @@ PageType {
return return
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Xray)
} }
var noButtonFunction = function () { var noButtonFunction = function () {
if (typeof GC !== "undefined" && !GC.isMobile()) { if (typeof GC !== "undefined" && !GC.isMobile()) {
@@ -179,7 +179,7 @@ PageType {
function mtProxyScheduleUpdate(closePage) { function mtProxyScheduleUpdate(closePage) {
var cp = closePage === undefined ? false : closePage var cp = closePage === undefined ? false : closePage
Qt.callLater(function () { Qt.callLater(function () {
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.MtProxy, cp) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.MtProxy, cp)
}) })
} }
@@ -285,7 +285,7 @@ PageType {
} }
PageController.goToPage(PageEnum.PageSetupWizardInstalling) PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Socks5Proxy) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Socks5Proxy)
tempPort = portTextField.textField.text tempPort = portTextField.textField.text
tempUsername = usernameTextField.textField.text tempUsername = usernameTextField.textField.text
tempPassword = passwordTextField.textField.text tempPassword = passwordTextField.textField.text
@@ -154,7 +154,7 @@ PageType {
function telemtScheduleUpdate(closePage) { function telemtScheduleUpdate(closePage) {
var cp = closePage === undefined ? false : closePage var cp = closePage === undefined ? false : closePage
Qt.callLater(function () { Qt.callLater(function () {
InstallController.updateContainer(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Telemt, cp) InstallController.updateServerConfig(ServersUiController.processedServerId, ServersUiController.processedContainerIndex, ProtocolEnum.Telemt, cp)
}) })
} }
@@ -100,6 +100,12 @@ PageType {
onLinkActivated: Qt.openUrlExternally(link) onLinkActivated: Qt.openUrlExternally(link)
textFormat: Text.RichText textFormat: Text.RichText
text: qsTr("Use <a href=\"https://www.torproject.org/download/\" style=\"color: #FBB26A;\">Tor Browser</a> to open this URL.") text: qsTr("Use <a href=\"https://www.torproject.org/download/\" style=\"color: #FBB26A;\">Tor Browser</a> to open this URL.")
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
cursorShape: parent.hoveredLink ? Qt.PointingHandCursor : Qt.ArrowCursor
}
} }
ParagraphTextType { ParagraphTextType {
@@ -30,6 +30,16 @@ PageType {
root.isInAppPurchase = ApiAccountInfoModel.data("isInAppPurchase") root.isInAppPurchase = ApiAccountInfoModel.data("isInAppPurchase")
} }
function selectConnectionCountry(countryIndex, countryCode, countryName) {
if (countryIndex === ApiCountryModel.currentIndex) {
return
}
PageController.showBusyIndicator(true)
SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, countryCode, countryName)
PageController.showBusyIndicator(false)
}
Component.onCompleted: { Component.onCompleted: {
root.updateSubscriptionState() root.updateSubscriptionState()
} }
@@ -83,7 +93,7 @@ PageType {
model: ApiCountryModel model: ApiCountryModel
currentIndex: 0 currentIndex: ApiCountryModel.currentIndex
ButtonGroup { ButtonGroup {
id: containersRadioButtonGroup id: containersRadioButtonGroup
@@ -204,15 +214,7 @@ PageType {
return return
} }
if (index !== ApiCountryModel.currentIndex) { root.selectConnectionCountry(index, countryCode, countryName)
PageController.showBusyIndicator(true)
var prevIndex = ApiCountryModel.currentIndex
ApiCountryModel.currentIndex = index
if (!SubscriptionUiController.updateServiceFromGateway(ServersUiController.processedServerId, countryCode, countryName)) {
ApiCountryModel.currentIndex = prevIndex
}
PageController.showBusyIndicator(false)
}
} }
Keys.onEnterPressed: { Keys.onEnterPressed: {
@@ -108,9 +108,9 @@ PageType {
text: qsTr("Auto start") text: qsTr("Auto start")
descriptionText: qsTr("Launch the application every time the device is starts") descriptionText: qsTr("Launch the application every time the device is starts")
checked: SettingsController.isAutoStartEnabled() checked: SettingsController.autoStartEnabled
onToggled: function() { onToggled: function() {
if (checked !== SettingsController.isAutoStartEnabled()) { if (checked !== SettingsController.autoStartEnabled) {
SettingsController.toggleAutoStart(checked) SettingsController.toggleAutoStart(checked)
} }
} }
@@ -154,10 +154,10 @@ PageType {
text: qsTr("Start minimized") text: qsTr("Start minimized")
descriptionText: qsTr("Launch application minimized (works with autostart option turned on)") descriptionText: qsTr("Launch application minimized (works with autostart option turned on)")
enabled: SettingsController.isAutoStartEnabled() enabled: SettingsController.autoStartEnabled
opacity: enabled ? 1.0 : 0.5 opacity: enabled ? 1.0 : 0.5
checked: SettingsController.isAutoStartEnabled() && SettingsController.startMinimized checked: SettingsController.autoStartEnabled && SettingsController.startMinimized
onToggled: function() { onToggled: function() {
if (checked !== SettingsController.startMinimized) { if (checked !== SettingsController.startMinimized) {
SettingsController.toggleStartMinimized(checked) SettingsController.toggleStartMinimized(checked)
@@ -166,7 +166,7 @@ PageType {
} }
DividerType { DividerType {
visible: !GC.isMobile() visible: !GC.isMobile() && ServersUiController.hasServersFromGatewayApi
} }
SwitcherType { SwitcherType {
@@ -36,17 +36,6 @@ PageType {
function onRebootServerFinished(finishedMessage) { function onRebootServerFinished(finishedMessage) {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
function onRemoveAllContainersFinished(finishedMessage) {
PageController.closePage() // close deInstalling page
PageController.showNotificationMessage(finishedMessage)
}
function onRemoveContainerFinished(finishedMessage) {
PageController.closePage() // close deInstalling page
PageController.closePage() // close page with remove button
PageController.showNotificationMessage(finishedMessage)
}
} }
Connections { Connections {
@@ -17,7 +17,8 @@ import "../Components"
PageType { PageType {
id: root id: root
property bool isClearCacheVisible: ServersUiController.isProcessedServerHasWriteAccess() && !ContainersModel.isServiceContainer(ServersUiController.processedContainerIndex) property bool isUnsupportedContainer: ContainerProps.isUnsupportedContainer(ServersUiController.processedContainerIndex)
property bool isClearCacheVisible: !isUnsupportedContainer && ServersUiController.isProcessedServerHasWriteAccess() && !ContainersModel.isServiceContainer(ServersUiController.processedContainerIndex)
BackButtonType { BackButtonType {
id: backButton id: backButton
@@ -52,10 +53,11 @@ PageType {
Layout.bottomMargin: 32 Layout.bottomMargin: 32
headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings") headerText: ContainersModel.getProcessedContainerName() + qsTr(" settings")
descriptionText: root.isUnsupportedContainer ? qsTr("This protocol is no longer supported.") : ""
} }
} }
model: ProtocolsModel model: root.isUnsupportedContainer ? null : ProtocolsModel
delegate: ColumnLayout { delegate: ColumnLayout {
id: delegateContent id: delegateContent
@@ -29,6 +29,10 @@ PageType {
ValueFilter { ValueFilter {
roleName: "isInstallationAllowed" roleName: "isInstallationAllowed"
value: true value: true
},
ValueFilter {
roleName: "isUnsupportedContainer"
value: false
} }
] ]
sorters: RoleSorter { sorters: RoleSorter {
+20 -7
View File
@@ -382,6 +382,10 @@ PageType {
ValueFilter { ValueFilter {
roleName: "isShareable" roleName: "isShareable"
value: true value: true
},
ValueFilter {
roleName: "isUnsupportedContainer"
value: false
} }
] ]
} }
@@ -396,9 +400,19 @@ PageType {
target: serverSelector target: serverSelector
function onServerSelectorIndexChanged() { function onServerSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersUiController.serverDefaultContainer(ServersUiController.processedServerId)) if (!proxyContainersModel.count) {
root.shareButtonEnabled = false
return
}
var defaultContainer = proxyContainersModel.mapFromSource(
ServersUiController.serverDefaultContainer(ServersUiController.processedServerId))
if (defaultContainer < 0) {
defaultContainer = 0
}
containerSelectorListView.selectedIndex = defaultContainer containerSelectorListView.selectedIndex = defaultContainer
containerSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning) containerSelectorListView.positionViewAtIndex(defaultContainer, ListView.Beginning)
containerSelectorListView.triggerCurrentItem() containerSelectorListView.triggerCurrentItem()
} }
} }
@@ -837,11 +851,10 @@ PageType {
var noButtonFunction = function() { var noButtonFunction = function() {
} }
var isActiveConfigForCurrentClient = ServersUiController.isDefaultServerCurrentlyProcessed() if (ConnectionController.isRevokeBlockedDuringActiveConnection(
&& ServersUiController.serverDefaultContainer(ServersUiController.defaultServerId) === ServersUiController.processedContainerIndex ServersUiController.processedServerId,
ServersUiController.processedContainerIndex,
if ((ConnectionController.isConnectionInProgress || ConnectionController.isConnected) clientId)) {
&& isActiveConfigForCurrentClient) {
PageController.showNotificationMessage("Unable to revoke current config during active connection") PageController.showNotificationMessage("Unable to revoke current config during active connection")
} else { } else {
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction) showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+25 -4
View File
@@ -105,6 +105,19 @@ PageType {
} }
} }
Connections {
objectName: "connectionControllerConnections"
target: ConnectionController
function onNoInstalledContainers() {
PageController.setTriggeredByConnectButton(true)
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId)
PageController.goToPage(PageEnum.PageSetupWizardEasy)
}
}
Connections { Connections {
objectName: "installControllerConnections" objectName: "installControllerConnections"
@@ -153,11 +166,19 @@ PageType {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
function onNoInstalledContainers() { function onRemoveAllContainersFinished(finishedMessage) {
PageController.setTriggeredByConnectButton(true) if (tabBarStackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageDeinstalling)) {
PageController.closePage()
}
PageController.showNotificationMessage(finishedMessage)
}
ServersUiController.setProcessedServerId(ServersUiController.defaultServerId) function onRemoveContainerFinished(finishedMessage) {
PageController.goToPage(PageEnum.PageSetupWizardEasy) if (tabBarStackView.currentItem.objectName === PageController.getPagePath(PageEnum.PageDeinstalling)) {
PageController.closePage()
}
PageController.closePage()
PageController.showNotificationMessage(finishedMessage)
} }
} }
+8
View File
@@ -234,6 +234,8 @@ Window {
DrawerType2 { DrawerType2 {
id: privateKeyPassphraseDrawer id: privateKeyPassphraseDrawer
property bool isCloseByUser: false
anchors.fill: parent anchors.fill: parent
expandedHeight: root.height * 0.35 + PageController.safeAreaBottomMargin + PageController.imeHeight expandedHeight: root.height * 0.35 + PageController.safeAreaBottomMargin + PageController.imeHeight
@@ -253,6 +255,11 @@ Window {
} }
function onAboutToHide() { function onAboutToHide() {
if (privateKeyPassphraseDrawer.isCloseByUser === false) {
privateKeyPassphraseDrawer.isCloseByUser = true
PageController.passphraseRequestDrawerClosed("")
}
if (passphrase.textField.text !== "") { if (passphrase.textField.text !== "") {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
} }
@@ -293,6 +300,7 @@ Window {
text: qsTr("Save") text: qsTr("Save")
clickedFunc: function() { clickedFunc: function() {
privateKeyPassphraseDrawer.isCloseByUser = true
privateKeyPassphraseDrawer.closeTriggered() privateKeyPassphraseDrawer.closeTriggered()
PageController.passphraseRequestDrawerClosed(passphrase.textField.text) PageController.passphraseRequestDrawerClosed(passphrase.textField.text)
} }