feat(uploads): preview storage paths, detect templates, attach covers and withdraw batches
ci / module boundaries / boundaries (push) Successful in 7s
ci / contract / contract (сгенерированный код совпадает с openapi.yaml) (push) Successful in 55s
ci / ts / ts (packages + web) (push) Failing after 4m4s
ci / api / api (push) Successful in 55s
ci / db / db (push) Failing after 1m14s
ci / mobile / mobile (Metro-бандл Android) (push) Successful in 1m11s

This commit is contained in:
mrleo1nid committed 2026-10-29 10:28:29 +03:00
1 parent 5e2d1e902b
commit 64dd8ed05e
29 files changed
+1219 -471

No files matched your search

+18
View File
@@ -210,6 +210,9 @@
"analysis_error_unknown": "No error reason was recorded."
},
"write_template": {
"auto_hint": "If no template is saved, we suggest the most common layout in the storage. You can edit it; it is applied only when you save.",
"detecting": "Detecting the storage file layout…",
"detected": "The suggested layout matches {{matched}} of {{total}} sampled files.",
"title": "Uploads and path template",
"intro": "Approved tracks from the upload queue are placed here using a template that repeats this storage's folder layout.",
"accepts": "Accept uploads into this storage",
@@ -294,6 +297,10 @@
"col_date": "Uploaded",
"received": "{{pct}}% received — open “Suggest tracks” in the same tab to continue",
"withdraw": "Withdraw",
"select_visible": "Select eligible files on this page",
"bulk_withdraw": "Withdraw multiple submissions",
"withdraw_selected": "Withdraw selected",
"withdraw_failed": "Could not withdraw {{count}} files: {{reason}}",
"load_more": "Show more",
"queue_title": "Upload queue",
"queue_subtitle": "Check the metadata and the storage path, then approve or reject",
@@ -351,6 +358,17 @@
"meta_track": "Track number",
"meta_disc": "Disc",
"target_source": "Storage",
"cover_hint": "Album covers named cover.jpg or cover.png are uploaded with the tracks. Otherwise we use embedded artwork from the first track that contains it.",
"cover_found": "Album cover: {{name}}",
"cover_embedded": "Album cover: embedded artwork",
"destination": "Will be saved to",
"destination_imported": "Saved to",
"target_selected": "Selected storage",
"target_not_selected": "No storage selected",
"target_path_hint": "Path relative to the storage root",
"target_path_missing": "Destination path has not been calculated",
"choose_destination": "Choose storage",
"fix_destination": "Fix destination",
"target_default": "Default",
"tags_note": "Edited fields are written into the file tags on import, so path and tags stay consistent.",
"save": "Save",
+1 -1
View File
@@ -60,7 +60,7 @@
"source_not_found": "Storage not found",
"scan_running": "A scan is already running",
"source_offline": "The storage is not connected",
"template_unavailable": "Could not suggest a template: no storage pattern converts to a template, or the storage has no files"
"template_unavailable": "Could not infer a layout from paths and metadata. Scan the storage first or enter a template manually."
},
"catalog": {
"not_found": "Not found"
+18
View File
@@ -210,6 +210,9 @@
"analysis_error_unknown": "Причина ошибки не указана."
},
"write_template": {
"auto_hint": "Если шаблон ещё не задан, определим его по преобладающей структуре файлов хранилища. Предложение можно изменить вручную; оно применяется только после сохранения.",
"detecting": "Определяем структуру файлов хранилища…",
"detected": "Предложенная структура совпадает с {{matched}} из {{total}} файлов выборки.",
"title": "Приём загрузок и шаблон пути",
"intro": "Сюда раскладываются одобренные треки из очереди на добавление — по шаблону, который повторяет структуру папок этого хранилища.",
"accepts": "Принимать загрузки в это хранилище",
@@ -294,6 +297,10 @@
"col_date": "Загружен",
"received": "принято {{pct}}% — откройте «Предложить треки» в той же вкладке, чтобы продолжить",
"withdraw": "Отозвать",
"select_visible": "Выбрать доступные файлы на странице",
"bulk_withdraw": "Массовый отзыв предложений",
"withdraw_selected": "Отозвать выбранные",
"withdraw_failed": "Не удалось отозвать: {{count}}. {{reason}}",
"load_more": "Показать ещё",
"queue_title": "Очередь на добавление",
"queue_subtitle": "Проверьте метаданные и путь в хранилище, затем одобрите или отклоните",
@@ -351,6 +358,17 @@
"meta_track": "Номер трека",
"meta_disc": "Диск",
"target_source": "Хранилище",
"cover_hint": "Обложку cover.jpg или cover.png из папки альбома загрузим вместе с треками. Если её нет, возьмём встроенную обложку из первого трека, где она есть.",
"cover_found": "Обложка альбома: {{name}}",
"cover_embedded": "Обложка альбома: из тегов трека",
"destination": "Будет записано в",
"destination_imported": "Записано в",
"target_selected": "Выбранное хранилище",
"target_not_selected": "Хранилище не выбрано",
"target_path_hint": "Путь относительно корня хранилища",
"target_path_missing": "Путь записи не рассчитан",
"choose_destination": "Выбрать хранилище",
"fix_destination": "Исправить размещение",
"target_default": "По умолчанию",
"tags_note": "Правленые поля запишутся в теги файла при импорте — путь и теги не разойдутся.",
"save": "Сохранить",
+1 -1
View File
@@ -60,7 +60,7 @@
"source_not_found": "Хранилище не найдено",
"scan_running": "Скан уже идёт",
"source_offline": "Хранилище не подключено",
"template_unavailable": "Не удалось подобрать шаблон: ни один регэксп хранилища не переводится в шаблон или в хранилище нет файлов"
"template_unavailable": "Не удалось определить структуру по путям и метаданным. Сначала просканируйте хранилище или задайте шаблон вручную."
},
"catalog": {
"not_found": "Не найдено"