Compare commits
15 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e08b62df40 | |||
| 90912f9231 | |||
| 1754a82f67 | |||
| 3384008277 | |||
| af22115706 | |||
| 4b114fd3b6 | |||
| a5564148f5 | |||
| 196f7778fc | |||
| de20add857 | |||
| c59216b58a | |||
| acf7fa261a | |||
| c3eddc92bd | |||
| 18c74f4b02 | |||
| 5de4b8eeb8 | |||
| aae420e469 |
@@ -65,6 +65,13 @@ jobs:
|
||||
path: deploy/AppDir
|
||||
retention-days: 7
|
||||
|
||||
- name: 'Upload translations artifact'
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: AmneziaVPN_translations
|
||||
path: client/translations
|
||||
retention-days: 7
|
||||
|
||||
# ------------------------------------------------------
|
||||
|
||||
Build-Windows:
|
||||
|
||||
@@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.25.0 FATAL_ERROR)
|
||||
|
||||
set(PROJECT AmneziaVPN)
|
||||
|
||||
project(${PROJECT} VERSION 4.6.0.3
|
||||
project(${PROJECT} VERSION 4.6.0.4
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
|
||||
@@ -6,6 +6,26 @@
|
||||
|
||||
Amnezia is an open-source VPN client, with a key feature that enables you to deploy your own VPN server on your server.
|
||||
|
||||

|
||||
|
||||
<br>
|
||||
|
||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_4.6.0.3_x64.exe"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/win.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_4.6.0.3.dmg"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/mac.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/download/4.6.0.3/AmneziaVPN_Linux_4.6.0.3.tar.zip"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/lin.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://github.com/amnezia-vpn/amnezia-client/releases/tag/4.6.0.3"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/andr.png" width="150" style="max-width: 100%;"></a>
|
||||
|
||||
<br>
|
||||
|
||||
<a href="https://play.google.com/store/search?q=amnezia+vpn&c=apps"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/play.png" width="150" style="max-width: 100%;"></a>
|
||||
<a href="https://apps.apple.com/us/app/amneziavpn/id1600529900"><img src="https://github.com/amnezia-vpn/amnezia-client/blob/dev/metadata/img-readme/apl.png" width="150" style="max-width: 100%;"></a>
|
||||
|
||||
|
||||
[All releases](https://github.com/amnezia-vpn/amnezia-client/releases)
|
||||
|
||||
<br>
|
||||
|
||||
|
||||
## Features
|
||||
|
||||
- Very easy to use - enter your IP address, SSH login, and password, and Amnezia will automatically install VPN docker containers to your server and connect to the VPN.
|
||||
@@ -16,12 +36,12 @@ Amnezia is an open-source VPN client, with a key feature that enables you to dep
|
||||
|
||||
## Links
|
||||
|
||||
[https://amnezia.org](https://amnezia.org) - project website
|
||||
[https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
||||
[https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
|
||||
[https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
|
||||
[https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Telegram support channel (Myanmar)
|
||||
[https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
|
||||
- [https://amnezia.org](https://amnezia.org) - project website
|
||||
- [https://www.reddit.com/r/AmneziaVPN](https://www.reddit.com/r/AmneziaVPN) - Reddit
|
||||
- [https://t.me/amnezia_vpn_en](https://t.me/amnezia_vpn_en) - Telegram support channel (English)
|
||||
- [https://t.me/amnezia_vpn_ir](https://t.me/amnezia_vpn_ir) - Telegram support channel (Farsi)
|
||||
- [https://t.me/amnezia_vpn_mm](https://t.me/amnezia_vpn_mm) - Telegram support channel (Myanmar)
|
||||
- [https://t.me/amnezia_vpn](https://t.me/amnezia_vpn) - Telegram support channel (Russian)
|
||||
|
||||
## Tech
|
||||
|
||||
@@ -46,6 +66,19 @@ git submodule update --init --recursive
|
||||
|
||||
Want to contribute? Welcome!
|
||||
|
||||
### Help with translations
|
||||
|
||||
Download the most actual translation files.
|
||||
|
||||
Go to ["Actions" tab](https://github.com/amnezia-vpn/amnezia-client/actions?query=is%3Asuccess+branch%3Adev), click on the first line.
|
||||
Then scroll down to the "Artifacts" section and download "AmneziaVPN_translations".
|
||||
|
||||
Unzip this file.
|
||||
Each *.ts file contains strings for one corresponding language.
|
||||
|
||||
Translate or correct some strings in one or multiple *.ts files and commit them back to this repository into the ``client/translations`` folder.
|
||||
You can do it via a web-interface or any other method you're familiar with.
|
||||
|
||||
### Building sources and deployment
|
||||
|
||||
Check deploy folder for build scripts.
|
||||
@@ -145,8 +178,9 @@ GPL v3.0
|
||||
## Donate
|
||||
|
||||
Patreon: [https://www.patreon.com/amneziavpn](https://www.patreon.com/amneziavpn)
|
||||
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4
|
||||
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d
|
||||
|
||||
USDT BEP20: 0x6abD576765a826f87D1D95183438f9408C901bE4 <br>
|
||||
USDT TRC20: TELAitazF1MZGmiNjTcnxDjEiH5oe7LC9d <br>
|
||||
XMR: 48spms39jt1L2L5vyw2RQW6CXD6odUd4jFu19GZcDyKKQV9U88wsJVjSbL4CfRys37jVMdoaWVPSvezCQPhHXUW5UKLqUp3
|
||||
|
||||
## Acknowledgments
|
||||
|
||||
@@ -286,8 +286,8 @@ bool ContainerProps::isSupportedByCurrentPlatform(DockerContainer c)
|
||||
case DockerContainer::OpenVpn: return true;
|
||||
case DockerContainer::Awg: return true;
|
||||
case DockerContainer::Xray: return true;
|
||||
case DockerContainer::Cloak:
|
||||
return true;
|
||||
case DockerContainer::Cloak: return true;
|
||||
case DockerContainer::SSXray: return true;
|
||||
// case DockerContainer::ShadowSocks: return true;
|
||||
default: return false;
|
||||
}
|
||||
|
||||
@@ -91,6 +91,7 @@ target_sources(networkextension PRIVATE
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+OpenVPN.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/PacketTunnelProvider+Xray.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/WGConfig.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/XrayConfig.swift
|
||||
${CLIENT_ROOT_DIR}/platforms/ios/iosglue.mm
|
||||
)
|
||||
|
||||
|
||||
@@ -33,6 +33,10 @@ void debugMessageHandler(QtMsgType type, const QMessageLogContext& context, cons
|
||||
}
|
||||
|
||||
// Skip annoying messages from Qt
|
||||
if (msg.contains("OpenType support missing for")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg.startsWith("Unknown property") || msg.startsWith("Could not create pixmap") || msg.startsWith("Populating font") || msg.startsWith("stale focus object")) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import WireGuardKitGo
|
||||
|
||||
enum XrayErrors: Error {
|
||||
case noXrayConfig
|
||||
case xrayConfigIsWrong
|
||||
case cantSaveXrayConfig
|
||||
case cantParseListenAndPort
|
||||
case cantSaveHevSocksConfig
|
||||
@@ -26,14 +27,14 @@ extension PacketTunnelProvider {
|
||||
// Xray configuration
|
||||
guard let protocolConfiguration = self.protocolConfiguration as? NETunnelProviderProtocol,
|
||||
let providerConfiguration = protocolConfiguration.providerConfiguration,
|
||||
let xrayConfigData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
||||
let configData = providerConfiguration[Constants.xrayConfigKey] as? Data else {
|
||||
xrayLog(.error, message: "Can't get xray configuration")
|
||||
completionHandler(XrayErrors.noXrayConfig)
|
||||
return
|
||||
}
|
||||
|
||||
// Tunnel settings
|
||||
let ipv6Enabled = true
|
||||
let ipv6Enabled = false
|
||||
let hideVPNIcon = false
|
||||
|
||||
let settings = NEPacketTunnelNetworkSettings(tunnelRemoteAddress: "254.1.1.1")
|
||||
@@ -57,12 +58,29 @@ extension PacketTunnelProvider {
|
||||
return settings
|
||||
}()
|
||||
|
||||
let dns = ["8.8.4.4","1.1.1.1"]
|
||||
settings.dnsSettings = NEDNSSettings(servers: dns)
|
||||
|
||||
do {
|
||||
let port = 10808
|
||||
let address = "::1"
|
||||
let xrayConfig = try JSONDecoder().decode(XrayConfig.self,
|
||||
from: configData)
|
||||
|
||||
var dnsArray = [String]()
|
||||
if let dns1 = xrayConfig.dns1 {
|
||||
dnsArray.append(dns1)
|
||||
}
|
||||
if let dns2 = xrayConfig.dns2 {
|
||||
dnsArray.append(dns2)
|
||||
}
|
||||
|
||||
settings.dnsSettings = !dnsArray.isEmpty
|
||||
? NEDNSSettings(servers: dnsArray)
|
||||
: NEDNSSettings(servers: ["1.1.1.1"])
|
||||
|
||||
let xrayConfigData = xrayConfig.config.data(using: .utf8)
|
||||
|
||||
guard let xrayConfigData else {
|
||||
xrayLog(.error, message: "Can't encode config to data")
|
||||
completionHandler(XrayErrors.xrayConfigIsWrong)
|
||||
return
|
||||
}
|
||||
|
||||
let jsonDict = try JSONSerialization.jsonObject(with: xrayConfigData,
|
||||
options: []) as? [String: Any]
|
||||
@@ -73,6 +91,9 @@ extension PacketTunnelProvider {
|
||||
return
|
||||
}
|
||||
|
||||
let port = 10808
|
||||
let address = "::1"
|
||||
|
||||
if var inboundsArray = jsonDict["inbounds"] as? [[String: Any]], !inboundsArray.isEmpty {
|
||||
inboundsArray[0]["port"] = port
|
||||
inboundsArray[0]["listen"] = address
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
import Foundation
|
||||
|
||||
struct XrayConfig: Decodable {
|
||||
let dns1: String?
|
||||
let dns2: String?
|
||||
let config: String
|
||||
}
|
||||
@@ -73,6 +73,7 @@ private:
|
||||
bool setupWireGuard();
|
||||
bool setupAwg();
|
||||
bool setupXray();
|
||||
bool setupSSXray();
|
||||
|
||||
bool startOpenVPN(const QString &config);
|
||||
bool startWireGuard(const QString &jsonConfig);
|
||||
|
||||
@@ -219,6 +219,9 @@ bool IosController::connectVpn(amnezia::Proto proto, const QJsonObject& configur
|
||||
if (proto == amnezia::Proto::Xray) {
|
||||
return setupXray();
|
||||
}
|
||||
if (proto == amnezia::Proto::SSXray) {
|
||||
return setupSSXray();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -508,9 +511,36 @@ bool IosController::setupXray()
|
||||
{
|
||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::Xray)].toObject();
|
||||
QJsonDocument xrayConfigDoc(config);
|
||||
|
||||
QString xrayConfigStr(xrayConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startXray(xrayConfigStr);
|
||||
QJsonObject finalConfig;
|
||||
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1].toString());
|
||||
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2].toString());
|
||||
finalConfig.insert(config_key::config, xrayConfigStr);
|
||||
|
||||
QJsonDocument finalConfigDoc(finalConfig);
|
||||
QString finalConfigStr(finalConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startXray(finalConfigStr);
|
||||
}
|
||||
|
||||
bool IosController::setupSSXray()
|
||||
{
|
||||
QJsonObject config = m_rawConfig[ProtocolProps::key_proto_config_data(amnezia::Proto::SSXray)].toObject();
|
||||
QJsonDocument ssXrayConfigDoc(config);
|
||||
|
||||
QString ssXrayConfigStr(ssXrayConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
QJsonObject finalConfig;
|
||||
finalConfig.insert(config_key::dns1, m_rawConfig[config_key::dns1]);
|
||||
finalConfig.insert(config_key::dns2, m_rawConfig[config_key::dns2]);
|
||||
finalConfig.insert(config_key::config, ssXrayConfigStr);
|
||||
|
||||
QJsonDocument finalConfigDoc(finalConfig);
|
||||
QString finalConfigStr(finalConfigDoc.toJson(QJsonDocument::Compact));
|
||||
|
||||
return startXray(finalConfigStr);
|
||||
}
|
||||
|
||||
bool IosController::setupAwg()
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
#include "ikev2_vpn_protocol_windows.h"
|
||||
#include "utilities.h"
|
||||
|
||||
|
||||
static Ikev2Protocol* self = nullptr;
|
||||
static std::mutex rasDialFuncMutex;
|
||||
|
||||
@@ -80,10 +81,10 @@ void Ikev2Protocol::newConnectionStateEventReceived(UINT unMsg, tagRASCONNSTATE
|
||||
case RASCS_AuthNotify:
|
||||
//qDebug()<<__FUNCTION__ << __LINE__;
|
||||
if (dwError != 0) {
|
||||
//qDebug() << "have error" << dwError;
|
||||
qDebug() << "have error" << dwError;
|
||||
setConnectionState(Vpn::ConnectionState::Disconnected);
|
||||
} else {
|
||||
//qDebug() << "RASCS_AuthNotify but no error" << dwError;
|
||||
qDebug() << "RASCS_AuthNotify but no error" << dwError;
|
||||
}
|
||||
break;
|
||||
case RASCS_AuthRetry:
|
||||
@@ -179,11 +180,13 @@ ErrorCode Ikev2Protocol::start()
|
||||
QByteArray cert = QByteArray::fromBase64(m_config[config_key::cert].toString().toUtf8());
|
||||
setConnectionState(Vpn::ConnectionState::Connecting);
|
||||
|
||||
QTemporaryFile certFile;
|
||||
certFile.setAutoRemove(false);
|
||||
certFile.open();
|
||||
certFile.write(cert);
|
||||
certFile.close();
|
||||
QTemporaryFile * certFile = new QTemporaryFile;
|
||||
certFile->setAutoRemove(false);
|
||||
certFile->open();
|
||||
QString m_filename = certFile->fileName();
|
||||
certFile->write(cert);
|
||||
certFile->close();
|
||||
delete certFile;
|
||||
|
||||
{
|
||||
auto certInstallProcess = IpcClient::CreatePrivilegedProcess();
|
||||
@@ -193,19 +196,19 @@ ErrorCode Ikev2Protocol::start()
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
|
||||
certInstallProcess->waitForSource(1000);
|
||||
certInstallProcess->waitForSource();
|
||||
if (!certInstallProcess->isInitialized()) {
|
||||
qWarning() << "IpcProcess replica is not connected!";
|
||||
setLastError(ErrorCode::AmneziaServiceConnectionFailed);
|
||||
return ErrorCode::AmneziaServiceConnectionFailed;
|
||||
}
|
||||
certInstallProcess->setProgram(PermittedProcess::CertUtil);
|
||||
QStringList arguments({"-f" , "-importpfx",
|
||||
"-p", m_config[config_key::password].toString(),
|
||||
certFile.fileName(), "NoExport"
|
||||
});
|
||||
certInstallProcess->setArguments(arguments);
|
||||
|
||||
QStringList arguments({"-f", "-importpfx", "-p", m_config[config_key::password].toString(),
|
||||
QDir::toNativeSeparators(m_filename), "NoExport"
|
||||
});
|
||||
|
||||
certInstallProcess->setArguments(arguments);
|
||||
certInstallProcess->start();
|
||||
}
|
||||
// /*
|
||||
@@ -219,40 +222,40 @@ ErrorCode Ikev2Protocol::start()
|
||||
}
|
||||
|
||||
{
|
||||
{
|
||||
if ( !create_new_vpn(tunnelName(), m_config[config_key::hostName].toString())){
|
||||
qDebug() <<"Can't create the VPN connect";
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
if ( !create_new_vpn(tunnelName(), m_config[config_key::hostName].toString())){
|
||||
qDebug() <<"Can't create the VPN connect";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto adapterConfigProcess = new QProcess;
|
||||
{
|
||||
QProcess adapterConfigProcess;
|
||||
adapterConfigProcess.setProgram("powershell");
|
||||
QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\" "
|
||||
"-ConnectionName '%1' "
|
||||
"-AuthenticationTransformConstants GCMAES128 "
|
||||
"-CipherTransformConstants GCMAES128 "
|
||||
"-EncryptionMethod AES256 "
|
||||
"-IntegrityCheckMethod SHA256 "
|
||||
"-PfsGroup None "
|
||||
"-DHGroup Group14 "
|
||||
"-PassThru -Force\"")
|
||||
.arg(tunnelName());
|
||||
|
||||
adapterConfigProcess->setProgram("powershell");
|
||||
QString arguments = QString("-command \"Set-VpnConnectionIPsecConfiguration\" "
|
||||
"-ConnectionName '%1' "
|
||||
"-AuthenticationTransformConstants GCMAES128 "
|
||||
"-CipherTransformConstants GCMAES128 "
|
||||
"-EncryptionMethod AES256 "
|
||||
"-IntegrityCheckMethod SHA256 "
|
||||
"-PfsGroup None "
|
||||
"-DHGroup Group14 "
|
||||
"-PassThru -Force\"")
|
||||
.arg(tunnelName());
|
||||
adapterConfigProcess->setNativeArguments(arguments);
|
||||
adapterConfigProcess.setNativeArguments(arguments);
|
||||
|
||||
adapterConfigProcess->start();
|
||||
adapterConfigProcess->waitForFinished(5000);
|
||||
adapterConfigProcess.start();
|
||||
adapterConfigProcess.waitForFinished(5000);
|
||||
}
|
||||
//*/
|
||||
{
|
||||
if (!connect_to_vpn(tunnelName())) {
|
||||
qDebug()<<"We can't connect to VPN";
|
||||
}
|
||||
//*/
|
||||
{
|
||||
if (!connect_to_vpn(tunnelName())) {
|
||||
qDebug()<<"We can't connect to VPN";
|
||||
}
|
||||
}
|
||||
//setConnectionState(Connecting);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
//setConnectionState(Connecting);
|
||||
return ErrorCode::NoError;
|
||||
}
|
||||
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
bool Ikev2Protocol::create_new_vpn(const QString & vpn_name,
|
||||
@@ -299,6 +302,7 @@ bool Ikev2Protocol::connect_to_vpn(const QString & vpn_name){
|
||||
auto ret = RasDial(NULL, NULL, &RasDialParams, 0,
|
||||
&RasDialFuncCallback,
|
||||
&hRasConn);
|
||||
|
||||
if (ret == ERROR_SUCCESS){
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -11,16 +11,6 @@
|
||||
<file>images/tray/default.png</file>
|
||||
<file>images/tray/error.png</file>
|
||||
<file>images/arrow_left.png</file>
|
||||
<file>fonts/Lato-Black.ttf</file>
|
||||
<file>fonts/Lato-BlackItalic.ttf</file>
|
||||
<file>fonts/Lato-Bold.ttf</file>
|
||||
<file>fonts/Lato-BoldItalic.ttf</file>
|
||||
<file>fonts/Lato-Italic.ttf</file>
|
||||
<file>fonts/Lato-Light.ttf</file>
|
||||
<file>fonts/Lato-LightItalic.ttf</file>
|
||||
<file>fonts/Lato-Regular.ttf</file>
|
||||
<file>fonts/Lato-Thin.ttf</file>
|
||||
<file>fonts/Lato-ThinItalic.ttf</file>
|
||||
<file>images/AmneziaVPN.png</file>
|
||||
<file>images/share.png</file>
|
||||
<file>server_scripts/remove_container.sh</file>
|
||||
@@ -95,7 +85,6 @@
|
||||
<file>server_scripts/check_user_in_sudo.sh</file>
|
||||
<file>ui/qml/Controls2/BasicButtonType.qml</file>
|
||||
<file>ui/qml/Controls2/TextFieldWithHeaderType.qml</file>
|
||||
<file>fonts/pt-root-ui_vf.ttf</file>
|
||||
<file>ui/qml/Controls2/LabelWithButtonType.qml</file>
|
||||
<file>images/controls/arrow-right.svg</file>
|
||||
<file>images/controls/chevron-right.svg</file>
|
||||
@@ -239,6 +228,7 @@
|
||||
<file>images/controls/alert-circle.svg</file>
|
||||
<file>images/controls/file-check-2.svg</file>
|
||||
<file>ui/qml/Controls2/WarningType.qml</file>
|
||||
<file>fonts/pt-root-ui_vf.ttf</file>
|
||||
<file>ui/qml/Modules/Style/qmldir</file>
|
||||
<file>ui/qml/Modules/Style/AmneziaStyle.qml</file>
|
||||
<file>ui/qml/Pages2/PageServiceSocksProxySettings.qml</file>
|
||||
|
||||
@@ -92,9 +92,9 @@ int LanguageModel::getCurrentLanguageIndex()
|
||||
|
||||
int LanguageModel::getLineHeightAppend()
|
||||
{
|
||||
int langIndex = getCurrentLanguageIndex();
|
||||
switch (langIndex) {
|
||||
case 5: return 10; break; // Burmese
|
||||
auto language = static_cast<LanguageSettings::AvailableLanguageEnum>(getCurrentLanguageIndex());
|
||||
switch (language) {
|
||||
case LanguageSettings::AvailableLanguageEnum::Burmese: return 10; break;
|
||||
default: return 0; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ DrawerType2 {
|
||||
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
||||
|
||||
anchors.fill: parent
|
||||
expandedHeight: parent.height * 0.7
|
||||
expandedHeight: parent.height * 0.9
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: content
|
||||
|
||||
@@ -93,20 +93,11 @@ ListView {
|
||||
PageController.goToPage(PageEnum.PageProtocolRaw)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.Sftp: {
|
||||
SftpConfigModel.updateModel(config)
|
||||
PageController.goToPage(PageEnum.PageServiceSftpSettings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.TorWebSite: {
|
||||
PageController.goToPage(PageEnum.PageServiceTorWebsiteSettings)
|
||||
break
|
||||
}
|
||||
case ContainerEnum.Dns: {
|
||||
PageController.goToPage(PageEnum.PageServiceDnsSettings)
|
||||
break
|
||||
}
|
||||
default: { // go to the settings page of the container with multiple protocols
|
||||
default: {
|
||||
ProtocolsModel.updateModel(config)
|
||||
PageController.goToPage(PageEnum.PageSettingsServerProtocol)
|
||||
}
|
||||
|
||||
@@ -32,6 +32,8 @@ Button {
|
||||
|
||||
property var clickedFunc
|
||||
|
||||
property alias buttonTextLabel: buttonText
|
||||
|
||||
implicitHeight: 56
|
||||
|
||||
hoverEnabled: true
|
||||
@@ -140,6 +142,8 @@ Button {
|
||||
}
|
||||
|
||||
ButtonTextType {
|
||||
id: buttonText
|
||||
|
||||
color: textColor
|
||||
text: root.text
|
||||
visible: root.text === "" ? false : true
|
||||
|
||||
@@ -102,7 +102,8 @@ Switch {
|
||||
contentItem: ColumnLayout {
|
||||
id: content
|
||||
|
||||
anchors.verticalCenter: parent.verticalCenter
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.left: parent.left
|
||||
|
||||
ListItemTitleType {
|
||||
|
||||
@@ -7,10 +7,10 @@ Text {
|
||||
lineHeightMode: Text.FixedHeight
|
||||
|
||||
color: AmneziaStyle.color.white
|
||||
font.pixelSize: 36
|
||||
font.pixelSize: 32
|
||||
font.weight: 700
|
||||
font.family: "PT Root UI VF"
|
||||
font.letterSpacing: -1.08
|
||||
font.letterSpacing: -1.0
|
||||
|
||||
wrapMode: Text.WordWrap
|
||||
}
|
||||
|
||||
@@ -85,6 +85,7 @@ PageType {
|
||||
|
||||
BasicButtonType {
|
||||
id: splitTunnelingButton
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 34
|
||||
leftPadding: 16
|
||||
@@ -100,6 +101,10 @@ PageType {
|
||||
leftImageColor: AmneziaStyle.color.transparent
|
||||
borderWidth: 0
|
||||
|
||||
buttonTextLabel.lineHeight: 20
|
||||
buttonTextLabel.font.pixelSize: 14
|
||||
buttonTextLabel.font.weight: 500
|
||||
|
||||
property bool isSplitTunnelingEnabled: SitesModel.isTunnelingEnabled || AppSplitTunnelingModel.isTunnelingEnabled ||
|
||||
(ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi"))
|
||||
|
||||
|
||||
@@ -58,7 +58,7 @@ PageType {
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: "Amnezia DNS"
|
||||
headerText: "AmneziaDNS"
|
||||
descriptionText: qsTr("A DNS service is installed on your server, and it is only accessible via VPN.\n") +
|
||||
qsTr("The DNS address is the same as the address of your server. You can configure DNS in the settings, under the connections tab.")
|
||||
}
|
||||
@@ -82,7 +82,7 @@ PageType {
|
||||
var yesButtonFunction = function() {
|
||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected
|
||||
&& SettingsController.isAmneziaDnsEnabled()) {
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove Amnezia DNS from running server"))
|
||||
PageController.showNotificationMessage(qsTr("Cannot remove AmneziaDNS from running server"))
|
||||
} else
|
||||
{
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
@@ -104,8 +104,6 @@ PageType {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ PageType {
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
listview.currentItem.focusItem.forceActiveFocus()
|
||||
listview.currentItem.listViewFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ PageType {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
property alias focusItem: hostLabel.rightButton
|
||||
property alias listViewFocusItem: hostLabel.rightButton
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
@@ -233,7 +233,7 @@ PageType {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.mountSftpDrive(port, password, username)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
@@ -290,48 +290,12 @@ PageType {
|
||||
text: qsTr("Detailed instructions")
|
||||
|
||||
parentFlickable: fl
|
||||
KeyNavigation.tab: removeButton
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunc: function() {
|
||||
// Qt.openUrlExternally("https://github.com/amnezia-vpn/desktop-client/releases/latest")
|
||||
}
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: removeButton
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.blackHovered
|
||||
pressedColor: AmneziaStyle.color.blackPressed
|
||||
textColor: AmneziaStyle.color.red
|
||||
|
||||
parentFlickable: fl
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
|
||||
text: qsTr("Remove SFTP and all data stored there")
|
||||
|
||||
clickedFunc: function() {
|
||||
var headerText = qsTr("Remove SFTP and all data stored there?")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
removeButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/copy.svg"
|
||||
rightImageColor: AmneziaStyle.color.white
|
||||
|
||||
KeyNavigation.tab: removeButton
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunction: function() {
|
||||
GC.copyToClipBoard(descriptionText)
|
||||
@@ -127,41 +127,6 @@ PageType {
|
||||
|
||||
text: qsTr("When configuring WordPress set the this onion address as domain.")
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: removeButton
|
||||
Layout.topMargin: 24
|
||||
Layout.bottomMargin: 16
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.blackHovered
|
||||
pressedColor: AmneziaStyle.color.blackPressed
|
||||
textColor: AmneziaStyle.color.red
|
||||
|
||||
text: qsTr("Remove website")
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunc: function() {
|
||||
var headerText = qsTr("The site with all data will be removed from the tor network.")
|
||||
var yesButtonText = qsTr("Continue")
|
||||
var noButtonText = qsTr("Cancel")
|
||||
|
||||
var yesButtonFunction = function() {
|
||||
PageController.goToPage(PageEnum.PageDeinstalling)
|
||||
InstallController.removeProcessedContainer()
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
removeButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -276,7 +276,7 @@ PageType {
|
||||
|
||||
if (Qt.platform.os === "windows") {
|
||||
var fileName = SystemController.getFileName(qsTr("Open executable file"),
|
||||
qsTr("Executable file (*.*)"))
|
||||
qsTr("Executable files (*.*)"))
|
||||
if (fileName !== "") {
|
||||
AppSplitTunnelingController.addApp(fileName)
|
||||
}
|
||||
|
||||
@@ -51,6 +51,8 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
|
||||
@@ -105,6 +105,7 @@ PageType {
|
||||
case ProtocolEnum.WireGuard: WireGuardConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ProtocolEnum.Awg: AwgConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ProtocolEnum.Xray: XrayConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ProtocolEnum.Sftp: SftpConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ProtocolEnum.Ipsec: Ikev2ConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
case ProtocolEnum.Socks5Proxy: Socks5ProxyConfigModel.updateModel(ProtocolsModel.getConfig()); break;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,8 @@ PageType {
|
||||
|
||||
clickedFunc: function() {
|
||||
if (!port.textField.acceptableInput &&
|
||||
ContainerProps.containerTypeToString(dockerContainer) !== "torwebsite") {
|
||||
ContainerProps.containerTypeToString(dockerContainer) !== "torwebsite" &&
|
||||
ContainerProps.containerTypeToString(dockerContainer) !== "ikev2") {
|
||||
port.errorText = qsTr("The port must be in the range of 1 to 65535")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -202,7 +202,7 @@ PageType {
|
||||
parent: root
|
||||
|
||||
anchors.fill: parent
|
||||
expandedHeight: root.height * 0.45
|
||||
expandedHeight: root.height
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
clientNameTextField.textField.forceActiveFocus()
|
||||
@@ -210,6 +210,7 @@ PageType {
|
||||
}
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: shareFullAccessDrawerContent
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
@@ -217,6 +218,10 @@ PageType {
|
||||
|
||||
spacing: 0
|
||||
|
||||
onImplicitHeightChanged: {
|
||||
shareFullAccessDrawer.expandedHeight = shareFullAccessDrawerContent.implicitHeight + 32
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: shareFullAccessDrawer
|
||||
enabled: !GC.isMobile()
|
||||
|
||||
|
After Width: | Height: | Size: 13 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 9.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 339 KiB |
|
After Width: | Height: | Size: 11 KiB |