/** * Zahlen, wie ein Mensch sie liest. * * Stand bis hierher in `pages/FileBrowser.tsx` – und **fünf** Module holten * sie von dort: Papierkorb, Etiketten, „Geteilt mit mir", Fassungen, * Eigenschaften. Eine Seite als Fundort für eine Rechenfunktion heißt, dass * jedes dieser Module am Dateibrowser hängt, samt allem, was der mitbringt. * Zum Umbenennen einer Zahl musste man eine Seite anfassen. */ /** * Byte-Zahl in Kilo, Mega, Giga. * * Tausend-vierundzwanzig, nicht tausend: Das ist die Einheit, in der * Dateisysteme und Betriebssysteme rechnen – eine Datei, die dort „1,4 MB" * heißt, soll hier nicht 1,5 heißen. */ export function formatBytes(n: number): string { if (n < 1024) return `${n} B` if (n < 1024 ** 2) return `${(n / 1024).toFixed(1)} KB` if (n < 1024 ** 3) return `${(n / 1024 ** 2).toFixed(1)} MB` return `${(n / 1024 ** 3).toFixed(1)} GB` } /** * Eine Dauer, wie man sie beim Warten liest. * * Grob genug, dass die Zahl nicht zappelt, genau genug, dass sie etwas sagt: * unter einer Minute in Sekunden, darüber als `3:07 min`. Sekunden bis in die * zehnte Minute auszuschreiben hieße eine Zahl, die sich jede Sekunde ändert * und trotzdem niemandem hilft. * * Leer bei allem, was keine Dauer ist – unendlich, negativ, keine Zahl. Der * Aufrufer zeigt dann gar nichts an, statt „NaN s" zu schreiben. */ export function formatDuration(seconds: number): string { if (!Number.isFinite(seconds) || seconds < 0) return '' // Unter einer Sekunde bleibt "1 s" stehen: "0 s" sähe aus wie fertig, // während der Balken noch läuft. if (seconds < 60) return `${Math.max(1, Math.round(seconds))} s` const total = Math.round(seconds) const m = Math.floor(total / 60) if (m < 60) return `${m}:${String(total % 60).padStart(2, '0')} min` return `${Math.floor(m / 60)}:${String(m % 60).padStart(2, '0')} h` }