From 7350d79c5000d5aa2bfcc6e53e3be3236ad93446 Mon Sep 17 00:00:00 2001 From: Vitaly Date: Thu, 2 Jan 2025 08:07:12 +0100 Subject: [PATCH 1/6] feature: WG and AWG: Subnet IP setting change support (#1323) feature: wg/awg subnet ip setting change support --- .../configurators/wireguard_configurator.cpp | 2 +- client/core/controllers/serverController.cpp | 12 ++++++--- .../server_scripts/awg/configure_container.sh | 2 +- client/server_scripts/awg/start.sh | 8 +++--- client/ui/models/protocols/awgConfigModel.cpp | 7 ++++- client/ui/models/protocols/awgConfigModel.h | 4 ++- .../models/protocols/wireguardConfigModel.cpp | 7 ++++- .../models/protocols/wireguardConfigModel.h | 4 ++- .../ui/qml/Pages2/PageProtocolAwgSettings.qml | 27 ++++++++++++++++--- .../PageProtocolWireGuardClientSettings.qml | 2 +- .../Pages2/PageProtocolWireGuardSettings.qml | 26 +++++++++++++++--- 11 files changed, 81 insertions(+), 20 deletions(-) diff --git a/client/configurators/wireguard_configurator.cpp b/client/configurators/wireguard_configurator.cpp index 3f96e74c..1bca973d 100644 --- a/client/configurators/wireguard_configurator.cpp +++ b/client/configurators/wireguard_configurator.cpp @@ -120,7 +120,7 @@ WireguardConfigurator::ConnectionData WireguardConfigurator::prepareWireguardCon } } - QString subnetIp = containerConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); + QString subnetIp = containerConfig.value(m_protocolName).toObject().value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress); { QStringList l = subnetIp.split(".", Qt::SkipEmptyParts); if (l.isEmpty()) { diff --git a/client/core/controllers/serverController.cpp b/client/core/controllers/serverController.cpp index b6795a01..7219ff7d 100644 --- a/client/core/controllers/serverController.cpp +++ b/client/core/controllers/serverController.cpp @@ -346,7 +346,9 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c } if (container == DockerContainer::Awg) { - if ((oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort) + if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) + != newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)) + || (oldProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort) != newProtoConfig.value(config_key::port).toString(protocols::awg::defaultPort)) || (oldProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount) != newProtoConfig.value(config_key::junkPacketCount).toString(protocols::awg::defaultJunkPacketCount)) @@ -370,8 +372,10 @@ bool ServerController::isReinstallContainerRequired(DockerContainer container, c } if (container == DockerContainer::WireGuard) { - if (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) - != newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort)) + if ((oldProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) + != newProtoConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress)) + || (oldProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort) + != newProtoConfig.value(config_key::port).toString(protocols::wireguard::defaultPort))) return true; } @@ -607,6 +611,8 @@ ServerController::Vars ServerController::genVarsForScript(const ServerCredential vars.append({ { "$SFTP_PASSWORD", sftpConfig.value(config_key::password).toString() } }); // Amnezia wireguard vars + vars.append({ { "$AWG_SUBNET_IP", + amneziaWireguarConfig.value(config_key::subnet_address).toString(protocols::wireguard::defaultSubnetAddress) } }); vars.append({ { "$AWG_SERVER_PORT", amneziaWireguarConfig.value(config_key::port).toString(protocols::awg::defaultPort) } }); vars.append({ { "$JUNK_PACKET_COUNT", amneziaWireguarConfig.value(config_key::junkPacketCount).toString() } }); diff --git a/client/server_scripts/awg/configure_container.sh b/client/server_scripts/awg/configure_container.sh index 322cc38f..2000c965 100644 --- a/client/server_scripts/awg/configure_container.sh +++ b/client/server_scripts/awg/configure_container.sh @@ -12,7 +12,7 @@ echo $WIREGUARD_PSK > /opt/amnezia/awg/wireguard_psk.key cat > /opt/amnezia/awg/wg0.conf < 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/Pages2/PageProtocolAwgSettings.qml b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml index 3093e134..44cedc11 100644 --- a/client/ui/qml/Pages2/PageProtocolAwgSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolAwgSettings.qml @@ -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 @@ -332,7 +352,8 @@ PageType { junkPacketMaxSizeTextField.errorText === "" && junkPacketMinSizeTextField.errorText === "" && junkPacketCountTextField.errorText === "" && - portTextField.errorText === "" + portTextField.errorText === "" && + vpnAddressSubnetTextField.errorText === "" text: qsTr("Save") diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml index 4f0f474c..d78ae6b9 100644 --- a/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolWireGuardClientSettings.qml @@ -16,7 +16,7 @@ import "../Components" PageType { id: root - defaultActiveFocusItem: listview.currentItem.mtuTextField.textField + //defaultActiveFocusItem: listview.currentItem.mtuTextField.textField Item { id: focusItem diff --git a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml index 8aa0b185..68d9611d 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 @@ -129,7 +148,8 @@ PageType { Layout.topMargin: 24 Layout.bottomMargin: 24 - enabled: portTextField.errorText === "" + enabled: portTextField.errorText === "" && + vpnAddressSubnetTextField.errorText === "" text: qsTr("Save") From e7fa160c9c51f829d93e837d44e4b1ab7d8217b7 Mon Sep 17 00:00:00 2001 From: Nethius Date: Tue, 7 Jan 2025 06:38:32 +0300 Subject: [PATCH 2/6] feature: added ad label on page home (#1316) * feature: added ad label on page home --- client/images/controls/external-link.svg | 5 ++ client/resources.qrc | 2 + client/settings.cpp | 10 +++ client/settings.h | 3 + client/ui/controllers/settingsController.cpp | 13 +++- client/ui/controllers/settingsController.h | 7 ++ client/ui/qml/Components/AdLabel.qml | 72 +++++++++++++++++++ client/ui/qml/Modules/Style/AmneziaStyle.qml | 1 + client/ui/qml/Pages2/PageHome.qml | 16 ++++- .../Pages2/PageSetupWizardConfigSource.qml | 26 +++++++ 10 files changed, 151 insertions(+), 4 deletions(-) create mode 100644 client/images/controls/external-link.svg create mode 100644 client/ui/qml/Components/AdLabel.qml diff --git a/client/images/controls/external-link.svg b/client/images/controls/external-link.svg new file mode 100644 index 00000000..6a51c902 --- /dev/null +++ b/client/images/controls/external-link.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/client/resources.qrc b/client/resources.qrc index 38f0e79a..ff03a6e7 100644 --- a/client/resources.qrc +++ b/client/resources.qrc @@ -21,6 +21,7 @@ images/controls/edit-3.svg images/controls/eye-off.svg images/controls/eye.svg + images/controls/external-link.svg images/controls/file-check-2.svg images/controls/file-cog-2.svg images/controls/folder-open.svg @@ -116,6 +117,7 @@ server_scripts/xray/run_container.sh server_scripts/xray/start.sh server_scripts/xray/template.json + ui/qml/Components/AdLabel.qml ui/qml/Components/ConnectButton.qml ui/qml/Components/ConnectionTypeSelectionDrawer.qml ui/qml/Components/HomeContainersListView.qml diff --git a/client/settings.cpp b/client/settings.cpp index 7a572a13..94b11d00 100644 --- a/client/settings.cpp +++ b/client/settings.cpp @@ -538,3 +538,13 @@ void Settings::toggleDevGatewayEnv(bool enabled) { m_isDevGatewayEnv = enabled; } + +bool Settings::isHomeAdLabelVisible() +{ + return value("Conf/homeAdLabelVisible", true).toBool(); +} + +void Settings::disableHomeAdLabel() +{ + setValue("Conf/homeAdLabelVisible", false); +} diff --git a/client/settings.h b/client/settings.h index f41f4d29..b383d3da 100644 --- a/client/settings.h +++ b/client/settings.h @@ -222,6 +222,9 @@ public: bool isDevGatewayEnv(); void toggleDevGatewayEnv(bool enabled); + bool isHomeAdLabelVisible(); + void disableHomeAdLabel(); + signals: void saveLogsChanged(bool enabled); void screenshotsEnabledChanged(bool enabled); diff --git a/client/ui/controllers/settingsController.cpp b/client/ui/controllers/settingsController.cpp index 6d777bd8..f4e3d83d 100644 --- a/client/ui/controllers/settingsController.cpp +++ b/client/ui/controllers/settingsController.cpp @@ -320,4 +320,15 @@ bool SettingsController::isOnTv() #else return false; #endif -} \ No newline at end of file +} + +bool SettingsController::isHomeAdLabelVisible() +{ + return m_settings->isHomeAdLabelVisible(); +} + +void SettingsController::disableHomeAdLabel() +{ + m_settings->disableHomeAdLabel(); + emit isHomeAdLabelVisibleChanged(false); +} diff --git a/client/ui/controllers/settingsController.h b/client/ui/controllers/settingsController.h index efc18a7d..7781f6c7 100644 --- a/client/ui/controllers/settingsController.h +++ b/client/ui/controllers/settingsController.h @@ -29,6 +29,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(); @@ -89,6 +91,9 @@ public slots: bool isOnTv(); + bool isHomeAdLabelVisible(); + void disableHomeAdLabel(); + signals: void primaryDnsChanged(); void secondaryDnsChanged(); @@ -112,6 +117,8 @@ signals: void gatewayEndpointChanged(const QString &endpoint); void devGatewayEnvChanged(bool enabled); + void isHomeAdLabelVisibleChanged(bool visible); + private: QSharedPointer m_serversModel; QSharedPointer m_containersModel; 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/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..d5cf8b6e 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 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: [ From 767b14b37a55f8111d1d7342c80a53bbe08294a3 Mon Sep 17 00:00:00 2001 From: Mykola Baibuz Date: Tue, 7 Jan 2025 06:52:10 -0800 Subject: [PATCH 3/6] Improve XRay protocol process close (#1318) --- client/protocols/xrayprotocol.cpp | 35 ++++++++++++++----------------- ipc/ipctun2socksprocess.cpp | 21 ++++++++++++------- 2 files changed, 29 insertions(+), 27 deletions(-) diff --git a/client/protocols/xrayprotocol.cpp b/client/protocols/xrayprotocol.cpp index 2dfbcc21..7c69ccde 100755 --- a/client/protocols/xrayprotocol.cpp +++ b/client/protocols/xrayprotocol.cpp @@ -1,7 +1,6 @@ #include "xrayprotocol.h" #include "utilities.h" -#include "containers/containers_defs.h" #include "core/networkUtilities.h" #include @@ -22,9 +21,8 @@ XrayProtocol::XrayProtocol(const QJsonObject &configuration, QObject *parent): XrayProtocol::~XrayProtocol() { + qDebug() << "XrayProtocol::~XrayProtocol()"; XrayProtocol::stop(); - QThread::msleep(200); - m_xrayProcess.close(); } ErrorCode XrayProtocol::start() @@ -36,10 +34,6 @@ ErrorCode XrayProtocol::start() return lastError(); } - if (Utils::processIsRunning(Utils::executable(xrayExecPath(), true))) { - Utils::killProcessByName(Utils::executable(xrayExecPath(), true)); - } - #ifdef QT_DEBUG m_xrayCfgFile.setAutoRemove(false); #endif @@ -54,9 +48,16 @@ ErrorCode XrayProtocol::start() qDebug().noquote() << "XrayProtocol::start()" << xrayExecPath() << args.join(" "); - m_xrayProcess.setProcessChannelMode(QProcess::MergedChannels); + + m_xrayProcess.setProcessChannelMode(QProcess::MergedChannels); m_xrayProcess.setProgram(xrayExecPath()); + + if (Utils::processIsRunning(Utils::executable("xray", false))) { + qDebug().noquote() << "kill previos xray"; + Utils::killProcessByName(Utils::executable("xray", false)); + } + m_xrayProcess.setArguments(args); connect(&m_xrayProcess, &QProcess::readyReadStandardOutput, this, [this]() { @@ -68,13 +69,9 @@ ErrorCode XrayProtocol::start() connect(&m_xrayProcess, QOverload::of(&QProcess::finished), this, [this](int exitCode, QProcess::ExitStatus exitStatus) { qDebug().noquote() << "XrayProtocol finished, exitCode, exitStatus" << exitCode << exitStatus; setConnectionState(Vpn::ConnectionState::Disconnected); - if (exitStatus != QProcess::NormalExit) { - emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed); - stop(); - } - if (exitCode != 0) { - emit protocolError(amnezia::ErrorCode::InternalError); - stop(); + if ((exitStatus != QProcess::NormalExit) || (exitCode != 0)) { + emit protocolError(amnezia::ErrorCode::XrayExecutableCrashed); + emit setConnectionState(Vpn::ConnectionState::Error); } }); @@ -177,14 +174,14 @@ void XrayProtocol::stop() IpcClient::Interface()->StartRoutingIpv6(); #endif qDebug() << "XrayProtocol::stop()"; - m_xrayProcess.terminate(); + m_xrayProcess.disconnect(); + m_xrayProcess.kill(); + m_xrayProcess.waitForFinished(3000); if (m_t2sProcess) { m_t2sProcess->stop(); } -#ifdef Q_OS_WIN - Utils::signalCtrl(m_xrayProcess.processId(), CTRL_C_EVENT); -#endif + setConnectionState(Vpn::ConnectionState::Disconnected); } QString XrayProtocol::xrayExecPath() 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 From 62f3a339b7603fc1593face0c06b055a851b8167 Mon Sep 17 00:00:00 2001 From: Nethius Date: Wed, 8 Jan 2025 09:12:55 +0300 Subject: [PATCH 4/6] bugfix: ui fixes after merge with android tab navigation branch (#1339) * bugfix: ui fixes after merge with android tab navigation branch * bugfix: fix crash on quit * chore: fix typos * chore: remove useless comment * bugfix: fix trigger behavior for `ListViewWithRadioButtonType` * bugfix: fixed dropdown listview scrolling * bugfix: fixed amfree availability display * chore: remove item existence check in triggerCurrentItem function --------- Co-authored-by: Cyril Anisimov --- client/ui/controllers/focusController.cpp | 17 +++++----- client/ui/controllers/focusController.h | 10 +++--- client/ui/models/apiServicesModel.cpp | 4 +-- client/ui/qml/Controls2/DrawerType2.qml | 4 +-- client/ui/qml/Controls2/DropDownType.qml | 26 +++++----------- .../Controls2/ListViewWithRadioButtonType.qml | 2 ++ client/ui/qml/Controls2/PageType.qml | 1 - client/ui/qml/Pages2/PageHome.qml | 8 ++--- .../ui/qml/Pages2/PageProtocolAwgSettings.qml | 24 ++------------ .../Pages2/PageProtocolOpenVpnSettings.qml | 2 -- .../PageProtocolWireGuardClientSettings.qml | 2 -- .../Pages2/PageProtocolWireGuardSettings.qml | 20 ------------ .../Pages2/PageSettingsApiLanguageList.qml | 10 +++--- .../ui/qml/Pages2/PageSettingsApplication.qml | 7 ----- client/ui/qml/Pages2/PageSettingsDns.qml | 7 ----- client/ui/qml/Pages2/PageShare.qml | 31 ++++++++++++++++--- 16 files changed, 63 insertions(+), 112 deletions(-) diff --git a/client/ui/controllers/focusController.cpp b/client/ui/controllers/focusController.cpp index d32f7555..54bdc7d8 100644 --- a/client/ui/controllers/focusController.cpp +++ b/client/ui/controllers/focusController.cpp @@ -10,16 +10,15 @@ FocusController::FocusController(QQmlApplicationEngine *engine, QObject *parent) m_focusChain {}, m_focusedItem { nullptr }, m_rootObjects {}, - m_defaultFocusItem { QSharedPointer() }, + m_defaultFocusItem { nullptr }, m_lvfc { nullptr } { - QObject::connect(m_engine.get(), &QQmlApplicationEngine::objectCreated, this, - [this](QObject *object, const QUrl &url) { - QQuickItem *newDefaultFocusItem = object->findChild("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("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) diff --git a/client/ui/controllers/focusController.h b/client/ui/controllers/focusController.h index dfcac57a..11074dae 100644 --- a/client/ui/controllers/focusController.h +++ b/client/ui/controllers/focusController.h @@ -42,11 +42,11 @@ private: void focusPreviousListViewItem(); void dropListView(); - QSharedPointer m_engine; // Pointer to engine to get root object - QList m_focusChain; // List of current objects to be focused - QQuickItem *m_focusedItem; // Pointer to the active focus item - QStack m_rootObjects; - QSharedPointer m_defaultFocusItem; + QQmlApplicationEngine *m_engine; // Pointer to engine to get root object + QList m_focusChain; // List of current objects to be focused + QQuickItem *m_focusedItem; // Pointer to the active focus item + QStack m_rootObjects; // Pointer to stack of roots for focus chain + QQuickItem *m_defaultFocusItem; ListViewFocusController *m_lvfc; // ListView focus manager 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/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/Controls2/PageType.qml b/client/ui/qml/Controls2/PageType.qml index c2ed5197..d7f3317f 100644 --- a/client/ui/qml/Controls2/PageType.qml +++ b/client/ui/qml/Controls2/PageType.qml @@ -20,7 +20,6 @@ Item { id: timer interval: 200 // Milliseconds onTriggered: { - console.debug(">>> PageType timer triggered") FocusController.resetRootObject() FocusController.setFocusOnDefaultItem() } diff --git a/client/ui/qml/Pages2/PageHome.qml b/client/ui/qml/Pages2/PageHome.qml index d5cf8b6e..ae29b80c 100644 --- a/client/ui/qml/Pages2/PageHome.qml +++ b/client/ui/qml/Pages2/PageHome.qml @@ -266,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 @@ -288,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" : "" @@ -347,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 44cedc11..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() } @@ -138,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 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 d78ae6b9..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 68d9611d..f83d97fd 100644 --- a/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml +++ b/client/ui/qml/Pages2/PageProtocolWireGuardSettings.qml @@ -122,26 +122,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 - } - BasicButtonType { id: saveButton Layout.fillWidth: true 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/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) } From c3fb62a6ab57d9114ba63b2f7fd9c9ca8c08ccfa Mon Sep 17 00:00:00 2001 From: Mikhail Kiselev <73298492+sund3RRR@users.noreply.github.com> Date: Wed, 8 Jan 2025 10:38:53 +0300 Subject: [PATCH 5/6] fix: rewrite linux router dns flusher (#1335) Co-authored-by: sund3RRR --- service/server/router_linux.cpp | 22 +++++++++++++++------- service/server/router_linux.h | 1 + 2 files changed, 16 insertions(+), 7 deletions(-) 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; }; From e43aa02a5b7709ba8d4ccca9aec374466712e069 Mon Sep 17 00:00:00 2001 From: Nethius Date: Thu, 9 Jan 2025 09:33:35 +0300 Subject: [PATCH 6/6] chore: changed the icon for the settings section (#1348) --- client/ui/qml/Pages2/PageStart.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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