diff --git a/.clang-format b/.clang-format
new file mode 100644
index 00000000..5c459fd2
--- /dev/null
+++ b/.clang-format
@@ -0,0 +1,39 @@
+BasedOnStyle: WebKit
+AccessModifierOffset: '-4'
+AlignAfterOpenBracket: Align
+AlignConsecutiveMacros: 'true'
+AlignTrailingComments: 'true'
+AllowAllArgumentsOnNextLine: 'true'
+AllowAllParametersOfDeclarationOnNextLine: 'true'
+AllowShortBlocksOnASingleLine: 'false'
+AllowShortCaseLabelsOnASingleLine: 'true'
+AllowShortEnumsOnASingleLine: 'false'
+AllowShortFunctionsOnASingleLine: None
+AlwaysBreakTemplateDeclarations: 'No'
+BreakBeforeBinaryOperators: NonAssignment
+BreakBeforeBraces: Custom
+BraceWrapping:
+ AfterClass: true
+ AfterControlStatement: false
+ AfterEnum: false
+ AfterFunction: true
+ AfterNamespace: true
+ AfterObjCDeclaration: false
+ AfterStruct: true
+ AfterUnion: false
+ BeforeCatch: false
+ BeforeElse: false
+ IndentBraces: false
+BreakConstructorInitializers: BeforeColon
+ColumnLimit: '120'
+CommentPragmas: '"^!|^:"'
+ConstructorInitializerAllOnOneLineOrOnePerLine: 'true'
+ConstructorInitializerIndentWidth: '4'
+ContinuationIndentWidth: '8'
+IndentPPDirectives: BeforeHash
+NamespaceIndentation: All
+PenaltyExcessCharacter: '10'
+PointerAlignment: Right
+SortIncludes: 'true'
+SpaceAfterTemplateKeyword: 'false'
+Standard: Auto
diff --git a/.clang-format-ignore b/.clang-format-ignore
new file mode 100644
index 00000000..4019357f
--- /dev/null
+++ b/.clang-format-ignore
@@ -0,0 +1,20 @@
+/client/3rd
+/client/3rd-prebuild
+/client/android
+/client/cmake
+/client/core/serialization
+/client/daemon
+/client/fonts
+/client/images
+/client/ios
+/client/mozilla
+/client/platforms/dummy
+/client/platforms/linux
+/client/platforms/macos
+/client/platforms/windows
+/client/server_scripts
+/client/translations
+/deploy
+/docs
+/metadata
+/service/src
diff --git a/README.md b/README.md
index 8b453907..8f887808 100644
--- a/README.md
+++ b/README.md
@@ -1,9 +1,14 @@
# Amnezia VPN
-## _The best client for self-hosted VPN_
+
+### _The best client for self-hosted VPN_
+
[](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml?query=branch:dev)
[](https://gitpod.io/#https://github.com/amnezia-vpn/amnezia-client)
+### [English]([https://github.com/amnezia-vpn/amnezia-client/blob/dev/README_RU.md](https://github.com/amnezia-vpn/amnezia-client/tree/dev?tab=readme-ov-file#)) | [Русский](https://github.com/amnezia-vpn/amnezia-client/blob/dev/README_RU.md)
+
+
[Amnezia](https://amnezia.org) is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
[](https://amnezia.org)
diff --git a/README_RU.md b/README_RU.md
new file mode 100644
index 00000000..fe9dd286
--- /dev/null
+++ b/README_RU.md
@@ -0,0 +1,75 @@
+# Amnezia VPN
+
+### _Лучший клиент для создания VPN на собственном сервере_
+
+[](https://github.com/amnezia-vpn/amnezia-client/actions/workflows/deploy.yml?query=branch:dev)
+[](https://gitpod.io/#https://github.com/amnezia-vpn/amnezia-client)
+
+### [English](https://github.com/amnezia-vpn/amnezia-client/blob/dev/README.md) | Русский
+[AmneziaVPN](https://amnezia.org) — это open sourse VPN-клиент, ключевая особенность которого заключается в возможности развернуть собственный VPN на вашем сервере.
+
+[](https://amnezia.org)
+
+### [Сайт](https://amnezia.org) | [Зеркало на сайт](https://storage.googleapis.com/kldscp/amnezia.org) | [Документация](https://docs.amnezia.org) | [Решение проблем](https://docs.amnezia.org/troubleshooting)
+
+> [!TIP]
+> Если [сайт Amnezia](https://amnezia.org) заблокирован в вашем регионе, вы можете воспользоваться [ссылкой на зеркало](https://storage.googleapis.com/kldscp/amnezia.org).
+
+
+
+
+[Все релизы](https://github.com/amnezia-vpn/amnezia-client/releases)
+
+
+
+
+
+## Особенности
+
+- Простой в использовании — введите IP-адрес, SSH-логин и пароль, и Amnezia автоматически установит VPN-контейнеры Docker на ваш сервер и подключится к VPN.
+- Классические VPN-протоколы: OpenVPN, WireGuard и IKEv2.
+- Протоколы с маскировкой трафика (обфускацией): OpenVPN с плагином [Cloak](https://github.com/cbeuw/Cloak), Shadowsocks (OpenVPN over Shadowsocks), [AmneziaWG](https://docs.amnezia.org/documentation/amnezia-wg/) and XRay.
+- Поддержка Split Tunneling — добавляйте любые сайты или приложения в список, чтобы включить VPN только для них.
+- Поддерживает платформы: Windows, MacOS, Linux, Android, iOS.
+- Поддержка конфигурации протокола AmneziaWG на [бета-прошивке Keenetic](https://docs.keenetic.com/ua/air/kn-1611/en/6319-latest-development-release.html#UUID-186c4108-5afd-c10b-f38a-cdff6c17fab3_section-idm33192196168192-improved).
+
+## Ссылки
+
+- [https://amnezia.org](https://amnezia.org) - Веб-сайт проекта | [Альтернативная ссылка (зеркало)](https://storage.googleapis.com/kldscp/amnezia.org)
+- [https://docs.amnezia.org](https://docs.amnezia.org) - Документация
+- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
+- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Канал поддржки в Telegram (Английский)
+- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Канал поддржки в Telegram (Фарси)
+- [https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Канал поддржки в Telegram (Мьянма)
+- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Канал поддржки в Telegram (Русский)
+- [https://vpnpay.io/en/amnezia-premium/](https://vpnpay.io/en/amnezia-premium/) - Amnezia Premium | [Зеркало](https://storage.googleapis.com/kldscp/vpnpay.io/ru/amnezia-premium\)
+
+## Технологии
+
+AmneziaVPN использует несколько проектов с открытым исходным кодом:
+
+- [OpenSSL](https://www.openssl.org/)
+- [OpenVPN](https://openvpn.net/)
+- [Shadowsocks](https://shadowsocks.org/)
+- [Qt](https://www.qt.io/)
+- [LibSsh](https://libssh.org)
+- и другие...
+
+## Лицензия
+
+GPL v3.0
+
+## Донаты
+
+Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
+
+Bitcoin: bc1q26eevjcg9j0wuyywd2e3uc9cs2w58lpkpjxq6p
+USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4
+USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d
+XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
+TON: UQDpU1CyKRmg7L8mNScKk9FRc2SlESuI7N-Hby4nX-CcVmns
+
+## Благодарности
+
+Этот проект тестируется с помощью BrowserStack.
+Мы выражаем благодарность [BrowserStack](https://www.browserstack.com) за поддержку нашего проекта.
diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp
index 24dc531a..6e84563e 100644
--- a/client/amnezia_application.cpp
+++ b/client/amnezia_application.cpp
@@ -69,7 +69,7 @@ void AmneziaApplication::init()
{
m_engine = new QQmlApplicationEngine;
- const QUrl url(QStringLiteral("qrc:/ui/qml/main2.qml"));
+ const QUrl url(QStringLiteral("qrc:/ui/qml/DefaultVpn/main.qml"));
QObject::connect(
m_engine, &QQmlApplicationEngine::objectCreated, this,
[url](QObject *obj, const QUrl &objUrl) {
@@ -154,7 +154,7 @@ void AmneziaApplication::init()
connect(this, &AmneziaApplication::translationsUpdated, m_notificationHandler.get(), &NotificationHandler::onTranslationsUpdated);
#endif
- m_engine->addImportPath("qrc:/ui/qml/Modules/");
+ m_engine->addImportPath("qrc:/ui/qml/DefaultVpn");
m_engine->load(url);
m_systemController->setQmlRoot(m_engine->rootObjects().value(0));
@@ -228,7 +228,7 @@ void AmneziaApplication::loadFonts()
{
QQuickStyle::setStyle("Basic");
- QFontDatabase::addApplicationFont(":/fonts/pt-root-ui_vf.ttf");
+ QFontDatabase::addApplicationFont(":/fonts/VelaSans-GX.ttf");
}
void AmneziaApplication::loadTranslator()
diff --git a/client/configurators/xray_configurator.cpp b/client/configurators/xray_configurator.cpp
index 786da47c..514aa821 100644
--- a/client/configurators/xray_configurator.cpp
+++ b/client/configurators/xray_configurator.cpp
@@ -3,38 +3,169 @@
#include
#include
#include
+#include
+#include "logger.h"
#include "containers/containers_defs.h"
#include "core/controllers/serverController.h"
#include "core/scripts_registry.h"
+namespace {
+Logger logger("XrayConfigurator");
+}
+
XrayConfigurator::XrayConfigurator(std::shared_ptr settings, const QSharedPointer &serverController, QObject *parent)
: ConfiguratorBase(settings, serverController, parent)
{
}
-QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
- ErrorCode &errorCode)
+QString XrayConfigurator::prepareServerConfig(const ServerCredentials &credentials, DockerContainer container,
+ const QJsonObject &containerConfig, ErrorCode &errorCode)
{
- QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
- m_serverController->genVarsForScript(credentials, container, containerConfig));
-
- QString xrayPublicKey =
- m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
- xrayPublicKey.replace("\n", "");
-
- QString xrayUuid = m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::uuidPath, errorCode);
- xrayUuid.replace("\n", "");
-
- QString xrayShortId =
- m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
- xrayShortId.replace("\n", "");
-
+ // Generate new UUID for client
+ QString clientId = QUuid::createUuid().toString(QUuid::WithoutBraces);
+
+ // Get current server config
+ QString currentConfig = m_serverController->getTextFileFromContainer(
+ container, credentials, amnezia::protocols::xray::serverConfigPath, errorCode);
+
if (errorCode != ErrorCode::NoError) {
+ logger.error() << "Failed to get server config file";
return "";
}
- config.replace("$XRAY_CLIENT_ID", xrayUuid);
+ // Parse current config as JSON
+ QJsonDocument doc = QJsonDocument::fromJson(currentConfig.toUtf8());
+ if (doc.isNull() || !doc.isObject()) {
+ logger.error() << "Failed to parse server config JSON";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QJsonObject serverConfig = doc.object();
+
+ // Validate server config structure
+ if (!serverConfig.contains("inbounds")) {
+ logger.error() << "Server config missing 'inbounds' field";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QJsonArray inbounds = serverConfig["inbounds"].toArray();
+ if (inbounds.isEmpty()) {
+ logger.error() << "Server config has empty 'inbounds' array";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QJsonObject inbound = inbounds[0].toObject();
+ if (!inbound.contains("settings")) {
+ logger.error() << "Inbound missing 'settings' field";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QJsonObject settings = inbound["settings"].toObject();
+ if (!settings.contains("clients")) {
+ logger.error() << "Settings missing 'clients' field";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QJsonArray clients = settings["clients"].toArray();
+
+ // Create configuration for new client
+ QJsonObject clientConfig {
+ {"id", clientId},
+ {"flow", "xtls-rprx-vision"}
+ };
+
+ clients.append(clientConfig);
+
+ // Update config
+ settings["clients"] = clients;
+ inbound["settings"] = settings;
+ inbounds[0] = inbound;
+ serverConfig["inbounds"] = inbounds;
+
+ // Save updated config to server
+ QString updatedConfig = QJsonDocument(serverConfig).toJson();
+ errorCode = m_serverController->uploadTextFileToContainer(
+ container,
+ credentials,
+ updatedConfig,
+ amnezia::protocols::xray::serverConfigPath,
+ libssh::ScpOverwriteMode::ScpOverwriteExisting
+ );
+ if (errorCode != ErrorCode::NoError) {
+ logger.error() << "Failed to upload updated config";
+ return "";
+ }
+
+ // Restart container
+ QString restartScript = QString("sudo docker restart $CONTAINER_NAME");
+ errorCode = m_serverController->runScript(
+ credentials,
+ m_serverController->replaceVars(restartScript, m_serverController->genVarsForScript(credentials, container))
+ );
+
+ if (errorCode != ErrorCode::NoError) {
+ logger.error() << "Failed to restart container";
+ return "";
+ }
+
+ return clientId;
+}
+
+QString XrayConfigurator::createConfig(const ServerCredentials &credentials, DockerContainer container,
+ const QJsonObject &containerConfig, ErrorCode &errorCode)
+{
+ // Get client ID from prepareServerConfig
+ QString xrayClientId = prepareServerConfig(credentials, container, containerConfig, errorCode);
+ if (errorCode != ErrorCode::NoError || xrayClientId.isEmpty()) {
+ logger.error() << "Failed to prepare server config";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QString config = m_serverController->replaceVars(amnezia::scriptData(ProtocolScriptType::xray_template, container),
+ m_serverController->genVarsForScript(credentials, container, containerConfig));
+
+ if (config.isEmpty()) {
+ logger.error() << "Failed to get config template";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ QString xrayPublicKey =
+ m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::PublicKeyPath, errorCode);
+ if (errorCode != ErrorCode::NoError || xrayPublicKey.isEmpty()) {
+ logger.error() << "Failed to get public key";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+ xrayPublicKey.replace("\n", "");
+
+ QString xrayShortId =
+ m_serverController->getTextFileFromContainer(container, credentials, amnezia::protocols::xray::shortidPath, errorCode);
+ if (errorCode != ErrorCode::NoError || xrayShortId.isEmpty()) {
+ logger.error() << "Failed to get short ID";
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+ xrayShortId.replace("\n", "");
+
+ // Validate all required variables are present
+ if (!config.contains("$XRAY_CLIENT_ID") || !config.contains("$XRAY_PUBLIC_KEY") || !config.contains("$XRAY_SHORT_ID")) {
+ logger.error() << "Config template missing required variables:"
+ << "XRAY_CLIENT_ID:" << !config.contains("$XRAY_CLIENT_ID")
+ << "XRAY_PUBLIC_KEY:" << !config.contains("$XRAY_PUBLIC_KEY")
+ << "XRAY_SHORT_ID:" << !config.contains("$XRAY_SHORT_ID");
+ errorCode = ErrorCode::InternalError;
+ return "";
+ }
+
+ config.replace("$XRAY_CLIENT_ID", xrayClientId);
config.replace("$XRAY_PUBLIC_KEY", xrayPublicKey);
config.replace("$XRAY_SHORT_ID", xrayShortId);
diff --git a/client/configurators/xray_configurator.h b/client/configurators/xray_configurator.h
index 2acfdf71..8ed4e775 100644
--- a/client/configurators/xray_configurator.h
+++ b/client/configurators/xray_configurator.h
@@ -14,6 +14,10 @@ public:
QString createConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
ErrorCode &errorCode);
+
+private:
+ QString prepareServerConfig(const ServerCredentials &credentials, DockerContainer container, const QJsonObject &containerConfig,
+ ErrorCode &errorCode);
};
#endif // XRAY_CONFIGURATOR_H
diff --git a/client/core/controllers/apiController.cpp b/client/core/controllers/apiController.cpp
index c50165e7..6562632a 100644
--- a/client/core/controllers/apiController.cpp
+++ b/client/core/controllers/apiController.cpp
@@ -379,6 +379,13 @@ ErrorCode ApiController::getServicesList(QByteArray &responseBody)
auto errorCode = checkErrors(sslErrors, reply);
reply->deleteLater();
+
+ if (errorCode == ErrorCode::NoError) {
+ if (!responseBody.contains("services")) {
+ return ErrorCode::ApiServicesMissingError;
+ }
+ }
+
return errorCode;
}
diff --git a/client/core/defs.h b/client/core/defs.h
index d00d347b..c0db2e12 100644
--- a/client/core/defs.h
+++ b/client/core/defs.h
@@ -109,6 +109,7 @@ namespace amnezia
ApiConfigSslError = 1104,
ApiMissingAgwPublicKey = 1105,
ApiConfigDecryptionError = 1106,
+ ApiServicesMissingError = 1107,
// QFile errors
OpenError = 1200,
diff --git a/client/core/errorstrings.cpp b/client/core/errorstrings.cpp
index 49534606..70f433c6 100644
--- a/client/core/errorstrings.cpp
+++ b/client/core/errorstrings.cpp
@@ -63,7 +63,8 @@ QString errorString(ErrorCode code) {
case (ErrorCode::ApiConfigTimeoutError): errorMessage = QObject::tr("Server response timeout on api request"); break;
case (ErrorCode::ApiMissingAgwPublicKey): errorMessage = QObject::tr("Missing AGW public key"); break;
case (ErrorCode::ApiConfigDecryptionError): errorMessage = QObject::tr("Failed to decrypt response payload"); break;
-
+ case (ErrorCode::ApiServicesMissingError): errorMessage = QObject::tr("Missing list of available services"); break;
+
// QFile errors
case(ErrorCode::OpenError): errorMessage = QObject::tr("QFile error: The file could not be opened"); break;
case(ErrorCode::ReadError): errorMessage = QObject::tr("QFile error: An error occurred when reading from the file"); break;
diff --git a/client/fonts/VelaSans-GX.ttf b/client/fonts/VelaSans-GX.ttf
new file mode 100644
index 00000000..0a75bb2e
Binary files /dev/null and b/client/fonts/VelaSans-GX.ttf differ
diff --git a/client/images/controls/connect-button.svg b/client/images/controls/connect-button.svg
new file mode 100644
index 00000000..74727c36
--- /dev/null
+++ b/client/images/controls/connect-button.svg
@@ -0,0 +1,4 @@
+
diff --git a/client/resources.qrc b/client/resources.qrc
index a10a784d..e8a3522e 100644
--- a/client/resources.qrc
+++ b/client/resources.qrc
@@ -220,6 +220,28 @@
ui/qml/Pages2/PageSettingsApiLanguageList.qmlimages/controls/archive-restore.svgimages/controls/help-circle.svg
+ ui/qml/DefaultVpn/Controls/DropDownType.qml
+ ui/qml/DefaultVpn/main.qml
+ ui/qml/DefaultVpn/Pages/PageHome.qml
+ ui/qml/DefaultVpn/Controls/TextTypes/MediumTextType.qml
+ ui/qml/DefaultVpn/Config/DeviceInfo.qml
+ ui/qml/DefaultVpn/Config/qmldir
+ ui/qml/DefaultVpn/Controls/TextTypes/XSmallTextType.qml
+ ui/qml/DefaultVpn/Controls/ButtonType.qml
+ ui/qml/DefaultVpn/Pages/PageSettingsServersList.qml
+ ui/qml/DefaultVpn/Controls/TextTypes/Header1TextType.qml
+ ui/qml/DefaultVpn/Controls/TextTypes/Header3TextType.qml
+ ui/qml/DefaultVpn/Config/Style.qml
+ ui/qml/DefaultVpn/Components/WhiteButtonWithBorder.qml
+ ui/qml/DefaultVpn/Components/WhiteButtonNoBorder.qml
+ ui/qml/DefaultVpn/Pages/PageSetupWizardConfigSource.qml
+ ui/qml/DefaultVpn/Components/BlueButtonNoBorder.qml
+ ui/qml/DefaultVpn/Controls/InputType.qml
+ ui/qml/DefaultVpn/Controls/PopupType.qml
+ ui/qml/DefaultVpn/Pages/PageSettingsServerInfo.qml
+ ui/qml/DefaultVpn/Controls/BusyIndicatorType.qml
+ images/controls/connect-button.svg
+ fonts/VelaSans-GX.ttfimages/flagKit/ZW.svg
diff --git a/client/translations/amneziavpn_ar_EG.ts b/client/translations/amneziavpn_ar_EG.ts
index 6d4634c4..df41239d 100644
--- a/client/translations/amneziavpn_ar_EG.ts
+++ b/client/translations/amneziavpn_ar_EG.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/sشبكة VPN كلاسيكية للعمل المريح وتنزيل الملفات الكبيرة ومشاهدة مقاطع الفيديو. تعمل مع أي موقع. تصل السرعة إلى %1 ميجابت/ثانية
-
+ VPN to access blocked sites in regions with high levels of Internet censorship. شبكة VPN للولوج للمواقع المحظورة في بلاد ذو مستوي عالي من الرقابة علي الانترنت.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.Amenzia Premium - شبكة VPN للعمل المريح, تحميل ملفات كبيرة الحجم, ومشاهدة مقاطع الفيديو ب جودة عالية. تعمل لجميع المواقع, حتي في البلاد ذو مستوي عالي من الرقابة علي الانترنت
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorshipAmnezia Free هو VPN مجاني لتخطي الحظر في البلاد ذو مستوي عالي من الرقابة علي الانترنت
-
+ %1 MBit/s%1 ميجابت/ثانية
-
+ %1 days%1 ايام
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>سيقوم VPN فقط بفتح المواقع المشهورة المحظورة في بلدك, مثل Instagram, Facebook, Twitter و مواقع اخري. المواقع الاخري ستٌفتح من عنوان ال IP الحقيقي الخاص بك, <a href="%1/free" style="color: #FBB26A;">معلومات اخري علي الموقع.</a>
-
+ Freeمجاني
-
+ %1 $/month%1 دولار/الشهر
@@ -482,6 +482,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionلا يمكن تغير الخادم بينما هناك اتصال مفعل
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1376,6 +1391,14 @@ Already installed containers were found on the server. All installed containers
سياسات الخصوصية
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1389,64 +1412,69 @@ Already installed containers were found on the server. All installed containers
السعر
-
+ Work periodمدة العمل
-
+
+ Valid until
+
+
+
+ Speedالسرعة
-
+ Support tagعلامة الدعم
-
+ Copiedتم النسخ
-
+ Reload API configإعادة تحميل تكوين API
-
+ Reload API config?إعادة تحميل تكوين API
-
-
+
+ Continueواصل
-
-
+
+ Cancelإلغاء
-
+ Cannot reload API config during active connectionلا يمكن إعادة تحميل تكوين API اثناء تواجد اتصال نشط
-
+ Remove from applicationاحذف من التطبيق
-
+ Remove from application?احذف من التطبيق؟
-
+ Cannot remove server during active connectionلا يمكن إزالة الخادم أثناء الاتصال النشط
@@ -2048,30 +2076,50 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameاسم الخادم
-
+ Saveاحفظ
-
+ Protocolsالبروتوكولات
-
+ Servicesالخدمات
-
+ Managementالإدارة
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2164,6 +2212,11 @@ Already installed containers were found on the server. All installed containers
Serversالخوادم
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2419,6 +2472,31 @@ Already installed containers were found on the server. All installed containers
I have nothingليس لدي اي شئ
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ مفتاح
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3315,7 +3393,7 @@ Already installed containers were found on the server. All installed containers
هذا التكوين بالفعل تمت إضافتة للبرنامج
-
+ ErrorCode: %1.
@@ -3420,37 +3498,42 @@ Already installed containers were found on the server. All installed containers
-
+
+ Missing list of available services
+
+
+
+ QFile error: The file could not be openedخطأ QFile: لا يمكن فتح الملف
-
+ QFile error: An error occurred when reading from the fileخطأ QFile: ظهر خطأ اثناء القراءه من الملف
-
+ QFile error: The file could not be accessedخطأ QFile: لا يمكن الوصول للملف
-
+ QFile error: An unspecified error occurredخطأ QFile: ظهر خطأ غير محدد
-
+ QFile error: A fatal error occurredخطأ QFile: حدث خطأ فادح
-
+ QFile error: The operation was abortedخطأ QFile: تم إحباط العملية
-
+ Internal errorخطأ داخلي
diff --git a/client/translations/amneziavpn_fa_IR.ts b/client/translations/amneziavpn_fa_IR.ts
index 5a65e415..789e52a1 100644
--- a/client/translations/amneziavpn_fa_IR.ts
+++ b/client/translations/amneziavpn_fa_IR.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/sبرای کار راحت، دانلود فایلهای بزرگ و تماشای ویدیوها، از VPN کلاسیک استفاده کنید. این VPN برای هر سایتی کار میکند و سرعت آن تا %1 مگابیت بر ثانیه است.
-
+ VPN to access blocked sites in regions with high levels of Internet censorship. وی پی ان برای دسترسی به سایتهای مسدود شده در مناطق با سانسور شدید اینترنت.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.امنزیا پریمیوم - یک وی پی ان کلاسیک برای کار راحت، دانلود فایلهای بزرگ و تماشای ویدیو با کیفیت بالا. قابل استفاده برای تمامی سایتها، حتی در کشورهایی با بالاترین سطح سانسور اینترنت.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorshipامنزیا رایگان یک وی پی ان رایگان برای دور زدن مسدودیتها در کشورهایی با سطح بالای سانسور اینترنت است.
-
+ %1 MBit/s%1 MBit/s
-
+ %1 days%1 روز
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>وی پی ان فقط سایتهای محبوبی را که در منطقه شما مسدود شدهاند، مانند اینستاگرام، فیسبوک، توییتر و غیره باز میکند. سایر سایتها با آدرس آیپی واقعی شما باز خواهند شد. <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
-
+ Freeرایگان
-
+ %1 $/month%1 $/ماه
@@ -486,6 +486,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionامکان تغییر سرور در هنگام متصل بودن وجود ندارد
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1459,6 +1474,14 @@ Already installed containers were found on the server. All installed containers
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1472,64 +1495,69 @@ Already installed containers were found on the server. All installed containers
قیمت
-
+ Work periodمدت زمان کار
-
+
+ Valid until
+
+
+
+ Speedسرعت
-
+ Support tag
-
+ Copiedکپی شد
-
+ Reload API configبارگذاری مجدد پیکربندی API
-
+ Reload API config?آیا میخواهید پیکربندی API را دوباره بارگذاری کنید؟
-
-
+
+ Continueادامه دهید
-
-
+
+ Cancelلغو
-
+ Cannot reload API config during active connectionنمیتوان پیکربندی API را در حین اتصال فعال دوباره بارگذاری کرد.
-
+ Remove from applicationحذف از برنامه
-
+ Remove from application?آیا میخواهید از برنامه حذف کنید؟
-
+ Cannot remove server during active connectionنمیتوان سرور را در حین اتصال فعال حذف کرد.
@@ -2143,30 +2171,50 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameنام سرور
-
+ Saveذخیره
-
+ Protocolsپروتکلها
-
+ Servicesسرویسها
-
+ Managementمدیریت
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2259,6 +2307,11 @@ Already installed containers were found on the server. All installed containers
Serversسرورها
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2542,6 +2595,31 @@ It's okay as long as it's from someone you trust.
Key as textمتن شامل کلید
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ کلید
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3506,7 +3584,7 @@ It's okay as long as it's from someone you trust.
این پیکربندی قبلاً به برنامه اضافه شده است
-
+ ErrorCode: %1. کد خطا: %1.
@@ -3606,37 +3684,42 @@ It's okay as long as it's from someone you trust.
-
- QFile error: The file could not be opened
+
+ Missing list of available services
- QFile error: An error occurred when reading from the file
+ QFile error: The file could not be opened
- QFile error: The file could not be accessed
+ QFile error: An error occurred when reading from the file
- QFile error: An unspecified error occurred
+ QFile error: The file could not be accessed
- QFile error: A fatal error occurred
+ QFile error: An unspecified error occurred
+ QFile error: A fatal error occurred
+
+
+
+ QFile error: The operation was aborted
-
+ Internal errorInternal error
diff --git a/client/translations/amneziavpn_hi_IN.ts b/client/translations/amneziavpn_hi_IN.ts
index 1ff5f013..b9d06701 100644
--- a/client/translations/amneziavpn_hi_IN.ts
+++ b/client/translations/amneziavpn_hi_IN.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
-
+ VPN to access blocked sites in regions with high levels of Internet censorship.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
-
+ %1 MBit/s
-
+ %1 days
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
-
+ Free
-
+ %1 $/month
@@ -482,6 +482,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionसक्रिय कनेक्शन होने पर सर्वर बदलने में असमर्थ
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1416,6 +1431,14 @@ Already installed containers were found on the server. All installed containers
गोपनीयता नीति
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1429,64 +1452,69 @@ Already installed containers were found on the server. All installed containers
-
+ Work period
-
+
+ Valid until
+
+
+
+ Speed
-
+ Support tag
-
+ Copiedकॉपी किया गया
-
+ Reload API config
-
+ Reload API config?
-
-
+
+ Continueजारी रखना
-
-
+
+ Cancelरद्द करना
-
+ Cannot reload API config during active connection
-
+ Remove from application
-
+ Remove from application?
-
+ Cannot remove server during active connectionसक्रिय कनेक्शन के दौरान सर्वर को हटाया नहीं जा सकता
@@ -2096,30 +2124,50 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameसर्वर का नाम
-
+ Saveसहेजें
-
+ Protocolsप्रोटोकॉल
-
+ Servicesसेवाएं
-
+ Managementप्रबंध
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2212,6 +2260,11 @@ Already installed containers were found on the server. All installed containers
Serversसर्वर
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2487,6 +2540,31 @@ Already installed containers were found on the server. All installed containers
Key as textपाठ के रूप में कुंजी
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ चाबी
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3450,7 +3528,12 @@ Already installed containers were found on the server. All installed containers
-
+
+ Missing list of available services
+
+
+
+ ErrorCode: %1. ErrorCode: %1.
@@ -3515,37 +3598,37 @@ Already installed containers were found on the server. All installed containers
कॉन्फ़िगरेशन में सर्वर से कनेक्ट करने के लिए कोई कंटेनर और क्रेडेंशियल नहीं है
-
+ QFile error: The file could not be openedQफ़ाइल त्रुटि: फ़ाइल खोली नहीं जा सकी
-
+ QFile error: An error occurred when reading from the fileQफ़ाइल त्रुटि: फ़ाइल से पढ़ते समय एक त्रुटि उत्पन्न हुई
-
+ QFile error: The file could not be accessedQफ़ाइल त्रुटि: फ़ाइल तक नहीं पहुंचा जा सका
-
+ QFile error: An unspecified error occurredQफ़ाइल त्रुटि: एक अनिर्दिष्ट त्रुटि उत्पन्न हुई
-
+ QFile error: A fatal error occurredQफ़ाइल त्रुटि: एक घातक त्रुटि उत्पन्न हुई
-
+ QFile error: The operation was abortedQफ़ाइल त्रुटि: ऑपरेशन निरस्त कर दिया गया था
-
+ Internal errorआंतरिक त्रुटि
diff --git a/client/translations/amneziavpn_my_MM.ts b/client/translations/amneziavpn_my_MM.ts
index a13e77f1..62e41897 100644
--- a/client/translations/amneziavpn_my_MM.ts
+++ b/client/translations/amneziavpn_my_MM.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/sသက်တောင့်သက်သာအလုပ်လုပ်နိုင်ဖို့အတွက်နှင့် ကြီးမားသောဖိုင်များကိုဒေါင်းလုဒ်လုပ်ခြင်းနှင့် ဗီဒီယိုများကြည့်ရှုခြင်းတို့အတွက် အသုံးပြုနိုင်သော VPN ဖြစ်ပါတယ်။ မည်သည့်ဆိုက်များအတွက်မဆိုအလုပ်လုပ်ပြီး လိုင်းအရှိန် %1 MBit/s အထိအသုံးပြုနိုင်ပါတယ်။
-
+ VPN to access blocked sites in regions with high levels of Internet censorship. အင်တာနက် ဆင်ဆာဖြတ်တောက်မှု မြင့်မားသော ဒေသများရှိ ပိတ်ဆို့ထားသော ဆိုက်များကို ဝင်ရောက်ရန် VPN။.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.Amnezia Premium - သက်တောင့်သက်သာအလုပ်လုပ်နိုင်ဖို့အတွက်နှင့် ကြီးမားသောဖိုင်များကိုဒေါင်းလုဒ်လုပ်ခြင်းနှင့် ဗီဒီယိုများကိုကြည်လင်ပြတ်သားစွာကြည့်ရှုခြင်းတို့အတွက် အသုံးပြုနိုင်သော VPN ဖြစ်ပါတယ်။ အင်တာနက်ဆင်ဆာဖြတ်မှု အဆင့်အမြင့်ဆုံးနိုင်ငံများတွင်ပင် မည်သည့်ဆိုက်များအတွက်မဆို အလုပ်လုပ်ပါသည်။.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorshipAmnezia Free သည် အင်တာနက်ဆင်ဆာဖြတ်တောက်မှု မြင့်မားသောနိုင်ငံများတွင် ပိတ်ဆို့ခြင်းကို ကျော်ဖြတ်ရန်အတွက် အခမဲ့ VPN တစ်ခုဖြစ်ပါသည်။
-
+ %1 MBit/s%1 MBit/s
-
+ %1 days%1 ရက်
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>ဤ VPN သည် သင့်ဒေသရှိ Instagram၊ Facebook၊ Twitter နှင့် အခြားသော လူကြိုက်များသော ဆိုက်များကိုသာ ဖွင့်ပေးပါမည်။ အခြားဝဘ်ဆိုက်များကိုမူ သင်၏ IP လိပ်စာအစစ်အမှန်ဖြင့်သာ ဖွင့်ပေးပါမည်၊ <a href="%1/free" style="color: #FBB26A;">နောက်ထပ်အသေးစိတ်အချက်အလက်များကို ဝဘ်ဆိုဒ်ပေါ်တွင်ကြည့်ရန်</a>
-
+ Freeအခမဲ့
-
+ %1 $/month%1 $/တစ်လ
@@ -482,6 +482,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionလက်ရှိချိတ်ဆက်မှုတစ်ခုရှိနေချိန်တွင် ဆာဗာကို ပြောင်းလဲ၍မရပါ
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1384,6 +1399,14 @@ Already installed containers were found on the server. All installed containers
ကိုယ်ရေးအချက်အလက်မူဝါဒ
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1397,64 +1420,69 @@ Already installed containers were found on the server. All installed containers
စျေးနှုန်း
-
+ Work periodအလုပ်လုပ်မည့်ကာလ
-
+
+ Valid until
+
+
+
+ Speedမြန်နှုန်း
-
+ Support tagကူညီပံ့ပိုးမှု tag
-
+ Copiedကူးယူပြီးပါပြီ
-
+ Reload API configAPI config ကို ပြန်လည်စတင်မည်
-
+ Reload API config?API config ကို ပြန်လည်စတင်မည်လား?
-
-
+
+ Continueဆက်လက်လုပ်ဆောင်မည်
-
-
+
+ Cancelပယ်ဖျက်မည်
-
+ Cannot reload API config during active connectionချိတ်ဆက်မှုရှိနေချိန်အတွင်း API config ကို ပြန်လည်စတင်၍မရပါ
-
+ Remove from applicationအပလီကေးရှင်းမှဖယ်ရှားမည်
-
+ Remove from application?အပလီကေးရှင်းမှဖယ်ရှားမည်လား?
-
+ Cannot remove server during active connectionချိတ်ဆက်မှုရှိနေချိန်အတွင်း ဆာဗာကို ဖယ်ရှား၍မရပါ
@@ -2057,30 +2085,50 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameဆာဗာအမည်
-
+ Saveသိမ်းဆည်းမည်
-
+ Protocolsပရိုတိုကောများ
-
+ Servicesဝန်ဆောင်မှုများ
-
+ Managementစီမံခန့်ခွဲမှု
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2173,6 +2221,11 @@ Already installed containers were found on the server. All installed containers
Serversဆာဗာများ
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2428,6 +2481,31 @@ Already installed containers were found on the server. All installed containers
I have nothingကျွန်ုပ်တွင်ဘာမှမရှိပါ
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ Key
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3311,7 +3389,7 @@ Already installed containers were found on the server. All installed containers
ဤ config ကို အပလီကေးရှင်းထဲသို့ ထည့်သွင်းပြီးဖြစ်သည်
-
+ ErrorCode: %1. မှားယွင်းမှုကုတ်: %1.
@@ -3416,37 +3494,42 @@ Already installed containers were found on the server. All installed containers
-
+
+ Missing list of available services
+
+
+
+ QFile error: The file could not be openedQFile မှားယွင်းမှု: ဖိုင်ကို ဖွင့်၍မရပါ
-
+ QFile error: An error occurred when reading from the fileQFile မှားယွင်းမှု: ဖိုင်ကိုဖတ်နေစဥ်အတွင်း မှားယွင်းမှုဖြစ်သွားသည်
-
+ QFile error: The file could not be accessedQFile မှားယွင်းမှု: ဖိုင်ကို ဝင်၍မရပါ
-
+ QFile error: An unspecified error occurredQFile မှားယွင်းမှု: သတ်မှတ်မထားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်
-
+ QFile error: A fatal error occurredQFile မှားယွင်းမှု: ကြီးမားသော မှားယွင်းမှုတစ်ခု ဖြစ်ပွားခဲ့သည်
-
+ QFile error: The operation was abortedQFile မှားယွင်းမှု: လုပ်ငန်းစဥ်ကို ဖျက်သိမ်းလိုက်ရသည်
-
+ Internal errorစက်တွင်းဖြစ်သော မှားယွင်းမှု
diff --git a/client/translations/amneziavpn_ru_RU.ts b/client/translations/amneziavpn_ru_RU.ts
index fc6c8d38..b2da3abc 100644
--- a/client/translations/amneziavpn_ru_RU.ts
+++ b/client/translations/amneziavpn_ru_RU.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/sКлассический VPN для комфортной работы, загрузки больших файлов и просмотра видео. Работает для любых сайтов. Скорость до %1 Мбит/с
-
+ VPN to access blocked sites in regions with high levels of Internet censorship. VPN для доступа к заблокированным сайтам в регионах с высоким уровнем интернет-цензуры.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.Amnezia Premium — классический VPN для комфортной работы, загрузки больших файлов и просмотра видео в высоком разрешении. Работает на всех сайтах, даже в странах с самым высоким уровнем интернет-цензуры.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorshipAmnezia Free - это бесплатный VPN для обхода блокировок в странах с высоким уровнем интернет-цензуры
-
+ %1 MBit/s
-
+ %1 days%1 дней
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>Через VPN будут открываться только популярные сайты, заблокированные в вашем регионе, такие как Instagram, Facebook, Twitter и другие. Остальные сайты будут открываться с вашего реального IP-адреса, <a href="%1/free" style="color: #FBB26A;">подробности на сайте.</a>
-
+ FreeБесплатно
-
+ %1 $/month%1 $/месяц
@@ -486,6 +486,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionНевозможно изменить сервер во время активного соединения
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1479,6 +1494,14 @@ Already installed containers were found on the server. All installed containers
Политика конфиденциальности
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1492,64 +1515,69 @@ Already installed containers were found on the server. All installed containers
Цена
-
+ Work periodПериод работы
-
+
+ Valid until
+
+
+
+ SpeedСкорость
-
+ Support tag
-
+ CopiedСкопировано
-
+ Reload API configПерезагрузить конфигурацию API
-
+ Reload API config?Перезагрузить конфигурацию API?
-
-
+
+ ContinueПродолжить
-
-
+
+ CancelОтменить
-
+ Cannot reload API config during active connectionНевозможно перзагрузить API конфигурацию при активном соединении
-
+ Remove from applicationУдалить из приложения
-
+ Remove from application?Удалить из приложения?
-
+ Cannot remove server during active connectionНевозможно удалить сервер во время активного соединения
@@ -2199,27 +2227,32 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameИмя сервера
-
+ SaveСохранить
-
+ ProtocolsПротоколы
-
+ ServicesСервисы
-
+ ManagementУправление
@@ -2227,6 +2260,21 @@ Already installed containers were found on the server. All installed containers
DataДанные
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2323,6 +2371,11 @@ Already installed containers were found on the server. All installed containers
ServersСерверы
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2614,6 +2667,31 @@ It's okay as long as it's from someone you trust.
Key as textКлюч в виде текста
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ Ключ
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3647,7 +3725,7 @@ and will not be shared or disclosed to the Amnezia or any third parties
Данная конфигурация уже была добавлена в приложение
-
+ ErrorCode: %1. Код ошибки: %1.
@@ -3741,37 +3819,42 @@ and will not be shared or disclosed to the Amnezia or any third parties
-
+
+ Missing list of available services
+
+
+
+ QFile error: The file could not be openedОшибка QFile: не удалось открыть файл
-
+ QFile error: An error occurred when reading from the fileОшибка QFile: произошла ошибка при чтении из файла
-
+ QFile error: The file could not be accessedОшибка QFile: не удалось получить доступ к файлу
-
+ QFile error: An unspecified error occurredОшибка QFile: произошла неизвестная ошибка
-
+ QFile error: A fatal error occurredОшибка QFile: произошла фатальная ошибка
-
+ QFile error: The operation was abortedОшибка QFile: операция была прервана
-
+ Internal errorВнутренняя ошибка
diff --git a/client/translations/amneziavpn_uk_UA.ts b/client/translations/amneziavpn_uk_UA.ts
index e2b79498..04e25744 100644
--- a/client/translations/amneziavpn_uk_UA.ts
+++ b/client/translations/amneziavpn_uk_UA.ts
@@ -27,52 +27,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/sЗвичайний VPN для комфортної роботи, завантаження великих файлів та перегляду відео. Працює для будь-яких сайтів. Швидкість до %1 MBit/s
-
+ VPN to access blocked sites in regions with high levels of Internet censorship. VPN для доступу до заблокованих сайтів у регіонах з високим рівнем інтернет-цензури.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.Amnezia Premium - звичайний VPN для комфортної роботи, завантаження великих файлів та перегляду відео у високій роздільній здатності. Працює для всіх вебсайтів, навіть у країнах з найвищим рівнем інтернет-цензури.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorshipAmnezia Free — це безкоштовний VPN для обходу блокувань у країнах з високим рівнем інтернет-цензури
-
+ %1 MBit/s%1 MBit/s
-
+ %1 days%1 днів
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>Лише популярні сайти, які заблоковані у вашому регіоні, будуть відкриватись за допомогою VPN підключення (Instagram, Facebook, Twitter та ін.). Звичайні сайти будуть відкриватися без використання VPN, <a href="%1/free" style="color: #FBB26A;">більш детально на нашому сайті.</a>
-
+ FreeБезкоштовно
-
+ %1 $/month%1 $/місяць
@@ -512,6 +512,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionНе можна змінити сервер при активному підключенні
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1553,6 +1568,14 @@ Already installed containers were found on the server. All installed containers
Політика конфіденційності
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1566,64 +1589,69 @@ Already installed containers were found on the server. All installed containers
Ціна
-
+ Work periodПеріод роботи
-
+
+ Valid until
+
+
+
+ SpeedШвидкість
-
+ Support tag
-
+ CopiedСкопійовано
-
+ Reload API configПерезавантажити конфігурацію API
-
+ Reload API config?Перезавантажити конфігурацію API?
-
-
+
+ ContinueПродовжити
-
-
+
+ CancelВідмінити
-
+ Cannot reload API config during active connectionНеможливо перезавантажити конфігурацію API під час активного підключення
-
+ Remove from applicationВидалити з додатку
-
+ Remove from application?Видалити з додатку?
-
+ Cannot remove server during active connectionНеможливо видалити сервер під час активного підключення
@@ -2285,27 +2313,32 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameІмя сервера
-
+ SaveЗберегти
-
+ ProtocolsПротоколи
-
+ ServicesСервіси
-
+ ManagementУправління
@@ -2313,6 +2346,21 @@ Already installed containers were found on the server. All installed containers
DataДані
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2409,6 +2457,11 @@ Already installed containers were found on the server. All installed containers
ServersСервери
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2700,6 +2753,31 @@ It's okay as long as it's from someone you trust.
Key as textКлюч у вигляді тексту
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ Ключ
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3743,7 +3821,7 @@ and will not be shared or disclosed to the Amnezia or any third parties
Ця конфігурація вже була додана в застосунок
-
+ ErrorCode: %1.
@@ -3837,37 +3915,42 @@ and will not be shared or disclosed to the Amnezia or any third parties
-
- QFile error: The file could not be opened
+
+ Missing list of available services
- QFile error: An error occurred when reading from the file
+ QFile error: The file could not be opened
- QFile error: The file could not be accessed
+ QFile error: An error occurred when reading from the file
- QFile error: An unspecified error occurred
+ QFile error: The file could not be accessed
- QFile error: A fatal error occurred
+ QFile error: An unspecified error occurred
+ QFile error: A fatal error occurred
+
+
+
+ QFile error: The operation was aborted
-
+ Internal errorInternal error
diff --git a/client/translations/amneziavpn_ur_PK.ts b/client/translations/amneziavpn_ur_PK.ts
index 76c25335..d20aae05 100644
--- a/client/translations/amneziavpn_ur_PK.ts
+++ b/client/translations/amneziavpn_ur_PK.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
-
+ VPN to access blocked sites in regions with high levels of Internet censorship.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
-
+ %1 MBit/s
-
+ %1 days
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
-
+ Free
-
+ %1 $/month
@@ -482,6 +482,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connectionفعال کنکشن موجود ہونے کی وجہ سے سرور تبدیل کرنے میں ناکام ہیں
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1420,6 +1435,14 @@ Already installed containers were found on the server. All installed containers
رازداری کی پالیسی
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1433,64 +1456,69 @@ Already installed containers were found on the server. All installed containers
-
+ Work period
-
+
+ Valid until
+
+
+
+ Speed
-
+ Support tag
-
+ Copied
-
+ Reload API config
-
+ Reload API config?
-
-
+
+ Continue
-
-
+
+ Cancel
-
+ Cannot reload API config during active connection
-
+ Remove from application
-
+ Remove from application?
-
+ Cannot remove server during active connectionچالو کنکشن کے دوران سرور کو ہٹایا نہیں جا سکتا
@@ -2100,30 +2128,50 @@ Already installed containers were found on the server. All installed containers
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server nameسرور کا نام
-
+ Saveمحفوظ
-
+ Protocolsپروٹوکولات
-
+ Servicesخدمات
-
+ Managementمینجمنٹ
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2216,6 +2264,11 @@ Already installed containers were found on the server. All installed containers
Serversسرور
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2491,6 +2544,31 @@ Already installed containers were found on the server. All installed containers
Key as textمتن کے طور پر کلید
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ کلید
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3414,7 +3492,7 @@ Already installed containers were found on the server. All installed containers
یہ تشکیل پہلے ہی ایپلی کیشن میں شامل کی جا چکی ہے
-
+ ErrorCode: %1. ایرر کوڈ: %1.
@@ -3519,37 +3597,42 @@ Already installed containers were found on the server. All installed containers
-
+
+ Missing list of available services
+
+
+
+ QFile error: The file could not be openedQFile کی خرابی: فائل کو نہیں کھولا جا سکا
-
+ QFile error: An error occurred when reading from the fileکیو فائل کی خرابی: فائل سے پڑھتے وقت ایک خرابی پیش آگئی
-
+ QFile error: The file could not be accessedQFile کی خرابی: فائل تک رسائی نہیں ہو سکی
-
+ QFile error: An unspecified error occurredکیو فائل میں خرابی: ایک غیر متعینہ خرابی پیش آگئی
-
+ QFile error: A fatal error occurredکیو فائل میں خرابی: ایک مہلک خرابی پیش آگئی
-
+ QFile error: The operation was abortedکیو فائل کی خرابی: آپریشن روک دیا گیا تھا
-
+ Internal errorداخلی خامی
diff --git a/client/translations/amneziavpn_zh_CN.ts b/client/translations/amneziavpn_zh_CN.ts
index fe4c5cf8..33cd7958 100644
--- a/client/translations/amneziavpn_zh_CN.ts
+++ b/client/translations/amneziavpn_zh_CN.ts
@@ -4,52 +4,52 @@
ApiServicesModel
-
+ Classic VPN for comfortable work, downloading large files and watching videos. Works for any sites. Speed up to %1 MBit/s
-
+ VPN to access blocked sites in regions with high levels of Internet censorship.
-
+ <p><a style="color: #EB5757;">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>
-
+ Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. It works for all websites, even in countries with the highest level of internet censorship.
-
+ Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship
-
+ %1 MBit/s
-
+ %1 days
-
+ VPN will open only popular sites blocked in your region, such as Instagram, Facebook, Twitter and others. Other sites will be opened from your real IP address, <a href="%1/free" style="color: #FBB26A;">more details on the website.</a>
-
+ Free
-
+ %1 $/month
@@ -500,6 +500,21 @@ Already installed containers were found on the server. All installed containers
Unable change server while there is an active connection已建立连接时无法更改服务器配置
+
+
+ Online
+
+
+
+
+ Offline
+
+
+
+
+ Connection to
+
+ PageProtocolAwgClientSettings
@@ -1484,6 +1499,14 @@ And if you don't like the app, all the more support it - the donation will
隐私政策
+
+ PageSettingsApiLanguageList
+
+
+ Unable change server location while there is an active connection
+
+
+PageSettingsApiServerInfo
@@ -1497,64 +1520,69 @@ And if you don't like the app, all the more support it - the donation will
-
+ Work period
-
+
+ Valid until
+
+
+
+ Speed
-
+ Support tag
-
+ Copied
-
+ Reload API config
-
+ Reload API config?
-
-
+
+ Continue继续
-
-
+
+ Cancel取消
-
+ Cannot reload API config during active connection
-
+ Remove from application
-
+ Remove from application?
-
+ Cannot remove server during active connection
@@ -2212,27 +2240,32 @@ And if you don't like the app, all the more support it - the donation will
PageSettingsServerInfo
-
+
+ Subscription is valid until
+
+
+
+ Server name服务器名
-
+ Save保存
-
+ Protocols协议
-
+ Services服务
-
+ Management管理
@@ -2240,6 +2273,21 @@ And if you don't like the app, all the more support it - the donation will
Data数据
+
+
+ Server settings
+
+
+
+
+ Name
+
+
+
+
+ Remove server
+
+ PageSettingsServerProtocol
@@ -2340,6 +2388,11 @@ And if you don't like the app, all the more support it - the donation will
Servers服务器
+
+
+ Connect to
+
+ PageSettingsSplitTunneling
@@ -2646,6 +2699,31 @@ It's okay as long as it's from someone you trust.
Key as text授权码文本
+
+
+ Adding a server to connect to
+
+
+
+
+ Key
+ 授权码
+
+
+
+ VPN://
+
+
+
+
+ Add
+
+
+
+
+ Unsupported config file
+
+ PageSetupWizardCredentials
@@ -3748,37 +3826,42 @@ and will not be shared or disclosed to the Amnezia or any third parties
-
- QFile error: The file could not be opened
+
+ Missing list of available services
- QFile error: An error occurred when reading from the file
+ QFile error: The file could not be opened
- QFile error: The file could not be accessed
+ QFile error: An error occurred when reading from the file
- QFile error: An unspecified error occurred
+ QFile error: The file could not be accessed
- QFile error: A fatal error occurred
+ QFile error: An unspecified error occurred
+ QFile error: A fatal error occurred
+
+
+
+ QFile error: The operation was aborted
-
+ ErrorCode: %1. 错误代码: %1.
@@ -3846,7 +3929,7 @@ and will not be shared or disclosed to the Amnezia or any third parties
该配置不包含任何用于连接到服务器的容器和凭据。
-
+ Internal error
diff --git a/client/ui/controllers/connectionController.cpp b/client/ui/controllers/connectionController.cpp
index f8516f6e..f9491d4e 100644
--- a/client/ui/controllers/connectionController.cpp
+++ b/client/ui/controllers/connectionController.cpp
@@ -55,7 +55,7 @@ void ConnectionController::openConnection()
&& !m_serversModel->data(serverIndex, ServersModel::Roles::HasInstalledContainers).toBool()) {
emit updateApiConfigFromGateway();
} else if (configVersion && m_serversModel->isApiKeyExpired(serverIndex)) {
- qDebug() << "attempt to update api config by end_date event";
+ qDebug() << "attempt to update api config by expires_at event";
if (configVersion == ApiConfigSources::Telegram) {
emit updateApiConfigFromTelegram();
} else {
diff --git a/client/ui/controllers/exportController.cpp b/client/ui/controllers/exportController.cpp
index 2690b5b1..8681406e 100644
--- a/client/ui/controllers/exportController.cpp
+++ b/client/ui/controllers/exportController.cpp
@@ -121,9 +121,8 @@ ErrorCode ExportController::generateNativeConfig(const DockerContainer container
jsonNativeConfig = QJsonDocument::fromJson(protocolConfigString.toUtf8()).object();
- if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg) {
- auto clientId = jsonNativeConfig.value(config_key::clientId).toString();
- errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials, serverController);
+ if (protocol == Proto::OpenVpn || protocol == Proto::WireGuard || protocol == Proto::Awg || protocol == Proto::Xray) {
+ errorCode = m_clientManagementModel->appendClient(jsonNativeConfig, clientName, container, credentials, serverController);
}
return errorCode;
}
@@ -248,10 +247,10 @@ void ExportController::generateCloakConfig()
emit exportConfigChanged();
}
-void ExportController::generateXrayConfig()
+void ExportController::generateXrayConfig(const QString &clientName)
{
QJsonObject nativeConfig;
- ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, "", Proto::Xray, nativeConfig);
+ ErrorCode errorCode = generateNativeConfig(DockerContainer::Xray, clientName, Proto::Xray, nativeConfig);
if (errorCode) {
emit exportErrorOccurred(errorCode);
return;
diff --git a/client/ui/controllers/exportController.h b/client/ui/controllers/exportController.h
index b031ea39..a2c9fcfa 100644
--- a/client/ui/controllers/exportController.h
+++ b/client/ui/controllers/exportController.h
@@ -28,7 +28,7 @@ public slots:
void generateAwgConfig(const QString &clientName);
void generateShadowSocksConfig();
void generateCloakConfig();
- void generateXrayConfig();
+ void generateXrayConfig(const QString &clientName);
QString getConfig();
QString getNativeConfigString();
diff --git a/client/ui/controllers/pageController.cpp b/client/ui/controllers/pageController.cpp
index bbcc55a1..34450fea 100644
--- a/client/ui/controllers/pageController.cpp
+++ b/client/ui/controllers/pageController.cpp
@@ -51,7 +51,7 @@ QString PageController::getPagePath(PageLoader::PageEnum page)
{
QMetaEnum metaEnum = QMetaEnum::fromType();
QString pageName = metaEnum.valueToKey(static_cast(page));
- return "qrc:/ui/qml/Pages2/" + pageName + ".qml";
+ return "qrc:/ui/qml/DefaultVpn/Pages/" + pageName + ".qml";
}
void PageController::closeWindow()
diff --git a/client/ui/models/apiServicesModel.cpp b/client/ui/models/apiServicesModel.cpp
index 2a87bde3..81a10f87 100644
--- a/client/ui/models/apiServicesModel.cpp
+++ b/client/ui/models/apiServicesModel.cpp
@@ -27,6 +27,9 @@ namespace
constexpr char storeEndpoint[] = "store_endpoint";
constexpr char isAvailable[] = "is_available";
+
+ constexpr char subscription[] = "subscription";
+ constexpr char endDate[] = "end_date";
}
namespace serviceType
@@ -51,23 +54,23 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
if (!index.isValid() || index.row() < 0 || index.row() >= static_cast(rowCount()))
return QVariant();
- QJsonObject service = m_services.at(index.row()).toObject();
- QJsonObject serviceInfo = service.value(configKey::serviceInfo).toObject();
- auto serviceType = service.value(configKey::serviceType).toString();
+ auto apiServiceData = m_services.at(index.row());
+ auto serviceType = apiServiceData.type;
+ auto isServiceAvailable = apiServiceData.isServiceAvailable;
switch (role) {
case NameRole: {
- return serviceInfo.value(configKey::name).toString();
+ return apiServiceData.serviceInfo.name;
}
case CardDescriptionRole: {
- auto speed = serviceInfo.value(configKey::speed).toString();
+ auto speed = apiServiceData.serviceInfo.speed;
if (serviceType == serviceType::amneziaPremium) {
return tr("Classic VPN for comfortable work, downloading large files and watching videos. "
"Works for any sites. Speed up to %1 MBit/s")
.arg(speed);
} else if (serviceType == serviceType::amneziaFree){
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
- if (service.value(configKey::isAvailable).isBool() && !service.value(configKey::isAvailable).toBool()) {
+ if (isServiceAvailable) {
description += tr("