Compare commits
12 Commits
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
55
.github/ISSUE_TEMPLATE/bug_report.yml
vendored
@@ -1,23 +1,41 @@
|
||||
name: Bug report
|
||||
description: Create a report to help us improve
|
||||
title: "[BUG]"
|
||||
name: 问题反馈 / Bug report
|
||||
title: "[BUG] "
|
||||
description: 反馈你遇到的问题 / Report the issue you are experiencing
|
||||
labels: ["bug"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
- type: markdown
|
||||
attributes:
|
||||
label: Describe the bug
|
||||
description: A clear and concise description of what the bug is.
|
||||
value: |
|
||||
## 在提交问题之前,请确认以下事项:
|
||||
1. 请 **确保** 您已经查阅了 [Clash Verge Rev 官方文档](https://clash-verge-rev.github.io/guide.html) 以及 [常见问题](https://clash-verge-rev.github.io/faq.html)
|
||||
2. 请 **确保** [已有的问题](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue) 中没有人提交过相似issue,否则请在已有的issue下进行讨论
|
||||
3. 请 **务必** 给issue填写一个简洁明了的标题,以便他人快速检索
|
||||
4. 请 **务必** 先下载 [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) 版本测试,确保问题依然存在
|
||||
5. 请 **务必** 按照模板规范详细描述问题,否则issue将会被关闭
|
||||
## Before submitting the issue, please make sure of the following checklist:
|
||||
1. Please make sure you have read the [Clash Verge Rev official documentation](https://clash-verge-rev.github.io/guide.html) and [FAQ](https://clash-verge-rev.github.io/faq.html)
|
||||
2. Please make sure there is no similar issue in the [existing issues](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue), otherwise please discuss under the existing issue
|
||||
3. Please be sure to fill in a concise and clear title for the issue so that others can quickly search
|
||||
4. Please be sure to download the [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) version for testing to ensure that the problem still exists
|
||||
5. Please describe the problem in detail according to the template specification, otherwise the issue will be closed
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 问题描述 / Describe the bug
|
||||
description: 详细清晰地描述你遇到的问题 / A clear and concise description of what the bug is
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: To Reproduce
|
||||
description: Steps to reproduce the behavior.
|
||||
label: 复现步骤 / To Reproduce
|
||||
description: 请提供复现问题的步骤 / Steps to reproduce the behavior
|
||||
validations:
|
||||
required: true
|
||||
- type: dropdown
|
||||
attributes:
|
||||
label: Platform
|
||||
label: 操作系统 / OS
|
||||
options:
|
||||
- Windows
|
||||
- Linux
|
||||
@@ -26,20 +44,13 @@ body:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: System Version
|
||||
placeholder: "e.g. macOS 10.15.7"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
attributes:
|
||||
label: Software Version
|
||||
placeholder: "e.g. 1.4.3"
|
||||
label: 操作系统版本 / OS Version
|
||||
description: 请提供你的操作系统版本,Linux请额外提供桌面环境及窗口系统 / Please provide your OS version, for Linux, please also provide the desktop environment and window system
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Log
|
||||
description: "Log file content or screenshot"
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional Information
|
||||
label: 日志 / Log
|
||||
description: 请提供完整或相关部分的Debug日志 / Please provide the complete or relevant part of the Debug log
|
||||
validations:
|
||||
required: true
|
||||
|
||||
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
44
.github/ISSUE_TEMPLATE/feature_request.yml
vendored
@@ -1,27 +1,35 @@
|
||||
name: Feature request
|
||||
description: Suggest an idea for this project
|
||||
title: "[Feature]"
|
||||
name: 功能请求 / Feature request
|
||||
title: "[Feature] "
|
||||
description: 提出你的功能请求 / Propose your feature request
|
||||
labels: ["enhancement"]
|
||||
|
||||
body:
|
||||
- type: textarea
|
||||
- type: markdown
|
||||
attributes:
|
||||
label: Is your feature request related to a problem? Please describe.
|
||||
description: A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||
value: |
|
||||
## 在提交问题之前,请确认以下事项:
|
||||
1. 请 **确保** 您已经查阅了 [Clash Verge Rev 官方文档](https://clash-verge-rev.github.io/guide.html) 确认软件不存在类似的功能
|
||||
2. 请 **确保** [已有的问题](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue) 中没有人提交过相似issue,否则请在已有的issue下进行讨论
|
||||
3. 请 **务必** 给issue填写一个简洁明了的标题,以便他人快速检索
|
||||
4. 请 **务必** 先下载 [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) 版本测试,确保该功能还未实现
|
||||
5. 请 **务必** 按照模板规范详细描述问题,否则issue将会被关闭
|
||||
## Before submitting the issue, please make sure of the following checklist:
|
||||
1. Please make sure you have read the [Clash Verge Rev official documentation](https://clash-verge-rev.github.io/guide.html) to confirm that the software does not have similar functions
|
||||
2. Please make sure there is no similar issue in the [existing issues](https://github.com/clash-verge-rev/clash-verge-rev/issues?q=is%3Aissue), otherwise please discuss under the existing issue
|
||||
3. Please be sure to fill in a concise and clear title for the issue so that others can quickly search
|
||||
4. Please be sure to download the [Alpha](https://github.com/clash-verge-rev/clash-verge-rev/releases/tag/alpha) version for testing to ensure that the function has not been implemented
|
||||
5. Please describe the problem in detail according to the template specification, otherwise the issue will be closed
|
||||
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: 功能描述 / Feature description
|
||||
description: 详细清晰地描述你的功能请求 / A clear and concise description of what the feature is
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe the solution you'd like
|
||||
description: A clear and concise description of what you want to happen.
|
||||
label: 使用场景 / Use case
|
||||
description: 请描述你的功能请求的使用场景 / Please describe the use case of your feature request
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Describe alternatives you've considered
|
||||
description: A clear and concise description of any alternative solutions or features you've considered.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional context
|
||||
description: Add any other context or screenshots about the feature request here.
|
||||
|
||||
16
UPDATELOG.md
16
UPDATELOG.md
@@ -1,3 +1,19 @@
|
||||
## 1.5.10
|
||||
|
||||
### Features
|
||||
|
||||
- 优化 Linux 托盘菜单显示
|
||||
- 添加透明代理端口设置
|
||||
- 删除订阅前确认
|
||||
|
||||
### Bugs Fixes
|
||||
|
||||
- 删除 MacOS 程序坞图标
|
||||
- Windows 下 service 日志没有清理
|
||||
- MacOS 无法开启系统代理
|
||||
|
||||
---
|
||||
|
||||
## v1.5.9
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clash-verge",
|
||||
"version": "1.5.9",
|
||||
"version": "1.5.10",
|
||||
"license": "GPL-3.0-only",
|
||||
"scripts": {
|
||||
"dev": "tauri dev",
|
||||
|
||||
292
src-tauri/Cargo.lock
generated
292
src-tauri/Cargo.lock
generated
@@ -749,7 +749,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clash-verge"
|
||||
version = "1.5.9"
|
||||
version = "1.5.10"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto-launch",
|
||||
@@ -767,7 +767,7 @@ dependencies = [
|
||||
"parking_lot",
|
||||
"percent-encoding",
|
||||
"port_scanner",
|
||||
"reqwest",
|
||||
"reqwest 0.12.0",
|
||||
"runas",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2062,7 +2062,26 @@ dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"indexmap 2.2.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
"indexmap 2.2.5",
|
||||
"slab",
|
||||
"tokio",
|
||||
@@ -2113,7 +2132,7 @@ dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"headers-core",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"httpdate",
|
||||
"mime",
|
||||
"sha1",
|
||||
@@ -2125,7 +2144,7 @@ version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e7f66481bfee273957b1f20485a4ff3362987f85b2c236580d81b4eb7a326429"
|
||||
dependencies = [
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2189,6 +2208,17 @@ dependencies = [
|
||||
"itoa 1.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa 1.0.10",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "0.4.6"
|
||||
@@ -2196,7 +2226,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http 1.1.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http-body-util"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-core",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
@@ -2234,9 +2287,9 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"h2 0.3.24",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.6",
|
||||
"httparse",
|
||||
"httpdate",
|
||||
"itoa 1.0.10",
|
||||
@@ -2249,17 +2302,40 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.24.2"
|
||||
name = "hyper"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590"
|
||||
checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2 0.4.3",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"httparse",
|
||||
"itoa 1.0.10",
|
||||
"pin-project-lite",
|
||||
"smallvec",
|
||||
"tokio",
|
||||
"want",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-rustls"
|
||||
version = "0.26.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a0bea761b46ae2b24eb4aef630d8d1c398157b6fc29e6350ecf090a0b70c952c"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"http",
|
||||
"hyper",
|
||||
"http 1.1.0",
|
||||
"hyper 1.2.0",
|
||||
"hyper-util",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2269,12 +2345,48 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"hyper",
|
||||
"hyper 0.14.28",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"http-body-util",
|
||||
"hyper 1.2.0",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-util"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"hyper 1.2.0",
|
||||
"pin-project-lite",
|
||||
"socket2 0.5.5",
|
||||
"tokio",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iana-time-zone"
|
||||
version = "0.1.60"
|
||||
@@ -3027,7 +3139,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"httparse",
|
||||
"log 0.4.20",
|
||||
"memchr",
|
||||
@@ -4146,12 +4258,56 @@ dependencies = [
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"hyper",
|
||||
"h2 0.3.24",
|
||||
"http 0.2.11",
|
||||
"http-body 0.4.6",
|
||||
"hyper 0.14.28",
|
||||
"hyper-tls 0.5.0",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log 0.4.20",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"rustls-pemfile",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"winreg 0.50.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "reqwest"
|
||||
version = "0.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58b48d98d932f4ee75e541614d32a7f44c889b72bd9c2e04d95edd135989df88"
|
||||
dependencies = [
|
||||
"base64 0.21.7",
|
||||
"bytes",
|
||||
"encoding_rs",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2 0.4.3",
|
||||
"http 1.1.0",
|
||||
"http-body 1.0.0",
|
||||
"http-body-util",
|
||||
"hyper 1.2.0",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-tls 0.6.0",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log 0.4.20",
|
||||
@@ -4162,6 +4318,7 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
@@ -4170,12 +4327,10 @@ dependencies = [
|
||||
"tokio",
|
||||
"tokio-native-tls",
|
||||
"tokio-rustls",
|
||||
"tokio-util",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"winreg 0.50.0",
|
||||
@@ -4296,14 +4451,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.21.10"
|
||||
version = "0.22.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9d5a6813c0759e4609cd494e8e725babae6a2ca7b62a5536a13daaec6fcb7ba"
|
||||
checksum = "e87c9956bd9807afa1f77e0f7594af32566e830e088a5576d27c5b6f30f49d41"
|
||||
dependencies = [
|
||||
"log 0.4.20",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"sct",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4316,12 +4473,19 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.101.7"
|
||||
name = "rustls-pki-types"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765"
|
||||
checksum = "5ede67b28608b4c60685c7d54122d4400d90f62b40caee7700e700380a390fa8"
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faaa0a62740bedb9b2ef5afa303da42764c012f743917351dc9a237ea1663610"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
@@ -4379,16 +4543,6 @@ version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "sct"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"untrusted",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.9.2"
|
||||
@@ -4869,6 +5023,12 @@ version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
|
||||
|
||||
[[package]]
|
||||
name = "subtle"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.109"
|
||||
@@ -5086,7 +5246,7 @@ dependencies = [
|
||||
"glob",
|
||||
"gtk",
|
||||
"heck 0.4.1",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"ignore",
|
||||
"indexmap 1.9.3",
|
||||
"infer 0.9.0",
|
||||
@@ -5102,7 +5262,7 @@ dependencies = [
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
"regex 1.10.3",
|
||||
"reqwest",
|
||||
"reqwest 0.11.24",
|
||||
"rfd",
|
||||
"semver 1.0.21",
|
||||
"serde",
|
||||
@@ -5194,7 +5354,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cf2d0652aa2891ff3e9caa2401405257ea29ab8372cce01f186a5825f1bd0e76"
|
||||
dependencies = [
|
||||
"gtk",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"http-range",
|
||||
"rand 0.8.5",
|
||||
"raw-window-handle",
|
||||
@@ -5529,11 +5689,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.24.1"
|
||||
version = "0.25.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081"
|
||||
checksum = "775e0c0f0adb3a2f22a00c4745d728b479985fc15ee7ca6a2608388c5569860f"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
@@ -5642,6 +5803,28 @@ dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"pin-project",
|
||||
"pin-project-lite",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tower-layer"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0"
|
||||
|
||||
[[package]]
|
||||
name = "tower-service"
|
||||
version = "0.3.2"
|
||||
@@ -5748,7 +5931,7 @@ dependencies = [
|
||||
"byteorder",
|
||||
"bytes",
|
||||
"data-encoding",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"httparse",
|
||||
"log 0.4.20",
|
||||
"rand 0.8.5",
|
||||
@@ -5998,8 +6181,8 @@ dependencies = [
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"headers",
|
||||
"http",
|
||||
"hyper",
|
||||
"http 0.2.11",
|
||||
"hyper 0.14.28",
|
||||
"log 0.4.20",
|
||||
"mime",
|
||||
"mime_guess",
|
||||
@@ -6242,9 +6425,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.25.4"
|
||||
version = "0.26.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f20c57d8d7db6d3b86154206ae5d8fba62dd39573114de97c2cb0578251f8e1"
|
||||
checksum = "b3de34ae270483955a94f4b21bdaaeb83d508bb84a01435f393818edb0012009"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webview2-com"
|
||||
@@ -6815,7 +7001,7 @@ dependencies = [
|
||||
"glib",
|
||||
"gtk",
|
||||
"html5ever",
|
||||
"http",
|
||||
"http 0.2.11",
|
||||
"kuchikiki",
|
||||
"libc",
|
||||
"log 0.4.20",
|
||||
@@ -7031,6 +7217,12 @@ dependencies = [
|
||||
"synstructure",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zeroize"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
|
||||
|
||||
[[package]]
|
||||
name = "zerovec"
|
||||
version = "0.10.1"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clash-verge"
|
||||
version = "1.5.9"
|
||||
version = "1.5.10"
|
||||
description = "clash verge"
|
||||
authors = ["zzzgydi", "wonfen", "MystiPanda"]
|
||||
license = "GPL-3.0-only"
|
||||
@@ -34,7 +34,7 @@ percent-encoding = "2.3.1"
|
||||
window-shadows = { version = "0.2" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
|
||||
reqwest = { version = "0.12", features = ["json", "rustls-tls"] }
|
||||
sysproxy = { git="https://github.com/zzzgydi/sysproxy-rs", branch = "main" }
|
||||
auto-launch = { git="https://github.com/zzzgydi/auto-launch", branch = "main" }
|
||||
tauri = { version = "1.6", features = [ "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
|
||||
|
||||
@@ -39,7 +39,10 @@ impl IClashTemp {
|
||||
tun.insert("auto-detect-interface".into(), true.into());
|
||||
tun.insert("dns-hijack".into(), vec!["any:53"].into());
|
||||
tun.insert("mtu".into(), 9000.into());
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
map.insert("redir-port".into(), 7895.into());
|
||||
#[cfg(target_os = "linux")]
|
||||
map.insert("tproxy-port".into(), 7896.into());
|
||||
map.insert("mixed-port".into(), 7897.into());
|
||||
map.insert("socks-port".into(), 7898.into());
|
||||
map.insert("port".into(), 7899.into());
|
||||
@@ -54,11 +57,18 @@ impl IClashTemp {
|
||||
}
|
||||
|
||||
fn guard(mut config: Mapping) -> Mapping {
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
let redir_port = Self::guard_redir_port(&config);
|
||||
#[cfg(target_os = "linux")]
|
||||
let tproxy_port = Self::guard_tproxy_port(&config);
|
||||
let mixed_port = Self::guard_mixed_port(&config);
|
||||
let socks_port = Self::guard_socks_port(&config);
|
||||
let port = Self::guard_port(&config);
|
||||
let ctrl = Self::guard_server_ctrl(&config);
|
||||
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
config.insert("redir-port".into(), redir_port.into());
|
||||
#[cfg(target_os = "linux")]
|
||||
config.insert("tproxy-port".into(), tproxy_port.into());
|
||||
config.insert("mixed-port".into(), mixed_port.into());
|
||||
config.insert("socks-port".into(), socks_port.into());
|
||||
config.insert("port".into(), port.into());
|
||||
@@ -110,6 +120,37 @@ impl IClashTemp {
|
||||
}),
|
||||
}
|
||||
}
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub fn guard_redir_port(config: &Mapping) -> u16 {
|
||||
let mut port = config
|
||||
.get("redir-port")
|
||||
.and_then(|value| match value {
|
||||
Value::String(val_str) => val_str.parse().ok(),
|
||||
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or(7895);
|
||||
if port == 0 {
|
||||
port = 7895;
|
||||
}
|
||||
port
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub fn guard_tproxy_port(config: &Mapping) -> u16 {
|
||||
let mut port = config
|
||||
.get("tproxy-port")
|
||||
.and_then(|value| match value {
|
||||
Value::String(val_str) => val_str.parse().ok(),
|
||||
Value::Number(val_num) => val_num.as_u64().map(|u| u as u16),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or(7896);
|
||||
if port == 0 {
|
||||
port = 7896;
|
||||
}
|
||||
port
|
||||
}
|
||||
|
||||
pub fn guard_mixed_port(config: &Mapping) -> u16 {
|
||||
let mut port = config
|
||||
|
||||
@@ -126,7 +126,13 @@ pub struct IVerge {
|
||||
/// 是否启用随机端口
|
||||
pub enable_random_port: Option<bool>,
|
||||
|
||||
/// verge mixed port 用于覆盖 clash 的 mixed port
|
||||
/// verge 的各种 port 用于覆盖 clash 的各种 port
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
pub verge_redir_port: Option<u16>,
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
pub verge_tproxy_port: Option<u16>,
|
||||
|
||||
pub verge_mixed_port: Option<u16>,
|
||||
|
||||
pub verge_socks_port: Option<u16>,
|
||||
@@ -190,6 +196,10 @@ impl IVerge {
|
||||
enable_silent_start: Some(false),
|
||||
enable_system_proxy: Some(false),
|
||||
enable_random_port: Some(false),
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
verge_redir_port: Some(7895),
|
||||
#[cfg(target_os = "linux")]
|
||||
verge_tproxy_port: Some(7896),
|
||||
verge_mixed_port: Some(7897),
|
||||
verge_socks_port: Some(7898),
|
||||
verge_port: Some(7899),
|
||||
@@ -239,6 +249,10 @@ impl IVerge {
|
||||
patch!(enable_auto_launch);
|
||||
patch!(enable_silent_start);
|
||||
patch!(enable_random_port);
|
||||
#[cfg(not(target_os = "windows"))]
|
||||
patch!(verge_redir_port);
|
||||
#[cfg(target_os = "linux")]
|
||||
patch!(verge_tproxy_port);
|
||||
patch!(verge_mixed_port);
|
||||
patch!(verge_socks_port);
|
||||
patch!(verge_port);
|
||||
|
||||
@@ -130,6 +130,44 @@ impl Tray {
|
||||
let _ = tray.get_item("global_mode").set_selected(mode == "global");
|
||||
let _ = tray.get_item("direct_mode").set_selected(mode == "direct");
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
match mode.as_str() {
|
||||
"rule" => {
|
||||
let _ = tray
|
||||
.get_item("rule_mode")
|
||||
.set_title(t!("Rule Mode ✔", "规则模式 ✔"));
|
||||
let _ = tray
|
||||
.get_item("global_mode")
|
||||
.set_title(t!("Global Mode", "全局模式"));
|
||||
let _ = tray
|
||||
.get_item("direct_mode")
|
||||
.set_title(t!("Direct Mode", "直连模式"));
|
||||
}
|
||||
"global" => {
|
||||
let _ = tray
|
||||
.get_item("rule_mode")
|
||||
.set_title(t!("Rule Mode", "规则模式"));
|
||||
let _ = tray
|
||||
.get_item("global_mode")
|
||||
.set_title(t!("Global Mode ✔", "全局模式 ✔"));
|
||||
let _ = tray
|
||||
.get_item("direct_mode")
|
||||
.set_title(t!("Direct Mode", "直连模式"));
|
||||
}
|
||||
"direct" => {
|
||||
let _ = tray
|
||||
.get_item("rule_mode")
|
||||
.set_title(t!("Rule Mode", "规则模式"));
|
||||
let _ = tray
|
||||
.get_item("global_mode")
|
||||
.set_title(t!("Global Mode", "全局模式"));
|
||||
let _ = tray
|
||||
.get_item("direct_mode")
|
||||
.set_title(t!("Direct Mode ✔", "直连模式 ✔"));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
|
||||
let verge = Config::verge();
|
||||
let verge = verge.latest();
|
||||
let system_proxy = verge.enable_system_proxy.as_ref().unwrap_or(&false);
|
||||
@@ -182,6 +220,27 @@ impl Tray {
|
||||
|
||||
let _ = tray.get_item("system_proxy").set_selected(*system_proxy);
|
||||
let _ = tray.get_item("tun_mode").set_selected(*tun_mode);
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
if *system_proxy {
|
||||
let _ = tray
|
||||
.get_item("system_proxy")
|
||||
.set_title(t!("System Proxy ✔", "系统代理 ✔"));
|
||||
} else {
|
||||
let _ = tray
|
||||
.get_item("system_proxy")
|
||||
.set_title(t!("System Proxy", "系统代理"));
|
||||
}
|
||||
if *tun_mode {
|
||||
let _ = tray
|
||||
.get_item("tun_mode")
|
||||
.set_title(t!("TUN Mode ✔", "Tun 模式 ✔"));
|
||||
} else {
|
||||
let _ = tray
|
||||
.get_item("tun_mode")
|
||||
.set_title(t!("TUN Mode", "Tun 模式"));
|
||||
}
|
||||
}
|
||||
|
||||
let switch_map = {
|
||||
let mut map = std::collections::HashMap::new();
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use serde_yaml::{Mapping, Value};
|
||||
use std::collections::HashSet;
|
||||
|
||||
pub const HANDLE_FIELDS: [&str; 9] = [
|
||||
pub const HANDLE_FIELDS: [&str; 11] = [
|
||||
"mode",
|
||||
"redir-port",
|
||||
"tproxy-port",
|
||||
"mixed-port",
|
||||
"socks-port",
|
||||
"port",
|
||||
|
||||
@@ -107,6 +107,8 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
|
||||
Config::clash().draft().patch_config(patch.clone());
|
||||
|
||||
match {
|
||||
let redir_port = patch.get("redir-port");
|
||||
let tproxy_port = patch.get("tproxy-port");
|
||||
let mixed_port = patch.get("mixed-port");
|
||||
let socks_port = patch.get("socks-port");
|
||||
let port = patch.get("port");
|
||||
@@ -129,7 +131,9 @@ pub async fn patch_clash(patch: Mapping) -> Result<()> {
|
||||
};
|
||||
|
||||
// 激活订阅
|
||||
if mixed_port.is_some()
|
||||
if redir_port.is_some()
|
||||
|| tproxy_port.is_some()
|
||||
|| mixed_port.is_some()
|
||||
|| socks_port.is_some()
|
||||
|| port.is_some()
|
||||
|| patch.get("secret").is_some()
|
||||
|
||||
@@ -135,6 +135,13 @@ pub fn delete_log() -> Result<()> {
|
||||
for file in fs::read_dir(&log_dir)?.flatten() {
|
||||
let _ = process_file(file);
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let service_log_dir = log_dir.join("service");
|
||||
for file in fs::read_dir(&service_log_dir)?.flatten() {
|
||||
let _ = process_file(file);
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -35,6 +35,8 @@ pub fn find_unused_port() -> Result<u16> {
|
||||
|
||||
/// handle something when start app
|
||||
pub fn resolve_setup(app: &mut App) {
|
||||
#[cfg(target_os = "macos")]
|
||||
app.set_activation_policy(tauri::ActivationPolicy::Accessory);
|
||||
let version = app.package_info().version.to_string();
|
||||
handle::Handle::global().init(app.app_handle());
|
||||
VERSION.get_or_init(|| version.clone());
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "Clash Verge",
|
||||
"version": "1.5.9"
|
||||
"version": "1.5.10"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
|
||||
46
src/components/profile/confirm-viewer.tsx
Normal file
46
src/components/profile/confirm-viewer.tsx
Normal file
@@ -0,0 +1,46 @@
|
||||
import { useEffect, useRef } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import {
|
||||
Button,
|
||||
Dialog,
|
||||
DialogActions,
|
||||
DialogContent,
|
||||
DialogTitle,
|
||||
} from "@mui/material";
|
||||
|
||||
interface Props {
|
||||
open: boolean;
|
||||
title: string;
|
||||
message: string;
|
||||
onClose: () => void;
|
||||
onConfirm: () => void;
|
||||
}
|
||||
|
||||
export const ConfirmViewer = (props: Props) => {
|
||||
const { open, title, message, onClose, onConfirm } = props;
|
||||
|
||||
const { t } = useTranslation();
|
||||
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
}, [open]);
|
||||
|
||||
return (
|
||||
<Dialog open={open} onClose={onClose} maxWidth="xs" fullWidth>
|
||||
<DialogTitle>{t(title)}</DialogTitle>
|
||||
|
||||
<DialogContent sx={{ width: "95%", pb: 1, userSelect: "text" }}>
|
||||
{t(message)}
|
||||
</DialogContent>
|
||||
|
||||
<DialogActions>
|
||||
<Button onClick={onClose} variant="outlined">
|
||||
{t("Cancel")}
|
||||
</Button>
|
||||
<Button onClick={onConfirm} variant="contained">
|
||||
{t("Confirm")}
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
);
|
||||
};
|
||||
@@ -23,6 +23,7 @@ import { Notice } from "@/components/base";
|
||||
import { EditorViewer } from "./editor-viewer";
|
||||
import { ProfileBox } from "./profile-box";
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
import { ConfirmViewer } from "./confirm-viewer";
|
||||
|
||||
const round = keyframes`
|
||||
from { transform: rotate(0deg); }
|
||||
@@ -92,6 +93,7 @@ export const ProfileItem = (props: Props) => {
|
||||
}, [hasUrl, updated]);
|
||||
|
||||
const [fileOpen, setFileOpen] = useState(false);
|
||||
const [confirmOpen, setConfirmOpen] = useState(false);
|
||||
|
||||
const onEditInfo = () => {
|
||||
setAnchorEl(null);
|
||||
@@ -171,14 +173,26 @@ export const ProfileItem = (props: Props) => {
|
||||
{ label: "Open File", handler: onOpenFile },
|
||||
{ label: "Update", handler: () => onUpdate(0) },
|
||||
{ label: "Update(Proxy)", handler: () => onUpdate(2) },
|
||||
{ label: "Delete", handler: onDelete },
|
||||
{
|
||||
label: "Delete",
|
||||
handler: () => {
|
||||
setAnchorEl(null);
|
||||
setConfirmOpen(true);
|
||||
},
|
||||
},
|
||||
];
|
||||
const fileModeMenu = [
|
||||
{ label: "Select", handler: onForceSelect },
|
||||
{ label: "Edit Info", handler: onEditInfo },
|
||||
{ label: "Edit File", handler: onEditFile },
|
||||
{ label: "Open File", handler: onOpenFile },
|
||||
{ label: "Delete", handler: onDelete },
|
||||
{
|
||||
label: "Delete",
|
||||
handler: () => {
|
||||
setAnchorEl(null);
|
||||
setConfirmOpen(true);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const boxStyle = {
|
||||
@@ -341,7 +355,19 @@ export const ProfileItem = (props: Props) => {
|
||||
<MenuItem
|
||||
key={item.label}
|
||||
onClick={item.handler}
|
||||
sx={{ minWidth: 120 }}
|
||||
sx={[
|
||||
{
|
||||
minWidth: 120,
|
||||
},
|
||||
(theme) => {
|
||||
return {
|
||||
color:
|
||||
item.label === "Delete"
|
||||
? theme.palette.error.main
|
||||
: undefined,
|
||||
};
|
||||
},
|
||||
]}
|
||||
dense
|
||||
>
|
||||
{t(item.label)}
|
||||
@@ -355,6 +381,16 @@ export const ProfileItem = (props: Props) => {
|
||||
mode="yaml"
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
<ConfirmViewer
|
||||
title="Confirm deletion"
|
||||
message="This operation is not reversible"
|
||||
open={confirmOpen}
|
||||
onClose={() => setConfirmOpen(false)}
|
||||
onConfirm={() => {
|
||||
onDelete();
|
||||
setConfirmOpen(false);
|
||||
}}
|
||||
/>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -17,6 +17,7 @@ import { Notice } from "@/components/base";
|
||||
import { EditorViewer } from "./editor-viewer";
|
||||
import { ProfileBox } from "./profile-box";
|
||||
import { LogViewer } from "./log-viewer";
|
||||
import { ConfirmViewer } from "./confirm-viewer";
|
||||
|
||||
interface Props {
|
||||
selected: boolean;
|
||||
@@ -51,6 +52,7 @@ export const ProfileMore = (props: Props) => {
|
||||
const [anchorEl, setAnchorEl] = useState<any>(null);
|
||||
const [position, setPosition] = useState({ left: 0, top: 0 });
|
||||
const [fileOpen, setFileOpen] = useState(false);
|
||||
const [confirmOpen, setConfirmOpen] = useState(false);
|
||||
const [logOpen, setLogOpen] = useState(false);
|
||||
|
||||
const onEditInfo = () => {
|
||||
@@ -87,7 +89,13 @@ export const ProfileMore = (props: Props) => {
|
||||
{ label: "Open File", handler: onOpenFile },
|
||||
{ label: "To Top", show: showMove, handler: fnWrapper(onMoveTop) },
|
||||
{ label: "To End", show: showMove, handler: fnWrapper(onMoveEnd) },
|
||||
{ label: "Delete", handler: fnWrapper(onDelete) },
|
||||
{
|
||||
label: "Delete",
|
||||
handler: () => {
|
||||
setAnchorEl(null);
|
||||
setConfirmOpen(true);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const disableMenu = [
|
||||
@@ -95,7 +103,13 @@ export const ProfileMore = (props: Props) => {
|
||||
{ label: "Edit Info", handler: onEditInfo },
|
||||
{ label: "Edit File", handler: onEditFile },
|
||||
{ label: "Open File", handler: onOpenFile },
|
||||
{ label: "Delete", handler: fnWrapper(onDelete) },
|
||||
{
|
||||
label: "Delete",
|
||||
handler: () => {
|
||||
setAnchorEl(null);
|
||||
setConfirmOpen(true);
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
const boxStyle = {
|
||||
@@ -200,7 +214,17 @@ export const ProfileMore = (props: Props) => {
|
||||
<MenuItem
|
||||
key={item.label}
|
||||
onClick={item.handler}
|
||||
sx={{ minWidth: 120 }}
|
||||
sx={[
|
||||
{ minWidth: 120 },
|
||||
(theme) => {
|
||||
return {
|
||||
color:
|
||||
item.label === "Delete"
|
||||
? theme.palette.error.main
|
||||
: undefined,
|
||||
};
|
||||
},
|
||||
]}
|
||||
dense
|
||||
>
|
||||
{t(item.label)}
|
||||
@@ -214,7 +238,16 @@ export const ProfileMore = (props: Props) => {
|
||||
mode={type === "merge" ? "yaml" : "javascript"}
|
||||
onClose={() => setFileOpen(false)}
|
||||
/>
|
||||
|
||||
<ConfirmViewer
|
||||
title="Confirm deletion"
|
||||
message="This operation is not reversible"
|
||||
open={confirmOpen}
|
||||
onClose={() => setConfirmOpen(false)}
|
||||
onConfirm={() => {
|
||||
onDelete();
|
||||
setConfirmOpen(false);
|
||||
}}
|
||||
/>
|
||||
{selected && (
|
||||
<LogViewer
|
||||
open={logOpen}
|
||||
|
||||
@@ -76,7 +76,7 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
group.icon.trim().startsWith("http") && (
|
||||
<img
|
||||
src={iconCachePath === "" ? group.icon : iconCachePath}
|
||||
height="32px"
|
||||
width="32px"
|
||||
style={{ marginRight: "12px", borderRadius: "6px" }}
|
||||
/>
|
||||
)}
|
||||
@@ -85,7 +85,7 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
group.icon.trim().startsWith("data") && (
|
||||
<img
|
||||
src={group.icon}
|
||||
height="32px"
|
||||
width="32px"
|
||||
style={{ marginRight: "12px", borderRadius: "6px" }}
|
||||
/>
|
||||
)}
|
||||
@@ -94,7 +94,7 @@ export const ProxyRender = (props: RenderProps) => {
|
||||
group.icon.trim().startsWith("<svg") && (
|
||||
<img
|
||||
src={`data:image/svg+xml;base64,${btoa(group.icon)}`}
|
||||
height="32px"
|
||||
width="32px"
|
||||
/>
|
||||
)}
|
||||
<ListItemText
|
||||
|
||||
@@ -5,6 +5,8 @@ import { List, ListItem, ListItemText, TextField } from "@mui/material";
|
||||
import { useClashInfo } from "@/hooks/use-clash";
|
||||
import { BaseDialog, DialogRef, Notice } from "@/components/base";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import getSystem from "@/utils/get-system";
|
||||
const OS = getSystem();
|
||||
|
||||
export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -13,6 +15,12 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { verge, patchVerge } = useVerge();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [redirPort, setRedirPort] = useState(
|
||||
verge?.verge_redir_port ?? clashInfo?.redir_port ?? 7895
|
||||
);
|
||||
const [tproxyPort, setTproxyPort] = useState(
|
||||
verge?.verge_tproxy_port ?? clashInfo?.tproxy_port ?? 7896
|
||||
);
|
||||
const [mixedPort, setMixedPort] = useState(
|
||||
verge?.verge_mixed_port ?? clashInfo?.mixed_port ?? 7897
|
||||
);
|
||||
@@ -25,6 +33,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
if (verge?.verge_redir_port) setRedirPort(verge?.verge_redir_port);
|
||||
if (verge?.verge_tproxy_port) setTproxyPort(verge?.verge_tproxy_port);
|
||||
if (verge?.verge_mixed_port) setMixedPort(verge?.verge_mixed_port);
|
||||
if (verge?.verge_socks_port) setSocksPort(verge?.verge_socks_port);
|
||||
if (verge?.verge_port) setPort(verge?.verge_port);
|
||||
@@ -35,6 +45,8 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
|
||||
const onSave = useLockFn(async () => {
|
||||
if (
|
||||
redirPort === verge?.verge_redir_port &&
|
||||
tproxyPort === verge?.verge_tproxy_port &&
|
||||
mixedPort === verge?.verge_mixed_port &&
|
||||
socksPort === verge?.verge_socks_port &&
|
||||
port === verge?.verge_port
|
||||
@@ -42,7 +54,34 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
setOpen(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
OS === "linux" &&
|
||||
new Set([redirPort, tproxyPort, mixedPort, socksPort, port]).size !== 5
|
||||
) {
|
||||
Notice.error("Port conflict!", 4000);
|
||||
return;
|
||||
}
|
||||
if (
|
||||
OS === "macos" &&
|
||||
new Set([redirPort, mixedPort, socksPort, port]).size !== 4
|
||||
) {
|
||||
Notice.error("Port conflict!", 4000);
|
||||
return;
|
||||
}
|
||||
if (OS === "windows" && new Set([mixedPort, socksPort, port]).size !== 3) {
|
||||
Notice.error("Port conflict!", 4000);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
if (OS !== "windows") {
|
||||
await patchInfo({ "redir-port": redirPort });
|
||||
await patchVerge({ verge_redir_port: redirPort });
|
||||
}
|
||||
if (OS === "linux") {
|
||||
await patchInfo({ "tproxy-port": tproxyPort });
|
||||
await patchVerge({ verge_tproxy_port: tproxyPort });
|
||||
}
|
||||
await patchInfo({ "mixed-port": mixedPort });
|
||||
await patchInfo({ "socks-port": socksPort });
|
||||
await patchInfo({ port });
|
||||
@@ -68,6 +107,35 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
onOk={onSave}
|
||||
>
|
||||
<List>
|
||||
{OS !== "windows" && (
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Redir Port" />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
sx={{ width: 135 }}
|
||||
value={redirPort}
|
||||
onChange={(e) =>
|
||||
setRedirPort(+e.target.value?.replace(/\D+/, "").slice(0, 5))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
)}
|
||||
{OS === "linux" && (
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Tproxy Port" />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
sx={{ width: 135 }}
|
||||
value={tproxyPort}
|
||||
onChange={(e) =>
|
||||
setTproxyPort(+e.target.value?.replace(/\D+/, "").slice(0, 5))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
)}
|
||||
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Mixed Port" />
|
||||
<TextField
|
||||
|
||||
@@ -49,11 +49,19 @@ export const useClashInfo = () => {
|
||||
patch: Partial<
|
||||
Pick<
|
||||
IConfigData,
|
||||
"port" | "socks-port" | "mixed-port" | "external-controller" | "secret"
|
||||
| "port"
|
||||
| "socks-port"
|
||||
| "mixed-port"
|
||||
| "redir-port"
|
||||
| "tproxy-port"
|
||||
| "external-controller"
|
||||
| "secret"
|
||||
>
|
||||
>
|
||||
) => {
|
||||
const hasInfo =
|
||||
patch["redir-port"] != null ||
|
||||
patch["tproxy-port"] != null ||
|
||||
patch["mixed-port"] != null ||
|
||||
patch["socks-port"] != null ||
|
||||
patch["port"] != null ||
|
||||
@@ -62,6 +70,26 @@ export const useClashInfo = () => {
|
||||
|
||||
if (!hasInfo) return;
|
||||
|
||||
if (patch["redir-port"]) {
|
||||
const port = patch["redir-port"];
|
||||
if (port < 1000) {
|
||||
throw new Error("The port should not < 1000");
|
||||
}
|
||||
if (port > 65536) {
|
||||
throw new Error("The port should not > 65536");
|
||||
}
|
||||
}
|
||||
|
||||
if (patch["tproxy-port"]) {
|
||||
const port = patch["tproxy-port"];
|
||||
if (port < 1000) {
|
||||
throw new Error("The port should not < 1000");
|
||||
}
|
||||
if (port > 65536) {
|
||||
throw new Error("The port should not > 65536");
|
||||
}
|
||||
}
|
||||
|
||||
if (patch["mixed-port"]) {
|
||||
const port = patch["mixed-port"];
|
||||
if (port < 1000) {
|
||||
|
||||
@@ -45,6 +45,8 @@
|
||||
"Update All Profiles": "更新所有订阅",
|
||||
"View Runtime Config": "查看运行时订阅",
|
||||
"Reactivate Profiles": "重新激活订阅",
|
||||
"Confirm deletion": "确认删除",
|
||||
"This operation is not reversible": "此操作不可逆",
|
||||
|
||||
"Location": "当前节点",
|
||||
"Delay check": "延迟测试",
|
||||
@@ -138,6 +140,7 @@
|
||||
"Save": "保存",
|
||||
"Cancel": "取消",
|
||||
"Exit": "退出",
|
||||
"Confirm": "确认",
|
||||
|
||||
"Default": "默认",
|
||||
"Download Speed": "下载速度",
|
||||
|
||||
4
src/services/types.d.ts
vendored
4
src/services/types.d.ts
vendored
@@ -142,6 +142,8 @@ interface IClashInfo {
|
||||
// status: string;
|
||||
mixed_port?: number; // clash mixed port
|
||||
socks_port?: number; // clash socks port
|
||||
redir_port?: number; // clash redir port
|
||||
tproxy_port?: number; // clash tproxy port
|
||||
port?: number; // clash http port
|
||||
server?: string; // external-controller
|
||||
secret?: string;
|
||||
@@ -214,6 +216,8 @@ interface IVergeConfig {
|
||||
enable_random_port?: boolean;
|
||||
verge_mixed_port?: number;
|
||||
verge_socks_port?: number;
|
||||
verge_redir_port?: number;
|
||||
verge_tproxy_port?: number;
|
||||
verge_port?: number;
|
||||
enable_proxy_guard?: boolean;
|
||||
proxy_guard_duration?: number;
|
||||
|
||||
Reference in New Issue
Block a user