From 464d77dfb58ae284cb2ae248b8a3541d2c8cc4a3 Mon Sep 17 00:00:00 2001 From: "vladimir.kuznetsov" Date: Fri, 30 Jun 2023 10:40:43 +0900 Subject: [PATCH] added functionality to change app language via settings --- client/CMakeLists.txt | 18 +- client/amnezia_application.cpp | 46 +- client/amnezia_application.h | 21 +- client/resources.qrc | 3 +- client/settings.h | 131 +- client/translations/amneziavpn_ru.qm | Bin 25539 -> 0 bytes client/translations/amneziavpn_ru.ts | 4382 +++++++++++------ client/ui/controllers/settingsController.cpp | 2 +- client/ui/models/languageModel.cpp | 62 + client/ui/models/languageModel.h | 62 + .../ConnectionTypeSelectionDrawer.qml | 2 + .../qml/Components/SelectLanguageDrawer.qml | 137 + .../qml/Components/ShareConnectionDrawer.qml | 2 - .../ui/qml/Components/ShowDetailsDrawer.qml | 10 - client/ui/qml/Controls2/BackButtonType.qml | 1 + client/ui/qml/Controls2/BasicButtonType.qml | 8 +- client/ui/qml/Controls2/DividerType.qml | 4 + client/ui/qml/Controls2/DropDownType.qml | 2 - .../Controls2/TextTypes/ButtonTextType.qml | 5 +- .../Controls2/TextTypes/CaptionTextType.qml | 5 +- .../Controls2/TextTypes/Header1TextType.qml | 7 +- .../Controls2/TextTypes/Header2TextType.qml | 5 +- .../qml/Controls2/TextTypes/LabelTextType.qml | 5 +- .../Controls2/TextTypes/ListItemTitleType.qml | 5 +- .../Controls2/TextTypes/ParagraphTextType.qml | 5 +- .../qml/Controls2/TextTypes/SmallTextType.qml | 5 +- client/ui/qml/Pages2/PageSettingsAbout.qml | 2 - .../ui/qml/Pages2/PageSettingsApplication.qml | 9 +- client/ui/qml/Pages2/PageSettingsBackup.qml | 2 - .../ui/qml/Pages2/PageSettingsConnection.qml | 2 - client/ui/qml/Pages2/PageSettingsDns.qml | 2 - .../ui/qml/Pages2/PageSettingsServerInfo.qml | 4 +- .../ui/qml/Pages2/PageSettingsServersList.qml | 4 +- .../Pages2/PageSetupWizardConfigSource.qml | 9 +- .../qml/Pages2/PageSetupWizardCredentials.qml | 2 - client/ui/qml/Pages2/PageSetupWizardEasy.qml | 2 - .../PageSetupWizardProtocolSettings.qml | 4 +- .../qml/Pages2/PageSetupWizardProtocols.qml | 22 +- client/ui/qml/Pages2/PageSetupWizardStart.qml | 1 + .../ui/qml/Pages2/PageSetupWizardTextKey.qml | 6 +- .../qml/Pages2/PageSetupWizardViewConfig.qml | 2 - client/ui/qml/Pages2/PageShare.qml | 2 - 42 files changed, 3333 insertions(+), 1677 deletions(-) delete mode 100644 client/translations/amneziavpn_ru.qm create mode 100644 client/ui/models/languageModel.cpp create mode 100644 client/ui/models/languageModel.h create mode 100644 client/ui/qml/Components/SelectLanguageDrawer.qml delete mode 100644 client/ui/qml/Components/ShowDetailsDrawer.qml diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index f2346ec5..ad9a4cf4 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -19,15 +19,12 @@ set_property(GLOBAL PROPERTY AUTOMOC_TARGETS_FOLDER "Autogen") set_property(GLOBAL PROPERTY PREDEFINED_TARGETS_FOLDER "Autogen") set(PACKAGES - Widgets Core Gui Network Xml - RemoteObjects Quick Svg QuickControls2 - Core5Compat Concurrent + Widgets Core Gui Network Xml + RemoteObjects Quick Svg QuickControls2 + Core5Compat Concurrent LinguistTools ) if(IOS) - set(PACKAGES - ${PACKAGES} - Multimedia - ) + set(PACKAGES ${PACKAGES} Multimedia) endif() find_package(Qt6 REQUIRED COMPONENTS ${PACKAGES}) @@ -38,11 +35,9 @@ set(LIBS ${LIBS} Qt6::Quick Qt6::Svg Qt6::QuickControls2 Qt6::Core5Compat Qt6::Concurrent ) + if(IOS) - set(LIBS - ${LIBS} - Qt6::Multimedia - ) + set(LIBS ${LIBS} Qt6::Multimedia) endif() qt_standard_project_setup() @@ -349,6 +344,7 @@ if(CMAKE_OSX_SYSROOT STREQUAL "iphoneos") endif() qt_add_executable(${PROJECT} ${SOURCES} ${HEADERS} ${RESOURCES} ${QRC}) + qt_add_translations(${PROJECT} TS_FILES ${CMAKE_CURRENT_LIST_DIR}/translations/amneziavpn_ru.ts) diff --git a/client/amnezia_application.cpp b/client/amnezia_application.cpp index 7159aa4f..7c3b466b 100644 --- a/client/amnezia_application.cpp +++ b/client/amnezia_application.cpp @@ -3,12 +3,11 @@ #include #include #include +#include #include #include #include #include -#include - #include "core/servercontroller.h" #include "logger.h" @@ -88,6 +87,10 @@ void AmneziaApplication::init() connect(m_serversModel.get(), &ServersModel::currentlyProcessedServerIndexChanged, m_containersModel.get(), &ContainersModel::setCurrentlyProcessedServerIndex); + m_languageModel.reset(new LanguageModel(m_settings, this)); + m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get()); + connect(m_languageModel.get(), &LanguageModel::updateTranslations, this, &AmneziaApplication::updateTranslator); + m_configurator = std::shared_ptr(new VpnConfigurator(m_settings, this)); m_vpnConnection.reset(new VpnConnection(m_settings, m_configurator)); @@ -130,18 +133,16 @@ void AmneziaApplication::init() // m_uiLogic->showOnStartup(); // #endif -#endif - - // TODO - fix -#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) - if (isPrimary()) { - QObject::connect(this, &SingleApplication::instanceStarted, m_uiLogic, [this](){ - qDebug() << "Secondary instance started, showing this window instead"; - emit m_uiLogic->show(); - emit m_uiLogic->raise(); - }); - } -#endif +// // TODO - fix +// #if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS) +// if (isPrimary()) { +// QObject::connect(this, &SingleApplication::instanceStarted, m_uiLogic, [this](){ +// qDebug() << "Secondary instance started, showing this window instead"; +// emit m_uiLogic->show(); +// emit m_uiLogic->raise(); +// }); +// } +// #endif // Android TextField clipboard workaround // https://bugreports.qt.io/browse/QTBUG-113461 @@ -195,12 +196,27 @@ void AmneziaApplication::loadFonts() void AmneziaApplication::loadTranslator() { + auto locale = m_settings->getAppLanguage(); m_translator = new QTranslator; - if (m_translator->load(QLocale(), QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/translations"))) { + if (m_translator->load(locale, QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/i18n"))) { installTranslator(m_translator); } } +void AmneziaApplication::updateTranslator(const QLocale &locale) +{ + QResource::registerResource(":/translations.qrc"); + if (!m_translator->isEmpty()) + QCoreApplication::removeTranslator(m_translator); + if (m_translator->load(locale, QString("amneziavpn"), QLatin1String("_"), QLatin1String(":/i18n"))) { + if (QCoreApplication::installTranslator(m_translator)) { + m_settings->setAppLanguage(locale); + } + + m_engine->retranslate(); + } +} + bool AmneziaApplication::parseCommands() { m_parser.setApplicationDescription(APPLICATION_NAME); diff --git a/client/amnezia_application.h b/client/amnezia_application.h index 893511b6..4e9cc348 100644 --- a/client/amnezia_application.h +++ b/client/amnezia_application.h @@ -20,17 +20,17 @@ #include "ui/controllers/pageController.h" #include "ui/controllers/settingsController.h" #include "ui/models/containers_model.h" +#include "ui/models/languageModel.h" #include "ui/models/servers_model.h" #define amnApp (static_cast(QCoreApplication::instance())) - #if defined(Q_OS_ANDROID) || defined(Q_OS_IOS) - #define AMNEZIA_BASE_CLASS QApplication + #define AMNEZIA_BASE_CLASS QApplication #else - #define AMNEZIA_BASE_CLASS SingleApplication - #define QAPPLICATION_CLASS QApplication - #include "singleapplication.h" + #define AMNEZIA_BASE_CLASS SingleApplication + #define QAPPLICATION_CLASS QApplication + #include "singleapplication.h" #endif class AmneziaApplication : public AMNEZIA_BASE_CLASS @@ -41,7 +41,8 @@ public: AmneziaApplication(int &argc, char *argv[]); #else AmneziaApplication(int &argc, char *argv[], bool allowSecondary = false, - SingleApplication::Options options = SingleApplication::User, int timeout = 1000, const QString &userData = {} ); + SingleApplication::Options options = SingleApplication::User, int timeout = 1000, + const QString &userData = {}); #endif virtual ~AmneziaApplication(); @@ -49,6 +50,7 @@ public: void registerTypes(); void loadFonts(); void loadTranslator(); + void updateTranslator(const QLocale &locale); bool parseCommands(); QQmlApplicationEngine *qmlEngine() const; @@ -58,14 +60,15 @@ private: std::shared_ptr m_settings; std::shared_ptr m_configurator; - ContainerProps* m_containerProps {}; - ProtocolProps* m_protocolProps {}; + ContainerProps *m_containerProps {}; + ProtocolProps *m_protocolProps {}; - QTranslator* m_translator; + QTranslator *m_translator; QCommandLineParser m_parser; QSharedPointer m_containersModel; QSharedPointer m_serversModel; + QScopedPointer m_languageModel; QSharedPointer m_vpnConnection; diff --git a/client/resources.qrc b/client/resources.qrc index b306c154..357cb40c 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -1,6 +1,5 @@ - translations/amneziavpn_ru.qm images/close.png images/settings.png images/favorites_disabled.png @@ -270,6 +269,6 @@ images/controls/telegram.svg ui/qml/Controls2/TextTypes/SmallTextType.qml ui/qml/Filters/ContainersModelFilters.qml - ui/qml/Components/ShowDetailsDrawer.qml + ui/qml/Components/SelectLanguageDrawer.qml diff --git a/client/settings.h b/client/settings.h index 28a49e18..9bf40ac7 100644 --- a/client/settings.h +++ b/client/settings.h @@ -2,15 +2,15 @@ #define SETTINGS_H #include -#include #include +#include -#include #include +#include #include -#include "core/defs.h" #include "containers/containers_defs.h" +#include "core/defs.h" #include "secure_qsettings.h" using namespace amnezia; @@ -22,13 +22,19 @@ class Settings : public QObject Q_OBJECT public: - explicit Settings(QObject* parent = nullptr); + explicit Settings(QObject *parent = nullptr); ServerCredentials defaultServerCredentials() const; ServerCredentials serverCredentials(int index) const; - QJsonArray serversArray() const { return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); } - void setServersArray(const QJsonArray &servers) { m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson()); } + QJsonArray serversArray() const + { + return QJsonDocument::fromJson(m_settings.value("Servers/serversList").toByteArray()).array(); + } + void setServersArray(const QJsonArray &servers) + { + m_settings.setValue("Servers/serversList", QJsonDocument(servers).toJson()); + } // Servers section int serversCount() const; @@ -37,9 +43,18 @@ public: void removeServer(int index); bool editServer(int index, const QJsonObject &server); - int defaultServerIndex() const { return m_settings.value("Servers/defaultServerIndex", 0).toInt(); } - void setDefaultServer(int index) { m_settings.setValue("Servers/defaultServerIndex", index); } - QJsonObject defaultServer() const { return server(defaultServerIndex()); } + int defaultServerIndex() const + { + return m_settings.value("Servers/defaultServerIndex", 0).toInt(); + } + void setDefaultServer(int index) + { + m_settings.setValue("Servers/defaultServerIndex", index); + } + QJsonObject defaultServer() const + { + return server(defaultServerIndex()); + } void setDefaultContainer(int serverIndex, DockerContainer container); DockerContainer defaultContainer(int serverIndex) const; @@ -61,13 +76,28 @@ public: QString nextAvailableServerName() const; // App settings section - bool isAutoConnect() const { return m_settings.value("Conf/autoConnect", false).toBool(); } - void setAutoConnect(bool enabled) { m_settings.setValue("Conf/autoConnect", enabled); } + bool isAutoConnect() const + { + return m_settings.value("Conf/autoConnect", false).toBool(); + } + void setAutoConnect(bool enabled) + { + m_settings.setValue("Conf/autoConnect", enabled); + } - bool isStartMinimized() const { return m_settings.value("Conf/startMinimized", false).toBool(); } - void setStartMinimized(bool enabled) { m_settings.setValue("Conf/startMinimized", enabled); } + bool isStartMinimized() const + { + return m_settings.value("Conf/startMinimized", false).toBool(); + } + void setStartMinimized(bool enabled) + { + m_settings.setValue("Conf/startMinimized", enabled); + } - bool isSaveLogs() const { return m_settings.value("Conf/saveLogs", false).toBool(); } + bool isSaveLogs() const + { + return m_settings.value("Conf/saveLogs", false).toBool(); + } void setSaveLogs(bool enabled); enum RouteMode { @@ -75,16 +105,29 @@ public: VpnOnlyForwardSites, VpnAllExceptSites }; - Q_ENUM (RouteMode) + Q_ENUM(RouteMode) QString routeModeString(RouteMode mode) const; - RouteMode routeMode() const { return static_cast(m_settings.value("Conf/routeMode", 0).toInt()); } - void setRouteMode(RouteMode mode) { m_settings.setValue("Conf/routeMode", mode); } + RouteMode routeMode() const + { + return static_cast(m_settings.value("Conf/routeMode", 0).toInt()); + } + void setRouteMode(RouteMode mode) + { + m_settings.setValue("Conf/routeMode", mode); + } - QVariantMap vpnSites(RouteMode mode) const { return m_settings.value("Conf/" + routeModeString(mode)).toMap(); } - void setVpnSites(RouteMode mode, const QVariantMap &sites) { m_settings.setValue("Conf/"+ routeModeString(mode), sites); m_settings.sync(); } - void addVpnSite(RouteMode mode, const QString &site, const QString &ip= ""); + QVariantMap vpnSites(RouteMode mode) const + { + return m_settings.value("Conf/" + routeModeString(mode)).toMap(); + } + void setVpnSites(RouteMode mode, const QVariantMap &sites) + { + m_settings.setValue("Conf/" + routeModeString(mode), sites); + m_settings.sync(); + } + void addVpnSite(RouteMode mode, const QString &site, const QString &ip = ""); void addVpnSites(RouteMode mode, const QMap &sites); // map QStringList getVpnIps(RouteMode mode) const; void removeVpnSite(RouteMode mode, const QString &site); @@ -92,33 +135,59 @@ public: void addVpnIps(RouteMode mode, const QStringList &ip); void removeVpnSites(RouteMode mode, const QStringList &sites); - bool useAmneziaDns() const { return m_settings.value("Conf/useAmneziaDns", true).toBool(); } - void setUseAmneziaDns(bool enabled) { m_settings.setValue("Conf/useAmneziaDns", enabled); } + bool useAmneziaDns() const + { + return m_settings.value("Conf/useAmneziaDns", true).toBool(); + } + void setUseAmneziaDns(bool enabled) + { + m_settings.setValue("Conf/useAmneziaDns", enabled); + } QString primaryDns() const; QString secondaryDns() const; - //QString primaryDns() const { return m_primaryDns; } - void setPrimaryDns(const QString &primaryDns) { m_settings.setValue("Conf/primaryDns", primaryDns); } + // QString primaryDns() const { return m_primaryDns; } + void setPrimaryDns(const QString &primaryDns) + { + m_settings.setValue("Conf/primaryDns", primaryDns); + } - //QString secondaryDns() const { return m_secondaryDns; } - void setSecondaryDns(const QString &secondaryDns) { m_settings.setValue("Conf/secondaryDns", secondaryDns); } + // QString secondaryDns() const { return m_secondaryDns; } + void setSecondaryDns(const QString &secondaryDns) + { + m_settings.setValue("Conf/secondaryDns", secondaryDns); + } static const char cloudFlareNs1[]; static const char cloudFlareNs2[]; -// static constexpr char openNicNs5[] = "94.103.153.176"; -// static constexpr char openNicNs13[] = "144.76.103.143"; + // static constexpr char openNicNs5[] = "94.103.153.176"; + // static constexpr char openNicNs13[] = "144.76.103.143"; - QByteArray backupAppConfig() const { return m_settings.backupAppConfig(); } - bool restoreAppConfig(const QByteArray &cfg) { return m_settings.restoreAppConfig(cfg); } + QByteArray backupAppConfig() const + { + return m_settings.backupAppConfig(); + } + bool restoreAppConfig(const QByteArray &cfg) + { + return m_settings.restoreAppConfig(cfg); + } + + QLocale getAppLanguage() + { + return m_settings.value("Conf/appLanguage", QLocale()).toLocale(); + }; + void setAppLanguage(QLocale locale) + { + m_settings.setValue("Conf/appLanguage", locale); + }; signals: void saveLogsChanged(); private: SecureQSettings m_settings; - }; #endif // SETTINGS_H diff --git a/client/translations/amneziavpn_ru.qm b/client/translations/amneziavpn_ru.qm deleted file mode 100644 index f0e3aaea97fb44a56c38e26996633d05308393e5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25539 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 LCgW%Av1|SxmH|-1 diff --git a/client/translations/amneziavpn_ru.ts b/client/translations/amneziavpn_ru.ts index befce5d5..b1e7817f 100644 --- a/client/translations/amneziavpn_ru.ts +++ b/client/translations/amneziavpn_ru.ts @@ -2,1145 +2,2481 @@ - MainWindow + AdvancedServerSettingsLogic - - Connect to the already created VPN server - Подключиться к уже созданному серверу VPN - - - - Connection code - Код для подключения - - - - Connecting... - Подключение... - - - - - - - - Connect - Подключиться - - - - - Set up your own server - Настроить собственный сервер - - - Connect your server to use VPN - Подключите ваш сервер, чтобы использовать VPN - - - - Server IP address - IP адрес сервера - - - - Login to connect via SSH - Логин для подключения по SSH - - - - - - Password - Пароль - - - - Where to get connection data → - Где взять логин для подключения → - - - - vpn://... - - - - - - - - - Please wait, configuring process may take up to 5 minutes - Пожалуйста подождите, настройка может занять до 5 минут - - - - - Setup your server to use VPN - Настроить ваш сервер для VPN - - - - root - - - - - - Connect using SSH key - Использовать SSH ключ - - - Select VPN protocols to install - Выберите VPN протоколы для установки - - - - OpenVPN and ShadowSocks - with masking using Cloak plugin - OpenVPN и ShadowSocks - с маскировкой плагином Cloak - - - - Port (TCP) - Порт (TCP) - - - - 443 - - - - - - Fake Web Site - Сайт маскировки - - - - - mail.ru - - - - - ShadowSocks - - - - - Port(TCP) - Порт (TCP) - - - - 6789 - - - - - Encryption - Шифрование - - - - chacha20-ietf-poly1305 - - - - - xchacha20-ietf-poly1305 - - - - - - - aes-256-gcm - - - - - - aes-192-gcm - - - - - - - aes-128-gcm - - - - - OpenVPN - - - - - - - - Port - Порт - - - - Protocol - Протокол - - - - DNS settings - Настройки DNS - - - - UDP - - - - - TCP - - - - - AmneziaVPN will install OpenVPN protocol with public/private key pairs generated on server and client sides. You can also configure connection on your mobile device by copying exported ".ovpn" file to your device and setting up official OpenVPN client. We recommend do not use messengers for sending connection profile - it contains VPN private keys. - AmneziaVPN установит протокол OpenVPN и сгенерирует публичные/приваные пары ключей для серверной и клиентской стороны. Вы сможете так же настроить подключение для вашего мобильного устройства, экспортировав конфиг ".ovpn" на устройство и установив официальный клиент OpenVPN. Мы рекоммендуем не передавать конфиг через мессенджеры - он содержит приватный ключ для VPN. - - - - - - - - - - Configuring... - Настройка... - - - - Setup server - Установить сервер - - - - - 0 Mbps - 0 Мбит/сек - - - Add site - Добавить сайт - - - - Connected - Подключено - - - - How to use VPN - Как использовать VPN - - - - For all connections - Для всех соединений - - - - For selected sites - Для выбранных сайтов - - - - Error text - - - - - List of the most popular prohibited sites - Список самых популярных запрещенных сайтов - - - For example, rutor.org or 17.21.111.8 - Например, rutor.org или 17.21.111.8 - - - Anyone who logs in with this code will have the same rights to use the VPN as you. To create a new code, change your login and / or password for connection in your server settings. - Тот, кто зайдёт с этим кодом, будет иметь те же права на использование VPN, что и вы. Чтобы создать новый код смените логин и/или пароль для подлючения в настройках вашего сервера. - - - These sites will open via VPN - These sites will open via VPN - - - Delete selected item - Удалить выбранный элемент - - - Hostname or IP address - Имя хоста или IP адрес - - - - + - + - - - - Server settings - Настройки сервера - - - - Share connection - Поделиться подключением - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Lato'; font-size:8.25pt; font-weight:400; font-style:normal;"> -<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><br /></p></body></html> + + + Clear server from Amnezia software - - Configure VPN protocols manually - Выбрать протоколы + + Service: + - - Run Setup Wizard - Мастер настройки - - - - If you want easily configure your server just run Wizard - Для облегченной настройки сервера запустите мастер настройки - - - - Press configure manually to choose VPN protocols you want to install - Выбрать протоколы для установки самостоятельно - - - - - - - - Setup Wizard - Мастер настройки - - - - High censorship level - Высокий уровень цензуры - - - - Medium censorship level - Средний уровень цензуры - - - - Low censorship level - Низкий уровень цензуры - - - - I'm living in country with high censorship level. Many of foreign web sites and VPNs blocked by my government. I want to setup reliable VPN, which is invisible for government. - Я живу в стране с высоким уровнем цензуры. Многие зарубежные сайты и VPN сервисы заблокированы. Я хочу установить надёжный VPN, невидимый для надзорных органов. - - - - I'm living in country with medium censorship level. Some web sites blocked by my government, but VPNs are not blocked at all. I want to setup flexible solution. - Я живу в стране со средним уровнем цензуры. Некоторые зарубежные сайты заблокированы, но VPN сервисы в целом работают. Я хочу установить гибкое решение. - - - - I just want to improve my privacy in internet. - Я просто хочу повысить уровень моей приватности в интернете. - - - - - - Next - Далее - - - - AmneziaVPN will install VPN protocol which is not visible for your internet provider and government firewall. Your VPN connection will be detected by your provider as regular web traffic to particular web site. - -You SHOULD set this web site address to some foreign web site which is not blocked by your internet provider. Other words you need to type below some foreign web site address which is accessible without VPN. - -Please note, this protocol still does not support export connection profile to mobile devices. Keep for updates. - AmneziaVPN установит VPN протокол невидимый для вашего провайдера и гос. фаервола. Ваше VPN соединение будет определяться как обычные запросы к определнному web сайту. -Вы ДОЛЖНЫ установить адрес этого сайта таким, который не заблокирован вашим провайдером, и находится за границей. Другими словами, вы должны ввести адрес какого-либо зарубежного сайта, который доступен и без VPN. - -Заметьте, этот протокол пока не имеет функции экспорта настроек подключения для мобильных устаройств. Следите за обновлениями. - - - - OpenVPN over Cloak (VPN obfuscation) profile will be installed - Будет установлен профиль OpenVPN over Cloak (VPN маскировка) - - - - Type web site address for mask - Адрес сайта для маскировки - - - - Optional. - -We recommend to enable VPN mode "For selected sites" and add blocked sites you need to visit manually. If you will choose this option, you will need add every blocked site you want to visit to the access list. You may switch between modes later. - -Please note, you should add addresses to the list after VPN connection established. You may add any domain, URL or IP address, it will be resolved to IP address. - Опционально. - -Мы рекомендуем включить режим VPN "Для выбранных сайтов" и добавить вручную заблокированные сайты, которые вы хотите посещать. Если вы выберите эту опцию, вы должны будете добавить каждый заблокированный сайт, который вы хотите посетить в список. Позже вы сможете переключаться между режимами работы VPN. - -Мы рекомендуем добавлять сайты в список только после того, как соединение VPN будет подключено. Вы сможете добавить любые домены, URL или IP адреса. - - - - - Start configuring - Начать настройку - - - - Turn on mode "VPN for selected sites" - Включить режим -"VPN для выбранных сайтов" - - - - AmneziaVPN will install VPN protocol which is difficult to detect by your internet provider and government firewall (but possible). In most cases, this is the most suitable protocol. This protocol is faster compared to the VPN protocols with "web traffic masking". - -This protocol support export connection profile to mobile devices using QR code (you should launch 3rd party opensource VPN client - ShadowSocks VPN). - AmneziaVPN установит VPN протокол, который трудно детектировать интернет провайдерам (но возможно). В большинстве случаев, это наиболее подходящий выбор. Этот протокол быстрее, по сравнению с VPN протоколами с полной маскировкой трафика. - -Этот протокол поддерживает экспорт профиля подключения с помощью QR кода для настройки на мобильных устройствах (вам нужно будет установить сторонний клиент VPN - ShadowSocks VPN). - - - - OpenVPN over ShadowSocks profile will be installed - Будет установлен профиль -OpenVPN over ShadowSocks - - - - OpenVPN profile will be installed - Будет установлен профиль OpenVPN - - - - Please wait. - Пожалуйста, ждите. - - - - Select VPN protocols - Выберите протоколы - - - - udp - - - - - tcp - - - - - + Add site - + Добавить сайт - - - - These sites will be opened using VPN - Эти сайты будут открываться через VPN - - - For example, yousite.com or 17.21.111.8 - Например, yousite.com или 17.21.111.8 - - - Web site or hostname or IP address - Web-сайт, имя хоста или IP-адрес - - - - - Reinstall server, clear server - Переустановить сервер, очистить сервер - - - - Server management - Управление сервером - - - - - Exit - Выход из приложения - - - - Auto start, Auto connect - Авто-запуск, авто-соединение - - - - App settings - Настройки приложения - - - - Network settings - Настройки сети - - - - Servers - Список серверов - - - - Add or import new server - Добавить или импортировать новый сервер - - - - Add server - Добавить сервер - - - - Servers list - Список серверов - - - - Auto start - Авто старт - - - - Application Settings - Настройки приложения - - - - Auto connect - Авто соединение - - - - Check for updates - Проверить обновления - - - - Start minimized - Запускать свёрнутым - - - - Open logs folder - Открыть папки с логами - - - - DNS Servers - DNS сервера - - - - - Reset to default value - Сбросить по умолчанию - - - - Primary DNS server - Первичный DSN сервер - - - - Secondary DNS server - Вторичный DNS сервер - - - - - Clear client cached profile - Удалить закешировнный профиль - - - - - Clear server from Amnezia software - Очистить сервер от Amnezia - - - - Forget this server - Забыть этот сервер - - - - root@yourserver.org - - - - - VPN protocols - VPN протоколы - - - - VPN Protocol: - VPN протокол: - - - - Protocols - Протоколы - - - - Cloak container - Cloak контейнер - - - - - - OpenVPN settings - Настройки OpenVPN - - - - - ShadowSocks settings - Настройки ShadowSocks - - - - Cloak settings - Настройки Cloak - - - - ShadowSocks container - ShadowSocks контейнер - - - - OpenVPN container - OpenVPN контейнер - - - - Full access - Полный доступ - - - - - - <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd"> -<html><head><meta name="qrichtext" content="1" /><style type="text/css"> -p, li { white-space: pre-wrap; } -</style></head><body style=" font-family:'Consolas'; font-size:20px; font-weight:600; font-style:normal;"> -<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:20pt;">vpn:\\xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx</span></p></body></html> - - - - - Anyone who logs in with this code will have the same permissions to use VPN and your server as you. -This code includes your server credentials! -Provide this code only to TRUSTED users. - Любой, кто получит этот код, получит полный доступ к серверу и использованию VPN. Этот код содержит пароль от сервера. -Предоставляйте этот код только доверенным пользователям. - - - - - - - Share for Amnezia client - Расшарить для Amnezia - - - - Anyone who logs in with this code will be able to connect to this VPN server. -This code does not include server credentials. - Любой, кто получит этот код, получит возможность подключаться к этому VPN серверу -Этот код не содержи пароль от сервера. - - - - - - - Generate config - Сгенерировать конфиг - - - - - Share for OpenVPN client - Расшарить для OpenVPN - - - - - Save file - Сохранить файл - - - - AmneziaVPN - - - - - Except selected sites - Кроме выбранных сайтов - - - - yousite.com or IP address - - - - - Web site/Hostname/IP address/Subnet - Web сайт/хост/IP адрес/подсеть - - - - Delete selected - Удалить выбранные - - - - Software version: X.X.X (01.06.2021) - - - - - Share Server (FULL ACCESS) - Расшарить сервер (FULL ACCESS) - - - - - Share for ShadowSocks client - Расшарить для ShadowSocks - - - - - Server: - Сервер: - - - - - Encryption: - Шифрование: - - - - - Port: - Порт: - - - - Password: - Пароль: - - - - Connection string - Строка подключения - - - - Share for Cloak client - Расшарить для Cloak - - - - OpenVPN Settings - Настройки OpenVPN - - - - Hash - Хеш - - - - - - Cipher - Шифр - - - - Network protocol - Сетевой протокол - - - - AES-256-GCM - - - - - AES-192-GCM - - - - - AES-128-GCM - - - - - AES-256-CBC - - - - - AES-192-CBC - - - - - AES-128-CBC - - - - - ChaCha20-Poly1305 - - - - - ARIA-256-CBC - - - - - CAMELLIA-256-CBC - - - - - none - - - - - VPN Addresses Subnet - Подсеть для VPN - - - - - - Save and restart VPN - Сохранить и перезапустить VPN - - - - Auto-negotiate encryption - Авто-согласование шифрования - - - - SHA512 - - - - - SHA384 - - - - - SHA256 - - - - - SHA3-512 - - - - - SHA3-384 - - - - - SHA3-256 - - - - - whirlpool - - - - - BLAKE2b512 - - - - - BLAKE2s256 - - - - - SHA1 - - - - - Block DNS requests outside of VPN - Блокировать запросы DNS мимо VPN - - - - Enable TLS auth - Включить TLS auth - - - - ShadowSocks Settings - Настройки ShadowSocks - - - - - chacha20-poly1305 - - - - - Cloak Settings - Настройки Cloak - - - - plain - - - - - - - - - - - - Copy - Копировать - - - - Cannot open logs folder! - Невозможно открыть папку с логами! - - - - - Please fill in all fields - Пожалуйста, заполните все поля - - - - It's public key. Private key required - Это публичный ключ. Требуется приватный - - - - of - из - - - - - - Error occurred while configuring server. - Ошибка во время настройки сервера - - - - Amnezia server installed - Amnezia сервер установлен - - - - Operation finished - Операция завершена - - - + Uninstalling Amnezia software... - Удаление Amnezia... + - + + Error occurred while cleaning the server. + + + + + + Error message: + + + + + See logs for details. - Смотрите логи для подробных деталей + - + Amnezia server successfully uninstalled - Amnezia сервер удален + - - Show - Показать окно + + Error occurred while scanning the server. + - - - Disconnect - Отключиться + + All containers installed on the server are added to the GUI + - - Visit Website - Посетить сайт + + No installed containers found on the server + + + + + AppSettingsLogic + + + Software version + - - Quit - Выход + + Save log + - - Do you really want to quit? - Вы действительно хотите выйти? + + Open backup + - - Import IP addresses - Импортовать IP адреса + + Can't import config, file is corrupted. + + + + + ClientInfoLogic + + + Service: + + + + + ClientManagementLogic + + + Service: + - - Import connection - Импортировать соединение + + An error occurred while getting the list of clients. + + + + ConnectionController - - Private key - Приватный ключ - - - - Connect using SSH password - Соединиться с паролем SSH - - - - Cache cleared - Кеш очищен - - - - - - - Copied - Скопировано - - - - Save AmneziaVPN config - Сохранить конфиг AmneziaVPN - - - - - Generating... - Генерация... - - - - Error while generating connection profile - Ошибка во время генерации профиля - - - - Save OpenVPN config - Сохранить OpenVPN конфиг - - - + VPN Protocols is not installed. Please install VPN container at first - VPN протоколы ещё не установлены. Установите VPN контейнеры + - - VPN Protocol not chosen - VPN протокол не выбран + + Connection... + - - Software version - Версия программы + + Disconnect + - - Protocol: - Протокол: + + Reconnection... + - - Press Generate config - Нажмите Сгенерировать конфиг + + + + + Connect + - - Share server full access - Расшарить полный доступ + + Disconnection... + + + + + ContextMenu + + + C&ut + + + + + &Copy + + + + + &Paste + + + + + &SelectAll + + + + + ExportController + + + Save AmneziaVPN config + + + + + NotificationHandler + + + + AmneziaVPN + + + + + VPN Connected + + + + + VPN Disconnected + + + + + AmneziaVPN notification + + + + + Unsecured network detected: + + + + + OpenVpnSettings + + + VPN Addresses Subnet + + + + + Network protocol + + + + + Port + + + + + Auto-negotiate encryption + + + + + + Hash + + + + + SHA512 + + + + + SHA384 + + + + + SHA256 + + + + + SHA3-512 + + + + + SHA3-384 + + + + + SHA3-256 + + + + + whirlpool + + + + + BLAKE2b512 + + + + + BLAKE2s256 + + + + + SHA1 + + + + + + Cipher + + + + + AES-256-GCM + + + + + AES-192-GCM + + + + + AES-128-GCM + + + + + AES-256-CBC + + + + + AES-192-CBC + + + + + AES-128-CBC + + + + + ChaCha20-Poly1305 + + + + + ARIA-256-CBC + + + + + CAMELLIA-256-CBC + + + + + none + + + + + TLS auth + + + + + Block DNS requests outside of VPN + + + + + Additional configuration commands + + + + + PageAbout + + + About Amnezia + + + + + AmneziaVPN is opensource software, it's free forever. Our goal is to make the best VPN client in the world. +<ul> +<li>Sources on <a href="https://github.com/amnezia-vpn/desktop-client">GitHub</a></li> +<li><a href="https://amnezia.org/">Web Site</a></li> +<li><a href="https://t.me/amnezia_vpn_en">Telegram group</a></li> +<li><a href="https://signal.group/#CjQKIB2gUf8QH_IXnOJMGQWMDjYz9cNfmRQipGWLFiIgc4MwEhAKBONrSiWHvoUFbbD0xwdh">Signal group</a></li> +</ul> + + + + + + Support + + + + + Have questions? You can get support by: +<ul> +<li><a href="https://t.me/amnezia_vpn_en">Telegram group</a> (preferred way)</li> +<li>Create issue on <a href="https://github.com/amnezia-vpn/desktop-client/issues">GitHub</a></li> +<li>Email to: <a href="support@amnezia.org">support@amnezia.org</a></li> +</ul> + + + + + Donate + + + + + Please support Amnezia project by donation, we really need it now more than ever. +<ul> +<li>By credit card on <a href="https://www.patreon.com/amneziavpn">Patreon</a> (starting from $1)</li> +<li>Send some coins to addresses listed <a href="https://github.com/amnezia-vpn/desktop-client/blob/master/README.md">on GitHub page</a></li> +</ul> + + + + + + PageAdvancedServerSettings + + + Advanced server settings + + + + + Clients Management + + + + + PageAppSetting + + + Application Settings + + + + + Auto connect + + + + + Auto start + + + + + Start minimized + + + + + Check for updates + + + + + Keep logs + + + + + Open logs folder + + + + + Export logs + + + + + Clear logs + + + + + Cleared + + + + + Backup and restore configuration + + + + + Backup app config + + + + + Restore app config + + + + + PageClientInfoOpenVPN + + + Client Info + + + + + Client name + + + + + Certificate id + + + + + Certificate + + + + + Revoke Certificate + + + + + PageClientInfoWireGuard + + + Client Info + + + + + Client name + + + + + Public Key + + + + + Revoke Key + + + + + PageClientManagement + + + Clients Management + + + + + PageDeinstalling + + + Removing services from + + + + + PageGeneralSettings + + + App settings + + + + + Network settings + + + + + Server Settings + + + + + Share connection + + + + + Servers + + + + + Add server + + + + + Exit + + + + + PageHome + + + Протокол подключения + + + + + Servers + + + + + PageNetworkSetting + + + DNS Servers + + + + + Use AmneziaDNS service (recommended) + + + + + Use AmneziaDNS container on your server, when it installed. + +Your AmneziaDNS server available only when it installed and VPN connected, it has internal IP address 172.29.172.254 + +If AmneziaDNS service is not installed on the same server, or this option is unchecked, the following DNS servers will be used: + + + + + Primary DNS server + + + + + + Reset to default + + + + + Secondary DNS server + + + + + PageNewServer + + + Setup your server to use VPN + + + + + If you want easily configure your server just run Wizard + + + + + Run Setup Wizard + + + + + Press configure manually to choose VPN protocols you want to install + + + + + Configure + + + + + PageNewServerProtocols + + + Select VPN protocols + + + + + Setup server + + + + + Select protocol container + + + + + Port + + + + + Network Protocol + + + + + udp + + + + + tcp + + + + + PageProtoCloak + + + Cloak Settings + + + + + Cipher + + + + + chacha20-poly1305 + + + + + aes-256-gcm + + + + + aes-192-gcm + + + + + aes-128-gcm + + + + + Fake Web Site + + + + + Port + + + + + Save and restart VPN + + + + + Cancel + + + + + PageProtoOpenVPN + + + OpenVPN Settings + + + + + VPN Addresses Subnet + + + + + Network protocol + + + + + TCP + + + + + UDP + + + + + Port + + + + + Auto-negotiate encryption + + + + + Cipher + + + + + AES-256-GCM + + + + + AES-192-GCM + + + + + AES-128-GCM + + + + + AES-256-CBC + + + + + AES-192-CBC + + + + + AES-128-CBC + + + + + ChaCha20-Poly1305 + + + + + ARIA-256-CBC + + + + + CAMELLIA-256-CBC + + + + + none + + + + + Hash + + + + + SHA512 + + + + + SHA384 + + + + + SHA256 + + + + + SHA3-512 + + + + + SHA3-384 + + + + + SHA3-256 + + + + + whirlpool + + + + + BLAKE2b512 + + + + + BLAKE2s256 + + + + + SHA1 + + + + + Enable TLS auth + + + + + Block DNS requests outside of VPN + + + + + Additional client config commands → + + + + + Additional server config commands → + + + + + Save and restart VPN + + + + + Cancel + + + + + PageProtoSftp + + + SFTP settings + + + + + Port + + + + + User Name + + + + + Password + + + + + Restore drive when client starts + + + + + Mount drive + + + + + PageProtoShadowSocks + + + ShadowSocks Settings + + + + + Cipher + + + + + chacha20-ietf-poly1305 + + + + + xchacha20-ietf-poly1305 + + + + + aes-256-gcm + + + + + aes-192-gcm + + + + + aes-128-gcm + + + + + Port + + + + + Save and restart VPN + + + + + Cancel + + + + + PageProtoTorWebSite + + + Tor Web Site settings + + + + + Web site onion address + + + + + Notes:<ul> +<li>Use <a href="https://www.torproject.org/download/">Tor Browser</a> to open this url.</li> +<li>After installation it takes several minutes while your onion site will become available in the Tor Network.</li> +<li>When configuring WordPress set the domain as this onion address.</li> +</ul> + + + + + + PageProtoWireGuard + + + WireGuard Settings + + + + + PageQrDecoderIos + + + Import configuration + + + + + PageServerConfiguringProgress + + + Configuring... + + + + + Please wait. + + + + + Cancel + + + + + PageServerContainers + + + + Install new service + + + + + Installed services + + + + + Default + + + + + Port + + + + + Network Protocol + + + + + udp + + + + + tcp + + + + + Cancel + + + + + Continue + Продолжить + + + + Installed Protocols and Services + + + + + Remove container + + + + + This action will erase all data of this container on the server. + + + + + PageServerList + + + Servers + + + + + PageServerSettings + + + Server settings + + + + + Protocols and Services + + + + + Share Server (FULL ACCESS) + + + + + Advanced server settings + + + + + Forget this server + + + + + PageSettings + + + Settings + + + + + Servers + + + + + Connection + + + + + Application + + + + + Backup + + + + + About AmneziaVPN + + + + + PageSettingsAbout + + + Support the project with a donation + + + + + This is a free and open source application. If you like it, support the developers with a donation. +And if you don't like the app, all the more support it - the donation will be used to improve the app. + + + + + Card on Patreon + + + + + Show other methods on Github + + + + + Contacts + + + + + Telegram group + + + + + To discuss features + + + + + Mail + + + + + For reviews and bug reports + + + + + Github + + + + + Website + + + + + Check for updates + + + + + PageSettingsApplication + + + Application + + + + + Language + + + + + Reset settings and remove all data from the application + + + + + PageSettingsBackup + + + Backup + + + + + Save logs + + + + + Open folder with logs + + + + + Save logs to file + + + + + Clear logs + + + + + Configuration backup + + + + + It will help you instantly restore connection settings at the next installation + + + + + Make a backup + + + + + Restore from backup + + + + + PageSettingsConnection + + + Connection + + + + + Use AmnesiaDNS if installed on the server + + + + + Internal IP address 172.29.172.254 + + + + + DNS servers + + + + + If AmneziaDNS is not used or installed + + + + + Split site tunneling + + + + + Allows you to connect to some sites through a secure connection, and to others bypassing it + + + + + Separate application tunneling + + + + + Allows you to use the VPN only for certain applications + + + + + PageSettingsDns + + + DNS servers + + + + + If AmneziaDNS is not used or installed + + + + + Save + + + + + PageSettingsServerData + + + All installed containers have been added to the application + + + + + Не найдено установленных контейнеров + + + + + Clear Amnezia cache + + + + + May be needed when changing other settings + + + + + Clear cached profiles? + Очистить закешированные профили + + + + some description + + + + + + + Continue + Продолжить + + + + + + Cancel + + + + + Проверить сервер на наличие ранее установленных сервисов Amnezia + + + + + Добавим их в приложение, если они не отображались + + + + + Remove server from application + + + + + Remove server? + + + + + All installed AmneziaVPN services will still remain on the server. + + + + + Clear server from Amnezia software + + + + + Clear server from Amnezia software? + + + + + All containers will be deleted on the server. This means that configuration files, keys and certificates will be deleted. + + + + + PageSettingsServerInfo + + + Server name + + + + + Save + + + + + Protocols + + + + + Services + + + + + Data + + + + + PageSetupWizard + + + Setup your server to use VPN + + + + + High censorship level + + + + + I'm living in a country with a high censorship level. Many of the foreign websites and VPNs are blocked by my government. I want to setup a reliable VPN, which can not be detected by my internet provider and my government. +OpenVPN and ShadowSocks over Cloak (VPN obfuscation) profiles will be installed. + + + + + + Medium censorship level + + + + + I'm living in a country with a medium censorship level. Some websites are blocked by my government, but VPNs are not blocked at all. I want to setup a flexible solution. +OpenVPN over ShadowSocks profile will be installed. + + + + + + Low censorship level + + + + + I want to improve my privacy on the internet. +OpenVPN profile will be installed. + + + + + + Next + + + + + PageSetupWizardCredentials + + + Server connection + + + + + Server IP address [:port] + + + + + + Enter the address in the format 255.255.255.255:88 + + + + + Login to connect via SSH + + + + + Password / Private key + + + + + Set up a server the easy way + + + + + Select protocol to install + + + + + Ip address cannot be empty + + + + + Login cannot be empty + + + + + Password/private key cannot be empty + + + + + PageSetupWizardEasy + + + What is the level of internet control in your region? + + + + + Continue + Продолжить + + + + PageSetupWizardHighLevel + + + Setup Wizard + + + + + AmneziaVPN will install a VPN protocol which is not visible to your internet provider and government firewall. Your VPN connection will be seen by your internet provider as regular web traffic to a particular website. + +You SHOULD set this website address to some foreign website which is not blocked by your internet provider. In other words, you need to type some foreign website address which is accessible to you without a VPN. + + + + + Type another web site address for masking or keep it by default. Your internet provider will think you working on this web site when you connected to VPN. + + + + + OpenVPN and ShadowSocks over Cloak (VPN obfuscation) profiles will be installed. + +This protocol support exporting connection profiles to mobile devices by exporting ShadowSocks and Cloak configs (you should launch the 3rd party open source VPN client - ShadowSocks VPN and install Cloak plugin). + + + + + Next + + + + + PageSetupWizardInstalling + + + + The container you are trying to install is already installed on the server. All installed containers have been added to the application + + + + + The server has already been added to the application + + + + + PageSetupWizardLowLevel + + + Setup Wizard + + + + + AmneziaVPN will install the OpenVPN protocol with public/private key pairs generated on both server and client sides. + +You can also configure the connection on your mobile device by copying the exported ".ovpn" file to your device, and setting up the official OpenVPN client. + +We recommend not to use messaging applications for sending the connection profile - it contains VPN private keys. + + + + + OpenVPN profile will be installed + + + + + Start configuring + + + + + PageSetupWizardMediumLevel + + + Setup Wizard + + + + + AmneziaVPN will install a VPN protocol which is difficult to detect by your internet provider and government firewall (but possible). In most cases, this is the most suitable protocol. This protocol is faster compared to the VPN protocols with "VPN masking". + +This protocol supports exporting connection profiles to mobile devices by using QR codes (you should launch the 3rd party open source VPN client - ShadowSocks VPN). + + + + + OpenVPN over ShadowSocks profile will be installed + + + + + Next + + + + + PageSetupWizardProtocolSettings + + + Installing + + + + + protocol description + + + + + More detailed + + + + + detailed protocol description + + + + + Close + + + + + Установить + + + + + PageSetupWizardStart + + + У меня есть данные для подключения + + + + + У меня ничего нет + + + + + PageSetupWizardTextKey + + + Connection key + + + + + A line that starts with vpn://... + + + + + Key + + + + + Insert + + + + + Continue + Продолжить + + + + PageSetupWizardVPNMode + + + Setup Wizard + + + + + Optional. + +You can enable VPN mode "For selected sites" and add blocked sites you need to visit manually. If you will choose this option, you will need add every blocked site you want to visit to the access list. You may switch between modes later. + +Please note, you should add addresses to the list after VPN connection established. You may add any domain, URL or IP address, it will be resolved to IP address. + + + + + Turn on mode "VPN for selected sites" + + + + + Start configuring + + + + + PageSetupWizardViewConfig + + + New connection + + + + + Do not use connection code from public sources. It could be created to intercept your data. + + + + + Collapse content + + + + + Show content + + + + + Connect + + + + + PageShare + + + For the AmnesiaVPN app + + + + + OpenVpn native format + + + + + WireGuard native format + + + + + VPN Access + + + + + Connection + + + + + Full + + + + + VPN access without the ability to manage the server + + + + + Full access to server + + + + + Server and service + + + + + Server + + + + + Protocols and services + + + + + + Connection to + + + + + + File with connection settings to + + + + + + Connection format + + + + + Share + + + + + PageShareConnection + + + Share protocol config + + + + + Share for Amnezia + + + + + Share for + + + + + PageShareProtoAmnezia + + + Share for Amnezia + + + + + Anyone who logs in with this code will have the same permissions to use VPN and YOUR SERVER as you. + +This code includes your server credentials! + +Provide this code only to TRUSTED users. + + + + + Anyone who logs in with this code will be able to connect to this VPN server. + +This code does not include server credentials. + +New encryption keys pair will be generated. + + + + + Share + + + + + Save to file + + + + + Save AmneziaVPN config + + + + + Scan QR code using AmneziaVPN mobile + + + + + PageShareProtoCloak + + + Share Cloak Settings + + + + + Note: Cloak protocol using same password for all connections + + + + + Share + + + + + Save to file + + + + + Save AmneziaVPN config + + + + + PageShareProtoIkev2 + + + Share IKEv2 Settings + + + + + + Export p12 certificate + + + + + + Export config for Apple + + + + + + Export config for StrongSwan + + + + + PageShareProtoOpenVPN + + + Share OpenVPN Settings + + + + + New encryption keys pair will be generated. + + + + + Share + + + + + Save to file + + + + + Save OpenVPN config + + + + + PageShareProtoSftp + + + Share SFTP settings + + + + + PageShareProtoShadowSocks + + + Share ShadowSocks Settings + + + + + Note: ShadowSocks protocol using same password for all connections + + + + + Copy config + + + + + Connection string + + + + + Copy string + + + + + PageShareProtoTorWebSite + + + Share Tor Web site + + + + + PageShareProtoWireGuard + + + Share WireGuard Settings + + + + + New encryption keys pair will be generated. + + + + + Share + + + + + Save to file + + + + + Save OpenVPN config + + + + + PageShareProtocolBase + + + Generate config + + + + + Generating config... + + + + + Show config + + + + + PageSites + + + Web site/Hostname/IP address/Subnet + + + + + yousite.com or IP address + + + + + Import IP addresses + + + + + Delete selected + + + + + Select all + + + + + Export all + + + + + PageStart + + + Setup your server to use VPN + + + + + Connect to the already created VPN server + + + + + + Set up your own server + + + + + Import connection + + + + + Connection code + + + + + Connect + + + + + Open file + + + + + Scan QR code + + + + + Restore app config + + + + + How to get own server? → + + + + + Server IP address [:port] + + + + + Login to connect via SSH + + + + + + Password + + + + + + Connect using SSH key + + + + + Private key + + + + + Connect using SSH password + + + + + PageTest + + + Протоколы + + + + + Сервисы + + + + + Данные + + + + + + Forget this server + + + + + SHA512 + + + + + SHA384 + + + + + SHA256 + + + + + SHA3-512 + + + + + SHA3-384 + + + + + SHA3-256 + + + + + whirlpool + + + + + BLAKE2b512 + + + + + BLAKE2s256 + + + + + SHA1 + + + + + + + Auto-negotiate encryption + + + + + PageVPN + + + Donate + + + + + Server + + + + + Profile + + + + + Proto + + + + + DNS + + + + + How to use VPN + + + + + For all connections + + + + + Except selected sites + + + + + For selected sites + + + + + + Add site + + + + + PageViewConfig + + + Check config + + + + + Attention! +The config above contains cached OpenVPN connection profile. +AmneziaVPN detected this profile may contain malicious scripts. Please, carefully review the config and import this config only if you completely trust it. + + + + + Suspicious string: + + + + + Cached connection profile: + + + + + Cancel + + + + + Import config + + + + + PopupType + + + Close + QObject - - AmneziaVPN is already running. - Приложение AmneziaVPN уже запущено. - No error @@ -1166,656 +2502,636 @@ This code does not include server credentials. Server port already used. Check for another software + + + Server error: Docker container missing + + + + + Server error: Docker failed + + - Ssh connection error + Installation canceled by user - Ssh connection timeout - - - - - Ssh protocol error - - - - - Ssh server ket check failed + The user does not have permission to use sudo - Ssh key file error + Ssh request was denied - Ssh authentication error + Ssh request was interrupted - Ssh session closed - - - - Ssh internal error - - Failed to create remote process on server + + Invalid private key or invalid passphrase entered - - Failed to start remote process on server + + The selected private key format is not supported, use openssh ED25519 key types or PEM key types + + + + + Timeout connecting to server - Remote process on server crashed + Sftp error: End-of-file encountered + + + + + Sftp error: File does not exist + + + + + Sftp error: Permission denied - Failed to save config to disk + Sftp error: Generic failure - OpenVPN config missing + Sftp error: Garbage received from server - OpenVPN management server error + Sftp error: No connection has been set up - EasyRSA runtime error + Sftp error: There was a connection, but we lost it + + + + + Sftp error: Operation not supported by libssh yet + + + + + Sftp error: Invalid file handle - OpenVPN executable missing + Sftp error: No such file or directory path exists - EasyRsa executable missing + Sftp error: An attempt to create an already existing file or directory has been made - Amnezia helper service error - Ошибка локального сервиса Amnezia + Sftp error: Write-protected filesystem + - + + Sftp error: No media was in remote drive + + + + + Failed to save config to disk + + + + + OpenVPN config missing + + + + + OpenVPN management server error + + + + + OpenVPN executable missing + + + + + ShadowSocks (ss-local) executable missing + + + + + Cloak (ck-client) executable missing + + + + + Amnezia helper service error + + + + + OpenSSL failed + + + + Can't connect: another VPN connection is active - + + Can't setup OpenVPN TAP network adapter + + + + + VPN pool error: no available addresses + + + + + The config does not contain any containers and credentiaks for connecting to the server + + + + Internal error - - - QSsh::Internal::SftpChannelPrivate - - Server could not start SFTP subsystem. + + IPsec - - The SFTP server finished unexpectedly with exit code %1. + + + Web site in Tor network - - The SFTP server crashed: %1. + + + DNS Service - - Unexpected packet of type %1. + + Sftp file sharing service - - Protocol version mismatch: Expected %1, got %2 + + OpenVPN container - - Unknown error. + + Container with OpenVpn and ShadowSocks - - Created remote directory "%1". + + Container with OpenVpn and ShadowSocks protocols configured with traffic masking by Cloak plugin - - Remote directory "%1" already exists. + + WireGuard container - - Error creating directory "%1": %2 + + IPsec container - - Could not open local file "%1": %2 + + Sftp file sharing service - is secure FTP service - - Remote directory could not be opened for reading. + + Sftp service - - Failed to list remote directory contents. - - - - - Failed to close remote directory. - - - - - Failed to open remote file for reading. - - - - - Failed to retrieve information on the remote file ('stat' failed). - - - - - Failed to read remote file. - - - - - - Failed to close remote file. - - - - - Failed to open remote file for writing. - - - - - Failed to write remote file. - - - - - Cannot append to remote file: Server does not support the file size attribute. - - - - - SFTP channel closed unexpectedly. - - - - - Server could not start session: %1 - - - - - Error reading local file: %1 + + An error occurred while saving the list of clients. - QSsh::Internal::SshChannelManager + SelectContainer - - Unexpected request success packet. + + VPN containers - - Unexpected request failure packet. - - - - - Invalid channel id %1 + + Other containers - QSsh::Internal::SshConnectionPrivate + SelectLanguageDrawer - - SSH Protocol error: %1 - - - - - Botan library exception: %1 - - - - - Server identification string is %n characters long, but the maximum allowed length is 255. - - - - - - - - - Server identification string contains illegal NUL character. - - - - - Server Identification string "%1" is invalid. - - - - - Server protocol version is "%1", but needs to be 2.0 or 1.99. - - - - - Server identification string is invalid (missing carriage return). - - - - - Server reports protocol version 1.99, but sends data before the identification string, which is not allowed. - - - - - - - - Unexpected packet of type %1. - - - - - Password expired. - - - - - Server rejected key. - - - - - Server rejected password. - - - - - The server sent an unexpected SSH packet of type SSH_MSG_UNIMPLEMENTED. - - - - - Server closed connection: %1 - - - - - Connection closed unexpectedly. - - - - - Timeout waiting for reply from server. - - - - - No private key file given. + + Choose language - QSsh::Internal::SshRemoteProcessPrivate + ServerConfiguringProgressLogic - - Process killed by signal + + + Please wait, configuring process may take up to 5 minutes - - Server sent invalid signal "%1" + + Configuring... + + + + + Operation finished - QSsh::SftpFileSystemModel + ServerContainersLogic - - File Type + + Error occurred while configuring server. - - File Name + + Error message: - - Error getting "stat" info about "%1": %2 - - - - - Error listing contents of directory "%1": %2 + + See logs for details. - QSsh::Ssh + ServerSettingsLogic - - Failed to open key file "%1" for reading: %2 + + + Clear client cached profile - - Failed to open key file "%1" for writing: %2 + + Service: - - Password Required + + Cache cleared - - - Please enter the password for your private key. - - - - - QSsh::SshKeyCreationDialog - - - SSH Key Configuration - - - - - Options - - - - - Key algorithm: - - - - - &RSA - - - - - &DSA - - - - - ECDSA - - - - - Key &size: - - - - - Private key file: - - - - - - Browse... - - - - - Public key file: - - - - - &Generate And Save Key Pair - - - - - &Cancel - - - - - Choose... - - - - - Key Generation Failed - - - - - Choose Private Key File Name - - - - - Cannot Save Key File - - - - - Failed to create directory: "%1". - - - - - Cannot Save Private Key File - - - - - The private key file could not be saved: %1 - - - - - Cannot Save Public Key File - - - - - The public key file could not be saved: %1 - - - - - File Exists - - - - - There already is a file of that name. Do you want to overwrite it? - - - - - ServerWidget - - - Form - - - - - Description - - - - - Address - - - - - Set as default - - - - - Share connection - Поделиться подключением - - - - Connection - - - - - Server settings - Настройки сервера - Settings - + Server #1 - - + + Server - SshConnection + SettingsController - - Server and client capabilities don't match. Client list was: %1. -Server list was %2. + + Software version + + + + + Save log + + + + + Backup application config + + + + + Open backup - SshKeyGenerator + ShareConnectionButtonCopyType - - Error generating key: %1 + + Copy - - Password for Private Key + + Copied + + + + + ShareConnectionDrawer + + + Save connection code - - It is recommended that you secure your private key -with a password, which you can enter below. + + Copy - - Encrypt Key File + + Show content - - Do Not Encrypt Key File + + To read the QR code in the Amnezia app, select "Add Server" → "I have connection details" + + + + + ShareConnectionLogic + + + Error while generating connection profile + + + + + Error occurred while generating the config. + + + + + Error message: + + + + + See logs for details. + + + + + SitesLogic + + + These sites will be opened using VPN + + + + + These sites will be excepted from VPN + + + + + StartPageLogic + + + + Connect + + + + + + Please fill in all fields + + + + + Connecting... + + + + + Open config file + + + + + SystemTrayNotificationHandler + + + Show + + + + + Connect + + + + + Disconnect + + + + + Visit Website + + + + + Quit + + + + + UiLogic + + + Error occurred while configuring server. + + + + + Error message: + + + + + See logs for details. VpnConnection - + Mbps + + VpnLogic + + + + 0 Mbps + + + + + AmneziaVPN not supporting selected protocol on this device. Select another protocol. + + + + + VPN Protocols is not installed. + Please install VPN container at first + + + + + VPN Protocol not chosen + + + VpnProtocol - + Unknown - Неизвестно + - + Disconnected - Отключено + - + Preparing - Подготовка + - + Connecting... - Подключение... + - + Connected - Подключено + - + Disconnecting... - Отключение... + - + Reconnecting... - Переподключение... + - + Error - Ошибка + + + + + amnezia::ContainerProps + + + Low + + + + + High + + + + + Medium + + + + + Many foreign websites and VPN providers are blocked + + + + + Some foreign sites are blocked, but VPN providers are not blocked + + + + + I just want to increase the level of privacy + + + + + main + + + It's public key. Private key required + + + + + Ssh log + + + + + App log + + + + + Wrap words + diff --git a/client/ui/controllers/settingsController.cpp b/client/ui/controllers/settingsController.cpp index fcfcc7af..42dd2231 100644 --- a/client/ui/controllers/settingsController.cpp +++ b/client/ui/controllers/settingsController.cpp @@ -2,9 +2,9 @@ #include -#include "defines.h" #include "logger.h" #include "utilities.h" +#include "version.h" SettingsController::SettingsController(const QSharedPointer &serversModel, const QSharedPointer &containersModel, diff --git a/client/ui/models/languageModel.cpp b/client/ui/models/languageModel.cpp new file mode 100644 index 00000000..e95b2ccf --- /dev/null +++ b/client/ui/models/languageModel.cpp @@ -0,0 +1,62 @@ +#include "languageModel.h" + +LanguageModel::LanguageModel(std::shared_ptr settings, QObject *parent) + : m_settings(settings), QAbstractListModel(parent) +{ + QMetaEnum metaEnum = QMetaEnum::fromType(); + for (int i = 0; i < metaEnum.keyCount(); i++) { + m_availableLanguages.push_back( + LanguageModelData { metaEnum.valueToKey(i), static_cast(i) }); + } +} + +int LanguageModel::rowCount(const QModelIndex &parent) const +{ + return static_cast(m_availableLanguages.size()); +} + +QVariant LanguageModel::data(const QModelIndex &index, int role) const +{ + if (!index.isValid() || index.row() < 0 || index.row() >= static_cast(m_availableLanguages.size())) { + return QVariant(); + } + + switch (role) { + case NameRole: { + return m_availableLanguages[index.row()].name; + break; + } + case IndexRole: { + return static_cast(m_availableLanguages[index.row()].index); + break; + } + } + return QVariant(); +} + +QHash LanguageModel::roleNames() const +{ + QHash roles; + roles[NameRole] = "languageName"; + roles[IndexRole] = "languageIndex"; + return roles; +} + +void LanguageModel::changeLanguage(const LanguageSettings::AvailableLanguageEnum language) +{ + switch (language) { + case LanguageSettings::AvailableLanguageEnum::English: emit updateTranslations(QLocale::English); break; + case LanguageSettings::AvailableLanguageEnum::Russian: emit updateTranslations(QLocale::Russian); break; + default: emit updateTranslations(QLocale::English); break; + } +} + +int LanguageModel::getCurrentLanguageIndex() +{ + auto locale = m_settings->getAppLanguage(); + switch (locale.language()) { + case QLocale::English: return static_cast(LanguageSettings::AvailableLanguageEnum::English); break; + case QLocale::Russian: return static_cast(LanguageSettings::AvailableLanguageEnum::Russian); break; + default: return static_cast(LanguageSettings::AvailableLanguageEnum::English); break; + } +} diff --git a/client/ui/models/languageModel.h b/client/ui/models/languageModel.h new file mode 100644 index 00000000..b3ff4f6e --- /dev/null +++ b/client/ui/models/languageModel.h @@ -0,0 +1,62 @@ +#ifndef LANGUAGEMODEL_H +#define LANGUAGEMODEL_H + +#include +#include + +#include "settings.h" + +namespace LanguageSettings +{ + Q_NAMESPACE + enum class AvailableLanguageEnum { + English, + Russian + }; + Q_ENUM_NS(AvailableLanguageEnum) + + static void declareQmlAvailableLanguageEnum() + { + qmlRegisterUncreatableMetaObject(LanguageSettings::staticMetaObject, "AvailableLanguageEnum", 1, 0, + "AvailableLanguageEnum", QString()); + } +} + +struct LanguageModelData +{ + QString name; + LanguageSettings::AvailableLanguageEnum index; +}; + +class LanguageModel : public QAbstractListModel +{ + Q_OBJECT + +public: + enum Roles { + NameRole = Qt::UserRole + 1, + IndexRole + }; + + LanguageModel(std::shared_ptr settings, QObject *parent = nullptr); + + int rowCount(const QModelIndex &parent = QModelIndex()) const override; + QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override; + +public slots: + void changeLanguage(const LanguageSettings::AvailableLanguageEnum language); + int getCurrentLanguageIndex(); + +signals: + void updateTranslations(const QLocale &locale); + +protected: + QHash roleNames() const override; + +private: + QVector m_availableLanguages; + + std::shared_ptr m_settings; +}; + +#endif // LANGUAGEMODEL_H diff --git a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml index 51bffc03..71299b1f 100644 --- a/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml +++ b/client/ui/qml/Components/ConnectionTypeSelectionDrawer.qml @@ -18,12 +18,14 @@ DrawerType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right + spacing: 0 Header2TextType { Layout.fillWidth: true Layout.topMargin: 24 Layout.rightMargin: 16 Layout.leftMargin: 16 + Layout.bottomMargin: 32 Layout.alignment: Qt.AlignHCenter text: "Данные для подключения" diff --git a/client/ui/qml/Components/SelectLanguageDrawer.qml b/client/ui/qml/Components/SelectLanguageDrawer.qml new file mode 100644 index 00000000..f1ffa416 --- /dev/null +++ b/client/ui/qml/Components/SelectLanguageDrawer.qml @@ -0,0 +1,137 @@ +import QtQuick +import QtQuick.Controls +import QtQuick.Layouts + +import "../Controls2" +import "../Controls2/TextTypes" + +DrawerType { + id: root + + width: parent.width + height: parent.height * 0.9 + + ColumnLayout { + id: backButton + + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.topMargin: 16 + + BackButtonType { + backButtonImage: "qrc:/images/controls/arrow-left.svg" + backButtonFunction: function() { + root.close() + } + } + } + + FlickableType { + anchors.top: backButton.bottom + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: parent.bottom + contentHeight: content.implicitHeight + + ColumnLayout { + id: content + + anchors.fill: parent + + Header2Type { + id: header + Layout.fillWidth: true + Layout.topMargin: 16 + Layout.rightMargin: 16 + Layout.leftMargin: 16 + + headerText: qsTr("Choose language") + } + + ListView { + id: listView + + Layout.fillWidth: true + height: listView.contentItem.height + + clip: true + interactive: false + + model: LanguageModel + currentIndex: LanguageModel.getCurrentLanguageIndex() + + ButtonGroup { + id: buttonGroup + } + + delegate: Item { + implicitWidth: root.width + implicitHeight: content.implicitHeight + + ColumnLayout { + id: delegateContent + + anchors.fill: parent + + RadioButton { + id: radioButton + + implicitWidth: parent.width + implicitHeight: radioButtonContent.implicitHeight + + hoverEnabled: true + + indicator: Rectangle { + anchors.fill: parent + color: radioButton.hovered ? "#2C2D30" : "#1C1D21" + + Behavior on color { + PropertyAnimation { duration: 200 } + } + } + + RowLayout { + id: radioButtonContent + anchors.fill: parent + + anchors.rightMargin: 16 + anchors.leftMargin: 16 + + spacing: 0 + + z: 1 + + ParagraphTextType { + Layout.fillWidth: true + Layout.topMargin: 20 + Layout.bottomMargin: 20 + + text: languageName + } + + Image { + source: "qrc:/images/controls/check.svg" + visible: radioButton.checked + + width: 24 + height: 24 + + Layout.rightMargin: 8 + } + } + + ButtonGroup.group: buttonGroup + checked: listView.currentIndex === index + + onClicked: { + listView.currentIndex = index + LanguageModel.changeLanguage(languageIndex) + } + } + } + } + } + } + } +} diff --git a/client/ui/qml/Components/ShareConnectionDrawer.qml b/client/ui/qml/Components/ShareConnectionDrawer.qml index 720e3206..99e172cc 100644 --- a/client/ui/qml/Components/ShareConnectionDrawer.qml +++ b/client/ui/qml/Components/ShareConnectionDrawer.qml @@ -105,8 +105,6 @@ DrawerType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 16 backButtonFunction: function() { diff --git a/client/ui/qml/Components/ShowDetailsDrawer.qml b/client/ui/qml/Components/ShowDetailsDrawer.qml deleted file mode 100644 index 2f6d2656..00000000 --- a/client/ui/qml/Components/ShowDetailsDrawer.qml +++ /dev/null @@ -1,10 +0,0 @@ -import QtQuick -import QtQuick.Controls -import QtQuick.Layouts - -import "../Controls2" -import "../Controls2/TextTypes" - -Item { - -} diff --git a/client/ui/qml/Controls2/BackButtonType.qml b/client/ui/qml/Controls2/BackButtonType.qml index 0ccb7345..91f5f28f 100644 --- a/client/ui/qml/Controls2/BackButtonType.qml +++ b/client/ui/qml/Controls2/BackButtonType.qml @@ -17,6 +17,7 @@ Item { id: content anchors.fill: parent + anchors.leftMargin: 8 ImageButtonType { image: backButtonImage diff --git a/client/ui/qml/Controls2/BasicButtonType.qml b/client/ui/qml/Controls2/BasicButtonType.qml index 05074fa9..d9168466 100644 --- a/client/ui/qml/Controls2/BasicButtonType.qml +++ b/client/ui/qml/Controls2/BasicButtonType.qml @@ -1,6 +1,8 @@ import QtQuick import QtQuick.Controls +import "TextTypes" + Button { id: root @@ -46,12 +48,8 @@ Button { cursorShape: Qt.PointingHandCursor } - contentItem: Text { + contentItem: ButtonTextType { anchors.fill: background - font.family: "PT Root UI VF" - font.styleName: "normal" - font.weight: 400 - font.pixelSize: 16 color: textColor text: root.text horizontalAlignment: Text.AlignHCenter diff --git a/client/ui/qml/Controls2/DividerType.qml b/client/ui/qml/Controls2/DividerType.qml index 6341807a..bf01e7a1 100644 --- a/client/ui/qml/Controls2/DividerType.qml +++ b/client/ui/qml/Controls2/DividerType.qml @@ -3,6 +3,10 @@ import QtQuick.Layouts Rectangle { Layout.fillWidth: true + + Layout.leftMargin: 16 + Layout.rightMargin: 16 + height: 1 color: "#2C2D30" } diff --git a/client/ui/qml/Controls2/DropDownType.qml b/client/ui/qml/Controls2/DropDownType.qml index 9b9c718a..85989ae6 100644 --- a/client/ui/qml/Controls2/DropDownType.qml +++ b/client/ui/qml/Controls2/DropDownType.qml @@ -146,8 +146,6 @@ Item { anchors.left: parent.left anchors.right: parent.right anchors.topMargin: 16 - anchors.leftMargin: 16 - anchors.rightMargin: 16 BackButtonType { backButtonImage: root.headerBackButtonImage diff --git a/client/ui/qml/Controls2/TextTypes/ButtonTextType.qml b/client/ui/qml/Controls2/TextTypes/ButtonTextType.qml index d26594d6..e3b14e63 100644 --- a/client/ui/qml/Controls2/TextTypes/ButtonTextType.qml +++ b/client/ui/qml/Controls2/TextTypes/ButtonTextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 24 + lineHeight: 24 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 16 - font.weight: Font.Medium + font.weight: 500 font.family: "PT Root UI VF" wrapMode: Text.WordWrap diff --git a/client/ui/qml/Controls2/TextTypes/CaptionTextType.qml b/client/ui/qml/Controls2/TextTypes/CaptionTextType.qml index 15cc96c1..b9e41da2 100644 --- a/client/ui/qml/Controls2/TextTypes/CaptionTextType.qml +++ b/client/ui/qml/Controls2/TextTypes/CaptionTextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 16 + lineHeight: 16 + lineHeightMode: Text.FixedHeight color: "#0E0E11" font.pixelSize: 13 - font.weight: Font.Normal + font.weight: 400 font.family: "PT Root UI VF" font.letterSpacing: 0.02 diff --git a/client/ui/qml/Controls2/TextTypes/Header1TextType.qml b/client/ui/qml/Controls2/TextTypes/Header1TextType.qml index 99addc7b..86b61d7a 100644 --- a/client/ui/qml/Controls2/TextTypes/Header1TextType.qml +++ b/client/ui/qml/Controls2/TextTypes/Header1TextType.qml @@ -1,13 +1,14 @@ import QtQuick Text { - height: 38 + lineHeight: 38 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 36 - font.weight: Font.Bold + font.weight: 700 font.family: "PT Root UI VF" - font.letterSpacing: -0.03 + font.letterSpacing: -1.08 wrapMode: Text.WordWrap } diff --git a/client/ui/qml/Controls2/TextTypes/Header2TextType.qml b/client/ui/qml/Controls2/TextTypes/Header2TextType.qml index ed96f6f1..9e2a8ae9 100644 --- a/client/ui/qml/Controls2/TextTypes/Header2TextType.qml +++ b/client/ui/qml/Controls2/TextTypes/Header2TextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 30 + lineHeight: 30 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 25 - font.weight: Font.Bold + font.weight: 700 font.family: "PT Root UI VF" wrapMode: Text.WordWrap diff --git a/client/ui/qml/Controls2/TextTypes/LabelTextType.qml b/client/ui/qml/Controls2/TextTypes/LabelTextType.qml index a2ffa18b..d47d460d 100644 --- a/client/ui/qml/Controls2/TextTypes/LabelTextType.qml +++ b/client/ui/qml/Controls2/TextTypes/LabelTextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 16 + lineHeight: 16 + lineHeightMode: Text.FixedHeight color: "#878B91" font.pixelSize: 13 - font.weight: Font.Normal + font.weight: 400 font.family: "PT Root UI VF" font.letterSpacing: 0.02 diff --git a/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml b/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml index 23069db2..30bd7900 100644 --- a/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml +++ b/client/ui/qml/Controls2/TextTypes/ListItemTitleType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 21.6 + lineHeight: 21.6 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 18 - font.weight: Font.Normal + font.weight: 400 font.family: "PT Root UI VF" wrapMode: Text.WordWrap diff --git a/client/ui/qml/Controls2/TextTypes/ParagraphTextType.qml b/client/ui/qml/Controls2/TextTypes/ParagraphTextType.qml index 74b155ab..a53ca67e 100644 --- a/client/ui/qml/Controls2/TextTypes/ParagraphTextType.qml +++ b/client/ui/qml/Controls2/TextTypes/ParagraphTextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 24 + lineHeight: 24 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 16 - font.weight: Font.Normal + font.weight: 400 font.family: "PT Root UI VF" wrapMode: Text.WordWrap diff --git a/client/ui/qml/Controls2/TextTypes/SmallTextType.qml b/client/ui/qml/Controls2/TextTypes/SmallTextType.qml index 96f3342d..d1b24e6a 100644 --- a/client/ui/qml/Controls2/TextTypes/SmallTextType.qml +++ b/client/ui/qml/Controls2/TextTypes/SmallTextType.qml @@ -1,11 +1,12 @@ import QtQuick Text { - height: 20 + lineHeight: 20 + lineHeightMode: Text.FixedHeight color: "#D7D8DB" font.pixelSize: 14 - font.weight: Font.Normal + font.weight: 400 font.family: "PT Root UI VF" wrapMode: Text.WordWrap diff --git a/client/ui/qml/Pages2/PageSettingsAbout.qml b/client/ui/qml/Pages2/PageSettingsAbout.qml index a1bdeb26..01b11bda 100644 --- a/client/ui/qml/Pages2/PageSettingsAbout.qml +++ b/client/ui/qml/Pages2/PageSettingsAbout.qml @@ -19,8 +19,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSettingsApplication.qml b/client/ui/qml/Pages2/PageSettingsApplication.qml index 08a5ec0d..b378a6c8 100644 --- a/client/ui/qml/Pages2/PageSettingsApplication.qml +++ b/client/ui/qml/Pages2/PageSettingsApplication.qml @@ -8,6 +8,7 @@ import "./" import "../Controls2" import "../Config" import "../Controls2/TextTypes" +import "../Components" PageType { id: root @@ -18,8 +19,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } @@ -52,10 +51,14 @@ PageType { rightImageSource: "qrc:/images/controls/chevron-right.svg" clickedFunction: function() { + selectLanguageDrawer.open() } } - DividerType {} + SelectLanguageDrawer { + id: selectLanguageDrawer + } + LabelWithButtonType { Layout.fillWidth: true diff --git a/client/ui/qml/Pages2/PageSettingsBackup.qml b/client/ui/qml/Pages2/PageSettingsBackup.qml index a5445754..ddf9f2ba 100644 --- a/client/ui/qml/Pages2/PageSettingsBackup.qml +++ b/client/ui/qml/Pages2/PageSettingsBackup.qml @@ -18,8 +18,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSettingsConnection.qml b/client/ui/qml/Pages2/PageSettingsConnection.qml index ad8524f5..1cf8a1a5 100644 --- a/client/ui/qml/Pages2/PageSettingsConnection.qml +++ b/client/ui/qml/Pages2/PageSettingsConnection.qml @@ -17,8 +17,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSettingsDns.qml b/client/ui/qml/Pages2/PageSettingsDns.qml index 1c989c0c..c51f9092 100644 --- a/client/ui/qml/Pages2/PageSettingsDns.qml +++ b/client/ui/qml/Pages2/PageSettingsDns.qml @@ -18,8 +18,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSettingsServerInfo.qml b/client/ui/qml/Pages2/PageSettingsServerInfo.qml index aa882aa5..7b6dce68 100644 --- a/client/ui/qml/Pages2/PageSettingsServerInfo.qml +++ b/client/ui/qml/Pages2/PageSettingsServerInfo.qml @@ -42,14 +42,14 @@ PageType { id: content Layout.topMargin: 20 - Layout.leftMargin: 16 - Layout.rightMargin: 16 BackButtonType { } HeaderType { Layout.fillWidth: true + Layout.leftMargin: 16 + Layout.rightMargin: 16 actionButtonImage: "qrc:/images/controls/edit-3.svg" diff --git a/client/ui/qml/Pages2/PageSettingsServersList.qml b/client/ui/qml/Pages2/PageSettingsServersList.qml index 7f2b1688..4c6a9839 100644 --- a/client/ui/qml/Pages2/PageSettingsServersList.qml +++ b/client/ui/qml/Pages2/PageSettingsServersList.qml @@ -25,14 +25,14 @@ PageType { anchors.right: parent.right anchors.topMargin: 20 - anchors.leftMargin: 16 - anchors.rightMargin: 16 BackButtonType { } HeaderType { Layout.fillWidth: true + Layout.leftMargin: 16 + Layout.rightMargin: 16 actionButtonImage: "qrc:/images/controls/plus.svg" diff --git a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml index 2ef38067..45e4c29c 100644 --- a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml +++ b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml @@ -26,19 +26,18 @@ PageType { anchors.left: parent.left anchors.right: parent.right + spacing: 0 + BackButtonType { Layout.topMargin: 20 - Layout.rightMargin: 16 - Layout.leftMargin: 16 } HeaderType { Layout.fillWidth: true - Layout.topMargin: 20 + Layout.topMargin: 8 Layout.rightMargin: 16 Layout.leftMargin: 16 - headerText: "Подключение к серверу" descriptionText: "Не используйте код подключения из публичных источников. Его могли создать, чтобы перехватывать ваши данные.\n Всё в порядке, если код передал друг." @@ -46,7 +45,7 @@ PageType { Header2TextType { Layout.fillWidth: true - Layout.topMargin: 32 + Layout.topMargin: 48 Layout.rightMargin: 16 Layout.leftMargin: 16 diff --git a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml index 5a2f7d88..487bdbde 100644 --- a/client/ui/qml/Pages2/PageSetupWizardCredentials.qml +++ b/client/ui/qml/Pages2/PageSetupWizardCredentials.qml @@ -18,8 +18,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSetupWizardEasy.qml b/client/ui/qml/Pages2/PageSetupWizardEasy.qml index 19f06d5f..2a6e1909 100644 --- a/client/ui/qml/Pages2/PageSetupWizardEasy.qml +++ b/client/ui/qml/Pages2/PageSetupWizardEasy.qml @@ -36,8 +36,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml index 5ca75f6f..e593393c 100644 --- a/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml +++ b/client/ui/qml/Pages2/PageSetupWizardProtocolSettings.qml @@ -63,6 +63,8 @@ PageType { id: backButton Layout.topMargin: 20 + Layout.rightMargin: -16 + Layout.leftMargin: -16 } HeaderType { @@ -107,8 +109,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 16 backButtonFunction: function() { diff --git a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml index 527df830..edc443d4 100644 --- a/client/ui/qml/Pages2/PageSetupWizardProtocols.qml +++ b/client/ui/qml/Pages2/PageSetupWizardProtocols.qml @@ -42,8 +42,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 spacing: 16 @@ -52,11 +50,23 @@ PageType { width: parent.width } - HeaderType { + Item { width: parent.width + height: header.implicitHeight - headerText: "Протокол подключения" - descriptionText: "Выберите более приоритетный для вас. Позже можно будет установить остальные протоколы и доп сервисы, вроде DNS-прокси и SFTP." + HeaderType { + id: header + + anchors.fill: parent + + anchors.leftMargin: 16 + anchors.rightMargin: 16 + + width: parent.width + + headerText: "Протокол подключения" + descriptionText: "Выберите более приоритетный для вас. Позже можно будет установить остальные протоколы и доп сервисы, вроде DNS-прокси и SFTP." + } } ListView { @@ -78,8 +88,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: -16 - anchors.leftMargin: -16 LabelWithButtonType { id: container diff --git a/client/ui/qml/Pages2/PageSetupWizardStart.qml b/client/ui/qml/Pages2/PageSetupWizardStart.qml index ad91303e..78ccfa95 100644 --- a/client/ui/qml/Pages2/PageSetupWizardStart.qml +++ b/client/ui/qml/Pages2/PageSetupWizardStart.qml @@ -34,6 +34,7 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right + spacing: 0 Image { id: image diff --git a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml index d7dbf43d..504645d1 100644 --- a/client/ui/qml/Pages2/PageSetupWizardTextKey.qml +++ b/client/ui/qml/Pages2/PageSetupWizardTextKey.qml @@ -24,8 +24,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 spacing: 16 @@ -35,6 +33,8 @@ PageType { HeaderType { Layout.fillWidth: true + Layout.rightMargin: 16 + Layout.leftMargin: 16 headerText: qsTr("Connection key") descriptionText: qsTr("A line that starts with vpn://...") @@ -45,6 +45,8 @@ PageType { Layout.fillWidth: true Layout.topMargin: 32 + Layout.rightMargin: 16 + Layout.leftMargin: 16 headerText: qsTr("Key") textFieldPlaceholderText: "vpn://" diff --git a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml index c7b774b4..e1b93302 100644 --- a/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml +++ b/client/ui/qml/Pages2/PageSetupWizardViewConfig.qml @@ -42,8 +42,6 @@ PageType { anchors.top: parent.top anchors.left: parent.left anchors.right: parent.right - anchors.rightMargin: 16 - anchors.leftMargin: 16 anchors.topMargin: 20 } diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml index 1e3d02e8..7f567b8d 100644 --- a/client/ui/qml/Pages2/PageShare.qml +++ b/client/ui/qml/Pages2/PageShare.qml @@ -185,8 +185,6 @@ PageType { anchors.left: parent.left anchors.right: parent.right anchors.topMargin: 16 - anchors.leftMargin: 16 - anchors.rightMargin: 16 BackButtonType { backButtonImage: "qrc:/images/controls/arrow-left.svg"