fix: handle non-image modalities across uploads, previews, and filenames (#255)

SnapOtter spans five modalities now, but several code paths still assumed image input.

- dropzone: default to accept-all when no fileFilter is given (image tools still pass one); neutral "supported file types" error text instead of "image files"
- automate (pipelines): accept any modality in the file pickers and dropzones; render modality-aware previews (video player, audio waveform, document/data card) instead of always using ImageViewer/BeforeAfterSlider
- filename sanitizer: extend the double-extension allowlist beyond image extensions to video/audio/document/data so e.g. "report.csv.php" becomes "report.csv"; add tests
- thumbnail route: return 422 for non-rasterisable files (audio, data, non-PDF docs) instead of attempting a doomed Sharp decode
- pool: unknown tools fall back to the "system" pool, not the image pool
- a11y labels: "Previous/Next image", "Image viewer/area/controls/drop zone" are now modality-neutral, across all 21 locales
- copy: bulk-rename default, find-duplicates ZIP name, SSRF user-agent, fetch-urls fallback name, file-details MIME label, URL-import placeholder, help dialog
This commit is contained in:
SnapOtter
2026-06-16 18:04:48 +08:00
committed by GitHub
parent 622c9f98a5
commit 8eee17aeea
29 changed files with 420 additions and 246 deletions
+12 -12
View File
@@ -2446,13 +2446,13 @@ export const ru: TranslationKeys = {
generatingPreview: "Генерация предпросмотра...",
cannotPreviewWillProcess:
"Файлы {ext} невозможно просмотреть в браузере. Инструмент всё равно обработает этот файл.",
previousImage: "Предыдущее изображение",
nextImage: "Следующее изображение",
previousImage: "Предыдущий файл",
nextImage: "Следующий файл",
imageCounter: "{current} / {total}",
settingsLabel: "Настройки",
downloadAllZip: "Скачать всё (ZIP)",
hideSettings: "Скрыть настройки",
imageArea: "Область изображения",
imageArea: "Область предпросмотра",
disabledByAdmin: "This tool has been disabled by your administrator",
browseOtherTools: "Browse other tools",
privacyNote: "Files are processed on your server and never leave your network",
@@ -3192,10 +3192,10 @@ export const ru: TranslationKeys = {
savingIndicator: "...",
cancelButton: "Отмена",
preview: "Предпросмотр",
previousImage: "Предыдущее изображение",
nextImage: "Следующее изображение",
previousImage: "Предыдущий файл",
nextImage: "Следующий файл",
imageCounter: "{current} / {total}",
imageArea: "Область изображения",
imageArea: "Область предпросмотра",
templateSocialMedia: "Готово для соцсетей",
templatePrivacyClean: "Очистка конфиденциальности",
templateWebOptimization: "Веб-оптимизация",
@@ -3416,14 +3416,14 @@ export const ru: TranslationKeys = {
zoomOut: "Zoom out",
fitToView: "Fit to view",
actualSize: "Actual size",
previousImage: "Previous image",
nextImage: "Next image",
imageArea: "Image area",
imageViewer: "Image viewer",
previousImage: "Предыдущий файл",
nextImage: "Следующий файл",
imageArea: "Область предпросмотра",
imageViewer: "Просмотр файла",
fileDropZone: "File drop zone",
imageDropZone: "Image drop zone",
imageDropZone: "Зона перетаскивания файлов",
beforeAfterSlider: "Before/after comparison slider",
imageControls: "Image controls",
imageControls: "Управление предпросмотром",
zoomControls: "Zoom controls",
dragToReorder: "Drag to reorder",
whiteBackground: "White background",