feat: handle remote clash config fields

This commit is contained in:
GyDi 2022-04-07 01:20:44 +08:00
parent 6ade0b2b1a
commit fd99ba6255
No known key found for this signature in database
GPG Key ID: 1C95E0D3467B3084
7 changed files with 146 additions and 7 deletions

View File

@ -125,6 +125,23 @@ pub fn change_profile_chain(
wrap_err!(clash.activate_enhanced(&profiles, false, false)) wrap_err!(clash.activate_enhanced(&profiles, false, false))
} }
/// change the profile valid fields
#[tauri::command]
pub fn change_profile_valid(
valid: Option<Vec<String>>,
app_handle: tauri::AppHandle,
clash_state: State<'_, ClashState>,
profiles_state: State<'_, ProfilesState>,
) -> Result<(), String> {
let mut clash = clash_state.0.lock().unwrap();
let mut profiles = profiles_state.0.lock().unwrap();
profiles.put_valid(valid);
clash.set_window(app_handle.get_window("main"));
wrap_err!(clash.activate_enhanced(&profiles, false, false))
}
/// manually exec enhanced profile /// manually exec enhanced profile
#[tauri::command] #[tauri::command]
pub fn enhance_profiles( pub fn enhance_profiles(

View File

@ -316,6 +316,9 @@ pub struct Profiles {
/// same as PrfConfig.chain /// same as PrfConfig.chain
chain: Option<Vec<String>>, chain: Option<Vec<String>>,
/// record valid fields for clash
valid: Option<Vec<String>>,
/// profile list /// profile list
items: Option<Vec<PrfItem>>, items: Option<Vec<PrfItem>>,
} }
@ -399,6 +402,11 @@ impl Profiles {
self.chain = chain; self.chain = chain;
} }
/// just change the `field`
pub fn put_valid(&mut self, valid: Option<Vec<String>>) {
self.valid = valid;
}
/// find the item by the uid /// find the item by the uid
pub fn get_item(&self, uid: &String) -> Result<&PrfItem> { pub fn get_item(&self, uid: &String) -> Result<&PrfItem> {
if self.items.is_some() { if self.items.is_some() {
@ -599,9 +607,12 @@ impl Profiles {
None => vec![], None => vec![],
}; };
let valid = self.valid.clone().unwrap_or(vec![]);
Ok(PrfEnhanced { Ok(PrfEnhanced {
current, current,
chain, chain,
valid,
callback, callback,
}) })
} }
@ -613,6 +624,8 @@ pub struct PrfEnhanced {
pub chain: Vec<PrfData>, pub chain: Vec<PrfData>,
pub valid: Vec<String>,
pub callback: String, pub callback: String,
} }

View File

@ -119,6 +119,7 @@ fn main() -> std::io::Result<()> {
cmds::sync_profiles, cmds::sync_profiles,
cmds::enhance_profiles, cmds::enhance_profiles,
cmds::change_profile_chain, cmds::change_profile_chain,
cmds::change_profile_valid,
cmds::read_profile_file, cmds::read_profile_file,
cmds::save_profile_file cmds::save_profile_file
]); ]);

View File

