Compare commits

...

10 Commits

18 changed files with 188 additions and 78 deletions

View File

@@ -13,15 +13,15 @@ A Clash Meta GUI based on <a href="https://github.com/tauri-apps/tauri">Tauri</a
Click on the corresponding link below to download the installation package. 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.5.2/Clash.Verge_1.5.2_x64-setup.exe)]
[[Windows arm64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/Clash.Verge_1.5.2_arm64-setup.exe)]
[[Windows x64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/Clash.Verge_1.5.3_x64-setup.exe)]
[[Windows arm64](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/Clash.Verge_1.5.3_arm64-setup.exe)]
[[macOS intel](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/Clash.Verge_1.5.2_x64.dmg)]
[[macOS apple](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/Clash.Verge_1.5.2_aarch64.dmg)]
[[macOS intel](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/Clash.Verge_1.5.3_x64.dmg)]
[[macOS apple](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/Clash.Verge_1.5.3_aarch64.dmg)]
[[Linux x64 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/clash-verge_1.5.2_amd64.AppImage)]
[[Linux x64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/clash-verge_1.5.2_amd64.deb)]
[[Linux arm64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.2/clash-verge_1.5.2_arm64.deb)]
[[Linux x64 AppImage](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/clash-verge_1.5.3_amd64.AppImage)]
[[Linux x64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/clash-verge_1.5.3_amd64.deb)]
[[Linux arm64 deb](https://github.com/clash-verge-rev/clash-verge-rev/releases/download/v1.5.3/clash-verge_1.5.3_arm64.deb)]
Or you can build it yourself. Supports Windows, Linux and macOS 10.15+

View File

@@ -1,3 +1,15 @@
## v1.5.3
### Features
- Tun 设置添加重置按钮
### Bugs Fixes
- Tun 设置项显示错误的问题
- 修改一些默认值
- 启动时不更改启动项设置
## v1.5.2
### Features

View File

@@ -1,6 +1,6 @@
{
"name": "clash-verge",
"version": "1.5.2",
"version": "1.5.3",
"license": "GPL-3.0-only",
"scripts": {
"dev": "tauri dev",

2
src-tauri/Cargo.lock generated
View File

@@ -598,7 +598,7 @@ dependencies = [
[[package]]
name = "clash-verge"
version = "1.5.2"
version = "1.5.3"
dependencies = [
"anyhow",
"auto-launch",

View File

@@ -1,6 +1,6 @@
[package]
name = "clash-verge"
version = "1.5.2"
version = "1.5.3"
description = "clash verge"
authors = ["zzzgydi", "wonfen", "MystiPanda"]
license = "GPL-3.0-only"

View File

@@ -32,12 +32,12 @@ impl IClashTemp {
pub fn template() -> Self {
let mut map = Mapping::new();
let mut tun = Mapping::new();
tun.insert("stack".into(), "gVisor".into());
tun.insert("stack".into(), "gvisor".into());
tun.insert("device".into(), "Meta".into());
tun.insert("auto-route".into(), true.into());
tun.insert("strict-route".into(), true.into());
tun.insert("strict-route".into(), false.into());
tun.insert("auto-detect-interface".into(), true.into());
tun.insert("dns-hijack".into(), vec!["any:53", "tcp://any:53"].into());
tun.insert("dns-hijack".into(), vec!["any:53"].into());
tun.insert("mtu".into(), 9000.into());
map.insert("mixed-port".into(), 7897.into());

View File

@@ -144,10 +144,9 @@ impl CoreManager {
let config_path = dirs::path_to_str(&config_path)?;
// fix #212
let args = match clash_core.as_str() {
"clash-meta" => vec!["-m", "-d", app_dir, "-f", config_path],
"clash-meta-alpha" => vec!["-m", "-d", app_dir, "-f", config_path],
"clash-meta" => vec!["-d", app_dir, "-f", config_path],
"clash-meta-alpha" => vec!["-d", app_dir, "-f", config_path],
_ => vec!["-d", app_dir, "-f", config_path],
};

View File

@@ -148,9 +148,6 @@ impl Sysopt {
/// init the auto launch
pub fn init_launch(&self) -> Result<()> {
let enable = { Config::verge().latest().enable_auto_launch };
let enable = enable.unwrap_or(false);
let app_exe = current_exe()?;
let app_exe = dunce::canonicalize(app_exe)?;
let app_name = app_exe
@@ -204,28 +201,6 @@ impl Sysopt {
.set_app_path(&app_path)
.build()?;
// 避免在开发时将自启动关了
#[cfg(feature = "verge-dev")]
if !enable {
return Ok(());
}
#[cfg(target_os = "macos")]
{
if enable && !auto.is_enabled().unwrap_or(false) {
// 避免重复设置登录项
let _ = auto.disable();
auto.enable()?;
} else if !enable {
let _ = auto.disable();
}
}
#[cfg(not(target_os = "macos"))]
if enable {
auto.enable()?;
}
*self.auto_launch.lock() = Some(auto);
Ok(())

View File

@@ -1,7 +1,7 @@
{
"package": {
"productName": "Clash Verge",
"version": "1.5.2"
"version": "1.5.3"
},
"build": {
"distDir": "../dist",

View File

@@ -55,6 +55,7 @@ export const ProviderButton = () => {
<Typography variant="h6">{t("Proxy Provider")}</Typography>
<Button
variant="contained"
size="small"
onClick={async () => {
Object.entries(data || {}).forEach(async ([key, item]) => {
await proxyProviderUpdate(key);

View File

@@ -53,6 +53,7 @@ export const ProviderButton = () => {
<Typography variant="h6">{t("Rule Provider")}</Typography>
<Button
variant="contained"
size="small"
onClick={async () => {
Object.entries(data || {}).forEach(async ([key, item]) => {
await ruleProviderUpdate(key);

View File

@@ -194,7 +194,7 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
spellCheck="false"
sx={{ width: 250 }}
value={values.defaultLatencyTimeout}
placeholder="http://1.1.1.1"
placeholder="10000"
onChange={(e) =>
setValues((v) => ({
...v,

View File

@@ -0,0 +1,71 @@
import { useTranslation } from "react-i18next";
import { Button, ButtonGroup, Tooltip } from "@mui/material";
import { checkService } from "@/services/cmds";
import { useVerge } from "@/hooks/use-verge";
import getSystem from "@/utils/get-system";
import useSWR from "swr";
const isWIN = getSystem() === "windows";
interface Props {
value?: string;
onChange?: (value: string) => void;
}
export const StackModeSwitch = (props: Props) => {
const { value, onChange } = props;
const { verge } = useVerge();
const { enable_service_mode } = verge ?? {};
// service mode
const { data: serviceStatus } = useSWR(
isWIN ? "checkService" : null,
checkService,
{
revalidateIfStale: false,
shouldRetryOnError: false,
}
);
const { t } = useTranslation();
return (
<Tooltip
title={
isWIN && (serviceStatus !== "active" || !enable_service_mode)
? t("System and Mixed Can Only be Used in Service Mode")
: ""
}
>
<ButtonGroup size="small" sx={{ my: "4px" }}>
<Button
variant={value?.toLowerCase() === "system" ? "contained" : "outlined"}
onClick={() => onChange?.("system")}
disabled={
isWIN && (serviceStatus !== "active" || !enable_service_mode)
}
sx={{ textTransform: "capitalize" }}
>
System
</Button>
<Button
variant={value?.toLowerCase() === "gvisor" ? "contained" : "outlined"}
onClick={() => onChange?.("gvisor")}
sx={{ textTransform: "capitalize" }}
>
gVisor
</Button>
<Button
variant={value?.toLowerCase() === "mixed" ? "contained" : "outlined"}
onClick={() => onChange?.("mixed")}
disabled={
isWIN && (serviceStatus !== "active" || !enable_service_mode)
}
sx={{ textTransform: "capitalize" }}
>
Mixed
</Button>
</ButtonGroup>
</Tooltip>
);
};

View File

@@ -5,13 +5,15 @@ import {
List,
ListItem,
ListItemText,
MenuItem,
Select,
Box,
Typography,
Button,
Switch,
TextField,
} from "@mui/material";
import { useClash } from "@/hooks/use-clash";
import { BaseDialog, DialogRef, Notice } from "@/components/base";
import { StackModeSwitch } from "./stack-mode-switch";
export const TunViewer = forwardRef<DialogRef>((props, ref) => {
const { t } = useTranslation();
@@ -20,12 +22,12 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
const [open, setOpen] = useState(false);
const [values, setValues] = useState({
stack: "gVisor",
device: "Mihomo",
stack: "gvisor",
device: "Meta",
autoRoute: true,
autoDetectInterface: true,
dnsHijack: ["any:53", "tcp://any:53"],
strictRoute: true,
dnsHijack: ["any:53"],
strictRoute: false,
mtu: 9000,
});
@@ -33,12 +35,12 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
open: () => {
setOpen(true);
setValues({
stack: clash?.tun.stack ?? "gVisor",
device: clash?.tun.device ?? "Mihomo",
stack: clash?.tun.stack ?? "gvisor",
device: clash?.tun.device ?? "Meta",
autoRoute: clash?.tun["auto-route"] ?? true,
autoDetectInterface: clash?.tun["auto-detect-interface"] ?? true,
dnsHijack: clash?.tun["dns-hijack"] ?? ["any:53", "tcp://any:53"],
strictRoute: clash?.tun["strict-route"] ?? true,
dnsHijack: clash?.tun["dns-hijack"] ?? ["any:53"],
strictRoute: clash?.tun["strict-route"] ?? false,
mtu: clash?.tun.mtu ?? 9000,
});
},
@@ -73,7 +75,45 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
return (
<BaseDialog
open={open}
title={t("Tun Mode")}
title={
<Box display="flex" justifyContent="space-between" gap={1}>
<Typography variant="h6">{t("Tun Mode")}</Typography>
<Button
variant="outlined"
size="small"
onClick={async () => {
let tun = {
stack: "gvisor",
device: "Meta",
"auto-route": true,
"auto-detect-interface": true,
"dns-hijack": ["any:53"],
"strict-route": false,
mtu: 9000,
};
setValues({
stack: "gvisor",
device: "Meta",
autoRoute: true,
autoDetectInterface: true,
dnsHijack: ["any:53"],
strictRoute: false,
mtu: 9000,
});
await patchClash({ tun });
await mutateClash(
(old) => ({
...(old! || {}),
tun,
}),
false
);
}}
>
{t("Reset to Default")}
</Button>
</Box>
}
contentSx={{ width: 450 }}
okBtn={t("Save")}
cancelBtn={t("Cancel")}
@@ -84,23 +124,15 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
<List>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary={t("Stack")} />
<Select
size="small"
sx={{ width: 100, "> div": { py: "7.5px" } }}
<StackModeSwitch
value={values.stack}
onChange={(e) => {
onChange={(value) => {
setValues((v) => ({
...v,
stack: e.target.value as string,
stack: value,
}));
}}
>
{["System", "gVisor", "Mixed"].map((i) => (
<MenuItem value={i} key={i}>
{i}
</MenuItem>
))}
</Select>
/>
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
@@ -113,7 +145,7 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
spellCheck="false"
sx={{ width: 250 }}
value={values.device}
placeholder="Mihomo"
placeholder="Meta"
onChange={(e) =>
setValues((v) => ({ ...v, device: e.target.value }))
}

View File

@@ -1,17 +1,16 @@
import useSWR, { mutate } from "swr";
import { useLockFn } from "ahooks";
import { getAxios, getVersion, updateConfigs } from "@/services/api";
import {
getAxios,
getClashConfig,
getVersion,
updateConfigs,
} from "@/services/api";
import { getClashInfo, patchClashConfig } from "@/services/cmds";
getClashInfo,
patchClashConfig,
getRuntimeConfig,
} from "@/services/cmds";
export const useClash = () => {
const { data: clash, mutate: mutateClash } = useSWR(
"getClashConfig",
getClashConfig
"getRuntimeConfig",
getRuntimeConfig
);
const { data: versionData, mutate: mutateVersion } = useSWR(

View File

@@ -160,7 +160,16 @@
"Retain 30 Days": "Retain 30 Days",
"Retain 90 Days": "Retain 90 Days",
"Stack": "Tun Stack",
"Device": "Device Name",
"Auto Route": "Auto Route",
"Strict Route": "Strict Route",
"Auto Detect Interface": "Auto Detect Interface",
"DNS Hijack": "DNS Hijack",
"MTU": "Max Transmission Unit",
"Portable Updater Error": "The portable version does not support in-app updates. Please manually download and replace it",
"Tun Mode Info Windows": "The Tun mode requires granting core-related permissions. Please enable service mode before using it",
"Tun Mode Info Unix": "The Tun mode requires granting core-related permissions. Before using it, please authorize the core in the core settings"
"Tun Mode Info Unix": "The Tun mode requires granting core-related permissions. Before using it, please authorize the core in the core settings",
"System and Mixed Can Only be Used in Service Mode": "System and Mixed Can Only be Used in Service Mode"
}

View File

@@ -160,7 +160,17 @@
"Retain 30 Days": "保留30天",
"Retain 90 Days": "保留90天",
"Stack": "Tun 模式堆栈",
"Device": "Tun 网卡名称",
"Auto Route": "自动设置全局路由",
"Strict Route": "严格路由",
"Auto Detect Interface": "自动选择流量出口接口",
"DNS Hijack": "DNS 劫持",
"MTU": "最大传输单元",
"Reset to Default": "重置为默认值",
"Portable Updater Error": "便携版不支持应用内更新,请手动下载替换",
"Tun Mode Info Windows": "Tun模式需要授予内核相关权限使用前请先开启服务模式",
"Tun Mode Info Unix": "Tun模式需要授予内核相关权限使用前请先在内核设置中给内核授权"
"Tun Mode Info Unix": "Tun模式需要授予内核相关权限使用前请先在内核设置中给内核授权",
"System and Mixed Can Only be Used in Service Mode": "System和Mixed只能在服务模式下使用"
}

View File

@@ -90,8 +90,9 @@ export async function getClashInfo() {
return invoke<IClashInfo | null>("get_clash_info");
}
// Get runtime config which controlled by verge
export async function getRuntimeConfig() {
return invoke<any | null>("get_runtime_config");
return invoke<IConfigData | null>("get_runtime_config");
}
export async function getRuntimeYaml() {