import { useEffect, useState } from "react"; import { useLockFn } from "ahooks"; import { CheckCircleOutlineRounded } from "@mui/icons-material"; import { alpha, Box, ListItem, ListItemButton, ListItemIcon, ListItemText, styled, SxProps, Theme, } from "@mui/material"; import { BaseLoading } from "@/components/base"; import delayManager from "@/services/delay"; interface Props { groupName: string; proxy: IProxyItem; selected: boolean; showType?: boolean; sx?: SxProps; onClick?: (name: string) => void; } const Widget = styled(Box)(() => ({ padding: "3px 6px", fontSize: 14, borderRadius: "4px", })); const TypeBox = styled(Box)(({ theme }) => ({ display: "inline-block", border: "1px solid #ccc", borderColor: alpha(theme.palette.text.secondary, 0.36), color: alpha(theme.palette.text.secondary, 0.42), borderRadius: 4, fontSize: 10, marginRight: "4px", padding: "0 2px", lineHeight: 1.25, })); export const ProxyItem = (props: Props) => { const { groupName, proxy, selected, showType = true, sx, onClick } = props; // -1/<=0 为 不显示 // -2 为 loading const [delay, setDelay] = useState(-1); useEffect(() => { delayManager.setListener(proxy.name, groupName, setDelay); return () => { delayManager.removeListener(proxy.name, groupName); }; }, [proxy.name, groupName]); useEffect(() => { if (!proxy) return; setDelay(delayManager.getDelayFix(proxy, groupName)); }, [proxy]); const onDelay = useLockFn(async () => { setDelay(-2); setDelay(await delayManager.checkDelay(proxy.name, groupName)); }); return ( onClick?.(proxy.name)} sx={[ { borderRadius: 1 }, ({ palette: { mode, primary } }) => { const bgcolor = mode === "light" ? alpha(primary.main, 0.15) : alpha(primary.main, 0.35); const color = mode === "light" ? primary.main : primary.light; const showDelay = delay > 0; return { "&:hover .the-check": { display: !showDelay ? "block" : "none" }, "&:hover .the-delay": { display: showDelay ? "block" : "none" }, "&:hover .the-icon": { display: "none" }, "&.Mui-selected": { bgcolor }, "&.Mui-selected .MuiListItemText-secondary": { color }, }; }, ]} > {proxy.name} {showType && !!proxy.provider && ( {proxy.provider} )} {showType && {proxy.type}} {showType && proxy.udp && UDP} } /> {delay === -2 && ( )} {!proxy.provider && delay !== -2 && ( // provider的节点不支持检测 { e.preventDefault(); e.stopPropagation(); onDelay(); }} sx={({ palette }) => ({ display: "none", // hover才显示 ":hover": { bgcolor: alpha(palette.primary.main, 0.15) }, })} > Check )} {delay > 0 && ( // 显示延迟 { if (proxy.provider) return; e.preventDefault(); e.stopPropagation(); onDelay(); }} color={ delay > 500 ? "error.main" : delay < 100 ? "success.main" : "text.secondary" } sx={({ palette }) => !proxy.provider ? { ":hover": { bgcolor: alpha(palette.primary.main, 0.15) } } : {} } > {delay > 1e5 ? "Error" : delay > 3000 ? "Timeout" : `${delay}ms`} )} {delay !== -2 && delay <= 0 && selected && ( // 展示已选择的icon )} ); };