m_containersModel;
diff --git a/client/ui/models/apiServicesModel.cpp b/client/ui/models/apiServicesModel.cpp
index 81a10f87..3e684195 100644
--- a/client/ui/models/apiServicesModel.cpp
+++ b/client/ui/models/apiServicesModel.cpp
@@ -70,7 +70,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
.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) {
+ if (!isServiceAvailable) {
description += tr("Not available in your region. If you have VPN enabled, disable it, return to the previous screen, and try again.");
}
return description;
@@ -86,7 +86,7 @@ QVariant ApiServicesModel::data(const QModelIndex &index, int role) const
}
case IsServiceAvailableRole: {
if (serviceType == serviceType::amneziaFree) {
- if (isServiceAvailable) {
+ if (!isServiceAvailable) {
return false;
}
}
diff --git a/client/ui/models/protocols/awgConfigModel.cpp b/client/ui/models/protocols/awgConfigModel.cpp
index 3a245ebe..860c8395 100644
--- a/client/ui/models/protocols/awgConfigModel.cpp
+++ b/client/ui/models/protocols/awgConfigModel.cpp
@@ -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 AwgConfigModel::roleNames() const
{
QHash 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
diff --git a/client/ui/models/protocols/awgConfigModel.h b/client/ui/models/protocols/awgConfigModel.h
index 06475bf5..c1f8bb27 100644
--- a/client/ui/models/protocols/awgConfigModel.h
+++ b/client/ui/models/protocols/awgConfigModel.h
@@ -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,
diff --git a/client/ui/models/protocols/wireguardConfigModel.cpp b/client/ui/models/protocols/wireguardConfigModel.cpp
index 555915de..1c8e1341 100644
--- a/client/ui/models/protocols/wireguardConfigModel.cpp
+++ b/client/ui/models/protocols/wireguardConfigModel.cpp
@@ -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 WireGuardConfigModel::roleNames() const
{
QHash 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;
diff --git a/client/ui/models/protocols/wireguardConfigModel.h b/client/ui/models/protocols/wireguardConfigModel.h
index a02bea5a..b1ce2d61 100644
--- a/client/ui/models/protocols/wireguardConfigModel.h
+++ b/client/ui/models/protocols/wireguardConfigModel.h
@@ -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
};
diff --git a/client/ui/qml/Components/AdLabel.qml b/client/ui/qml/Components/AdLabel.qml
new file mode 100644
index 00000000..4133a01c
--- /dev/null
+++ b/client/ui/qml/Components/AdLabel.qml
@@ -0,0 +1,72 @@
+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: 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()
+ }
+ }
+ }
+}
diff --git a/client/ui/qml/Controls2/DrawerType2.qml b/client/ui/qml/Controls2/DrawerType2.qml
index 4c9bd010..e67e36a1 100644
--- a/client/ui/qml/Controls2/DrawerType2.qml
+++ b/client/ui/qml/Controls2/DrawerType2.qml
@@ -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 }
diff --git a/client/ui/qml/Controls2/DropDownType.qml b/client/ui/qml/Controls2/DropDownType.qml
index 60751e21..ae6dac85 100644
--- a/client/ui/qml/Controls2/DropDownType.qml
+++ b/client/ui/qml/Controls2/DropDownType.qml
@@ -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
}
}
}
diff --git a/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml b/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
index eafc1f5a..bd7ca32e 100644
--- a/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
+++ b/client/ui/qml/Controls2/ListViewWithRadioButtonType.qml
@@ -30,6 +30,8 @@ ListView {
property bool isFocusable: true
+ ScrollBar.vertical: ScrollBarType {}
+
ButtonGroup {
id: buttonGroup
}
diff --git a/client/ui/qml/Modules/Style/AmneziaStyle.qml b/client/ui/qml/Modules/Style/AmneziaStyle.qml
index 1abfbe3a..f54fefce 100644
--- a/client/ui/qml/Modules/Style/AmneziaStyle.qml
+++ b/client/ui/qml/Modules/Style/AmneziaStyle.qml
@@ -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'
}
}
diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml
index 74db8a13..ae29b80c 100644
--- a/client/ui/qml/Pages2/PageHome.qml
+++ b/client/ui/qml/Pages2/PageHome.qml
@@ -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"
diff --git a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
index 3093e134..3594cd9d 100644
--- a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml
@@ -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,12 +98,32 @@ PageType {
}
TextFieldWithHeaderType {
- id: portTextField
+ id: vpnAddressSubnetTextField
+
Layout.fillWidth: true
Layout.topMargin: 40
enabled: delegateItem.isEnabled
+ headerText: qsTr("VPN address subnet")
+ textFieldText: subnetAddress
+
+ textField.onEditingFinished: {
+ if (textFieldText !== subnetAddress) {
+ subnetAddress = textFieldText
+ }
+ }
+
+ checkEmptyText: true
+ }
+
+ TextFieldWithHeaderType {
+ id: portTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+
+ enabled: delegateItem.isEnabled
+
headerText: qsTr("Port")
textFieldText: port
textField.maximumLength: 5
@@ -118,26 +138,6 @@ PageType {
checkEmptyText: true
}
- TextFieldWithHeaderType {
- id: mtuTextField
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- headerText: qsTr("MTU")
- textFieldText: mtu
- textField.validator: IntValidator { bottom: 576; top: 65535 }
-
- textField.onEditingFinished: {
- if (textFieldText === "") {
- textFieldText = "0"
- }
- if (textFieldText !== mtu) {
- mtu = textFieldText
- }
- }
- checkEmptyText: true
- }
-
TextFieldWithHeaderType {
id: junkPacketCountTextField
Layout.fillWidth: true
@@ -332,7 +332,8 @@ PageType {
junkPacketMaxSizeTextField.errorText === "" &&
junkPacketMinSizeTextField.errorText === "" &&
junkPacketCountTextField.errorText === "" &&
- portTextField.errorText === ""
+ portTextField.errorText === "" &&
+ vpnAddressSubnetTextField.errorText === ""
text: qsTr("Save")
diff --git a/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml b/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml
index 2b1f3f44..6c5ad23f 100644
--- a/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolOpenVpnSettings.qml
@@ -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
diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
index 4f0f474c..7413df38 100644
--- a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml
@@ -16,8 +16,6 @@ import "../Components"
PageType {
id: root
- defaultActiveFocusItem: listview.currentItem.mtuTextField.textField
-
Item {
id: focusItem
onFocusChanged: {
diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
index 8aa0b185..f83d97fd 100644
--- a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
+++ b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml
@@ -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,12 +83,31 @@ PageType {
}
TextFieldWithHeaderType {
- id: portTextField
+ id: vpnAddressSubnetTextField
Layout.fillWidth: true
Layout.topMargin: 40
enabled: delegateItem.isEnabled
+ headerText: qsTr("VPN address subnet")
+ textFieldText: subnetAddress
+
+ textField.onEditingFinished: {
+ if (textFieldText !== subnetAddress) {
+ subnetAddress = textFieldText
+ }
+ }
+
+ checkEmptyText: true
+ }
+
+ TextFieldWithHeaderType {
+ id: portTextField
+ Layout.fillWidth: true
+ Layout.topMargin: 16
+
+ enabled: delegateItem.isEnabled
+
headerText: qsTr("Port")
textFieldText: port
textField.maximumLength: 5
@@ -103,33 +122,14 @@ PageType {
checkEmptyText: true
}
- TextFieldWithHeaderType {
- id: mtuTextField
- Layout.fillWidth: true
- Layout.topMargin: 16
-
- headerText: qsTr("MTU")
- textFieldText: mtu
- textField.validator: IntValidator { bottom: 576; top: 65535 }
-
- textField.onEditingFinished: {
- if (textFieldText === "") {
- textFieldText = "0"
- }
- if (textFieldText !== mtu) {
- mtu = textFieldText
- }
- }
- checkEmptyText: true
- }
-
BasicButtonType {
id: saveButton
Layout.fillWidth: true
Layout.topMargin: 24
Layout.bottomMargin: 24
- enabled: portTextField.errorText === ""
+ enabled: portTextField.errorText === "" &&
+ vpnAddressSubnetTextField.errorText === ""
text: qsTr("Save")
diff --git a/client/ui/qml/Pages2/PageSettingsApiLanguageList.qml b/client/ui/qml/Pages2/PageSettingsApiLanguageList.qml
index dd097a1a..30968b38 100644
--- a/client/ui/qml/Pages2/PageSettingsApiLanguageList.qml
+++ b/client/ui/qml/Pages2/PageSettingsApiLanguageList.qml
@@ -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 {
diff --git a/client/ui/qml/Pages2/PageSettingsApplication.qml b/client/ui/qml/Pages2/PageSettingsApplication.qml
index c5fc0bc1..6f77a521 100644
--- a/client/ui/qml/Pages2/PageSettingsApplication.qml
+++ b/client/ui/qml/Pages2/PageSettingsApplication.qml
@@ -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)
diff --git a/client/ui/qml/Pages2/PageSettingsDns.qml b/client/ui/qml/Pages2/PageSettingsDns.qml
index b6ade37a..11e49cf9 100644
--- a/client/ui/qml/Pages2/PageSettingsDns.qml
+++ b/client/ui/qml/Pages2/PageSettingsDns.qml
@@ -109,15 +109,8 @@ PageType {
SettingsController.secondaryDns = "1.0.0.1"
secondaryDns.textFieldText = 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)
diff --git a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
index f5ac64b1..17d733d8 100644
--- a/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
+++ b/client/ui/qml/Pages2/PageSetupWizardConfigSource.qml
@@ -206,6 +206,32 @@ PageType {
onClicked: { handler() }
}
}
+
+ footer: ColumnLayout {
+ width: listView.width
+
+ BasicButtonType {
+ id: siteLink2
+ Layout.topMargin: 24
+ Layout.bottomMargin: 16
+ Layout.alignment: Qt.AlignHCenter
+ implicitHeight: 32
+
+ 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 variants: [
diff --git a/client/ui/qml/Pages2/PageShare.qml b/client/ui/qml/Pages2/PageShare.qml
index 049df1dd..f5c85a5f 100644
--- a/client/ui/qml/Pages2/PageShare.qml
+++ b/client/ui/qml/Pages2/PageShare.qml
@@ -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()
}
}
@@ -603,6 +605,7 @@ PageType {
}
clip: true
+ interactive: false
reuseItems: true
delegate: Item {
@@ -667,7 +670,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 +682,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 +694,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 +706,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 +718,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)
}
diff --git a/client/ui/qml/Pages2/PageStart.qml b/client/ui/qml/Pages2/PageStart.qml
index 83e7626d..71009e28 100644
--- a/client/ui/qml/Pages2/PageStart.qml
+++ b/client/ui/qml/Pages2/PageStart.qml
@@ -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
diff --git a/ipc/ipctun2socksprocess.cpp b/ipc/ipctun2socksprocess.cpp
index ffcb1bcd..2125f6ab 100644
--- a/ipc/ipctun2socksprocess.cpp
+++ b/ipc/ipctun2socksprocess.cpp
@@ -11,7 +11,6 @@ IpcProcessTun2Socks::IpcProcessTun2Socks(QObject *parent) :
IpcProcessTun2SocksSource(parent),
m_t2sProcess(QSharedPointer(new QProcess()))
{
- connect(m_t2sProcess.data(), &QProcess::stateChanged, this, &IpcProcessTun2Socks::stateChanged);
qDebug() << "IpcProcessTun2Socks::IpcProcessTun2Socks()";
}
@@ -23,8 +22,10 @@ IpcProcessTun2Socks::~IpcProcessTun2Socks()
void IpcProcessTun2Socks::start()
{
+ connect(m_t2sProcess.data(), &QProcess::stateChanged, this, &IpcProcessTun2Socks::stateChanged);
qDebug() << "IpcProcessTun2Socks::start()";
m_t2sProcess->setProgram(amnezia::permittedProcessPath(static_cast(amnezia::PermittedProcess::Tun2Socks)));
+
QString XrayConStr = "socks5://127.0.0.1:10808";
#ifdef Q_OS_WIN
@@ -41,7 +42,11 @@ void IpcProcessTun2Socks::start()
m_t2sProcess->setArguments(arguments);
- Utils::killProcessByName(m_t2sProcess->program());
+ if (Utils::processIsRunning(Utils::executable("tun2socks", false))) {
+ qDebug().noquote() << "kill previos tun2socks";
+ Utils::killProcessByName(Utils::executable("tun2socks", false));
+ }
+
m_t2sProcess->start();
connect(m_t2sProcess.data(), &QProcess::readyReadStandardOutput, this, [this]() {
@@ -54,12 +59,10 @@ void IpcProcessTun2Socks::start()
connect(m_t2sProcess.data(), QOverload::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) {
qDebug().noquote() << "tun2socks finished, exitCode, exiStatus" << exitCode << exitStatus;
emit setConnectionState(Vpn::ConnectionState::Disconnected);
- if (exitStatus != QProcess::NormalExit){
- stop();
- }
- if (exitCode !=0 ){
- stop();
+ if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) {
+ emit setConnectionState(Vpn::ConnectionState::Error);
}
+
});
m_t2sProcess->start();
@@ -69,6 +72,8 @@ void IpcProcessTun2Socks::start()
void IpcProcessTun2Socks::stop()
{
qDebug() << "IpcProcessTun2Socks::stop()";
- m_t2sProcess->close();
+ m_t2sProcess->disconnect();
+ m_t2sProcess->kill();
+ m_t2sProcess->waitForFinished(3000);
}
#endif
diff --git a/service/server/router_linux.cpp b/service/server/router_linux.cpp
index 105e5397..852c878f 100644
--- a/service/server/router_linux.cpp
+++ b/service/server/router_linux.cpp
@@ -152,21 +152,29 @@ bool RouterLinux::routeDeleteList(const QString &gw, const QStringList &ips)
return cnt;
}
+bool RouterLinux::isServiceActive(const QString &serviceName) {
+ QProcess process;
+ process.start("systemctl", { "is-active", "--quiet", serviceName });
+ process.waitForFinished();
+
+ return process.exitCode() == 0;
+}
+
void RouterLinux::flushDns()
{
QProcess p;
p.setProcessChannelMode(QProcess::MergedChannels);
//check what the dns manager use
- if (QFileInfo::exists("/usr/bin/nscd")
- || QFileInfo::exists("/usr/sbin/nscd")
- || QFileInfo::exists("/usr/lib/systemd/system/nscd.service"))
- {
+ if (isServiceActive("nscd.service")) {
+ qDebug() << "Restarting nscd.service";
p.start("systemctl", { "restart", "nscd" });
- }
- else
- {
+ } else if (isServiceActive("systemd-resolved.service")) {
+ qDebug() << "Restarting systemd-resolved.service";
p.start("systemctl", { "restart", "systemd-resolved" });
+ } else {
+ qDebug() << "No suitable DNS manager found.";
+ return;
}
p.waitForFinished();
diff --git a/service/server/router_linux.h b/service/server/router_linux.h
index 04a26fd2..2094f596 100644
--- a/service/server/router_linux.h
+++ b/service/server/router_linux.h
@@ -43,6 +43,7 @@ private:
RouterLinux(RouterLinux const &) = delete;
RouterLinux& operator= (RouterLinux const&) = delete;
+ bool isServiceActive(const QString &serviceName);
QList m_addedRoutes;
DnsUtilsLinux *m_dnsUtil;
};