feat(uploads): show batch format counts and quality ranges
ci / ts / ts (packages + web) (push) Failing after 5m56s
ci / module boundaries / boundaries (push) Successful in 5s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m39s

This commit is contained in:
mrleo1nid committed 2026-10-29 17:41:28 +03:00
1 parent e78cab6ce6
commit 1e3a149aef
7 files changed
+63 -1

No files matched your search

@@ -0,0 +1,30 @@
import type { UploadFile } from './common';
import { audioExt } from './files';
type SummaryFile = Pick<UploadFile, 'format' | 'original_name' | 'bitrate' | 'sample_rate' | 'bit_depth'>;
function range(values: (number | null)[], divisor: number, decimals: number, unit: string): string | null {
const known = values.filter((value): value is number => value !== null && Number.isFinite(value) && value > 0);
if (!known.length) return null;
const format = (value: number) => String(Number((value / divisor).toFixed(decimals)));
const min = format(Math.min(...known));
const max = format(Math.max(...known));
return `${min === max ? min : `${min}–${max}`} ${unit}`;
}
/** Only measured positive values contribute to quality ranges; absent metadata is not zero. */
export function batchSummary(files: SummaryFile[]) {
const counts = new Map<string, number>();
for (const file of files) {
const format = (file.format?.trim() || audioExt(file.original_name)).toUpperCase();
counts.set(format, (counts.get(format) ?? 0) + 1);
}
return {
formats: [...counts].sort(([a, ac], [b, bc]) => bc - ac || a.localeCompare(b)),
quality: [
range(files.map((file) => file.bitrate), 1000, 0, 'kbps'),
range(files.map((file) => file.sample_rate), 1000, 3, 'kHz'),
range(files.map((file) => file.bit_depth), 1, 0, 'bit'),
].filter(Boolean).join(' · '),
};
}