mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-07-03 14:07:39 +02:00
Compare commits
27 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1e8909c50c | |||
| 699b2e8a4e | |||
| 1343d10aa7 | |||
| 6f96ebd8bf | |||
| cb531dacb3 | |||
| dfd0b4d0e5 | |||
| f978f55e7f | |||
| ef06fcb4f4 | |||
| ffe2314d47 | |||
| 4e970322d0 | |||
| 8dee0d27cf | |||
| c520f9a2a4 | |||
| 003c3a23c4 | |||
| 1754a82f67 | |||
| 3384008277 | |||
| af22115706 | |||
| 4b114fd3b6 | |||
| 9d531f5d74 | |||
| 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
-2
@@ -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.1.0
|
||||
DESCRIPTION "AmneziaVPN"
|
||||
HOMEPAGE_URL "https://amnezia.org/"
|
||||
)
|
||||
@@ -11,7 +11,7 @@ string(TIMESTAMP CURRENT_DATE "%Y-%m-%d")
|
||||
set(RELEASE_DATE "${CURRENT_DATE}")
|
||||
|
||||
set(APP_MAJOR_VERSION ${CMAKE_PROJECT_VERSION_MAJOR}.${CMAKE_PROJECT_VERSION_MINOR}.${CMAKE_PROJECT_VERSION_PATCH})
|
||||
set(APP_ANDROID_VERSION_CODE 55)
|
||||
set(APP_ANDROID_VERSION_CODE 56)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
set(MZ_PLATFORM_NAME "linux")
|
||||
|
||||
@@ -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
|
||||
|
||||
+1
-1
Submodule client/3rd-prebuilt updated: ff8445c8aa...c38a587fcd
Vendored
+1
-1
Submodule client/3rd/OpenVPNAdapter updated: 7c821a8d5c...dea6040996
@@ -11,6 +11,9 @@
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.any" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
|
||||
<!-- for TV -->
|
||||
<uses-feature android:name="android.software.leanback" android:required="false" />
|
||||
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
|
||||
|
||||
<!-- The following comment will be replaced upon deployment with default features based on the dependencies
|
||||
of the application. Remove the comment if you do not require these default features. -->
|
||||
@@ -31,9 +34,11 @@
|
||||
android:label="-- %%INSERT_APP_NAME%% --"
|
||||
android:icon="@mipmap/icon"
|
||||
android:roundIcon="@mipmap/icon_round"
|
||||
android:banner="@mipmap/ic_banner"
|
||||
android:theme="@style/NoActionBar"
|
||||
android:fullBackupContent="@xml/backup_content"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
android:hasFragileUserData="false"
|
||||
tools:targetApi="s">
|
||||
|
||||
<activity
|
||||
@@ -47,6 +52,7 @@
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
|
||||
</intent-filter>
|
||||
|
||||
<intent-filter>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@color/ic_banner_background"/>
|
||||
<foreground android:drawable="@mipmap/ic_banner_foreground"/>
|
||||
</adaptive-icon>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 11 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="ic_banner_background">#1E1E1F</color>
|
||||
</resources>
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.amnezia.vpn
|
||||
|
||||
import android.Manifest
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.AlertDialog
|
||||
import android.app.NotificationManager
|
||||
import android.content.BroadcastReceiver
|
||||
@@ -230,7 +231,10 @@ class AmneziaActivity : QtActivity() {
|
||||
override fun onStop() {
|
||||
Log.d(TAG, "Stop Amnezia activity")
|
||||
doUnbindService()
|
||||
QtAndroidController.onServiceDisconnected()
|
||||
mainScope.launch {
|
||||
qtInitialized.await()
|
||||
QtAndroidController.onServiceDisconnected()
|
||||
}
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
@@ -542,7 +546,7 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
}.also {
|
||||
startActivityForResult(it, OPEN_FILE_ACTION_CODE, ActivityResultHandler(
|
||||
onSuccess = {
|
||||
onAny = {
|
||||
val uri = it?.data?.toString() ?: ""
|
||||
Log.d(TAG, "Open file: $uri")
|
||||
mainScope.launch {
|
||||
@@ -556,8 +560,12 @@ class AmneziaActivity : QtActivity() {
|
||||
}
|
||||
|
||||
@Suppress("unused")
|
||||
@SuppressLint("UnsupportedChromeOsCameraSystemFeature")
|
||||
fun isCameraPresent(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA)
|
||||
|
||||
@Suppress("unused")
|
||||
fun isOnTv(): Boolean = applicationContext.packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK)
|
||||
|
||||
@Suppress("unused")
|
||||
fun startQrCodeReader() {
|
||||
Log.v(TAG, "Start camera")
|
||||
|
||||
@@ -88,16 +88,24 @@ class NetworkState(
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
|
||||
connectivityManager.registerBestMatchingNetworkCallback(networkRequest, networkCallback, handler)
|
||||
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
try {
|
||||
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
|
||||
} catch (e: SecurityException) {
|
||||
Log.e(TAG, "Failed to bind network listener: $e")
|
||||
// Android 11 bug: https://issuetracker.google.com/issues/175055271
|
||||
if (e.message?.startsWith("Package android does not belong to") == true) {
|
||||
delay(1000)
|
||||
val numberAttempts = 3
|
||||
var attemptCount = 0
|
||||
while(true) {
|
||||
try {
|
||||
connectivityManager.requestNetwork(networkRequest, networkCallback, handler)
|
||||
} else {
|
||||
throw e
|
||||
break
|
||||
} catch (e: SecurityException) {
|
||||
Log.e(TAG, "Failed to bind network listener: $e")
|
||||
// Android 11 bug: https://issuetracker.google.com/issues/175055271
|
||||
if (e.message?.startsWith("Package android does not belong to") == true) {
|
||||
if (++attemptCount > numberAttempts) {
|
||||
throw e
|
||||
}
|
||||
delay(1000)
|
||||
continue
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -119,18 +119,21 @@ QString OpenVpnConfigurator::processConfigWithLocalSettings(const QPair<QString,
|
||||
|
||||
if (!m_settings->isSitesSplitTunnelingEnabled()) {
|
||||
config.append("\nredirect-gateway def1 ipv6 bypass-dhcp\n");
|
||||
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
// Prevent ipv6 leak
|
||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||
#endif
|
||||
config.append("block-ipv6\n");
|
||||
} else if (m_settings->routeMode() == Settings::VpnOnlyForwardSites) {
|
||||
|
||||
// no redirect-gateway
|
||||
} else if (m_settings->routeMode() == Settings::VpnAllExceptSites) {
|
||||
#ifndef Q_OS_ANDROID
|
||||
#if !defined(Q_OS_ANDROID) && !defined(Q_OS_IOS)
|
||||
config.append("\nredirect-gateway ipv6 !ipv4 bypass-dhcp\n");
|
||||
#endif
|
||||
// Prevent ipv6 leak
|
||||
config.append("ifconfig-ipv6 fd15:53b6:dead::2/64 fd15:53b6:dead::1\n");
|
||||
#endif
|
||||
config.append("block-ipv6\n");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +96,7 @@ QMap<DockerContainer, QString> ContainerProps::containerHumanNames()
|
||||
{ DockerContainer::Awg, "AmneziaWG" },
|
||||
{ DockerContainer::Xray, "XRay" },
|
||||
{ DockerContainer::Ipsec, QObject::tr("IPsec") },
|
||||
{ DockerContainer::SSXray, "ShadowSocks"},
|
||||
{ DockerContainer::SSXray, "Shadowsocks"},
|
||||
|
||||
{ DockerContainer::TorWebSite, QObject::tr("Website in Tor network") },
|
||||
{ DockerContainer::Dns, QObject::tr("AmneziaDNS") },
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
}
|
||||
|
||||
@@ -179,6 +179,11 @@ bool AndroidController::isCameraPresent()
|
||||
return callActivityMethod<jboolean>("isCameraPresent", "()Z");
|
||||
}
|
||||
|
||||
bool AndroidController::isOnTv()
|
||||
{
|
||||
return callActivityMethod<jboolean>("isOnTv", "()Z");
|
||||
}
|
||||
|
||||
void AndroidController::startQrReaderActivity()
|
||||
{
|
||||
callActivityMethod("startQrCodeReader", "()V");
|
||||
|
||||
@@ -35,6 +35,7 @@ public:
|
||||
void saveFile(const QString &fileName, const QString &data);
|
||||
QString openFile(const QString &filter);
|
||||
bool isCameraPresent();
|
||||
bool isOnTv();
|
||||
void startQrReaderActivity();
|
||||
void setSaveLogs(bool enabled);
|
||||
void exportLogsFile(const QString &fileName);
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -65,14 +65,14 @@ QString ProtocolProps::transportProtoToString(TransportProto proto, Proto p)
|
||||
QMap<amnezia::Proto, QString> ProtocolProps::protocolHumanNames()
|
||||
{
|
||||
return { { Proto::OpenVpn, "OpenVPN" },
|
||||
{ Proto::ShadowSocks, "ShadowSocks" },
|
||||
{ Proto::ShadowSocks, "Shadowsocks" },
|
||||
{ Proto::Cloak, "Cloak" },
|
||||
{ Proto::WireGuard, "WireGuard" },
|
||||
{ Proto::Awg, "AmneziaWG" },
|
||||
{ Proto::Ikev2, "IKEv2" },
|
||||
{ Proto::L2tp, "L2TP" },
|
||||
{ Proto::Xray, "XRay" },
|
||||
{ Proto::SSXray, "ShadowSocks"},
|
||||
{ Proto::SSXray, "Shadowsocks"},
|
||||
|
||||
|
||||
{ Proto::TorWebSite, "Website in Tor network" },
|
||||
|
||||
+2
-11
@@ -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>
|
||||
@@ -246,5 +236,6 @@
|
||||
<file>server_scripts/socks5_proxy/Dockerfile</file>
|
||||
<file>server_scripts/socks5_proxy/configure_container.sh</file>
|
||||
<file>server_scripts/socks5_proxy/start.sh</file>
|
||||
<file>ui/qml/Controls2/FocusChainType.qml</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
||||
+1104
-858
File diff suppressed because it is too large
Load Diff
+1081
-555
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+1081
-555
File diff suppressed because it is too large
Load Diff
+1152
-639
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
+1082
-556
File diff suppressed because it is too large
Load Diff
@@ -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,74 +14,71 @@ DrawerType2 {
|
||||
width: parent.width
|
||||
height: parent.height
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: content
|
||||
expandedContent: FocusChainType {
|
||||
focus: root.visible
|
||||
focusTabBarOnLastItem: false
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 0
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
Component.onCompleted: {
|
||||
root.expandedHeight = content.implicitHeight + 32
|
||||
}
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 0
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
enabled: !GC.isMobile()
|
||||
function onOpened() {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
headerText: qsTr("Add new connection")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: ip.rightButton
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: ip
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
text: qsTr("Configure your server")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
||||
root.close()
|
||||
Component.onCompleted: {
|
||||
root.expandedHeight = content.implicitHeight + 32
|
||||
}
|
||||
|
||||
KeyNavigation.tab: qrCode.rightButton
|
||||
}
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: qrCode
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Open config file, key or QR code")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||
root.close()
|
||||
headerText: qsTr("Add new connection")
|
||||
}
|
||||
|
||||
KeyNavigation.tab: focusItem
|
||||
}
|
||||
// Item {
|
||||
// id: focusItem
|
||||
// KeyNavigation.tab: ip.rightButton
|
||||
// }
|
||||
|
||||
DividerType {}
|
||||
LabelWithButtonType {
|
||||
id: ip
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
text: qsTr("Configure your server")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardCredentials)
|
||||
root.close()
|
||||
}
|
||||
|
||||
// KeyNavigation.tab: qrCode.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: qrCode
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("Open config file, key or QR code")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardConfigSource)
|
||||
root.close()
|
||||
}
|
||||
|
||||
// KeyNavigation.tab: focusItem
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,105 +14,111 @@ 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
|
||||
expandedContent: FocusChainType {
|
||||
focus: root.visible
|
||||
focusTabBarOnLastItem: false
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 0
|
||||
ColumnLayout {
|
||||
id: content
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
enabled: !GC.isMobile()
|
||||
function onOpened() {
|
||||
focusItem.forceActiveFocus()
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
spacing: 0
|
||||
|
||||
// onActiveFocusChanged: {
|
||||
// if (activeFocus) {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
// Connections {
|
||||
// target: root
|
||||
// enabled: !GC.isMobile()
|
||||
// function onOpened() {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
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")
|
||||
}
|
||||
}
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 24
|
||||
Layout.rightMargin: 16
|
||||
Layout.leftMargin: 16
|
||||
Layout.bottomMargin: 16
|
||||
LabelWithButtonType {
|
||||
id: splitTunnelingSwitch
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
headerText: qsTr("Split tunneling")
|
||||
descriptionText: qsTr("Allows you to connect to some sites or applications through a VPN connection and bypass others")
|
||||
}
|
||||
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: splitTunnelingSwitch.visible ? splitTunnelingSwitch : siteBasedSplitTunnelingSwitch.rightButton
|
||||
}
|
||||
text: qsTr("Split tunneling on the server")
|
||||
descriptionText: qsTr("Enabled \nCan't be disabled for current server")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
LabelWithButtonType {
|
||||
id: splitTunnelingSwitch
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
// KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
|
||||
|
||||
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"
|
||||
|
||||
KeyNavigation.tab: siteBasedSplitTunnelingSwitch.visible ? siteBasedSplitTunnelingSwitch.rightButton : focusItem
|
||||
|
||||
clickedFunction: function() {
|
||||
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||
// root.close()
|
||||
clickedFunction: function() {
|
||||
// PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||
// root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: siteBasedSplitTunnelingSwitch
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
text: qsTr("Site-based split tunneling")
|
||||
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
|
||||
appSplitTunnelingSwitch.rightButton :
|
||||
focusItem
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||
root.close()
|
||||
DividerType {
|
||||
visible: ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && ServersModel.getDefaultServerData("isServerFromApi")
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
}
|
||||
LabelWithButtonType {
|
||||
id: siteBasedSplitTunnelingSwitch
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 16
|
||||
|
||||
LabelWithButtonType {
|
||||
id: appSplitTunnelingSwitch
|
||||
visible: isAppSplitTinnelingEnabled
|
||||
text: qsTr("Site-based split tunneling")
|
||||
descriptionText: enabled && SitesModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
Layout.fillWidth: true
|
||||
// KeyNavigation.tab: appSplitTunnelingSwitch.visible ?
|
||||
// appSplitTunnelingSwitch.rightButton :
|
||||
// focusItem
|
||||
|
||||
text: qsTr("App-based split tunneling")
|
||||
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
KeyNavigation.tab: focusItem
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
||||
root.close()
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsSplitTunneling)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
visible: isAppSplitTinnelingEnabled
|
||||
DividerType {
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
id: appSplitTunnelingSwitch
|
||||
visible: isAppSplitTinnelingEnabled
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: qsTr("App-based split tunneling")
|
||||
descriptionText: AppSplitTunnelingModel.isTunnelingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
// KeyNavigation.tab: focusItem
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsAppSplitTunneling)
|
||||
root.close()
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
visible: isAppSplitTinnelingEnabled
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ import Qt5Compat.GraphicalEffects
|
||||
|
||||
import Style 1.0
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
property string backButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||
@@ -15,12 +15,6 @@ Item {
|
||||
|
||||
visible: backButtonImage !== ""
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
backButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
id: content
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -20,7 +20,8 @@ Menu {
|
||||
MenuItem {
|
||||
text: qsTr("&Paste")
|
||||
shortcut: StandardKey.Paste
|
||||
enabled: textObj.canPaste
|
||||
// Fix calling paste from clipboard when launching app on android
|
||||
enabled: Qt.platform.os === "android" ? true : textObj.canPaste
|
||||
onTriggered: textObj.paste()
|
||||
}
|
||||
|
||||
|
||||
@@ -4,9 +4,10 @@ import QtQuick.Layouts
|
||||
|
||||
import Style 1.0
|
||||
|
||||
import "../Config"
|
||||
import "TextTypes"
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
readonly property string drawerExpanded: "expanded"
|
||||
@@ -40,6 +41,50 @@ Item {
|
||||
signal closed
|
||||
signal opened
|
||||
|
||||
onClosed: {
|
||||
if (GC.isMobile()) {
|
||||
return
|
||||
}
|
||||
|
||||
// if (parent && parent instanceof PageType) {
|
||||
// parent.focusItem_.forceActiveFocus()
|
||||
// }
|
||||
|
||||
// tabBarStackView.currentItem.focusItem_.forceActiveFocus()
|
||||
|
||||
// PageController.forceStackActiveFocus()
|
||||
}
|
||||
|
||||
// onOpened: {
|
||||
// if (GC.isMobile()) {
|
||||
// return
|
||||
// }
|
||||
|
||||
// if (root.expandedContent) {
|
||||
// expandedLoader.item.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (GC.isMobile()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (root.activeFocus && !root.isOpened && root.collapsedContent) {
|
||||
collapsedLoader.item.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
onOpened: {
|
||||
if (isOpened) {
|
||||
if (drawerContent.state === root.drawerExpanded) {
|
||||
expandedLoader.item.forceActiveFocus()
|
||||
} else {
|
||||
collapsedLoader.item.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
|
||||
@@ -175,6 +220,7 @@ Item {
|
||||
Item {
|
||||
id: drawerContent
|
||||
|
||||
focus: true
|
||||
Drag.active: dragArea.drag.active
|
||||
anchors.right: root.right
|
||||
anchors.left: root.left
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
import QtQuick
|
||||
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
property bool focusTabBarOnLastItem: true
|
||||
property alias focusItem_: focusItem
|
||||
|
||||
QtObject {
|
||||
id: internal
|
||||
|
||||
property var firstActiveFocusItem: null
|
||||
property var focusChain: []
|
||||
}
|
||||
|
||||
onVisibleChanged: {
|
||||
focusItem_.focus = true
|
||||
}
|
||||
|
||||
function getChildren(parent) {
|
||||
for (var i = 0; i < parent.children.length; i++) {
|
||||
var child = parent.children[i]
|
||||
|
||||
if (child.children) {
|
||||
getChildren(child)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function isFocusableItem(item) {
|
||||
if (!item || !item.visible || !item.enabled) {
|
||||
return false
|
||||
}
|
||||
|
||||
return item instanceof BasicButtonType ||
|
||||
item instanceof ConnectButton ||
|
||||
item instanceof LabelWithButtonType ||
|
||||
item instanceof SwitcherType ||
|
||||
item instanceof ImageButtonType ||
|
||||
item instanceof TextFieldWithHeaderType ||
|
||||
item instanceof BackButtonType ||
|
||||
item instanceof HorizontalRadioButton ||
|
||||
item instanceof DrawerType2 && !item.isOpened && item.collapsedContent
|
||||
}
|
||||
|
||||
function getFocusChain(parent) {
|
||||
let focusChain = []
|
||||
for (var i = 0; i < parent.children.length; i++) {
|
||||
var child = parent.children[i]
|
||||
|
||||
if (child instanceof DropDownType ||
|
||||
child instanceof HomeSplitTunnelingDrawer ||
|
||||
child instanceof ConnectionTypeSelectionDrawer
|
||||
) {
|
||||
continue
|
||||
}
|
||||
|
||||
if (isFocusableItem(child)) {
|
||||
focusChain.push(child)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
if (child.children) {
|
||||
focusChain = focusChain.concat(getFocusChain(child))
|
||||
}
|
||||
}
|
||||
|
||||
return focusChain
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
internal.focusChain = getFocusChain(root)
|
||||
|
||||
if (internal.focusChain.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
for (let i = 0; i < internal.focusChain.length; i++) {
|
||||
internal.focusChain[i].KeyNavigation.tab = internal.focusChain[(i + 1) % internal.focusChain.length]
|
||||
internal.focusChain[i].KeyNavigation.backtab = internal.focusChain[(i + internal.focusChain.length - 1) % internal.focusChain.length]
|
||||
}
|
||||
|
||||
internal.firstActiveFocusItem = internal.focusChain[0]
|
||||
|
||||
const lastItem = internal.focusChain[internal.focusChain.length - 1]
|
||||
lastItem.Keys.onTabPressed.connect(function() {
|
||||
lastItemTabClicked(lastItem)
|
||||
})
|
||||
|
||||
for (let j = 0; j < internal.focusChain.length; j++) {
|
||||
if (internal.focusChain[j] instanceof TextFieldWithHeaderType) {
|
||||
internal.focusChain[j].forceActiveFocus()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
focus: true
|
||||
|
||||
Keys.onTabPressed: {
|
||||
if (internal.firstActiveFocusItem) {
|
||||
internal.firstActiveFocusItem.focus = true
|
||||
internal.firstActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function lastItemTabClicked() {
|
||||
focusItem.focus = true
|
||||
|
||||
if (GC.isMobile()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (focusTabBarOnLastItem) {
|
||||
PageController.forceTabBarActiveFocus()
|
||||
}
|
||||
|
||||
|
||||
if (lastItem && lastItem.parentFlickable) {
|
||||
lastItem.parentFlickable.contentY = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -43,25 +43,17 @@ Item {
|
||||
implicitWidth: content.implicitWidth + content.anchors.topMargin + content.anchors.bottomMargin
|
||||
implicitHeight: content.implicitHeight + content.anchors.leftMargin + content.anchors.rightMargin
|
||||
|
||||
onFocusChanged: {
|
||||
onActiveFocusChanged: {
|
||||
if (root.activeFocus) {
|
||||
if (rightImage.visible) {
|
||||
rightImage.forceActiveFocus()
|
||||
}
|
||||
if (root.parentFlickable) {
|
||||
root.parentFlickable.ensureVisible(root)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: rightImage
|
||||
function onFocusChanged() {
|
||||
if (rightImage.activeFocus) {
|
||||
if (root.parentFlickable) {
|
||||
root.parentFlickable.ensureVisible(root)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
@@ -251,6 +243,7 @@ Item {
|
||||
hoverEnabled: false
|
||||
image: rightImageSource
|
||||
imageColor: rightImageColor
|
||||
// focus: visible
|
||||
visible: rightImageSource ? true : false
|
||||
|
||||
Layout.alignment: Qt.AlignRight
|
||||
@@ -277,6 +270,7 @@ Item {
|
||||
id: background
|
||||
anchors.fill: root
|
||||
color: AmneziaStyle.color.transparent
|
||||
visible: !rightImageSource
|
||||
|
||||
border.color: root.activeFocus ? root.borderFocusedColor : AmneziaStyle.color.transparent
|
||||
border.width: root.activeFocus ? root.borderFocusedWidth : 0
|
||||
|
||||
@@ -1,37 +1,19 @@
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
|
||||
import "../Config"
|
||||
import "../Components"
|
||||
|
||||
Item {
|
||||
FocusChainType {
|
||||
id: root
|
||||
|
||||
property StackView stackView: StackView.view
|
||||
|
||||
property var defaultActiveFocusItem: null
|
||||
|
||||
onVisibleChanged: {
|
||||
if (visible && !GC.isMobile()) {
|
||||
timer.start()
|
||||
}
|
||||
}
|
||||
|
||||
function lastItemTabClicked(focusItem) {
|
||||
if (GC.isMobile()) {
|
||||
return
|
||||
}
|
||||
|
||||
if (focusItem) {
|
||||
focusItem.forceActiveFocus()
|
||||
PageController.forceTabBarActiveFocus()
|
||||
} else {
|
||||
if (defaultActiveFocusItem) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
PageController.forceTabBarActiveFocus()
|
||||
}
|
||||
}
|
||||
// onVisibleChanged: {
|
||||
// if (visible && !GC.isMobile()) {
|
||||
// timer.start()
|
||||
// }
|
||||
// }
|
||||
|
||||
// MouseArea {
|
||||
// id: globalMouseArea
|
||||
@@ -47,15 +29,13 @@ Item {
|
||||
// }
|
||||
|
||||
// Set a timer to set focus after a short delay
|
||||
Timer {
|
||||
id: timer
|
||||
interval: 100 // Milliseconds
|
||||
onTriggered: {
|
||||
if (defaultActiveFocusItem) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
repeat: false // Stop the timer after one trigger
|
||||
running: !GC.isMobile() // Start the timer
|
||||
}
|
||||
// Timer {
|
||||
// id: timer
|
||||
// interval: 100 // Milliseconds
|
||||
// onTriggered: {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
// repeat: false // Stop the timer after one trigger
|
||||
// running: !GC.isMobile() // Start the timer
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -19,6 +19,7 @@ TabButton {
|
||||
|
||||
property var clickedFunc
|
||||
|
||||
focus: true
|
||||
hoverEnabled: true
|
||||
focusPolicy: Qt.TabFocus
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import Style 1.0
|
||||
|
||||
import "TextTypes"
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
id: root
|
||||
|
||||
property string headerText
|
||||
@@ -40,16 +40,17 @@ Item {
|
||||
implicitHeight: content.implicitHeight
|
||||
|
||||
property FlickableType parentFlickable
|
||||
Connections {
|
||||
target: textField
|
||||
function onFocusChanged() {
|
||||
if (textField.activeFocus) {
|
||||
if (root.parentFlickable) {
|
||||
root.parentFlickable.ensureVisible(root)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Connections {
|
||||
// target: textField
|
||||
// function onFocusChanged() {
|
||||
// if (textField.activeFocus) {
|
||||
// if (root.parentFlickable) {
|
||||
// root.parentFlickable.ensureVisible(root)
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
ColumnLayout {
|
||||
id: content
|
||||
@@ -85,6 +86,7 @@ Item {
|
||||
TextField {
|
||||
id: textField
|
||||
activeFocusOnTab: false
|
||||
focus: true
|
||||
|
||||
enabled: root.textFieldEditable
|
||||
color: root.enabled ? root.textFieldTextColor : root.textFieldTextDisabledColor
|
||||
@@ -119,6 +121,7 @@ Item {
|
||||
}
|
||||
|
||||
onActiveFocusChanged: {
|
||||
backgroud.border.color = getBackgroundBorderColor(root.borderColor)
|
||||
if (checkEmptyText && textFieldText === "") {
|
||||
errorText = qsTr("The field can't be empty")
|
||||
}
|
||||
@@ -136,9 +139,6 @@ Item {
|
||||
textObj: textField
|
||||
}
|
||||
|
||||
onFocusChanged: {
|
||||
backgroud.border.color = getBackgroundBorderColor(root.borderColor)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -199,7 +199,7 @@ Item {
|
||||
}
|
||||
|
||||
function getBackgroundBorderColor(noneFocusedColor) {
|
||||
return textField.focus ? root.borderFocusedColor : noneFocusedColor
|
||||
return textField.activeFocus ? root.borderFocusedColor : noneFocusedColor
|
||||
}
|
||||
|
||||
Keys.onEnterPressed: {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
+424
-418
@@ -18,8 +18,7 @@ import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
focus: true
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
@@ -32,7 +31,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
FocusScope {
|
||||
anchors.fill: parent
|
||||
anchors.bottomMargin: drawer.collapsedHeight
|
||||
|
||||
@@ -41,12 +40,6 @@ PageType {
|
||||
anchors.topMargin: 34
|
||||
anchors.bottomMargin: 34
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: loggingButton.visible ?
|
||||
loggingButton :
|
||||
connectButton
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: loggingButton
|
||||
@@ -68,8 +61,9 @@ PageType {
|
||||
|
||||
Keys.onEnterPressed: loggingButton.clicked()
|
||||
Keys.onReturnPressed: loggingButton.clicked()
|
||||
// activeFocusOnTab: true
|
||||
|
||||
KeyNavigation.tab: connectButton
|
||||
// KeyNavigation.tab: connectButton
|
||||
|
||||
onClicked: {
|
||||
PageController.goToPage(PageEnum.PageSettingsLogging)
|
||||
@@ -78,13 +72,15 @@ PageType {
|
||||
|
||||
ConnectButton {
|
||||
id: connectButton
|
||||
activeFocusOnTab: true
|
||||
Layout.fillHeight: true
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
KeyNavigation.tab: splitTunnelingButton
|
||||
// KeyNavigation.tab: splitTunnelingButton
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: splitTunnelingButton
|
||||
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
|
||||
Layout.bottomMargin: 34
|
||||
leftPadding: 16
|
||||
@@ -100,6 +96,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"))
|
||||
|
||||
@@ -111,7 +111,7 @@ PageType {
|
||||
Keys.onEnterPressed: splitTunnelingButton.clicked()
|
||||
Keys.onReturnPressed: splitTunnelingButton.clicked()
|
||||
|
||||
KeyNavigation.tab: drawer
|
||||
// KeyNavigation.tab: drawer
|
||||
|
||||
onClicked: {
|
||||
homeSplitTunnelingDrawer.open()
|
||||
@@ -121,420 +121,426 @@ PageType {
|
||||
id: homeSplitTunnelingDrawer
|
||||
parent: root
|
||||
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
// onClosed: {
|
||||
// if (!GC.isMobile()) {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DrawerType2 {
|
||||
id: drawer
|
||||
objectName: "drawer"
|
||||
anchors.fill: parent
|
||||
focus: true
|
||||
|
||||
// collapsedContent: FocusScope {
|
||||
// id: collapsed123
|
||||
// focus: true
|
||||
// implicitHeight: Qt.platform.os !== "ios" ? root.height * 0.9 : screen.height * 0.77
|
||||
// Component.onCompleted: {
|
||||
// drawer.expandedHeight = implicitHeight
|
||||
// }
|
||||
|
||||
// // Connections {
|
||||
// // target: drawer
|
||||
// // enabled: !GC.isMobile()
|
||||
// // function onActiveFocusChanged() {
|
||||
// // if (drawer.activeFocus && !drawer.isOpened) {
|
||||
// // collapsed123.forceActiveFocus()
|
||||
// // // collapsedButtonChevron.forceActiveFocus()
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// ColumnLayout {
|
||||
// id: collapsed
|
||||
|
||||
// anchors.left: parent.left
|
||||
// anchors.right: parent.right
|
||||
|
||||
// Component.onCompleted: {
|
||||
// drawer.collapsedHeight = collapsed.implicitHeight
|
||||
// }
|
||||
|
||||
// DividerType {
|
||||
// Layout.topMargin: 10
|
||||
// Layout.fillWidth: false
|
||||
// Layout.preferredWidth: 20
|
||||
// Layout.preferredHeight: 2
|
||||
// Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
// }
|
||||
|
||||
// RowLayout {
|
||||
// Layout.topMargin: 14
|
||||
// Layout.leftMargin: 24
|
||||
// Layout.rightMargin: 24
|
||||
// Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
// spacing: 0
|
||||
|
||||
// Connections {
|
||||
// target: drawer
|
||||
// function onEntered() {
|
||||
// if (drawer.isCollapsed) {
|
||||
// collapsedButtonChevron.backgroundColor = collapsedButtonChevron.hoveredColor
|
||||
// collapsedButtonHeader.opacity = 0.8
|
||||
// } else {
|
||||
// collapsedButtonHeader.opacity = 1
|
||||
// }
|
||||
// }
|
||||
|
||||
// function onExited() {
|
||||
// if (drawer.isCollapsed) {
|
||||
// collapsedButtonChevron.backgroundColor = collapsedButtonChevron.defaultColor
|
||||
// collapsedButtonHeader.opacity = 1
|
||||
// } else {
|
||||
// collapsedButtonHeader.opacity = 1
|
||||
// }
|
||||
// }
|
||||
|
||||
// function onPressed(pressed, entered) {
|
||||
// if (drawer.isCollapsed) {
|
||||
// collapsedButtonChevron.backgroundColor = pressed ? collapsedButtonChevron.pressedColor : entered ? collapsedButtonChevron.hoveredColor : collapsedButtonChevron.defaultColor
|
||||
// collapsedButtonHeader.opacity = 0.7
|
||||
// } else {
|
||||
// collapsedButtonHeader.opacity = 1
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Header1TextType {
|
||||
// id: collapsedButtonHeader
|
||||
// Layout.maximumWidth: drawer.width - 48 - 18 - 12
|
||||
|
||||
// maximumLineCount: 2
|
||||
// elide: Qt.ElideRight
|
||||
|
||||
// text: ServersModel.defaultServerName
|
||||
// horizontalAlignment: Qt.AlignHCenter
|
||||
|
||||
// Behavior on opacity {
|
||||
// PropertyAnimation { duration: 200 }
|
||||
// }
|
||||
// }
|
||||
|
||||
// ImageButtonType {
|
||||
// id: collapsedButtonChevron
|
||||
|
||||
// Layout.leftMargin: 8
|
||||
|
||||
// visible: drawer.isCollapsed
|
||||
|
||||
// hoverEnabled: false
|
||||
// image: "qrc:/images/controls/chevron-down.svg"
|
||||
// imageColor: AmneziaStyle.color.white
|
||||
|
||||
// icon.width: 18
|
||||
// icon.height: 18
|
||||
// backgroundRadius: 16
|
||||
// horizontalPadding: 4
|
||||
// topPadding: 4
|
||||
// bottomPadding: 3
|
||||
|
||||
// Keys.onEnterPressed: collapsedButtonChevron.clicked()
|
||||
// Keys.onReturnPressed: collapsedButtonChevron.clicked()
|
||||
// // Keys.onTabPressed: lastItemTabClicked()
|
||||
|
||||
// focus: true
|
||||
|
||||
// onClicked: {
|
||||
// if (drawer.isCollapsed) {
|
||||
// drawer.open()
|
||||
// focusItem1.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// LabelTextType {
|
||||
// id: collapsedServerMenuDescription
|
||||
// Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 89 : 44
|
||||
// Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
// text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
|
||||
// }
|
||||
// }
|
||||
|
||||
// // Connections {
|
||||
// // target: drawer
|
||||
// // enabled: !GC.isMobile()
|
||||
// // function onIsCollapsedChanged() {
|
||||
// // if (!drawer.isCollapsed) {
|
||||
// // focusItem1.forceActiveFocus()
|
||||
// // }
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// ColumnLayout {
|
||||
// id: serversMenuHeader
|
||||
|
||||
// anchors.top: collapsed.bottom
|
||||
// anchors.right: parent.right
|
||||
// anchors.left: parent.left
|
||||
|
||||
// RowLayout {
|
||||
// Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
// focus: false
|
||||
// spacing: 8
|
||||
|
||||
// visible: !ServersModel.isDefaultServerFromApi
|
||||
|
||||
// Item {
|
||||
// id: focusItem1
|
||||
// KeyNavigation.tab: serversMenuContent /*containersDropDown*/
|
||||
// }
|
||||
|
||||
// // DropDownType {
|
||||
// // id: containersDropDown
|
||||
|
||||
// // rootButtonImageColor: AmneziaStyle.color.black
|
||||
// // rootButtonBackgroundColor: AmneziaStyle.color.white
|
||||
// // rootButtonBackgroundHoveredColor: Qt.rgba(215, 216, 219, 0.8)
|
||||
// // rootButtonBackgroundPressedColor: Qt.rgba(215, 216, 219, 0.65)
|
||||
// // rootButtonHoveredBorderColor: AmneziaStyle.color.transparent
|
||||
// // rootButtonDefaultBorderColor: AmneziaStyle.color.transparent
|
||||
// // rootButtonTextTopMargin: 8
|
||||
// // rootButtonTextBottomMargin: 8
|
||||
|
||||
// // text: ServersModel.defaultServerDefaultContainerName
|
||||
// // textColor: AmneziaStyle.color.black
|
||||
// // headerText: qsTr("VPN protocol")
|
||||
// // headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||
|
||||
// // rootButtonClickedFunction: function() {
|
||||
// // containersDropDown.open()
|
||||
// // }
|
||||
|
||||
// // drawerParent: root
|
||||
// // KeyNavigation.tab: serversMenuContent
|
||||
|
||||
// // listView: HomeContainersListView {
|
||||
// // id: containersListView
|
||||
// // rootWidth: root.width
|
||||
// // // onVisibleChanged: {
|
||||
// // // if (containersDropDown.visible && !GC.isMobile()) {
|
||||
// // // focusItem1.forceActiveFocus()
|
||||
// // // }
|
||||
// // // }
|
||||
|
||||
// // Connections {
|
||||
// // target: ServersModel
|
||||
|
||||
// // function onDefaultServerIndexChanged() {
|
||||
// // updateContainersModelFilters()
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // function updateContainersModelFilters() {
|
||||
// // if (ServersModel.isDefaultServerHasWriteAccess()) {
|
||||
// // proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
|
||||
// // } else {
|
||||
// // proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// // model: SortFilterProxyModel {
|
||||
// // id: proxyDefaultServerContainersModel
|
||||
// // sourceModel: DefaultServerContainersModel
|
||||
|
||||
// // sorters: [
|
||||
// // RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
|
||||
// // ]
|
||||
// // }
|
||||
|
||||
// // Component.onCompleted: updateContainersModelFilters()
|
||||
// // }
|
||||
// // }
|
||||
|
||||
// }
|
||||
|
||||
// Header2Type {
|
||||
// Layout.fillWidth: true
|
||||
// Layout.topMargin: 48
|
||||
// Layout.leftMargin: 16
|
||||
// Layout.rightMargin: 16
|
||||
|
||||
// headerText: qsTr("Servers")
|
||||
// }
|
||||
// }
|
||||
|
||||
// ButtonGroup {
|
||||
// id: serversRadioButtonGroup
|
||||
// }
|
||||
|
||||
// ListView {
|
||||
// id: serversMenuContent
|
||||
|
||||
// anchors.top: serversMenuHeader.bottom
|
||||
// anchors.right: parent.right
|
||||
// anchors.left: parent.left
|
||||
// anchors.bottom: parent.bottom
|
||||
// anchors.topMargin: 16
|
||||
|
||||
// model: ServersModel
|
||||
// currentIndex: ServersModel.defaultIndex
|
||||
|
||||
// ScrollBar.vertical: ScrollBar {
|
||||
// id: scrollBar
|
||||
// policy: serversMenuContent.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
|
||||
// }
|
||||
|
||||
|
||||
// activeFocusOnTab: true
|
||||
// focus: true
|
||||
|
||||
// property int focusItemIndex: 0
|
||||
// onActiveFocusChanged: {
|
||||
// if (activeFocus) {
|
||||
// serversMenuContent.focusItemIndex = 0
|
||||
// serversMenuContent.itemAtIndex(focusItemIndex).forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
// onFocusItemIndexChanged: {
|
||||
// const focusedElement = serversMenuContent.itemAtIndex(focusItemIndex)
|
||||
// if (focusedElement) {
|
||||
// if (focusedElement.y + focusedElement.height > serversMenuContent.height) {
|
||||
// serversMenuContent.contentY = focusedElement.y + focusedElement.height - serversMenuContent.height
|
||||
// } else {
|
||||
// serversMenuContent.contentY = 0
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Keys.onUpPressed: scrollBar.decrease()
|
||||
// Keys.onDownPressed: scrollBar.increase()
|
||||
|
||||
// Connections {
|
||||
// target: drawer
|
||||
// enabled: !GC.isMobile()
|
||||
// function onIsCollapsedChanged() {
|
||||
// if (drawer.isCollapsed) {
|
||||
// const item = serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex)
|
||||
// if (item) { item.serverRadioButtonProperty.focus = false }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// Connections {
|
||||
// target: ServersModel
|
||||
// function onDefaultServerIndexChanged(serverIndex) {
|
||||
// serversMenuContent.currentIndex = serverIndex
|
||||
// }
|
||||
// }
|
||||
|
||||
// clip: true
|
||||
|
||||
// delegate: Item {
|
||||
// id: menuContentDelegate
|
||||
|
||||
// property variant delegateData: model
|
||||
// property VerticalRadioButton serverRadioButtonProperty: serverRadioButton
|
||||
|
||||
// implicitWidth: serversMenuContent.width
|
||||
// implicitHeight: serverRadioButtonContent.implicitHeight
|
||||
|
||||
// onActiveFocusChanged: {
|
||||
// if (activeFocus) {
|
||||
// serverRadioButton.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
// ColumnLayout {
|
||||
// id: serverRadioButtonContent
|
||||
|
||||
// anchors.fill: parent
|
||||
// anchors.rightMargin: 16
|
||||
// anchors.leftMargin: 16
|
||||
|
||||
// spacing: 0
|
||||
|
||||
// RowLayout {
|
||||
// Layout.fillWidth: true
|
||||
// VerticalRadioButton {
|
||||
// id: serverRadioButton
|
||||
|
||||
// Layout.fillWidth: true
|
||||
|
||||
// text: name
|
||||
// descriptionText: serverDescription
|
||||
|
||||
// checked: index === serversMenuContent.currentIndex
|
||||
// checkable: !ConnectionController.isConnected
|
||||
|
||||
// ButtonGroup.group: serversRadioButtonGroup
|
||||
|
||||
// onClicked: {
|
||||
// if (ConnectionController.isConnected) {
|
||||
// PageController.showNotificationMessage(qsTr("Unable change server while there is an active connection"))
|
||||
// return
|
||||
// }
|
||||
|
||||
// serversMenuContent.currentIndex = index
|
||||
|
||||
// ServersModel.defaultIndex = index
|
||||
// }
|
||||
|
||||
// MouseArea {
|
||||
// anchors.fill: serverRadioButton
|
||||
// cursorShape: Qt.PointingHandCursor
|
||||
// enabled: false
|
||||
// }
|
||||
|
||||
// Keys.onTabPressed: serverInfoButton.forceActiveFocus()
|
||||
// Keys.onEnterPressed: serverRadioButton.clicked()
|
||||
// Keys.onReturnPressed: serverRadioButton.clicked()
|
||||
|
||||
// KeyNavigation.tab: serverInfoButton
|
||||
// }
|
||||
|
||||
// ImageButtonType {
|
||||
// id: serverInfoButton
|
||||
// image: "qrc:/images/controls/settings.svg"
|
||||
// imageColor: AmneziaStyle.color.white
|
||||
|
||||
// implicitWidth: 56
|
||||
// implicitHeight: 56
|
||||
|
||||
// z: 1
|
||||
|
||||
// Keys.onTabPressed: {
|
||||
// if (serversMenuContent.focusItemIndex < serversMenuContent.count - 1) {
|
||||
// serversMenuContent.focusItemIndex++
|
||||
// serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex).forceActiveFocus()
|
||||
// } else {
|
||||
// focusItem1.forceActiveFocus()
|
||||
// serversMenuContent.contentY = 0
|
||||
// }
|
||||
// }
|
||||
// Keys.onEnterPressed: serverInfoButton.clicked()
|
||||
// Keys.onReturnPressed: serverInfoButton.clicked()
|
||||
|
||||
// onClicked: function() {
|
||||
// ServersModel.processedIndex = index
|
||||
// PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||
// drawer.close()
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// DividerType {
|
||||
// Layout.fillWidth: true
|
||||
// Layout.leftMargin: 0
|
||||
// Layout.rightMargin: 0
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
// }
|
||||
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
collapsedContent: Item {
|
||||
implicitHeight: Qt.platform.os !== "ios" ? root.height * 0.9 : screen.height * 0.77
|
||||
Component.onCompleted: {
|
||||
drawer.expandedHeight = implicitHeight
|
||||
}
|
||||
Connections {
|
||||
target: drawer
|
||||
enabled: !GC.isMobile()
|
||||
function onActiveFocusChanged() {
|
||||
if (drawer.activeFocus && !drawer.isOpened) {
|
||||
collapsedButtonChevron.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: collapsed
|
||||
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
Component.onCompleted: {
|
||||
drawer.collapsedHeight = collapsed.implicitHeight
|
||||
}
|
||||
|
||||
DividerType {
|
||||
Layout.topMargin: 10
|
||||
Layout.fillWidth: false
|
||||
Layout.preferredWidth: 20
|
||||
Layout.preferredHeight: 2
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Layout.topMargin: 14
|
||||
Layout.leftMargin: 24
|
||||
Layout.rightMargin: 24
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
|
||||
spacing: 0
|
||||
|
||||
Connections {
|
||||
target: drawer
|
||||
function onEntered() {
|
||||
if (drawer.isCollapsed) {
|
||||
collapsedButtonChevron.backgroundColor = collapsedButtonChevron.hoveredColor
|
||||
collapsedButtonHeader.opacity = 0.8
|
||||
} else {
|
||||
collapsedButtonHeader.opacity = 1
|
||||
}
|
||||
}
|
||||
|
||||
function onExited() {
|
||||
if (drawer.isCollapsed) {
|
||||
collapsedButtonChevron.backgroundColor = collapsedButtonChevron.defaultColor
|
||||
collapsedButtonHeader.opacity = 1
|
||||
} else {
|
||||
collapsedButtonHeader.opacity = 1
|
||||
}
|
||||
}
|
||||
|
||||
function onPressed(pressed, entered) {
|
||||
if (drawer.isCollapsed) {
|
||||
collapsedButtonChevron.backgroundColor = pressed ? collapsedButtonChevron.pressedColor : entered ? collapsedButtonChevron.hoveredColor : collapsedButtonChevron.defaultColor
|
||||
collapsedButtonHeader.opacity = 0.7
|
||||
} else {
|
||||
collapsedButtonHeader.opacity = 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Header1TextType {
|
||||
id: collapsedButtonHeader
|
||||
Layout.maximumWidth: drawer.width - 48 - 18 - 12
|
||||
|
||||
maximumLineCount: 2
|
||||
elide: Qt.ElideRight
|
||||
|
||||
text: ServersModel.defaultServerName
|
||||
horizontalAlignment: Qt.AlignHCenter
|
||||
|
||||
KeyNavigation.tab: tabBar
|
||||
|
||||
Behavior on opacity {
|
||||
PropertyAnimation { duration: 200 }
|
||||
}
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
id: collapsedButtonChevron
|
||||
|
||||
Layout.leftMargin: 8
|
||||
|
||||
visible: drawer.isCollapsed
|
||||
|
||||
hoverEnabled: false
|
||||
image: "qrc:/images/controls/chevron-down.svg"
|
||||
imageColor: AmneziaStyle.color.white
|
||||
|
||||
icon.width: 18
|
||||
icon.height: 18
|
||||
backgroundRadius: 16
|
||||
horizontalPadding: 4
|
||||
topPadding: 4
|
||||
bottomPadding: 3
|
||||
|
||||
Keys.onEnterPressed: collapsedButtonChevron.clicked()
|
||||
Keys.onReturnPressed: collapsedButtonChevron.clicked()
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
|
||||
|
||||
onClicked: {
|
||||
if (drawer.isCollapsed) {
|
||||
drawer.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LabelTextType {
|
||||
id: collapsedServerMenuDescription
|
||||
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 89 : 44
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: drawer
|
||||
enabled: !GC.isMobile()
|
||||
function onIsCollapsedChanged() {
|
||||
if (!drawer.isCollapsed) {
|
||||
focusItem1.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: serversMenuHeader
|
||||
|
||||
anchors.top: collapsed.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
|
||||
spacing: 8
|
||||
|
||||
visible: !ServersModel.isDefaultServerFromApi
|
||||
|
||||
Item {
|
||||
id: focusItem1
|
||||
KeyNavigation.tab: containersDropDown
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
id: containersDropDown
|
||||
|
||||
rootButtonImageColor: AmneziaStyle.color.black
|
||||
rootButtonBackgroundColor: AmneziaStyle.color.white
|
||||
rootButtonBackgroundHoveredColor: Qt.rgba(215, 216, 219, 0.8)
|
||||
rootButtonBackgroundPressedColor: Qt.rgba(215, 216, 219, 0.65)
|
||||
rootButtonHoveredBorderColor: AmneziaStyle.color.transparent
|
||||
rootButtonDefaultBorderColor: AmneziaStyle.color.transparent
|
||||
rootButtonTextTopMargin: 8
|
||||
rootButtonTextBottomMargin: 8
|
||||
|
||||
text: ServersModel.defaultServerDefaultContainerName
|
||||
textColor: AmneziaStyle.color.black
|
||||
headerText: qsTr("VPN protocol")
|
||||
headerBackButtonImage: "qrc:/images/controls/arrow-left.svg"
|
||||
|
||||
rootButtonClickedFunction: function() {
|
||||
containersDropDown.open()
|
||||
}
|
||||
|
||||
drawerParent: root
|
||||
KeyNavigation.tab: serversMenuContent
|
||||
|
||||
listView: HomeContainersListView {
|
||||
id: containersListView
|
||||
rootWidth: root.width
|
||||
onVisibleChanged: {
|
||||
if (containersDropDown.visible && !GC.isMobile()) {
|
||||
focusItem1.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
|
||||
function onDefaultServerIndexChanged() {
|
||||
updateContainersModelFilters()
|
||||
}
|
||||
}
|
||||
|
||||
function updateContainersModelFilters() {
|
||||
if (ServersModel.isDefaultServerHasWriteAccess()) {
|
||||
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getWriteAccessProtocolsListFilters()
|
||||
} else {
|
||||
proxyDefaultServerContainersModel.filters = ContainersModelFilters.getReadAccessProtocolsListFilters()
|
||||
}
|
||||
}
|
||||
|
||||
model: SortFilterProxyModel {
|
||||
id: proxyDefaultServerContainersModel
|
||||
sourceModel: DefaultServerContainersModel
|
||||
|
||||
sorters: [
|
||||
RoleSorter { roleName: "isInstalled"; sortOrder: Qt.DescendingOrder }
|
||||
]
|
||||
}
|
||||
|
||||
Component.onCompleted: updateContainersModelFilters()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Header2Type {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 48
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Servers")
|
||||
}
|
||||
}
|
||||
|
||||
ButtonGroup {
|
||||
id: serversRadioButtonGroup
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: serversMenuContent
|
||||
|
||||
anchors.top: serversMenuHeader.bottom
|
||||
anchors.right: parent.right
|
||||
anchors.left: parent.left
|
||||
anchors.bottom: parent.bottom
|
||||
anchors.topMargin: 16
|
||||
|
||||
model: ServersModel
|
||||
currentIndex: ServersModel.defaultIndex
|
||||
|
||||
ScrollBar.vertical: ScrollBar {
|
||||
id: scrollBar
|
||||
policy: serversMenuContent.height >= serversMenuContent.contentHeight ? ScrollBar.AlwaysOff : ScrollBar.AlwaysOn
|
||||
}
|
||||
|
||||
|
||||
activeFocusOnTab: true
|
||||
focus: true
|
||||
|
||||
property int focusItemIndex: 0
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
serversMenuContent.focusItemIndex = 0
|
||||
serversMenuContent.itemAtIndex(focusItemIndex).forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
onFocusItemIndexChanged: {
|
||||
const focusedElement = serversMenuContent.itemAtIndex(focusItemIndex)
|
||||
if (focusedElement) {
|
||||
if (focusedElement.y + focusedElement.height > serversMenuContent.height) {
|
||||
serversMenuContent.contentY = focusedElement.y + focusedElement.height - serversMenuContent.height
|
||||
} else {
|
||||
serversMenuContent.contentY = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onUpPressed: scrollBar.decrease()
|
||||
Keys.onDownPressed: scrollBar.increase()
|
||||
|
||||
Connections {
|
||||
target: drawer
|
||||
enabled: !GC.isMobile()
|
||||
function onIsCollapsedChanged() {
|
||||
if (drawer.isCollapsed) {
|
||||
const item = serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex)
|
||||
if (item) { item.serverRadioButtonProperty.focus = false }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: ServersModel
|
||||
function onDefaultServerIndexChanged(serverIndex) {
|
||||
serversMenuContent.currentIndex = serverIndex
|
||||
}
|
||||
}
|
||||
|
||||
clip: true
|
||||
|
||||
delegate: Item {
|
||||
id: menuContentDelegate
|
||||
|
||||
property variant delegateData: model
|
||||
property VerticalRadioButton serverRadioButtonProperty: serverRadioButton
|
||||
|
||||
implicitWidth: serversMenuContent.width
|
||||
implicitHeight: serverRadioButtonContent.implicitHeight
|
||||
|
||||
onActiveFocusChanged: {
|
||||
if (activeFocus) {
|
||||
serverRadioButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: serverRadioButtonContent
|
||||
|
||||
anchors.fill: parent
|
||||
anchors.rightMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
|
||||
spacing: 0
|
||||
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
VerticalRadioButton {
|
||||
id: serverRadioButton
|
||||
|
||||
Layout.fillWidth: true
|
||||
|
||||
text: name
|
||||
descriptionText: serverDescription
|
||||
|
||||
checked: index === serversMenuContent.currentIndex
|
||||
checkable: !ConnectionController.isConnected
|
||||
|
||||
ButtonGroup.group: serversRadioButtonGroup
|
||||
|
||||
onClicked: {
|
||||
if (ConnectionController.isConnected) {
|
||||
PageController.showNotificationMessage(qsTr("Unable change server while there is an active connection"))
|
||||
return
|
||||
}
|
||||
|
||||
serversMenuContent.currentIndex = index
|
||||
|
||||
ServersModel.defaultIndex = index
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: serverRadioButton
|
||||
cursorShape: Qt.PointingHandCursor
|
||||
enabled: false
|
||||
}
|
||||
|
||||
Keys.onTabPressed: serverInfoButton.forceActiveFocus()
|
||||
Keys.onEnterPressed: serverRadioButton.clicked()
|
||||
Keys.onReturnPressed: serverRadioButton.clicked()
|
||||
}
|
||||
|
||||
ImageButtonType {
|
||||
id: serverInfoButton
|
||||
image: "qrc:/images/controls/settings.svg"
|
||||
imageColor: AmneziaStyle.color.white
|
||||
|
||||
implicitWidth: 56
|
||||
implicitHeight: 56
|
||||
|
||||
z: 1
|
||||
|
||||
Keys.onTabPressed: {
|
||||
if (serversMenuContent.focusItemIndex < serversMenuContent.count - 1) {
|
||||
serversMenuContent.focusItemIndex++
|
||||
serversMenuContent.itemAtIndex(serversMenuContent.focusItemIndex).forceActiveFocus()
|
||||
} else {
|
||||
focusItem1.forceActiveFocus()
|
||||
serversMenuContent.contentY = 0
|
||||
}
|
||||
}
|
||||
Keys.onEnterPressed: serverInfoButton.clicked()
|
||||
Keys.onReturnPressed: serverInfoButton.clicked()
|
||||
|
||||
onClicked: function() {
|
||||
ServersModel.processedIndex = index
|
||||
PageController.goToPage(PageEnum.PageSettingsServerInfo)
|
||||
drawer.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 0
|
||||
Layout.rightMargin: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview.currentItem.portTextField.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
onFocusChanged: {
|
||||
|
||||
@@ -15,12 +15,7 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview.currentItem.trafficFromField.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
// defaultActiveFocusItem: listview.currentItem.trafficFromField.textField
|
||||
|
||||
ColumnLayout {
|
||||
id: backButtonLayout
|
||||
@@ -183,7 +178,6 @@ PageType {
|
||||
Layout.bottomMargin: 24
|
||||
|
||||
text: qsTr("Save")
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunc: function() {
|
||||
forceActiveFocus()
|
||||
|
||||
@@ -17,7 +17,7 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview.currentItem.vpnAddressSubnetTextField.textField
|
||||
// defaultActiveFocusItem: listview.currentItem.vpnAddressSubnetTextField.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
|
||||
@@ -19,13 +19,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: header
|
||||
|
||||
@@ -122,7 +115,7 @@ PageType {
|
||||
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,7 +219,6 @@ PageType {
|
||||
text: qsTr("Remove ") + ContainersModel.getProcessedContainerName()
|
||||
textColor: AmneziaStyle.color.red
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
clickedFunction: function() {
|
||||
var headerText = qsTr("Remove %1 from server?").arg(ContainersModel.getProcessedContainerName())
|
||||
var descriptionText = qsTr("All users with whom you shared a connection with will no longer be able to connect to it.")
|
||||
@@ -239,7 +231,7 @@ PageType {
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
focusItem.forceActiveFocus()
|
||||
// focusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,9 +15,9 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview.currentItem.focusItemId.enabled ?
|
||||
listview.currentItem.focusItemId.textField :
|
||||
focusItem
|
||||
// defaultActiveFocusItem: listview.currentItem.focusItemId.enabled ?
|
||||
// listview.currentItem.focusItemId.textField :
|
||||
// focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
|
||||
@@ -15,8 +15,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
|
||||
@@ -16,8 +16,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
|
||||
@@ -16,8 +16,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
@@ -58,7 +56,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 +80,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 +102,6 @@ PageType {
|
||||
enabled: false
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
@@ -74,7 +72,7 @@ PageType {
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
listview.currentItem.focusItem.forceActiveFocus()
|
||||
listview.currentItem.listViewFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +80,7 @@ PageType {
|
||||
implicitWidth: listview.width
|
||||
implicitHeight: col.implicitHeight
|
||||
|
||||
property alias focusItem: hostLabel.rightButton
|
||||
property alias listViewFocusItem: hostLabel.rightButton
|
||||
|
||||
ColumnLayout {
|
||||
id: col
|
||||
@@ -233,7 +231,7 @@ PageType {
|
||||
PageController.showBusyIndicator(true)
|
||||
InstallController.mountSftpDrive(port, password, username)
|
||||
PageController.showBusyIndicator(false)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
@@ -290,48 +288,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,8 +16,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: listview
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Connections {
|
||||
target: InstallController
|
||||
|
||||
@@ -88,7 +86,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 +125,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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,8 +13,6 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: header
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: parent.top
|
||||
@@ -38,8 +36,6 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
|
||||
headerText: qsTr("Settings")
|
||||
|
||||
KeyNavigation.tab: account.rightButton
|
||||
}
|
||||
|
||||
LabelWithButtonType {
|
||||
@@ -55,7 +51,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsServersList)
|
||||
}
|
||||
|
||||
KeyNavigation.tab: connection.rightButton
|
||||
// KeyNavigation.tab: connection.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -72,7 +68,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsConnection)
|
||||
}
|
||||
|
||||
KeyNavigation.tab: application.rightButton
|
||||
// KeyNavigation.tab: application.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -89,7 +85,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsApplication)
|
||||
}
|
||||
|
||||
KeyNavigation.tab: backup.rightButton
|
||||
// KeyNavigation.tab: backup.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -106,7 +102,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsBackup)
|
||||
}
|
||||
|
||||
KeyNavigation.tab: about.rightButton
|
||||
// KeyNavigation.tab: about.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -122,7 +118,7 @@ PageType {
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSettingsAbout)
|
||||
}
|
||||
KeyNavigation.tab: close
|
||||
// KeyNavigation.tab: close
|
||||
|
||||
}
|
||||
|
||||
@@ -136,9 +132,9 @@ PageType {
|
||||
|
||||
text: qsTr("Close application")
|
||||
leftImageSource: "qrc:/images/controls/x-circle.svg"
|
||||
isLeftImageHoverEnabled: false
|
||||
isLeftImageHoverEnabled: false
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(header)
|
||||
// Keys.onTabPressed: lastItemTabClicked()
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.closeApplication()
|
||||
|
||||
@@ -14,19 +14,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
|
||||
onFocusChanged: {
|
||||
if (focusItem.activeFocus) {
|
||||
fl.contentY = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -34,8 +21,6 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: telegramButton
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -106,7 +91,7 @@ PageType {
|
||||
descriptionText: qsTr("To discuss features")
|
||||
leftImageSource: "qrc:/images/controls/telegram.svg"
|
||||
|
||||
KeyNavigation.tab: mailButton
|
||||
// KeyNavigation.tab: mailButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -124,7 +109,7 @@ PageType {
|
||||
descriptionText: qsTr("For reviews and bug reports")
|
||||
leftImageSource: "qrc:/images/controls/mail.svg"
|
||||
|
||||
KeyNavigation.tab: githubButton
|
||||
// KeyNavigation.tab: githubButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -141,7 +126,7 @@ PageType {
|
||||
text: qsTr("GitHub")
|
||||
leftImageSource: "qrc:/images/controls/github.svg"
|
||||
|
||||
KeyNavigation.tab: websiteButton
|
||||
// KeyNavigation.tab: websiteButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -195,7 +180,7 @@ PageType {
|
||||
|
||||
text: qsTr("Check for updates")
|
||||
|
||||
KeyNavigation.tab: privacyPolicyButton
|
||||
// KeyNavigation.tab: privacyPolicyButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunc: function() {
|
||||
@@ -218,7 +203,6 @@ PageType {
|
||||
|
||||
text: qsTr("Privacy Policy")
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunc: function() {
|
||||
|
||||
@@ -21,8 +21,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
property bool pageEnabled
|
||||
|
||||
Component.onCompleted: {
|
||||
@@ -66,11 +64,6 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: header
|
||||
|
||||
@@ -82,7 +75,6 @@ PageType {
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
KeyNavigation.tab: switcher
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
@@ -103,10 +95,6 @@ PageType {
|
||||
|
||||
enabled: root.pageEnabled
|
||||
|
||||
KeyNavigation.tab: selector.enabled ?
|
||||
selector :
|
||||
searchField.textField
|
||||
|
||||
checked: AppSplitTunnelingModel.isTunnelingEnabled
|
||||
onToggled: {
|
||||
AppSplitTunnelingModel.toggleSplitTunneling(checked)
|
||||
@@ -130,8 +118,6 @@ PageType {
|
||||
|
||||
enabled: Qt.platform.os === "android" && root.pageEnabled
|
||||
|
||||
KeyNavigation.tab: searchField.textField
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
rootWidth: root.width
|
||||
|
||||
@@ -267,7 +253,6 @@ PageType {
|
||||
textFieldPlaceholderText: qsTr("application name")
|
||||
buttonImageSource: "qrc:/images/controls/plus.svg"
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
clickedFunc: function() {
|
||||
@@ -276,7 +261,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)
|
||||
}
|
||||
|
||||
@@ -14,18 +14,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
|
||||
onFocusChanged: {
|
||||
if (focusItem.activeFocus) {
|
||||
fl.contentY = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
@@ -35,7 +23,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: GC.isMobile() ? switcher : switcherAutoStart
|
||||
// KeyNavigation.tab: GC.isMobile() ? switcher : switcherAutoStart
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -51,6 +39,8 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
|
||||
spacing: 0
|
||||
|
||||
HeaderType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
@@ -75,8 +65,8 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
KeyNavigation.tab: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted ?
|
||||
labelWithButtonNotification.rightButton : labelWithButtonLanguage.rightButton
|
||||
// KeyNavigation.tab: Qt.platform.os === "android" && !SettingsController.isNotificationPermissionGranted ?
|
||||
// labelWithButtonNotification.rightButton : labelWithButtonLanguage.rightButton
|
||||
parentFlickable: fl
|
||||
}
|
||||
|
||||
@@ -93,7 +83,7 @@ PageType {
|
||||
descriptionText: qsTr("Enable notifications to show the VPN state in the status bar")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
KeyNavigation.tab: labelWithButtonLanguage.rightButton
|
||||
// KeyNavigation.tab: labelWithButtonLanguage.rightButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -115,7 +105,7 @@ PageType {
|
||||
text: qsTr("Auto start")
|
||||
descriptionText: qsTr("Launch the application every time the device is starts")
|
||||
|
||||
KeyNavigation.tab: switcherAutoConnect
|
||||
// KeyNavigation.tab: switcherAutoConnect
|
||||
parentFlickable: fl
|
||||
|
||||
checked: SettingsController.isAutoStartEnabled()
|
||||
@@ -140,7 +130,7 @@ PageType {
|
||||
text: qsTr("Auto connect")
|
||||
descriptionText: qsTr("Connect to VPN on app start")
|
||||
|
||||
KeyNavigation.tab: switcherStartMinimized
|
||||
// KeyNavigation.tab: switcherStartMinimized
|
||||
parentFlickable: fl
|
||||
|
||||
checked: SettingsController.isAutoConnectEnabled()
|
||||
@@ -165,7 +155,7 @@ PageType {
|
||||
text: qsTr("Start minimized")
|
||||
descriptionText: qsTr("Launch application minimized")
|
||||
|
||||
KeyNavigation.tab: labelWithButtonLanguage.rightButton
|
||||
// KeyNavigation.tab: labelWithButtonLanguage.rightButton
|
||||
parentFlickable: fl
|
||||
|
||||
checked: SettingsController.isStartMinimizedEnabled()
|
||||
@@ -188,7 +178,7 @@ PageType {
|
||||
descriptionText: LanguageModel.currentLanguageName
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
KeyNavigation.tab: labelWithButtonLogging.rightButton
|
||||
// KeyNavigation.tab: labelWithButtonLogging.rightButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -206,7 +196,7 @@ PageType {
|
||||
descriptionText: SettingsController.isLoggingEnabled ? qsTr("Enabled") : qsTr("Disabled")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
KeyNavigation.tab: labelWithButtonReset.rightButton
|
||||
// KeyNavigation.tab: labelWithButtonReset.rightButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
@@ -224,9 +214,6 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
textColor: AmneziaStyle.color.red
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunction: function() {
|
||||
var headerText = qsTr("Reset settings and remove all data from the application?")
|
||||
var descriptionText = qsTr("All settings will be reset to default. All installed AmneziaVPN services will still remain on the server.")
|
||||
@@ -243,12 +230,12 @@ PageType {
|
||||
}
|
||||
|
||||
if (!GC.isMobile()) {
|
||||
root.defaultActiveFocusItem.forceActiveFocus()
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
root.defaultActiveFocusItem.forceActiveFocus()
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,8 +17,6 @@ import "../Controls2/TextTypes"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Connections {
|
||||
target: SettingsController
|
||||
|
||||
@@ -37,11 +35,6 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -50,7 +43,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: makeBackupButton
|
||||
// KeyNavigation.tab: makeBackupButton
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -113,7 +106,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
KeyNavigation.tab: restoreBackupButton
|
||||
// KeyNavigation.tab: restoreBackupButton
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
@@ -138,7 +131,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
// Keys.onTabPressed: lastItemTabClicked()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,15 +11,8 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
property bool isAppSplitTinnelingEnabled: Qt.platform.os === "windows" || Qt.platform.os === "android"
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -28,7 +21,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: amneziaDnsSwitch
|
||||
// KeyNavigation.tab: amneziaDnsSwitch
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -67,7 +60,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
KeyNavigation.tab: dnsServersButton.rightButton
|
||||
// KeyNavigation.tab: dnsServersButton.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -84,7 +77,7 @@ PageType {
|
||||
PageController.goToPage(PageEnum.PageSettingsDns)
|
||||
}
|
||||
|
||||
KeyNavigation.tab: splitTunnelingButton.rightButton
|
||||
// KeyNavigation.tab: splitTunnelingButton.rightButton
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
@@ -166,7 +159,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked()
|
||||
// Keys.onTabPressed: lastItemTabClicked()
|
||||
}
|
||||
|
||||
DividerType {
|
||||
|
||||
@@ -14,8 +14,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: primaryDns.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
@@ -29,7 +27,7 @@ PageType {
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: root.defaultActiveFocusItem
|
||||
// KeyNavigation.tab: root.defaultActiveFocusItem
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -124,12 +122,12 @@ PageType {
|
||||
PageController.showNotificationMessage(qsTr("Settings have been reset"))
|
||||
|
||||
if (!GC.isMobile()) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -28,13 +28,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
}
|
||||
}
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -42,8 +35,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: switcher
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -79,7 +70,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
text: qsTr("Save logs")
|
||||
|
||||
checked: SettingsController.isLoggingEnabled
|
||||
KeyNavigation.tab: openFolderButton
|
||||
onCheckedChanged: {
|
||||
if (checked !== SettingsController.isLoggingEnabled) {
|
||||
SettingsController.isLoggingEnabled = checked
|
||||
@@ -103,7 +93,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
implicitHeight: 56
|
||||
|
||||
image: "qrc:/images/controls/folder-open.svg"
|
||||
KeyNavigation.tab: saveButton
|
||||
|
||||
onClicked: SettingsController.openLogsFolder()
|
||||
Keys.onReturnPressed: openFolderButton.clicked()
|
||||
@@ -131,7 +120,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
implicitHeight: 56
|
||||
|
||||
image: "qrc:/images/controls/save.svg"
|
||||
KeyNavigation.tab: clearButton
|
||||
|
||||
Keys.onReturnPressed: saveButton.clicked()
|
||||
Keys.onEnterPressed: saveButton.clicked()
|
||||
@@ -176,7 +164,6 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
implicitHeight: 56
|
||||
|
||||
image: "qrc:/images/controls/delete.svg"
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
Keys.onReturnPressed: clearButton.clicked()
|
||||
Keys.onEnterPressed: clearButton.clicked()
|
||||
@@ -190,14 +177,14 @@ disabled after 14 days, and all log files will be deleted.")
|
||||
SettingsController.clearLogs()
|
||||
PageController.showBusyIndicator(false)
|
||||
PageController.showNotificationMessage(qsTr("Logs have been cleaned up"))
|
||||
if (!GC.isMobile()) {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
// if (!GC.isMobile()) {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
}
|
||||
var noButtonFunction = function() {
|
||||
if (!GC.isMobile()) {
|
||||
focusItem.forceActiveFocus()
|
||||
}
|
||||
// if (!GC.isMobile()) {
|
||||
// focusItem.forceActiveFocus()
|
||||
// }
|
||||
}
|
||||
|
||||
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
|
||||
|
||||
@@ -19,8 +19,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
|
||||
|
||||
@@ -21,8 +21,6 @@ PageType {
|
||||
|
||||
property bool isClearCacheVisible: ServersModel.isProcessedServerHasWriteAccess() && !ContainersModel.isServiceContainer(ContainersModel.getProcessedContainerIndex())
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
@@ -105,6 +103,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;
|
||||
}
|
||||
|
||||
@@ -17,13 +17,6 @@ import "../Components"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
id: header
|
||||
|
||||
@@ -35,7 +28,7 @@ PageType {
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
KeyNavigation.tab: servers
|
||||
// KeyNavigation.tab: servers
|
||||
}
|
||||
|
||||
HeaderType {
|
||||
@@ -69,8 +62,8 @@ PageType {
|
||||
clip: true
|
||||
interactive: false
|
||||
|
||||
activeFocusOnTab: true
|
||||
focus: true
|
||||
// activeFocusOnTab: true
|
||||
// focus: true
|
||||
Keys.onTabPressed: {
|
||||
if (currentIndex < servers.count - 1) {
|
||||
servers.incrementCurrentIndex()
|
||||
@@ -93,11 +86,11 @@ PageType {
|
||||
implicitWidth: servers.width
|
||||
implicitHeight: delegateContent.implicitHeight
|
||||
|
||||
onFocusChanged: {
|
||||
if (focus) {
|
||||
server.rightButton.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
// onFocusChanged: {
|
||||
// if (focus) {
|
||||
// server.rightButton.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
ColumnLayout {
|
||||
id: delegateContent
|
||||
|
||||
@@ -23,8 +23,6 @@ PageType {
|
||||
|
||||
property var isServerFromApi: ServersModel.getDefaultServerData("isServerFromApi")
|
||||
|
||||
defaultActiveFocusItem: searchField.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
@@ -360,11 +358,11 @@ PageType {
|
||||
anchors.fill: parent
|
||||
expandedHeight: parent.height * 0.4375
|
||||
|
||||
onClosed: {
|
||||
if (root.defaultActiveFocusItem && !GC.isMobile()) {
|
||||
root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
// onClosed: {
|
||||
// if (root.defaultActiveFocusItem && !GC.isMobile()) {
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
// }
|
||||
// }
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: moreActionsDrawerContent
|
||||
|
||||
@@ -22,8 +22,6 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: parent.top
|
||||
@@ -39,15 +37,9 @@ PageType {
|
||||
|
||||
spacing: 0
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
Layout.topMargin: 20
|
||||
KeyNavigation.tab: fileButton.rightButton
|
||||
}
|
||||
|
||||
HeaderType {
|
||||
@@ -78,8 +70,6 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
leftImageSource: "qrc:/images/controls/folder-open.svg"
|
||||
|
||||
KeyNavigation.tab: qrButton.visible ? qrButton.rightButton : textButton.rightButton
|
||||
|
||||
clickedFunction: function() {
|
||||
var nameFilter = !ServersModel.getServersCount() ? "Config or backup files (*.vpn *.ovpn *.conf *.json *.backup)" :
|
||||
"Config files (*.vpn *.ovpn *.conf *.json)"
|
||||
@@ -103,8 +93,6 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
leftImageSource: "qrc:/images/controls/qr-code.svg"
|
||||
|
||||
KeyNavigation.tab: textButton.rightButton
|
||||
|
||||
clickedFunction: function() {
|
||||
ImportController.startDecodingQr()
|
||||
if (Qt.platform.os === "ios") {
|
||||
@@ -125,8 +113,6 @@ PageType {
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
leftImageSource: "qrc:/images/controls/text-cursor.svg"
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunction: function() {
|
||||
PageController.goToPage(PageEnum.PageSetupWizardTextKey)
|
||||
}
|
||||
|
||||
@@ -12,13 +12,6 @@ import "../Controls2/TextTypes"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: hostname.textField
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -26,8 +19,6 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: hostname.textField
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -67,7 +58,7 @@ PageType {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
KeyNavigation.tab: username.textField
|
||||
// KeyNavigation.stab: username.textField
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -81,7 +72,7 @@ PageType {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
KeyNavigation.tab: secretData.textField
|
||||
// KeyNavigation.tab: secretData.textField
|
||||
}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
@@ -103,7 +94,7 @@ PageType {
|
||||
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
|
||||
}
|
||||
|
||||
KeyNavigation.tab: continueButton
|
||||
// KeyNavigation.tab: continueButton
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
@@ -114,7 +105,7 @@ PageType {
|
||||
|
||||
text: qsTr("Continue")
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
// Keys.onTabPressed: lastItemTabClicked()
|
||||
|
||||
clickedFunc: function() {
|
||||
forceActiveFocus()
|
||||
|
||||
@@ -17,7 +17,6 @@ PageType {
|
||||
id: root
|
||||
|
||||
property bool isEasySetup: true
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: proxyContainersModel
|
||||
@@ -34,14 +33,6 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
implicitWidth: 1
|
||||
implicitHeight: 54
|
||||
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -49,8 +40,6 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: continueButton
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -163,7 +152,6 @@ PageType {
|
||||
implicitWidth: parent.width
|
||||
|
||||
text: qsTr("Continue")
|
||||
KeyNavigation.tab: setupLaterButton
|
||||
parentFlickable: fl
|
||||
|
||||
clickedFunc: function() {
|
||||
@@ -193,7 +181,6 @@ PageType {
|
||||
textColor: AmneziaStyle.color.white
|
||||
borderWidth: 1
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
parentFlickable: fl
|
||||
|
||||
visible: {
|
||||
|
||||
@@ -13,7 +13,6 @@ import "../Config"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
Component.onCompleted: PageController.disableTabBar(true)
|
||||
Component.onDestruction: PageController.disableTabBar(false)
|
||||
|
||||
|
||||
@@ -113,7 +113,7 @@ PageType {
|
||||
parent: root
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
defaultActiveFocusItem.forceActiveFocus()
|
||||
// defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,10 +288,10 @@ PageType {
|
||||
transportProtoSelector.visible = protocolSelectorVisible
|
||||
transportProtoHeader.visible = protocolSelectorVisible
|
||||
|
||||
if (port.visible && port.enabled)
|
||||
defaultActiveFocusItem = port.textField
|
||||
else
|
||||
defaultActiveFocusItem = focusItem
|
||||
// if (port.visible && port.enabled)
|
||||
// defaultActiveFocusItem = port.textField
|
||||
// else
|
||||
// defaultActiveFocusItem = focusItem
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,13 +14,6 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
SortFilterProxyModel {
|
||||
id: proxyContainersModel
|
||||
sourceModel: ContainersModel
|
||||
|
||||
@@ -13,11 +13,10 @@ import "../Components"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
objectName: "PageStart"
|
||||
|
||||
property bool isControlsDisabled: false
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Connections {
|
||||
target: PageController
|
||||
|
||||
@@ -139,11 +138,6 @@ PageType {
|
||||
qsTr(" Helps you access blocked content without revealing your privacy, even to VPN providers.")
|
||||
}
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: startButton
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
id: startButton
|
||||
Layout.fillWidth: true
|
||||
@@ -156,8 +150,6 @@ PageType {
|
||||
clickedFunc: function() {
|
||||
connectionTypeSelection.open()
|
||||
}
|
||||
|
||||
KeyNavigation.tab: startButton2
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
@@ -179,8 +171,6 @@ PageType {
|
||||
clickedFunc: function() {
|
||||
Qt.openUrlExternally(qsTr("https://amnezia.org/instructions/0_starter-guide"))
|
||||
}
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -188,9 +178,12 @@ PageType {
|
||||
ConnectionTypeSelectionDrawer {
|
||||
id: connectionTypeSelection
|
||||
|
||||
onClosed: {
|
||||
PageController.forceTabBarActiveFocus()
|
||||
root.defaultActiveFocusItem.forceActiveFocus()
|
||||
}
|
||||
// onClosed: {
|
||||
// PageController.forceTabBarActiveFocus()
|
||||
// root.defaultActiveFocusItem.forceActiveFocus()
|
||||
// PageController.forceStackActiveFocus()
|
||||
|
||||
// startButton2.forceActiveFocus()
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,14 +12,6 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: textKey.textField
|
||||
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: fl
|
||||
anchors.top: parent.top
|
||||
@@ -38,7 +30,6 @@ PageType {
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
Layout.topMargin: 20
|
||||
KeyNavigation.tab: textKey.textField
|
||||
}
|
||||
|
||||
HeaderType {
|
||||
@@ -66,8 +57,6 @@ PageType {
|
||||
textField.text = ""
|
||||
textField.paste()
|
||||
}
|
||||
|
||||
KeyNavigation.tab: continueButton
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -83,7 +72,6 @@ PageType {
|
||||
anchors.bottomMargin: 32
|
||||
|
||||
text: qsTr("Continue")
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunc: function() {
|
||||
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
|
||||
|
||||
@@ -16,13 +16,6 @@ PageType {
|
||||
|
||||
property bool showContent: false
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -30,8 +23,6 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: showContentButton
|
||||
}
|
||||
|
||||
Connections {
|
||||
@@ -192,8 +183,6 @@ PageType {
|
||||
anchors.rightMargin: 16
|
||||
anchors.leftMargin: 16
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
BasicButtonType {
|
||||
id: connectButton
|
||||
Layout.fillWidth: true
|
||||
|
||||
@@ -18,8 +18,6 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: clientNameTextField.textField
|
||||
|
||||
enum ConfigType {
|
||||
AmneziaConnection,
|
||||
OpenVpn,
|
||||
@@ -154,7 +152,7 @@ PageType {
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
id: a
|
||||
id: fl
|
||||
|
||||
anchors.top: parent.top
|
||||
anchors.bottom: parent.bottom
|
||||
@@ -177,7 +175,7 @@ PageType {
|
||||
KeyNavigation.tab: header.actionButton
|
||||
onFocusChanged: {
|
||||
if (focusItem.activeFocus) {
|
||||
a.contentY = 0
|
||||
fl.contentY = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -202,7 +200,7 @@ PageType {
|
||||
parent: root
|
||||
|
||||
anchors.fill: parent
|
||||
expandedHeight: root.height * 0.45
|
||||
expandedHeight: root.height
|
||||
onClosed: {
|
||||
if (!GC.isMobile()) {
|
||||
clientNameTextField.textField.forceActiveFocus()
|
||||
@@ -210,6 +208,7 @@ PageType {
|
||||
}
|
||||
|
||||
expandedContent: ColumnLayout {
|
||||
id: shareFullAccessDrawerContent
|
||||
anchors.top: parent.top
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
@@ -217,6 +216,10 @@ PageType {
|
||||
|
||||
spacing: 0
|
||||
|
||||
onImplicitHeightChanged: {
|
||||
shareFullAccessDrawer.expandedHeight = shareFullAccessDrawerContent.implicitHeight + 32
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: shareFullAccessDrawer
|
||||
enabled: !GC.isMobile()
|
||||
@@ -283,7 +286,7 @@ PageType {
|
||||
implicitWidth: (root.width - 32) / 2
|
||||
text: qsTr("Connection")
|
||||
|
||||
KeyNavigation.tab: usersRadioButton
|
||||
// KeyNavigation.tab: usersRadioButton
|
||||
|
||||
onClicked: {
|
||||
accessTypeSelector.currentIndex = 0
|
||||
@@ -300,7 +303,7 @@ PageType {
|
||||
implicitWidth: (root.width - 32) / 2
|
||||
text: qsTr("Users")
|
||||
|
||||
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ? clientNameTextField.textField : serverSelector
|
||||
// KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ? clientNameTextField.textField : serverSelector
|
||||
|
||||
onClicked: {
|
||||
accessTypeSelector.currentIndex = 1
|
||||
@@ -338,7 +341,7 @@ PageType {
|
||||
|
||||
checkEmptyText: true
|
||||
|
||||
KeyNavigation.tab: serverSelector
|
||||
// KeyNavigation.tab: serverSelector
|
||||
|
||||
}
|
||||
|
||||
@@ -404,7 +407,7 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
KeyNavigation.tab: protocolSelector
|
||||
// KeyNavigation.tab: protocolSelector
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
@@ -504,11 +507,11 @@ PageType {
|
||||
}
|
||||
}
|
||||
|
||||
KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ?
|
||||
exportTypeSelector :
|
||||
isSearchBarVisible ?
|
||||
searchTextField.textField :
|
||||
usersHeader.actionButton
|
||||
// KeyNavigation.tab: accessTypeSelector.currentIndex === 0 ?
|
||||
// exportTypeSelector :
|
||||
// isSearchBarVisible ?
|
||||
// searchTextField.textField :
|
||||
// usersHeader.actionButton
|
||||
}
|
||||
|
||||
DropDownType {
|
||||
@@ -572,7 +575,7 @@ PageType {
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
parentFlickable: a
|
||||
parentFlickable:fl
|
||||
|
||||
clickedFunc: function(){
|
||||
if (clientNameTextField.textFieldText !== "") {
|
||||
@@ -718,10 +721,10 @@ PageType {
|
||||
|
||||
onCurrentIndexChanged: {
|
||||
if (currentItem) {
|
||||
if (currentItem.y < a.contentY) {
|
||||
a.contentY = currentItem.y
|
||||
} else if (currentItem.y + currentItem.height + clientsListView.y > a.contentY + a.height) {
|
||||
a.contentY = currentItem.y + clientsListView.y + currentItem.height - a.height
|
||||
if (currentItem.y < fl.contentY) {
|
||||
fl.contentY = currentItem.y
|
||||
} else if (currentItem.y + currentItem.height + clientsListView.y > fl.contentY + fl.height) {
|
||||
fl.contentY = currentItem.y + clientsListView.y + currentItem.height - fl.height
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,13 +18,6 @@ import "../Config"
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
defaultActiveFocusItem: focusItem
|
||||
|
||||
Item {
|
||||
id: focusItem
|
||||
KeyNavigation.tab: backButton
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
|
||||
@@ -32,8 +25,6 @@ PageType {
|
||||
anchors.left: parent.left
|
||||
anchors.right: parent.right
|
||||
anchors.topMargin: 20
|
||||
|
||||
KeyNavigation.tab: serverSelector
|
||||
}
|
||||
|
||||
FlickableType {
|
||||
@@ -85,8 +76,6 @@ PageType {
|
||||
descriptionText: qsTr("Server")
|
||||
headerText: qsTr("Server")
|
||||
|
||||
KeyNavigation.tab: shareButton
|
||||
|
||||
listView: ListViewWithRadioButtonType {
|
||||
id: serverSelectorListView
|
||||
|
||||
@@ -137,8 +126,6 @@ PageType {
|
||||
text: qsTr("Share")
|
||||
imageSource: "qrc:/images/controls/share-2.svg"
|
||||
|
||||
Keys.onTabPressed: lastItemTabClicked(focusItem)
|
||||
|
||||
clickedFunc: function() {
|
||||
shareConnectionDrawer.headerText = qsTr("Connection to ") + serverSelector.text
|
||||
shareConnectionDrawer.configContentHeaderText = qsTr("File with connection settings to ") + serverSelector.text
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user