mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-23 02:00:20 +07:00
feat: implement local proxy settings UI and functionality
- Added new QML pages for managing local proxy settings and connection types. - Updated SettingsController to handle local proxy enablement and port configuration. - Enhanced server model to include processed server UUID for local proxy management.
This commit is contained in:
@@ -253,6 +253,8 @@
|
|||||||
<file>ui/qml/Components/AwgTextField.qml</file>
|
<file>ui/qml/Components/AwgTextField.qml</file>
|
||||||
<file>ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml</file>
|
<file>ui/qml/Pages2/PageSettingsApiSubscriptionKey.qml</file>
|
||||||
<file>ui/qml/Components/SmartScroll.qml</file>
|
<file>ui/qml/Components/SmartScroll.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageSettingsConnectionType.qml</file>
|
||||||
|
<file>ui/qml/Pages2/PageSettingsLocalProxy.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/countriesFlags">
|
<qresource prefix="/countriesFlags">
|
||||||
<file>images/flagKit/ZW.svg</file>
|
<file>images/flagKit/ZW.svg</file>
|
||||||
|
|||||||
@@ -42,6 +42,8 @@ namespace PageLoader
|
|||||||
PageSettingsApiDevices,
|
PageSettingsApiDevices,
|
||||||
PageSettingsApiSubscriptionKey,
|
PageSettingsApiSubscriptionKey,
|
||||||
PageSettingsKillSwitchExceptions,
|
PageSettingsKillSwitchExceptions,
|
||||||
|
PageSettingsConnectionType,
|
||||||
|
PageSettingsLocalProxy,
|
||||||
|
|
||||||
PageServiceSftpSettings,
|
PageServiceSftpSettings,
|
||||||
PageServiceTorWebsiteSettings,
|
PageServiceTorWebsiteSettings,
|
||||||
|
|||||||
@@ -16,6 +16,11 @@
|
|||||||
#include <AmneziaVPN-Swift.h>
|
#include <AmneziaVPN-Swift.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
constexpr int kLocalProxyPortMin = 1024;
|
||||||
|
constexpr int kLocalProxyPortMax = 65535;
|
||||||
|
}
|
||||||
|
|
||||||
SettingsController::SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
SettingsController::SettingsController(const QSharedPointer<ServersModel> &serversModel,
|
||||||
const QSharedPointer<ContainersModel> &containersModel,
|
const QSharedPointer<ContainersModel> &containersModel,
|
||||||
const QSharedPointer<LanguageModel> &languageModel,
|
const QSharedPointer<LanguageModel> &languageModel,
|
||||||
@@ -49,6 +54,8 @@ SettingsController::SettingsController(const QSharedPointer<ServersModel> &serve
|
|||||||
|
|
||||||
m_isDevModeEnabled = m_settings->isDevGatewayEnv();
|
m_isDevModeEnabled = m_settings->isDevGatewayEnv();
|
||||||
toggleDevGatewayEnv(m_isDevModeEnabled);
|
toggleDevGatewayEnv(m_isDevModeEnabled);
|
||||||
|
|
||||||
|
connect(m_settings.get(), &Settings::localProxySettingsChanged, this, &SettingsController::localProxySettingsUpdated);
|
||||||
}
|
}
|
||||||
|
|
||||||
QString getPlatformName()
|
QString getPlatformName()
|
||||||
@@ -523,3 +530,57 @@ void SettingsController::disableHomeAdLabel()
|
|||||||
m_settings->disableHomeAdLabel();
|
m_settings->disableHomeAdLabel();
|
||||||
emit isHomeAdLabelVisibleChanged(false);
|
emit isHomeAdLabelVisibleChanged(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool SettingsController::isLocalProxyHttpEnabled() const
|
||||||
|
{
|
||||||
|
return m_settings->isLocalProxyHttpEnabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
int SettingsController::localProxyPort() const
|
||||||
|
{
|
||||||
|
return static_cast<int>(m_settings->localProxyPort());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString SettingsController::localProxyOwnerUuid() const
|
||||||
|
{
|
||||||
|
return m_settings->localProxyOwnerUuid();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SettingsController::setLocalProxyPort(int port)
|
||||||
|
{
|
||||||
|
if (port < kLocalProxyPortMin || port > kLocalProxyPortMax) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_settings->localProxyPort() == static_cast<quint16>(port)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settings->setLocalProxyPort(static_cast<quint16>(port));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SettingsController::enableLocalProxy(const QString &ownerUuid, int port)
|
||||||
|
{
|
||||||
|
if (port < kLocalProxyPortMin || port > kLocalProxyPortMax || ownerUuid.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_settings->isLocalProxyHttpEnabled() && m_settings->localProxyOwnerUuid() != ownerUuid) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_settings->setLocalProxyOwnerUuid(ownerUuid);
|
||||||
|
setLocalProxyPort(port);
|
||||||
|
m_settings->setLocalProxyHttpEnabled(true);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SettingsController::disableLocalProxy()
|
||||||
|
{
|
||||||
|
if (m_settings->isLocalProxyHttpEnabled()) {
|
||||||
|
m_settings->setLocalProxyHttpEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -36,6 +36,9 @@ public:
|
|||||||
Q_PROPERTY(int safeAreaTopMargin READ getSafeAreaTopMargin NOTIFY safeAreaTopMarginChanged)
|
Q_PROPERTY(int safeAreaTopMargin READ getSafeAreaTopMargin NOTIFY safeAreaTopMarginChanged)
|
||||||
Q_PROPERTY(int safeAreaBottomMargin READ getSafeAreaBottomMargin NOTIFY safeAreaBottomMarginChanged)
|
Q_PROPERTY(int safeAreaBottomMargin READ getSafeAreaBottomMargin NOTIFY safeAreaBottomMarginChanged)
|
||||||
Q_PROPERTY(int imeHeight READ getImeHeight NOTIFY imeHeightChanged)
|
Q_PROPERTY(int imeHeight READ getImeHeight NOTIFY imeHeightChanged)
|
||||||
|
Q_PROPERTY(bool isLocalProxyHttpEnabled READ isLocalProxyHttpEnabled NOTIFY localProxySettingsUpdated)
|
||||||
|
Q_PROPERTY(int localProxyPort READ localProxyPort WRITE setLocalProxyPort NOTIFY localProxySettingsUpdated)
|
||||||
|
Q_PROPERTY(QString localProxyOwnerUuid READ localProxyOwnerUuid NOTIFY localProxySettingsUpdated)
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void toggleAmneziaDns(bool enable);
|
void toggleAmneziaDns(bool enable);
|
||||||
@@ -109,6 +112,13 @@ public slots:
|
|||||||
bool isHomeAdLabelVisible();
|
bool isHomeAdLabelVisible();
|
||||||
void disableHomeAdLabel();
|
void disableHomeAdLabel();
|
||||||
|
|
||||||
|
bool isLocalProxyHttpEnabled() const;
|
||||||
|
int localProxyPort() const;
|
||||||
|
QString localProxyOwnerUuid() const;
|
||||||
|
bool setLocalProxyPort(int port);
|
||||||
|
bool enableLocalProxy(const QString &ownerUuid, int port);
|
||||||
|
void disableLocalProxy();
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void primaryDnsChanged();
|
void primaryDnsChanged();
|
||||||
void secondaryDnsChanged();
|
void secondaryDnsChanged();
|
||||||
@@ -140,6 +150,7 @@ signals:
|
|||||||
|
|
||||||
void isHomeAdLabelVisibleChanged(bool visible);
|
void isHomeAdLabelVisibleChanged(bool visible);
|
||||||
void startMinimizedChanged();
|
void startMinimizedChanged();
|
||||||
|
void localProxySettingsUpdated();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<ServersModel> m_serversModel;
|
QSharedPointer<ServersModel> m_serversModel;
|
||||||
|
|||||||
@@ -984,3 +984,9 @@ QString ServersModel::getServerUuid(int index) const
|
|||||||
return QString();
|
return QString();
|
||||||
return m_servers.at(index).toObject().value(config_key::server_uuid).toString();
|
return m_servers.at(index).toObject().value(config_key::server_uuid).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString ServersModel::getProcessedServerUuid() const
|
||||||
|
{
|
||||||
|
return getServerUuid(m_processedServerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,7 @@ public:
|
|||||||
|
|
||||||
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
Q_PROPERTY(int processedIndex READ getProcessedServerIndex WRITE setProcessedServerIndex NOTIFY processedServerIndexChanged)
|
||||||
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerChanged)
|
Q_PROPERTY(bool processedServerIsPremium READ processedServerIsPremium NOTIFY processedServerChanged)
|
||||||
|
Q_PROPERTY(QString processedServerUuid READ getProcessedServerUuid NOTIFY processedServerChanged)
|
||||||
|
|
||||||
Q_PROPERTY(bool isAdVisible READ isAdVisible NOTIFY defaultServerIndexChanged)
|
Q_PROPERTY(bool isAdVisible READ isAdVisible NOTIFY defaultServerIndexChanged)
|
||||||
Q_PROPERTY(QString adHeader READ adHeader NOTIFY defaultServerIndexChanged)
|
Q_PROPERTY(QString adHeader READ adHeader NOTIFY defaultServerIndexChanged)
|
||||||
@@ -161,6 +162,8 @@ public slots:
|
|||||||
|
|
||||||
QString getServerUuid(int index) const;
|
QString getServerUuid(int index) const;
|
||||||
|
|
||||||
|
QString getProcessedServerUuid() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
QHash<int, QByteArray> roleNames() const override;
|
QHash<int, QByteArray> roleNames() const override;
|
||||||
|
|
||||||
|
|||||||
@@ -151,32 +151,6 @@ PageType {
|
|||||||
|
|
||||||
readonly property bool isVisibleForAmneziaFree: ApiAccountInfoModel.data("isComponentVisible")
|
readonly property bool isVisibleForAmneziaFree: ApiAccountInfoModel.data("isComponentVisible")
|
||||||
|
|
||||||
SwitcherType {
|
|
||||||
id: switcher
|
|
||||||
|
|
||||||
readonly property bool isVlessProtocol: ApiConfigsController.isVlessProtocol()
|
|
||||||
|
|
||||||
Layout.fillWidth: true
|
|
||||||
Layout.topMargin: 24
|
|
||||||
Layout.rightMargin: 16
|
|
||||||
Layout.leftMargin: 16
|
|
||||||
|
|
||||||
visible: ApiAccountInfoModel.data("isProtocolSelectionSupported")
|
|
||||||
|
|
||||||
text: qsTr("Use VLESS protocol")
|
|
||||||
checked: switcher.isVlessProtocol
|
|
||||||
onToggled: function() {
|
|
||||||
if (ServersModel.isDefaultServerCurrentlyProcessed() && ConnectionController.isConnected) {
|
|
||||||
PageController.showNotificationMessage(qsTr("Cannot change protocol during active connection"))
|
|
||||||
} else {
|
|
||||||
PageController.showBusyIndicator(true)
|
|
||||||
ApiConfigsController.setCurrentProtocol(switcher.isVlessProtocol ? "awg" : "vless")
|
|
||||||
ApiConfigsController.updateServiceFromGateway(ServersModel.processedIndex, "", "", true)
|
|
||||||
PageController.showBusyIndicator(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
WarningType {
|
WarningType {
|
||||||
id: warning
|
id: warning
|
||||||
|
|
||||||
@@ -201,11 +175,25 @@ PageType {
|
|||||||
}
|
}
|
||||||
|
|
||||||
LabelWithButtonType {
|
LabelWithButtonType {
|
||||||
id: vpnKey
|
id: connectionSwitcher
|
||||||
|
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
Layout.topMargin: warning.visible ? 16 : 32
|
Layout.topMargin: warning.visible ? 16 : 32
|
||||||
|
text: qsTr("Connection")
|
||||||
|
descriptionText: qsTr("Protocol selection and local proxy setup")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
PageController.goToPage(PageEnum.PageSettingsConnectionType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
id: vpnKey
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
visible: footer.isVisibleForAmneziaFree
|
visible: footer.isVisibleForAmneziaFree
|
||||||
|
|
||||||
text: qsTr("Subscription Key")
|
text: qsTr("Subscription Key")
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
import Style 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Config"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if(backButton.enabled && backButton.activeFocus) {
|
||||||
|
listView.positionViewAtBeginning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListViewType {
|
||||||
|
id: listView
|
||||||
|
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
header: ColumnLayout {
|
||||||
|
width: listView.width
|
||||||
|
|
||||||
|
BaseHeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("Connection")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: 1
|
||||||
|
|
||||||
|
delegate: ColumnLayout {
|
||||||
|
width: listView.width
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
id: vpnProtocolButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.topMargin: 16
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("VPN protocol")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
PageController.goToPage(PageEnum.PageSettingsConnectionProtocols)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
|
|
||||||
|
LabelWithButtonType {
|
||||||
|
id: localProxyButton
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("Local proxy")
|
||||||
|
descriptionText: SettingsController.isLocalProxyHttpEnabled ? qsTr("Running: 127.0.0.1:%1").arg(SettingsController.localProxyPort || 0)
|
||||||
|
: qsTr("Disabled")
|
||||||
|
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||||
|
|
||||||
|
clickedFunction: function() {
|
||||||
|
PageController.goToPage(PageEnum.PageSettingsLocalProxy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,207 @@
|
|||||||
|
import QtQuick
|
||||||
|
import QtQuick.Controls
|
||||||
|
import QtQuick.Layouts
|
||||||
|
|
||||||
|
import PageEnum 1.0
|
||||||
|
import Style 1.0
|
||||||
|
|
||||||
|
import "./"
|
||||||
|
import "../Controls2"
|
||||||
|
import "../Controls2/TextTypes"
|
||||||
|
|
||||||
|
PageType {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
readonly property int localProxyPortMin: 1024
|
||||||
|
readonly property int localProxyPortMax: 65535
|
||||||
|
|
||||||
|
BackButtonType {
|
||||||
|
id: backButton
|
||||||
|
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.topMargin: 20 + SettingsController.safeAreaTopMargin
|
||||||
|
|
||||||
|
onActiveFocusChanged: {
|
||||||
|
if (activeFocus) {
|
||||||
|
listView.positionViewAtBeginning()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ListViewType {
|
||||||
|
id: listView
|
||||||
|
|
||||||
|
anchors.top: backButton.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.right: parent.right
|
||||||
|
|
||||||
|
header: ColumnLayout {
|
||||||
|
width: listView.width
|
||||||
|
|
||||||
|
BaseHeaderType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
headerText: qsTr("Local proxy")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
model: 1 // fake model to force the ListView to be created without a model
|
||||||
|
|
||||||
|
delegate: ColumnLayout {
|
||||||
|
width: listView.width
|
||||||
|
spacing: 16
|
||||||
|
|
||||||
|
SwitcherType {
|
||||||
|
id: localProxySwitch
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.margins: 16
|
||||||
|
|
||||||
|
property string statusText: ""
|
||||||
|
|
||||||
|
text: qsTr("Enable local proxy")
|
||||||
|
descriptionText: statusText
|
||||||
|
|
||||||
|
checked: SettingsController.isLocalProxyHttpEnabled
|
||||||
|
|
||||||
|
function computeStatusText() {
|
||||||
|
statusText = SettingsController.isLocalProxyHttpEnabled
|
||||||
|
? qsTr("Running: 127.0.0.1:%1").arg(SettingsController.localProxyPort || 0)
|
||||||
|
: qsTr("Disabled")
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncState() {
|
||||||
|
computeStatusText()
|
||||||
|
if (checked !== SettingsController.isLocalProxyHttpEnabled) {
|
||||||
|
checked = SettingsController.isLocalProxyHttpEnabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: syncState()
|
||||||
|
|
||||||
|
onToggled: function() {
|
||||||
|
if (checked) {
|
||||||
|
const serverUuid = ServersModel.processedServerUuid
|
||||||
|
if (!serverUuid) {
|
||||||
|
checked = false
|
||||||
|
PageController.showNotificationMessage(qsTr("Unable to determine the current server"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (SettingsController.isLocalProxyHttpEnabled
|
||||||
|
&& SettingsController.localProxyOwnerUuid
|
||||||
|
&& SettingsController.localProxyOwnerUuid !== serverUuid) {
|
||||||
|
checked = false
|
||||||
|
PageController.showNotificationMessage(qsTr("Local proxy is already enabled for another server"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const requestedPort = portField.portValue()
|
||||||
|
if (requestedPort < root.localProxyPortMin || requestedPort > root.localProxyPortMax) {
|
||||||
|
checked = false
|
||||||
|
PageController.showNotificationMessage(qsTr("Port must be between %1 and %2")
|
||||||
|
.arg(root.localProxyPortMin)
|
||||||
|
.arg(root.localProxyPortMax))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SettingsController.enableLocalProxy(serverUuid, requestedPort)) {
|
||||||
|
checked = false
|
||||||
|
PageController.showNotificationMessage(qsTr("Failed to enable local proxy. Check the port (%1-%2).")
|
||||||
|
.arg(root.localProxyPortMin)
|
||||||
|
.arg(root.localProxyPortMax))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
SettingsController.disableLocalProxy()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DividerType {}
|
||||||
|
|
||||||
|
TextFieldWithHeaderType {
|
||||||
|
id: portField
|
||||||
|
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
headerText: qsTr("HTTP API port")
|
||||||
|
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
textField.validator: IntValidator {
|
||||||
|
bottom: root.localProxyPortMin
|
||||||
|
top: root.localProxyPortMax
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncPortValue() {
|
||||||
|
const port = SettingsController.localProxyPort
|
||||||
|
textField.text = (port >= root.localProxyPortMin && port <= root.localProxyPortMax) ? port.toString() : ""
|
||||||
|
}
|
||||||
|
|
||||||
|
function portValue() {
|
||||||
|
const value = parseInt(textField.text)
|
||||||
|
return isNaN(value) ? -1 : value
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: syncPortValue()
|
||||||
|
|
||||||
|
textField.onEditingFinished: {
|
||||||
|
const value = portField.portValue()
|
||||||
|
if (value < root.localProxyPortMin || value > root.localProxyPortMax) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Port must be between %1 and %2")
|
||||||
|
.arg(root.localProxyPortMin)
|
||||||
|
.arg(root.localProxyPortMax))
|
||||||
|
portField.syncPortValue()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!SettingsController.setLocalProxyPort(value)) {
|
||||||
|
PageController.showNotificationMessage(qsTr("Failed to save port. Valid range: %1-%2")
|
||||||
|
.arg(root.localProxyPortMin)
|
||||||
|
.arg(root.localProxyPortMax))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
portField.syncPortValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ParagraphTextType {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.leftMargin: 16
|
||||||
|
Layout.rightMargin: 16
|
||||||
|
|
||||||
|
text: qsTr("HTTP API controls Xray via /api/v1/up and /api/v1/down. SOCKS inbound stays on port 10808.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: SettingsController
|
||||||
|
|
||||||
|
function onLocalProxySettingsUpdated() {
|
||||||
|
localProxySwitch.syncState()
|
||||||
|
if (!portField.textField.activeFocus) {
|
||||||
|
portField.syncPortValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: ServersModel
|
||||||
|
|
||||||
|
function onProcessedServerChanged() {
|
||||||
|
localProxySwitch.syncState()
|
||||||
|
if (!portField.textField.activeFocus) {
|
||||||
|
portField.syncPortValue()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user