mirror of
https://github.com/Corfirean/coa-server-manager.git
synced 2026-11-11 20:01:01 +00:00
PLAY turns into UPDATE CLIENT when a tracked client is outdated; with no client linked it offers choosing an existing folder or downloading from the community launcher servers (resumable, hash-verified, free-space checked, progress and stop). Files the player changed are kept on request or moved aside, never silently replaced. Existing clients can be adopted from Settings. Fresh downloads get a realmlist for each installed locale. Fixes zero-length files in the downloader (found by the live probe). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
29 lines
886 B
TypeScript
29 lines
886 B
TypeScript
import { clsx, type ClassValue } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
/** 1536 -> "1.5 KB"; 43.2e9 -> "40.2 GB" (binary units, as drive sizes are shown). */
|
|
export function formatBytes(n: number): string {
|
|
const units = ["B", "KB", "MB", "GB", "TB"];
|
|
let v = Math.max(0, n);
|
|
let i = 0;
|
|
while (v >= 1024 && i < units.length - 1) {
|
|
v /= 1024;
|
|
i++;
|
|
}
|
|
return `${i === 0 || v >= 100 ? Math.round(v) : v.toFixed(1)} ${units[i]}`;
|
|
}
|
|
|
|
export function formatUptime(secs: number | null | undefined): string {
|
|
if (secs == null) return "—";
|
|
const d = Math.floor(secs / 86400);
|
|
const h = Math.floor((secs % 86400) / 3600);
|
|
const m = Math.floor((secs % 3600) / 60);
|
|
if (d > 0) return `${d}d ${h}h`;
|
|
if (h > 0) return `${h}h ${m}m`;
|
|
return `${m}m ${secs % 60}s`;
|
|
}
|