36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
import { clsx, type ClassValue } from "clsx";
|
|
import { twMerge } from "tailwind-merge";
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs));
|
|
}
|
|
|
|
export function formatBytes(n: number): string {
|
|
if (n < 1024) return `${n} B`;
|
|
const u = ["KB", "MB", "GB"];
|
|
let v = n / 1024;
|
|
let i = 0;
|
|
while (v >= 1024 && i < u.length - 1) { v /= 1024; i++; }
|
|
return `${v.toFixed(v < 10 ? 1 : 0)} ${u[i]}`;
|
|
}
|
|
|
|
export function coverHref(image: { id: number; code: string | null }): string {
|
|
if (image.code && image.code.trim()) return `/id/${encodeURIComponent(image.code)}`;
|
|
return `/image/${image.id}`;
|
|
}
|
|
|
|
export function relativeTime(ms: number): string {
|
|
const diff = Date.now() - ms;
|
|
const s = Math.floor(diff / 1000);
|
|
if (s < 60) return "just now";
|
|
const m = Math.floor(s / 60);
|
|
if (m < 60) return `${m}m ago`;
|
|
const h = Math.floor(m / 60);
|
|
if (h < 24) return `${h}h ago`;
|
|
const d = Math.floor(h / 24);
|
|
if (d < 30) return `${d}d ago`;
|
|
const mo = Math.floor(d / 30);
|
|
if (mo < 12) return `${mo}mo ago`;
|
|
return `${Math.floor(mo / 12)}y ago`;
|
|
}
|