feat: auto close connection when proxy changed

This commit is contained in:
GyDi
2022-11-10 01:27:05 +08:00
parent 5f486d0f51
commit 0cfd718d8a
9 changed files with 175 additions and 3 deletions

View File

@@ -15,8 +15,14 @@ import {
ExpandLessRounded,
ExpandMoreRounded,
} from "@mui/icons-material";
import { providerHealthCheck, updateProxy } from "@/services/api";
import {
getConnections,
providerHealthCheck,
updateProxy,
deleteConnection,
} from "@/services/api";
import { getProfiles, patchProfile } from "@/services/cmds";
import { useVergeConfig } from "@/hooks/use-verge-config";
import delayManager from "@/services/delay";
import useHeadState from "./use-head-state";
import useFilterSort from "./use-filter-sort";
@@ -42,6 +48,7 @@ const ProxyGroup = ({ group }: Props) => {
);
const { data: profiles } = useSWR("getProfiles", getProfiles);
const { data: vergeConfig } = useVergeConfig();
const onChangeProxy = useLockFn(async (name: string) => {
// Todo: support another proxy group type
@@ -51,6 +58,16 @@ const ProxyGroup = ({ group }: Props) => {
try {
setNow(name);
await updateProxy(group.name, name);
if (vergeConfig?.auto_close_connection) {
getConnections().then((snapshot) => {
snapshot.connections.forEach((conn) => {
if (conn.chains.includes(oldValue!)) {
deleteConnection(conn.id);
}
});
});
}
} catch {
setNow(oldValue);
return; // do not update profile

View File

@@ -0,0 +1,107 @@
import { useEffect, useState } from "react";
import { useLockFn } from "ahooks";
import { useTranslation } from "react-i18next";
import {
Button,
Dialog,
DialogActions,
DialogContent,
DialogTitle,
List,
ListItem,
ListItemText,
Switch,
TextField,
} from "@mui/material";
import { ModalHandler } from "@/hooks/use-modal-handler";
import { useVergeConfig } from "@/hooks/use-verge-config";
import Notice from "@/components/base/base-notice";
interface Props {
handler: ModalHandler;
}
const MiscViewer = ({ handler }: Props) => {
const { t } = useTranslation();
const { data, patchVerge } = useVergeConfig();
const [open, setOpen] = useState(false);
const [values, setValues] = useState({
autoCloseConnection: false,
defaultLatencyTest: "",
});
if (handler) {
handler.current = {
open: () => setOpen(true),
close: () => setOpen(false),
};
}
useEffect(() => {
if (open) {
setValues({
autoCloseConnection: data?.auto_close_connection || false,
defaultLatencyTest: data?.default_latency_test || "",
});
}
}, [open, data]);
const onSave = useLockFn(async () => {
try {
await patchVerge({
auto_close_connection: values.autoCloseConnection,
default_latency_test: values.defaultLatencyTest,
});
setOpen(false);
} catch (err: any) {
Notice.error(err.message || err.toString());
}
});
return (
<Dialog open={open} onClose={() => setOpen(false)}>
<DialogTitle>{t("Miscellaneous")}</DialogTitle>
<DialogContent sx={{ width: 420 }}>
<List>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary="Auto Close Connections" />
<Switch
edge="end"
checked={values.autoCloseConnection}
onChange={(_, c) =>
setValues((v) => ({ ...v, autoCloseConnection: c }))
}
/>
</ListItem>
<ListItem sx={{ padding: "5px 2px" }}>
<ListItemText primary="Default Latency Test" />
<TextField
size="small"
autoComplete="off"
sx={{ width: 200 }}
value={values.defaultLatencyTest}
placeholder="http://www.gstatic.com/generate_204"
onChange={(e) =>
setValues((v) => ({ ...v, defaultLatencyTest: e.target.value }))
}
/>
</ListItem>
</List>
</DialogContent>
<DialogActions>
<Button variant="outlined" onClick={() => setOpen(false)}>
{t("Cancel")}
</Button>
<Button onClick={onSave} variant="contained">
{t("Save")}
</Button>
</DialogActions>
</Dialog>
);
};
export default MiscViewer;

View File

@@ -124,7 +124,7 @@ const SettingClash = ({ onError }: Props) => {
/>
</SettingItem>
<SettingItem label={t("External Controller")}>
<SettingItem label={t("External")}>
<IconButton
color="inherit"
size="small"

View File

@@ -22,6 +22,7 @@ import ThemeModeSwitch from "./mods/theme-mode-switch";
import ConfigViewer from "./mods/config-viewer";
import HotkeyViewer from "./mods/hotkey-viewer";
import GuardState from "./mods/guard-state";
import MiscViewer from "./mods/misc-viewer";
import SettingTheme from "./setting-theme";
interface Props {
@@ -45,11 +46,13 @@ const SettingVerge = ({ onError }: Props) => {
mutateVerge({ ...vergeConfig, ...patch }, false);
};
const miscHandler = useModalHandler();
const hotkeyHandler = useModalHandler();
return (
<SettingList title={t("Verge Setting")}>
<HotkeyViewer handler={hotkeyHandler} />
<MiscViewer handler={miscHandler} />
<SettingItem label={t("Language")}>
<GuardState
@@ -103,6 +106,17 @@ const SettingVerge = ({ onError }: Props) => {
</GuardState>
</SettingItem>
<SettingItem label={t("Miscellaneous")}>
<IconButton
color="inherit"
size="small"
sx={{ my: "2px" }}
onClick={() => miscHandler.current.open()}
>
<ArrowForward />
</IconButton>
</SettingItem>
<SettingItem label={t("Theme Setting")}>
<IconButton
color="inherit"