|
@@ -1,24 +1,51 @@
|
|
|
|
+import { useEffect, useState } from "react";
|
|
import { CheckCircleOutlineRounded } from "@mui/icons-material";
|
|
import { CheckCircleOutlineRounded } from "@mui/icons-material";
|
|
import {
|
|
import {
|
|
alpha,
|
|
alpha,
|
|
|
|
+ Box,
|
|
ListItem,
|
|
ListItem,
|
|
ListItemButton,
|
|
ListItemButton,
|
|
ListItemIcon,
|
|
ListItemIcon,
|
|
ListItemText,
|
|
ListItemText,
|
|
|
|
+ styled,
|
|
SxProps,
|
|
SxProps,
|
|
Theme,
|
|
Theme,
|
|
} from "@mui/material";
|
|
} from "@mui/material";
|
|
import { ApiType } from "../../services/types";
|
|
import { ApiType } from "../../services/types";
|
|
|
|
+import delayManager from "../../services/delay";
|
|
|
|
|
|
interface Props {
|
|
interface Props {
|
|
|
|
+ groupName: string;
|
|
proxy: ApiType.ProxyItem;
|
|
proxy: ApiType.ProxyItem;
|
|
selected: boolean;
|
|
selected: boolean;
|
|
sx?: SxProps<Theme>;
|
|
sx?: SxProps<Theme>;
|
|
onClick?: (name: string) => void;
|
|
onClick?: (name: string) => void;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+const Widget = styled(Box)(() => ({
|
|
|
|
+ padding: "4px 6px",
|
|
|
|
+ fontSize: 14,
|
|
|
|
+}));
|
|
|
|
+
|
|
const ProxyItem = (props: Props) => {
|
|
const ProxyItem = (props: Props) => {
|
|
- const { proxy, selected, sx, onClick } = props;
|
|
|
|
|
|
+ const { groupName, proxy, selected, sx, onClick } = props;
|
|
|
|
+ const [delay, setDelay] = useState(-1);
|
|
|
|
+
|
|
|
|
+ useEffect(() => {
|
|
|
|
+ if (proxy) {
|
|
|
|
+ setDelay(delayManager.getDelay(proxy.name, groupName));
|
|
|
|
+ }
|
|
|
|
+ }, [proxy]);
|
|
|
|
+
|
|
|
|
+ const onDelay = (e: any) => {
|
|
|
|
+ e.preventDefault();
|
|
|
|
+ e.stopPropagation();
|
|
|
|
+
|
|
|
|
+ delayManager
|
|
|
|
+ .checkDelay(proxy.name, groupName)
|
|
|
|
+ .then((result) => setDelay(result))
|
|
|
|
+ .catch(() => setDelay(1e6));
|
|
|
|
+ };
|
|
|
|
|
|
return (
|
|
return (
|
|
<ListItem sx={sx}>
|
|
<ListItem sx={sx}>
|
|
@@ -27,9 +54,7 @@ const ProxyItem = (props: Props) => {
|
|
selected={selected}
|
|
selected={selected}
|
|
onClick={() => onClick?.(proxy.name)}
|
|
onClick={() => onClick?.(proxy.name)}
|
|
sx={[
|
|
sx={[
|
|
- {
|
|
|
|
- borderRadius: 1,
|
|
|
|
- },
|
|
|
|
|
|
+ { borderRadius: 1 },
|
|
({ palette: { mode, primary } }) => {
|
|
({ palette: { mode, primary } }) => {
|
|
const bgcolor =
|
|
const bgcolor =
|
|
mode === "light"
|
|
mode === "light"
|
|
@@ -37,7 +62,16 @@ const ProxyItem = (props: Props) => {
|
|
: alpha(primary.main, 0.35);
|
|
: alpha(primary.main, 0.35);
|
|
const color = mode === "light" ? primary.main : primary.light;
|
|
const color = mode === "light" ? primary.main : primary.light;
|
|
|
|
|
|
|
|
+ const showDelay = delay > 0;
|
|
|
|
+ const showIcon = !showDelay && selected;
|
|
|
|
+
|
|
return {
|
|
return {
|
|
|
|
+ ".the-check": { display: "none" },
|
|
|
|
+ ".the-delay": { display: showDelay ? "block" : "none" },
|
|
|
|
+ ".the-icon": { display: showIcon ? "block" : "none" },
|
|
|
|
+ "&:hover .the-check": { display: !showDelay ? "block" : "none" },
|
|
|
|
+ "&:hover .the-delay": { display: showDelay ? "block" : "none" },
|
|
|
|
+ "&:hover .the-icon": { display: "none" },
|
|
"&.Mui-selected": { bgcolor },
|
|
"&.Mui-selected": { bgcolor },
|
|
"&.Mui-selected .MuiListItemText-secondary": { color },
|
|
"&.Mui-selected .MuiListItemText-secondary": { color },
|
|
};
|
|
};
|
|
@@ -45,10 +79,32 @@ const ProxyItem = (props: Props) => {
|
|
]}
|
|
]}
|
|
>
|
|
>
|
|
<ListItemText title={proxy.name} secondary={proxy.name} />
|
|
<ListItemText title={proxy.name} secondary={proxy.name} />
|
|
|
|
+
|
|
<ListItemIcon
|
|
<ListItemIcon
|
|
sx={{ justifyContent: "flex-end", color: "primary.main" }}
|
|
sx={{ justifyContent: "flex-end", color: "primary.main" }}
|
|
>
|
|
>
|
|
- {selected && <CheckCircleOutlineRounded sx={{ fontSize: 16 }} />}
|
|
|
|
|
|
+ <Widget className="the-check" onClick={onDelay}>
|
|
|
|
+ Check
|
|
|
|
+ </Widget>
|
|
|
|
+
|
|
|
|
+ <Widget
|
|
|
|
+ className="the-delay"
|
|
|
|
+ onClick={onDelay}
|
|
|
|
+ color={
|
|
|
|
+ delay > 500
|
|
|
|
+ ? "error.main"
|
|
|
|
+ : delay < 100
|
|
|
|
+ ? "success.main"
|
|
|
|
+ : "text.secondary"
|
|
|
|
+ }
|
|
|
|
+ >
|
|
|
|
+ {delay > 1e5 ? "Error" : delay > 3000 ? "Timeout" : `${delay}ms`}
|
|
|
|
+ </Widget>
|
|
|
|
+
|
|
|
|
+ <CheckCircleOutlineRounded
|
|
|
|
+ className="the-icon"
|
|
|
|
+ sx={{ fontSize: 16 }}
|
|
|
|
+ />
|
|
</ListItemIcon>
|
|
</ListItemIcon>
|
|
</ListItemButton>
|
|
</ListItemButton>
|
|
</ListItem>
|
|
</ListItem>
|