mirror of
https://github.com/amnezia-vpn/amnezia-client.git
synced 2026-06-22 02:01:08 +07:00
feat: Update local proxy settings page
This commit is contained in:
@@ -81,7 +81,7 @@ PageType {
|
||||
|
||||
text: qsTr("Local proxy")
|
||||
descriptionText: SettingsController.isLocalProxyHttpEnabled ? qsTr("Running: 127.0.0.1:%1").arg(SettingsController.localProxyPort || 0)
|
||||
: qsTr("Disabled")
|
||||
: qsTr("Off")
|
||||
rightImageSource: "qrc:/images/controls/chevron-right.svg"
|
||||
|
||||
clickedFunction: function() {
|
||||
|
||||
@@ -8,12 +8,98 @@ import Style 1.0
|
||||
import "./"
|
||||
import "../Controls2"
|
||||
import "../Controls2/TextTypes"
|
||||
import "../Config"
|
||||
|
||||
PageType {
|
||||
id: root
|
||||
|
||||
readonly property int localProxyPortMin: 1024
|
||||
readonly property int localProxyPortMax: 65535
|
||||
readonly property int defaultLocalProxyPort: 10808
|
||||
|
||||
property bool portValidationEnabled: false
|
||||
property string portValidationError: ""
|
||||
property bool suppressToggleHandler: false
|
||||
|
||||
Component.onCompleted: root.syncSwitchState()
|
||||
|
||||
function computePortErrorText() {
|
||||
const text = portField.textField.text.trim()
|
||||
if (text === "") {
|
||||
return qsTr("Enter a port")
|
||||
}
|
||||
const value = parseInt(text)
|
||||
if (isNaN(value) || value < root.localProxyPortMin || value > root.localProxyPortMax) {
|
||||
return qsTr("Port must be between %1 and %2")
|
||||
.arg(root.localProxyPortMin)
|
||||
.arg(root.localProxyPortMax)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
function updatePortValidation(force) {
|
||||
if (force) {
|
||||
root.portValidationEnabled = true
|
||||
}
|
||||
root.portValidationError = root.portValidationEnabled ? root.computePortErrorText() : ""
|
||||
}
|
||||
|
||||
function isPortValid() {
|
||||
return root.computePortErrorText() === ""
|
||||
}
|
||||
|
||||
function syncSwitchState() {
|
||||
setSwitcherChecked(SettingsController.isLocalProxyHttpEnabled)
|
||||
}
|
||||
|
||||
function setSwitcherChecked(value) {
|
||||
if (localProxyHeader.switcher.checked === value) {
|
||||
return
|
||||
}
|
||||
root.suppressToggleHandler = true
|
||||
localProxyHeader.switcher.checked = value
|
||||
}
|
||||
|
||||
function handleLocalProxyToggle(checked) {
|
||||
if (checked) {
|
||||
const serverUuid = ServersModel.processedServerUuid
|
||||
if (!serverUuid) {
|
||||
root.setSwitcherChecked(false)
|
||||
PageController.showNotificationMessage(qsTr("Unable to determine the current server"))
|
||||
return
|
||||
}
|
||||
|
||||
if (SettingsController.isLocalProxyHttpEnabled
|
||||
&& SettingsController.localProxyOwnerUuid
|
||||
&& SettingsController.localProxyOwnerUuid !== serverUuid) {
|
||||
root.setSwitcherChecked(false)
|
||||
PageController.showNotificationMessage(qsTr("Local proxy is already enabled for another server"))
|
||||
return
|
||||
}
|
||||
|
||||
const requestedPort = portField.portValue()
|
||||
if (requestedPort < root.localProxyPortMin || requestedPort > root.localProxyPortMax) {
|
||||
root.setSwitcherChecked(false)
|
||||
PageController.showNotificationMessage(qsTr("Port must be between %1 and %2")
|
||||
.arg(root.localProxyPortMin)
|
||||
.arg(root.localProxyPortMax))
|
||||
return
|
||||
}
|
||||
|
||||
if (!SettingsController.enableLocalProxy(serverUuid, requestedPort)) {
|
||||
root.setSwitcherChecked(false)
|
||||
PageController.showNotificationMessage(qsTr("Failed to enable local proxy. Check the port (%1-%2).")
|
||||
.arg(root.localProxyPortMin)
|
||||
.arg(root.localProxyPortMax))
|
||||
root.syncSwitchState()
|
||||
return
|
||||
}
|
||||
root.syncSwitchState()
|
||||
} else {
|
||||
SettingsController.disableLocalProxy()
|
||||
root.syncSwitchState()
|
||||
}
|
||||
}
|
||||
|
||||
BackButtonType {
|
||||
id: backButton
|
||||
@@ -41,11 +127,48 @@ PageType {
|
||||
header: ColumnLayout {
|
||||
width: listView.width
|
||||
|
||||
BaseHeaderType {
|
||||
HeaderTypeWithSwitcher {
|
||||
id: localProxyHeader
|
||||
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
headerText: qsTr("Local proxy")
|
||||
headerText: qsTr("Local Proxy")
|
||||
descriptionText: qsTr("Use a proxy to route selected apps (for example, the CensorTracker extension) through Amnezia Premium.")
|
||||
showSwitcher: true
|
||||
switcherFunction: function(checked) {
|
||||
if (root.suppressToggleHandler) {
|
||||
root.suppressToggleHandler = false
|
||||
return
|
||||
}
|
||||
root.handleLocalProxyToggle(checked)
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
Layout.fillWidth: true
|
||||
Layout.topMargin: 8
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("Only one can be on at a time: VPN or local proxy.")
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.topMargin: 8
|
||||
Layout.leftMargin: 8
|
||||
implicitHeight: 32
|
||||
|
||||
defaultColor: AmneziaStyle.color.transparent
|
||||
hoveredColor: AmneziaStyle.color.translucentWhite
|
||||
pressedColor: AmneziaStyle.color.sheerWhite
|
||||
disabledColor: AmneziaStyle.color.mutedGray
|
||||
textColor: AmneziaStyle.color.goldenApricot
|
||||
|
||||
text: qsTr("Learn more")
|
||||
clickedFunc: function() {
|
||||
Qt.openUrlExternally(LanguageModel.getCurrentSiteUrl())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,79 +178,6 @@ PageType {
|
||||
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
|
||||
console.log("serverUuid", serverUuid)
|
||||
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))
|
||||
localProxySwitch.syncState()
|
||||
return
|
||||
}
|
||||
localProxySwitch.syncState()
|
||||
} else {
|
||||
SettingsController.disableLocalProxy()
|
||||
localProxySwitch.syncState()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DividerType {}
|
||||
|
||||
TextFieldWithHeaderType {
|
||||
id: portField
|
||||
|
||||
@@ -135,14 +185,25 @@ PageType {
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
headerText: qsTr("Local proxy port")
|
||||
headerText: qsTr("Address and port")
|
||||
buttonText: qsTr("Copy")
|
||||
errorText: root.portValidationError
|
||||
|
||||
enabled: true
|
||||
rightButtonClickedOnEnter: true
|
||||
|
||||
clickedFunc: function() {
|
||||
const portText = portField.effectivePortText()
|
||||
GC.copyToClipBoard("127.0.0.1:" + portText)
|
||||
}
|
||||
|
||||
textField.validator: IntValidator {
|
||||
bottom: root.localProxyPortMin
|
||||
top: root.localProxyPortMax
|
||||
}
|
||||
textField.leftPadding: portPrefix.implicitWidth + 8
|
||||
textField.placeholderText: root.defaultLocalProxyPort.toString()
|
||||
textField.inputMethodHints: Qt.ImhDigitsOnly | Qt.ImhNoPredictiveText
|
||||
|
||||
function syncPortValue() {
|
||||
const port = SettingsController.localProxyPort
|
||||
@@ -154,35 +215,61 @@ PageType {
|
||||
return isNaN(value) ? -1 : value
|
||||
}
|
||||
|
||||
function effectivePortText() {
|
||||
const value = portValue()
|
||||
if (value >= root.localProxyPortMin && value <= root.localProxyPortMax) {
|
||||
return value.toString()
|
||||
}
|
||||
const fallback = SettingsController.localProxyPort
|
||||
if (fallback >= root.localProxyPortMin && fallback <= root.localProxyPortMax) {
|
||||
return fallback.toString()
|
||||
}
|
||||
return root.defaultLocalProxyPort.toString()
|
||||
}
|
||||
|
||||
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
|
||||
textField.onTextChanged: root.updatePortValidation(false)
|
||||
textField.onActiveFocusChanged: {
|
||||
if (!textField.activeFocus) {
|
||||
root.updatePortValidation(true)
|
||||
}
|
||||
|
||||
if (!SettingsController.setLocalProxyPort(value)) {
|
||||
PageController.showNotificationMessage(qsTr("Failed to save port. Valid range: %1-%2")
|
||||
.arg(root.localProxyPortMin)
|
||||
.arg(root.localProxyPortMax))
|
||||
|
||||
}
|
||||
|
||||
portField.syncPortValue()
|
||||
}
|
||||
}
|
||||
|
||||
ParagraphTextType {
|
||||
LabelTextType {
|
||||
id: portPrefix
|
||||
|
||||
parent: portField
|
||||
text: "127.0.0.1:"
|
||||
color: AmneziaStyle.color.paleGray
|
||||
z: 1
|
||||
|
||||
anchors.left: portField.textField.left
|
||||
anchors.verticalCenter: portField.textField.verticalCenter
|
||||
}
|
||||
|
||||
BasicButtonType {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: 16
|
||||
Layout.rightMargin: 16
|
||||
|
||||
text: qsTr("SOCKS inbound listens on the specified port. Connect your client to 127.0.0.1.")
|
||||
text: qsTr("Save")
|
||||
enabled: root.isPortValid()
|
||||
|
||||
clickedFunc: function() {
|
||||
root.updatePortValidation(true)
|
||||
if (!root.isPortValid()) {
|
||||
return
|
||||
}
|
||||
const value = portField.portValue()
|
||||
if (!SettingsController.setLocalProxyPort(value)) {
|
||||
PageController.showNotificationMessage(qsTr("Failed to save port. Valid range: %1-%2")
|
||||
.arg(root.localProxyPortMin)
|
||||
.arg(root.localProxyPortMax))
|
||||
}
|
||||
portField.syncPortValue()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -191,7 +278,7 @@ PageType {
|
||||
target: SettingsController
|
||||
|
||||
function onLocalProxySettingsUpdated() {
|
||||
localProxySwitch.syncState()
|
||||
root.syncSwitchState()
|
||||
if (!portField.textField.activeFocus) {
|
||||
portField.syncPortValue()
|
||||
}
|
||||
@@ -199,7 +286,7 @@ PageType {
|
||||
|
||||
function onLocalProxyStartFailed(message) {
|
||||
PageController.showNotificationMessage(message)
|
||||
localProxySwitch.syncState()
|
||||
root.syncSwitchState()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -207,7 +294,7 @@ PageType {
|
||||
target: ServersModel
|
||||
|
||||
function onProcessedServerChanged() {
|
||||
localProxySwitch.syncState()
|
||||
root.syncSwitchState()
|
||||
if (!portField.textField.activeFocus) {
|
||||
portField.syncPortValue()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user