Compare commits

..

49 Commits

Author SHA1 Message Date
pokamest d8ee32d4b1 Merge branch 'dev' into feature/auto-scroll-for-server-selection-list 2024-02-26 22:18:15 +00:00
Andrey Zaharow 2f39136143 Fix translations (#646)
Fix awg texts
2024-02-26 21:17:57 +00:00
pokamest 8d0d3c5ce9 Merge pull request #641 from amnezia-vpn/feature/linux-ipv6
Remove ipv6 address for Linux WG/AWG interface
2024-02-26 12:07:50 -08:00
lunardunno 256081e4ed Improved server cleaning (#639)
Deleting the amnezia directory in opt when cleaning the server.
2024-02-26 12:35:31 +00:00
pokamest 1dd7b0a221 Merge pull request #647 from amnezia-vpn/bugfix/ru-translations
fixed ru translations file
2024-02-26 04:17:42 -08:00
vladimir.kuznetsov 82c0b28906 fixed ru translations file 2024-02-26 17:12:46 +05:00
KsZnak 985fe083f0 split-tunneling translate (#640)
Update amneziavpn_ru.ts
2024-02-26 11:53:22 +00:00
pokamest 6a0000dc4b Merge pull request #642 from amnezia-vpn/translations/update_zh_CN
Update amneziavpn_zh_CN.ts
2024-02-26 03:47:31 -08:00
pokamest 1dd2f38066 Merge pull request #643 from amnezia-vpn/translations/update_fa_IR.ts
Update amneziavpn_fa_IR.ts
2024-02-26 03:45:04 -08:00
pokamest 004e1e3ca5 MacOS GH actions QIF fix (#645)
Install Qt Installer Framework 4.6 from R2 to keep compatibility for old MacOS. In addition, update Qt version in build scripts.
2024-02-26 10:44:28 +00:00
KsZnak 7c560d709b Update amneziavpn_fa_IR.ts 2024-02-24 22:16:18 +02:00
KsZnak d3743ad62f Update amneziavpn_zh_CN.ts 2024-02-24 22:06:05 +02:00
pokamest ac234b77e2 Merge pull request #638 from amnezia-vpn/update/update_ts
Update all translations
2024-02-24 06:59:50 -08:00
Mykola Baibuz 9886987e68 Remove ipv6 address for Linux WG/AWG interface 2024-02-24 16:07:59 +02:00
pokamest d34cb8898f Update all translations 2024-02-24 11:51:22 +00: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
Shehab Ahmed f646b38ec9 added auto-scroll for server selection list 2024-02-21 03:44:37 +02: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
pokamest a32952fde6 Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText for
all TextFields
2024-02-19 14:06:18 +00:00
isamnezia 9c4ee4014d Fix for Codacy: variable name should be between 3 and 40 characters long (#608)
Tiny fixes for iOS
2024-02-19 13:13:10 +00:00
KsZnak dc9069f1f4 Update_2_amneziavpn_ru.ts
Add new change
2024-02-19 13:37:40 +02:00
pokamest e402cacc05 Merge pull request #614 from amnezia-vpn/bugfix/translations
returned translation files to commit fab167bb34a9f7199359e3d8589a1cd1…
2024-02-19 02:23:39 -08:00
vladimir.kuznetsov a98cd248d6 returned translation files to commit fab167bb34 2024-02-19 09:31:31 +05:00
pokamest 00fbfb6a01 Merge pull request #611 from amnezia-vpn/refactoring/show-installed-containers-first
show installed protocols first
2024-02-18 11:10:37 -08:00
vladimir.kuznetsov 86c31c3766 show installed protocols first in services tab and page home containers listview 2024-02-18 13:24:21 +05:00
60 changed files with 4741 additions and 3368 deletions
+12 -7
View File
@@ -14,8 +14,8 @@ jobs:
runs-on: ubuntu-20.04 runs-on: ubuntu-20.04
env: env:
QT_VERSION: 6.5.1 QT_VERSION: 6.6.2
QIF_VERSION: 4.6 QIF_VERSION: 4.7
steps: steps:
- name: 'Install Qt' - name: 'Install Qt'
@@ -72,8 +72,8 @@ jobs:
runs-on: windows-latest runs-on: windows-latest
env: env:
QT_VERSION: 6.5.1 QT_VERSION: 6.6.2
QIF_VERSION: 4.6 QIF_VERSION: 4.7
BUILD_ARCH: 64 BUILD_ARCH: 64
steps: steps:
@@ -134,7 +134,7 @@ jobs:
runs-on: macos-13 runs-on: macos-13
env: env:
QT_VERSION: 6.5.2 QT_VERSION: 6.6.2
CC: cc CC: cc
CXX: c++ CXX: c++
@@ -245,10 +245,15 @@ jobs:
modules: 'qtremoteobjects qt5compat qtshadertools' modules: 'qtremoteobjects qt5compat qtshadertools'
dir: ${{ runner.temp }} dir: ${{ runner.temp }}
setup-python: 'true' setup-python: 'true'
tools: 'tools_ifw'
set-env: 'true' set-env: 'true'
extra: '--external 7z --base ${{ env.QT_MIRROR }}' extra: '--external 7z --base ${{ env.QT_MIRROR }}'
- name: 'Install Qt Installer Framework ${{ env.QIF_VERSION }}'
run: |
mkdir -pv ${{ runner.temp }}/Qt/Tools/QtInstallerFramework
wget https://qt.amzsvc.com/tools/ifw/${{ env.QIF_VERSION }}.zip
unzip ${{ env.QIF_VERSION }}.zip -d ${{ runner.temp }}/Qt/Tools/QtInstallerFramework/
- name: 'Get sources' - name: 'Get sources'
uses: actions/checkout@v4 uses: actions/checkout@v4
with: with:
@@ -286,7 +291,7 @@ jobs:
env: env:
ANDROID_BUILD_PLATFORM: android-34 ANDROID_BUILD_PLATFORM: android-34
QT_VERSION: 6.6.1 QT_VERSION: 6.6.2
QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools' QT_MODULES: 'qtremoteobjects qt5compat qtimageformats qtshadertools'
steps: steps:
+3
View File
@@ -131,3 +131,6 @@ client/3rd/ShadowSocks/ss_ios.xcconfig
# UML generated pics # UML generated pics
out/ out/
# CMake files
CMakeFiles/
+9
View File
@@ -15,6 +15,15 @@ set(PACKAGES
Core5Compat Concurrent LinguistTools 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) if(IOS)
set(PACKAGES ${PACKAGES} Multimedia) set(PACKAGES ${PACKAGES} Multimedia)
endif() endif()
+7 -1
View File
@@ -286,10 +286,16 @@ void AmneziaApplication::initModels()
m_containersModel.reset(new ContainersModel(this)); m_containersModel.reset(new ContainersModel(this));
m_engine->rootContext()->setContextProperty("ContainersModel", m_containersModel.get()); 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_serversModel.reset(new ServersModel(m_settings, this));
m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get()); m_engine->rootContext()->setContextProperty("ServersModel", m_serversModel.get());
connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(), connect(m_serversModel.get(), &ServersModel::containersUpdated, m_containersModel.get(),
&ContainersModel::updateModel); &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_languageModel.reset(new LanguageModel(m_settings, this));
m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get()); m_engine->rootContext()->setContextProperty("LanguageModel", m_languageModel.get());
@@ -333,7 +339,7 @@ void AmneziaApplication::initModels()
connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this, connect(m_configurator.get(), &VpnConfigurator::newVpnConfigCreated, this,
[this](const QString &clientId, const QString &clientName, const DockerContainer container, [this](const QString &clientId, const QString &clientName, const DockerContainer container,
ServerCredentials credentials) { ServerCredentials credentials) {
m_serversModel->reloadContainerConfig(); m_serversModel->reloadDefaultServerContainerConfig();
m_clientManagementModel->appendClient(clientId, clientName, container, credentials); m_clientManagementModel->appendClient(clientId, clientName, container, credentials);
emit m_configurator->clientModelUpdated(); emit m_configurator->clientModelUpdated();
}); });
+1
View File
@@ -92,6 +92,7 @@ private:
QCommandLineParser m_parser; QCommandLineParser m_parser;
QSharedPointer<ContainersModel> m_containersModel; QSharedPointer<ContainersModel> m_containersModel;
QSharedPointer<ContainersModel> m_defaultServerContainersModel;
QSharedPointer<ServersModel> m_serversModel; QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<LanguageModel> m_languageModel; QSharedPointer<LanguageModel> m_languageModel;
QSharedPointer<ProtocolsModel> m_protocolsModel; 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("hopindex", QJsonValue((double)hop.m_hopindex));
json.insert("privateKey", wgConfig.value(amnezia::config_key::client_priv_key)); json.insert("privateKey", wgConfig.value(amnezia::config_key::client_priv_key));
json.insert("deviceIpv4Address", wgConfig.value(amnezia::config_key::client_ip)); json.insert("deviceIpv4Address", wgConfig.value(amnezia::config_key::client_ip));
// todo review wg ipv6
#ifdef Q_OS_MACOS
json.insert("deviceIpv6Address", "dead::1"); json.insert("deviceIpv6Address", "dead::1");
#endif
json.insert("serverPublicKey", wgConfig.value(amnezia::config_key::server_pub_key)); json.insert("serverPublicKey", wgConfig.value(amnezia::config_key::server_pub_key));
json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key)); json.insert("serverPskKey", wgConfig.value(amnezia::config_key::psk_key));
json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName)); json.insert("serverIpv4AddrIn", wgConfig.value(amnezia::config_key::hostName));
@@ -175,7 +175,7 @@ class PacketTunnelProvider: NEPacketTunnelProvider {
return return
} }
guard let wgConfigStr = try? JSONDecoder().decode(WGConfig.self, from: wgConfig).wg, guard let wgConfigStr = try? JSONDecoder().decode(WGConfig.self, from: wgConfig).str,
let tunnelConfiguration = try? TunnelConfiguration(fromWgQuickConfig: wgConfigStr) let tunnelConfiguration = try? TunnelConfiguration(fromWgQuickConfig: wgConfigStr)
else { else {
wg_log(.error, message: "Can't parse WireGuard config") wg_log(.error, message: "Can't parse WireGuard config")
+28 -26
View File
@@ -1,22 +1,23 @@
import Foundation import Foundation
struct WGConfigData: Decodable { struct WGConfigData: Decodable {
let h1, h2, h3, h4: String? let initPacketMagicHeader, responsePacketMagicHeader: String?
let jc, jmax, jmin: String? let underloadPacketMagicHeader, transportPacketMagicHeader: String?
let s1, s2: String? let junkPacketCount, junkPacketMinSize, junkPacketMaxSize: String?
let initPacketJunkSize, responsePacketJunkSize: String?
var settings: String { var settings: String {
jc == nil ? "" : junkPacketCount == nil ? "" :
""" """
Jc = \(jc!) Jc = \(junkPacketCount!)
Jmin = \(jmin!) Jmin = \(junkPacketMinSize!)
Jmax = \(jmax!) Jmax = \(junkPacketMaxSize!)
S1 = \(s1!) S1 = \(initPacketJunkSize!)
S2 = \(s2!) S2 = \(responsePacketJunkSize!)
H1 = \(h1!) H1 = \(initPacketMagicHeader!)
H2 = \(h2!) H2 = \(responsePacketMagicHeader!)
H3 = \(h3!) H3 = \(underloadPacketMagicHeader!)
H4 = \(h4!) H4 = \(transportPacketMagicHeader!)
""" """
} }
@@ -33,9 +34,10 @@ struct WGConfigData: Decodable {
var persistentKeepAlive: String var persistentKeepAlive: String
enum CodingKeys: String, CodingKey { enum CodingKeys: String, CodingKey {
case h1 = "H1", h2 = "H2", h3 = "H3", h4 = "H4" case initPacketMagicHeader = "H1", responsePacketMagicHeader = "H2"
case jc = "Jc", jmax = "Jmax", jmin = "Jmin" case underloadPacketMagicHeader = "H3", transportPacketMagicHeader = "H4"
case s1 = "S1", s2 = "S2" case junkPacketCount = "Jc", junkPacketMinSize = "Jmin", junkPacketMaxSize = "Jmax"
case initPacketJunkSize = "S1", responsePacketJunkSize = "S2"
case clientIP = "client_ip" // "10.8.1.16" case clientIP = "client_ip" // "10.8.1.16"
case clientPrivateKey = "client_priv_key" case clientPrivateKey = "client_priv_key"
@@ -51,15 +53,15 @@ struct WGConfigData: Decodable {
init(from decoder: Decoder) throws { init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self) let container = try decoder.container(keyedBy: CodingKeys.self)
self.h1 = try container.decodeIfPresent(String.self, forKey: .h1) self.initPacketMagicHeader = try container.decodeIfPresent(String.self, forKey: .initPacketMagicHeader)
self.h2 = try container.decodeIfPresent(String.self, forKey: .h2) self.responsePacketMagicHeader = try container.decodeIfPresent(String.self, forKey: .responsePacketMagicHeader)
self.h3 = try container.decodeIfPresent(String.self, forKey: .h3) self.underloadPacketMagicHeader = try container.decodeIfPresent(String.self, forKey: .underloadPacketMagicHeader)
self.h4 = try container.decodeIfPresent(String.self, forKey: .h4) self.transportPacketMagicHeader = try container.decodeIfPresent(String.self, forKey: .transportPacketMagicHeader)
self.jc = try container.decodeIfPresent(String.self, forKey: .jc) self.junkPacketCount = try container.decodeIfPresent(String.self, forKey: .junkPacketCount)
self.jmax = try container.decodeIfPresent(String.self, forKey: .jmax) self.junkPacketMinSize = try container.decodeIfPresent(String.self, forKey: .junkPacketMinSize)
self.jmin = try container.decodeIfPresent(String.self, forKey: .jmin) self.junkPacketMaxSize = try container.decodeIfPresent(String.self, forKey: .junkPacketMaxSize)
self.s1 = try container.decodeIfPresent(String.self, forKey: .s1) self.initPacketJunkSize = try container.decodeIfPresent(String.self, forKey: .initPacketJunkSize)
self.s2 = try container.decodeIfPresent(String.self, forKey: .s2) self.responsePacketJunkSize = try container.decodeIfPresent(String.self, forKey: .responsePacketJunkSize)
self.clientIP = try container.decode(String.self, forKey: .clientIP) self.clientIP = try container.decode(String.self, forKey: .clientIP)
self.clientPrivateKey = try container.decode(String.self, forKey: .clientPrivateKey) self.clientPrivateKey = try container.decode(String.self, forKey: .clientPrivateKey)
self.clientPublicKey = try container.decode(String.self, forKey: .clientPublicKey) self.clientPublicKey = try container.decode(String.self, forKey: .clientPublicKey)
@@ -115,7 +117,7 @@ struct WGConfig: Decodable {
self.splitTunnelType = try container.decode(Int.self, forKey: .splitTunnelType) self.splitTunnelType = try container.decode(Int.self, forKey: .splitTunnelType)
} }
var wg: String { var str: String {
""" """
[Interface] [Interface]
Address = \(data.clientIP)/32 Address = \(data.clientIP)/32
+2
View File
@@ -224,6 +224,8 @@
<file>ui/qml/Pages2/PageShareFullAccess.qml</file> <file>ui/qml/Pages2/PageShareFullAccess.qml</file>
<file>images/controls/close.svg</file> <file>images/controls/close.svg</file>
<file>images/controls/search.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/Controls2/DrawerType2.qml</file>
</qresource> </qresource>
</RCC> </RCC>
@@ -1,4 +1,5 @@
sudo docker ps -a | grep amnezia | awk '{print $1}' | xargs sudo docker stop sudo docker ps -a | grep amnezia | awk '{print $1}' | xargs sudo docker stop;\
sudo docker ps -a | grep amnezia | awk '{print $1}' | xargs sudo docker rm -fv sudo docker ps -a | grep amnezia | awk '{print $1}' | xargs sudo docker rm -fv;\
sudo docker images -a | grep amnezia | awk '{print $3}' | xargs sudo docker rmi sudo docker images -a | grep amnezia | awk '{print $3}' | xargs sudo docker rmi;\
sudo docker network ls | grep amnezia-dns-net | awk '{print $1}' | xargs sudo docker network rm sudo docker network ls | grep amnezia-dns-net | awk '{print $1}' | xargs sudo docker network rm;\
sudo rm -frd /opt/amnezia
+2 -2
View File
@@ -1,3 +1,3 @@
sudo docker stop $CONTAINER_NAME sudo docker stop $CONTAINER_NAME;\
sudo docker rm -fv $CONTAINER_NAME sudo docker rm -fv $CONTAINER_NAME;\
sudo docker rmi $CONTAINER_NAME sudo docker rmi $CONTAINER_NAME
+196 -165
View File
@@ -92,7 +92,7 @@
<context> <context>
<name>ExportController</name> <name>ExportController</name>
<message> <message>
<location filename="../ui/controllers/exportController.cpp" line="38"/> <location filename="../ui/controllers/exportController.cpp" line="39"/>
<source>Access error!</source> <source>Access error!</source>
<translation>خطأ في الوصول!</translation> <translation>خطأ في الوصول!</translation>
</message> </message>
@@ -100,16 +100,60 @@
<context> <context>
<name>HomeContainersListView</name> <name>HomeContainersListView</name>
<message> <message>
<location filename="../ui/qml/Components/HomeContainersListView.qml" line="58"/> <location filename="../ui/qml/Components/HomeContainersListView.qml" line="59"/>
<source>Unable change protocol while there is an active connection</source> <source>Unable change protocol while there is an active connection</source>
<translation>قم بتغيير البروتوكول عند تواجد اتصال</translation> <translation>قم بتغيير البروتوكول عند تواجد اتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/HomeContainersListView.qml" line="67"/> <location filename="../ui/qml/Components/HomeContainersListView.qml" line="68"/>
<source>The selected protocol is not supported on the current platform</source> <source>The selected protocol is not supported on the current platform</source>
<translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation> <translation>البروتوكول المحدد غير مدعوم علي المنصة الحالية</translation>
</message> </message>
</context> </context>
<context>
<name>HomeSplitTunnelingDrawer</name>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="32"/>
<source>Split tunneling</source>
<translation type="unfinished">تقسيم الانفاق</translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="33"/>
<source>Allows you to connect to some sites or applications through a VPN connection and bypass others</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="42"/>
<source>Split tunneling on the server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="43"/>
<source>Enabled
Can&apos;t be disabled for current server</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="62"/>
<source>Site-based split tunneling</source>
<translation type="unfinished">انقسام الانفاق القائم علي الموقع</translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="63"/>
<source>Enabled</source>
<translation type="unfinished">مٌفعل</translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="63"/>
<source>Disabled</source>
<translation type="unfinished">مٌعطل</translation>
</message>
<message>
<location filename="../ui/qml/Components/HomeSplitTunnelingDrawer.qml" line="79"/>
<source>App-based split tunneling</source>
<translation type="unfinished">انقسام الانفاق القائم علي التطبيق</translation>
</message>
</context>
<context> <context>
<name>ImportController</name> <name>ImportController</name>
<message> <message>
@@ -270,17 +314,27 @@ Already installed containers were found on the server. All installed containers
<context> <context>
<name>PageHome</name> <name>PageHome</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageHome.qml" line="184"/> <location filename="../ui/qml/Pages2/PageHome.qml" line="61"/>
<source>Split tunneling enabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageHome.qml" line="61"/>
<source>Split tunneling disabled</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageHome.qml" line="224"/>
<source>VPN protocol</source> <source>VPN protocol</source>
<translation>بروتوكول VPN</translation> <translation>بروتوكول VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageHome.qml" line="229"/> <location filename="../ui/qml/Pages2/PageHome.qml" line="272"/>
<source>Servers</source> <source>Servers</source>
<translation>الخوادم</translation> <translation>الخوادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageHome.qml" line="331"/> <location filename="../ui/qml/Pages2/PageHome.qml" line="360"/>
<source>Unable change server while there is an active connection</source> <source>Unable change server while there is an active connection</source>
<translation>لا يمكن تغير الخادم بينما هناك اتصال مفعل</translation> <translation>لا يمكن تغير الخادم بينما هناك اتصال مفعل</translation>
</message> </message>
@@ -297,51 +351,6 @@ Already installed containers were found on the server. All installed containers
<source>Port</source> <source>Port</source>
<translation>منفذ</translation> <translation>منفذ</translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="114"/>
<source>Junk packet count</source>
<translation>عدد الحزم الغير مرغوب فيها</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="139"/>
<source>Junk packet minimum size</source>
<translation>الحد الادني لحجم الحزمة الغير مرغوب فيها</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="159"/>
<source>Junk packet maximum size</source>
<translation>الحجم الاقصي للحزمة الغير مرغوب فيها</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="179"/>
<source>Init packet junk size</source>
<translation>Init packet junk size</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="199"/>
<source>Response packet junk size</source>
<translation>حجم حزمة الاستجابة الغير مرغوب فيها</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="219"/>
<source>Init packet magic header</source>
<translation>إطلاق حزمة magic header</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="239"/>
<source>Response packet magic header</source>
<translation>حزمة الرد magic header</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="259"/>
<source>Transport packet magic header</source>
<translation>نقل حزمة magic header</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="279"/>
<source>Underload packet magic header</source>
<translation>تحميل حزمة magic header</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="304"/> <location filename="../ui/qml/Pages2/PageProtocolAwgSettings.qml" line="304"/>
<source>Remove AmneziaWG</source> <source>Remove AmneziaWG</source>
@@ -997,6 +1006,11 @@ And if you don&apos;t like the app, all the more support it - the donation will
<source>https://amnezia.org</source> <source>https://amnezia.org</source>
<translation></translation> <translation></translation>
</message> </message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="178"/>
<source>Software version: %1</source>
<translation>%1 :إصدار البرنامج</translation>
</message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="194"/> <location filename="../ui/qml/Pages2/PageSettingsAbout.qml" line="194"/>
<source>Check for updates</source> <source>Check for updates</source>
@@ -1035,56 +1049,66 @@ And if you don&apos;t like the app, all the more support it - the donation will
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="93"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="93"/>
<source>Auto connect</source>
<translation type="unfinished">الاتصال التلقائي</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="94"/>
<source>Connect to VPN on app start</source>
<translation type="unfinished">اتصل ب ال VPN عند تشغيل التطبيق</translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="114"/>
<source>Start minimized</source> <source>Start minimized</source>
<translation>ابدأ ب الحجم الادني</translation> <translation>ابدأ ب الحجم الادني</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="94"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="115"/>
<source>Launch application minimized</source> <source>Launch application minimized</source>
<translation>تشغيل التطبيق في الحد الادني</translation> <translation>تشغيل التطبيق في الحد الادني</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="111"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="132"/>
<source>Language</source> <source>Language</source>
<translation>اللغة</translation> <translation>اللغة</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="126"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="147"/>
<source>Logging</source> <source>Logging</source>
<translation>تسجيل</translation> <translation>تسجيل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="127"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="148"/>
<source>Enabled</source> <source>Enabled</source>
<translation>مٌفعل</translation> <translation>مٌفعل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="127"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="148"/>
<source>Disabled</source> <source>Disabled</source>
<translation>مٌعطل</translation> <translation>مٌعطل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="140"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="161"/>
<source>Reset settings and remove all data from the application</source> <source>Reset settings and remove all data from the application</source>
<translation>إعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق</translation> <translation>إعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="144"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="166"/>
<source>Reset settings and remove all data from the application?</source> <source>Reset settings and remove all data from the application?</source>
<translation>إعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق؟</translation> <translation>إعادة ضبط الاعدادات ومسح جميع البيانات من التطبيق؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="145"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="167"/>
<source>All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.</source> <source>All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.</source>
<translation>سيتم ضبط الاعدادات الافتراضية. جميع خدمات AmneziaVPN المٌثبتة ستبقي علي الخادم.</translation> <translation>سيتم ضبط الاعدادات الافتراضية. جميع خدمات AmneziaVPN المٌثبتة ستبقي علي الخادم.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="146"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="168"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="147"/> <location filename="../ui/qml/Pages2/PageSettingsApplication.qml" line="169"/>
<source>Cancel</source> <source>Cancel</source>
<translation>إلغاء</translation> <translation>إلغاء</translation>
</message> </message>
@@ -1139,7 +1163,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="122"/>
<source>Restore from backup</source> <source>Restore from backup</source>
<translation>استرجاع من ملف احتياطي</translation> <translation>استرجاع من ملف يحتوي علي نسخة احتياطية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="125"/> <location filename="../ui/qml/Pages2/PageSettingsBackup.qml" line="125"/>
@@ -1175,22 +1199,20 @@ And if you don&apos;t like the app, all the more support it - the donation will
<translation>الاتصال</translation> <translation>الاتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="50"/>
<source>Auto connect</source> <source>Auto connect</source>
<translation>الاتصال التلقائي</translation> <translation type="vanished">الاتصال التلقائي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="51"/>
<source>Connect to VPN on app start</source> <source>Connect to VPN on app start</source>
<translation>اتصل ب ال VPN عند تشغيل التطبيق</translation> <translation type="vanished">اتصل ب ال VPN عند تشغيل التطبيق</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="86"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="65"/>
<source>When AmneziaDNS is not used or installed</source> <source>When AmneziaDNS is not used or installed</source>
<translation>عندما يكون AmneziaDNS غير مٌثبت او غير مستخدم</translation> <translation>عندما يكون AmneziaDNS غير مٌثبت او غير مستخدم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="120"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="99"/>
<source>Allows you to use the VPN only for certain Apps</source> <source>Allows you to use the VPN only for certain Apps</source>
<translation>يسمح لك بأستخدام ال VPN علي تطبيقات معينة</translation> <translation>يسمح لك بأستخدام ال VPN علي تطبيقات معينة</translation>
</message> </message>
@@ -1199,32 +1221,32 @@ And if you don&apos;t like the app, all the more support it - the donation will
<translation type="obsolete">استخدم AmneziaDNS إذا كان مٌثبت علي الخادم</translation> <translation type="obsolete">استخدم AmneziaDNS إذا كان مٌثبت علي الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="69"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="48"/>
<source>Use AmneziaDNS</source> <source>Use AmneziaDNS</source>
<translation>استخدم AmneziaDNS</translation> <translation>استخدم AmneziaDNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="70"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="49"/>
<source>If AmneziaDNS is installed on the server</source> <source>If AmneziaDNS is installed on the server</source>
<translation>في حالة كان AmneziaDNS مٌثبت علي الخادم</translation> <translation>في حالة كان AmneziaDNS مٌثبت علي الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="85"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="64"/>
<source>DNS servers</source> <source>DNS servers</source>
<translation>خوادم DNS</translation> <translation>خوادم DNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="101"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="80"/>
<source>Site-based split tunneling</source> <source>Site-based split tunneling</source>
<translation>انقسام الانفاق القائم علي الموقع</translation> <translation>انقسام الانفاق القائم علي الموقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="102"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="81"/>
<source>Allows you to select which sites you want to access through the VPN</source> <source>Allows you to select which sites you want to access through the VPN</source>
<translation>يسمح لك بتحديد اي موقع تريد الوصول له عن طريق ال VPN</translation> <translation>يسمح لك بتحديد اي موقع تريد الوصول له عن طريق ال VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="119"/> <location filename="../ui/qml/Pages2/PageSettingsConnection.qml" line="98"/>
<source>App-based split tunneling</source> <source>App-based split tunneling</source>
<translation>انقسام الانفاق القائم علي التطبيق</translation> <translation>انقسام الانفاق القائم علي التطبيق</translation>
</message> </message>
@@ -1244,62 +1266,62 @@ And if you don&apos;t like the app, all the more support it - the donation will
<context> <context>
<name>PageSettingsDns</name> <name>PageSettingsDns</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="37"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="39"/>
<source>Default server does not support custom dns</source> <source>Default server does not support custom dns</source>
<translation>الخادم الافتراضي لا يدعم DNS مخصص</translation> <translation>الخادم الافتراضي لا يدعم DNS مخصص</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="55"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="57"/>
<source>DNS servers</source> <source>DNS servers</source>
<translation>خوادم ال DNS</translation> <translation>خوادم ال DNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="60"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="62"/>
<source>If AmneziaDNS is not used or installed</source> <source>If AmneziaDNS is not used or installed</source>
<translation>AmneziaVPN ليس مٌستخدم او مٌثبت</translation> <translation>AmneziaVPN ليس مٌستخدم او مٌثبت</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="67"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="69"/>
<source>Primary DNS</source> <source>Primary DNS</source>
<translation>الرئيسي DNS</translation> <translation>الرئيسي DNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="81"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="83"/>
<source>Secondary DNS</source> <source>Secondary DNS</source>
<translation>الثانوي DNS</translation> <translation>الثانوي DNS</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="101"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="103"/>
<source>Restore default</source> <source>Restore default</source>
<translation>استعادة الافتراضي</translation> <translation>استعادة الافتراضي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="104"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="106"/>
<source>Restore default DNS settings?</source> <source>Restore default DNS settings?</source>
<translation>قم بأعادة ضبط إعدادات ال DNS الافتراضية؟</translation> <translation>قم بأعادة ضبط إعدادات ال DNS الافتراضية؟</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="105"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="107"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="106"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="108"/>
<source>Cancel</source> <source>Cancel</source>
<translation>إلغاء</translation> <translation>إلغاء</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="113"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="115"/>
<source>Settings have been reset</source> <source>Settings have been reset</source>
<translation>لم يتم إعادة ضبط الإعدادات</translation> <translation>لم يتم إعادة ضبط الإعدادات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="127"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="129"/>
<source>Save</source> <source>Save</source>
<translation>احفظ</translation> <translation>احفظ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="136"/> <location filename="../ui/qml/Pages2/PageSettingsDns.qml" line="138"/>
<source>Settings saved</source> <source>Settings saved</source>
<translation>تم حفظ الإعدادات</translation> <translation>تم حفظ الإعدادات</translation>
</message> </message>
@@ -1339,7 +1361,7 @@ And if you don&apos;t like the app, all the more support it - the donation will
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="128"/> <location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="128"/>
<source>Save logs to file</source> <source>Save logs to file</source>
<translation>احفظ السجلات لملف</translation> <translation>احفظ السجلات في ملف</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="146"/> <location filename="../ui/qml/Pages2/PageSettingsLogging.qml" line="146"/>
@@ -1486,27 +1508,27 @@ And if you don&apos;t like the app, all the more support it - the donation will
<context> <context>
<name>PageSettingsServerInfo</name> <name>PageSettingsServerInfo</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="109"/> <location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="105"/>
<source>Server name</source> <source>Server name</source>
<translation>اسم الخادم</translation> <translation>اسم الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="122"/> <location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="118"/>
<source>Save</source> <source>Save</source>
<translation>احفظ</translation> <translation>احفظ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="153"/> <location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="155"/>
<source>Protocols</source> <source>Protocols</source>
<translation>البروتوكولات</translation> <translation>البروتوكولات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="159"/> <location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="161"/>
<source>Services</source> <source>Services</source>
<translation>الخدمات</translation> <translation>الخدمات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="163"/> <location filename="../ui/qml/Pages2/PageSettingsServerInfo.qml" line="165"/>
<source>Data</source> <source>Data</source>
<translation>البيانات</translation> <translation>البيانات</translation>
</message> </message>
@@ -1575,95 +1597,100 @@ And if you don&apos;t like the app, all the more support it - the donation will
<translation type="obsolete">قسم نفق الموقع</translation> <translation type="obsolete">قسم نفق الموقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="31"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="36"/>
<source>Default server does not support split tunneling function</source> <source>Default server does not support split tunneling function</source>
<translation>السرفر الافتراضي لا يدعم ميزة تقسيم الانفاق</translation> <translation>السرفر الافتراضي لا يدعم ميزة تقسيم الانفاق</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="66"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="74"/>
<source>Addresses from the list should not be accessed via VPN</source> <source>Addresses from the list should not be accessed via VPN</source>
<translation>لا يجب الولوج للعنواين المذكورة هنا من خلال ال VPN</translation> <translation>لا يجب الولوج للعنواين المذكورة هنا من خلال ال VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="98"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="106"/>
<source>Split tunneling</source> <source>Split tunneling</source>
<translation>تقسيم الانفاق</translation> <translation>تقسيم الانفاق</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="130"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="138"/>
<source>Mode</source> <source>Mode</source>
<translation>وضع</translation> <translation>وضع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="208"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="216"/>
<source>Remove </source> <source>Remove </source>
<translation>احذف </translation> <translation>احذف </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="209"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="217"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="210"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="218"/>
<source>Cancel</source> <source>Cancel</source>
<translation>إلغاء</translation> <translation>إلغاء</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="61"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="69"/>
<source>Only the sites listed here will be accessed through the VPN</source> <source>Only the sites listed here will be accessed through the VPN</source>
<translation>سيتم الولوج للمواقع المذكورة هنا فقط عن طريق ال VPN</translation> <translation>سيتم الولوج للمواقع المذكورة هنا فقط عن طريق ال VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="254"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="33"/>
<source>Cannot change split tunneling settings during active connection</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="262"/>
<source>website or IP</source> <source>website or IP</source>
<translation>موقع او IP</translation> <translation>موقع او IP</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="295"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="303"/>
<source>Import / Export Sites</source> <source>Import / Export Sites</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="301"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="309"/>
<source>Import</source> <source>Import</source>
<translation>استرد</translation> <translation>استرد</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="313"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="321"/>
<source>Save site list</source> <source>Save site list</source>
<translation>احفظ قائمة المواقع</translation> <translation>احفظ قائمة المواقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="320"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="328"/>
<source>Save sites</source> <source>Save sites</source>
<translation>احفظ المواقع</translation> <translation>احفظ المواقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="321"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="329"/>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="390"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="398"/>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="405"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="413"/>
<source>Sites files (*.json)</source> <source>Sites files (*.json)</source>
<translation></translation> <translation></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="380"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="388"/>
<source>Import a list of sites</source> <source>Import a list of sites</source>
<translation>استرد قائمة من المواقع</translation> <translation>استرد قائمة من المواقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="386"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="394"/>
<source>Replace site list</source> <source>Replace site list</source>
<translation>تبديل قائمة المواقع</translation> <translation>تبديل قائمة المواقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="389"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="397"/>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="404"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="412"/>
<source>Open sites file</source> <source>Open sites file</source>
<translation>افتح ملف المواقع</translation> <translation>افتح ملف المواقع</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="401"/> <location filename="../ui/qml/Pages2/PageSettingsSplitTunneling.qml" line="409"/>
<source>Add imported sites to existing ones</source> <source>Add imported sites to existing ones</source>
<translation>إضافة المواقع المستردة للمواقع الموجودة</translation> <translation>إضافة المواقع المستردة للمواقع الموجودة</translation>
</message> </message>
@@ -1937,7 +1964,8 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="42"/> <location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="42"/>
<source>A line that starts with vpn://...</source> <source>A line that starts with vpn://...</source>
<translation>سطر يبدأ ب vpn://...</translation> <translatorcomment>يجب ان تٌكتب بهذه الطريقة حتي بوجود الخطأ كي تظهر بشكل صحيح داخل التطبيق</translatorcomment>
<translation>سطر يبدأ ب ...//:vpn</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="53"/> <location filename="../ui/qml/Pages2/PageSetupWizardTextKey.qml" line="53"/>
@@ -1986,128 +2014,138 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<context> <context>
<name>PageShare</name> <name>PageShare</name>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="54"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="58"/>
<source>Save OpenVPN config</source> <source>Save OpenVPN config</source>
<translation>احفظ تكوين OpenVPN</translation> <translation>احفظ تكوين OpenVPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="61"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="65"/>
<source>Save WireGuard config</source> <source>Save WireGuard config</source>
<translation>احفظ تكوين WireGuard</translation> <translation>احفظ تكوين WireGuard</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="68"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="72"/>
<source>Save AmneziaWG config</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="79"/>
<source>Save ShadowSocks config</source> <source>Save ShadowSocks config</source>
<translation>احفظ تكوين ShadowSocks</translation> <translation>احفظ تكوين ShadowSocks</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="75"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="86"/>
<source>Save Cloak config</source> <source>Save Cloak config</source>
<translation>احفظ تكوين Cloak</translation> <translation>احفظ تكوين Cloak</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="100"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="111"/>
<source>For the AmneziaVPN app</source> <source>For the AmneziaVPN app</source>
<translation>AmneziaVPN من اجل تطبيق</translation> <translation>AmneziaVPN من اجل تطبيق</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="105"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="116"/>
<source>OpenVpn native format</source> <source>OpenVpn native format</source>
<translation>تنسيق OpenVpn الاصلي</translation> <translation>تنسيق OpenVpn الاصلي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="110"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="121"/>
<source>WireGuard native format</source> <source>WireGuard native format</source>
<translation>تنسيق WireGuard الاصلي</translation> <translation>تنسيق WireGuard الاصلي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="115"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="126"/>
<source>AmneziaWG native format</source>
<translation type="unfinished"></translation>
</message>
<message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="131"/>
<source>ShadowSocks native format</source> <source>ShadowSocks native format</source>
<translation>تنسيق ShadowSocks الاصلي</translation> <translation>تنسيق ShadowSocks الاصلي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="120"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="136"/>
<source>Cloak native format</source> <source>Cloak native format</source>
<translation>تنسيق Cloak الاصلي</translation> <translation>تنسيق Cloak الاصلي</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="145"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="161"/>
<source>Share VPN Access</source> <source>Share VPN Access</source>
<translation>شارك اتصال VPN</translation> <translation>شارك اتصال VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="174"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="190"/>
<source>Share full access to the server and VPN</source> <source>Share full access to the server and VPN</source>
<translation>شارك ولوج كامل للخادم و ال VPN</translation> <translation>شارك ولوج كامل للخادم و ال VPN</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="175"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="191"/>
<source>Use for your own devices, or share with those you trust to manage the server.</source> <source>Use for your own devices, or share with those you trust to manage the server.</source>
<translation>استخدمه للأجهزة الخاصة بك، أو شاركه مع من تثق بهم لإدارة الخادم.</translation> <translation>استخدمه للأجهزة الخاصة بك، أو شاركه مع من تثق بهم لإدارة الخادم.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="227"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="243"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="486"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="504"/>
<source>Users</source> <source>Users</source>
<translation>المستخدمين</translation> <translation>المستخدمين</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="247"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="263"/>
<source>Share VPN access without the ability to manage the server</source> <source>Share VPN access without the ability to manage the server</source>
<translation>شارك اتصال VPN بدون القدرة علي إدارة الخادم</translation> <translation>شارك اتصال VPN بدون القدرة علي إدارة الخادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="502"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="520"/>
<source>Search</source> <source>Search</source>
<translation>ابحث</translation> <translation>ابحث</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="586"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="604"/>
<source>Creation date: </source> <source>Creation date: </source>
<translation>تاريخ الإنشاء: </translation> <translation>تاريخ الإنشاء: </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="600"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="618"/>
<source>Rename</source> <source>Rename</source>
<translation>إعادة التسمية</translation> <translation>إعادة التسمية</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="632"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="650"/>
<source>Client name</source> <source>Client name</source>
<translation>اسم العميل</translation> <translation>اسم العميل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="645"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="663"/>
<source>Save</source> <source>Save</source>
<translation>احفظ</translation> <translation>احفظ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="677"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="695"/>
<source>Revoke</source> <source>Revoke</source>
<translation>سحب وإبطال</translation> <translation>سحب وإبطال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="680"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="698"/>
<source>Revoke the config for a user - %1?</source> <source>Revoke the config for a user - %1?</source>
<translation>سحب وإبطال للمستخدم - %1?</translation> <translation>سحب وإبطال للمستخدم - %1?</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="681"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="699"/>
<source>The user will no longer be able to connect to your server.</source> <source>The user will no longer be able to connect to your server.</source>
<translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation> <translation>المستخدم لن يكون قادر علي الاتصال بعد الان.</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="682"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="700"/>
<source>Continue</source> <source>Continue</source>
<translation>واصل</translation> <translation>واصل</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="683"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="701"/>
<source>Cancel</source> <source>Cancel</source>
<translation>إلغاء</translation> <translation>إلغاء</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="216"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="232"/>
<source>Connection</source> <source>Connection</source>
<translation>الاتصال</translation> <translation>الاتصال</translation>
</message> </message>
@@ -2120,13 +2158,13 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="obsolete">الخوادم</translation> <translation type="obsolete">الخوادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="279"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="295"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="280"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="296"/>
<source>Server</source> <source>Server</source>
<translation>خادم</translation> <translation>خادم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="44"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="45"/>
<source>File with connection settings to </source> <source>File with connection settings to </source>
<translation>ملف بإعدادات إلي </translation> <translation>ملف بإعدادات إلي </translation>
</message> </message>
@@ -2135,35 +2173,35 @@ It&apos;s okay as long as it&apos;s from someone you trust.</source>
<translation type="obsolete">البروتوكولات</translation> <translation type="obsolete">البروتوكولات</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="332"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="348"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="333"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="349"/>
<source>Protocol</source> <source>Protocol</source>
<translation>بروتوكول</translation> <translation>بروتوكول</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="43"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="44"/>
<source>Connection to </source> <source>Connection to </source>
<translation>اتصال إلي </translation> <translation>اتصال إلي </translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="36"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="37"/>
<source>Config revoked</source> <source>Config revoked</source>
<translation>تم سحب وإبطال التكوين</translation> <translation>تم سحب وإبطال التكوين</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="258"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="274"/>
<source>User name</source> <source>User name</source>
<translation>اسم المستخدم</translation> <translation>اسم المستخدم</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="431"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="449"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="432"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="450"/>
<source>Connection format</source> <source>Connection format</source>
<translation>تنسيق الاتصال</translation> <translation>تنسيق الاتصال</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Pages2/PageShare.qml" line="182"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="198"/>
<location filename="../ui/qml/Pages2/PageShare.qml" line="469"/> <location filename="../ui/qml/Pages2/PageShare.qml" line="487"/>
<source>Share</source> <source>Share</source>
<translation>شارك</translation> <translation>شارك</translation>
</message> </message>
@@ -2993,11 +3031,6 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
</context> </context>
<context> <context>
<name>SettingsController</name> <name>SettingsController</name>
<message>
<location filename="../ui/controllers/settingsController.cpp" line="31"/>
<source>Software version</source>
<translation>إصدار البرنامج</translation>
</message>
<message> <message>
<location filename="../ui/controllers/settingsController.cpp" line="139"/> <location filename="../ui/controllers/settingsController.cpp" line="139"/>
<source>Backup file is corrupted</source> <source>Backup file is corrupted</source>
@@ -3033,20 +3066,18 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<translation>انسخ</translation> <translation>انسخ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="115"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="167"/>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="140"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="177"/>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="181"/>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="191"/>
<source>Copied</source> <source>Copied</source>
<translation>تم النسخ</translation> <translation>تم النسخ</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="133"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="126"/>
<source>Copy config string</source> <source>Copy config string</source>
<translation>انسخ نص التكوين</translation> <translation>انسخ نص التكوين</translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="155"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="141"/>
<source>Show connection settings</source> <source>Show connection settings</source>
<translation>اظهر إعدادات الاتصال</translation> <translation>اظهر إعدادات الاتصال</translation>
</message> </message>
@@ -3055,7 +3086,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<translation type="obsolete"></translation> <translation type="obsolete"></translation>
</message> </message>
<message> <message>
<location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="319"/> <location filename="../ui/qml/Components/ShareConnectionDrawer.qml" line="305"/>
<source>To read the QR code in the Amnezia app, select &quot;Add server&quot; &quot;I have data to connect&quot; &quot;QR code, key or settings file&quot;</source> <source>To read the QR code in the Amnezia app, select &quot;Add server&quot; &quot;I have data to connect&quot; &quot;QR code, key or settings file&quot;</source>
<translation>حتي تقرأ رمز ال QR في تطبيق Amnezia, اختار &quot;إضافة خادم&quot; - &quot;لدي بيانات الاتصال&quot; - &quot;رمز Qr, او مفتاح تعريف او ملف إعدادات&quot;</translation> <translation>حتي تقرأ رمز ال QR في تطبيق Amnezia, اختار &quot;إضافة خادم&quot; - &quot;لدي بيانات الاتصال&quot; - &quot;رمز Qr, او مفتاح تعريف او ملف إعدادات&quot;</translation>
</message> </message>
@@ -3139,7 +3170,7 @@ While it offers a blend of security, stability, and speed, it&apos;s essential t
<context> <context>
<name>TextFieldWithHeaderType</name> <name>TextFieldWithHeaderType</name>
<message> <message>
<location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="106"/> <location filename="../ui/qml/Controls2/TextFieldWithHeaderType.qml" line="108"/>
<source>The field can&apos;t be empty</source> <source>The field can&apos;t be empty</source>
<translation>الحقل لا يمكن ان يكون فارغ</translation> <translation>الحقل لا يمكن ان يكون فارغ</translation>
</message> </message>
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+2 -3
View File
@@ -136,8 +136,7 @@ void ApiController::updateServerConfigFromApi()
auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString(); auto defaultContainer = apiConfig.value(config_key::defaultContainer).toString();
serverConfig.insert(config_key::defaultContainer, defaultContainer); serverConfig.insert(config_key::defaultContainer, defaultContainer);
m_serversModel->editServer(serverConfig); m_serversModel->editServer(serverConfig, m_serversModel->getDefaultServerIndex());
emit m_serversModel->defaultContainerChanged(ContainerProps::containerFromString(defaultContainer));
} else { } else {
qDebug() << reply->error(); qDebug() << reply->error();
qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute); qDebug() << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
@@ -164,5 +163,5 @@ void ApiController::clearApiConfig()
serverConfig.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None)); 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(); int serverIndex = m_serversModel->getDefaultServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); 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); const QJsonObject &containerConfig = m_containersModel->getContainerConfig(container);
if (container == DockerContainer::None) { if (container == DockerContainer::None) {
+47 -7
View File
@@ -8,6 +8,7 @@
#include <QImage> #include <QImage>
#include <QStandardPaths> #include <QStandardPaths>
#include "configurators/awg_configurator.h"
#include "configurators/cloak_configurator.h" #include "configurators/cloak_configurator.h"
#include "configurators/openvpn_configurator.h" #include "configurators/openvpn_configurator.h"
#include "configurators/shadowsocks_configurator.h" #include "configurators/shadowsocks_configurator.h"
@@ -45,7 +46,7 @@ void ExportController::generateFullAccessConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QJsonObject config = m_settings->server(serverIndex); QJsonObject config = m_settings->server(serverIndex);
QJsonArray containers = config.value(config_key::containers).toArray(); QJsonArray containers = config.value(config_key::containers).toArray();
@@ -99,7 +100,7 @@ void ExportController::generateConnectionConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -155,7 +156,7 @@ void ExportController::generateOpenVpnConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -193,7 +194,7 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -228,11 +229,50 @@ void ExportController::generateWireGuardConfig(const QString &clientName)
emit exportConfigChanged(); 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() void ExportController::generateShadowSocksConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex());
@@ -268,7 +308,7 @@ void ExportController::generateCloakConfig()
{ {
clearPreviousConfig(); clearPreviousConfig();
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex); ServerCredentials credentials = m_serversModel->getServerCredentials(serverIndex);
DockerContainer container = static_cast<DockerContainer>(m_containersModel->getCurrentlyProcessedContainerIndex()); 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) void ExportController::revokeConfig(const int row, const DockerContainer container, ServerCredentials credentials)
{ {
ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials, ErrorCode errorCode = m_clientManagementModel->revokeClient(row, container, credentials,
m_serversModel->getCurrentlyProcessedServerIndex()); m_serversModel->getProcessedServerIndex());
if (errorCode != ErrorCode::NoError) { if (errorCode != ErrorCode::NoError) {
emit exportErrorOccurred(errorString(errorCode)); emit exportErrorOccurred(errorString(errorCode));
} }
+1
View File
@@ -34,6 +34,7 @@ public slots:
void generateConnectionConfig(const QString &clientName); void generateConnectionConfig(const QString &clientName);
void generateOpenVpnConfig(const QString &clientName); void generateOpenVpnConfig(const QString &clientName);
void generateWireGuardConfig(const QString &clientName); void generateWireGuardConfig(const QString &clientName);
void generateAwgConfig(const QString &clientName);
void generateShadowSocksConfig(); void generateShadowSocksConfig();
void generateCloakConfig(); void generateCloakConfig();
+14 -14
View File
@@ -176,7 +176,7 @@ void InstallController::installServer(DockerContainer container, QJsonObject &co
void InstallController::installContainer(DockerContainer container, QJsonObject &config) void InstallController::installContainer(DockerContainer container, QJsonObject &config)
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -238,7 +238,7 @@ bool InstallController::isServerAlreadyExists()
void InstallController::scanServerForInstalledContainers() void InstallController::scanServerForInstalledContainers()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
@@ -267,7 +267,7 @@ void InstallController::scanServerForInstalledContainers()
void InstallController::updateContainer(QJsonObject config) void InstallController::updateContainer(QJsonObject config)
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); 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_serversModel->updateContainerConfig(container, config);
m_protocolModel->updateModel(config); m_protocolModel->updateModel(config);
if ((serverIndex == m_serversModel->getDefaultServerIndex()) auto defaultContainer = qvariant_cast<DockerContainer>(m_serversModel->data(serverIndex, ServersModel::Roles::DefaultContainerRole));
&& (container == m_serversModel->getDefaultContainer(serverIndex))) { if ((serverIndex == m_serversModel->getDefaultServerIndex()) && (container == defaultContainer)) {
emit currentContainerUpdated(); emit currentContainerUpdated();
} else { } else {
emit updateContainerFinished(tr("Settings updated successfully")); emit updateContainerFinished(tr("Settings updated successfully"));
@@ -296,27 +296,27 @@ void InstallController::updateContainer(QJsonObject config)
emit installationErrorOccurred(errorString(errorCode)); 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(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->rebootServer(); 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(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
m_serversModel->removeServer(); m_serversModel->removeServer();
emit removeCurrentlyProcessedServerFinished(tr("Server '%1' was removed").arg(serverName)); emit removeProcessedServerFinished(tr("Server '%1' was removed").arg(serverName));
} }
void InstallController::removeAllContainers() void InstallController::removeAllContainers()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
ErrorCode errorCode = m_serversModel->removeAllContainers(); ErrorCode errorCode = m_serversModel->removeAllContainers();
@@ -329,7 +329,7 @@ void InstallController::removeAllContainers()
void InstallController::removeCurrentlyProcessedContainer() void InstallController::removeCurrentlyProcessedContainer()
{ {
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString(); QString serverName = m_serversModel->data(serverIndex, ServersModel::Roles::NameRole).toString();
int container = m_containersModel->getCurrentlyProcessedContainerIndex(); int container = m_containersModel->getCurrentlyProcessedContainerIndex();
@@ -377,7 +377,7 @@ void InstallController::mountSftpDrive(const QString &port, const QString &passw
QString mountPath; QString mountPath;
QString cmd; QString cmd;
int serverIndex = m_serversModel->getCurrentlyProcessedServerIndex(); int serverIndex = m_serversModel->getProcessedServerIndex();
ServerCredentials serverCredentials = ServerCredentials serverCredentials =
qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole)); qvariant_cast<ServerCredentials>(m_serversModel->data(serverIndex, ServersModel::Roles::CredentialsRole));
QString hostname = serverCredentials.hostName; QString hostname = serverCredentials.hostName;
+4 -4
View File
@@ -30,8 +30,8 @@ public slots:
void updateContainer(QJsonObject config); void updateContainer(QJsonObject config);
void removeCurrentlyProcessedServer(); void removeProcessedServer();
void rebootCurrentlyProcessedServer(); void rebootProcessedServer();
void removeAllContainers(); void removeAllContainers();
void removeCurrentlyProcessedContainer(); void removeCurrentlyProcessedContainer();
@@ -54,8 +54,8 @@ signals:
void scanServerFinished(bool isInstalledContainerFound); void scanServerFinished(bool isInstalledContainerFound);
void rebootCurrentlyProcessedServerFinished(const QString &finishedMessage); void rebootProcessedServerFinished(const QString &finishedMessage);
void removeCurrentlyProcessedServerFinished(const QString &finishedMessage); void removeProcessedServerFinished(const QString &finishedMessage);
void removeAllContainersFinished(const QString &finishedMessage); void removeAllContainersFinished(const QString &finishedMessage);
void removeCurrentlyProcessedContainerFinished(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_sitesModel(sitesModel),
m_settings(settings) 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 #ifdef Q_OS_ANDROID
if (!m_settings->isScreenshotsEnabled()) { if (!m_settings->isScreenshotsEnabled()) {
+144 -111
View File
@@ -5,19 +5,13 @@
ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent) ServersModel::ServersModel(std::shared_ptr<Settings> settings, QObject *parent)
: m_settings(settings), QAbstractListModel(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::defaultServerIndexChanged, this, &ServersModel::defaultServerNameChanged);
connect(this, &ServersModel::defaultContainerChanged, this, &ServersModel::defaultServerDescriptionChanged);
connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) { connect(this, &ServersModel::defaultServerIndexChanged, this, [this](const int serverIndex) {
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString()); 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();
connect(this, &ServersModel::currentlyProcessedServerIndexChanged, this, [this](const int serverIndex) { updateDefaultServerContainersModel();
auto defaultContainer = ContainerProps::containerFromString(m_servers.at(serverIndex).toObject().value(config_key::defaultContainer).toString());
emit ServersModel::defaultContainerChanged(defaultContainer);
}); });
} }
@@ -74,16 +68,14 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
return name; return name;
} }
case ServerDescriptionRole: { case ServerDescriptionRole: {
if (configVersion) { auto description = getServerDescription(server, index.row());
return server.value(config_key::description).toString(); return configVersion ? description : description + server.value(config_key::hostName).toString();
}
return server.value(config_key::hostName).toString();
} }
case HostNameRole: return server.value(config_key::hostName).toString(); case HostNameRole: return server.value(config_key::hostName).toString();
case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row())); case CredentialsRole: return QVariant::fromValue(serverCredentials(index.row()));
case CredentialsLoginRole: return serverCredentials(index.row()).userName; case CredentialsLoginRole: return serverCredentials(index.row()).userName;
case IsDefaultRole: return index.row() == m_defaultServerIndex; case IsDefaultRole: return index.row() == m_defaultServerIndex;
case IsCurrentlyProcessedRole: return index.row() == m_currentlyProcessedServerIndex; case IsCurrentlyProcessedRole: return index.row() == m_processedServerIndex;
case HasWriteAccessRole: { case HasWriteAccessRole: {
auto credentials = serverCredentials(index.row()); auto credentials = serverCredentials(index.row());
return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty()); return (!credentials.userName.isEmpty() && !credentials.secretData.isEmpty());
@@ -95,6 +87,13 @@ QVariant ServersModel::data(const QModelIndex &index, int role) const
case DefaultContainerRole: { case DefaultContainerRole: {
return ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); 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(); return QVariant();
@@ -111,8 +110,9 @@ void ServersModel::resetModel()
beginResetModel(); beginResetModel();
m_servers = m_settings->serversArray(); m_servers = m_settings->serversArray();
m_defaultServerIndex = m_settings->defaultServerIndex(); m_defaultServerIndex = m_settings->defaultServerIndex();
m_currentlyProcessedServerIndex = m_defaultServerIndex; m_processedServerIndex = m_defaultServerIndex;
endResetModel(); endResetModel();
emit defaultServerIndexChanged(m_defaultServerIndex);
} }
void ServersModel::setDefaultServerIndex(const int index) void ServersModel::setDefaultServerIndex(const int index)
@@ -132,12 +132,7 @@ const QString ServersModel::getDefaultServerName()
return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole)); return qvariant_cast<QString>(data(m_defaultServerIndex, NameRole));
} }
const QString ServersModel::getDefaultServerHostName() QString ServersModel::getServerDescription(const QJsonObject &server, const int index) const
{
return qvariant_cast<QString>(data(m_defaultServerIndex, HostNameRole));
}
QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
{ {
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
@@ -145,13 +140,12 @@ QString ServersModel::getDefaultServerDescription(const QJsonObject &server)
if (configVersion) { if (configVersion) {
return server.value(config_key::description).toString(); return server.value(config_key::description).toString();
} else if (isDefaultServerHasWriteAccess()) { } else if (data(index, HasWriteAccessRole).toBool()) {
if (m_isAmneziaDnsEnabled if (m_isAmneziaDnsEnabled && isAmneziaDnsContainerInstalled(index)) {
&& isAmneziaDnsContainerInstalled(m_defaultServerIndex)) {
description += "Amnezia DNS | "; description += "Amnezia DNS | ";
} }
} else { } else {
if (isDefaultServerConfigContainsAmneziaDns()) { if (data(index, HasAmneziaDns).toBool()) {
description += "Amnezia DNS | "; description += "Amnezia DNS | ";
} }
} }
@@ -162,7 +156,7 @@ const QString ServersModel::getDefaultServerDescriptionCollapsed()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server); auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@@ -176,7 +170,7 @@ const QString ServersModel::getDefaultServerDescriptionExpanded()
{ {
const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject(); const QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
const auto configVersion = server.value(config_key::configVersion).toInt(); const auto configVersion = server.value(config_key::configVersion).toInt();
auto description = getDefaultServerDescription(server); auto description = getServerDescription(server, m_defaultServerIndex);
if (configVersion) { if (configVersion) {
return description; return description;
} }
@@ -199,26 +193,21 @@ bool ServersModel::hasServerWithWriteAccess()
return false; return false;
} }
void ServersModel::setCurrentlyProcessedServerIndex(const int index) void ServersModel::setProcessedServerIndex(const int index)
{ {
m_currentlyProcessedServerIndex = index; m_processedServerIndex = index;
updateContainersModel(); 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)); return serverCredentials(m_processedServerIndex);
}
const ServerCredentials ServersModel::getCurrentlyProcessedServerCredentials()
{
return serverCredentials(m_currentlyProcessedServerIndex);
} }
const ServerCredentials ServersModel::getServerCredentials(const int index) const ServerCredentials ServersModel::getServerCredentials(const int index)
@@ -228,12 +217,17 @@ const ServerCredentials ServersModel::getServerCredentials(const int index)
bool ServersModel::isDefaultServerCurrentlyProcessed() 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() bool ServersModel::isDefaultServerHasWriteAccess()
@@ -249,40 +243,42 @@ void ServersModel::addServer(const QJsonObject &server)
endResetModel(); endResetModel();
} }
void ServersModel::editServer(const QJsonObject &server) void ServersModel::editServer(const QJsonObject &server, const int serverIndex)
{ {
m_settings->editServer(m_currentlyProcessedServerIndex, server); m_settings->editServer(serverIndex, server);
m_servers.replace(m_currentlyProcessedServerIndex, m_settings->serversArray().at(m_currentlyProcessedServerIndex)); m_servers.replace(serverIndex, m_settings->serversArray().at(serverIndex));
emit dataChanged(index(m_currentlyProcessedServerIndex, 0), index(m_currentlyProcessedServerIndex, 0)); emit dataChanged(index(serverIndex, 0), index(serverIndex, 0));
if (serverIndex == m_defaultServerIndex) {
updateDefaultServerContainersModel();
}
updateContainersModel(); updateContainersModel();
if (serverIndex == m_defaultServerIndex) {
auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
emit defaultServerDefaultContainerChanged(defaultContainer);
}
} }
void ServersModel::removeServer() void ServersModel::removeServer()
{ {
beginResetModel(); beginResetModel();
m_settings->removeServer(m_currentlyProcessedServerIndex); m_settings->removeServer(m_processedServerIndex);
m_servers = m_settings->serversArray(); m_servers = m_settings->serversArray();
if (m_settings->defaultServerIndex() == m_currentlyProcessedServerIndex) { if (m_settings->defaultServerIndex() == m_processedServerIndex) {
setDefaultServerIndex(0); setDefaultServerIndex(0);
} else if (m_settings->defaultServerIndex() > m_currentlyProcessedServerIndex) { } else if (m_settings->defaultServerIndex() > m_processedServerIndex) {
setDefaultServerIndex(m_settings->defaultServerIndex() - 1); setDefaultServerIndex(m_settings->defaultServerIndex() - 1);
} }
if (m_settings->serversCount() == 0) { if (m_settings->serversCount() == 0) {
setDefaultServerIndex(-1); setDefaultServerIndex(-1);
} }
setCurrentlyProcessedServerIndex(m_defaultServerIndex); setProcessedServerIndex(m_defaultServerIndex);
endResetModel(); 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> ServersModel::roleNames() const
{ {
QHash<int, QByteArray> roles; QHash<int, QByteArray> roles;
@@ -290,6 +286,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[NameRole] = "serverName"; roles[NameRole] = "serverName";
roles[NameRole] = "name"; roles[NameRole] = "name";
roles[ServerDescriptionRole] = "serverDescription"; roles[ServerDescriptionRole] = "serverDescription";
roles[CollapsedServerDescriptionRole] = "collapsedServerDescription";
roles[ExpandedServerDescriptionRole] = "expandedServerDescription";
roles[HostNameRole] = "hostName"; roles[HostNameRole] = "hostName";
@@ -304,6 +302,8 @@ QHash<int, QByteArray> ServersModel::roleNames() const
roles[ContainsAmneziaDnsRole] = "containsAmneziaDns"; roles[ContainsAmneziaDnsRole] = "containsAmneziaDns";
roles[DefaultContainerRole] = "defaultContainer"; roles[DefaultContainerRole] = "defaultContainer";
roles[IsServerFromApiRole] = "isServerFromApi";
return roles; return roles;
} }
@@ -322,28 +322,29 @@ ServerCredentials ServersModel::serverCredentials(int index) const
void ServersModel::updateContainersModel() 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); 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() QJsonObject ServersModel::getDefaultServerConfig()
{ {
return m_servers.at(m_defaultServerIndex).toObject(); return m_servers.at(m_defaultServerIndex).toObject();
} }
QJsonObject ServersModel::getCurrentlyProcessedServerConfig() void ServersModel::reloadDefaultServerContainerConfig()
{ {
return m_servers.at(m_currentlyProcessedServerIndex).toObject(); QJsonObject server = m_servers.at(m_defaultServerIndex).toObject();
}
void ServersModel::reloadContainerConfig()
{
QJsonObject server = m_servers.at(m_currentlyProcessedServerIndex).toObject();
auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString()); auto container = ContainerProps::containerFromString(server.value(config_key::defaultContainer).toString());
auto containers = server.value(config_key::containers).toArray(); 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++) { for (auto i = 0; i < containers.size(); i++) {
auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString()); auto c = ContainerProps::containerFromString(containers.at(i).toObject().value(config_key::container).toString());
if (c == container) { if (c == container) {
@@ -353,13 +354,13 @@ void ServersModel::reloadContainerConfig()
} }
server.insert(config_key::containers, containers); server.insert(config_key::containers, containers);
editServer(server); editServer(server, m_defaultServerIndex);
} }
void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config) void ServersModel::updateContainerConfig(const int containerIndex, const QJsonObject config)
{ {
auto container = static_cast<DockerContainer>(containerIndex); 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(); auto containers = server.value(config_key::containers).toArray();
for (auto i = 0; i < containers.size(); i++) { 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)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
} }
editServer(server); editServer(server, m_processedServerIndex);
} }
void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config) void ServersModel::addContainerConfig(const int containerIndex, const QJsonObject config)
{ {
auto container = static_cast<DockerContainer>(containerIndex); 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(); auto containers = server.value(config_key::containers).toArray();
containers.push_back(config); containers.push_back(config);
server.insert(config_key::containers, containers); server.insert(config_key::containers, containers);
bool isDefaultContainerChanged = false;
auto defaultContainer = server.value(config_key::defaultContainer).toString(); auto defaultContainer = server.value(config_key::defaultContainer).toString();
if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) { if ((ContainerProps::containerFromString(defaultContainer) == DockerContainer::None || ContainerProps::containerService(container) != ServiceType::Other)) {
server.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
isDefaultContainerChanged = true;
} }
editServer(server); editServer(server, m_processedServerIndex);
if (isDefaultContainerChanged) {
emit defaultContainerChanged(container);
}
} }
void ServersModel::setDefaultContainer(const int serverIndex, const int containerIndex) 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); auto container = static_cast<DockerContainer>(containerIndex);
QJsonObject s = m_servers.at(serverIndex).toObject(); QJsonObject s = m_servers.at(serverIndex).toObject();
s.insert(config_key::defaultContainer, ContainerProps::containerToString(container)); s.insert(config_key::defaultContainer, ContainerProps::containerToString(container));
editServer(s); //check editServer(s, serverIndex); //check
emit defaultContainerChanged(container);
} }
DockerContainer ServersModel::getDefaultContainer(const int serverIndex) const QString ServersModel::getDefaultServerDefaultContainerName()
{ {
return qvariant_cast<DockerContainer>(data(serverIndex, DefaultContainerRole)); auto defaultContainer = qvariant_cast<DockerContainer>(getDefaultServerData("defaultContainer"));
}
const QString ServersModel::getDefaultContainerName()
{
auto defaultContainer = getDefaultContainer(m_defaultServerIndex);
return ContainerProps::containerHumanNames().value(defaultContainer); return ContainerProps::containerHumanNames().value(defaultContainer);
} }
@@ -427,15 +417,14 @@ ErrorCode ServersModel::removeAllContainers()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
ErrorCode errorCode = ErrorCode errorCode =
serverController.removeAllContainers(m_settings->serverCredentials(m_currentlyProcessedServerIndex)); serverController.removeAllContainers(m_settings->serverCredentials(m_processedServerIndex));
if (errorCode == ErrorCode::NoError) { 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::containers, {});
s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None)); s.insert(config_key::defaultContainer, ContainerProps::containerToString(DockerContainer::None));
editServer(s); editServer(s, m_processedServerIndex);
emit defaultContainerChanged(DockerContainer::None);
} }
return errorCode; return errorCode;
} }
@@ -443,7 +432,7 @@ ErrorCode ServersModel::removeAllContainers()
ErrorCode ServersModel::rebootServer() ErrorCode ServersModel::rebootServer()
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); auto credentials = m_settings->serverCredentials(m_processedServerIndex);
ErrorCode errorCode = serverController.rebootServer(credentials); ErrorCode errorCode = serverController.rebootServer(credentials);
return errorCode; return errorCode;
@@ -452,13 +441,13 @@ ErrorCode ServersModel::rebootServer()
ErrorCode ServersModel::removeContainer(const int containerIndex) ErrorCode ServersModel::removeContainer(const int containerIndex)
{ {
ServerController serverController(m_settings); ServerController serverController(m_settings);
auto credentials = m_settings->serverCredentials(m_currentlyProcessedServerIndex); auto credentials = m_settings->serverCredentials(m_processedServerIndex);
auto dockerContainer = static_cast<DockerContainer>(containerIndex); auto dockerContainer = static_cast<DockerContainer>(containerIndex);
ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer); ErrorCode errorCode = serverController.removeContainer(credentials, dockerContainer);
if (errorCode == ErrorCode::NoError) { 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(); auto containers = server.value(config_key::containers).toArray();
for (auto it = containers.begin(); it != containers.end(); it++) { 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)); server.insert(config_key::defaultContainer, ContainerProps::containerToString(defaultContainer));
} }
editServer(server); editServer(server, m_processedServerIndex);
emit defaultContainerChanged(defaultContainer);
} }
return errorCode; return errorCode;
} }
void ServersModel::clearCachedProfiles() void ServersModel::clearCachedProfiles()
{ {
const auto &containers = m_settings->containers(m_currentlyProcessedServerIndex); const auto &containers = m_settings->containers(m_processedServerIndex);
for (DockerContainer container : containers.keys()) { 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(); updateContainersModel();
} }
void ServersModel::clearCachedProfile(const DockerContainer container) 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(); updateContainersModel();
} }
bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) bool ServersModel::isAmneziaDnsContainerInstalled(const int serverIndex) const
{ {
QJsonObject server = m_servers.at(serverIndex).toObject(); QJsonObject server = m_servers.at(serverIndex).toObject();
auto containers = server.value(config_key::containers).toArray(); auto containers = server.value(config_key::containers).toArray();
@@ -544,16 +538,6 @@ void ServersModel::toggleAmneziaDns(bool enabled)
emit defaultServerDescriptionChanged(); 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) bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
{ {
for (const auto &server : qAsConst(m_servers)) { for (const auto &server : qAsConst(m_servers)) {
@@ -564,3 +548,52 @@ bool ServersModel::isServerFromApiAlreadyExists(const quint16 crc)
return false; 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 { enum Roles {
NameRole = Qt::UserRole + 1, NameRole = Qt::UserRole + 1,
ServerDescriptionRole, ServerDescriptionRole,
CollapsedServerDescriptionRole,
ExpandedServerDescriptionRole,
HostNameRole, HostNameRole,
CredentialsRole, CredentialsRole,
@@ -25,7 +26,11 @@ public:
ContainsAmneziaDnsRole, ContainsAmneziaDnsRole,
DefaultContainerRole DefaultContainerRole,
IsServerFromApiRole,
HasAmneziaDns
}; };
ServersModel(std::shared_ptr<Settings> settings, QObject *parent = nullptr); 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(int defaultIndex READ getDefaultServerIndex WRITE setDefaultServerIndex NOTIFY defaultServerIndexChanged)
Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged) Q_PROPERTY(QString defaultServerName READ getDefaultServerName NOTIFY defaultServerNameChanged)
Q_PROPERTY(QString defaultServerHostName READ getDefaultServerHostName NOTIFY defaultServerIndexChanged) Q_PROPERTY(QString defaultServerDefaultContainerName READ getDefaultServerDefaultContainerName NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultContainerName READ getDefaultContainerName NOTIFY defaultContainerChanged) Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionCollapsed READ getDefaultServerDescriptionCollapsed NOTIFY defaultServerDescriptionChanged) Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(QString defaultServerDescriptionExpanded READ getDefaultServerDescriptionExpanded NOTIFY defaultServerDescriptionChanged) Q_PROPERTY(bool isDefaultServerDefaultContainerHasSplitTunneling READ isDefaultServerDefaultContainerHasSplitTunneling NOTIFY defaultServerDefaultContainerChanged)
Q_PROPERTY(bool isDefaultServerFromApi READ isDefaultServerFromApi NOTIFY defaultServerIndexChanged)
Q_PROPERTY(int currentlyProcessedIndex READ getCurrentlyProcessedServerIndex WRITE setCurrentlyProcessedServerIndex Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
NOTIFY currentlyProcessedServerIndexChanged)
public slots: public slots:
void setDefaultServerIndex(const int index); void setDefaultServerIndex(const int index);
const int getDefaultServerIndex(); const int getDefaultServerIndex();
const QString getDefaultServerName(); const QString getDefaultServerName();
const QString getDefaultServerHostName();
const QString getDefaultServerDescriptionCollapsed(); const QString getDefaultServerDescriptionCollapsed();
const QString getDefaultServerDescriptionExpanded(); const QString getDefaultServerDescriptionExpanded();
const QString getDefaultServerDefaultContainerName();
bool isDefaultServerCurrentlyProcessed(); bool isDefaultServerCurrentlyProcessed();
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerHasWriteAccess(); bool isProcessedServerHasWriteAccess();
bool isDefaultServerHasWriteAccess(); bool isDefaultServerHasWriteAccess();
bool hasServerWithWriteAccess(); bool hasServerWithWriteAccess();
const int getServersCount(); const int getServersCount();
void setCurrentlyProcessedServerIndex(const int index); void setProcessedServerIndex(const int index);
int getCurrentlyProcessedServerIndex(); int getProcessedServerIndex();
QString getCurrentlyProcessedServerHostName(); const ServerCredentials getProcessedServerCredentials();
const ServerCredentials getCurrentlyProcessedServerCredentials();
const ServerCredentials getServerCredentials(const int index); const ServerCredentials getServerCredentials(const int index);
void addServer(const QJsonObject &server); void addServer(const QJsonObject &server);
void editServer(const QJsonObject &server); void editServer(const QJsonObject &server, const int serverIndex);
void removeServer(); void removeServer();
bool isDefaultServerConfigContainsAmneziaDns();
bool isAmneziaDnsContainerInstalled(const int serverIndex);
QJsonObject getDefaultServerConfig(); QJsonObject getDefaultServerConfig();
QJsonObject getCurrentlyProcessedServerConfig();
void reloadContainerConfig(); void reloadDefaultServerContainerConfig();
void updateContainerConfig(const int containerIndex, const QJsonObject config); void updateContainerConfig(const int containerIndex, const QJsonObject config);
void addContainerConfig(const int containerIndex, const QJsonObject config); void addContainerConfig(const int containerIndex, const QJsonObject config);
@@ -92,42 +93,49 @@ public slots:
ErrorCode rebootServer(); ErrorCode rebootServer();
void setDefaultContainer(const int serverIndex, const int containerIndex); void setDefaultContainer(const int serverIndex, const int containerIndex);
DockerContainer getDefaultContainer(const int serverIndex);
const QString getDefaultContainerName();
QStringList getAllInstalledServicesName(const int serverIndex); QStringList getAllInstalledServicesName(const int serverIndex);
void toggleAmneziaDns(bool enabled); void toggleAmneziaDns(bool enabled);
bool isDefaultServerFromApi();
bool isCurrentlyProcessedServerFromApi();
bool isServerFromApiAlreadyExists(const quint16 crc); 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: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
signals: signals:
void currentlyProcessedServerIndexChanged(const int index); void processedServerIndexChanged(const int index);
void defaultServerIndexChanged(const int index); void defaultServerIndexChanged(const int index);
void defaultServerNameChanged(); void defaultServerNameChanged();
void defaultServerDescriptionChanged(); void defaultServerDescriptionChanged();
void containersUpdated(const QJsonArray &containers); void containersUpdated(const QJsonArray &containers);
void defaultContainerChanged(const int containerIndex); void defaultServerContainersUpdated(const QJsonArray &containers);
void defaultServerDefaultContainerChanged(const int containerIndex);
private: private:
ServerCredentials serverCredentials(int index) const; ServerCredentials serverCredentials(int index) const;
void updateContainersModel(); 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; QJsonArray m_servers;
std::shared_ptr<Settings> m_settings; std::shared_ptr<Settings> m_settings;
int m_defaultServerIndex; int m_defaultServerIndex;
int m_currentlyProcessedServerIndex; int m_processedServerIndex;
bool m_isAmneziaDnsEnabled = m_settings->useAmneziaDns(); 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_settings->setRouteMode(Settings::RouteMode::VpnAllSites);
} }
m_isSplitTunnelingEnabled = enabled; m_isSplitTunnelingEnabled = enabled;
emit splitTunnelingToggled();
} }
QVector<QPair<QString, QString> > SitesModel::getCurrentSites() 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; QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged) Q_PROPERTY(int routeMode READ getRouteMode WRITE setRouteMode NOTIFY routeModeChanged)
Q_PROPERTY(bool isTunnelingEnabled READ isSplitTunnelingEnabled NOTIFY splitTunnelingToggled)
public slots: public slots:
bool addSite(const QString &hostname, const QString &ip); bool addSite(const QString &hostname, const QString &ip);
@@ -38,6 +39,7 @@ public slots:
signals: signals:
void routeModeChanged(); void routeModeChanged();
void splitTunnelingToggled();
protected: protected:
QHash<int, QByteArray> roleNames() const override; QHash<int, QByteArray> roleNames() const override;
+1 -1
View File
@@ -138,7 +138,7 @@ Button {
} }
onClicked: { onClicked: {
ServersModel.setCurrentlyProcessedServerIndex(ServersModel.defaultIndex) ServersModel.setProcessedServerIndex(ServersModel.defaultIndex)
ApiController.updateServerConfigFromApi() ApiController.updateServerConfigFromApi()
} }
} }
@@ -15,6 +15,7 @@ ListView {
id: menuContent id: menuContent
property var rootWidth property var rootWidth
property var selectedText
width: rootWidth width: rootWidth
height: menuContent.contentItem.height height: menuContent.contentItem.height
@@ -51,7 +52,7 @@ ListView {
showImage: !isInstalled showImage: !isInstalled
checkable: isInstalled && !ConnectionController.isConnected && isSupported checkable: isInstalled && !ConnectionController.isConnected && isSupported
checked: proxyContainersModel.mapToSource(index) === ServersModel.getDefaultContainer(ServersModel.defaultIndex) checked: proxyDefaultServerContainersModel.mapToSource(index) === ServersModel.getDefaultServerData("defaultContainer")
onClicked: { onClicked: {
if (ConnectionController.isConnected && isInstalled) { if (ConnectionController.isConnected && isInstalled) {
@@ -61,14 +62,14 @@ ListView {
if (checked) { if (checked) {
containersDropDown.close() containersDropDown.close()
ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyContainersModel.mapToSource(index)) ServersModel.setDefaultContainer(ServersModel.defaultIndex, proxyDefaultServerContainersModel.mapToSource(index))
} else { } else {
if (!isSupported && isInstalled) { if (!isSupported && isInstalled) {
PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform")) PageController.showErrorMessage(qsTr("The selected protocol is not supported on the current platform"))
return return
} }
ContainersModel.setCurrentlyProcessedContainerIndex(proxyContainersModel.mapToSource(index)) ContainersModel.setCurrentlyProcessedContainerIndex(proxyDefaultServerContainersModel.mapToSource(index))
InstallController.setShouldCreateServer(false) InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings) PageController.goToPage(PageEnum.PageSetupWizardProtocolSettings)
containersDropDown.close() 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
}
}
}
@@ -107,13 +107,6 @@ DrawerType2 {
text: qsTr("Copy") text: qsTr("Copy")
imageSource: "qrc:/images/controls/copy.svg" imageSource: "qrc:/images/controls/copy.svg"
clickedFunc: function() {
configText.selectAll()
configText.copy()
configText.select(0, 0)
PageController.showNotificationMessage(qsTr("Copied"))
}
} }
BasicButtonType { BasicButtonType {
@@ -132,13 +125,6 @@ DrawerType2 {
text: qsTr("Copy config string") text: qsTr("Copy config string")
imageSource: "qrc:/images/controls/copy.svg" imageSource: "qrc:/images/controls/copy.svg"
clickedFunc: function() {
nativeConfigString.selectAll()
nativeConfigString.copy()
nativeConfigString.select(0, 0)
PageController.showNotificationMessage(qsTr("Copied"))
}
} }
BasicButtonType { BasicButtonType {
@@ -201,7 +187,7 @@ DrawerType2 {
anchors.topMargin: 16 anchors.topMargin: 16
backButtonFunction: function() { backButtonFunction: function() {
configContentDrawer.open() configContentDrawer.close()
} }
} }
+18 -1
View File
@@ -21,6 +21,8 @@ Button {
property int borderFocusedWidth: 1 property int borderFocusedWidth: 1
property string imageSource property string imageSource
property string rightImageSource
property string leftImageColor: textColor
property bool squareLeftSide: false property bool squareLeftSide: false
@@ -118,7 +120,7 @@ Button {
layer { layer {
enabled: true enabled: true
effect: ColorOverlay { effect: ColorOverlay {
color: textColor color: leftImageColor
} }
} }
} }
@@ -131,6 +133,21 @@ Button {
horizontalAlignment: Text.AlignLeft horizontalAlignment: Text.AlignLeft
verticalAlignment: Text.AlignVCenter 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 id: emptyArea
anchors.fill: parent anchors.fill: parent
enabled: root.isExpanded enabled: root.isExpanded
visible: enabled
onClicked: { onClicked: {
root.close() root.close()
} }
@@ -74,6 +74,8 @@ Item {
enabled: root.textFieldEditable enabled: root.textFieldEditable
color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
placeholderText: root.textFieldPlaceholderText placeholderText: root.textFieldPlaceholderText
placeholderTextColor: "#494B50" placeholderTextColor: "#494B50"
+72 -46
View File
@@ -18,6 +18,7 @@ import "../Components"
PageType { PageType {
id: root id: root
property var selectedServerIndex: ServersModel.getDefaultServerIndex()
Connections { Connections {
target: PageController target: PageController
@@ -34,10 +35,46 @@ PageType {
anchors.bottomMargin: drawer.collapsedHeight anchors.bottomMargin: drawer.collapsedHeight
ConnectButton { ConnectButton {
id: connectButton
anchors.centerIn: parent 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
}
}
}
DrawerType2 { DrawerType2 {
id: drawer id: drawer
@@ -141,7 +178,6 @@ PageType {
anchors.right: parent.right anchors.right: parent.right
anchors.left: parent.left anchors.left: parent.left
Header1TextType { Header1TextType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 14 Layout.topMargin: 14
@@ -156,7 +192,7 @@ PageType {
LabelTextType { LabelTextType {
id: expandedServersMenuDescription id: expandedServersMenuDescription
Layout.bottomMargin: 24 Layout.bottomMargin: ServersModel.isDefaultServerFromApi ? 69 : 24
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Qt.AlignHCenter horizontalAlignment: Qt.AlignHCenter
verticalAlignment: Qt.AlignVCenter verticalAlignment: Qt.AlignVCenter
@@ -167,6 +203,9 @@ PageType {
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
spacing: 8 spacing: 8
visible: !ServersModel.isDefaultServerFromApi
onVisibleChanged: expandedServersMenuDescription.Layout
DropDownType { DropDownType {
id: containersDropDown id: containersDropDown
@@ -179,13 +218,12 @@ PageType {
rootButtonTextTopMargin: 8 rootButtonTextTopMargin: 8
rootButtonTextBottomMargin: 8 rootButtonTextBottomMargin: 8
text: ServersModel.defaultContainerName text: ServersModel.defaultServerDefaultContainerName
textColor: "#0E0E11" textColor: "#0E0E11"
headerText: qsTr("VPN protocol") headerText: qsTr("VPN protocol")
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg" headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
rootButtonClickedFunction: function() { rootButtonClickedFunction: function() {
ServersModel.currentlyProcessedIndex = serversMenuContent.currentIndex
containersDropDown.open() containersDropDown.open()
} }
@@ -197,22 +235,26 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onDefaultServerIndexChanged() {
updateContainersModelFilters() updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isDefaultServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters() proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters() proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
} }
} }
model: SortFilterProxyModel { model: SortFilterProxyModel {
id: proxyContainersModel id: proxyDefaultServerContainersModel
sourceModel: ContainersModel sourceModel: DefaultServerContainersModel
sorters: [
RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
]
} }
Component.onCompleted: updateContainersModelFilters() Component.onCompleted: updateContainersModelFilters()
@@ -238,27 +280,13 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.topMargin: 16 anchors.topMargin: 16
contentHeight: col.height + col.anchors.bottomMargin
implicitHeight: parent.height - serversMenuHeader.implicitHeight implicitHeight: parent.height - serversMenuHeader.implicitHeight
clip: true clip: true
interactive: true
ScrollBar.vertical: ScrollBar {
id: scrollBar
policy: serversContainer.height >= serversContainer.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
}
Keys.onUpPressed: scrollBar.decrease() Keys.onUpPressed: scrollBar.decrease()
Keys.onDownPressed: scrollBar.increase() Keys.onDownPressed: scrollBar.increase()
Column {
id: col
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.bottomMargin: 32
spacing: 16
ButtonGroup { ButtonGroup {
id: serversRadioButtonGroup id: serversRadioButtonGroup
} }
@@ -266,10 +294,24 @@ PageType {
ListView { ListView {
id: serversMenuContent id: serversMenuContent
width: parent.width width: parent.width
height: serversMenuContent.contentItem.height spacing: 16
anchors.fill: parent
anchors.bottomMargin: 32
highlightFollowsCurrentItem: true
highlightMoveDuration: 100
model: ServersModel model: ServersModel
currentIndex: ServersModel.defaultIndex
Component.onCompleted: currentIndex = selectedServerIndex //auto-scroll to the selected server
ScrollBar.vertical: ScrollBar {
id: scrollBar
active: true
policy: serversContainer.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
width: 12
}
Connections { Connections {
target: ServersModel target: ServersModel
@@ -279,7 +321,7 @@ PageType {
} }
clip: true clip: true
interactive: false interactive: true
delegate: Item { delegate: Item {
id: menuContentDelegate id: menuContentDelegate
@@ -305,21 +347,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
text: name text: name
descriptionText: { descriptionText: serverDescription
var fullDescription = ""
if (hasWriteAccess) {
if (SettingsController.isAmneziaDnsEnabled()
&& ServersModel.isAmneziaDnsContainerInstalled(index)) {
fullDescription += "Amnezia DNS | "
}
} else {
if (containsAmneziaDns) {
fullDescription += "Amnezia DNS | "
}
}
return fullDescription += serverDescription
}
checked: index === serversMenuContent.currentIndex checked: index === serversMenuContent.currentIndex
checkable: !ConnectionController.isConnected checkable: !ConnectionController.isConnected
@@ -334,7 +362,6 @@ PageType {
serversMenuContent.currentIndex = index serversMenuContent.currentIndex = index
ServersModel.currentlyProcessedIndex = index
ServersModel.defaultIndex = index ServersModel.defaultIndex = index
} }
@@ -355,7 +382,7 @@ PageType {
z: 1 z: 1
onClicked: function() { onClicked: function() {
ServersModel.currentlyProcessedIndex = index ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo) PageController.goToPage(PageEnum.PageSettingsServerInfo)
drawer.close() drawer.close()
} }
@@ -374,4 +401,3 @@ PageType {
} }
} }
} }
}
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
@@ -111,7 +111,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Junk packet count") headerText: "Jc - Junk packet count"
textFieldText: junkPacketCount textFieldText: junkPacketCount
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -136,7 +136,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Junk packet minimum size") headerText: "Jmin - Junk packet minimum size"
textFieldText: junkPacketMinSize textFieldText: junkPacketMinSize
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -156,7 +156,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Junk packet maximum size") headerText: "Jmax - Junk packet maximum size"
textFieldText: junkPacketMaxSize textFieldText: junkPacketMaxSize
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -176,7 +176,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Init packet junk size") headerText: "S1 - Init packet junk size"
textFieldText: initPacketJunkSize textFieldText: initPacketJunkSize
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -196,7 +196,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Response packet junk size") headerText: "S2 - Response packet junk size"
textFieldText: responsePacketJunkSize textFieldText: responsePacketJunkSize
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -216,7 +216,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Init packet magic header") headerText: "H1 - Init packet magic header"
textFieldText: initPacketMagicHeader textFieldText: initPacketMagicHeader
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -236,7 +236,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Response packet magic header") headerText: "H2 - Response packet magic header"
textFieldText: responsePacketMagicHeader textFieldText: responsePacketMagicHeader
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -256,7 +256,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Transport packet magic header") headerText: "H4 - Transport packet magic header"
textFieldText: transportPacketMagicHeader textFieldText: transportPacketMagicHeader
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -276,7 +276,7 @@ PageType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.topMargin: 16 Layout.topMargin: 16
headerText: qsTr("Underload packet magic header") headerText: "H3 - Underload packet magic header"
textFieldText: underloadPacketMagicHeader textFieldText: underloadPacketMagicHeader
textField.validator: IntValidator { bottom: 0 } textField.validator: IntValidator { bottom: 0 }
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -44,7 +44,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
width: parent.width width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess() visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757" textColor: "#EB5757"
@@ -43,7 +43,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -49,7 +49,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
enabled: ServersModel.isCurrentlyProcessedServerHasWriteAccess() enabled: ServersModel.isProcessedServerHasWriteAccess()
ListView { ListView {
id: listview id: listview
@@ -88,7 +88,7 @@ PageType {
Layout.topMargin: 32 Layout.topMargin: 32
text: qsTr("Host") text: qsTr("Host")
descriptionText: ServersModel.getCurrentlyProcessedServerHostName() descriptionText: ServersModel.getProcessedServerData("HostName")
descriptionOnTop: true descriptionOnTop: true
+1 -1
View File
@@ -175,7 +175,7 @@ PageType {
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
text: SettingsController.getAppVersion() text: qsTr("Software version: %1").arg(SettingsController.getAppVersion())
color: "#878B91" color: "#878B91"
} }
@@ -84,6 +84,27 @@ PageType {
visible: !GC.isMobile() 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 { SwitcherType {
visible: !GC.isMobile() visible: !GC.isMobile()
@@ -41,27 +41,6 @@ PageType {
headerText: qsTr("Connection") 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 { SwitcherType {
Layout.fillWidth: true Layout.fillWidth: true
Layout.margins: 16 Layout.margins: 16
+4 -2
View File
@@ -30,10 +30,12 @@ PageType {
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
contentHeight: content.height contentHeight: content.height
enabled: !ServersModel.isDefaultServerFromApi() property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
enabled: !isServerFromApi
Component.onCompleted: { Component.onCompleted: {
if (ServersModel.isDefaultServerFromApi()) { if (isServerFromApi) {
PageController.showNotificationMessage(qsTr("Default server does not support custom dns")) PageController.showNotificationMessage(qsTr("Default server does not support custom dns"))
} }
} }
@@ -28,7 +28,7 @@ PageType {
PageController.showErrorMessage(message) PageController.showErrorMessage(message)
} }
function onRemoveCurrentlyProcessedServerFinished(finishedMessage) { function onRemoveProcessedServerFinished(finishedMessage) {
if (!ServersModel.getServersCount()) { if (!ServersModel.getServersCount()) {
PageController.replaceStartPage() PageController.replaceStartPage()
} else { } else {
@@ -38,7 +38,7 @@ PageType {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
function onRebootCurrentlyProcessedServerFinished(finishedMessage) { function onRebootProcessedServerFinished(finishedMessage) {
PageController.showNotificationMessage(finishedMessage) PageController.showNotificationMessage(finishedMessage)
} }
@@ -64,8 +64,8 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
content.isServerWithWriteAccess = ServersModel.isCurrentlyProcessedServerHasWriteAccess() content.isServerWithWriteAccess = ServersModel.isProcessedServerHasWriteAccess()
} }
} }
@@ -82,7 +82,7 @@ PageType {
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
property bool isServerWithWriteAccess: ServersModel.isCurrentlyProcessedServerHasWriteAccess() property bool isServerWithWriteAccess: ServersModel.isProcessedServerHasWriteAccess()
LabelWithButtonType { LabelWithButtonType {
visible: content.isServerWithWriteAccess visible: content.isServerWithWriteAccess
@@ -149,7 +149,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection() ConnectionController.closeConnection()
} }
InstallController.rebootCurrentlyProcessedServer() InstallController.rebootProcessedServer()
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
@@ -180,7 +180,7 @@ PageType {
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) { if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
ConnectionController.closeConnection() ConnectionController.closeConnection()
} }
InstallController.removeCurrentlyProcessedServer() InstallController.removeProcessedServer()
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
var noButtonFunction = function() { var noButtonFunction = function() {
@@ -224,7 +224,7 @@ PageType {
} }
LabelWithButtonType { LabelWithButtonType {
visible: ServersModel.isCurrentlyProcessedServerFromApi() visible: ServersModel.getProcessedServerData("isServerFromApi")
Layout.fillWidth: true Layout.fillWidth: true
text: qsTr("Reset API config") text: qsTr("Reset API config")
@@ -249,7 +249,7 @@ PageType {
} }
DividerType { DividerType {
visible: ServersModel.isCurrentlyProcessedServerFromApi() visible: ServersModel.getProcessedServerData("isServerFromApi")
} }
} }
} }
@@ -63,7 +63,7 @@ PageType {
headerText: name headerText: name
descriptionText: { descriptionText: {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
return credentialsLogin + " · " + hostName return credentialsLogin + " · " + hostName
} else { } else {
return hostName return hostName
@@ -107,7 +107,7 @@ PageType {
width: parent.width width: parent.width
visible: ServersModel.isCurrentlyProcessedServerHasWriteAccess() visible: ServersModel.isProcessedServerHasWriteAccess()
text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName() text: qsTr("Remove ") + ContainersModel.getCurrentlyProcessedContainerName()
textColor: "#EB5757" textColor: "#EB5757"
@@ -38,13 +38,13 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters() settingsContainersListView.updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters() proxyContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters() proxyContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
@@ -38,13 +38,13 @@ PageType {
Connections { Connections {
target: ServersModel target: ServersModel
function onCurrentlyProcessedServerIndexChanged() { function onProcessedServerIndexChanged() {
settingsContainersListView.updateContainersModelFilters() settingsContainersListView.updateContainersModelFilters()
} }
} }
function updateContainersModelFilters() { function updateContainersModelFilters() {
if (ServersModel.isCurrentlyProcessedServerHasWriteAccess()) { if (ServersModel.isProcessedServerHasWriteAccess()) {
proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters() proxyContainersModel.filters = ContainersModelFilters.getWriteAccessServicesListFilters()
} else { } else {
proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters() proxyContainersModel.filters = ContainersModelFilters.getReadAccessServicesListFilters()
@@ -55,6 +55,9 @@ PageType {
model: SortFilterProxyModel { model: SortFilterProxyModel {
id: proxyContainersModel id: proxyContainersModel
sourceModel: ContainersModel sourceModel: ContainersModel
sorters: [
RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
]
} }
Component.onCompleted: updateContainersModelFilters() Component.onCompleted: updateContainersModelFilters()
@@ -87,7 +87,7 @@ PageType {
rightImageSource: "qrc:/images/controls/chevron-right.svg" rightImageSource: "qrc:/images/controls/chevron-right.svg"
clickedFunction: function() { clickedFunction: function() {
ServersModel.currentlyProcessedIndex = index ServersModel.processedIndex = index
PageController.goToPage(PageEnum.PageSettingsServerInfo) PageController.goToPage(PageEnum.PageSettingsServerInfo)
} }
} }
@@ -20,15 +20,23 @@ import "../Components"
PageType { PageType {
id: root id: root
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
defaultActiveFocusItem: website_ip_field.textField defaultActiveFocusItem: website_ip_field.textField
property bool pageEnabled: { property bool pageEnabled: {
return !ConnectionController.isConnected && !ServersModel.isDefaultServerFromApi() return !ConnectionController.isConnected && !isServerFromApi
} }
Component.onCompleted: { 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")) 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.fillWidth: true
Layout.rightMargin: 16 Layout.rightMargin: 16
checked: SitesModel.isSplitTunnelingEnabled() checked: SitesModel.isTunnelingEnabled
onToggled: { onToggled: {
SitesModel.toggleSplitTunneling(checked) SitesModel.toggleSplitTunneling(checked)
selector.text = root.routeModesModel[getRouteModesModelIndex()].name selector.text = root.routeModesModel[getRouteModesModelIndex()].name
@@ -26,7 +26,7 @@ PageType {
function onInstallContainerFinished(finishedMessage, isServiceInstall) { function onInstallContainerFinished(finishedMessage, isServiceInstall) {
if (!ConnectionController.isConnected && !isServiceInstall) { if (!ConnectionController.isConnected && !isServiceInstall) {
ServersModel.setDefaultContainer(ServersModel.currentlyProcessedIndex, ContainersModel.getCurrentlyProcessedContainerIndex()) ServersModel.setDefaultContainer(ServersModel.processedIndex, ContainersModel.getCurrentlyProcessedContainerIndex())
} }
PageController.closePage() // close installing page PageController.closePage() // close installing page
@@ -42,7 +42,7 @@ PageType {
function onInstallServerFinished(finishedMessage) { function onInstallServerFinished(finishedMessage) {
if (!ConnectionController.isConnected) { if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1); ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
} }
PageController.goToStartPage() PageController.goToStartPage()
@@ -55,7 +55,7 @@ PageType {
function onServerAlreadyExists(serverIndex) { function onServerAlreadyExists(serverIndex) {
PageController.goToStartPage() PageController.goToStartPage()
ServersModel.currentlyProcessedIndex = serverIndex ServersModel.processedIndex = serverIndex
PageController.goToPage(PageEnum.PageSettingsServerInfo, false) PageController.goToPage(PageEnum.PageSettingsServerInfo, false)
PageController.showErrorMessage(qsTr("The server has already been added to the application")) PageController.showErrorMessage(qsTr("The server has already been added to the application"))
@@ -30,7 +30,7 @@ PageType {
function onImportFinished() { function onImportFinished() {
if (!ConnectionController.isConnected) { if (!ConnectionController.isConnected) {
ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1); ServersModel.setDefaultServerIndex(ServersModel.getServersCount() - 1);
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
} }
PageController.goToStartPage() PageController.goToStartPage()
+25 -7
View File
@@ -22,6 +22,7 @@ PageType {
AmneziaConnection, AmneziaConnection,
OpenVpn, OpenVpn,
WireGuard, WireGuard,
Awg,
ShadowSocks, ShadowSocks,
Cloak Cloak
} }
@@ -31,7 +32,7 @@ PageType {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.revokeConfig(index, ExportController.revokeConfig(index,
ContainersModel.getCurrentlyProcessedContainerIndex(), ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
PageController.showNotificationMessage(qsTr("Config revoked")) PageController.showNotificationMessage(qsTr("Config revoked"))
} }
@@ -48,7 +49,10 @@ PageType {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
switch (type) { switch (type) {
case PageShare.ConfigType.AmneziaConnection: ExportController.generateConnectionConfig(clientNameTextField.textFieldText); break; case PageShare.ConfigType.AmneziaConnection: {
ExportController.generateConnectionConfig(clientNameTextField.textFieldText);
break;
}
case PageShare.ConfigType.OpenVpn: { case PageShare.ConfigType.OpenVpn: {
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText) ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config") shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
@@ -63,6 +67,13 @@ PageType {
shareConnectionDrawer.configFileName = "amnezia_for_wireguard" shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break 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: { case PageShare.ConfigType.ShadowSocks: {
ExportController.generateShadowSocksConfig() ExportController.generateShadowSocksConfig()
shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config") shareConnectionDrawer.configCaption = qsTr("Save ShadowSocks config")
@@ -110,6 +121,11 @@ PageType {
property string name: qsTr("WireGuard native format") property string name: qsTr("WireGuard native format")
property var type: PageShare.ConfigType.WireGuard property var type: PageShare.ConfigType.WireGuard
} }
QtObject {
id: awgConnectionFormat
property string name: qsTr("AmneziaWG native format")
property var type: PageShare.ConfigType.Awg
}
QtObject { QtObject {
id: shadowSocksConnectionFormat id: shadowSocksConnectionFormat
property string name: qsTr("ShadowSocks native format") property string name: qsTr("ShadowSocks native format")
@@ -230,7 +246,7 @@ PageType {
accessTypeSelector.currentIndex = 1 accessTypeSelector.currentIndex = 1
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(), ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
} }
@@ -315,7 +331,7 @@ PageType {
function handler() { function handler() {
serverSelector.text = selectedText serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex) ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
} }
} }
} }
@@ -365,7 +381,7 @@ PageType {
target: serverSelector target: serverSelector
function onSeverSelectorIndexChanged() { function onSeverSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getDefaultContainer(ServersModel.currentlyProcessedIndex)) var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.currentIndex = defaultContainer protocolSelectorListView.currentIndex = defaultContainer
protocolSelectorListView.triggerCurrentItem() protocolSelectorListView.triggerCurrentItem()
} }
@@ -388,7 +404,7 @@ PageType {
if (accessTypeSelector.currentIndex === 1) { if (accessTypeSelector.currentIndex === 1) {
PageController.showBusyIndicator(true) PageController.showBusyIndicator(true)
ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(), ExportController.updateClientManagementModel(ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
} }
} }
@@ -402,6 +418,8 @@ PageType {
root.connectionTypesModel.push(openVpnConnectionFormat) root.connectionTypesModel.push(openVpnConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-wireguard")) { } else if (index === ContainerProps.containerFromString("amnezia-wireguard")) {
root.connectionTypesModel.push(wireGuardConnectionFormat) root.connectionTypesModel.push(wireGuardConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-awg")) {
root.connectionTypesModel.push(awgConnectionFormat)
} else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) { } else if (index === ContainerProps.containerFromString("amnezia-shadowsocks")) {
root.connectionTypesModel.push(openVpnConnectionFormat) root.connectionTypesModel.push(openVpnConnectionFormat)
root.connectionTypesModel.push(shadowSocksConnectionFormat) root.connectionTypesModel.push(shadowSocksConnectionFormat)
@@ -654,7 +672,7 @@ PageType {
ExportController.renameClient(index, ExportController.renameClient(index,
clientNameEditor.textFieldText, clientNameEditor.textFieldText,
ContainersModel.getCurrentlyProcessedContainerIndex(), ContainersModel.getCurrentlyProcessedContainerIndex(),
ServersModel.getCurrentlyProcessedServerCredentials()) ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false) PageController.showBusyIndicator(false)
clientNameEditDrawer.close() clientNameEditDrawer.close()
} }
+1 -1
View File
@@ -111,7 +111,7 @@ PageType {
function handler() { function handler() {
serverSelector.text = selectedText serverSelector.text = selectedText
ServersModel.currentlyProcessedIndex = proxyServersModel.mapToSource(currentIndex) ServersModel.processedIndex = proxyServersModel.mapToSource(currentIndex)
} }
} }
} }
+5 -4
View File
@@ -44,6 +44,7 @@ PageType {
function onClosePage() { function onClosePage() {
tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo) tabBar.isServerInfoShow = tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsServerInfo)
&& tabBarStackView.currentItem.objectName !== PageController.getPagePath(PageEnum.PageSettingsSplitTunneling)
if (tabBarStackView.depth <= 1) { if (tabBarStackView.depth <= 1) {
return return
@@ -60,7 +61,7 @@ PageType {
tabBarStackView.push(pagePath, { "objectName" : pagePath }, StackView.Immediate) 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() { function onGoToStartPage() {
@@ -108,7 +109,7 @@ PageType {
function onNoInstalledContainers() { function onNoInstalledContainers() {
PageController.setTriggeredBtConnectButton(true) PageController.setTriggeredBtConnectButton(true)
ServersModel.currentlyProcessedIndex = ServersModel.getDefaultServerIndex() ServersModel.processedIndex = ServersModel.getDefaultServerIndex()
InstallController.setShouldCreateServer(false) InstallController.setShouldCreateServer(false)
PageController.goToPage(PageEnum.PageSetupWizardEasy) PageController.goToPage(PageEnum.PageSetupWizardEasy)
} }
@@ -136,7 +137,7 @@ PageType {
Component.onCompleted: { Component.onCompleted: {
var pagePath = PageController.getPagePath(PageEnum.PageHome) var pagePath = PageController.getPagePath(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
tabBarStackView.push(pagePath, { "objectName" : pagePath }) tabBarStackView.push(pagePath, { "objectName" : pagePath })
} }
} }
@@ -180,7 +181,7 @@ PageType {
image: "qrc:/images/controls/home.svg" image: "qrc:/images/controls/home.svg"
onClicked: { onClicked: {
tabBarStackView.goToTabBarPage(PageEnum.PageHome) tabBarStackView.goToTabBarPage(PageEnum.PageHome)
ServersModel.currentlyProcessedIndex = ServersModel.defaultIndex ServersModel.processedIndex = ServersModel.defaultIndex
tabBar.previousIndex = 0 tabBar.previousIndex = 0
} }
} }
+1 -1
View File
@@ -20,7 +20,7 @@ PLIST_NAME=$APP_NAME.plist
# Search Qt # Search Qt
if [ -z "${QT_VERSION+x}" ]; then if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=6.5.2; QT_VERSION=6.6.2;
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/ios/bin QT_BIN_DIR=$HOME/Qt/$QT_VERSION/ios/bin
fi fi
+1 -1
View File
@@ -36,7 +36,7 @@ QMAKE_STASH_FILE=$PROJECT_DIR/.qmake_stash
# Search Qt # Search Qt
if [ -z "${QT_VERSION+x}" ]; then if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=5.15.2 QT_VERSION=6.6.2
if [ -f /opt/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then if [ -f /opt/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then
QT_BIN_DIR=/opt/Qt/$QT_VERSION/gcc_64/bin QT_BIN_DIR=/opt/Qt/$QT_VERSION/gcc_64/bin
elif [ -f $HOME/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then elif [ -f $HOME/Qt/$QT_VERSION/gcc_64/bin/qmake ]; then
+3 -2
View File
@@ -37,7 +37,7 @@ DMG_FILENAME=$PROJECT_DIR/${APP_NAME}.dmg
# Search Qt # Search Qt
if [ -z "${QT_VERSION+x}" ]; then if [ -z "${QT_VERSION+x}" ]; then
QT_VERSION=6.5.1; QT_VERSION=6.4.3;
QIF_VERSION=4.6 QIF_VERSION=4.6
QT_BIN_DIR=$HOME/Qt/$QT_VERSION/macos/bin QT_BIN_DIR=$HOME/Qt/$QT_VERSION/macos/bin
QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin QIF_BIN_DIR=$QT_BIN_DIR/../../../Tools/QtInstallerFramework/$QIF_VERSION/bin
@@ -146,7 +146,8 @@ if [ "${MAC_CERT_PW+x}" ]; then
fi fi
echo "Building DMG installer..." 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 if [ "${MAC_CERT_PW+x}" ]; then
echo "Signing DMG installer..." echo "Signing DMG installer..."