Merge branch 'dev' into feature/killswitch-strict-mode

This commit is contained in:
Mykola Baibuz
2025-02-17 21:26:20 +02:00
115 changed files with 7477 additions and 5998 deletions
+8 -9
View File
@@ -10,16 +10,15 @@ FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent)
m_focusChain {},
m_focusedItem { nullptr },
m_rootObjects {},
m_defaultFocusItem { QSharedPointer<QQuickItem>() },
m_defaultFocusItem { nullptr },
m_lvfc { nullptr }
{
QObject::connect(m_engine.get(), &QQmlApplicationEngine::objectCreated, this,
[this](QObject *object, const QUrl &url) {
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
m_defaultFocusItem.reset(newDefaultFocusItem);
}
});
QObject::connect(m_engine, &QQmlApplicationEngine::objectCreated, this, [this](QObject *object, const QUrl &url) {
QQuickItem *newDefaultFocusItem = object->findChild<QQuickItem *>("defaultFocusItem");
if (newDefaultFocusItem && m_defaultFocusItem != newDefaultFocusItem) {
m_defaultFocusItem = newDefaultFocusItem;
}
});
QObject::connect(this, &FocusController::focusedItemChanged, this,
[this]() { m_focusedItem->forceActiveFocus(Qt::TabFocusReason); });
@@ -65,7 +64,7 @@ void FocusController::setFocusItem(QQuickItem *item)
void FocusController::setFocusOnDefaultItem()
{
setFocusItem(m_defaultFocusItem.get());
setFocusItem(m_defaultFocusItem);
}
void FocusController::pushRootObject(QObject *object)
+5 -5
View File
@@ -42,11 +42,11 @@ private:
void focusPreviousListViewItem();
void dropListView();
QSharedPointer<QQmlApplicationEngine> m_engine; // Pointer to engine to get root object
QList<QObject *> m_focusChain; // List of current objects to be focused
QQuickItem *m_focusedItem; // Pointer to the active focus item
QStack<QObject *> m_rootObjects;
QSharedPointer<QQuickItem> m_defaultFocusItem;
QQmlApplicationEngine *m_engine; // Pointer to engine to get root object
QList<QObject *> m_focusChain; // List of current objects to be focused
QQuickItem *m_focusedItem; // Pointer to the active focus item
QStack<QObject *> m_rootObjects; // Pointer to stack of roots for focus chain
QQuickItem *m_defaultFocusItem;
ListViewFocusController *m_lvfc; // ListView focus manager
+12 -1
View File
@@ -332,4 +332,15 @@ bool SettingsController::isOnTv()
#else
return false;
#endif
}
}
bool SettingsController::isHomeAdLabelVisible()
{
return m_settings->isHomeAdLabelVisible();
}
void SettingsController::disableHomeAdLabel()
{
m_settings->disableHomeAdLabel();
emit isHomeAdLabelVisibleChanged(false);
}
@@ -31,6 +31,8 @@ public:
Q_PROPERTY(QString gatewayEndpoint READ getGatewayEndpoint WRITE setGatewayEndpoint NOTIFY gatewayEndpointChanged)
Q_PROPERTY(bool isDevGatewayEnv READ isDevGatewayEnv WRITE toggleDevGatewayEnv NOTIFY devGatewayEnvChanged)
Q_PROPERTY(bool isHomeAdLabelVisible READ isHomeAdLabelVisible NOTIFY isHomeAdLabelVisibleChanged)
public slots:
void toggleAmneziaDns(bool enable);
bool isAmneziaDnsEnabled();
@@ -94,6 +96,9 @@ public slots:
bool isOnTv();
bool isHomeAdLabelVisible();
void disableHomeAdLabel();
signals:
void primaryDnsChanged();
void secondaryDnsChanged();
@@ -119,6 +124,8 @@ signals:
void gatewayEndpointChanged(const QString &endpoint);
void devGatewayEnvChanged(bool enabled);
void isHomeAdLabelVisibleChanged(bool visible);
private:
QSharedPointer<ServersModel> m_serversModel;
QSharedPointer<ContainersModel> m_containersModel;
+16 -14
View File
@@ -65,28 +65,29 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
case CardDescriptionRole: {
auto speed = apiServiceData.serviceInfo.speed;
if (serviceType == serviceType::amneziaPremium) {
return tr("Classic VPN for comfortable work, downloading large files and watching videos. "
"Works for any sites. Speed up to %1 MBit/s")
return tr("Amnezia Premium is VPN for comfortable work, downloading large files and watching videos in 8K resolution. "
"Works for any sites with no restrictions. Speed up to %1 MBit/s. Unlimited traffic.")
.arg(speed);
} else if (serviceType == serviceType::amneziaFree){
QString description = tr("VPN to access blocked sites in regions with high levels of Internet censorship. ");
if (isServiceAvailable) {
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.</a>");
} else if (serviceType == serviceType::amneziaFree) {
QString description = tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
if (!isServiceAvailable) {
description += tr("<p><a style=\"color: #EB5757;\">Not available in your region. If you have VPN enabled, disable it, "
"return to the previous screen, and try again.</a>");
}
return description;
}
}
case ServiceDescriptionRole: {
if (serviceType == serviceType::amneziaPremium) {
return tr("Amnezia Premium - A classic VPN for comfortable work, downloading large files, and watching videos in high resolution. "
"It works for all websites, even in countries with the highest level of internet censorship.");
return tr("Amnezia Premium is VPN for comfortable work, downloading large files and watching videos in 8K resolution. "
"Works for any sites with no restrictions.");
} else {
return tr("Amnezia Free is a free VPN to bypass blocking in countries with high levels of internet censorship");
return tr("AmneziaFree provides free unlimited access to a basic set of web sites, such as Facebook, Instagram, Twitter (X), Discord, Telegram, and others. YouTube is not included in the free plan.");
}
}
case IsServiceAvailableRole: {
if (serviceType == serviceType::amneziaFree) {
if (isServiceAvailable) {
if (!isServiceAvailable) {
return false;
}
}
@@ -143,7 +144,8 @@ void ApiServicesModel::updateModel(const QJsonObject &data)
m_selectedServiceIndex = 0;
} else {
for (const auto &service : services) {
m_services.push_back(getApiServicesData(service.toObject()));
auto serviceObject = service.toObject();
m_services.push_back(getApiServicesData(serviceObject));
}
}
@@ -228,7 +230,7 @@ QHash<int, QByteArray> ApiServicesModel::roleNames() const
ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJsonObject &data)
{
auto serviceInfo = data.value(configKey::serviceInfo).toObject();
auto serviceInfo = data.value(configKey::serviceInfo).toObject();
auto serviceType = data.value(configKey::serviceType).toString();
auto serviceProtocol = data.value(configKey::serviceProtocol).toString();
auto availableCountries = data.value(configKey::availableCountries).toArray();
@@ -245,9 +247,9 @@ ApiServicesModel::ApiServicesData ApiServicesModel::getApiServicesData(const QJs
serviceData.type = serviceType;
serviceData.protocol = serviceProtocol;
serviceData.storeEndpoint = serviceInfo.value(configKey::storeEndpoint).toString();
serviceData.storeEndpoint = data.value(configKey::storeEndpoint).toString();
if (serviceInfo.value(configKey::isAvailable).isBool()) {
if (data.value(configKey::isAvailable).isBool()) {
serviceData.isServiceAvailable = data.value(configKey::isAvailable).toBool();
} else {
serviceData.isServiceAvailable = true;
+1 -1
View File
@@ -108,7 +108,7 @@ QString LanguageModel::getCurrentSiteUrl()
{
auto language = static_cast<LanguageSettings::AvailableLanguageEnum>(getCurrentLanguageIndex());
switch (language) {
case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/kldscp/amnezia.org";
case LanguageSettings::AvailableLanguageEnum::Russian: return "https://storage.googleapis.com/amnezia/amnezia.org";
default: return "https://amnezia.org";
}
}
@@ -21,6 +21,7 @@ bool AwgConfigModel::setData(const QModelIndex &index, const QVariant &value, in
}
switch (role) {
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break;
case Roles::ClientMtuRole: m_clientProtocolConfig.insert(config_key::mtu, value.toString()); break;
@@ -58,6 +59,7 @@ QVariant AwgConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
@@ -92,6 +94,7 @@ void AwgConfigModel::updateModel(const QJsonObject &config)
m_serverProtocolConfig.insert(config_key::transport_proto,
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
m_serverProtocolConfig[config_key::junkPacketCount] =
serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
@@ -168,6 +171,7 @@ QHash<int, QByteArray> AwgConfigModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[SubnetAddressRole] = "subnetAddress";
roles[PortRole] = "port";
roles[ClientMtuRole] = "clientMtu";
@@ -197,6 +201,7 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
clientJunkPacketMinSize = clientProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
clientJunkPacketMaxSize = clientProtocolConfig.value(config_key::junkPacketMaxSize).toString(protocols::awg::defaultJunkPacketMaxSize);
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
port = serverProtocolConfig.value(config_key::port).toString(protocols::awg::defaultPort);
serverJunkPacketCount = serverProtocolConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount);
serverJunkPacketMinSize = serverProtocolConfig.value(config_key::junkPacketMinSize).toString(protocols::awg::defaultJunkPacketMinSize);
@@ -216,7 +221,7 @@ AwgConfig::AwgConfig(const QJsonObject &serverProtocolConfig)
bool AwgConfig::hasEqualServerSettings(const AwgConfig &other) const
{
if (port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
if (subnetAddress != other.subnetAddress || port != other.port || serverJunkPacketCount != other.serverJunkPacketCount
|| serverJunkPacketMinSize != other.serverJunkPacketMinSize || serverJunkPacketMaxSize != other.serverJunkPacketMaxSize
|| serverInitPacketJunkSize != other.serverInitPacketJunkSize || serverResponsePacketJunkSize != other.serverResponsePacketJunkSize
|| serverInitPacketMagicHeader != other.serverInitPacketMagicHeader
+3 -1
View File
@@ -15,6 +15,7 @@ struct AwgConfig
{
AwgConfig(const QJsonObject &jsonConfig);
QString subnetAddress;
QString port;
QString clientMtu;
@@ -43,7 +44,8 @@ class AwgConfigModel : public QAbstractListModel
public:
enum Roles {
PortRole = Qt::UserRole + 1,
SubnetAddressRole = Qt::UserRole + 1,
PortRole,
ClientMtuRole,
ClientJunkPacketCountRole,
@@ -21,6 +21,7 @@ bool WireGuardConfigModel::setData(const QModelIndex &index, const QVariant &val
}
switch (role) {
case Roles::SubnetAddressRole: m_serverProtocolConfig.insert(config_key::subnet_address, value.toString()); break;
case Roles::PortRole: m_serverProtocolConfig.insert(config_key::port, value.toString()); break;
case Roles::ClientMtuRole: m_clientProtocolConfig.insert(config_key::mtu, value.toString()); break;
}
@@ -36,6 +37,7 @@ QVariant WireGuardConfigModel::data(const QModelIndex &index, int role) const
}
switch (role) {
case Roles::SubnetAddressRole: return m_serverProtocolConfig.value(config_key::subnet_address).toString();
case Roles::PortRole: return m_serverProtocolConfig.value(config_key::port).toString();
case Roles::ClientMtuRole: return m_clientProtocolConfig.value(config_key::mtu);
}
@@ -56,6 +58,7 @@ void WireGuardConfigModel::updateModel(const QJsonObject &config)
m_serverProtocolConfig.insert(config_key::transport_proto,
serverProtocolConfig.value(config_key::transport_proto).toString(defaultTransportProto));
m_serverProtocolConfig[config_key::last_config] = serverProtocolConfig.value(config_key::last_config);
m_serverProtocolConfig[config_key::subnet_address] = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
m_serverProtocolConfig[config_key::port] = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
auto lastConfig = m_serverProtocolConfig.value(config_key::last_config).toString();
@@ -96,6 +99,7 @@ QHash<int, QByteArray> WireGuardConfigModel::roleNames() const
{
QHash<int, QByteArray> roles;
roles[SubnetAddressRole] = "subnetAddress";
roles[PortRole] = "port";
roles[ClientMtuRole] = "clientMtu";
@@ -108,12 +112,13 @@ WgConfig::WgConfig(const QJsonObject &serverProtocolConfig)
QJsonObject clientProtocolConfig = QJsonDocument::fromJson(lastConfig.toUtf8()).object();
clientMtu = clientProtocolConfig[config_key::mtu].toString(protocols::wireguard::defaultMtu);
subnetAddress = serverProtocolConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress);
port = serverProtocolConfig.value(config_key::port).toString(protocols::wireguard::defaultPort);
}
bool WgConfig::hasEqualServerSettings(const WgConfig &other) const
{
if (port != other.port) {
if (subnetAddress != other.subnetAddress || port != other.port) {
return false;
}
return true;
@@ -10,6 +10,7 @@ struct WgConfig
{
WgConfig(const QJsonObject &jsonConfig);
QString subnetAddress;
QString port;
QString clientMtu;
@@ -24,7 +25,8 @@ class WireGuardConfigModel : public QAbstractListModel
public:
enum Roles {
PortRole = Qt::UserRole + 1,
SubnetAddressRole = Qt::UserRole + 1,
PortRole,
ClientMtuRole
};
+73
View File
@@ -0,0 +1,73 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick.Shapes
import Qt5Compat.GraphicalEffects
import Style 1.0
import "../Config"
import "../Controls2"
import "../Controls2/TextTypes"
Rectangle {
id: root
property real contentHeight: ad.implicitHeight + ad.anchors.topMargin + ad.anchors.bottomMargin
border.width: 1
border.color: AmneziaStyle.color.goldenApricot
color: AmneziaStyle.color.transparent
radius: 13
visible: false
// visible: GC.isDesktop() && ServersModel.isDefaultServerFromApi
// && ServersModel.isDefaultServerDefaultContainerHasSplitTunneling && SettingsController.isHomeAdLabelVisible
MouseArea {
anchors.fill: parent
cursorShape: Qt.PointingHandCursor
onClicked: function() {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl() + "/premium")
}
}
RowLayout {
id: ad
anchors.fill: parent
anchors.margins: 16
Image {
source: "qrc:/images/controls/amnezia.svg"
sourceSize: Qt.size(36, 36)
layer {
effect: ColorOverlay {
color: AmneziaStyle.color.paleGray
}
}
}
CaptionTextType {
Layout.fillWidth: true
Layout.rightMargin: 10
Layout.leftMargin: 10
text: qsTr("Amnezia Premium - for access to any website")
color: AmneziaStyle.color.pearlGray
lineHeight: 18
font.pixelSize: 15
}
ImageButtonType {
image: "qrc:/images/controls/close.svg"
imageColor: AmneziaStyle.color.paleGray
onClicked: function() {
SettingsController.disableHomeAdLabel()
}
}
}
}
@@ -135,7 +135,7 @@ DrawerType2 {
backgroundColor: AmneziaStyle.color.slateGray
textFieldPlaceholderText: qsTr("application name")
textField.placeholderText: qsTr("application name")
}
BasicButtonType {
+2 -2
View File
@@ -12,7 +12,7 @@ Item {
readonly property string drawerExpandedStateName: "expanded"
readonly property string drawerCollapsedStateName: "collapsed"
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive && (dragArea.drag.active === true))
readonly property bool isOpened: isExpandedStateActive() || (isCollapsedStateActive() && (dragArea.drag.active === true))
readonly property bool isClosed: isCollapsedStateActive() && (dragArea.drag.active === false)
property Component collapsedStateContent
@@ -123,7 +123,7 @@ Item {
id: background
anchors.fill: parent
color: root.isCollapsed ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack
color: root.isCollapsedStateActive() ? AmneziaStyle.color.transparent : AmneziaStyle.color.translucentMidnightBlack
Behavior on color {
PropertyAnimation { duration: 200 }
+7 -19
View File
@@ -216,9 +216,7 @@ Item {
ColumnLayout {
id: header
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
anchors.fill: parent
anchors.topMargin: 16
BackButtonType {
@@ -226,31 +224,21 @@ Item {
backButtonImage: root.headerBackButtonImage
backButtonFunction: function() { menu.closeTriggered() }
}
}
Column {
id: col
anchors.top: header.bottom
anchors.left: parent.left
anchors.right: parent.right
anchors.topMargin: 16
spacing: 16
Header2Type {
anchors.left: parent.left
anchors.right: parent.right
anchors.leftMargin: 16
anchors.rightMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 16
Layout.fillWidth: true
headerText: root.headerText
width: parent.width
}
Loader {
id: listViewLoader
sourceComponent: root.listView
Layout.fillHeight: true
}
}
}
@@ -30,6 +30,8 @@ ListView {
property bool isFocusable: true
ScrollBar.vertical: ScrollBarType {}
ButtonGroup {
id: buttonGroup
}
-1
View File
@@ -20,7 +20,6 @@ Item {
id: timer
interval: 200 // Milliseconds
onTriggered: {
console.debug(">>> PageType timer triggered")
FocusController.resetRootObject()
FocusController.setFocusOnDefaultItem()
}
@@ -22,11 +22,9 @@ Item {
property var clickedFunc
property alias textField: textField
property alias textFieldText: textField.text
property string textFieldTextColor: AmneziaStyle.color.paleGray
property string textFieldTextDisabledColor: AmneziaStyle.color.mutedGray
property string textFieldPlaceholderText
property bool textFieldEditable: true
property string borderColor: AmneziaStyle.color.slateGray
@@ -101,7 +99,6 @@ Item {
inputMethodHints: Qt.ImhNoAutoUppercase | Qt.ImhSensitiveData | Qt.ImhNoPredictiveText
placeholderText: root.textFieldPlaceholderText
placeholderTextColor: AmneziaStyle.color.charcoalGray
selectionColor: AmneziaStyle.color.richBrown
@@ -129,8 +126,8 @@ Item {
}
onActiveFocusChanged: {
if (checkEmptyText && textFieldText === "") {
errorText = qsTr("The field can't be empty")
if (root.checkEmptyText && text === "") {
root.errorText = qsTr("The field can't be empty")
}
}
@@ -26,5 +26,6 @@ QtObject {
readonly property color softGoldenApricot: Qt.rgba(251/255, 178/255, 106/255, 0.3)
readonly property color mistyGray: Qt.rgba(215/255, 216/255, 219/255, 0.8)
readonly property color cloudyGray: Qt.rgba(215/255, 216/255, 219/255, 0.65)
readonly property color pearlGray: '#EAEAEC'
}
}
+5 -5
View File
@@ -66,18 +66,18 @@ PageType {
Layout.leftMargin: 16
headerText: qsTr("Gateway endpoint")
textFieldText: SettingsController.gatewayEndpoint
textField.text: SettingsController.gatewayEndpoint
buttonImageSource: textFieldText !== "" ? "qrc:/images/controls/refresh-cw.svg" : ""
buttonImageSource: textField.text !== "" ? "qrc:/images/controls/refresh-cw.svg" : ""
clickedFunc: function() {
SettingsController.resetGatewayEndpoint()
}
textField.onEditingFinished: {
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
if (textFieldText !== SettingsController.gatewayEndpoint) {
SettingsController.gatewayEndpoint = textFieldText
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
if (textField.text !== SettingsController.gatewayEndpoint) {
SettingsController.gatewayEndpoint = textField.text
}
}
}
+17 -7
View File
@@ -1,6 +1,7 @@
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import Qt5Compat.GraphicalEffects
import SortFilterProxyModel 0.2
@@ -42,8 +43,18 @@ PageType {
objectName: "homeColumnLayout"
anchors.fill: parent
anchors.topMargin: 34
anchors.bottomMargin: 34
anchors.topMargin: 12
anchors.bottomMargin: 16
AdLabel {
id: adLabel
Layout.fillWidth: true
Layout.preferredHeight: adLabel.contentHeight
Layout.leftMargin: 16
Layout.rightMargin: 16
Layout.bottomMargin: 22
}
BasicButtonType {
id: loggingButton
@@ -86,7 +97,6 @@ PageType {
objectName: "splitTunnelingButton"
Layout.alignment: Qt.AlignHCenter | Qt.AlignBottom
Layout.bottomMargin: 34
leftPadding: 16
rightPadding: 16
@@ -256,11 +266,11 @@ PageType {
objectName: "rowLayoutLabel"
Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
Layout.topMargin: 8
Layout.bottomMargin: drawer.isCollapsed ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
Layout.bottomMargin: drawer.isCollapsedStateActive ? 44 : ServersModel.isDefaultServerFromApi ? 61 : 16
spacing: 0
BasicButtonType {
enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsed
enabled: (ServersModel.defaultServerImagePathCollapsed !== "") && drawer.isCollapsedStateActive
hoverEnabled: enabled
implicitHeight: 36
@@ -278,8 +288,9 @@ PageType {
buttonTextLabel.font.pixelSize: 13
buttonTextLabel.font.weight: 400
text: drawer.isCollapsed ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
text: drawer.isCollapsedStateActive ? ServersModel.defaultServerDescriptionCollapsed : ServersModel.defaultServerDescriptionExpanded
leftImageSource: ServersModel.defaultServerImagePathCollapsed
leftImageColor: ""
changeLeftImageSize: false
rightImageSource: hoverEnabled ? "qrc:/images/controls/chevron-down.svg" : ""
@@ -337,7 +348,6 @@ PageType {
objectName: "containersListView"
rootWidth: root.width
height: 500 // TODO: make calculated
Connections {
objectName: "rowLayoutConnections"
@@ -103,12 +103,12 @@ PageType {
Layout.topMargin: 40
headerText: qsTr("MTU")
textFieldText: clientMtu
textField.text: clientMtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== clientMtu) {
clientMtu = textFieldText
if (textField.text !== clientMtu) {
clientMtu = textField.text
}
}
checkEmptyText: true
@@ -121,12 +121,12 @@ PageType {
Layout.topMargin: 16
headerText: "Jc - Junk packet count"
textFieldText: clientJunkPacketCount
textField.text: clientJunkPacketCount
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== clientJunkPacketCount) {
clientJunkPacketCount = textFieldText
if (textField.text !== clientJunkPacketCount) {
clientJunkPacketCount = textField.text
}
}
@@ -141,12 +141,12 @@ PageType {
Layout.topMargin: 16
headerText: "Jmin - Junk packet minimum size"
textFieldText: clientJunkPacketMinSize
textField.text: clientJunkPacketMinSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== clientJunkPacketMinSize) {
clientJunkPacketMinSize = textFieldText
if (textField.text !== clientJunkPacketMinSize) {
clientJunkPacketMinSize = textField.text
}
}
@@ -161,12 +161,12 @@ PageType {
Layout.topMargin: 16
headerText: "Jmax - Junk packet maximum size"
textFieldText: clientJunkPacketMaxSize
textField.text: clientJunkPacketMaxSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== clientJunkPacketMaxSize) {
clientJunkPacketMaxSize = textFieldText
if (textField.text !== clientJunkPacketMaxSize) {
clientJunkPacketMaxSize = textField.text
}
}
@@ -189,7 +189,7 @@ PageType {
enabled: false
headerText: qsTr("Port")
textFieldText: port
textField.text: port
}
TextFieldWithHeaderType {
@@ -200,7 +200,7 @@ PageType {
enabled: false
headerText: "S1 - Init packet junk size"
textFieldText: serverInitPacketJunkSize
textField.text: serverInitPacketJunkSize
}
TextFieldWithHeaderType {
@@ -211,7 +211,7 @@ PageType {
enabled: false
headerText: "S2 - Response packet junk size"
textFieldText: serverResponsePacketJunkSize
textField.text: serverResponsePacketJunkSize
}
TextFieldWithHeaderType {
@@ -222,7 +222,7 @@ PageType {
enabled: false
headerText: "H1 - Init packet magic header"
textFieldText: serverInitPacketMagicHeader
textField.text: serverInitPacketMagicHeader
}
TextFieldWithHeaderType {
@@ -233,7 +233,7 @@ PageType {
enabled: false
headerText: "H2 - Response packet magic header"
textFieldText: serverResponsePacketMagicHeader
textField.text: serverResponsePacketMagicHeader
}
TextFieldWithHeaderType {
@@ -244,7 +244,7 @@ PageType {
enabled: false
headerText: "H3 - Underload packet magic header"
textFieldText: serverUnderloadPacketMagicHeader
textField.text: serverUnderloadPacketMagicHeader
}
TextFieldWithHeaderType {
@@ -255,7 +255,7 @@ PageType {
enabled: false
headerText: "H4 - Transport packet magic header"
textFieldText: serverTransportPacketMagicHeader
textField.text: serverTransportPacketMagicHeader
}
}
}
@@ -36,13 +36,13 @@ PageType {
ListView {
id: listview
property bool isFocusable: true
anchors.top: backButtonLayout.bottom
anchors.bottom: parent.bottom
width: parent.width
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
@@ -76,7 +76,7 @@ PageType {
implicitWidth: listview.width
implicitHeight: col.implicitHeight
property alias portTextField: portTextField
property alias vpnAddressSubnetTextField: vpnAddressSubnetTextField
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
ColumnLayout {
@@ -98,20 +98,19 @@ PageType {
}
TextFieldWithHeaderType {
id: portTextField
id: vpnAddressSubnetTextField
Layout.fillWidth: true
Layout.topMargin: 40
enabled: delegateItem.isEnabled
headerText: qsTr("Port")
textFieldText: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
headerText: qsTr("VPN address subnet")
textField.text: subnetAddress
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
if (textField.text !== subnetAddress) {
subnetAddress = textField.text
}
}
@@ -119,22 +118,23 @@ PageType {
}
TextFieldWithHeaderType {
id: mtuTextField
id: portTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
enabled: delegateItem.isEnabled
headerText: qsTr("Port")
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
if (textField.text !== port) {
port = textField.text
}
}
checkEmptyText: true
}
@@ -144,16 +144,16 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("Jc - Junk packet count")
textFieldText: serverJunkPacketCount
textField.text: serverJunkPacketCount
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
if (textField.text === "") {
textField.text = "0"
}
if (textFieldText !== serverJunkPacketCount) {
serverJunkPacketCount = textFieldText
if (textField.text !== serverJunkPacketCount) {
serverJunkPacketCount = textField.text
}
}
@@ -166,12 +166,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("Jmin - Junk packet minimum size")
textFieldText: serverJunkPacketMinSize
textField.text: serverJunkPacketMinSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverJunkPacketMinSize) {
serverJunkPacketMinSize = textFieldText
if (textField.text !== serverJunkPacketMinSize) {
serverJunkPacketMinSize = textField.text
}
}
@@ -184,12 +184,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("Jmax - Junk packet maximum size")
textFieldText: serverJunkPacketMaxSize
textField.text: serverJunkPacketMaxSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverJunkPacketMaxSize) {
serverJunkPacketMaxSize = textFieldText
if (textField.text !== serverJunkPacketMaxSize) {
serverJunkPacketMaxSize = textField.text
}
}
@@ -202,12 +202,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("S1 - Init packet junk size")
textFieldText: serverInitPacketJunkSize
textField.text: serverInitPacketJunkSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverInitPacketJunkSize) {
serverInitPacketJunkSize = textFieldText
if (textField.text !== serverInitPacketJunkSize) {
serverInitPacketJunkSize = textField.text
}
}
@@ -226,12 +226,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("S2 - Response packet junk size")
textFieldText: serverResponsePacketJunkSize
textField.text: serverResponsePacketJunkSize
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverResponsePacketJunkSize) {
serverResponsePacketJunkSize = textFieldText
if (textField.text !== serverResponsePacketJunkSize) {
serverResponsePacketJunkSize = textField.text
}
}
@@ -250,12 +250,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("H1 - Init packet magic header")
textFieldText: serverInitPacketMagicHeader
textField.text: serverInitPacketMagicHeader
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverInitPacketMagicHeader) {
serverInitPacketMagicHeader = textFieldText
if (textField.text !== serverInitPacketMagicHeader) {
serverInitPacketMagicHeader = textField.text
}
}
@@ -268,12 +268,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("H2 - Response packet magic header")
textFieldText: serverResponsePacketMagicHeader
textField.text: serverResponsePacketMagicHeader
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverResponsePacketMagicHeader) {
serverResponsePacketMagicHeader = textFieldText
if (textField.text !== serverResponsePacketMagicHeader) {
serverResponsePacketMagicHeader = textField.text
}
}
@@ -286,12 +286,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("H4 - Transport packet magic header")
textFieldText: serverTransportPacketMagicHeader
textField.text: serverTransportPacketMagicHeader
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverTransportPacketMagicHeader) {
serverTransportPacketMagicHeader = textFieldText
if (textField.text !== serverTransportPacketMagicHeader) {
serverTransportPacketMagicHeader = textField.text
}
}
@@ -304,12 +304,12 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("H3 - Underload packet magic header")
textFieldText: serverUnderloadPacketMagicHeader
textField.text: serverUnderloadPacketMagicHeader
textField.validator: IntValidator { bottom: 0 }
textField.onEditingFinished: {
if (textFieldText !== serverUnderloadPacketMagicHeader) {
serverUnderloadPacketMagicHeader = textFieldText
if (textField.text !== serverUnderloadPacketMagicHeader) {
serverUnderloadPacketMagicHeader = textField.text
}
}
@@ -332,7 +332,8 @@ PageType {
junkPacketMaxSizeTextField.errorText === "" &&
junkPacketMinSizeTextField.errorText === "" &&
junkPacketCountTextField.errorText === "" &&
portTextField.errorText === ""
portTextField.errorText === "" &&
vpnAddressSubnetTextField.errorText === ""
text: qsTr("Save")
@@ -89,18 +89,18 @@ PageType {
Layout.topMargin: 32
headerText: qsTr("Disguised as traffic from")
textFieldText: site
textField.text: site
textField.onEditingFinished: {
if (textFieldText !== site) {
var tmpText = textFieldText
if (textField.text !== site) {
var tmpText = textField.text
tmpText = tmpText.toLocaleLowerCase()
var indexHttps = tmpText.indexOf("https://")
if (indexHttps === 0) {
tmpText = textFieldText.substring(8)
tmpText = textField.text.substring(8)
} else {
site = textFieldText
site = textField.text
}
}
}
@@ -113,13 +113,13 @@ PageType {
Layout.topMargin: 16
headerText: qsTr("Port")
textFieldText: port
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
if (textField.text !== port) {
port = textField.text
}
}
}
@@ -88,13 +88,13 @@ PageType {
Layout.topMargin: 32
headerText: qsTr("VPN address subnet")
textFieldText: subnetAddress
textField.text: subnetAddress
parentFlickable: fl
textField.onEditingFinished: {
if (textFieldText !== subnetAddress) {
subnetAddress = textFieldText
if (textField.text !== subnetAddress) {
subnetAddress = textField.text
}
}
}
@@ -137,13 +137,13 @@ PageType {
enabled: isPortEditable
headerText: qsTr("Port")
textFieldText: port
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
if (textField.text !== port) {
port = textField.text
}
}
}
@@ -176,7 +176,6 @@ PageType {
headerText: qsTr("Hash")
drawerParent: root
parentFlickable: fl
listView: ListViewWithRadioButtonType {
id: hashListView
@@ -225,7 +224,6 @@ PageType {
headerText: qsTr("Cipher")
drawerParent: root
parentFlickable: fl
listView: ListViewWithRadioButtonType {
id: cipherListView
@@ -93,13 +93,13 @@ PageType {
enabled: isPortEditable
headerText: qsTr("Port")
textFieldText: port
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
if (textField.text !== port) {
port = textField.text
}
}
}
@@ -16,8 +16,6 @@ import "../Components"
PageType {
id: root
defaultActiveFocusItem: listview.currentItem.mtuTextField.textField
Item {
id: focusItem
onFocusChanged: {
@@ -99,12 +97,12 @@ PageType {
Layout.topMargin: 40
headerText: qsTr("MTU")
textFieldText: clientMtu
textField.text: clientMtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
textField.onEditingFinished: {
if (textFieldText !== clientMtu) {
clientMtu = textFieldText
if (textField.text !== clientMtu) {
clientMtu = textField.text
}
}
checkEmptyText: true
@@ -126,7 +124,7 @@ PageType {
enabled: false
headerText: qsTr("Port")
textFieldText: port
textField.text: port
}
}
}
@@ -59,7 +59,7 @@ PageType {
delegate: Item {
id: delegateItem
property alias focusItemId: portTextField.textField
property alias focusItemId: vpnAddressSubnetTextField
property bool isEnabled: ServersModel.isProcessedServerHasWriteAccess()
implicitWidth: listview.width
@@ -83,20 +83,18 @@ PageType {
}
TextFieldWithHeaderType {
id: portTextField
id: vpnAddressSubnetTextField
Layout.fillWidth: true
Layout.topMargin: 40
enabled: delegateItem.isEnabled
headerText: qsTr("Port")
textFieldText: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
headerText: qsTr("VPN address subnet")
textField.text: subnetAddress
textField.onEditingFinished: {
if (textFieldText !== port) {
port = textFieldText
if (textField.text !== subnetAddress) {
subnetAddress = textField.text
}
}
@@ -104,22 +102,23 @@ PageType {
}
TextFieldWithHeaderType {
id: mtuTextField
id: portTextField
Layout.fillWidth: true
Layout.topMargin: 16
headerText: qsTr("MTU")
textFieldText: mtu
textField.validator: IntValidator { bottom: 576; top: 65535 }
enabled: delegateItem.isEnabled
headerText: qsTr("Port")
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
if (textFieldText === "") {
textFieldText = "0"
}
if (textFieldText !== mtu) {
mtu = textFieldText
if (textField.text !== port) {
port = textField.text
}
}
checkEmptyText: true
}
@@ -129,7 +128,8 @@ PageType {
Layout.topMargin: 24
Layout.bottomMargin: 24
enabled: portTextField.errorText === ""
enabled: portTextField.errorText === "" &&
vpnAddressSubnetTextField.errorText === ""
text: qsTr("Save")
@@ -86,18 +86,18 @@ PageType {
Layout.topMargin: 32
headerText: qsTr("Disguised as traffic from")
textFieldText: site
textField.text: site
textField.onEditingFinished: {
if (textFieldText !== site) {
var tmpText = textFieldText
if (textField.text !== site) {
var tmpText = textField.text
tmpText = tmpText.toLocaleLowerCase()
var indexHttps = tmpText.indexOf("https://")
if (indexHttps === 0) {
tmpText = textFieldText.substring(8)
tmpText = textField.text.substring(8)
} else {
site = textFieldText
site = textField.text
}
}
}
@@ -211,9 +211,9 @@ PageType {
port = tempPort
username = tempUsername
password = tempPassword
portTextField.textFieldText = port
usernameTextField.textFieldText = username
passwordTextField.textFieldText = password
portTextField.textField.text = port
usernameTextField.textField.text = username
passwordTextField.textField.text = password
}
}
@@ -231,14 +231,14 @@ PageType {
parentFlickable: fl
headerText: qsTr("Port")
textFieldText: port
textField.text: port
textField.maximumLength: 5
textField.validator: IntValidator { bottom: 1; top: 65535 }
textField.onEditingFinished: {
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
if (textFieldText !== port) {
port = textFieldText
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
if (textField.text !== port) {
port = textField.text
}
}
}
@@ -251,14 +251,14 @@ PageType {
parentFlickable: fl
headerText: qsTr("Username")
textFieldPlaceholderText: "username"
textFieldText: username
textField.placeholderText: "username"
textField.text: username
textField.maximumLength: 32
textField.onEditingFinished: {
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
if (textFieldText !== username) {
username = textFieldText
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
if (textField.text !== username) {
username = textField.text
}
}
}
@@ -273,12 +273,12 @@ PageType {
parentFlickable: fl
headerText: qsTr("Password")
textFieldPlaceholderText: "password"
textFieldText: password
textField.placeholderText: "password"
textField.text: password
textField.maximumLength: 32
textField.echoMode: hidePassword ? TextInput.Password : TextInput.Normal
buttonImageSource: textFieldText !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
buttonImageSource: textField.text !== "" ? (hidePassword ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg")
: ""
clickedFunc: function() {
@@ -286,9 +286,9 @@ PageType {
}
textField.onFocusChanged: {
textFieldText = textField.text.replace(/^\s+|\s+$/g, '')
if (textFieldText !== password) {
password = textFieldText
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
if (textField.text !== password) {
password = textField.text
}
}
}
@@ -309,19 +309,19 @@ PageType {
portTextField.errorText = qsTr("The port must be in the range of 1 to 65535")
return
}
if (usernameTextField.textFieldText && passwordTextField.textFieldText === "") {
if (usernameTextField.textField.text && passwordTextField.textField.text === "") {
passwordTextField.errorText = qsTr("Password cannot be empty")
return
} else if (usernameTextField.textFieldText === "" && passwordTextField.textFieldText) {
} else if (usernameTextField.textField.text === "" && passwordTextField.textField.text) {
usernameTextField.errorText = qsTr("Username cannot be empty")
return
}
PageController.goToPage(PageEnum.PageSetupWizardInstalling)
InstallController.updateContainer(Socks5ProxyConfigModel.getConfig())
tempPort = portTextField.textFieldText
tempUsername = usernameTextField.textFieldText
tempPassword = passwordTextField.textFieldText
tempPort = portTextField.textField.text
tempUsername = usernameTextField.textField.text
tempPassword = passwordTextField.textField.text
changeSettingsDrawer.closeTriggered()
}
}
+1 -4
View File
@@ -87,7 +87,6 @@ PageType {
LabelWithButtonType {
id: backup
visible: !SettingsController.isOnTv()
Layout.fillWidth: true
text: qsTr("Backup")
@@ -99,9 +98,7 @@ PageType {
}
}
DividerType {
visible: !SettingsController.isOnTv()
}
DividerType {}
LabelWithButtonType {
id: about
@@ -18,13 +18,13 @@ PageType {
ListView {
id: menuContent
property var selectedText
property bool isFocusable: true
width: parent.width
height: menuContent.contentItem.height
height: parent.height
clip: true
interactive: false
interactive: true
model: ApiCountryModel
ButtonGroup {
@@ -34,8 +34,8 @@ PageType {
delegate: ColumnLayout {
id: content
implicitWidth: parent.width
implicitHeight: content.implicitHeight
width: menuContent.width
height: content.implicitHeight
RowLayout {
VerticalRadioButton {
@@ -15,61 +15,100 @@ import "../Components"
PageType {
id: root
FlickableType {
id: fl
anchors.top: parent.top
anchors.bottom: parent.bottom
contentHeight: content.height
property list<QtObject> labelsModel: [
regionObject,
priceObject,
endDateObject,
speedObject
]
ColumnLayout {
id: content
QtObject {
id: regionObject
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
readonly property string title: qsTr("For the region")
readonly property string contentKey: "region"
readonly property string objectImageSource: "qrc:/images/controls/map-pin.svg"
}
QtObject {
id: priceObject
readonly property string title: qsTr("Price")
readonly property string contentKey: "price"
readonly property string objectImageSource: "qrc:/images/controls/tag.svg"
}
QtObject {
id: endDateObject
readonly property string title: qsTr("Valid until")
readonly property string contentKey: "endDate"
readonly property string objectImageSource: "qrc:/images/controls/history.svg"
}
QtObject {
id: speedObject
readonly property string title: qsTr("Speed")
readonly property string contentKey: "speed"
readonly property string objectImageSource: "qrc:/images/controls/gauge.svg"
}
ListView {
id: listView
anchors.fill: parent
property bool isFocusable: true
Keys.onTabPressed: {
FocusController.nextKeyTabItem()
}
Keys.onBacktabPressed: {
FocusController.previousKeyTabItem()
}
Keys.onUpPressed: {
FocusController.nextKeyUpItem()
}
Keys.onDownPressed: {
FocusController.nextKeyDownItem()
}
Keys.onLeftPressed: {
FocusController.nextKeyLeftItem()
}
Keys.onRightPressed: {
FocusController.nextKeyRightItem()
}
ScrollBar.vertical: ScrollBarType {}
model: labelsModel
clip: true
reuseItems: true
delegate: ColumnLayout {
width: listView.width
spacing: 0
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/map-pin.svg"
leftText: qsTr("For the region")
rightText: ApiServicesModel.getSelectedServiceData("region")
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/tag.svg"
leftText: qsTr("Price")
rightText: ApiServicesModel.getSelectedServiceData("price")
}
LabelWithImageType {
property bool showSubscriptionEndDate: ServersModel.getProcessedServerData("isCountrySelectionAvailable")
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/history.svg"
leftText: showSubscriptionEndDate ? qsTr("Valid until") : qsTr("Work period")
rightText: showSubscriptionEndDate ? ApiServicesModel.getSelectedServiceData("endDate")
: ApiServicesModel.getSelectedServiceData("workPeriod")
imageSource: objectImageSource
leftText: title
rightText: ApiServicesModel.getSelectedServiceData(contentKey)
visible: rightText !== ""
}
}
LabelWithImageType {
Layout.fillWidth: true
Layout.margins: 16
imageSource: "qrc:/images/controls/gauge.svg"
leftText: qsTr("Speed")
rightText: ApiServicesModel.getSelectedServiceData("speed")
}
footer: ColumnLayout {
width: listView.width
spacing: 0
ParagraphTextType {
Layout.fillWidth: true
@@ -88,6 +127,8 @@ PageType {
return text.replace("%1", LanguageModel.getCurrentSiteUrl())
}
visible: text !== ""
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.NoButton
@@ -252,7 +252,7 @@ PageType {
Layout.fillWidth: true
textFieldPlaceholderText: qsTr("application name")
textField.placeholderText: qsTr("application name")
buttonImageSource: "qrc:/images/controls/plus.svg"
rightButtonClickedOnEnter: true
@@ -221,15 +221,8 @@ PageType {
SettingsController.clearSettings()
PageController.goToPageHome()
}
if (!GC.isMobile()) {
// root.defaultActiveFocusItem.forceActiveFocus()
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
// root.defaultActiveFocusItem.forceActiveFocus()
}
}
showQuestionDrawer(headerText, descriptionText, yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
+8 -15
View File
@@ -67,7 +67,7 @@ PageType {
Layout.fillWidth: true
headerText: qsTr("Primary DNS")
textFieldText: SettingsController.primaryDns
textField.text: SettingsController.primaryDns
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
@@ -79,7 +79,7 @@ PageType {
Layout.fillWidth: true
headerText: qsTr("Secondary DNS")
textFieldText: SettingsController.secondaryDns
textField.text: SettingsController.secondaryDns
textField.validator: RegularExpressionValidator {
regularExpression: InstallController.ipAddressRegExp()
}
@@ -105,19 +105,12 @@ PageType {
var yesButtonFunction = function() {
SettingsController.primaryDns = "1.1.1.1"
primaryDns.textFieldText = SettingsController.primaryDns
primaryDns.textField.text = SettingsController.primaryDns
SettingsController.secondaryDns = "1.0.0.1"
secondaryDns.textFieldText = SettingsController.secondaryDns
secondaryDns.textField.text = SettingsController.secondaryDns
PageController.showNotificationMessage(qsTr("Settings have been reset"))
if (!GC.isMobile()) {
// defaultActiveFocusItem.forceActiveFocus()
}
}
var noButtonFunction = function() {
if (!GC.isMobile()) {
// defaultActiveFocusItem.forceActiveFocus()
}
}
showQuestionDrawer(headerText, "", yesButtonText, noButtonText, yesButtonFunction, noButtonFunction)
@@ -132,11 +125,11 @@ PageType {
text: qsTr("Save")
clickedFunc: function() {
if (primaryDns.textFieldText !== SettingsController.primaryDns) {
SettingsController.primaryDns = primaryDns.textFieldText
if (primaryDns.textField.text !== SettingsController.primaryDns) {
SettingsController.primaryDns = primaryDns.textField.text
}
if (secondaryDns.textFieldText !== SettingsController.secondaryDns) {
SettingsController.secondaryDns = secondaryDns.textFieldText
if (secondaryDns.textField.text !== SettingsController.secondaryDns) {
SettingsController.secondaryDns = secondaryDns.textField.text
}
PageController.showNotificationMessage(qsTr("Settings saved"))
}
@@ -137,6 +137,8 @@ PageType {
Layout.topMargin: -8
Layout.bottomMargin: -8
visible: !GC.isMobile()
text: qsTr("Open logs folder")
leftImageSource: "qrc:/images/controls/folder-open.svg"
isSmallLeftImage: true
@@ -142,7 +142,7 @@ PageType {
Layout.fillWidth: true
headerText: qsTr("Server name")
textFieldText: root.processedServer.name
textField.text: root.processedServer.name
textField.maximumLength: 30
checkEmptyText: true
}
@@ -155,12 +155,12 @@ PageType {
text: qsTr("Save")
clickedFunc: function() {
if (serverName.textFieldText === "") {
if (serverName.textField.text === "") {
return
}
if (serverName.textFieldText !== root.processedServer.name) {
ServersModel.setProcessedServerData("name", serverName.textFieldText);
if (serverName.textField.text !== root.processedServer.name) {
ServersModel.setProcessedServerData("name", serverName.textField.text);
}
serverNameEditDrawer.closeTriggered()
}
@@ -144,6 +144,7 @@ PageType {
model: root.routeModesModel
selectedIndex: getRouteModesModelIndex()
clickedFunction: function() {
selector.text = selectedText
@@ -273,13 +274,13 @@ PageType {
Layout.fillWidth: true
rightButtonClickedOnEnter: true
textFieldPlaceholderText: qsTr("website or IP")
textField.placeholderText: qsTr("website or IP")
buttonImageSource: "qrc:/images/controls/plus.svg"
clickedFunc: function() {
PageController.showBusyIndicator(true)
SitesController.addSite(textFieldText)
textFieldText = ""
SitesController.addSite(textField.text)
textField.text = ""
PageController.showBusyIndicator(false)
}
}
@@ -337,7 +338,6 @@ PageType {
LabelWithButtonType {
id: exportSitesButton
enabled: !SettingsController.isOnTv()
Layout.fillWidth: true
text: qsTr("Save site list")
@@ -361,9 +361,7 @@ PageType {
}
}
DividerType {
enabled: !SettingsController.isOnTv()
}
DividerType {}
}
}
@@ -70,7 +70,7 @@ PageType {
imageSource: "qrc:/images/controls/history.svg"
leftText: qsTr("Work period")
rightText: ApiServicesModel.getSelectedServiceData("workPeriod")
rightText: ApiServicesModel.getSelectedServiceData("timeLimit")
visible: rightText !== ""
}
@@ -163,12 +163,12 @@ PageType {
Layout.rightMargin: 16
Layout.leftMargin: 16
visible: textKey.textFieldText !== ""
visible: textKey.textField.text !== ""
text: qsTr("Continue")
clickedFunc: function() {
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
if (ImportController.extractConfigFromData(textKey.textField.text)) {
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
}
}
@@ -206,6 +206,34 @@ PageType {
onClicked: { handler() }
}
}
footer: ColumnLayout {
width: listView.width
BasicButtonType {
id: siteLink2
Layout.topMargin: 24
Layout.bottomMargin: 16
Layout.alignment: Qt.AlignHCenter
implicitHeight: 32
visible: Qt.platform.os !== "ios"
defaultColor: AmneziaStyle.color.transparent
hoveredColor: AmneziaStyle.color.translucentWhite
pressedColor: AmneziaStyle.color.sheerWhite
disabledColor: AmneziaStyle.color.mutedGray
textColor: AmneziaStyle.color.goldenApricot
text: qsTr("Site Amnezia")
rightImageSource: "qrc:/images/controls/external-link.svg"
clickedFunc: function() {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}
}
}
}
property list<QtObject> variants: [
@@ -304,7 +332,7 @@ PageType {
property string title: qsTr("I have nothing")
property string description: qsTr("")
property string imageSource: "qrc:/images/controls/help-circle.svg"
property bool isVisible: PageController.isStartPageVisible()
property bool isVisible: PageController.isStartPageVisible() && Qt.platform.os !== "ios"
property var handler: function() {
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
}
@@ -82,24 +82,19 @@ PageType {
reuseItems: true
delegate: ColumnLayout {
property alias textField: _textField.textField
width: listView.width
TextFieldWithHeaderType {
id: _textField
id: delegate
Layout.fillWidth: true
Layout.leftMargin: 16
Layout.rightMargin: 16
property bool hidePassword: hideText
headerText: title
textField.echoMode: hideText ? TextInput.Password : TextInput.Normal
buttonImageSource: imageSource
textFieldPlaceholderText: placeholderText
textField.text: textFieldText
textField.echoMode: hideContent ? TextInput.Password : TextInput.Normal
textField.placeholderText: placeholderContent
textField.text: textField.text
rightButtonClickedOnEnter: true
@@ -108,17 +103,12 @@ PageType {
}
textField.onFocusChanged: {
var _currentIndex = listView.currentIndex
var _currentItem = listView.itemAtIndex(_currentIndex).children[0]
listView.model[_currentIndex].textFieldText = _currentItem.textFieldText.replace(/^\s+|\s+$/g, '')
textField.text = textField.text.replace(/^\s+|\s+$/g, '')
}
textField.onTextChanged: {
var _currentIndex = listView.currentIndex
textFieldText = textField.text
if (_currentIndex === vars.secretDataIndex) {
buttonImageSource = textFieldText !== "" ? (hideText ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
if (hideContent) {
buttonImageSource = textField.text !== "" ? (hideContent ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
}
}
}
@@ -143,9 +133,9 @@ PageType {
}
InstallController.setShouldCreateServer(true)
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0].textFieldText
var _username = listView.itemAtIndex(vars.usernameIndex).children[0].textFieldText
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textFieldText
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0].textField.text
var _username = listView.itemAtIndex(vars.usernameIndex).children[0].textField.text
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0].textField.text
InstallController.setProcessedServerCredentials(_hostname, _username, _secretData)
@@ -194,23 +184,23 @@ PageType {
function isCredentialsFilled() {
var hasEmptyField = false
var _hostname = listView.itemAtIndex(vars.hostnameIndex).children[0]
if (_hostname.textFieldText === "") {
_hostname.errorText = qsTr("Ip address cannot be empty")
var hostnameItem = listView.itemAtIndex(vars.hostnameIndex).children[0]
if (hostnameItem.textField.text === "") {
hostnameItem.errorText = qsTr("Ip address cannot be empty")
hasEmptyField = true
} else if (!_hostname.textField.acceptableInput) {
_hostname.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
} else if (!hostnameItem.textField.acceptableInput) {
hostnameItem.errorText = qsTr("Enter the address in the format 255.255.255.255:88")
}
var _username = listView.itemAtIndex(vars.usernameIndex).children[0]
if (_username.textFieldText === "") {
_username.errorText = qsTr("Login cannot be empty")
var usernameItem = listView.itemAtIndex(vars.usernameIndex).children[0]
if (usernameItem.textField.text === "") {
usernameItem.errorText = qsTr("Login cannot be empty")
hasEmptyField = true
}
var _secretData = listView.itemAtIndex(vars.secretDataIndex).children[0]
if (_secretData.textFieldText === "") {
_secretData.errorText = qsTr("Password/private key cannot be empty")
var secretDataItem = listView.itemAtIndex(vars.secretDataIndex).children[0]
if (secretDataItem.textField.text === "") {
secretDataItem.errorText = qsTr("Password/private key cannot be empty")
hasEmptyField = true
}
@@ -218,46 +208,37 @@ PageType {
}
property list<QtObject> inputFields: [
hostname,
username,
secretData
hostnameObject,
usernameObject,
secretDataObject
]
QtObject {
id: hostname
id: hostnameObject
property string title: qsTr("Server IP address [:port]")
readonly property string placeholderText: qsTr("255.255.255.255:22")
property string textFieldText: ""
property bool hideText: false
property string imageSource: ""
readonly property var clickedHandler: function() {
console.debug(">>> Server IP address text field was clicked!!!")
clicked()
}
}
QtObject {
id: username
property string title: qsTr("SSH Username")
readonly property string placeholderText: "root"
property string textFieldText: ""
property bool hideText: false
property string imageSource: ""
readonly property string placeholderContent: qsTr("255.255.255.255:22")
property bool hideContent: false
readonly property var clickedHandler: undefined
}
QtObject {
id: secretData
id: usernameObject
property string title: qsTr("SSH Username")
readonly property string placeholderContent: "root"
property bool hideContent: false
readonly property var clickedHandler: undefined
}
QtObject {
id: secretDataObject
property string title: qsTr("Password or SSH private key")
readonly property string placeholderText: ""
property string textFieldText: ""
property bool hideText: true
property string imageSource: textFieldText !== "" ? (hideText ? "qrc:/images/controls/eye.svg" : "qrc:/images/controls/eye-off.svg") : ""
readonly property string placeholderContent: ""
property bool hideContent: true
readonly property var clickedHandler: function() {
hideText = !hideText
hideContent = !hideContent
}
}
+3 -2
View File
@@ -65,7 +65,7 @@ PageType {
implicitWidth: parent.width
headerTextMaximumLineCount: 10
headerText: qsTr("What is the level of internet control in your region?")
headerText: qsTr("Choose Installation Type")
}
ButtonGroup {
@@ -139,7 +139,8 @@ PageType {
CardType {
implicitWidth: parent.width
headerText: qsTr("Choose a VPN protocol")
headerText: qsTr("Manual")
bodyText: qsTr("Choose a VPN protocol")
ButtonGroup.group: buttonGroup
@@ -257,7 +257,7 @@ PageType {
}
PageController.goToPage(PageEnum.PageSetupWizardInstalling);
InstallController.install(dockerContainer, port.textFieldText, transportProtoSelector.currentIndex)
InstallController.install(dockerContainer, port.textField.text, transportProtoSelector.currentIndex)
}
}
@@ -267,7 +267,7 @@ PageType {
if (ProtocolProps.defaultPort(defaultContainerProto) < 0) {
port.visible = false
} else {
port.textFieldText = ProtocolProps.getPortForInstall(defaultContainerProto)
port.textField.text = ProtocolProps.getPortForInstall(defaultContainerProto)
}
transportProtoSelector.currentIndex = ProtocolProps.defaultTransportProto(defaultContainerProto)
@@ -51,7 +51,7 @@ PageType {
Layout.leftMargin: 16
headerText: qsTr("Key")
textFieldPlaceholderText: "vpn://"
textField.placeholderText: "vpn://"
buttonText: qsTr("Insert")
clickedFunc: function() {
@@ -75,7 +75,7 @@ PageType {
text: qsTr("Continue")
clickedFunc: function() {
if (ImportController.extractConfigFromData(textKey.textFieldText)) {
if (ImportController.extractConfigFromData(textKey.textField.text)) {
PageController.goToPage(PageEnum.PageSetupWizardViewConfig)
}
}
+48 -25
View File
@@ -51,25 +51,25 @@ PageType {
switch (type) {
case PageShare.ConfigType.AmneziaConnection: {
ExportController.generateConnectionConfig(clientNameTextField.textFieldText);
ExportController.generateConnectionConfig(clientNameTextField.textField.text);
break;
}
case PageShare.ConfigType.OpenVpn: {
ExportController.generateOpenVpnConfig(clientNameTextField.textFieldText)
ExportController.generateOpenVpnConfig(clientNameTextField.textField.text)
shareConnectionDrawer.configCaption = qsTr("Save OpenVPN config")
shareConnectionDrawer.configExtension = ".ovpn"
shareConnectionDrawer.configFileName = "amnezia_for_openvpn"
break
}
case PageShare.ConfigType.WireGuard: {
ExportController.generateWireGuardConfig(clientNameTextField.textFieldText)
ExportController.generateWireGuardConfig(clientNameTextField.textField.text)
shareConnectionDrawer.configCaption = qsTr("Save WireGuard config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_wireguard"
break
}
case PageShare.ConfigType.Awg: {
ExportController.generateAwgConfig(clientNameTextField.textFieldText)
ExportController.generateAwgConfig(clientNameTextField.textField.text)
shareConnectionDrawer.configCaption = qsTr("Save AmneziaWG config")
shareConnectionDrawer.configExtension = ".conf"
shareConnectionDrawer.configFileName = "amnezia_for_awg"
@@ -90,7 +90,7 @@ PageType {
break
}
case PageShare.ConfigType.Xray: {
ExportController.generateXrayConfig(clientNameTextField.textFieldText)
ExportController.generateXrayConfig(clientNameTextField.textField.text)
shareConnectionDrawer.configCaption = qsTr("Save XRay config")
shareConnectionDrawer.configExtension = ".json"
shareConnectionDrawer.configFileName = "amnezia_for_xray"
@@ -296,7 +296,7 @@ PageType {
visible: accessTypeSelector.currentIndex === 0
headerText: qsTr("User name")
textFieldText: "New client"
textField.text: "New client"
textField.maximumLength: 20
checkEmptyText: true
@@ -355,6 +355,7 @@ PageType {
serverSelectorListView.selectedIndex = 0
}
serverSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
serverSelectorListView.triggerCurrentItem()
}
@@ -410,6 +411,7 @@ PageType {
function onSeverSelectorIndexChanged() {
var defaultContainer = proxyContainersModel.mapFromSource(ServersModel.getProcessedServerData("defaultContainer"))
protocolSelectorListView.selectedIndex = defaultContainer
protocolSelectorListView.positionViewAtIndex(selectedIndex, ListView.Beginning)
protocolSelectorListView.triggerCurrentItem()
}
}
@@ -479,9 +481,11 @@ PageType {
headerText: qsTr("Connection format")
listView: ListViewWithRadioButtonType {
id: exportTypeSelectorListView
onCurrentIndexChanged: {
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
exportTypeSelector.text = exportTypeSelectorListView.selectedText
}
rootWidth: root.width
@@ -492,14 +496,14 @@ PageType {
currentIndex: 0
clickedFunction: function() {
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.text = exportTypeSelectorListView.selectedText
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
exportTypeSelector.closeTriggered()
}
Component.onCompleted: {
exportTypeSelector.text = selectedText
exportTypeSelector.currentIndex = currentIndex
exportTypeSelector.text = exportTypeSelectorListView.selectedText
exportTypeSelector.currentIndex = exportTypeSelectorListView.selectedIndex
}
}
}
@@ -521,7 +525,7 @@ PageType {
parentFlickable: a
clickedFunc: function(){
if (clientNameTextField.textFieldText !== "") {
if (clientNameTextField.textField.text !== "") {
ExportController.generateConfig(root.connectionTypesModel[exportTypeSelector.currentIndex].type)
}
}
@@ -551,14 +555,14 @@ PageType {
id: searchTextField
Layout.fillWidth: true
textFieldPlaceholderText: qsTr("Search")
textField.placeholderText: qsTr("Search")
Keys.onEscapePressed: {
root.isSearchBarVisible = false
}
function navigateTo() {
if (searchTextField.textFieldText === "") {
if (searchTextField.textField.text === "") {
root.isSearchBarVisible = false
}
}
@@ -597,12 +601,13 @@ PageType {
sourceModel: ClientManagementModel
filters: RegExpFilter {
roleName: "clientName"
pattern: ".*" + searchTextField.textFieldText + ".*"
pattern: ".*" + searchTextField.textField.text + ".*"
caseSensitivity: Qt.CaseInsensitive
}
}
clip: true
interactive: false
reuseItems: true
delegate: Item {
@@ -667,7 +672,11 @@ PageType {
ParagraphTextType {
color: AmneziaStyle.color.mutedGray
visible: creationDate
Layout.fillWidth: true
Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Creation date: %1").arg(creationDate)
}
@@ -675,7 +684,11 @@ PageType {
ParagraphTextType {
color: AmneziaStyle.color.mutedGray
visible: latestHandshake
Layout.fillWidth: true
Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Latest handshake: %1").arg(latestHandshake)
}
@@ -683,7 +696,11 @@ PageType {
ParagraphTextType {
color: AmneziaStyle.color.mutedGray
visible: dataReceived
Layout.fillWidth: true
Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Data received: %1").arg(dataReceived)
}
@@ -691,7 +708,11 @@ PageType {
ParagraphTextType {
color: AmneziaStyle.color.mutedGray
visible: dataSent
Layout.fillWidth: true
Layout.maximumWidth: parent.width
maximumLineCount: 2
wrapMode: Text.Wrap
elide: Qt.ElideRight
text: qsTr("Data sent: %1").arg(dataSent)
}
@@ -699,7 +720,9 @@ PageType {
ParagraphTextType {
color: AmneziaStyle.color.mutedGray
visible: allowedIps
Layout.fillWidth: true
Layout.maximumWidth: parent.width
wrapMode: Text.Wrap
text: qsTr("Allowed IPs: %1").arg(allowedIps)
}
@@ -742,7 +765,7 @@ PageType {
id: clientNameEditor
Layout.fillWidth: true
headerText: qsTr("Client name")
textFieldText: clientName
textField.text: clientName
textField.maximumLength: 20
checkEmptyText: true
}
@@ -755,14 +778,14 @@ PageType {
text: qsTr("Save")
clickedFunc: function() {
if (clientNameEditor.textFieldText === "") {
if (clientNameEditor.textField.text === "") {
return
}
if (clientNameEditor.textFieldText !== clientName) {
if (clientNameEditor.textField.text !== clientName) {
PageController.showBusyIndicator(true)
ExportController.renameClient(index,
clientNameEditor.textFieldText,
clientNameEditor.textField.text,
ContainersModel.getProcessedContainerIndex(),
ServersModel.getProcessedServerCredentials())
PageController.showBusyIndicator(false)
+1 -1
View File
@@ -348,7 +348,7 @@ PageType {
objectName: "settingsTabButton"
isSelected: tabBar.currentIndex === 2
image: "qrc:/images/controls/settings-2.svg"
image: "qrc:/images/controls/settings.svg"
clickedFunc: function () {
tabBarStackView.goToTabBarPage(PageEnum.PageSettings)
tabBar.currentIndex = 2
+3 -3
View File
@@ -176,12 +176,12 @@ Window {
Connections {
target: privateKeyPassphraseDrawer
function onOpened() {
passphrase.textFieldText = ""
passphrase.textField.text = ""
passphrase.textField.forceActiveFocus()
}
function onAboutToHide() {
if (passphrase.textFieldText !== "") {
if (passphrase.textField.text !== "") {
PageController.showBusyIndicator(true)
}
}
@@ -222,7 +222,7 @@ Window {
clickedFunc: function() {
privateKeyPassphraseDrawer.closeTriggered()
PageController.passphraseRequestDrawerClosed(passphrase.textFieldText)
PageController.passphraseRequestDrawerClosed(passphrase.textField.text)
}
}
}