import i18n from "../i18n"; export function relativeTime(iso: string | null): string { if (!iso) return ""; const then = new Date(iso).getTime(); const secs = Math.max(0, (Date.now() - then) / 1000); const units: [number, string][] = [ [60, "time.secondsAgo"], [3600, "time.minutesAgo"], [86400, "time.hoursAgo"], [604800, "time.daysAgo"], [2592000, "time.weeksAgo"], [31536000, "time.monthsAgo"], ]; if (secs < 60) return i18n.t("time.justNow"); for (let i = 0; i < units.length - 1; i++) { const [, key] = units[i]; const next = units[i + 1][0]; if (secs < next) { const v = Math.floor(secs / units[i][0]); return i18n.t(key, { count: v }); } } const years = Math.floor(secs / 31536000); if (years >= 1) return i18n.t("time.yearsAgo", { count: years }); const months = Math.floor(secs / 2592000); return i18n.t("time.monthsAgo", { count: months }); } export function formatDuration(sec: number | null): string { if (sec == null) return ""; const h = Math.floor(sec / 3600); const m = Math.floor((sec % 3600) / 60); const s = Math.floor(sec % 60); const pad = (n: number) => String(n).padStart(2, "0"); return h > 0 ? `${h}:${pad(m)}:${pad(s)}` : `${m}:${pad(s)}`; } const QUOTA_ACTION_LABELS: Record = { sync_subscriptions: "Sync subscriptions", backfill_recent: "Recent backfill", backfill_deep: "Full-history backfill", enrich: "Enrichment", unsubscribe: "Unsubscribe", subscription_resync: "Auto subscription resync", api: "Other", }; export function quotaActionLabel(action: string): string { return QUOTA_ACTION_LABELS[action] ?? action; } /** Coarse, human ETA for a remaining duration in seconds ("~3 hours", "~2 days"). */ export function formatEta(seconds: number): string { if (seconds <= 0) return "done"; const hours = seconds / 3600; if (hours < 1) return "< 1 hour"; if (hours < 24) { const h = Math.round(hours); return `~${h} hour${h === 1 ? "" : "s"}`; } const d = Math.round(hours / 24); return `~${d} day${d === 1 ? "" : "s"}`; } export function formatViews(n: number | null): string { if (n == null) return ""; if (n >= 1e9) return `${(n / 1e9).toFixed(1).replace(/\.0$/, "")}B`; if (n >= 1e6) return `${(n / 1e6).toFixed(1).replace(/\.0$/, "")}M`; if (n >= 1e3) return `${(n / 1e3).toFixed(1).replace(/\.0$/, "")}K`; return String(n); }