import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useLockFn } from "ahooks"; import { proxyProviderUpdate } from "@/services/api"; import { useAppData } from "@/providers/app-data-provider"; import { showNotice } from "@/services/noticeService"; import { Database, RefreshCw } from "lucide-react"; import dayjs from "dayjs"; import parseTraffic from "@/utils/parse-traffic"; import { Button } from "@/components/ui/button"; import { Dialog, DialogContent, DialogFooter, DialogHeader, DialogTitle, DialogTrigger, } from "@/components/ui/dialog"; import { Progress } from "@/components/ui/progress"; // 定义代理提供者类型 interface ProxyProviderItem { name?: string; proxies: any[]; updatedAt: number; vehicleType: string; subscriptionInfo?: { Upload: number; Download: number; Total: number; Expire: number; }; } // 解析过期时间 const parseExpire = (expire?: number) => { if (!expire) return "-"; return dayjs(expire * 1000).format("YYYY-MM-DD"); }; export const ProviderButton = () => { const { t } = useTranslation(); const [open, setOpen] = useState(false); const { proxyProviders, refreshProxy, refreshProxyProviders } = useAppData(); const [updating, setUpdating] = useState>({}); // 检查是否有提供者 const hasProviders = Object.keys(proxyProviders || {}).length > 0; // 更新单个代理提供者 const updateProvider = useLockFn(async (name: string) => { try { // 设置更新状态 setUpdating((prev) => ({ ...prev, [name]: true })); await proxyProviderUpdate(name); // 刷新数据 await refreshProxy(); await refreshProxyProviders(); showNotice("success", `${name} 更新成功`); } catch (err: any) { showNotice( "error", `${name} 更新失败: ${err?.message || err.toString()}`, ); } finally { // 清除更新状态 setUpdating((prev) => ({ ...prev, [name]: false })); } }); // 更新所有代理提供者 const updateAllProviders = useLockFn(async () => { try { // 获取所有provider的名称 const allProviders = Object.keys(proxyProviders || {}); if (allProviders.length === 0) { showNotice("info", "没有可更新的代理提供者"); return; } // 设置所有provider为更新中状态 const newUpdating = allProviders.reduce( (acc, key) => { acc[key] = true; return acc; }, {} as Record, ); setUpdating(newUpdating); // 改为串行逐个更新所有provider for (const name of allProviders) { try { await proxyProviderUpdate(name); // 每个更新完成后更新状态 setUpdating((prev) => ({ ...prev, [name]: false })); } catch (err) { console.error(`更新 ${name} 失败`, err); // 继续执行下一个,不中断整体流程 } } // 刷新数据 await refreshProxy(); await refreshProxyProviders(); showNotice("success", "全部代理提供者更新成功"); } catch (err: any) { showNotice("error", `更新失败: ${err?.message || err.toString()}`); } finally { // 清除所有更新状态 setUpdating({}); } }); if (!hasProviders) return null; return (
{t("Proxy Provider")}
{Object.entries(proxyProviders || {}).map(([key, item]) => { const provider = item as ProxyProviderItem; const time = dayjs(provider.updatedAt); const isUpdating = updating[key]; const sub = provider.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 = total > 0 ? Math.min( Math.round(((download + upload) * 100) / total) + 1, 100, ) : 0; const TypeBoxDisplay = ({ children, }: { children: React.ReactNode; }) => ( {children} ); return (
{key} {provider.proxies.length} {provider.vehicleType}
{t("Update At")}: {time.fromNow()}
{hasSubInfo && (
{parseTraffic(upload + download)} /{" "} {parseTraffic(total)} {parseExpire(expire)}
{total > 0 && ( )}
)}
); })}
); };