Compare commits
9 Commits
20
README.md
20
README.md
@@ -41,18 +41,18 @@ A Clash Meta GUI based on <a href="https://github.com/tauri-apps/tauri">Tauri</a
|
||||
|
||||
Download from [release](https://github.com/clash-verge-rev/clash-verge-rev/releases). Supports Windows (x64/x86), Linux (x64/arm64) and macOS 10.15+ (intel/apple).
|
||||
|
||||
- [Windows x64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/Clash.Verge_1.4.7_x64-setup.exe)
|
||||
- [Windows x86](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/Clash.Verge_1.4.7_x86-setup.exe)
|
||||
- [Windows arm64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/Clash.Verge_1.4.7_arm64-setup.exe)
|
||||
- [Windows x64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/Clash.Verge_1.4.8_x64-setup.exe)
|
||||
- [Windows x86](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/Clash.Verge_1.4.8_x86-setup.exe)
|
||||
- [Windows arm64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/Clash.Verge_1.4.8_arm64-setup.exe)
|
||||
|
||||
- [macOS intel](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/Clash.Verge_1.4.7_x64.dmg)
|
||||
- [macOS apple](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/Clash.Verge_1.4.7_aarch64.dmg)
|
||||
- [macOS intel](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/Clash.Verge_1.4.8_x64.dmg)
|
||||
- [macOS apple](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/Clash.Verge_1.4.8_aarch64.dmg)
|
||||
|
||||
- [Linux x64 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/clash-verge_1.4.7_amd64.AppImage)
|
||||
- [Linux x64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/clash-verge_1.4.7_amd64.deb)
|
||||
- [Linux x86 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/clash-verge_1.4.7_i386.AppImage)
|
||||
- [Linux x86 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/clash-verge_1.4.7_i386.deb)
|
||||
- [Linux arm64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.7/clash-verge_1.4.7_arm64.deb)
|
||||
- [Linux x64 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/clash-verge_1.4.8_amd64.AppImage)
|
||||
- [Linux x64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/clash-verge_1.4.8_amd64.deb)
|
||||
- [Linux x86 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/clash-verge_1.4.8_i386.AppImage)
|
||||
- [Linux x86 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/clash-verge_1.4.8_i386.deb)
|
||||
- [Linux arm64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.4.8/clash-verge_1.4.8_arm64.deb)
|
||||
|
||||
Or you can build it yourself. Supports Windows, Linux and macOS 10.15+
|
||||
|
||||
|
||||
16
UPDATELOG.md
16
UPDATELOG.md
@@ -1,3 +1,19 @@
|
||||
## v1.4.8
|
||||
|
||||
### Features
|
||||
|
||||
- 连接页面总流量显示
|
||||
|
||||
### Bugs Fixes
|
||||
|
||||
- 连接页面数据排序错误
|
||||
- 新建订阅时设置更新间隔无效
|
||||
- Windows 拨号网络无法设置系统代理
|
||||
- Windows 开启/关闭系统代理延迟(使用注册表即可)
|
||||
- 删除无效的背景模糊选项
|
||||
|
||||
---
|
||||
|
||||
## v1.4.7
|
||||
|
||||
### Features
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "clash-verge",
|
||||
"version": "1.4.7",
|
||||
"version": "1.4.8",
|
||||
"license": "GPL-3.0",
|
||||
"scripts": {
|
||||
"dev": "tauri dev",
|
||||
|
||||
56
src-tauri/Cargo.lock
generated
56
src-tauri/Cargo.lock
generated
@@ -28,6 +28,19 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ahash"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "77c3a9648d43b9cd48db467b3f87fdd6e146bcc88ab0180006cef2179fe11d01"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"getrandom 0.2.11",
|
||||
"once_cell",
|
||||
"version_check",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.6.10"
|
||||
@@ -567,7 +580,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clash-verge"
|
||||
version = "1.4.7"
|
||||
version = "1.4.8"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"auto-launch",
|
||||
@@ -1815,7 +1828,7 @@ version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"ahash 0.7.7",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2169,6 +2182,17 @@ version = "2.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f518f335dce6725a761382244631d86cf0ccb2863413590b31338feb467f9c3"
|
||||
|
||||
[[package]]
|
||||
name = "iptools"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c03bfb870879ce6a141b644653d63b203d290ec5f3b6919cf7b30cba06a164a5"
|
||||
dependencies = [
|
||||
"ahash 0.8.7",
|
||||
"once_cell",
|
||||
"regex 1.10.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-docker"
|
||||
version = "0.2.0"
|
||||
@@ -4468,13 +4492,13 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "sysproxy"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9707a79d3b95683aa5a9521e698ffd878b8fb289727c25a69157fb85d529ffff"
|
||||
source = "git+https://github.com/clash-verge-rev/sysproxy-rs?branch=main#79390614ede8252158bf775ffaabbec04d8a4359"
|
||||
dependencies = [
|
||||
"interfaces",
|
||||
"iptools",
|
||||
"thiserror",
|
||||
"winapi",
|
||||
"winreg 0.10.1",
|
||||
"windows 0.52.0",
|
||||
"winreg 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -6318,6 +6342,26 @@ dependencies = [
|
||||
"zvariant",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d4d3961e53fa4c9a25a8637fc2bfaf2595b3d3ae34875568a5cf64787716be"
|
||||
dependencies = [
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zerocopy-derive"
|
||||
version = "0.7.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.39",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "0.6.6"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "clash-verge"
|
||||
version = "1.4.7"
|
||||
version = "1.4.8"
|
||||
description = "clash verge"
|
||||
authors = ["zzzgydi", "wonfen", "MystiPanda"]
|
||||
license = "GPL-3.0"
|
||||
@@ -14,7 +14,6 @@ tauri-build = { version = "1", features = [] }
|
||||
|
||||
[dependencies]
|
||||
warp = "0.3"
|
||||
sysproxy = "0.3.0"
|
||||
which = "5.0.0"
|
||||
anyhow = "1.0"
|
||||
dirs = "5.0"
|
||||
@@ -39,6 +38,7 @@ window-shadows = { version = "0.2" }
|
||||
tokio = { version = "1", features = ["full"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
reqwest = { version = "0.11", features = ["json", "rustls-tls"] }
|
||||
sysproxy = { git="https://github.com/clash-verge-rev/sysproxy-rs", branch = "main" }
|
||||
tauri = { version = "1.5", features = [ "notification-all", "icon-png", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<array>
|
||||
<dict>
|
||||
<key>CFBundleURLName</key>
|
||||
<string>io.github.clash-verge-rev.clash-verge-rev</string>
|
||||
<string>Clash Verge</string>
|
||||
<key>CFBundleURLSchemes</key>
|
||||
<array>
|
||||
<string>clash</string>
|
||||
|
||||
@@ -171,6 +171,7 @@ impl PrfItem {
|
||||
let with_proxy = opt_ref.map_or(false, |o| o.with_proxy.unwrap_or(false));
|
||||
let self_proxy = opt_ref.map_or(false, |o| o.self_proxy.unwrap_or(false));
|
||||
let user_agent = opt_ref.and_then(|o| o.user_agent.clone());
|
||||
let update_interval = opt_ref.and_then(|o| o.update_interval);
|
||||
|
||||
let mut builder = reqwest::ClientBuilder::new().use_rustls_tls().no_proxy();
|
||||
|
||||
@@ -262,17 +263,21 @@ impl PrfItem {
|
||||
}
|
||||
None => None,
|
||||
};
|
||||
|
||||
// parse the profile-update-interval
|
||||
let option = match header.get("profile-update-interval") {
|
||||
Some(value) => match value.to_str().unwrap_or("").parse::<u64>() {
|
||||
Ok(val) => Some(PrfOption {
|
||||
update_interval: Some(val * 60), // hour -> min
|
||||
..PrfOption::default()
|
||||
}),
|
||||
Err(_) => None,
|
||||
let option = match update_interval {
|
||||
Some(val) => Some(PrfOption {
|
||||
update_interval: Some(val),
|
||||
..PrfOption::default()
|
||||
}),
|
||||
None => match header.get("profile-update-interval") {
|
||||
Some(value) => match value.to_str().unwrap_or("").parse::<u64>() {
|
||||
Ok(val) => Some(PrfOption {
|
||||
update_interval: Some(val * 60), // hour -> min
|
||||
..PrfOption::default()
|
||||
}),
|
||||
Err(_) => None,
|
||||
},
|
||||
None => None,
|
||||
},
|
||||
None => None,
|
||||
};
|
||||
|
||||
let uid = help::get_uid("r");
|
||||
|
||||
@@ -19,10 +19,6 @@ pub struct IVerge {
|
||||
/// `light` or `dark` or `system`
|
||||
pub theme_mode: Option<String>,
|
||||
|
||||
/// enable blur mode
|
||||
/// maybe be able to set the alpha
|
||||
pub theme_blur: Option<bool>,
|
||||
|
||||
/// tray click event
|
||||
pub tray_event: Option<String>,
|
||||
|
||||
@@ -57,6 +53,9 @@ pub struct IVerge {
|
||||
/// set system proxy bypass
|
||||
pub system_proxy_bypass: Option<String>,
|
||||
|
||||
/// set system proxy method
|
||||
pub system_proxy_registry_mode: Option<bool>,
|
||||
|
||||
/// proxy guard duration
|
||||
pub proxy_guard_duration: Option<u64>,
|
||||
|
||||
@@ -140,12 +139,12 @@ impl IVerge {
|
||||
env_type: Some("bash".into()),
|
||||
#[cfg(target_os = "windows")]
|
||||
env_type: Some("powershell".into()),
|
||||
theme_blur: Some(false),
|
||||
traffic_graph: Some(true),
|
||||
enable_memory_usage: Some(true),
|
||||
enable_auto_launch: Some(false),
|
||||
enable_silent_start: Some(false),
|
||||
enable_system_proxy: Some(false),
|
||||
system_proxy_registry_mode: Some(false),
|
||||
enable_random_port: Some(false),
|
||||
verge_mixed_port: Some(7897),
|
||||
enable_proxy_guard: Some(false),
|
||||
@@ -177,7 +176,6 @@ impl IVerge {
|
||||
patch!(app_log_level);
|
||||
patch!(language);
|
||||
patch!(theme_mode);
|
||||
patch!(theme_blur);
|
||||
patch!(tray_event);
|
||||
patch!(env_type);
|
||||
patch!(traffic_graph);
|
||||
@@ -192,6 +190,7 @@ impl IVerge {
|
||||
patch!(enable_system_proxy);
|
||||
patch!(enable_proxy_guard);
|
||||
patch!(system_proxy_bypass);
|
||||
patch!(system_proxy_registry_mode);
|
||||
patch!(proxy_guard_duration);
|
||||
|
||||
patch!(theme_setting);
|
||||
|
||||
@@ -58,6 +58,12 @@ impl Sysopt {
|
||||
)
|
||||
};
|
||||
|
||||
let registry_mode = {
|
||||
let verge = Config::verge();
|
||||
let verge = verge.latest();
|
||||
verge.system_proxy_registry_mode.unwrap_or(false)
|
||||
};
|
||||
|
||||
let current = Sysproxy {
|
||||
enable,
|
||||
host: String::from("127.0.0.1"),
|
||||
@@ -67,7 +73,15 @@ impl Sysopt {
|
||||
|
||||
if enable {
|
||||
let old = Sysproxy::get_system_proxy().ok();
|
||||
current.set_system_proxy()?;
|
||||
|
||||
if registry_mode {
|
||||
#[cfg(windows)]
|
||||
current.set_system_proxy_with_registry()?;
|
||||
#[cfg(not(windows))]
|
||||
current.set_system_proxy()?;
|
||||
} else {
|
||||
current.set_system_proxy()?;
|
||||
}
|
||||
|
||||
*self.old_sysproxy.lock() = old;
|
||||
*self.cur_sysproxy.lock() = Some(current);
|
||||
@@ -97,12 +111,26 @@ impl Sysopt {
|
||||
verge.system_proxy_bypass.clone(),
|
||||
)
|
||||
};
|
||||
|
||||
let registry_mode = {
|
||||
let verge = Config::verge();
|
||||
let verge = verge.latest();
|
||||
verge.system_proxy_registry_mode.unwrap_or(false)
|
||||
};
|
||||
|
||||
let mut sysproxy = cur_sysproxy.take().unwrap();
|
||||
|
||||
sysproxy.enable = enable;
|
||||
sysproxy.bypass = bypass.unwrap_or(DEFAULT_BYPASS.into());
|
||||
|
||||
sysproxy.set_system_proxy()?;
|
||||
if registry_mode {
|
||||
#[cfg(windows)]
|
||||
sysproxy.set_system_proxy_with_registry()?;
|
||||
#[cfg(not(windows))]
|
||||
sysproxy.set_system_proxy()?;
|
||||
} else {
|
||||
sysproxy.set_system_proxy()?;
|
||||
}
|
||||
*cur_sysproxy = Some(sysproxy);
|
||||
|
||||
Ok(())
|
||||
@@ -112,7 +140,11 @@ impl Sysopt {
|
||||
pub fn reset_sysproxy(&self) -> Result<()> {
|
||||
let mut cur_sysproxy = self.cur_sysproxy.lock();
|
||||
let mut old_sysproxy = self.old_sysproxy.lock();
|
||||
|
||||
let registry_mode = {
|
||||
let verge = Config::verge();
|
||||
let verge = verge.latest();
|
||||
verge.system_proxy_registry_mode.unwrap_or(false)
|
||||
};
|
||||
let cur_sysproxy = cur_sysproxy.take();
|
||||
|
||||
if let Some(mut old) = old_sysproxy.take() {
|
||||
@@ -127,12 +159,26 @@ impl Sysopt {
|
||||
log::info!(target: "app", "reset proxy to the original proxy");
|
||||
}
|
||||
|
||||
old.set_system_proxy()?;
|
||||
if registry_mode {
|
||||
#[cfg(windows)]
|
||||
old.set_system_proxy_with_registry()?;
|
||||
#[cfg(not(windows))]
|
||||
old.set_system_proxy()?;
|
||||
} else {
|
||||
old.set_system_proxy()?;
|
||||
}
|
||||
} else if let Some(mut cur @ Sysproxy { enable: true, .. }) = cur_sysproxy {
|
||||
// 没有原代理,就按现在的代理设置disable即可
|
||||
log::info!(target: "app", "reset proxy by disabling the current proxy");
|
||||
cur.enable = false;
|
||||
cur.set_system_proxy()?;
|
||||
if registry_mode {
|
||||
#[cfg(windows)]
|
||||
cur.set_system_proxy_with_registry()?;
|
||||
#[cfg(not(windows))]
|
||||
cur.set_system_proxy()?;
|
||||
} else {
|
||||
cur.set_system_proxy()?;
|
||||
}
|
||||
} else {
|
||||
log::info!(target: "app", "reset proxy with no action");
|
||||
}
|
||||
@@ -251,7 +297,11 @@ impl Sysopt {
|
||||
use tokio::time::{sleep, Duration};
|
||||
|
||||
let guard_state = self.guard_state.clone();
|
||||
|
||||
let registry_mode = {
|
||||
let verge = Config::verge();
|
||||
let verge = verge.latest();
|
||||
verge.system_proxy_registry_mode.unwrap_or(false)
|
||||
};
|
||||
tauri::async_runtime::spawn(async move {
|
||||
// if it is running, exit
|
||||
let mut state = guard_state.lock().await;
|
||||
@@ -301,8 +351,14 @@ impl Sysopt {
|
||||
port,
|
||||
bypass: bypass.unwrap_or(DEFAULT_BYPASS.into()),
|
||||
};
|
||||
|
||||
log_err!(sysproxy.set_system_proxy());
|
||||
if registry_mode {
|
||||
#[cfg(windows)]
|
||||
log_err!(sysproxy.set_system_proxy_with_registry());
|
||||
#[cfg(not(windows))]
|
||||
log_err!(sysproxy.set_system_proxy());
|
||||
} else {
|
||||
log_err!(sysproxy.set_system_proxy());
|
||||
}
|
||||
}
|
||||
|
||||
let mut state = guard_state.lock().await;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"package": {
|
||||
"productName": "Clash Verge",
|
||||
"version": "1.4.7"
|
||||
"version": "1.4.8"
|
||||
},
|
||||
"build": {
|
||||
"distDir": "../dist",
|
||||
|
||||
@@ -3,6 +3,7 @@ import { useMemo, useState } from "react";
|
||||
import { DataGrid, GridColDef } from "@mui/x-data-grid";
|
||||
import { truncateStr } from "@/utils/truncate-str";
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
import { sortWithUnit, sortStringTime } from "@/utils/custom-comparator";
|
||||
|
||||
interface Props {
|
||||
connections: IConnectionsItem[];
|
||||
@@ -24,6 +25,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: sortWithUnit,
|
||||
},
|
||||
{
|
||||
field: "upload",
|
||||
@@ -31,6 +33,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: sortWithUnit,
|
||||
},
|
||||
{
|
||||
field: "dlSpeed",
|
||||
@@ -38,6 +41,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: sortWithUnit,
|
||||
},
|
||||
{
|
||||
field: "ulSpeed",
|
||||
@@ -45,6 +49,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
width: 88,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: sortWithUnit,
|
||||
},
|
||||
{ field: "chains", headerName: "Chains", flex: 360, minWidth: 360 },
|
||||
{ field: "rule", headerName: "Rule", flex: 300, minWidth: 250 },
|
||||
@@ -56,6 +61,7 @@ export const ConnectionTable = (props: Props) => {
|
||||
minWidth: 100,
|
||||
align: "right",
|
||||
headerAlign: "right",
|
||||
sortComparator: sortStringTime,
|
||||
},
|
||||
{ field: "source", headerName: "Source", flex: 200, minWidth: 130 },
|
||||
{
|
||||
@@ -72,7 +78,6 @@ export const ConnectionTable = (props: Props) => {
|
||||
const { metadata, rulePayload } = each;
|
||||
const chains = [...each.chains].reverse().join(" / ");
|
||||
const rule = rulePayload ? `${each.rule}(${rulePayload})` : each.rule;
|
||||
|
||||
return {
|
||||
id: each.id,
|
||||
host: metadata.host
|
||||
|
||||
@@ -36,19 +36,6 @@ export const LayoutViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
onCancel={() => setOpen(false)}
|
||||
>
|
||||
<List>
|
||||
<SettingItem label={t("Theme Blur")}>
|
||||
<GuardState
|
||||
value={verge?.theme_blur ?? false}
|
||||
valueProps="checked"
|
||||
onCatch={onError}
|
||||
onFormat={onSwitchFormat}
|
||||
onChange={(e) => onChangeData({ theme_blur: e })}
|
||||
onGuard={(e) => patchVerge({ theme_blur: e })}
|
||||
>
|
||||
<Switch edge="end" />
|
||||
</GuardState>
|
||||
</SettingItem>
|
||||
|
||||
<SettingItem label={t("Traffic Graph")}>
|
||||
<GuardState
|
||||
value={verge?.traffic_graph ?? true}
|
||||
|
||||
@@ -11,11 +11,15 @@ import {
|
||||
Switch,
|
||||
TextField,
|
||||
Typography,
|
||||
Tooltip,
|
||||
} from "@mui/material";
|
||||
import getSystem from "@/utils/get-system";
|
||||
import { useVerge } from "@/hooks/use-verge";
|
||||
import { getSystemProxy } from "@/services/cmds";
|
||||
import { BaseDialog, DialogRef, Notice } from "@/components/base";
|
||||
|
||||
const OS = getSystem();
|
||||
|
||||
export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
@@ -31,12 +35,14 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
enable_proxy_guard,
|
||||
system_proxy_bypass,
|
||||
proxy_guard_duration,
|
||||
system_proxy_registry_mode,
|
||||
} = verge ?? {};
|
||||
|
||||
const [value, setValue] = useState({
|
||||
guard: enable_proxy_guard,
|
||||
bypass: system_proxy_bypass,
|
||||
duration: proxy_guard_duration ?? 10,
|
||||
registryMode: system_proxy_registry_mode,
|
||||
});
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
@@ -46,6 +52,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
guard: enable_proxy_guard,
|
||||
bypass: system_proxy_bypass,
|
||||
duration: proxy_guard_duration ?? 10,
|
||||
registryMode: system_proxy_registry_mode,
|
||||
});
|
||||
getSystemProxy().then((p) => setSysproxy(p));
|
||||
},
|
||||
@@ -69,6 +76,9 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
if (value.bypass !== system_proxy_bypass) {
|
||||
patch.system_proxy_bypass = value.bypass;
|
||||
}
|
||||
if (value.registryMode !== system_proxy_registry_mode) {
|
||||
patch.system_proxy_registry_mode = value.registryMode;
|
||||
}
|
||||
|
||||
try {
|
||||
await patchVerge(patch);
|
||||
@@ -82,7 +92,7 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<BaseDialog
|
||||
open={open}
|
||||
title={t("System Proxy Setting")}
|
||||
contentSx={{ width: 450, maxHeight: 300 }}
|
||||
contentSx={{ width: 450, maxHeight: 500 }}
|
||||
okBtn={t("Save")}
|
||||
cancelBtn={t("Cancel")}
|
||||
onClose={() => setOpen(false)}
|
||||
@@ -134,6 +144,27 @@ export const SysproxyViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
{OS === "windows" && (
|
||||
<Tooltip
|
||||
title={
|
||||
enabled
|
||||
? t("Please disable the system proxy")
|
||||
: t("Using the registry instead of Windows API")
|
||||
}
|
||||
>
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Use Registry")} />
|
||||
<Switch
|
||||
edge="end"
|
||||
disabled={enabled}
|
||||
checked={value.registryMode}
|
||||
onChange={(_, e) =>
|
||||
setValue((v) => ({ ...v, registryMode: e }))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
</Tooltip>
|
||||
)}
|
||||
</List>
|
||||
|
||||
<Box sx={{ mt: 2.5 }}>
|
||||
|
||||
@@ -84,12 +84,12 @@
|
||||
"Proxy Guard": "Proxy Guard",
|
||||
"Guard Duration": "Guard Duration",
|
||||
"Proxy Bypass": "Proxy Bypass",
|
||||
"Use Registry": "Use Registry",
|
||||
"Enable status": "Enable status",
|
||||
"Server Addr": "Server Addr",
|
||||
"Bypass": "Bypass",
|
||||
"Current System Proxy": "Current System Proxy",
|
||||
"Theme Mode": "Theme Mode",
|
||||
"Theme Blur": "Theme Blur",
|
||||
"Tray Click Event": "Tray Click Event",
|
||||
"Copy Env Type": "Copy Env Type",
|
||||
"Show Main Window": "Show Main Window",
|
||||
@@ -147,5 +147,7 @@
|
||||
"Retain 30 Days": "Retain 30 Days",
|
||||
"Retain 90 Days": "Retain 90 Days",
|
||||
|
||||
"Portable Updater Error": "The portable version does not support in-app updates. Please manually download and replace it"
|
||||
"Portable Updater Error": "The portable version does not support in-app updates. Please manually download and replace it",
|
||||
"Please disable the system proxy": "Please disable the system proxy",
|
||||
"Using the registry instead of Windows API": "Using the registry instead of Windows API"
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@
|
||||
"Proxy Guard": "Защита прокси",
|
||||
"Guard Duration": "Период защиты",
|
||||
"Proxy Bypass": "Игнорирование прокси",
|
||||
"Use Registry": "Использование реестра",
|
||||
"Current System Proxy": "Текущий системный прокси",
|
||||
"Theme Mode": "Режим темы",
|
||||
"Theme Blur": "Размытие темы",
|
||||
"Tray Click Event": "Событие щелчка в лотке",
|
||||
"Copy Env Type": "Скопировать тип Env",
|
||||
"Show Main Window": "Показать главное окно",
|
||||
@@ -117,5 +117,7 @@
|
||||
"enable_tun_mode": "Включить режим туннеля",
|
||||
"disable_tun_mode": "Отключить режим туннеля",
|
||||
|
||||
"Portable Updater Error": "Портативная версия не поддерживает обновление внутри приложения, пожалуйста, скачайте и замените вручную"
|
||||
"Portable Updater Error": "Портативная версия не поддерживает обновление внутри приложения, пожалуйста, скачайте и замените вручную",
|
||||
"Please disable the system proxy": "Пожалуйста, отключите системный прокси",
|
||||
"Using the registry instead of Windows API": "Использование реестра вместо Windows API"
|
||||
}
|
||||
|
||||
@@ -84,12 +84,12 @@
|
||||
"Proxy Guard": "系统代理守卫",
|
||||
"Guard Duration": "代理守卫间隔",
|
||||
"Proxy Bypass": "代理绕过",
|
||||
"Use Registry": "使用注册表",
|
||||
"Current System Proxy": "当前系统代理",
|
||||
"Enable status": "开启状态:",
|
||||
"Server Addr": "服务地址:",
|
||||
"Bypass": "当前绕过:",
|
||||
"Theme Mode": "主题模式",
|
||||
"Theme Blur": "背景模糊",
|
||||
"Tray Click Event": "托盘点击事件",
|
||||
"Copy Env Type": "复制环境变量类型",
|
||||
"Show Main Window": "显示主窗口",
|
||||
@@ -147,5 +147,7 @@
|
||||
"Retain 30 Days": "保留30天",
|
||||
"Retain 90 Days": "保留90天",
|
||||
|
||||
"Portable Updater Error": "便携版不支持应用内更新,请手动下载替换"
|
||||
"Portable Updater Error": "便携版不支持应用内更新,请手动下载替换",
|
||||
"Please disable the system proxy": "请先关闭系统代理",
|
||||
"Using the registry instead of Windows API": "使用注册表替代Windows API"
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ const Layout = () => {
|
||||
const { theme } = useCustomTheme();
|
||||
|
||||
const { verge } = useVerge();
|
||||
const { theme_blur, language } = verge || {};
|
||||
const { language } = verge || {};
|
||||
|
||||
const location = useLocation();
|
||||
|
||||
@@ -116,7 +116,7 @@ const Layout = () => {
|
||||
}}
|
||||
sx={[
|
||||
({ palette }) => ({
|
||||
bgcolor: alpha(palette.background.paper, theme_blur ? 0.8 : 1),
|
||||
bgcolor: palette.background.paper,
|
||||
}),
|
||||
]}
|
||||
>
|
||||
|
||||
@@ -24,6 +24,7 @@ import {
|
||||
ConnectionDetail,
|
||||
ConnectionDetailRef,
|
||||
} from "@/components/connection/connection-detail";
|
||||
import parseTraffic from "@/utils/parse-traffic";
|
||||
|
||||
const initConn = { uploadTotal: 0, downloadTotal: 0, connections: [] };
|
||||
|
||||
@@ -48,14 +49,20 @@ const ConnectionsPage = () => {
|
||||
list.sort((a, b) => b.curDownload! - a.curDownload!),
|
||||
};
|
||||
|
||||
const filterConn = useMemo(() => {
|
||||
const [filterConn, download, upload] = useMemo(() => {
|
||||
const orderFunc = orderOpts[curOrderOpt];
|
||||
const connections = connData.connections.filter((conn) =>
|
||||
let connections = connData.connections.filter((conn) =>
|
||||
(conn.metadata.host || conn.metadata.destinationIP)?.includes(filterText)
|
||||
);
|
||||
|
||||
if (orderFunc) return orderFunc(connections);
|
||||
return connections;
|
||||
if (orderFunc) connections = orderFunc(connections);
|
||||
let download = 0;
|
||||
let upload = 0;
|
||||
connections.forEach((x) => {
|
||||
download += x.download;
|
||||
upload += x.upload;
|
||||
});
|
||||
return [connections, download, upload];
|
||||
}, [connData, filterText, curOrderOpt]);
|
||||
|
||||
const { connect, disconnect } = useWebsocket(
|
||||
@@ -119,6 +126,8 @@ const ConnectionsPage = () => {
|
||||
contentStyle={{ height: "100%" }}
|
||||
header={
|
||||
<Box sx={{ mt: 1, display: "flex", alignItems: "center", gap: 2 }}>
|
||||
<Box sx={{ mx: 1 }}>Download: {parseTraffic(download)}</Box>
|
||||
<Box sx={{ mx: 1 }}>Upload: {parseTraffic(upload)}</Box>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="small"
|
||||
@@ -184,7 +193,6 @@ const ConnectionsPage = () => {
|
||||
placeholder={t("Filter conditions")}
|
||||
value={filterText}
|
||||
onChange={(e) => setFilterText(e.target.value)}
|
||||
sx={{ input: { py: 0.65, px: 1.25 } }}
|
||||
/>
|
||||
</Box>
|
||||
|
||||
|
||||
2
src/services/types.d.ts
vendored
2
src/services/types.d.ts
vendored
@@ -161,7 +161,6 @@ interface IVergeConfig {
|
||||
env_type?: "bash" | "cmd" | "powershell" | string;
|
||||
clash_core?: string;
|
||||
theme_mode?: "light" | "dark" | "system";
|
||||
theme_blur?: boolean;
|
||||
traffic_graph?: boolean;
|
||||
enable_memory_usage?: boolean;
|
||||
enable_tun_mode?: boolean;
|
||||
@@ -174,6 +173,7 @@ interface IVergeConfig {
|
||||
enable_proxy_guard?: boolean;
|
||||
proxy_guard_duration?: number;
|
||||
system_proxy_bypass?: string;
|
||||
system_proxy_registry_mode?: boolean;
|
||||
web_ui_list?: string[];
|
||||
hotkeys?: string[];
|
||||
theme_setting?: {
|
||||
|
||||
38
src/utils/custom-comparator.ts
Normal file
38
src/utils/custom-comparator.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { GridComparatorFn } from "@mui/x-data-grid";
|
||||
|
||||
const UNITS = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
|
||||
const unitMap = new Map<string, number>();
|
||||
unitMap.set("分钟前", 60);
|
||||
unitMap.set("小时前", 60 * 60);
|
||||
unitMap.set("天前", 60 * 60 * 24);
|
||||
unitMap.set("个月前", 60 * 60 * 24 * 30);
|
||||
unitMap.set("年前", 60 * 60 * 24 * 30 * 12);
|
||||
|
||||
export const sortWithUnit: GridComparatorFn<string> = (v1, v2) => {
|
||||
const [ret1, unit1] = v1.split(" ");
|
||||
const [ret2, unit2] = v2.split(" ");
|
||||
let value1 =
|
||||
parseFloat(ret1) *
|
||||
Math.pow(1024, UNITS.indexOf(unit1.replace("/s", "").trim()));
|
||||
let value2 =
|
||||
parseFloat(ret2) *
|
||||
Math.pow(1024, UNITS.indexOf(unit2.replace("/s", "").trim()));
|
||||
return value1 - value2;
|
||||
};
|
||||
|
||||
export const sortStringTime: GridComparatorFn<string> = (v1, v2) => {
|
||||
if (v1 === "几秒前") {
|
||||
return -1;
|
||||
}
|
||||
if (v2 === "几秒前") {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const matches1 = v1.match(/[0-9]+/);
|
||||
const num1 = matches1 !== null ? parseInt(matches1[0]) : 0;
|
||||
const matches2 = v2.match(/[0-9]+/);
|
||||
const num2 = matches2 !== null ? parseInt(matches2[0]) : 0;
|
||||
const unit1 = unitMap.get(v1.replace(num1.toString(), "").trim()) || 0;
|
||||
const unit2 = unitMap.get(v2.replace(num2.toString(), "").trim()) || 0;
|
||||
return num1 * unit1 - num2 * unit2;
|
||||
};
|
||||
Reference in New Issue
Block a user