@ -1,26 +1,49 @@
import useSWR from "swr"; import useSWR from "swr";
import { useState } from "react";
import { useLockFn } from "ahooks"; import { useLockFn } from "ahooks";
import { Box, Grid, IconButton, Stack } from "@mui/material"; import {
import { RestartAltRounded } from "@mui/icons-material"; Box,
Divider,
Grid,
IconButton,
ListItemIcon,
ListItemText,
Menu,
MenuItem,
Stack,
} from "@mui/material";
import {
AddchartRounded,
CheckRounded,
MenuRounded,
RestartAltRounded,
} from "@mui/icons-material";
import { import {
getProfiles, getProfiles,
deleteProfile, deleteProfile,
enhanceProfiles, enhanceProfiles,
changeProfileChain, changeProfileChain,
changeProfileValid,
} from "../../services/cmds"; } from "../../services/cmds";
import { CmdType } from "../../services/types"; import { CmdType } from "../../services/types";
import Notice from "../base/base-notice"; import getSystem from "../../utils/get-system";
import ProfileMore from "./profile-more"; import ProfileMore from "./profile-more";
import Notice from "../base/base-notice";
interface Props { interface Props {
items: CmdType.ProfileItem[]; items: CmdType.ProfileItem[];
chain: string[]; chain: string[];
} }
const OS = getSystem();
const EnhancedMode = (props: Props) => { const EnhancedMode = (props: Props) => {
const { items, chain } = props; const { items, chain } = props;
const { mutate } = useSWR("getProfiles", getProfiles); const { data, mutate } = useSWR("getProfiles", getProfiles);
const valid = data?.valid || [];
const [anchorEl, setAnchorEl] = useState<any>(null);
// handler // handler
const onEnhance = useLockFn(async () => { const onEnhance = useLockFn(async () => {
@ -74,6 +97,19 @@ const EnhancedMode = (props: Props) => {
mutate((conf = {}) => ({ ...conf, chain: newChain }), true); mutate((conf = {}) => ({ ...conf, chain: newChain }), true);
}); });
// update valid list
const onToggleValid = useLockFn(async (key: string) => {
try {
const newValid = valid.includes(key)
? valid.filter((i) => i !== key)
: valid.concat(key);
await changeProfileValid(newValid);
mutate();
} catch (err: any) {
Notice.error(err.message || err.toString());
}
});
return ( return (
<Box sx={{ mt: 4 }}> <Box sx={{ mt: 4 }}>
<Stack <Stack
@ -92,9 +128,74 @@ const EnhancedMode = (props: Props) => {
<RestartAltRounded /> <RestartAltRounded />
</IconButton> </IconButton>
{/* <IconButton size="small" color="inherit"> <IconButton
size="small"
color="inherit"
id="profile-use-button"
title="enable clash fields"
aria-controls={!!anchorEl ? "profile-use-menu" : undefined}
aria-haspopup="true"
aria-expanded={!!anchorEl ? "true" : undefined}
onClick={(e) => setAnchorEl(e.currentTarget)}
>
<MenuRounded /> <MenuRounded />
</IconButton> */} </IconButton>
<Menu
id="profile-use-menu"
open={!!anchorEl}
anchorEl={anchorEl}
onClose={() => setAnchorEl(null)}
transitionDuration={225}
TransitionProps={
OS === "macos" ? { style: { transitionDuration: "225ms" } } : {}
}
MenuListProps={{
dense: true,
"aria-labelledby": "profile-use-button",
}}
onContextMenu={(e) => {
setAnchorEl(null);
e.preventDefault();
}}
>
<MenuItem>
<ListItemIcon color="inherit">
<AddchartRounded />
</ListItemIcon>
Use Clash Fields
</MenuItem>
<Divider />
{[
"tun",
"dns",
"hosts",
"script",
"profile",
"payload",
"interface-name",
"routing-mark",
].map((key) => {
const has = valid.includes(key);
return (
<MenuItem
key={key}
sx={{ width: 180 }}
onClick={() => onToggleValid(key)}
>
{has && (
<ListItemIcon color="inherit">
<CheckRounded />
</ListItemIcon>
)}
<ListItemText inset={!has}>{key}</ListItemText>
</MenuItem>
);
})}
</Menu>
</Stack> </Stack>
<Grid container spacing={2}> <Grid container spacing={2}>

View File

@ -66,6 +66,10 @@ export async function changeProfileChain(chain?: string[]) {
return invoke<void>("change_profile_chain", { chain }); return invoke<void>("change_profile_chain", { chain });
} }
export async function changeProfileValid(valid?: string[]) {
return invoke<void>("change_profile_valid", { valid });
}
export async function getClashInfo() { export async function getClashInfo() {
return invoke<CmdType.ClashInfo | null>("get_clash_info"); return invoke<CmdType.ClashInfo | null>("get_clash_info");
} }

View File

@ -145,11 +145,12 @@ class Enhance {
// enhanced mode runner // enhanced mode runner
private async runner(payload: CmdType.EnhancedPayload) { private async runner(payload: CmdType.EnhancedPayload) {
const chain = payload.chain || []; const chain = payload.chain || [];
const valid = payload.valid || [];
if (!Array.isArray(chain)) throw new Error("unhandle error"); if (!Array.isArray(chain)) throw new Error("unhandle error");
let pdata = payload.current || {}; let pdata = payload.current || {};
let useList = [] as string[]; let useList = valid;
for (const each of chain) { for (const each of chain) {
const { uid, type = "" } = each.item; const { uid, type = "" } = each.item;

View File

@ -116,6 +116,7 @@ export namespace CmdType {
export interface ProfilesConfig { export interface ProfilesConfig {
current?: string; current?: string;
chain?: string[]; chain?: string[];
valid?: string[];
items?: ProfileItem[]; items?: ProfileItem[];
} }
@ -191,6 +192,7 @@ export namespace CmdType {
export interface EnhancedPayload { export interface EnhancedPayload {
chain: ChainItem[]; chain: ChainItem[];
valid: string[];
current: ProfileData; current: ProfileData;
callback: string; callback: string;
} }