import { forwardRef, useImperativeHandle, useState } from "react"; import { useLockFn } from "ahooks"; import { useTranslation } from "react-i18next"; import { List, ListItem, ListItemText, MenuItem, Select, 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((props, ref) => { const { t } = useTranslation(); const { clash, mutateClash, patchClash } = useClash(); const [open, setOpen] = useState(false); const [values, setValues] = useState({ stack: "gVisor", device: "Mihomo", autoRoute: true, autoDetectInterface: true, dnsHijack: ["any:53"], strictRoute: false, mtu: 9000, }); useImperativeHandle(ref, () => ({ open: () => { setOpen(true); setValues({ stack: clash?.tun.stack ?? "gVisor", device: clash?.tun.device ?? "Mihomo", autoRoute: clash?.tun["auto-route"] ?? true, autoDetectInterface: clash?.tun["auto-detect-interface"] ?? true, dnsHijack: clash?.tun["dns-hijack"] ?? ["any:53"], strictRoute: clash?.tun["strict-route"] ?? false, mtu: clash?.tun.mtu ?? 9000, }); }, close: () => setOpen(false), })); const onSave = useLockFn(async () => { try { let tun = { stack: values.stack, device: values.device, "auto-route": values.autoRoute, "auto-detect-interface": values.autoDetectInterface, "dns-hijack": values.dnsHijack, "strict-route": values.strictRoute, mtu: values.mtu, }; await patchClash({ tun }); await mutateClash( (old) => ({ ...(old! || {}), tun, }), false ); setOpen(false); } catch (err: any) { Notice.error(err.message || err.toString()); } }); return ( setOpen(false)} onCancel={() => setOpen(false)} onOk={onSave} > { setValues((v) => ({ ...v, stack: value, })); }} /> setValues((v) => ({ ...v, device: e.target.value })) } /> setValues((v) => ({ ...v, autoRoute: c }))} /> setValues((v) => ({ ...v, strictRoute: c }))} /> setValues((v) => ({ ...v, autoDetectInterface: c })) } /> setValues((v) => ({ ...v, dnsHijack: e.target.value.split(",") })) } /> setValues((v) => ({ ...v, mtu: parseInt(e.target.value), })) } /> ); });