77 lines
2.2 KiB
TypeScript
77 lines
2.2 KiB
TypeScript
// frontend/src/components/ui/formatters.ts
|
||
|
||
export function formatFps(n?: number | null): string {
|
||
if (!n || !Number.isFinite(n)) return '—'
|
||
const digits = n >= 10 ? 0 : 2
|
||
return `${n.toFixed(digits)} fps`
|
||
}
|
||
|
||
export function formatResolution(r?: { w: number; h: number } | null): string {
|
||
if (!r) return ''
|
||
|
||
const w = Math.round(Number(r.w))
|
||
const h = Math.round(Number(r.h))
|
||
if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) return ''
|
||
|
||
// "p" orientiert sich an der kleineren Seite:
|
||
// - Landscape: min = Höhe
|
||
// - Portrait: min = Breite (damit 1080×1920 => 1080p)
|
||
const p = Math.min(w, h)
|
||
|
||
// Toleranz, weil Encoder manchmal krumme Werte liefern (z.B. 1072 statt 1080)
|
||
const tol = Math.max(12, Math.round(p * 0.02))
|
||
const pick = (target: number) => Math.abs(p - target) <= tol
|
||
|
||
if (pick(4320)) return '8K'
|
||
if (pick(2160) || p >= 2000) return '4K'
|
||
if (pick(1440)) return '1440p'
|
||
if (pick(1080)) return '1080p'
|
||
if (pick(720)) return '720p'
|
||
if (pick(480)) return '480p'
|
||
if (pick(360)) return '360p'
|
||
if (pick(240)) return '240p'
|
||
|
||
// Fallback: z.B. 1600p (Ultrawide) oder 800p
|
||
return `${p}p`
|
||
}
|
||
|
||
export function formatDuration(ms: number): string {
|
||
if (!Number.isFinite(ms) || ms <= 0) return '—'
|
||
const totalSec = Math.floor(ms / 1000)
|
||
const h = Math.floor(totalSec / 3600)
|
||
const m = Math.floor((totalSec % 3600) / 60)
|
||
const s = totalSec % 60
|
||
if (h > 0) return `${h}h ${m}m`
|
||
if (m > 0) return `${m}m ${s}s`
|
||
return `${s}s`
|
||
}
|
||
|
||
export function formatBytes(bytes?: number | null): string {
|
||
if (typeof bytes !== 'number' || !Number.isFinite(bytes) || bytes <= 0) return '—'
|
||
const units = ['B', 'KB', 'MB', 'GB', 'TB']
|
||
let v = bytes
|
||
let i = 0
|
||
while (v >= 1024 && i < units.length - 1) {
|
||
v /= 1024
|
||
i++
|
||
}
|
||
const digits = i === 0 ? 0 : v >= 100 ? 0 : v >= 10 ? 1 : 2
|
||
return `${v.toFixed(digits)} ${units[i]}`
|
||
}
|
||
|
||
|
||
export function formatDateTime(v?: string | number | Date | null): string {
|
||
if (!v) return '—'
|
||
const d = v instanceof Date ? v : new Date(v)
|
||
const t = d.getTime()
|
||
if (!Number.isFinite(t)) return '—'
|
||
return d.toLocaleString(undefined, {
|
||
year: 'numeric',
|
||
month: '2-digit',
|
||
day: '2-digit',
|
||
hour: '2-digit',
|
||
minute: '2-digit',
|
||
})
|
||
}
|
||
|