"use client"; import { Activity, Clock3, RefreshCw, Route } from "lucide-react"; import { useLatencyRefreshMeta, type LatencyItem } from "./latency-loader"; import type { TraceItem } from "./trace-loader"; import { cn } from "@/lib/utils"; const carrierLabels: Record = { telecom: "电信", unicom: "联通", mobile: "移动", }; const CARRIER_ORDER: string[] = ["telecom", "unicom", "mobile"]; function sortByCarrier(items: T[]): T[] { return [...items].sort( (a, b) => (CARRIER_ORDER.indexOf(a.carrier) >>> 0) - (CARRIER_ORDER.indexOf(b.carrier) >>> 0), ); } export function getCarrierLabel(carrier: string) { return carrierLabels[carrier] ?? carrier.replace("中国", ""); } function formatRefreshLabel(meta: ReturnType) { if (meta.loading) return "正在刷新"; if (!meta.updatedAt) return "约 1 分钟更新"; const updatedAt = new Date(meta.updatedAt); const nextRefreshAt = meta.nextRefreshAt ? new Date(meta.nextRefreshAt) : null; const updated = updatedAt.toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }); const next = nextRefreshAt?.toLocaleTimeString("zh-CN", { hour: "2-digit", minute: "2-digit" }); return next ? `${updated} 更新 · ${next} 再刷` : `${updated} 已更新`; } export function ProxySignalPanel({ latencyItems, traceItems, onTraceSelect, onLatencyClick, }: { latencyItems: LatencyItem[]; traceItems: TraceItem[]; onTraceSelect: (item: TraceItem) => void; onLatencyClick?: () => void; }) { const refreshMeta = useLatencyRefreshMeta(); if (latencyItems.length === 0 && traceItems.length === 0) { return (
线路数据采集中,可先购买,开通后在订阅页查看连接状态。
); } return (

线路体验

延迟与访问路径会持续更新,帮助你选择更舒服的线路。

{refreshMeta.loading ? : } {formatRefreshLabel(refreshMeta)}
{refreshMeta.error && (
自动重试中
)}
{latencyItems.length > 0 && } {traceItems.length > 0 && }
); } export function ProxyLatencyGrid({ items, onClick }: { items: LatencyItem[]; onClick?: () => void }) { if (items.length === 0) return null; const sorted = sortByCarrier(items); const bestLatency = Math.min(...sorted.map((item) => item.latencyMs)); return (

延迟{onClick && · 点击查看趋势}

{sorted.map((item) => { const strong = item.latencyMs === bestLatency; return (

{getCarrierLabel(item.carrier)}

{item.latencyMs} ms

{strong &&

BEST

}
); })}
); } export function ProxyTraceGrid({ items, onTraceSelect, }: { items: TraceItem[]; onTraceSelect: (item: TraceItem) => void; }) { if (items.length === 0) return null; const sorted = sortByCarrier(items); return (

访问路径

{sorted.map((item) => ( ))}
); }