mirror of
https://github.com/clash-verge-rev/clash-verge-rev.git
synced 2026-01-29 17:15:38 +08:00
refactor: Remove clash field filter
This commit is contained in:
@@ -1,123 +0,0 @@
|
||||
import useSWR from "swr";
|
||||
import { forwardRef, useImperativeHandle, useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Checkbox, Divider, Stack, Tooltip, Typography } from "@mui/material";
|
||||
import { InfoRounded } from "@mui/icons-material";
|
||||
import { getRuntimeExists } from "@/services/cmds";
|
||||
import {
|
||||
HANDLE_FIELDS,
|
||||
DEFAULT_FIELDS,
|
||||
OTHERS_FIELDS,
|
||||
} from "@/utils/clash-fields";
|
||||
import { BaseDialog, DialogRef } from "@/components/base";
|
||||
import { useProfiles } from "@/hooks/use-profiles";
|
||||
import { Notice } from "@/components/base";
|
||||
|
||||
const otherFields = [...OTHERS_FIELDS];
|
||||
const handleFields = [...HANDLE_FIELDS, ...DEFAULT_FIELDS];
|
||||
|
||||
export const ClashFieldViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const { profiles = {}, patchProfiles } = useProfiles();
|
||||
const { data: existsKeys = [], mutate: mutateExists } = useSWR(
|
||||
"getRuntimeExists",
|
||||
getRuntimeExists
|
||||
);
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [selected, setSelected] = useState<string[]>([]);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
mutateExists();
|
||||
setSelected(profiles.valid || []);
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => setOpen(false),
|
||||
}));
|
||||
|
||||
const handleChange = (item: string) => {
|
||||
if (!item) return;
|
||||
|
||||
setSelected((old) =>
|
||||
old.includes(item) ? old.filter((e) => e !== item) : [...old, item]
|
||||
);
|
||||
};
|
||||
|
||||
const handleSave = async () => {
|
||||
setOpen(false);
|
||||
|
||||
const oldSet = new Set(profiles.valid || []);
|
||||
const curSet = new Set(selected);
|
||||
const joinSet = new Set(selected.concat([...oldSet]));
|
||||
|
||||
if (curSet.size === oldSet.size && curSet.size === joinSet.size) return;
|
||||
|
||||
try {
|
||||
await patchProfiles({ valid: [...curSet] });
|
||||
// Notice.success("Refresh clash config", 1000);
|
||||
} catch (err: any) {
|
||||
Notice.error(err?.message || err.toString());
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<BaseDialog
|
||||
open={open}
|
||||
title={t("Clash Field")}
|
||||
contentSx={{
|
||||
pb: 0,
|
||||
width: 320,
|
||||
height: 300,
|
||||
overflowY: "auto",
|
||||
userSelect: "text",
|
||||
}}
|
||||
okBtn={t("Save")}
|
||||
cancelBtn={t("Back")}
|
||||
onClose={() => setOpen(false)}
|
||||
onCancel={() => setOpen(false)}
|
||||
onOk={handleSave}
|
||||
>
|
||||
{otherFields.map((item) => {
|
||||
const inSelect = selected.includes(item);
|
||||
const inConfig = existsKeys.includes(item);
|
||||
|
||||
return (
|
||||
<Stack key={item} mb={0.5} direction="row" alignItems="center">
|
||||
<Checkbox
|
||||
checked={inSelect}
|
||||
size="small"
|
||||
sx={{ p: 0.5 }}
|
||||
onChange={() => handleChange(item)}
|
||||
/>
|
||||
<Typography width="100%">{item}</Typography>
|
||||
|
||||
{!inSelect && inConfig && <WarnIcon />}
|
||||
</Stack>
|
||||
);
|
||||
})}
|
||||
|
||||
<Divider sx={{ my: 1 }}>
|
||||
<Typography color="text.secondary" fontSize={14}>
|
||||
Clash Verge Control Fields
|
||||
</Typography>
|
||||
</Divider>
|
||||
|
||||
{handleFields.map((item) => (
|
||||
<Stack key={item} mb={0.5} direction="row" alignItems="center">
|
||||
<Checkbox defaultChecked disabled size="small" sx={{ p: 0.5 }} />
|
||||
<Typography>{item}</Typography>
|
||||
</Stack>
|
||||
))}
|
||||
</BaseDialog>
|
||||
);
|
||||
});
|
||||
|
||||
function WarnIcon() {
|
||||
return (
|
||||
<Tooltip title="The field exists in the config but not enabled.">
|
||||
<InfoRounded color="warning" sx={{ cursor: "pointer", opacity: 0.5 }} />
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
@@ -13,26 +13,42 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const { verge, patchVerge } = useVerge();
|
||||
|
||||
const [open, setOpen] = useState(false);
|
||||
const [mixedPort, setMixedPort] = useState(
|
||||
verge?.verge_mixed_port ?? clashInfo?.mixed_port ?? 7897
|
||||
);
|
||||
const [socksPort, setSocksPort] = useState(
|
||||
verge?.verge_socks_port ?? clashInfo?.socks_port ?? 7898
|
||||
);
|
||||
const [port, setPort] = useState(
|
||||
verge?.verge_mixed_port ?? clashInfo?.port ?? 7897
|
||||
verge?.verge_port ?? clashInfo?.port ?? 7899
|
||||
);
|
||||
|
||||
useImperativeHandle(ref, () => ({
|
||||
open: () => {
|
||||
if (verge?.verge_mixed_port) setPort(verge?.verge_mixed_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);
|
||||
setOpen(true);
|
||||
},
|
||||
close: () => setOpen(false),
|
||||
}));
|
||||
|
||||
const onSave = useLockFn(async () => {
|
||||
if (port === verge?.verge_mixed_port) {
|
||||
if (
|
||||
mixedPort === verge?.verge_mixed_port &&
|
||||
socksPort === verge?.verge_socks_port &&
|
||||
port === verge?.verge_port
|
||||
) {
|
||||
setOpen(false);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
await patchInfo({ "mixed-port": port });
|
||||
await patchVerge({ verge_mixed_port: port });
|
||||
await patchInfo({ "mixed-port": mixedPort });
|
||||
await patchInfo({ "socks-port": socksPort });
|
||||
await patchInfo({ port });
|
||||
await patchVerge({ verge_mixed_port: mixedPort });
|
||||
await patchVerge({ verge_socks_port: socksPort });
|
||||
await patchVerge({ verge_port: port });
|
||||
setOpen(false);
|
||||
Notice.success("Change Clash port successfully!", 1000);
|
||||
} catch (err: any) {
|
||||
@@ -54,6 +70,30 @@ export const ClashPortViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
<List>
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Mixed Port" />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
sx={{ width: 135 }}
|
||||
value={mixedPort}
|
||||
onChange={(e) =>
|
||||
setMixedPort(+e.target.value?.replace(/\D+/, "").slice(0, 5))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Socks Port" />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
sx={{ width: 135 }}
|
||||
value={socksPort}
|
||||
onChange={(e) =>
|
||||
setSocksPort(+e.target.value?.replace(/\D+/, "").slice(0, 5))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary="Http Port" />
|
||||
<TextField
|
||||
size="small"
|
||||
autoComplete="off"
|
||||
|
||||
@@ -21,7 +21,6 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
const [values, setValues] = useState({
|
||||
appLogLevel: "info",
|
||||
autoCloseConnection: true,
|
||||
enableClashFields: true,
|
||||
enableBuiltinEnhanced: true,
|
||||
proxyLayoutColumn: 6,
|
||||
defaultLatencyTest: "",
|
||||
@@ -34,7 +33,6 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
setValues({
|
||||
appLogLevel: verge?.app_log_level ?? "info",
|
||||
autoCloseConnection: verge?.auto_close_connection ?? true,
|
||||
enableClashFields: verge?.enable_clash_fields ?? true,
|
||||
enableBuiltinEnhanced: verge?.enable_builtin_enhanced ?? true,
|
||||
proxyLayoutColumn: verge?.proxy_layout_column || 6,
|
||||
defaultLatencyTest: verge?.default_latency_test || "",
|
||||
@@ -49,7 +47,6 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
await patchVerge({
|
||||
app_log_level: values.appLogLevel,
|
||||
auto_close_connection: values.autoCloseConnection,
|
||||
enable_clash_fields: values.enableClashFields,
|
||||
enable_builtin_enhanced: values.enableBuiltinEnhanced,
|
||||
proxy_layout_column: values.proxyLayoutColumn,
|
||||
default_latency_test: values.defaultLatencyTest,
|
||||
@@ -105,17 +102,6 @@ export const MiscViewer = forwardRef<DialogRef>((props, ref) => {
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Enable Clash Fields Filter")} />
|
||||
<Switch
|
||||
edge="end"
|
||||
checked={values.enableClashFields}
|
||||
onChange={(_, c) =>
|
||||
setValues((v) => ({ ...v, enableClashFields: c }))
|
||||
}
|
||||
/>
|
||||
</ListItem>
|
||||
|
||||
<ListItem sx={{ padding: "5px 2px" }}>
|
||||
<ListItemText primary={t("Enable Builtin Enhanced")} />
|
||||
<Switch
|
||||
|
||||
@@ -15,7 +15,6 @@ import { DialogRef, Notice } from "@/components/base";
|
||||
import { useClash } from "@/hooks/use-clash";
|
||||
import { GuardState } from "./mods/guard-state";
|
||||
import { WebUIViewer } from "./mods/web-ui-viewer";
|
||||
import { ClashFieldViewer } from "./mods/clash-field-viewer";
|
||||
import { ClashPortViewer } from "./mods/clash-port-viewer";
|
||||
import { ControllerViewer } from "./mods/controller-viewer";
|
||||
import { SettingList, SettingItem } from "./mods/setting-comp";
|
||||
@@ -39,11 +38,7 @@ const SettingClash = ({ onError }: Props) => {
|
||||
|
||||
const { ipv6, "allow-lan": allowLan, "log-level": logLevel } = clash ?? {};
|
||||
|
||||
const {
|
||||
enable_random_port = false,
|
||||
verge_mixed_port,
|
||||
enable_clash_fields = true,
|
||||
} = verge ?? {};
|
||||
const { enable_random_port = false, verge_mixed_port } = verge ?? {};
|
||||
|
||||
const webRef = useRef<DialogRef>(null);
|
||||
const fieldRef = useRef<DialogRef>(null);
|
||||
@@ -70,7 +65,6 @@ const SettingClash = ({ onError }: Props) => {
|
||||
return (
|
||||
<SettingList title={t("Clash Setting")}>
|
||||
<WebUIViewer ref={webRef} />
|
||||
<ClashFieldViewer ref={fieldRef} />
|
||||
<ClashPortViewer ref={portRef} />
|
||||
<ControllerViewer ref={ctrlRef} />
|
||||
<ClashCoreViewer ref={coreRef} />
|
||||
@@ -176,19 +170,6 @@ const SettingClash = ({ onError }: Props) => {
|
||||
</IconButton>
|
||||
</SettingItem>
|
||||
|
||||
{enable_clash_fields && (
|
||||
<SettingItem label={t("Clash Field")}>
|
||||
<IconButton
|
||||
color="inherit"
|
||||
size="small"
|
||||
sx={{ my: "2px" }}
|
||||
onClick={() => fieldRef.current?.open()}
|
||||
>
|
||||
<ArrowForward />
|
||||
</IconButton>
|
||||
</SettingItem>
|
||||
)}
|
||||
|
||||
<SettingItem
|
||||
label={t("Clash Core")}
|
||||
extra={
|
||||
|
||||
@@ -48,11 +48,16 @@ export const useClashInfo = () => {
|
||||
|
||||
const patchInfo = async (
|
||||
patch: Partial<
|
||||
Pick<IConfigData, "mixed-port" | "external-controller" | "secret">
|
||||
Pick<
|
||||
IConfigData,
|
||||
"port" | "socks-port" | "mixed-port" | "external-controller" | "secret"
|
||||
>
|
||||
>
|
||||
) => {
|
||||
const hasInfo =
|
||||
patch["mixed-port"] != null ||
|
||||
patch["socks-port"] != null ||
|
||||
patch["port"] != null ||
|
||||
patch["external-controller"] != null ||
|
||||
patch.secret != null;
|
||||
|
||||
@@ -68,6 +73,26 @@ export const useClashInfo = () => {
|
||||
}
|
||||
}
|
||||
|
||||
if (patch["socks-port"]) {
|
||||
const port = patch["socks-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["port"]) {
|
||||
const port = patch["port"];
|
||||
if (port < 1000) {
|
||||
throw new Error("The port should not < 1000");
|
||||
}
|
||||
if (port > 65536) {
|
||||
throw new Error("The port should not > 65536");
|
||||
}
|
||||
}
|
||||
|
||||
await patchClashConfig(patch);
|
||||
mutateInfo();
|
||||
mutate("getClashConfig");
|
||||
|
||||
7
src/services/types.d.ts
vendored
7
src/services/types.d.ts
vendored
@@ -131,7 +131,9 @@ interface IConnections {
|
||||
|
||||
interface IClashInfo {
|
||||
// status: string;
|
||||
port?: number; // clash mixed port
|
||||
mixed_port?: number; // clash mixed port
|
||||
socks_port?: number; // clash socks port
|
||||
port?: number; // clash http port
|
||||
server?: string; // external-controller
|
||||
secret?: string;
|
||||
}
|
||||
@@ -196,6 +198,8 @@ interface IVergeConfig {
|
||||
enable_system_proxy?: boolean;
|
||||
enable_random_port?: boolean;
|
||||
verge_mixed_port?: number;
|
||||
verge_socks_port?: number;
|
||||
verge_port?: number;
|
||||
enable_proxy_guard?: boolean;
|
||||
proxy_guard_duration?: number;
|
||||
system_proxy_bypass?: string;
|
||||
@@ -215,7 +219,6 @@ interface IVergeConfig {
|
||||
};
|
||||
auto_close_connection?: boolean;
|
||||
default_latency_test?: string;
|
||||
enable_clash_fields?: boolean;
|
||||
enable_builtin_enhanced?: boolean;
|
||||
auto_log_clean?: 0 | 1 | 2 | 3;
|
||||
proxy_layout_column?: number;
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
export const HANDLE_FIELDS = [
|
||||
"mode",
|
||||
"port",
|
||||
"socks-port",
|
||||
"mixed-port",
|
||||
"allow-lan",
|
||||
"log-level",
|
||||
"ipv6",
|
||||
"secret",
|
||||
"external-controller",
|
||||
];
|
||||
|
||||
export const DEFAULT_FIELDS = [
|
||||
"proxies",
|
||||
"proxy-groups",
|
||||
"proxy-providers",
|
||||
"rules",
|
||||
"rule-providers",
|
||||
] as const;
|
||||
|
||||
export const OTHERS_FIELDS = [
|
||||
"dns",
|
||||
"tun",
|
||||
"ebpf",
|
||||
"hosts",
|
||||
"script",
|
||||
"profile",
|
||||
"payload",
|
||||
"tunnels",
|
||||
"auto-redir",
|
||||
"experimental",
|
||||
"interface-name",
|
||||
"routing-mark",
|
||||
"redir-port",
|
||||
"tproxy-port",
|
||||
"iptables",
|
||||
"external-ui",
|
||||
"bind-address",
|
||||
"authentication",
|
||||
"tls", // meta
|
||||
"sniffer", // meta
|
||||
"geox-url", // meta
|
||||
"listeners", // meta
|
||||
"sub-rules", // meta
|
||||
"geodata-mode", // meta
|
||||
"unified-delay", // meta
|
||||
"tcp-concurrent", // meta
|
||||
"enable-process", // meta
|
||||
"find-process-mode", // meta
|
||||
"skip-auth-prefixes", // meta
|
||||
"external-controller-tls", // meta
|
||||
"global-client-fingerprint", // meta
|
||||
] as const;
|
||||
Reference in New Issue
Block a user