import dayjs from "dayjs"; import useSWR, { mutate } from "swr"; import { useState } from "react"; import { Button, IconButton, List, ListItem, ListItemText, styled, Box, alpha, Typography, Divider, LinearProgress, keyframes, } from "@mui/material"; import { RefreshRounded } from "@mui/icons-material"; import { useTranslation } from "react-i18next"; import { getProxyProviders, proxyProviderUpdate } from "@/services/api"; import { BaseDialog } from "../base"; import parseTraffic from "@/utils/parse-traffic"; const round = keyframes` from { transform: rotate(0deg); } to { transform: rotate(360deg); } `; export const ProviderButton = () => { const { t } = useTranslation(); const { data } = useSWR("getProxyProviders", getProxyProviders); const [open, setOpen] = useState(false); const hasProvider = Object.keys(data || {}).length > 0; const [updating, setUpdating] = useState( Object.keys(data || {}).map(() => false) ); const setUpdatingAt = (status: boolean, index: number) => { setUpdating((prev) => { const next = [...prev]; next[index] = status; return next; }); }; const handleUpdate = async (key: string, index: number) => { setUpdatingAt(true, index); proxyProviderUpdate(key) .then(async () => { setUpdatingAt(false, index); await mutate("getProxies"); await mutate("getProxyProviders"); }) .catch(async () => { setUpdatingAt(false, index); await mutate("getProxies"); await mutate("getProxyProviders"); }); }; if (!hasProvider) return null; return ( <> {t("Proxy Provider")} } contentSx={{ width: 400 }} disableOk cancelBtn={t("Cancel")} onClose={() => setOpen(false)} onCancel={() => setOpen(false)} > {Object.entries(data || {}).map(([key, item], index) => { const time = dayjs(item.updatedAt); const sub = item.subscriptionInfo; const hasSubInfo = !!sub; const upload = sub?.Upload || 0; const download = sub?.Download || 0; const total = sub?.Total || 0; const expire = sub?.Expire || 0; const progress = Math.round( ((download + upload) * 100) / (total + 0.1) ); return ( <> {key} {item.proxies.length} } secondary={ <> {item.vehicleType} {t("Update At")} {time.fromNow()} {hasSubInfo && ( <> {parseTraffic(upload + download)} /{" "} {parseTraffic(total)} {parseExpire(expire)} )} } /> handleUpdate(key, index)} sx={{ animation: updating[index] ? `1s linear infinite ${round}` : "none", }} > ); })} ); }; const TypeBox = styled(Box)(({ theme }) => ({ display: "inline-block", border: "1px solid #ccc", borderColor: alpha(theme.palette.secondary.main, 0.5), color: alpha(theme.palette.secondary.main, 0.8), borderRadius: 4, fontSize: 10, marginRight: "4px", padding: "0 2px", lineHeight: 1.25, })); const StyledTypeBox = styled(Box)(({ theme }) => ({ display: "inline-block", border: "1px solid #ccc", borderColor: alpha(theme.palette.primary.main, 0.5), color: alpha(theme.palette.primary.main, 0.8), borderRadius: 4, fontSize: 10, marginRight: "4px", padding: "0 2px", lineHeight: 1.25, })); const boxStyle = { height: 26, display: "flex", alignItems: "center", justifyContent: "space-between", }; function parseExpire(expire?: number) { if (!expire) return "-"; return dayjs(expire * 1000).format("YYYY-MM-DD"); }