fix(web): treat AIFF and WavPack as lossless in the upload format hint
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m30s
ci / ts / ts (packages + web) (push) Successful in 2m11s

The web check only accepted FLAC and WAV, so AIFF files were flagged
"needs attention" although the server already counts them as lossless.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Opus 5.5 committed 2026-10-21 10:35:43 +03:00
1 parent dca7173a88
commit 4d2c6ce22f
6 files changed
+14 -10

No files matched your search

+2 -2
View File
@@ -316,10 +316,10 @@ describe('my wave', () => {
}); });
describe('suggest tracks', () => { describe('suggest tracks', () => {
it('warns that FLAC and WAV are the formats to send', async () => { it('warns that lossless formats are the ones to send', async () => {
const admin = makeUser('admin', 'admin'); const admin = makeUser('admin', 'admin');
await renderApp([admin], '/uploads/new', { signedInAs: admin }); await renderApp([admin], '/uploads/new', { signedInAs: admin });
expect(await screen.findByText(/Нужны FLAC или WAV/)).toBeInTheDocument(); expect(await screen.findByText(/Нужны FLAC, WAV или AIFF/)).toBeInTheDocument();
expect(screen.getByText(/MP3 — только в крайнем случае/)).toBeInTheDocument(); expect(screen.getByText(/MP3 — только в крайнем случае/)).toBeInTheDocument();
}); });
}); });
+4 -1
View File
@@ -3,10 +3,13 @@ import { describe, expect, it } from 'vitest';
import { needsFormatAttention } from './files'; import { needsFormatAttention } from './files';
describe('needsFormatAttention', () => { describe('needsFormatAttention', () => {
it('marks everything except flac and wav', () => { it('marks everything except lossless formats', () => {
expect(needsFormatAttention('flac', 'a.mp3')).toBe(false); expect(needsFormatAttention('flac', 'a.mp3')).toBe(false);
expect(needsFormatAttention('WAV', 'track.wav')).toBe(false); expect(needsFormatAttention('WAV', 'track.wav')).toBe(false);
expect(needsFormatAttention(null, 'Кино/01.wav')).toBe(false); expect(needsFormatAttention(null, 'Кино/01.wav')).toBe(false);
expect(needsFormatAttention('aiff', 'a.aif')).toBe(false);
expect(needsFormatAttention(null, 'track.AIFF')).toBe(false);
expect(needsFormatAttention(null, 'track.wv')).toBe(false);
expect(needsFormatAttention('mp3', 'a.flac')).toBe(true); expect(needsFormatAttention('mp3', 'a.flac')).toBe(true);
expect(needsFormatAttention(null, 'folder/song.MP3')).toBe(true); expect(needsFormatAttention(null, 'folder/song.MP3')).toBe(true);
expect(needsFormatAttention(null, 'song.m4a')).toBe(true); expect(needsFormatAttention(null, 'song.m4a')).toBe(true);
+3 -2
View File
@@ -9,7 +9,8 @@ export interface PickedFile {
export const AUDIO_EXTENSIONS = ['flac', 'mp3', 'm4a', 'ogg', 'opus', 'wav', 'aiff', 'aif', 'wv']; export const AUDIO_EXTENSIONS = ['flac', 'mp3', 'm4a', 'ogg', 'opus', 'wav', 'aiff', 'aif', 'wv'];
/** То, что просим присылать. MP3 и прочие — крайний случай, их помечает очередь. */ /** То, что просим присылать. MP3 и прочие — крайний случай, их помечает очередь. */
const PREFERRED_AUDIO = new Set(['flac', 'wav']); // Lossless — как в quality.go на сервере.
const PREFERRED_AUDIO = new Set(['flac', 'wav', 'aiff', 'aif', 'wv']);
export function audioExt(name: string): string { export function audioExt(name: string): string {
const base = name.split(/[/\\]/).pop() ?? name; const base = name.split(/[/\\]/).pop() ?? name;
@@ -18,7 +19,7 @@ export function audioExt(name: string): string {
return base.slice(dot + 1).toLowerCase(); return base.slice(dot + 1).toLowerCase();
} }
/** Не FLAC и не WAV: в очереди на добавление такой файл нужно выделить. */ /** Не lossless (FLAC, WAV, AIFF, WavPack): в очереди на добавление такой файл нужно выделить. */
export function needsFormatAttention(format: string | null | undefined, name: string): boolean { export function needsFormatAttention(format: string | null | undefined, name: string): boolean {
const ext = (format || audioExt(name)).toLowerCase(); const ext = (format || audioExt(name)).toLowerCase();
return ext !== '' && !PREFERRED_AUDIO.has(ext); return ext !== '' && !PREFERRED_AUDIO.has(ext);
+1 -1
View File
@@ -84,7 +84,7 @@
до 4 параллельных загрузок, прогресс по каждому файлу. до 4 параллельных загрузок, прогресс по каждому файлу.
- Мобильный клиент загрузку не поддерживает (первая версия). - Мобильный клиент загрузку не поддерживает (первая версия).
- Staging — локальный диск сервера `/srv/pipu/uploads/<upload_id>/<file_id>` (не NFS). - Staging — локальный диск сервера `/srv/pipu/uploads/<upload_id>/<file_id>` (не NFS).
- Разрешённые форматы: `flac mp3 m4a ogg opus wav aiff wv`. Просим присылать **FLAC или WAV**; MP3 и остальные — крайний случай: форма предупреждает об этом, а очередь на добавление помечает такой файл «обратить внимание». Проверяется не расширение, а содержимое (`ffprobe`): - Разрешённые форматы: `flac mp3 m4a ogg opus wav aiff wv`. Просим присылать lossless — **FLAC, WAV или AIFF** (WavPack тоже считается lossless); MP3 и остальные lossy — крайний случай: форма предупреждает об этом, а очередь на добавление помечает такой файл «обратить внимание». Проверяется не расширение, а содержимое (`ffprobe`):
должен быть ровно один аудиопоток, длительность 5 с – 3 ч. Иначе `invalid` с кодом причины. должен быть ровно один аудиопоток, длительность 5 с – 3 ч. Иначе `invalid` с кодом причины.
- Допускается отдельная картинка обложки (`cover.jpg|png`) в той же пачке — привязывается к файлам той же папки. - Допускается отдельная картинка обложки (`cover.jpg|png`) в той же пачке — привязывается к файлам той же папки.
+2 -2
View File
@@ -200,9 +200,9 @@
"suggest_title": "Suggest tracks", "suggest_title": "Suggest tracks",
"suggest_subtitle": "Files go to the upload queue; an administrator reviews them and places them into a storage", "suggest_subtitle": "Files go to the upload queue; an administrator reviews them and places them into a storage",
"drop_title": "Drop music files or folders here", "drop_title": "Drop music files or folders here",
"drop_hint": "Use FLAC or WAV. MP3 only as a last resort: the quality is worse, and the queue marks that file “needs attention”.", "drop_hint": "Use FLAC, WAV or AIFF. MP3 only as a last resort: the quality is worse, and the queue marks that file “needs attention”.",
"drop_folders": "Folder structure helps guess the artist and album.", "drop_folders": "Folder structure helps guess the artist and album.",
"format_attention": "Not FLAC or WAV. Send MP3 only when there is no lossless file.", "format_attention": "Not lossless (FLAC, WAV, AIFF). Send MP3 only when there is no lossless file.",
"pick_files": "Choose files", "pick_files": "Choose files",
"pick_folder": "Choose folder", "pick_folder": "Choose folder",
"files": "Files to send", "files": "Files to send",
+2 -2
View File
@@ -200,9 +200,9 @@
"suggest_title": "Предложить треки", "suggest_title": "Предложить треки",
"suggest_subtitle": "Файлы попадут в очередь на добавление; администратор проверит и разложит их в хранилище", "suggest_subtitle": "Файлы попадут в очередь на добавление; администратор проверит и разложит их в хранилище",
"drop_title": "Перетащите сюда файлы или папки с музыкой", "drop_title": "Перетащите сюда файлы или папки с музыкой",
"drop_hint": "Нужны FLAC или WAV. MP3 — только в крайнем случае: качество хуже, и в очереди такой файл помечается «обратить внимание».", "drop_hint": "Нужны FLAC, WAV или AIFF. MP3 — только в крайнем случае: качество хуже, и в очереди такой файл помечается «обратить внимание».",
"drop_folders": "Структура папок поможет угадать исполнителя и альбом.", "drop_folders": "Структура папок поможет угадать исполнителя и альбом.",
"format_attention": "Не FLAC и не WAV. MP3 присылайте, только если lossless нет.", "format_attention": "Не lossless (FLAC, WAV, AIFF). MP3 присылайте, только если lossless нет.",
"pick_files": "Выбрать файлы", "pick_files": "Выбрать файлы",
"pick_folder": "Выбрать папку", "pick_folder": "Выбрать папку",
"files": "Файлы для отправки", "files": "Файлы для отправки",