Compare commits
8 Commits
v1.6.1
...
dependenci
@@ -37,7 +37,7 @@ serde = { version = "1.0", features = ["derive"] }
|
||||
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 = [ "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
|
||||
tauri = { version = "1.6", features = [ "fs-read-file", "fs-exists", "path-all", "protocol-asset", "dialog-open", "notification-all", "icon-png", "icon-ico", "clipboard-all", "global-shortcut-all", "process-all", "shell-all", "system-tray", "updater", "window-all", "devtools"] }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
runas = "=1.2.0"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
function main(params) {
|
||||
if (params.mode === "script") {
|
||||
params.mode = "rule";
|
||||
function main(config) {
|
||||
if (config.mode === "script") {
|
||||
config.mode = "rule";
|
||||
}
|
||||
return params;
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
function main(params) {
|
||||
if (Array.isArray(params.proxies)) {
|
||||
params.proxies.forEach((p, i) => {
|
||||
function main(config) {
|
||||
if (Array.isArray(config.proxies)) {
|
||||
config.proxies.forEach((p, i) => {
|
||||
if (p.type === "hysteria" && typeof p.alpn === "string") {
|
||||
params.proxies[i].alpn = [p.alpn];
|
||||
config.proxies[i].alpn = [p.alpn];
|
||||
}
|
||||
});
|
||||
}
|
||||
return params;
|
||||
return config;
|
||||
}
|
||||
|
||||
@@ -42,8 +42,19 @@ pub fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
|
||||
let resource_dir = dirs::app_resources_dir().unwrap();
|
||||
let script = resource_dir.join("set_dns.sh");
|
||||
let script = script.to_string_lossy();
|
||||
match Command::new("bash").args([script]).output() {
|
||||
Ok(_) => log::info!(target: "app", "set system dns successfully"),
|
||||
match Command::new("bash")
|
||||
.args([script])
|
||||
.current_dir(resource_dir)
|
||||
.status()
|
||||
{
|
||||
Ok(status) => {
|
||||
if status.success() {
|
||||
log::info!(target: "app", "set system dns successfully");
|
||||
} else {
|
||||
let code = status.code().unwrap_or(-1);
|
||||
log::error!(target: "app", "set system dns failed: {code}");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!(target: "app", "set system dns failed: {err}");
|
||||
}
|
||||
@@ -59,8 +70,19 @@ pub fn use_tun(mut config: Mapping, enable: bool) -> Mapping {
|
||||
let resource_dir = dirs::app_resources_dir().unwrap();
|
||||
let script = resource_dir.join("unset_dns.sh");
|
||||
let script = script.to_string_lossy();
|
||||
match Command::new("bash").args([script]).output() {
|
||||
Ok(_) => log::info!(target: "app", "unset system dns successfully"),
|
||||
match Command::new("bash")
|
||||
.args([script])
|
||||
.current_dir(resource_dir)
|
||||
.status()
|
||||
{
|
||||
Ok(status) => {
|
||||
if status.success() {
|
||||
log::info!(target: "app", "unset system dns successfully");
|
||||
} else {
|
||||
let code = status.code().unwrap_or(-1);
|
||||
log::error!(target: "app", "unset system dns failed: {code}");
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
log::error!(target: "app", "unset system dns failed: {err}");
|
||||
}
|
||||
|
||||
@@ -299,7 +299,7 @@ pub fn copy_clash_env(app_handle: &AppHandle) {
|
||||
|
||||
let sh =
|
||||
format!("export https_proxy={http_proxy} http_proxy={http_proxy} all_proxy={socks5_proxy}");
|
||||
let cmd: String = format!("set http_proxy={http_proxy} \n set https_proxy={http_proxy}");
|
||||
let cmd: String = format!("set http_proxy={http_proxy}\r\nset https_proxy={http_proxy}");
|
||||
let ps: String = format!("$env:HTTP_PROXY=\"{http_proxy}\"; $env:HTTPS_PROXY=\"{http_proxy}\"");
|
||||
|
||||
let mut cliboard = app_handle.clipboard_manager();
|
||||
|
||||
@@ -20,6 +20,9 @@ fn main() -> std::io::Result<()> {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
std::env::set_var("WEBKIT_DISABLE_DMABUF_RENDERER", "1");
|
||||
|
||||
crate::log_err!(init::init_config());
|
||||
|
||||
#[allow(unused_mut)]
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
//! Some config file template
|
||||
|
||||
/// template for new a profile item
|
||||
pub const ITEM_LOCAL: &str = "# Profile Template for clash verge
|
||||
pub const ITEM_LOCAL: &str = "# Profile Template for Clash Verge
|
||||
|
||||
proxies:
|
||||
proxies: []
|
||||
|
||||
proxy-groups:
|
||||
proxy-groups: []
|
||||
|
||||
rules:
|
||||
rules: []
|
||||
";
|
||||
|
||||
/// enhanced profile
|
||||
pub const ITEM_MERGE: &str = "# Merge Template for clash verge
|
||||
# The `Merge` format used to enhance profile
|
||||
pub const ITEM_MERGE: &str = "# Profile Enhancement Merge Template for Clash Verge
|
||||
|
||||
prepend-rules: []
|
||||
|
||||
@@ -36,9 +35,9 @@ append-proxy-groups: []
|
||||
";
|
||||
|
||||
/// enhanced profile
|
||||
pub const ITEM_SCRIPT: &str = "// Define the `main` function
|
||||
pub const ITEM_SCRIPT: &str = "// Define main function (script entry)
|
||||
|
||||
function main(params) {
|
||||
return params;
|
||||
function main(config) {
|
||||
return config;
|
||||
}
|
||||
";
|
||||
|
||||
@@ -69,7 +69,8 @@
|
||||
},
|
||||
"fs": {
|
||||
"exists": true,
|
||||
"scope": ["$APPDATA/**", "$RESOURCE/../**"]
|
||||
"readFile": true,
|
||||
"scope": ["$APPDATA/**", "$RESOURCE/../**", "**"]
|
||||
}
|
||||
},
|
||||
"windows": [],
|
||||
|
||||
@@ -86,12 +86,15 @@ export const ServiceViewer = forwardRef<DialogRef, Props>((props, ref) => {
|
||||
disableFooter
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
<Typography>Current State: {state}</Typography>
|
||||
<Typography>
|
||||
{t("Current State")}: {t(state)}
|
||||
</Typography>
|
||||
|
||||
{(state === "unknown" || state === "uninstall") && (
|
||||
<Typography>
|
||||
Information: Please make sure that the Clash Verge Service is
|
||||
installed and enabled
|
||||
{t(
|
||||
"Information: Please make sure that the Clash Verge Service is installed and enabled"
|
||||
)}
|
||||
</Typography>
|
||||
)}
|
||||
|
||||
@@ -102,19 +105,19 @@ export const ServiceViewer = forwardRef<DialogRef, Props>((props, ref) => {
|
||||
>
|
||||
{state === "uninstall" && enable && (
|
||||
<Button variant="contained" onClick={onDisable}>
|
||||
Disable Service Mode
|
||||
{t("Disable Service Mode")}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{state === "uninstall" && (
|
||||
<Button variant="contained" onClick={onInstall}>
|
||||
Install
|
||||
{t("Install")}
|
||||
</Button>
|
||||
)}
|
||||
|
||||
{(state === "active" || state === "installed") && (
|
||||
<Button variant="outlined" onClick={onUninstall}>
|
||||
Uninstall
|
||||
{t("Uninstall")}
|
||||
</Button>
|
||||
)}
|
||||
</Stack>
|
||||
|
||||
@@ -13,6 +13,7 @@ import {
|
||||
import { useClash } from "@/hooks/use-clash";
|
||||
import { BaseDialog, DialogRef, Notice, Switch } from "@/components/base";
|
||||
import { StackModeSwitch } from "./stack-mode-switch";
|
||||
import { enhanceProfiles } from "@/services/cmds";
|
||||
|
||||
export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
@@ -65,6 +66,12 @@ export const TunViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
}),
|
||||
false
|
||||
);
|
||||
try {
|
||||
await enhanceProfiles();
|
||||
Notice.success("Refresh clash config", 1000);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString(), 3000);
|
||||
}
|
||||
setOpen(false);
|
||||
} catch (err: any) {
|
||||
Notice.error(err.message || err.toString());
|
||||
|
||||
@@ -185,9 +185,20 @@
|
||||
"MTU": "Max Transmission Unit",
|
||||
"Reset to Default": "Reset to Default",
|
||||
|
||||
"Current State": "Current State",
|
||||
"pending": "pending",
|
||||
"installed": "installed",
|
||||
"uninstall": "uninstalled",
|
||||
"active": "active",
|
||||
"unknown": "unknown",
|
||||
"Disable Service Mode": "Disable Service Mode",
|
||||
"Install": "Install",
|
||||
"Uninstall": "Uninstall",
|
||||
|
||||
"Portable Updater Error": "The portable version does not support in-app updates. Please manually download and replace it",
|
||||
"Tun Mode Info": "The Tun mode requires granting core-related permissions. Please enable service mode before using it",
|
||||
"System and Mixed Can Only be Used in Service Mode": "System and Mixed Can Only be Used in Service Mode",
|
||||
"Information: Please make sure that the Clash Verge Service is installed and enabled": "Information: Please make sure that the Clash Verge Service is installed and enabled",
|
||||
|
||||
"Use Regular Expression": "Use Regular Expression"
|
||||
}
|
||||
|
||||
@@ -185,9 +185,20 @@
|
||||
"MTU": "Максимальная единица передачи",
|
||||
"Reset to Default": "Сбросить настройки по умолчанию",
|
||||
|
||||
"Current State": "Текущее состояние",
|
||||
"pending": "Ожидающий",
|
||||
"installed": "Установленный",
|
||||
"uninstall": "Не установленный",
|
||||
"active": "Активированный",
|
||||
"unknown": "неизвестный",
|
||||
"Disable Service Mode": "Отключить режим обслуживания",
|
||||
"Install": "Установить",
|
||||
"Uninstall": "Удалить",
|
||||
|
||||
"Portable Updater Error": "Портативная версия не поддерживает обновление внутри приложения, пожалуйста, скачайте и замените вручную",
|
||||
"Tun Mode Info": "Режим туннеля требует предоставления разрешений, связанных с ядром. Пожалуйста, включите сервисный режим перед его использованием",
|
||||
"System and Mixed Can Only be Used in Service Mode": "Система и смешанные могут использоваться только в сервисном режиме",
|
||||
"Information: Please make sure that the Clash Verge Service is installed and enabled": "Информация: Пожалуйста, убедитесь, что сервис Clash Verge Service установлен и включен",
|
||||
|
||||
"Use Regular Expression": "Использование регулярных выражений"
|
||||
}
|
||||
|
||||
@@ -185,9 +185,20 @@
|
||||
"MTU": "最大传输单元",
|
||||
"Reset to Default": "重置为默认值",
|
||||
|
||||
"Current State": "当前状态",
|
||||
"pending": "等待中",
|
||||
"installed": "已安装",
|
||||
"uninstall": "未安装",
|
||||
"active": "已激活",
|
||||
"unknown": "未知",
|
||||
"Disable Service Mode": "禁用服务模式",
|
||||
"Install": "安装",
|
||||
"Uninstall": "卸载",
|
||||
|
||||
"Portable Updater Error": "便携版不支持应用内更新,请手动下载替换",
|
||||
"Tun Mode Info": "Tun模式需要授予内核相关权限,使用前请先开启服务模式",
|
||||
"System and Mixed Can Only be Used in Service Mode": "System和Mixed只能在服务模式下使用",
|
||||
"Information: Please make sure that the Clash Verge Service is installed and enabled": "提示信息: 请确保Clash Verge Service已安装并启用",
|
||||
|
||||
"Use Regular Expression": "使用正则表达式"
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import useSWR, { mutate } from "swr";
|
||||
import { useMemo, useRef, useState } from "react";
|
||||
import { useEffect, useMemo, useRef, useState } from "react";
|
||||
import { useLockFn } from "ahooks";
|
||||
import { useSetRecoilState } from "recoil";
|
||||
import { Box, Button, Grid, IconButton, Stack, Divider } from "@mui/material";
|
||||
@@ -33,6 +33,7 @@ import {
|
||||
deleteProfile,
|
||||
updateProfile,
|
||||
reorderProfile,
|
||||
createProfile,
|
||||
} from "@/services/cmds";
|
||||
import { atomLoadingCache } from "@/services/states";
|
||||
import { closeAllConnections } from "@/services/api";
|
||||
@@ -49,6 +50,8 @@ import { throttle } from "lodash-es";
|
||||
import { useRecoilState } from "recoil";
|
||||
import { atomThemeMode } from "@/services/states";
|
||||
import { BaseStyledTextField } from "@/components/base/base-styled-text-field";
|
||||
import { listen } from "@tauri-apps/api/event";
|
||||
import { readTextFile } from "@tauri-apps/api/fs";
|
||||
|
||||
const ProfilePage = () => {
|
||||
const { t } = useTranslation();
|
||||
@@ -63,6 +66,35 @@ const ProfilePage = () => {
|
||||
coordinateGetter: sortableKeyboardCoordinates,
|
||||
})
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
const unlisten = listen("tauri://file-drop", async (event) => {
|
||||
const fileList = event.payload as string[];
|
||||
for (let file of fileList) {
|
||||
if (!file.endsWith(".yaml") && !file.endsWith(".yml")) {
|
||||
Notice.error("Only support YAML files.");
|
||||
continue;
|
||||
}
|
||||
const item = {
|
||||
type: "local",
|
||||
name: file.split(/\/|\\/).pop() ?? "New Profile",
|
||||
desc: "",
|
||||
url: "",
|
||||
option: {
|
||||
with_proxy: false,
|
||||
self_proxy: false,
|
||||
},
|
||||
} as IProfileItem;
|
||||
let data = await readTextFile(file);
|
||||
await createProfile(item, data);
|
||||
await mutateProfiles();
|
||||
}
|
||||
});
|
||||
return () => {
|
||||
unlisten.then((fn) => fn());
|
||||
};
|
||||
}, []);
|
||||
|
||||
const {
|
||||
profiles = {},
|
||||
activateSelected,
|
||||
|
||||
Reference in New Issue
Block a user