Compare commits

..

29 Commits

Author SHA1 Message Date
Andrey Zaharow 6572b83a97 Revert minor fixes 2024-02-26 17:33:27 +01:00
Andrey Zaharow 7aa4b54196 UI fixes 2024-02-24 23:42:38 +01:00
pokamest 13aadbda64 Merge pull request #637 from amnezia-vpn/bugfix/connection-drawer-close-button
fixed connection drawer close button
2024-02-23 09:56:52 -08:00
agalehaga c7c7c8eb01 added export awg native format (#635)
add export awg native format
2024-02-23 17:55:59 +00:00
vladimir.kuznetsov b1e5bba33f fixed connection drawer close button 2024-02-23 22:51:46 +05:00
pokamest 474e7c6d62 Merge pull request #634 from amnezia-vpn/update/gh_actions_qt_update
Update Qt in deploy.yml
2024-02-22 06:02:04 -08:00
pokamest 794ec921b8 Update Qt in deploy.yml 2024-02-22 13:28:37 +00:00
pokamest b674240362 Merge pull request #632 from amnezia-vpn/refactoring/changing-settings-item-location
moving settings item to other settings page
2024-02-22 05:02:13 -08:00
pokamest a768c7c451 Merge pull request #633 from rodionos/patch-1
MacOS build: increase image size to 256Mb
2024-02-22 04:58:21 -08:00
Sergei Rodionov 28d2a4ec2c MacOS build: increase image size to 256Mb
In my case, using Qt 6.6.2, the size of the AmneziaVPN.dmg file is 226Mb so a higher image size is needed for the hdiutil command.
2024-02-22 13:57:58 +03:00
Shehab Ahmed 9f1210d18f changed the location of Auto connect item from settings connections page to settings application page 2024-02-22 02:31:51 +02:00
pokamest 3012559627 Merge pull request #630 from amnezia-vpn/feature/api-containers-listview
for api servers, removed the ability to select a container
2024-02-21 11:03:18 -08:00
vladimir.kuznetsov b3ed57aee7 for api servers, removed the ability to select a container 2024-02-21 23:41:47 +05:00
pokamest 89d0a8107d Merge pull request #620 from amnezia-vpn/translations/fix-for-pr618
Fix translation for #618
2024-02-21 06:03:12 -08:00
Andrey Zaharow 6c0b71bd1b Fix translation on About Page (#618)
Fix About Page
2024-02-21 14:01:53 +00:00
Nethius 61abf74b2d feature/page-home-split-tunneling (#540)
Added split tunneling button on home page
2024-02-21 11:27:27 +00:00
pokamest 21fdf02921 Merge pull request #625 from amnezia-vpn/bugfix/default-server-default-container-update
fixed the use of defaultServerDefaultContainerChanged
2024-02-21 03:22:09 -08:00
vladimir.kuznetsov 7a245d80ee fixed the use of defaultServerDefaultContainerChanged 2024-02-21 13:06:39 +05:00
KsZnak da85922f23 Update amneziavpn_zh_CN.ts (#617)
Update amneziavpn_zh_CN.ts
2024-02-20 20:49:26 +00:00
pokamest a5356b6319 Merge pull request #623 from amnezia-vpn/update/Arabic-translation
updated the Arabic translation for fixing some sentences
2024-02-20 12:47:41 -08:00
KsZnak 3828891b9b Update amneziavpn_fa_IR.ts (#622)
Update amneziavpn_fa_IR.ts
2024-02-20 20:46:23 +00:00
pokamest 15d866ce04 WG/AWG ipv6 fix (#621)
WG/AWG ipv6 fix
2024-02-20 19:05:36 +00:00
Shehab Ahmed 560eb3d620 updated the Arabic translation for fixing some sentences 2024-02-20 20:37:19 +02:00
Andrey Zaharow ac894254cc Fix translation for #618 2024-02-20 00:23:20 +01:00
pokamest 17e3fbde25 Merge pull request #616 from amnezia-vpn/bugfix/cursor-changing-fix
Fix cursor change when hover over elements
2024-02-19 12:20:46 -08:00
Andrey Zaharow ee11a8410c Fix cursor change when hover over elements 2024-02-19 18:28:29 +01:00
pokamest ff5c51cfd9 Merge pull request #615 from amnezia-vpn/KsZnak-patch-1
Update amneziavpn_ru.ts
2024-02-19 07:10:49 -08:00
Nethius b3943ae5e3 serversModel cleanup (#599) 2024-02-19 14:54:15 +00:00
KsZnak dc9069f1f4 Update_2_amneziavpn_ru.ts
Add new change
2024-02-19 13:37:40 +02:00
54 changed files with 759 additions and 412 deletions
+7 -7
View File
@@ -14,8 +14,8 @@ jobs:
runs-on: ubuntu-20.04
env:
QT_VERSION: 6.5.1
QIF_VERSION: 4.6
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
steps:
- name: 'Install Qt'
@@ -72,8 +72,8 @@ jobs:
runs-on: windows-latest
env:
QT_VERSION: 6.5.1
QIF_VERSION: 4.6
QT_VERSION: 6.6.2
QIF_VERSION: 4.7
BUILD_ARCH: 64
steps:
@@ -134,7 +134,7 @@ jobs:
runs-on: macos-13
env:
QT_VERSION: 6.5.2
QT_VERSION: 6.6.2
CC: cc
CXX: c++
@@ -227,7 +227,7 @@ jobs:
env:
# Keep compat with MacOS 10.15 aka Catalina by Qt 6.4
QT_VERSION: 6.4.3
QIF_VERSION: 4.6
QIF_VERSION: 4.7
steps:
- name: 'Setup xcode'
@@ -286,7 +286,7 @@ jobs:
env:
ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.6.1
QT_VERSION: 6.6.2
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
steps:
+3
View File
@@ -131,3 +131,6 @@ client/3rd/ShadowSocks/ss_ios.xcconfig
# UML generated pics
out/
# CMake files
CMakeFiles/
+9
View File
@@ -15,6 +15,15 @@ set(PACKAGES
Core5Compat Concurrent LinguistTools
)
execute_process(
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
COMMAND git rev-parse --short HEAD
OUTPUT_VARIABLE GIT_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE
)
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
if(IOS)
set(PACKAGES ${PACKAGES} Multimedia)
endif()
+7 -1
View File
@@ -286,10 +286,16 @@ void AmneziaApplication::initModels()
m_containersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get());
m_defaultServerContainersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("DefaultServerContainersModel", m_defaultServerContainersModel.get());
m_serversModel.reset(new ServersModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(),
&ContainersModel::updateModel);
connect(m_serversModel.get(), &ServersModel::defaultServerContainersUpdated, m_defaultServerContainersModel.get(),
&ContainersModel::updateModel);
m_serversModel->resetModel();
m_languageModel.reset(new LanguageModel(m_settings, this));
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
@@ -333,7 +339,7 @@ void AmneziaApplication::initModels()
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this,
[this](const QString &clientId, const QString &clientName, const DockerContainer container,
ServerCredentials credentials) {
m_serversModel->reloadContainerConfig();
m_serversModel->reloadDefaultServerContainerConfig();
m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
emit m_configurator->clientModelUpdated();
});
+1
View File
@@ -92,6 +92,7 @@ private:
QCommandLineParser m_parser;
QSharedPointer<ContainersModel> m_containersModel;
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<LanguageModel> m_languageModel;
QSharedPointer<ProtocolsModel> m_protocolsModel;
@@ -0,0 +1,6 @@
<svg width="19" height="18" viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect x="0.5" width="18" height="18" rx="5" fill="white"/>
<path d="M8.49219 13.5L8.49219 9.44141L14.0191 4.99484" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M4.47363 5.49805L6.98828 8.0127" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M14.4727 9.5L14.4727 4.5033L9.50195 4.5033" stroke="#0E0E11" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 511 B

+3
View File
@@ -124,7 +124,10 @@ void LocalSocketController::activate(const QJsonObject &rawConfig) {
// json.insert("hopindex", QJsonValue((double)hop.m_hopindex));
json.insert("privateKey", wgConfig.value(amnezia::config_key::client_priv_key));
json.insert("deviceIpv4Address", wgConfig.value(amnezia::config_key::client_ip));
// todo review wg ipv6
#ifndef Q_OS_WINDOWS
json.insert("deviceIpv6Address", "dead::1");
#endif
json.insert("serverPublicKey", wgConfig.value(amnezia::config_key::server_pub_key));
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
+3
View File
@@ -224,6 +224,9 @@
<file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file>
<file>images/controls/search.svg</file>
<file>ui/qml/Components/HomeSplitTunnelingDrawer.qml</file>
<file>images/controls/split-tunneling.svg</file>
<file>ui/qml/Controls2/DrawerType2.qml</file>
<file>ui/qml/Components/FadeBehavior.qml</file>
</qresource>
</RCC>
+9 -8
View File
@@ -997,6 +997,11 @@ And if you don&apos;t like the app, all the more support it - the donation will
<source>https://amnezia.org</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>%1 :إصدار البرنامج</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source>
@@ -1139,7 +1144,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="122"/>
<source>Restore from backup</source>
<translation>استرجاع من ملف احتياطي</translation>
<translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="125"/>
@@ -1339,7 +1344,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="128"/>
<source>Save logs to file</source>
<translation>احفظ السجلات لملف</translation>
<translation>احفظ السجلات في ملف</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="146"/>
@@ -1942,7 +1947,8 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="40"/>
<source>A line that starts with vpn://...</source>
<translation>سطر يبدأ ب vpn://...</translation>
<translatorcomment>يجب ان تٌكتب بهذه الطريقة حتي بوجود الخطأ كي تظهر بشكل صحيح داخل التطبيق</translatorcomment>
<translation>سطر يبدأ ب ...//:vpn</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="51"/>
@@ -2998,11 +3004,6 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
</context>
<context>
<name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="31"/>
<source>Software version</source>
<translation>إصدار البرنامج</translation>
</message>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="139"/>
<source>Backup file is corrupted</source>
+63 -47
View File
@@ -144,7 +144,7 @@
</message>
<message>
<source>Reconnect via VPN Procotol: </source>
<translation type="vanished">Переподключение через VPN протокол: </translation>
<translation type="vanished">پروتکل VPN را متصل مجدد کنید" </translation>
</message>
</context>
<context>
@@ -371,7 +371,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation>
<translation type="vanished">همه کاربرانی که با آن‌ها این پروتکل VPN را به اشتراک گذاشته‌اید دیگر نمی‌توانند به آن متصل شوند.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="280"/>
@@ -604,7 +604,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation>
<translation type="vanished">همه کاربرانی که با آن این پروتکل VPN را به اشتراک گذاشته‌اید دیگر نمی‌توانند به آن متصل شوند.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolOpenVpnSettings.qml" line="369"/>
@@ -656,7 +656,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="obsolete">Все пользователи, с которыми вы поделились этим VPN-протоколом, больше не смогут к нему подключаться.</translation>
<translation type="obsolete">همه کاربرانی که با آن این پروتکل VPN را به اشتراک گذاشته‌اید دیگر نمی‌توانند به آن متصل شوند.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolRaw.qml" line="180"/>
@@ -697,7 +697,7 @@ Already installed containers were found on the server. All installed containers
<name>PageServerContainers</name>
<message>
<source>Continue</source>
<translation type="obsolete">Продолжить</translation>
<translation type="obsolete">ادامه دهید</translation>
</message>
</context>
<context>
@@ -847,13 +847,13 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="94"/>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL.</source>
<translation type="unfinished"></translation>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL. </source>
<translation>استفاده &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; برای باز کردن این نشانی.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/>
<source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source>
<translation type="unfinished"></translation>
<translation>پس از ایجاد سایت پیاز خود، چند دقیقه طول می‌کشد تا شبکه تور آن را برای استفاده فراهم کند.</translation>
</message>
<message>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this url.</source>
@@ -870,7 +870,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<source>When configuring WordPress set the this address as domain.</source>
<translation type="vanished">При настройке WordPress укажите этот onion адрес в качестве домена.</translation>
<translation type="vanished">هنگام تنظیم وردپرس، این آدرس پیاز را به عنوان دامنه مشخص کنید.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="126"/>
@@ -940,7 +940,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source>
<translation type="unfinished"></translation>
<translation>پشتیبانی از Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1022,6 +1022,11 @@ Already installed containers were found on the server. All installed containers
<source>https://amnezia.org</source>
<translation>https://amnezia.org</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>%1 :نسخه نرم‎افزار</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source>
@@ -1215,7 +1220,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/>
<source>When AmneziaDNS is not used or installed</source>
<translation type="unfinished"></translation>
<translation>وقتی AmneziaDNS استفاده نشده یا نصب نشده است.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/>
@@ -1251,7 +1256,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="35"/>
<source>Default server does not support custom dns</source>
<translation type="unfinished"></translation>
<translation>سرور پیش‌فرض از دی‌ان‌اس سفارشی پشتیبانی نمی‌کند.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="53"/>
@@ -1433,27 +1438,27 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/>
<source>Reboot server</source>
<translation type="unfinished"></translation>
<translation>سرور را دوباره راه‌اندازی کنید.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/>
<source>Do you want to reboot the server?</source>
<translation type="unfinished"></translation>
<translation>آیا می‌خواهید سرور را دوباره راه‌اندازی کنید؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/>
<source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source>
<translation type="unfinished"></translation>
<translation>فرآیند راه‌اندازی ممکن است حدود ۳۰ ثانیه طول بکشد. آیا مطمئن هستید که می‌خواهید ادامه دهید؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/>
<source>Do you want to remove the server from application?</source>
<translation type="unfinished"></translation>
<translation>آیا می‌خواهید سرور را از برنامه حذف کنید؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/>
<source>Do you want to clear server from Amnezia software?</source>
<translation type="unfinished"></translation>
<translation>آیا می‌خواهید سرور را از نرم‌افزار Amnezia پاک کنید؟</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/>
@@ -1536,7 +1541,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<source>All users who you shared a connection with will no longer be able to connect to it.</source>
<translation type="vanished">Все пользователи, которым вы поделились VPN, больше не смогут к нему подключаться.</translation>
<translation type="vanished">تمام کاربرانی که با آن VPN را به اشتراک گذاشته‌اید، دیگر نمی‌توانند به آن متصل شوند.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerProtocol.qml" line="118"/>
@@ -1562,7 +1567,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="29"/>
<source>Default server does not support split tunneling function</source>
<translation type="unfinished"></translation>
<translation>سرور پیش‌فرض از عملکرد تونل‌سازی تقسیم شده پشتیبانی نمی‌کند.</translation>
</message>
<message>
<source>Addresses from the list should be accessed via VPN</source>
@@ -1609,17 +1614,17 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/>
<source>Only the sites listed here will be accessed through the VPN</source>
<translation type="unfinished"></translation>
<translation>تنها سایت‌های موجود در اینجا از طریق VPN دسترسی داده خواهند شد.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/>
<source>website or IP</source>
<translation type="unfinished"></translation>
<translation>وب‌سایت یا آدرس IP</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/>
<source>Import / Export Sites</source>
<translation type="unfinished"></translation>
<translation>وارد کردن / صادر کردن وب‌سایت‌ها</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/>
@@ -1716,7 +1721,7 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<name>PageSetupWizardCredentials</name>
<message>
<source>Server connection</source>
<translation type="vanished">Подключение к серверу</translation>
<translation type="vanished">اتصال به سرور</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardCredentials.qml" line="51"/>
@@ -1823,12 +1828,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<translation>سرور در حال حاضر به نرم‎افزار اضافه شده است</translation>
</message>
<message>
<source>Amnesia has detected that your server is currently </source>
<translation type="vanished">Amnesia обнаружила, что ваш сервер в настоящее время </translation>
<source>Amnezia has detected that your server is currently </source>
<translation type="vanished">Amnezia has detected that your server is currently </translation>
</message>
<message>
<source>busy installing other software. Amnesia installation </source>
<translation type="vanished">занят установкой других протоколов или сервисов. Установка Amnesia </translation>
<source>busy installing other software. Amnezia installation </source>
<translation type="vanished">busy installing other software. Amnezia installation</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSetupWizardInstalling.qml" line="67"/>
@@ -2019,7 +2024,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
</message>
<message>
<source>VPN Access</source>
<translation type="vanished">VPN-Доступ</translation>
<translation type="vanished">دسترسی VPN</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="220"/>
@@ -2028,11 +2033,11 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
</message>
<message>
<source>VPN access without the ability to manage the server</source>
<translation type="vanished">Доступ к VPN, без возможности управления сервером</translation>
<translation type="vanished">دسترسی به VPN بدون امکان مدیریت سرور</translation>
</message>
<message>
<source>Access to server management. The user with whom you share full access to the connection will be able to add and remove your protocols and services to the server, as well as change settings.</source>
<translation type="vanished">Доступ к управлению сервером. Пользователь, с которым вы делитесь полным доступом к соединению, сможет добавлять и удалять ваши протоколы и службы на сервере, а также изменять настройки.</translation>
<translation type="vanished">دسترسی به مدیریت سرور. کاربری که با او دسترسی کامل به اتصال را به اشتراک می‌گذارید، می‌تواند پروتکل‌ها و سرویس‌های شما را در سرور اضافه و حذف کند، همچنین تنظیمات را تغییر دهد.</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="280"/>
@@ -2132,7 +2137,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="584"/>
<source>Creation date: </source>
<translation type="unfinished"></translation>
<translation>تاریخ ایجاد:</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="598"/>
@@ -2157,7 +2162,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="671"/>
<source>Revoke the config for a user - %1?</source>
<translation type="unfinished"></translation>
<translation> لغو پیکربندی برای یک کاربر %1؟</translation>
</message>
<message>
<source>Revoke the config for a user - </source>
@@ -2732,17 +2737,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../containers/containers_defs.cpp" line="101"/>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="unfinished"></translation>
<translation>شدوساکس - ترافیک VPN را پنهان می کند، به طوری که مشابه ترافیک وب عادی می شود، اما ممکن است توسط سیستم های تجزیه و تحلیل در برخی از مناطق با سانسور شدید شناسایی شود.</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="104"/>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="unfinished"></translation>
<translation>OpenVPN روی Cloak - OpenVPN با VPN که به عنوان ترافیک وب پنهان می‌شود و مقاومت در برابر تشخیص فعال از طریق پیشرفته. ایده‌آل برای دور زدن مسدود کردن در مناطق با بالاترین سطوح سانسور</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="122"/>
<source>Create a file vault on your server to securely store and transfer files.</source>
<translation type="unfinished"></translation>
<translation>ساختن یک گنجانده فایل بر روی سرور شما برای ذخیره و انتقال ایمن فایل‌ها</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="155"/>
@@ -2764,7 +2769,23 @@ If there is a extreme level of Internet censorship in your region, we advise you
* Not recognised by DPI analysis systems
* Works over TCP network protocol, 443 port.
</source>
<translation type="unfinished"></translation>
<translation>این ترکیبی از پروتکل OpenVPN و پلاگین Cloak به طور خاص برای محافظت در برابر مسدود کردن طراحی شده است.
OpenVPN ارتباط امن VPN را با رمزگذاری تمام ترافیک اینترنتی بین مشتری و سرور فراهم می‌کند.
Cloak OpenVPN را از شناسایی و مسدود کردن محافظت می‌کند.
Cloak می‌تواند اطلاعات فراداده بسته را تغییر دهد تا ترافیک VPN را به طور کامل به عنوان ترافیک وب عادی پنهان کند و همچنین VPN را از شناسایی توسط Active Probing محافظت کند. این باعث می‌شود این سیستم بسیار مقاوم در برابر شناسایی شود.
فوراً پس از دریافت اولین بسته داده، Cloak اتصال ورودی را تأیید می‌کند. اگر تأیید اعتبار ناموفق باشد، پلاگین سرور را به عنوان یک وب‌سایت جعلی پنهان می‌کند و VPN شما برای سیستم‌های تجزیه و تحلیل غیر قابل دسترسی می‌شود.
اگر در منطقه شما سطح بسیار بالایی از سانسور اینترنت وجود دارد، به شما توصیه می‌شود که از اولین اتصال فقط از OpenVPN over Cloak استفاده کنید.
در دسترس در AmneziaVPN بر روی تمام پلتفرم‌ها
مصرف بالای برق در دستگاه‌های تلفن همراه
تنظیمات انعطاف پذیر
توسط سیستم‌های تجزیه و تحلیل DPI شناخته نمی‌شود
بر روی پروتکل شبکه TCP، پورت 443 کار می‌کند.</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="174"/>
@@ -3091,11 +3112,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</context>
<context>
<name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation>نسخه نرم‎افزار</translation>
</message>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
<source>All settings have been reset to default values</source>
@@ -3233,7 +3249,7 @@ This means that AmneziaWG keeps the fast performance of the original while addin
<message>
<location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="105"/>
<source>The field can&apos;t be empty</source>
<translation>Поле не может быть пустым</translation>
<translation>این فیلد نمی‌تواند خالی باشد.</translation>
</message>
</context>
<context>
@@ -3321,23 +3337,23 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</message>
<message>
<source>High</source>
<translation type="vanished">Высокий</translation>
<translation type="vanished">بالایی</translation>
</message>
<message>
<source>Medium</source>
<translation type="vanished">Средний</translation>
<translation type="vanished">متوسط</translation>
</message>
<message>
<source>Many foreign websites and VPN providers are blocked</source>
<translation type="vanished">Многие иностранные сайты и VPN-провайдеры заблокированы</translation>
<translation type="vanished">بسیاری از وب‌سایت‌ها و ارائه‌دهندگان VPN خارجی مسدود شده‌اند.</translation>
</message>
<message>
<source>Some foreign sites are blocked, but VPN providers are not blocked</source>
<translation type="vanished">Некоторые иностранные сайты заблокированы, но VPN-провайдеры не блокируются</translation>
<translation type="vanished">بعضی از وب‌سایت‌های خارجی مسدود شده‌اند، اما ارائه‌دهندگان VPN مسدود نمی‌شوند.</translation>
</message>
<message>
<source>I just want to increase the level of privacy</source>
<translation type="vanished">Хочу просто повысить уровень приватности</translation>
<translation type="vanished">من فقط می‌خواهم سطح حریم خصوصی خود را افزایش دهم.</translation>
</message>
</context>
<context>
+8 -8
View File
@@ -938,7 +938,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source>
<translation type="unfinished"></translation>
<translation type="unfinished">Поддержите Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1020,6 +1020,11 @@ Already installed containers were found on the server. All installed containers
<source>https://amnezia.org</source>
<translation>https://amnezia.org</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>Версия ПО: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source>
@@ -1202,7 +1207,7 @@ Already installed containers were found on the server. All installed containers
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="70"/>
<source>When AmneziaDNS is installed on the server</source>
<source>If AmneziaDNS is installed on the server</source>
<translation>Если он уставновлен на сервере</translation>
</message>
<message>
@@ -2808,7 +2813,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<translation>OpenVPN - популярный VPN-протокол, с гибкой настройкой. Имеет собственный протокол безопасности с SSL/TLS для обмена ключами.</translation>
</message>
<message>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognised by analysis systems in some highly censored regions.</source>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="vanished">ShadowSocks - маскирует VPN-трафик под обычный веб-трафик, но распознается системами анализа в некоторых регионах с высоким уровнем цензуры.</translation>
</message>
<message>
@@ -3058,11 +3063,6 @@ This means that AmneziaWG keeps the fast performance of the original while addin
</context>
<context>
<name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation>Версия ПО</translation>
</message>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="148"/>
<source>All settings have been reset to default values</source>
+48 -40
View File
@@ -200,7 +200,7 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/controllers/installController.cpp" line="305"/>
<source>Server &apos;%1&apos; was rebooted</source>
<translation type="unfinished"></translation>
<translation type="unfinished">服务器 &apos;%1&apos; 已重新启动</translation>
</message>
<message>
<location filename="../ui/controllers/installController.cpp" line="314"/>
@@ -891,10 +891,10 @@ Already installed containers were found on the server. All installed containers
<message>
<location filename="../ui/qml/Pages2/PageServiceTorWebsiteSettings.qml" line="103"/>
<source>After creating your onion site, it takes a few minutes for the Tor network to make it available for use.</source>
<translation type="unfinished"></translation>
<translation>创建您的洋葱网站后,需要几分钟时间,才能使其在Tor网络上可用</translation>
</message>
<message>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this url.</source>
<source>Use &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor Browser&lt;/a&gt; to open this URL.</source>
<translation type="vanished">用 &lt;a href=&quot;https://www.torproject.org/download/&quot; style=&quot;color: #FBB26A;&quot;&gt;Tor 浏览器&lt;/a&gt; 打开上面网址</translation>
</message>
<message>
@@ -984,7 +984,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="56"/>
<source>Support Amnezia</source>
<translation type="unfinished"></translation>
<translation>支持Amnezia</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="71"/>
@@ -1067,6 +1067,11 @@ And if you don&apos;t like the app, all the more support it - the donation will
<source>https://amnezia.org</source>
<translation></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="176"/>
<source>Software version: %1</source>
<translation>软件版本: %1</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="192"/>
<source>Check for updates</source>
@@ -1261,7 +1266,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/>
<source>When AmneziaDNS is not used or installed</source>
<translation type="unfinished"></translation>
<translation>当未使用或未安装AmneziaDNS时</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/>
@@ -1479,12 +1484,12 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="143"/>
<source>Do you want to reboot the server?</source>
<translation type="unfinished"></translation>
<translation type="unfinished">您想重新启动服务器吗?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="206"/>
<source>Do you want to clear server from Amnezia software?</source>
<translation type="unfinished"></translation>
<translation>您要清除服务器上的Amnezia软件吗?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="92"/>
@@ -1520,12 +1525,12 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="139"/>
<source>Reboot server</source>
<translation type="unfinished"></translation>
<translation>重新启动服务器</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="144"/>
<source>The reboot process may take approximately 30 seconds. Are you sure you wish to proceed?</source>
<translation type="unfinished"></translation>
<translation> 重新启动过程可能需要大约30秒。您确定要继续吗?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="171"/>
@@ -1535,7 +1540,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsServerData.qml" line="175"/>
<source>Do you want to remove the server from application?</source>
<translation type="unfinished"></translation>
<translation type="unfinished">您想要从应用程序中移除服务器吗?</translation>
</message>
<message>
<source>Remove server?</source>
@@ -1706,17 +1711,17 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="59"/>
<source>Only the sites listed here will be accessed through the VPN</source>
<translation type="unfinished"></translation>
<translation>只有这里列出的网站将通过VPN访问</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/>
<source>website or IP</source>
<translation type="unfinished"></translation>
<translation>网站或IP</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="298"/>
<source>Import / Export Sites</source>
<translation type="unfinished"></translation>
<translation>导入/导出网站</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="304"/>
@@ -2138,12 +2143,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="120"/>
<source>ShadowSocks native format</source>
<translation type="unfinished"></translation>
<translation>ShadowSocks原生格式</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="125"/>
<source>Cloak native format</source>
<translation type="unfinished"></translation>
<translation>Cloak原生格式</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="150"/>
@@ -2153,18 +2158,18 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="178"/>
<source>Share full access to the server and VPN</source>
<translation type="unfinished"></translation>
<translation>共享服务器和VPN的完全访问权限</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="179"/>
<source>Use for your own devices, or share with those you trust to manage the server.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">用于您自己的设备,或与您信任的人共享以管理服务器</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="231"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="486"/>
<source>Users</source>
<translation type="unfinished"></translation>
<translation>用户</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="251"/>
@@ -2199,17 +2204,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="668"/>
<source>Revoke</source>
<translation type="unfinished"></translation>
<translation>撤销</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="671"/>
<source>Revoke the config for a user - %1?</source>
<translation type="unfinished"></translation>
<translation>撤销用户的配置- %1?</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="672"/>
<source>The user will no longer be able to connect to your server.</source>
<translation type="unfinished"></translation>
<translation type="unfinished">该用户将无法再连接到您的服务器</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="673"/>
@@ -2295,12 +2300,12 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="34"/>
<source>Config revoked</source>
<translation type="unfinished"></translation>
<translation>配置已撤销</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="262"/>
<source>User name</source>
<translation type="unfinished"></translation>
<translation>用户名</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="429"/>
@@ -2320,7 +2325,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="49"/>
<source>Full access to the server and VPN</source>
<translation type="unfinished"></translation>
<translation>对服务器和VPN的完全访问权限</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="57"/>
@@ -2331,7 +2336,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="58"/>
<source>If you share full access with other people, they can remove and add protocols and services to the server, which will cause the VPN to work incorrectly for all users. </source>
<translation type="unfinished"></translation>
<translation>如果您与其他人共享完全访问权限,他们可以从服务器中删除和添加协议和服务,这将导致VPN对所有用户的工作出现问题。</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShareFullAccess.qml" line="73"/>
@@ -2822,7 +2827,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../core/errorstrings.cpp" line="62"/>
<source>The config does not contain any containers and credentials for connecting to the server</source>
<translation type="unfinished"></translation>
<translation>配置不包含任何用于连接服务器的容器和凭据</translation>
</message>
<message>
<source>The config does not contain any containers and credentiaks for connecting to the server</source>
@@ -2831,7 +2836,7 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../core/errorstrings.cpp" line="69"/>
<source>Internal error</source>
<translation>内部错误</translation>
<translation></translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="88"/>
@@ -2862,17 +2867,17 @@ and will not be shared or disclosed to the Amnezia or any third parties</source>
<message>
<location filename="../containers/containers_defs.cpp" line="101"/>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but it may be recognized by analysis systems in some highly censored regions.</source>
<translation type="unfinished"></translation>
<translation>ShadowSocks - 掩盖VPN流量,使其类似于正常的网络流量,但在一些高度审查的地区可能会被分析系统识别</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="104"/>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="unfinished"></translation>
<source>OpenVPN over Cloak - OpenVPN with masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="unfinished">OpenVPN over Cloak - OpenVPN与VPN结合,伪装成Web流量,并保护免受主动探测的侦测。非常适合在具有最高审查水平的地区绕过封锁</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="122"/>
<source>Create a file vault on your server to securely store and transfer files.</source>
<translation type="unfinished"></translation>
<translation>在您的服务器上创建一个文件保险库,用于安全存储和传输文件。</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="155"/>
@@ -2907,15 +2912,23 @@ WireGuard is very susceptible to blocking due to its distinct packet signatures.
* Minimum number of settings
* Easily recognised by DPI analysis systems, susceptible to blocking
* Works over UDP network protocol.</source>
<translation type="unfinished"></translation>
<translation>一个相对较新的流行VPN协议,具有简化的架构。
WireGuard提供稳定的VPN连接,并在所有设备上具有高性能。它使用硬编码的加密设置。与OpenVPN相比,WireGuard具有较低的延迟和更好的数据传输吞吐量。
WireGuard非常容易被阻挡,因为其独特的数据包签名。与一些其他VPN协议不同,这些协议使用混淆技术,WireGuard数据包的一致签名模式更容易被高级深度数据包检测(DPI)系统和其他网络监控工具识别和阻挡。
在AmneziaVPN上适用于所有平台
低功耗
最少的设置
易于被DPI分析系统识别,容易被阻挡
通过UDP网络协议运行。</translation>
</message>
<message>
<source>ShadowSocks - masks VPN traffic, making it similar to normal web traffic, but is recognised by analysis systems in some highly censored regions.</source>
<translation type="vanished">ShadowSocks - 混淆 VPN 流量,使其与正常的 Web 流量相似,但在一些审查力度高的地区可以被分析系统识别。</translation>
</message>
<message>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probbing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="vanished">OpenVPN over Cloak - OpenVPN 与 VPN 具有伪装成网络流量和防止主动探测检测的保护。非常适合绕过审查力度特别强的地区的封锁。</translation>
<source>OpenVPN over Cloak - OpenVPN with VPN masquerading as web traffic and protection against active-probing detection. Ideal for bypassing blocking in regions with the highest levels of censorship.</source>
<translation type="vanished">OpenVPN over Cloak - OpenVPN与VPN结合,伪装成Web流量,并保护免受主动探测的侦测。非常适合在具有最高审查水平的地区绕过封锁</translation>
</message>
<message>
<location filename="../containers/containers_defs.cpp" line="108"/>
@@ -3198,11 +3211,6 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
</context>
<context>
<name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="27"/>
<source>Software version</source>
<translation>软件版本</translation>
</message>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="132"/>
<source>Backup file is corrupted</source>
@@ -3246,7 +3254,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="128"/>
<source>Copy config string</source>
<translation type="unfinished"></translation>
<translation>复制配置字符串</translation>
</message>
<message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="150"/>
+2 -3
View File
@@ -136,8 +136,7 @@ void ApiController::updateServerConfigFromApi()
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
serverConfig.insert(config_key::defaultContainer, defaultContainer);
m_serversModel->editServer(serverConfig);
emit m_serversModel->defaultContainerChanged(ContainerProps::containerFromString(defaultContainer));
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
} else {
qDebug() << reply->error();
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
@@ -164,5 +163,5 @@ void ApiController::clearApiConfig()
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
m_serversModel->editServer(serverConfig);
m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
}
@@ -33,7 +33,7 @@ void ConnectionController::openConnection()
int serverIndex = m_serversModel->getDefaultServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = m_serversModel->getDefaultContainer(serverIndex);
DockerContainer container = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container);
if (container == DockerContainer::None) {
@@ -61,7 +61,7 @@ void ConnectionController::onConnectionStateChanged(Vpn::ConnectionState state)
m_state = state;
m_isConnected = false;
m_connectionStateText = tr("Connection...");
m_connectionStateText = tr("Connecting...");
switch (state) {
case Vpn::ConnectionState::Connected: {
m_isConnectionInProgress = false;
+47 -7
View File
@@ -8,6 +8,7 @@
#include <QImage>
#include <QStandardPaths>
#include "configurators/awg_configurator.h"
#include "configurators/cloak_configurator.h"
#include "configurators/openvpn_configurator.h"
#include "configurators/shadowsocks_configurator.h"
@@ -45,7 +46,7 @@ void ExportController::generateFullAccessConfig()
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
QJsonObject config = m_settings->server(serverIndex);
QJsonArray containers = config.value(config_key::containers).toArray();
@@ -99,7 +100,7 @@ void ExportController::generateConnectionConfig(const QString &clientName)
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -155,7 +156,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -193,7 +194,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -228,11 +229,50 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
emit exportConfigChanged();
}
void ExportController::generateAwgConfig(const QString &clientName)
{
clearPreviousConfig();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
QJsonObject containerConfig = m_containersModel->getContainerConfig(container);
containerConfig.insert(config_key::container, ContainerProps::containerToString(container));
QString clientId;
ErrorCode errorCode = ErrorCode::NoError;
QString config = m_configurator->awgConfigurator->genAwgConfig(credentials, container, containerConfig,
clientId, &errorCode);
if (errorCode) {
emit exportErrorOccurred(errorString(errorCode));
return;
}
config = m_configurator->processConfigWithExportSettings(serverIndex, container, Proto::Awg, config);
auto configJson = QJsonDocument::fromJson(config.toUtf8()).object();
QStringList lines = configJson.value(config_key::config).toString().replace("\r", "").split("\n");
for (const QString &line : lines) {
m_config.append(line + "\n");
}
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(m_config.toUtf8(), qrcodegen::QrCode::Ecc::LOW);
m_qrCodes << svgToBase64(QString::fromStdString(toSvgString(qr, 1)));
errorCode = m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
if (errorCode) {
emit exportErrorOccurred(errorString(errorCode));
return;
}
emit exportConfigChanged();
}
void ExportController::generateShadowSocksConfig()
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -268,7 +308,7 @@ void ExportController::generateCloakConfig()
{
clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -328,7 +368,7 @@ void ExportController::updateClientManagementModel(const DockerContainer contain
void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
{
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials,
m_serversModel->getCurrentlyProcessedServerIndex());
m_serversModel->getProcessedServerIndex());
if (errorCode != ErrorCode::NoError) {
emit exportErrorOccurred(errorString(errorCode));
}
+1
View File
@@ -34,6 +34,7 @@ public slots:
void generateConnectionConfig(const QString &clientName);
void generateOpenVpnConfig(const QString &clientName);
void generateWireGuardConfig(const QString &clientName);
void generateAwgConfig(const QString &clientName);
void generateShadowSocksConfig();
void generateCloakConfig();
+14 -14
View File
@@ -176,7 +176,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
void InstallController::installContainer(DockerContainer container, QJsonObject &config)
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -238,7 +238,7 @@ bool InstallController::isServerAlreadyExists()
void InstallController::scanServerForInstalledContainers()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -267,7 +267,7 @@ void InstallController::scanServerForInstalledContainers()
void InstallController::updateContainer(QJsonObject config)
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -283,8 +283,8 @@ void InstallController::updateContainer(QJsonObject config)
m_serversModel->updateContainerConfig(container, config);
m_protocolModel->updateModel(config);
if ((serverIndex == m_serversModel->getDefaultServerIndex())
&& (container == m_serversModel->getDefaultContainer(serverIndex))) {
auto defaultContainer = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
if ((serverIndex == m_serversModel->getDefaultServerIndex()) && (container == defaultContainer)) {
emit currentContainerUpdated();
} else {
emit updateContainerFinished(tr("Settings updated successfully"));
@@ -296,27 +296,27 @@ void InstallController::updateContainer(QJsonObject config)
emit installationErrorOccurred(errorString(errorCode));
}
void InstallController::rebootCurrentlyProcessedServer()
void InstallController::rebootProcessedServer()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->rebootServer();
emit rebootCurrentlyProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
emit rebootProcessedServerFinished(tr("Server '%1' was rebooted").arg(serverName));
}
void InstallController::removeCurrentlyProcessedServer()
void InstallController::removeProcessedServer()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->removeServer();
emit removeCurrentlyProcessedServerFinished(tr("Server '%1' was removed").arg(serverName));
emit removeProcessedServerFinished(tr("Server '%1' was removed").arg(serverName));
}
void InstallController::removeAllContainers()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_serversModel->removeAllContainers();
@@ -329,7 +329,7 @@ void InstallController::removeAllContainers()
void InstallController::removeCurrentlyProcessedContainer()
{
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex();
@@ -377,7 +377,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
QString mountPath;
QString cmd;
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex();
int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
QString hostname = serverCredentials.hostName;
+4 -4
View File
@@ -30,8 +30,8 @@ public slots:
void updateContainer(QJsonObject config);
void removeCurrentlyProcessedServer();
void rebootCurrentlyProcessedServer();
void removeProcessedServer();
void rebootProcessedServer();
void removeAllContainers();
void removeCurrentlyProcessedContainer();
@@ -54,8 +54,8 @@ signals:
void scanServerFinished(bool isInstalledContainerFound);
void rebootCurrentlyProcessedServerFinished(const QString &finishedMessage);
void removeCurrentlyProcessedServerFinished(const QString &finishedMessage);
void rebootProcessedServerFinished(const QString &finishedMessage);
void removeProcessedServerFinished(const QString &finishedMessage);
void removeAllContainersFinished(const QString &finishedMessage);
void removeCurrentlyProcessedContainerFinished(const QString &finishedMessage);
+1 -1
View File
@@ -28,7 +28,7 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
m_sitesModel(sitesModel),
m_settings(settings)
{
m_appVersion = QString("%1: %2 (%3)").arg(tr("Software version"), QString(APP_VERSION), __DATE__);
m_appVersion = QString("%1 (%2, %3)").arg(QString(APP_VERSION), __DATE__, GIT_COMMIT_HASH);
#ifdef Q_OS_ANDROID
if (!m_settings->isScreenshotsEnabled()) {
+144 -111
View File
@@ -5,19 +5,13 @@
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(parent)
{
m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex;
connect(this, &ServersModel::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
connect(this, &ServersModel::defaultContainerChanged, this, &ServersModel::defaultServerDescriptionChanged);
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
emit ServersModel::defaultContainerChanged(defaultContainer);
});
connect(this, &ServersModel::currentlyProcessedServerIndexChanged, this, [this](const int serverIndex) {
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
emit ServersModel::defaultContainerChanged(defaultContainer);
emit ServersModel::defaultServerDefaultContainerChanged(defaultContainer);
emit ServersModel::defaultServerNameChanged();
updateDefaultServerContainersModel();
});
}
@@ -74,16 +68,14 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
return name;
}
case ServerDescriptionRole: {
if (configVersion) {
return server.value(config_key::description).toString();
}
return server.value(config_key::hostName).toString();
auto description = getServerDescription(server, index.row());
return configVersion ? description : description + server.value(config_key::hostName).toString();
}
case HostNameRole: return server.value(config_key::hostName).toString();
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
case CredentialsLoginRole: return serverCredentials(index.row()).userName;
case IsDefaultRole: return index.row() == m_defaultServerIndex;
case IsCurrentlyProcessedRole: return index.row() == m_currentlyProcessedServerIndex;
case IsCurrentlyProcessedRole: return index.row() == m_processedServerIndex;
case HasWriteAccessRole: {
auto credentials = serverCredentials(index.row());
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
@@ -95,6 +87,13 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
case DefaultContainerRole: {
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
}
case IsServerFromApiRole: {
return server.value(config_key::configVersion).toInt();
}
case HasAmneziaDns: {
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
}
}
return QVariant();
@@ -111,8 +110,9 @@ void ServersModel::resetModel()
beginResetModel();
m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex;
m_processedServerIndex = m_defaultServerIndex;
endResetModel();
emit defaultServerIndexChanged(m_defaultServerIndex);
}
void ServersModel::setDefaultServerIndex(const int index)
@@ -132,12 +132,7 @@ const QString ServersModel::getDefaultServerName()
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
}
const QString ServersModel::getDefaultServerHostName()
{
return qvariant_cast<QString>(data(m_defaultServerIndex, HostNameRole));
}
QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const
{
const auto configVersion = server.value(config_key::configVersion).toInt();
@@ -145,13 +140,12 @@ QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
if (configVersion) {
return server.value(config_key::description).toString();
} else if (isDefaultServerHasWriteAccess()) {
if (m_isAmneziaDnsEnabled
&& isAmneziaDnsContainerInstalled(m_defaultServerIndex)) {
} else if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
description += "Amnezia DNS | ";
}
} else {
if (isDefaultServerConfigContainsAmneziaDns()) {
if (data(index, HasAmneziaDns).toBool()) {
description += "Amnezia DNS | ";
}
}
@@ -162,7 +156,7 @@ const QString ServersModel::getDefaultServerDescriptionCollapsed()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server);
auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) {
return description;
}
@@ -176,7 +170,7 @@ const QString ServersModel::getDefaultServerDescriptionExpanded()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server);
auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) {
return description;
}
@@ -199,26 +193,21 @@ bool ServersModel::hasServerWithWriteAccess()
return false;
}
void ServersModel::setCurrentlyProcessedServerIndex(const int index)
void ServersModel::setProcessedServerIndex(const int index)
{
m_currentlyProcessedServerIndex = index;
m_processedServerIndex = index;
updateContainersModel();
emit currentlyProcessedServerIndexChanged(m_currentlyProcessedServerIndex);
emit processedServerIndexChanged(m_processedServerIndex);
}
int ServersModel::getCurrentlyProcessedServerIndex()
int ServersModel::getProcessedServerIndex()
{
return m_currentlyProcessedServerIndex;
return m_processedServerIndex;
}
QString ServersModel::getCurrentlyProcessedServerHostName()
const ServerCredentials ServersModel::getProcessedServerCredentials()
{
return qvariant_cast<QString>(data(m_currentlyProcessedServerIndex, HostNameRole));
}
const ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials()
{
return serverCredentials(m_currentlyProcessedServerIndex);
return serverCredentials(m_processedServerIndex);
}
const ServerCredentials ServersModel::getServerCredentials(const int index)
@@ -228,12 +217,17 @@ const ServerCredentials ServersModel::getServerCredentials(const int index)
bool ServersModel::isDefaultServerCurrentlyProcessed()
{
return m_defaultServerIndex == m_currentlyProcessedServerIndex;
return m_defaultServerIndex == m_processedServerIndex;
}
bool ServersModel::isCurrentlyProcessedServerHasWriteAccess()
bool ServersModel::isDefaultServerFromApi()
{
return qvariant_cast<bool>(data(m_currentlyProcessedServerIndex, HasWriteAccessRole));
return qvariant_cast<bool>(data(m_defaultServerIndex, IsServerFromApiRole));
}
bool ServersModel::isProcessedServerHasWriteAccess()
{
return qvariant_cast<bool>(data(m_processedServerIndex, HasWriteAccessRole));
}
bool ServersModel::isDefaultServerHasWriteAccess()
@@ -249,40 +243,42 @@ void ServersModel::addServer(const QJsonObject &server)
endResetModel();
}
void ServersModel::editServer(const QJsonObject &server)
void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
{
m_settings->editServer(m_currentlyProcessedServerIndex, server);
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->serversArray().at(m_currentlyProcessedServerIndex));
emit dataChanged(index(m_currentlyProcessedServerIndex, 0), index(m_currentlyProcessedServerIndex, 0));
m_settings->editServer(serverIndex, server);
m_servers.replace(serverIndex, m_settings->serversArray().at(serverIndex));
emit dataChanged(index(serverIndex, 0), index(serverIndex, 0));
if (serverIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel();
if (serverIndex == m_defaultServerIndex) {
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
emit defaultServerDefaultContainerChanged(defaultContainer);
}
}
void ServersModel::removeServer()
{
beginResetModel();
m_settings->removeServer(m_currentlyProcessedServerIndex);
m_settings->removeServer(m_processedServerIndex);
m_servers = m_settings->serversArray();
if (m_settings->defaultServerIndex() == m_currentlyProcessedServerIndex) {
if (m_settings->defaultServerIndex() == m_processedServerIndex) {
setDefaultServerIndex(0);
} else if (m_settings->defaultServerIndex() > m_currentlyProcessedServerIndex) {
} else if (m_settings->defaultServerIndex() > m_processedServerIndex) {
setDefaultServerIndex(m_settings->defaultServerIndex() - 1);
}
if (m_settings->serversCount() == 0) {
setDefaultServerIndex(-1);
}
setCurrentlyProcessedServerIndex(m_defaultServerIndex);
setProcessedServerIndex(m_defaultServerIndex);
endResetModel();
}
bool ServersModel::isDefaultServerConfigContainsAmneziaDns()
{
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
QString primaryDns = server.value(config_key::dns1).toString();
return primaryDns == protocols::dns::amneziaDnsIp;
}
QHash<int, QByteArray> ServersModel::roleNames() const
{
QHash<int, QByteArray> roles;
@@ -290,6 +286,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[NameRole] = "serverName";
roles[NameRole] = "name";
roles[ServerDescriptionRole] = "serverDescription";
roles[CollapsedServerDescriptionRole] = "collapsedServerDescription";
roles[ExpandedServerDescriptionRole] = "expandedServerDescription";
roles[HostNameRole] = "hostName";
@@ -304,6 +302,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[ContainsAmneziaDnsRole] = "containsAmneziaDns";
roles[DefaultContainerRole] = "defaultContainer";
roles[IsServerFromApiRole] = "isServerFromApi";
return roles;
}
@@ -322,28 +322,29 @@ ServerCredentials ServersModel::serverCredentials(int index) const
void ServersModel::updateContainersModel()
{
auto containers = m_servers.at(m_currentlyProcessedServerIndex).toObject().value(config_key::containers).toArray();
auto containers = m_servers.at(m_processedServerIndex).toObject().value(config_key::containers).toArray();
emit containersUpdated(containers);
}
void ServersModel::updateDefaultServerContainersModel()
{
auto containers = m_servers.at(m_defaultServerIndex).toObject().value(config_key::containers).toArray();
emit defaultServerContainersUpdated(containers);
}
QJsonObject ServersModel::getDefaultServerConfig()
{
return m_servers.at(m_defaultServerIndex).toObject();
}
QJsonObject ServersModel::getCurrentlyProcessedServerConfig()
void ServersModel::reloadDefaultServerContainerConfig()
{
return m_servers.at(m_currentlyProcessedServerIndex).toObject();
}
void ServersModel::reloadContainerConfig()
{
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containers = server.value(config_key::containers).toArray();
auto config = m_settings->containerConfig(m_currentlyProcessedServerIndex, container);
auto config = m_settings->containerConfig(m_defaultServerIndex, container);
for (auto i = 0; i < containers.size(); i++) {
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
if (c == container) {
@@ -353,13 +354,13 @@ void ServersModel::reloadContainerConfig()
}
server.insert(config_key::containers, containers);
editServer(server);
editServer(server, m_defaultServerIndex);
}
void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config)
{
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) {
@@ -377,30 +378,25 @@ void ServersModel::updateContainerConfig(const int containerIndex, const QJsonOb
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
}
editServer(server);
editServer(server, m_processedServerIndex);
}
void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config)
{
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
containers.push_back(config);
server.insert(config_key::containers, containers);
bool isDefaultContainerChanged = false;
auto defaultContainer = server.value(config_key::defaultContainer).toString();
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
isDefaultContainerChanged = true;
}
editServer(server);
if (isDefaultContainerChanged) {
emit defaultContainerChanged(container);
}
editServer(server, m_processedServerIndex);
}
void ServersModel::setDefaultContainer(const int serverIndex, const int containerIndex)
@@ -408,18 +404,12 @@ void ServersModel::setDefaultContainer(const int serverIndex, const int containe
auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject s = m_servers.at(serverIndex).toObject();
s.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
editServer(s); //check
emit defaultContainerChanged(container);
editServer(s, serverIndex); //check
}
DockerContainer ServersModel::getDefaultContainer(const int serverIndex)
const QString ServersModel::getDefaultServerDefaultContainerName()
{
return qvariant_cast<DockerContainer>(data(serverIndex, DefaultContainerRole));
}
const QString ServersModel::getDefaultContainerName()
{
auto defaultContainer = getDefaultContainer(m_defaultServerIndex);
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
return ContainerProps::containerHumanNames().value(defaultContainer);
}
@@ -427,15 +417,14 @@ ErrorCode ServersModel::removeAllContainers()
{
ServerController serverController(m_settings);
ErrorCode errorCode =
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex));
serverController.removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
if (errorCode == ErrorCode::NoError) {
QJsonObject s = m_servers.at(m_currentlyProcessedServerIndex).toObject();
QJsonObject s = m_servers.at(m_processedServerIndex).toObject();
s.insert(config_key::containers, {});
s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
editServer(s);
emit defaultContainerChanged(DockerContainer::None);
editServer(s, m_processedServerIndex);
}
return errorCode;
}
@@ -443,7 +432,7 @@ ErrorCode ServersModel::removeAllContainers()
ErrorCode ServersModel::rebootServer()
{
ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
ErrorCode errorCode = serverController.rebootServer(credentials);
return errorCode;
@@ -452,13 +441,13 @@ ErrorCode ServersModel::rebootServer()
ErrorCode ServersModel::removeContainer(const int containerIndex)
{
ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex);
auto credentials = m_settings->serverCredentials(m_processedServerIndex);
auto dockerContainer = static_cast<DockerContainer>(containerIndex);
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
if (errorCode == ErrorCode::NoError) {
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
QJsonObject server = m_servers.at(m_processedServerIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) {
@@ -480,32 +469,37 @@ ErrorCode ServersModel::removeContainer(const int containerIndex)
server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
}
editServer(server);
emit defaultContainerChanged(defaultContainer);
editServer(server, m_processedServerIndex);
}
return errorCode;
}
void ServersModel::clearCachedProfiles()
{
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex);
const auto &containers = m_settings->containers(m_processedServerIndex);
for (DockerContainer container : containers.keys()) {
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container);
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
}
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex));
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
if (m_processedServerIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel();
}
void ServersModel::clearCachedProfile(const DockerContainer container)
{
m_settings->clearLastConnectionConfig(m_currentlyProcessedServerIndex, container);
m_settings->clearLastConnectionConfig(m_processedServerIndex, container);
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->server(m_currentlyProcessedServerIndex));
m_servers.replace(m_processedServerIndex, m_settings->server(m_processedServerIndex));
if (m_processedServerIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel();
}
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex)
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) const
{
QJsonObject server = m_servers.at(serverIndex).toObject();
auto containers = server.value(config_key::containers).toArray();
@@ -544,16 +538,6 @@ void ServersModel::toggleAmneziaDns(bool enabled)
emit defaultServerDescriptionChanged();
}
bool ServersModel::isDefaultServerFromApi()
{
return m_settings->server(m_defaultServerIndex).value(config_key::configVersion).toInt();
}
bool ServersModel::isCurrentlyProcessedServerFromApi()
{
return m_settings->server(m_currentlyProcessedServerIndex).value(config_key::configVersion).toInt();
}
bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
{
for (const auto &server : qAsConst(m_servers)) {
@@ -564,3 +548,52 @@ bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
return false;
}
QVariant ServersModel::getDefaultServerData(const QString roleString)
{
auto roles = roleNames();
for (auto it = roles.begin(); it != roles.end(); it++) {
if (QString(it.value()) == roleString) {
return data(m_defaultServerIndex, it.key());
}
}
return {};
}
void ServersModel::setDefaultServerData(const QString roleString, const QVariant &value)
{
}
QVariant ServersModel::getProcessedServerData(const QString roleString)
{
auto roles = roleNames();
for (auto it = roles.begin(); it != roles.end(); it++) {
if (QString(it.value()) == roleString) {
return data(m_processedServerIndex, it.key());
}
}
return {};
}
void ServersModel::setProcessedServerData(const QString roleString, const QVariant &value)
{
}
bool ServersModel::isDefaultServerDefaultContainerHasSplitTunneling()
{
auto server = m_servers.at(m_defaultServerIndex).toObject();
auto defaultContainer = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containerConfig = server.value(config_key::containers).toArray().at(defaultContainer).toObject();
auto protocolConfig = containerConfig.value(ContainerProps::containerTypeToString(defaultContainer)).toObject();
if (defaultContainer == DockerContainer::Awg || defaultContainer == DockerContainer::WireGuard) {
return !(protocolConfig.value(config_key::last_config).toString().contains("AllowedIPs = 0.0.0.0/0, ::/0"));
} else if (defaultContainer == DockerContainer::Cloak || defaultContainer == DockerContainer::OpenVpn || defaultContainer == DockerContainer::ShadowSocks) {
return !(protocolConfig.value(config_key::last_config).toString().contains("redirect-gateway"));
}
return false;
}
+37 -29
View File
@@ -12,7 +12,8 @@ public:
enum Roles {
NameRole = Qt::UserRole + 1,
ServerDescriptionRole,
CollapsedServerDescriptionRole,
ExpandedServerDescriptionRole,
HostNameRole,
CredentialsRole,
@@ -25,7 +26,11 @@ public:
ContainsAmneziaDnsRole,
DefaultContainerRole
DefaultContainerRole,
IsServerFromApiRole,
HasAmneziaDns
};
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr);
@@ -40,47 +45,43 @@ public:
Q_PROPERTY(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDescriptionChanged)
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDescriptionChanged)
Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex
NOTIFY currentlyProcessedServerIndexChanged)
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
public slots:
void setDefaultServerIndex(const int index);
const int getDefaultServerIndex();
const QString getDefaultServerName();
const QString getDefaultServerHostName();
const QString getDefaultServerDescriptionCollapsed();
const QString getDefaultServerDescriptionExpanded();
const QString getDefaultServerDefaultContainerName();
bool isDefaultServerCurrentlyProcessed();
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerHasWriteAccess();
bool isProcessedServerHasWriteAccess();
bool isDefaultServerHasWriteAccess();
bool hasServerWithWriteAccess();
const int getServersCount();
void setCurrentlyProcessedServerIndex(const int index);
int getCurrentlyProcessedServerIndex();
void setProcessedServerIndex(const int index);
int getProcessedServerIndex();
QString getCurrentlyProcessedServerHostName();
const ServerCredentials getCurrentlyProcessedServerCredentials();
const ServerCredentials getProcessedServerCredentials();
const ServerCredentials getServerCredentials(const int index);
void addServer(const QJsonObject &server);
void editServer(const QJsonObject &server);
void editServer(const QJsonObject &server, const int serverIndex);
void removeServer();
bool isDefaultServerConfigContainsAmneziaDns();
bool isAmneziaDnsContainerInstalled(const int serverIndex);
QJsonObject getDefaultServerConfig();
QJsonObject getCurrentlyProcessedServerConfig();
void reloadContainerConfig();
void reloadDefaultServerContainerConfig();
void updateContainerConfig(const int containerIndex, const QJsonObject config);
void addContainerConfig(const int containerIndex, const QJsonObject config);
@@ -92,42 +93,49 @@ public slots:
ErrorCode rebootServer();
void setDefaultContainer(const int serverIndex, const int containerIndex);
DockerContainer getDefaultContainer(const int serverIndex);
const QString getDefaultContainerName();
QStringList getAllInstalledServicesName(const int serverIndex);
void toggleAmneziaDns(bool enabled);
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerFromApi();
bool isServerFromApiAlreadyExists(const quint16 crc);
QVariant getDefaultServerData(const QString roleString);
void setDefaultServerData(const QString roleString, const QVariant &value);
QVariant getProcessedServerData(const QString roleString);
void setProcessedServerData(const QString roleString, const QVariant &value);
bool isDefaultServerDefaultContainerHasSplitTunneling();
protected:
QHash<int, QByteArray> roleNames() const override;
signals:
void currentlyProcessedServerIndexChanged(const int index);
void processedServerIndexChanged(const int index);
void defaultServerIndexChanged(const int index);
void defaultServerNameChanged();
void defaultServerDescriptionChanged();
void containersUpdated(const QJsonArray &containers);
void defaultContainerChanged(const int containerIndex);
void defaultServerContainersUpdated(const QJsonArray &containers);
void defaultServerDefaultContainerChanged(const int containerIndex);
private:
ServerCredentials serverCredentials(int index) const;
void updateContainersModel();
void updateDefaultServerContainersModel();
QString getDefaultServerDescription(const QJsonObject &server);
QString getServerDescription(const QJsonObject &server, const int index) const;
bool isAmneziaDnsContainerInstalled(const int serverIndex) const;
QJsonArray m_servers;
std::shared_ptr<Settings> m_settings;
int m_defaultServerIndex;
int m_currentlyProcessedServerIndex;
int m_processedServerIndex;
bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns();
};
+1
View File
@@ -113,6 +113,7 @@ void SitesModel::toggleSplitTunneling(bool enabled)
m_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
}
m_isSplitTunnelingEnabled = enabled;
emit splitTunnelingToggled();
}
QVector<QPair<QString, QString> > SitesModel::getCurrentSites()
+2
View File
@@ -22,6 +22,7 @@ public:
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged)
Q_PROPERTY(bool isTunnelingEnabled READ isSplitTunnelingEnabled NOTIFY splitTunnelingToggled)
public slots:
bool addSite(const QString &hostname, const QString &ip);
@@ -38,6 +39,7 @@ public slots:
signals:
void routeModeChanged();
void splitTunnelingToggled();
protected:
QHash<int, QByteArray> roleNames() const override;
+1 -1
View File
@@ -138,7 +138,7 @@ Button {
}
onClicked: {
ServersModel.setCurrentlyProcessedServerIndex(ServersModel.defaultIndex)
ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
ApiController.updateServerConfigFromApi()
}
}
+35
View File
@@ -0,0 +1,35 @@
import QtQuick 2.15
import QtQml 2.15
Behavior {
id: root
property QtObject fadeTarget: targetProperty.object
property string fadeProperty: "opacity"
property int fadeDuration: 200
property int fadeValue: 0
property string easingType: "Quad"
property alias exitAnimation: exitAnimation
property alias enterAnimation: enterAnimation
SequentialAnimation {
NumberAnimation {
id: exitAnimation
target: root.fadeTarget
property: root.fadeProperty
duration: root.fadeDuration
to: root.fadeValue
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["In"+root.easingType]
}
PropertyAction { }
NumberAnimation {
id: enterAnimation
target: root.fadeTarget
property: root.fadeProperty
duration: root.fadeDuration
to: target[property]
easing.type: root.easingType === "Linear" ? Easing.Linear : Easing["Out"+root.easingType]
}
}
}
@@ -15,6 +15,7 @@ ListView {
id: menuContent
property var rootWidth
property var selectedText
width: rootWidth
height: menuContent.contentItem.height
@@ -51,7 +52,7 @@ ListView {
showImage: !isInstalled
checkable: isInstalled && !ConnectionController.isConnected && isSupported
checked: proxyContainersModel.mapToSource(index) === ServersModel.getDefaultContainer(ServersModel.defaultIndex)
checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
onClicked: {
if (ConnectionController.isConnected && isInstalled) {
@@ -61,14 +62,14 @@ ListView {
if (checked) {
containersDropDown.close()
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyContainersModel.mapToSource(index))
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
} else {
if (!isSupported && isInstalled) {
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
return
}
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(index))
ContainersModel.setCurrentlyProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
containersDropDown.close()
@@ -0,0 +1,92 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import PageEnum 1.0
import "../Controls2"
import "../Controls2/TextTypes"
import "../Config"
DrawerType2 {
id: root
anchors.fill: parent
expandedHeight: parent.height * 0.7
expandedContent: ColumnLayout {
id: content
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Header2Type {
Layout.fillWidth: true
Layout.topMargin: 24
Layout.rightMargin: 16
Layout.leftMargin: 16
Layout.bottomMargin: 16
headerText: qsTr("Split tunneling")
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
}
LabelWithButtonType {
Layout.fillWidth: true
Layout.topMargin: 16
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
text: qsTr("Split tunneling on the server")
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
// root.close()
}
}
DividerType {
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
}
LabelWithButtonType {
Layout.fillWidth: true
Layout.topMargin: 16
enabled: ! ServersModel.isDefaultServerDefaultContainerHasSplitTunneling || !ServersModel.getDefaultServerData("isServerFromApi")
text: qsTr("Site-based split tunneling")
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
root.close()
}
}
DividerType {
}
LabelWithButtonType {
Layout.fillWidth: true
visible: false
text: qsTr("App-based split tunneling")
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
// PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
root.close()
}
}
DividerType {
visible: false
}
}
}
@@ -38,14 +38,6 @@ DrawerType2 {
expandedContent: Item {
implicitHeight: root.expandedHeight
Connections {
target: root
function onOpened() {
header.forceActiveFocus()
}
}
Header2Type {
id: header
anchors.top: parent.top
@@ -56,8 +48,6 @@ DrawerType2 {
anchors.rightMargin: 16
headerText: root.headerText
KeyNavigation.tab: shareButton
}
FlickableType {
@@ -78,15 +68,12 @@ DrawerType2 {
visible: root.contentVisible
BasicButtonType {
id: shareButton
Layout.fillWidth: true
Layout.topMargin: 16
text: qsTr("Share")
imageSource: "qrc:/images/controls/share-2.svg"
KeyNavigation.tab: copyConfigTextButton
clickedFunc: function() {
var fileName = ""
if (GC.isMobile()) {
@@ -120,8 +107,6 @@ DrawerType2 {
text: qsTr("Copy")
imageSource: "qrc:/images/controls/copy.svg"
KeyNavigation.tab: copyNativeConfigStringButton.visible ? copyNativeConfigStringButton : showSettingsButton
}
BasicButtonType {
@@ -140,13 +125,9 @@ DrawerType2 {
text: qsTr("Copy config string")
imageSource: "qrc:/images/controls/copy.svg"
KeyNavigation.tab: showSettingsButton
}
BasicButtonType {
id: showSettingsButton
Layout.fillWidth: true
Layout.topMargin: 24
@@ -162,8 +143,6 @@ DrawerType2 {
clickedFunc: function() {
configContentDrawer.open()
}
KeyNavigation.tab: header
}
DrawerType2 {
@@ -208,7 +187,7 @@ DrawerType2 {
anchors.topMargin: 16
backButtonFunction: function() {
configContentDrawer.open()
configContentDrawer.close()
}
}
+26 -10
View File
@@ -21,6 +21,8 @@ Button {
property int borderFocusedWidth: 1
property string imageSource
property string rightImageSource
property string leftImageColor: textColor
property bool squareLeftSide: false
@@ -31,23 +33,22 @@ Button {
hoverEnabled: true
background: Rectangle {
id: focusBorder
id: background_border
color: "transparent"
border.color: root.activeFocus ? root.borderFocusedColor : "transparent"
border.width: root.activeFocus ? root.borderFocusedWidth : "transparent"
anchors.fill: parent
radius: 16
Rectangle {
id: background
anchors.fill: focusBorder
anchors.margins: root.activeFocus ? 2 : 0
anchors.fill: background_border
anchors.margins: root.activeFocus ? 2: 0
radius: root.activeFocus ? 14 : 16
radius: 16
color: {
if (root.enabled) {
if (root.pressed) {
@@ -58,8 +59,8 @@ Button {
return disabledColor
}
}
border.color: borderColor
border.width: borderWidth
border.color: root.activeFocus ? "transparent" : borderColor
border.width: root.activeFocus ? 0 : borderWidth
Behavior on color {
PropertyAnimation { duration: 200 }
@@ -94,13 +95,13 @@ Button {
}
MouseArea {
anchors.fill: focusBorder
anchors.fill: background_border
enabled: false
cursorShape: Qt.PointingHandCursor
}
contentItem: Item {
anchors.fill: focusBorder
anchors.fill: background_border
implicitWidth: content.implicitWidth
implicitHeight: content.implicitHeight
@@ -119,7 +120,7 @@ Button {
layer {
enabled: true
effect: ColorOverlay {
color: textColor
color: leftImageColor
}
}
}
@@ -132,6 +133,21 @@ Button {
horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter
}
Image {
Layout.preferredHeight: 20
Layout.preferredWidth: 20
source: root.rightImageSource
visible: root.rightImageSource === "" ? false : true
layer {
enabled: true
effect: ColorOverlay {
color: textColor
}
}
}
}
}
+1
View File
@@ -84,6 +84,7 @@ Item {
id: emptyArea
anchors.fill: parent
enabled: root.isExpanded
visible: enabled
onClicked: {
root.close()
}
+80 -27
View File
@@ -34,8 +34,45 @@ PageType {
anchors.bottomMargin: drawer.collapsedHeight
ConnectButton {
id: connectButton
anchors.centerIn: parent
}
BasicButtonType {
anchors.horizontalCenter: parent.horizontalCenter
anchors.bottom: parent.bottom
anchors.bottomMargin: 34
leftPadding: 16
rightPadding: 16
implicitHeight: 36
defaultColor: "transparent"
hoveredColor: Qt.rgba(1, 1, 1, 0.08)
pressedColor: Qt.rgba(1, 1, 1, 0.12)
disabledColor: "#878B91"
textColor: "#878B91"
leftImageColor: "transparent"
borderWidth: 0
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled ||
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
text: isSplitTunnelingEnabled ? qsTr("Split tunneling enabled") : qsTr("Split tunneling disabled")
imageSource: isSplitTunnelingEnabled ? "qrc:/images/controls/split-tunneling.svg" : ""
rightImageSource: "qrc:/images/controls/chevron-down.svg"
onClicked: {
homeSplitTunnelingDrawer.open()
}
HomeSplitTunnelingDrawer {
id: homeSplitTunnelingDrawer
parent: root
}
}
}
@@ -122,6 +159,20 @@ PageType {
Layout.bottomMargin: 44
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
text: ServersModel.defaultServerDescriptionCollapsed
FadeBehavior on text { }
Connections {
target: drawer
function onOpen() {
collapsedServerMenuDescription.text = ServersModel.defaultServerDescriptionExpanded
}
function onClose() {
collapsedServerMenuDescription.text = ServersModel.defaultServerDescriptionCollapsed
}
}
}
}
@@ -156,17 +207,34 @@ PageType {
LabelTextType {
id: expandedServersMenuDescription
Layout.bottomMargin: 24
Layout.bottomMargin: ServersModel.isDefaultServerFromApi ? 69 : 24
Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter
text: ServersModel.defaultServerDescriptionExpanded
text: ServersModel.defaultServerDescriptionCollapsed
FadeBehavior on text { }
Connections {
target: drawer
function onOpen() {
expandedServersMenuDescription.text = ServersModel.defaultServerDescriptionExpanded
}
function onClose() {
expandedServersMenuDescription.text = ServersModel.defaultServerDescriptionCollapsed
}
}
}
RowLayout {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
spacing: 8
visible: !ServersModel.isDefaultServerFromApi
onVisibleChanged: expandedServersMenuDescription.Layout
DropDownType {
id: containersDropDown
@@ -179,13 +247,12 @@ PageType {
rootButtonTextTopMargin: 8
rootButtonTextBottomMargin: 8
text: ServersModel.defaultContainerName
text: ServersModel.defaultServerDefaultContainerName
textColor: "#0E0E11"
headerText: qsTr("VPN protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
rootButtonClickedFunction: function() {
ServersModel.currentlyProcessedIndex = serversMenuContent.currentIndex
containersDropDown.open()
}
@@ -197,22 +264,23 @@ PageType {
Connections {
target: ServersModel
function onCurrentlyProcessedServerIndexChanged() {
function onDefaultServerIndexChanged() {
updateContainersModelFilters()
}
}
function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
if (ServersModel.isDefaultServerHasWriteAccess()) {
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
}
}
model: SortFilterProxyModel {
id: proxyContainersModel
sourceModel: ContainersModel
id: proxyDefaultServerContainersModel
sourceModel: DefaultServerContainersModel
sorters: [
RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
]
@@ -308,21 +376,7 @@ PageType {
Layout.fillWidth: true
text: name
descriptionText: {
var fullDescription = ""
if (hasWriteAccess) {
if (SettingsController.isAmneziaDnsEnabled()
&& ServersModel.isAmneziaDnsContainerInstalled(index)) {
fullDescription += "Amnezia DNS | "
}
} else {
if (containsAmneziaDns) {
fullDescription += "Amnezia DNS | "
}
}
return fullDescription += serverDescription
}
descriptionText: serverDescription
checked: index === serversMenuContent.currentIndex
checkable: !ConnectionController.isConnected
@@ -337,7 +391,6 @@ PageType {
serversMenuContent.currentIndex = index
ServersModel.currentlyProcessedIndex = index
ServersModel.defaultIndex = index
}
@@ -358,7 +411,7 @@ PageType {
z: 1
onClicked: function() {
ServersModel.currentlyProcessedIndex = index
ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo)
drawer.close()
}
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView {
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView {
id: listview
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView {
id: listview
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757"
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView {
id: listview
@@ -49,7 +49,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView {
id: listview
@@ -88,7 +88,7 @@ PageType {
Layout.topMargin: 32
text: qsTr("Host")
descriptionText: ServersModel.getCurrentlyProcessedServerHostName()
descriptionText: ServersModel.getProcessedServerData("HostName")
descriptionOnTop: true
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
horizontalAlignment: Text.AlignHCenter
text: SettingsController.getAppVersion()
text: qsTr("Software version: %1").arg(SettingsController.getAppVersion())
color: "#878B91"
}
@@ -84,6 +84,27 @@ PageType {
visible: !GC.isMobile()
}
SwitcherType {
visible: !GC.isMobile()
Layout.fillWidth: true
Layout.margins: 16
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
checked: SettingsController.isAutoConnectEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoConnectEnabled()) {
SettingsController.toggleAutoConnect(checked)
}
}
}
DividerType {
visible: !GC.isMobile()
}
SwitcherType {
visible: !GC.isMobile()
@@ -41,27 +41,6 @@ PageType {
headerText: qsTr("Connection")
}
SwitcherType {
visible: !GC.isMobile()
Layout.fillWidth: true
Layout.margins: 16
text: qsTr("Auto connect")
descriptionText: qsTr("Connect to VPN on app start")
checked: SettingsController.isAutoConnectEnabled()
onCheckedChanged: {
if (checked !== SettingsController.isAutoConnectEnabled()) {
SettingsController.toggleAutoConnect(checked)
}
}
}
DividerType {
visible: !GC.isMobile()
}
SwitcherType {
Layout.fillWidth: true
Layout.margins: 16
+4 -2
View File
@@ -30,10 +30,12 @@ PageType {
anchors.bottom: parent.bottom
contentHeight: content.height
enabled: !ServersModel.isDefaultServerFromApi()
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
enabled: !isServerFromApi
Component.onCompleted: {
if (ServersModel.isDefaultServerFromApi()) {
if (isServerFromApi) {
PageController.showNotificationMessage(qsTr("Default server does not support custom dns"))
}
}
@@ -28,7 +28,7 @@ PageType {
PageController.showErrorMessage(message)
}
function onRemoveCurrentlyProcessedServerFinished(finishedMessage) {
function onRemoveProcessedServerFinished(finishedMessage) {
if (!ServersModel.getServersCount()) {
PageController.replaceStartPage()
} else {
@@ -38,7 +38,7 @@ PageType {
PageController.showNotificationMessage(finishedMessage)
}
function onRebootCurrentlyProcessedServerFinished(finishedMessage) {
function onRebootProcessedServerFinished(finishedMessage) {
PageController.showNotificationMessage(finishedMessage)
}
@@ -64,8 +64,8 @@ PageType {
Connections {
target: ServersModel
function onCurrentlyProcessedServerIndexChanged() {
content.isServerWithWriteAccess = ServersModel.isCurrentlyProcessedServerHasWriteAccess()
function onProcessedServerIndexChanged() {
content.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
}
}
@@ -82,7 +82,7 @@ PageType {
anchors.left: parent.left
anchors.right: parent.right
property bool isServerWithWriteAccess: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
LabelWithButtonType {
visible: content.isServerWithWriteAccess
@@ -149,7 +149,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection()
}
InstallController.rebootCurrentlyProcessedServer()
InstallController.rebootProcessedServer()
PageController.showBusyIndicator(false)
}
var noButtonFunction = function() {
@@ -180,7 +180,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection()
}
InstallController.removeCurrentlyProcessedServer()
InstallController.removeProcessedServer()
PageController.showBusyIndicator(false)
}
var noButtonFunction = function() {
@@ -224,7 +224,7 @@ PageType {
}
LabelWithButtonType {
visible: ServersModel.isCurrentlyProcessedServerFromApi()
visible: ServersModel.getProcessedServerData("isServerFromApi")
Layout.fillWidth: true
text: qsTr("Reset API config")
@@ -249,7 +249,7 @@ PageType {
}
DividerType {
visible: ServersModel.isCurrentlyProcessedServerFromApi()
visible: ServersModel.getProcessedServerData("isServerFromApi")
}
}
}
@@ -63,7 +63,7 @@ PageType {
headerText: name
descriptionText: {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
if (ServersModel.isProcessedServerHasWriteAccess()) {
return credentialsLogin + " · " + hostName
} else {
return hostName
@@ -107,7 +107,7 @@ PageType {
width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess()
visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757"
@@ -38,13 +38,13 @@ PageType {
Connections {
target: ServersModel
function onCurrentlyProcessedServerIndexChanged() {
function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters()
}
}
function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
@@ -38,13 +38,13 @@ PageType {
Connections {
target: ServersModel
function onCurrentlyProcessedServerIndexChanged() {
function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters()
}
}
function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) {
if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters()
} else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters()
@@ -87,7 +87,7 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() {
ServersModel.currentlyProcessedIndex = index
ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo)
}
}
@@ -20,15 +20,23 @@ import "../Components"
PageType {
id: root
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
defaultActiveFocusItem: website_ip_field.textField
property bool pageEnabled: {
return !ConnectionController.isConnected && !ServersModel.isDefaultServerFromApi()
return !ConnectionController.isConnected && !isServerFromApi
}
Component.onCompleted: {
if (ServersModel.isDefaultServerFromApi()) {
if (ConnectionController.isConnected) {
PageController.showNotificationMessage(qsTr("Cannot change split tunneling settings during active connection"))
root.pageEnabled = false
} else if (ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && isServerFromApi) {
PageController.showNotificationMessage(qsTr("Default server does not support split tunneling function"))
root.pageEnabled = false
} else {
root.pageEnabled = true
}
}
@@ -106,7 +114,7 @@ PageType {
Layout.fillWidth: true
Layout.rightMargin: 16
checked: SitesModel.isSplitTunnelingEnabled()
checked: SitesModel.isTunnelingEnabled
onToggled: {
SitesModel.toggleSplitTunneling(checked)
selector.text = root.routeModesModel[getRouteModesModelIndex()].name
@@ -26,7 +26,7 @@ PageType {
function onInstallContainerFinished(finishedMessage, isServiceInstall) {
if (!ConnectionController.isConnected && !isServiceInstall) {
ServersModel.setDefaultContainer(ServersModel.currentlyProcessedIndex, ContainersModel.getCurrentlyProcessedContainerIndex())
ServersModel.setDefaultContainer(ServersModel.processedIndex, ContainersModel.getCurrentlyProcessedContainerIndex())
}
PageController.closePage() // close installing page
@@ -42,7 +42,7 @@ PageType {
function onInstallServerFinished(finishedMessage) {
if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
ServersModel.processedIndex = ServersModel.defaultIndex
}
PageController.goToStartPage()
@@ -55,7 +55,7 @@ PageType {
function onServerAlreadyExists(serverIndex) {
PageController.goToStartPage()
ServersModel.currentlyProcessedIndex = serverIndex
ServersModel.processedIndex = serverIndex
PageController.goToPage(PageEnum.PageSettingsServerInfo, false)
PageController.showErrorMessage(qsTr("The server has already been added to the application"))
@@ -30,7 +30,7 @@ PageType {
function onImportFinished() {
if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
ServersModel.processedIndex = ServersModel.defaultIndex
}
PageController.goToStartPage()
+25 -7
View File
@@ -22,6 +22,7 @@ PageType {
AmneziaConnection,
OpenVpn,
WireGuard,
Awg,
ShadowSocks,
Cloak
}
@@ -31,7 +32,7 @@ PageType {
PageController.showBusyIndicator(true)
ExportController.revokeConfig(index,
ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
PageController.showNotificationMessage(qsTr("Config revoked"))
}
@@ -48,7 +49,10 @@ PageType {
PageController.showBusyIndicator(true)
switch (type) {
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(clientNameTextField.textFieldText); break;
case PageShare.ConfigType.AmneziaConnection: {
ExportController.generateConnectionConfig(clientNameTextField.textFieldText);
break;
}
case PageShare.ConfigType.OpenVpn: {
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
@@ -63,6 +67,13 @@ PageType {
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break
}
case PageShare.ConfigType.Awg: {
ExportController.generateAwgConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save AmneziaWG config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_awg"
break
}
case PageShare.ConfigType.ShadowSocks: {
ExportController.generateShadowSocksConfig()
shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config")
@@ -110,6 +121,11 @@ PageType {
property string name: qsTr("WireGuard native format")
property var type: PageShare.ConfigType.WireGuard
}
QtObject {
id: awgConnectionFormat
property string name: qsTr("AmneziaWG native format")
property var type: PageShare.ConfigType.Awg
}
QtObject {
id: shadowSocksConnectionFormat
property string name: qsTr("ShadowSocks native format")
@@ -230,7 +246,7 @@ PageType {
accessTypeSelector.currentIndex = 1
PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
}
@@ -315,7 +331,7 @@ PageType {
function handler() {
serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
}
}
}
@@ -365,7 +381,7 @@ PageType {
target: serverSelector
function onSeverSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer(ServersModel.currentlyProcessedIndex))
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.currentIndex = defaultContainer
protocolSelectorListView.triggerCurrentItem()
}
@@ -388,7 +404,7 @@ PageType {
if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
}
}
@@ -402,6 +418,8 @@ PageType {
root.connectionTypesModel.push(openVpnConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
root.connectionTypesModel.push(wireGuardConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
root.connectionTypesModel.push(openVpnConnectionFormat)
root.connectionTypesModel.push(shadowSocksConnectionFormat)
@@ -654,7 +672,7 @@ PageType {
ExportController.renameClient(index,
clientNameEditor.textFieldText,
ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials())
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
clientNameEditDrawer.close()
}
+1 -1
View File
@@ -111,7 +111,7 @@ PageType {
function handler() {
serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex)
ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
}
}
}
+5 -4
View File
@@ -44,6 +44,7 @@ PageType {
function onClosePage() {
tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo)
&& tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsSplitTunneling)
if (tabBarStackView.depth <= 1) {
return
@@ -60,7 +61,7 @@ PageType {
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate)
}
tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || tabBar.isServerInfoShow
tabBar.isServerInfoShow = page === PageEnum.PageSettingsServerInfo || PageEnum.PageSettingsSplitTunneling || tabBar.isServerInfoShow
}
function onGoToStartPage() {
@@ -108,7 +109,7 @@ PageType {
function onNoInstalledContainers() {
PageController.setTriggeredBtConnectButton(true)
ServersModel.currentlyProcessedIndex = ServersModel.getDefaultServerIndex()
ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardEasy)
}
@@ -136,7 +137,7 @@ PageType {
Component.onCompleted: {
var pagePath = PageController.getPagePath(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
ServersModel.processedIndex = ServersModel.defaultIndex
tabBarStackView.push(pagePath, { "objectName" : pagePath })
}
}
@@ -180,7 +181,7 @@ PageType {
image: "qrc:/images/controls/home.svg"
onClicked: {
tabBarStackView.goToTabBarPage(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex
ServersModel.processedIndex = ServersModel.defaultIndex
tabBar.previousIndex = 0
}
}
+2 -1
View File
@@ -146,7 +146,8 @@ if [ "${MAC_CERT_PW+x}" ]; then
fi
echo "Building DMG installer..."
hdiutil create -size 120mb -volname AmneziaVPN -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME
# Allow Terminal to make changes in Privacy & Security > App Management
hdiutil create -size 256mb -volname AmneziaVPN -srcfolder $BUILD_DIR/installer/$APP_NAME.app -ov -format UDZO $DMG_FILENAME
if [ "${MAC_CERT_PW+x}" ]; then
echo "Signing DMG installer..."