Co-authored-by: Silow9 <soulskytony@gmail.com>tags/1.3.1
| e.stopPropagation() | e.stopPropagation() | ||||
| e.target === dragRef.current && setDragging(false) | e.target === dragRef.current && setDragging(false) | ||||
| } | } | ||||
| type FileWithPath = { | |||||
| relativePath?: string | |||||
| } & File | |||||
| const traverseFileEntry = useCallback( | |||||
| (entry: any, prefix = ''): Promise<FileWithPath[]> => { | |||||
| return new Promise((resolve) => { | |||||
| if (entry.isFile) { | |||||
| entry.file((file: FileWithPath) => { | |||||
| file.relativePath = `${prefix}${file.name}` | |||||
| resolve([file]) | |||||
| }) | |||||
| } | |||||
| else if (entry.isDirectory) { | |||||
| const reader = entry.createReader() | |||||
| const entries: any[] = [] | |||||
| const read = () => { | |||||
| reader.readEntries(async (results: FileSystemEntry[]) => { | |||||
| if (!results.length) { | |||||
| const files = await Promise.all( | |||||
| entries.map(ent => | |||||
| traverseFileEntry(ent, `${prefix}${entry.name}/`), | |||||
| ), | |||||
| ) | |||||
| resolve(files.flat()) | |||||
| } | |||||
| else { | |||||
| entries.push(...results) | |||||
| read() | |||||
| } | |||||
| }) | |||||
| } | |||||
| read() | |||||
| } | |||||
| else { | |||||
| resolve([]) | |||||
| } | |||||
| }) | |||||
| }, | |||||
| [], | |||||
| ) | |||||
| const handleDrop = useCallback((e: DragEvent) => { | |||||
| e.preventDefault() | |||||
| e.stopPropagation() | |||||
| setDragging(false) | |||||
| if (!e.dataTransfer) | |||||
| return | |||||
| let files = [...e.dataTransfer.files] as File[] | |||||
| if (notSupportBatchUpload) | |||||
| files = files.slice(0, 1) | |||||
| const validFiles = files.filter(isValid) | |||||
| initialUpload(validFiles) | |||||
| }, [initialUpload, isValid, notSupportBatchUpload]) | |||||
| const handleDrop = useCallback( | |||||
| async (e: DragEvent) => { | |||||
| e.preventDefault() | |||||
| e.stopPropagation() | |||||
| setDragging(false) | |||||
| if (!e.dataTransfer) return | |||||
| const nested = await Promise.all( | |||||
| Array.from(e.dataTransfer.items).map((it) => { | |||||
| const entry = (it as any).webkitGetAsEntry?.() | |||||
| if (entry) return traverseFileEntry(entry) | |||||
| const f = it.getAsFile?.() | |||||
| return f ? Promise.resolve([f]) : Promise.resolve([]) | |||||
| }), | |||||
| ) | |||||
| let files = nested.flat() | |||||
| if (notSupportBatchUpload) files = files.slice(0, 1) | |||||
| const valid = files.filter(isValid) | |||||
| initialUpload(valid) | |||||
| }, | |||||
| [initialUpload, isValid, notSupportBatchUpload, traverseFileEntry], | |||||
| ) | |||||
| const selectHandle = () => { | const selectHandle = () => { | ||||
| if (fileUploader.current) | if (fileUploader.current) | ||||
| fileUploader.current.click() | fileUploader.current.click() |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Textdatei hochladen', | title: 'Textdatei hochladen', | ||||
| button: 'Datei hierher ziehen oder', | |||||
| button: 'Dateien und Ordner hierher ziehen oder klicken', | |||||
| browse: 'Durchsuchen', | browse: 'Durchsuchen', | ||||
| tip: 'Unterstützt {{supportTypes}}. Maximal {{size}}MB pro Datei.', | tip: 'Unterstützt {{supportTypes}}. Maximal {{size}}MB pro Datei.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Upload file', | title: 'Upload file', | ||||
| button: 'Drag and drop file, or', | |||||
| button: 'Drag and drop file or folder, or', | |||||
| browse: 'Browse', | browse: 'Browse', | ||||
| tip: 'Supports {{supportTypes}}. Max {{size}}MB each.', | tip: 'Supports {{supportTypes}}. Max {{size}}MB each.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Cargar archivo', | title: 'Cargar archivo', | ||||
| button: 'Arrastra y suelta el archivo, o', | |||||
| button: 'Arrastre y suelte archivos o carpetas, o', | |||||
| browse: 'Buscar', | browse: 'Buscar', | ||||
| tip: 'Soporta {{supportTypes}}. Máximo {{size}}MB cada uno.', | tip: 'Soporta {{supportTypes}}. Máximo {{size}}MB cada uno.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'بارگذاری فایل', | title: 'بارگذاری فایل', | ||||
| button: 'کشیدن و رها کردن فایل، یا', | |||||
| button: 'فایل ها یا پوشه ها را بکشید و رها کنید یا', | |||||
| browse: 'مرور', | browse: 'مرور', | ||||
| tip: 'پشتیبانی از {{supportTypes}}. حداکثر {{size}}MB هر کدام.', | tip: 'پشتیبانی از {{supportTypes}}. حداکثر {{size}}MB هر کدام.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Télécharger le fichier texte', | title: 'Télécharger le fichier texte', | ||||
| button: 'Glisser et déposer le fichier, ou', | |||||
| button: 'Faites glisser et déposez des fichiers ou des dossiers, ou', | |||||
| browse: 'Parcourir', | browse: 'Parcourir', | ||||
| tip: 'Prend en charge {{supportTypes}}. Max {{size}}MB chacun.', | tip: 'Prend en charge {{supportTypes}}. Max {{size}}MB chacun.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'फ़ाइल अपलोड करें', | title: 'फ़ाइल अपलोड करें', | ||||
| button: 'फ़ाइल खींचें और छोड़ें, या', | |||||
| button: 'फ़ाइलों या फ़ोल्डरों को खींचें और छोड़ें, या', | |||||
| browse: 'ब्राउज़ करें', | browse: 'ब्राउज़ करें', | ||||
| tip: 'समर्थित {{supportTypes}}। प्रत्येक अधिकतम {{size}}MB।', | tip: 'समर्थित {{supportTypes}}। प्रत्येक अधिकतम {{size}}MB।', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Carica file', | title: 'Carica file', | ||||
| button: 'Trascina e rilascia il file, o', | |||||
| button: 'Trascina e rilascia file o cartelle, oppure', | |||||
| browse: 'Sfoglia', | browse: 'Sfoglia', | ||||
| tip: 'Supporta {{supportTypes}}. Max {{size}}MB ciascuno.', | tip: 'Supporta {{supportTypes}}. Max {{size}}MB ciascuno.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'テキストファイルをアップロード', | title: 'テキストファイルをアップロード', | ||||
| button: 'ファイルをドラッグ&ドロップするか', | |||||
| button: 'ファイルまたはフォルダをドラッグアンドドロップする', | |||||
| browse: '参照', | browse: '参照', | ||||
| tip: '{{supportTypes}}をサポートしています。1つあたりの最大サイズは{{size}}MBです。', | tip: '{{supportTypes}}をサポートしています。1つあたりの最大サイズは{{size}}MBです。', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: '텍스트 파일 업로드', | title: '텍스트 파일 업로드', | ||||
| button: '파일을 끌어다 놓거나', | |||||
| button: '파일이나 폴더를 끌어서 놓기', | |||||
| browse: '찾아보기', | browse: '찾아보기', | ||||
| tip: '{{supportTypes}}을(를) 지원합니다. 파일당 최대 크기는 {{size}}MB입니다.', | tip: '{{supportTypes}}을(를) 지원합니다. 파일당 최대 크기는 {{size}}MB입니다.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Prześlij plik tekstowy', | title: 'Prześlij plik tekstowy', | ||||
| button: 'Przeciągnij i upuść plik lub', | |||||
| button: 'Przeciągnij i upuść pliki lub foldery lub', | |||||
| browse: 'Przeglądaj', | browse: 'Przeglądaj', | ||||
| tip: 'Obsługuje {{supportTypes}}. Maksymalnie {{size}}MB każdy.', | tip: 'Obsługuje {{supportTypes}}. Maksymalnie {{size}}MB każdy.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Enviar arquivo de texto', | title: 'Enviar arquivo de texto', | ||||
| button: 'Arraste e solte o arquivo, ou', | |||||
| button: 'Arraste e solte arquivos ou pastas, ou', | |||||
| browse: 'Navegar', | browse: 'Navegar', | ||||
| tip: 'Suporta {{supportTypes}}. Máximo de {{size}}MB cada.', | tip: 'Suporta {{supportTypes}}. Máximo de {{size}}MB cada.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Încărcați fișier text', | title: 'Încărcați fișier text', | ||||
| button: 'Trageți și fixați fișierul, sau', | |||||
| button: 'Trageți și plasați fișiere sau foldere sau', | |||||
| browse: 'Răsfoire', | browse: 'Răsfoire', | ||||
| tip: 'Acceptă {{supportTypes}}. Maxim {{size}}MB fiecare.', | tip: 'Acceptă {{supportTypes}}. Maxim {{size}}MB fiecare.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Загрузить файл', | title: 'Загрузить файл', | ||||
| button: 'Перетащите файл или', | |||||
| button: 'Перетащите файлы или папки или', | |||||
| browse: 'Обзор', | browse: 'Обзор', | ||||
| tip: 'Поддерживаются {{supportTypes}}. Максимум {{size}} МБ каждый.', | tip: 'Поддерживаются {{supportTypes}}. Максимум {{size}} МБ каждый.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Naloži datoteko', | title: 'Naloži datoteko', | ||||
| button: 'Povleci in spusti datoteko ali', | |||||
| button: 'Povleci in spusti datoteke ali mape oz', | |||||
| browse: 'Prebrskaj', | browse: 'Prebrskaj', | ||||
| tip: 'Podprti tipi datotek: {{supportTypes}}. Največ {{size}}MB na datoteko.', | tip: 'Podprti tipi datotek: {{supportTypes}}. Največ {{size}}MB na datoteko.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'อัปโหลดไฟล์', | title: 'อัปโหลดไฟล์', | ||||
| button: 'ลากและวางไฟล์ หรือ', | |||||
| button: 'ลากและวางไฟล์หรือโฟลเดอร์หรือ', | |||||
| browse: 'เล็ม', | browse: 'เล็ม', | ||||
| tip: 'รองรับ {{supportTypes}} สูงสุด {{size}}MB แต่ละตัว', | tip: 'รองรับ {{supportTypes}} สูงสุด {{size}}MB แต่ละตัว', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Dosya yükle', | title: 'Dosya yükle', | ||||
| button: 'Dosyayı sürükleyip bırakın veya', | |||||
| button: 'Dosyaları veya klasörleri sürükleyip bırakın veya', | |||||
| browse: 'Göz atın', | browse: 'Göz atın', | ||||
| tip: 'Destekler {{supportTypes}}. Her biri en fazla {{size}}MB.', | tip: 'Destekler {{supportTypes}}. Her biri en fazla {{size}}MB.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Завантажити текстовий файл', | title: 'Завантажити текстовий файл', | ||||
| button: 'Перетягніть файл або', | |||||
| button: 'Перетягніть файли або папки або', | |||||
| browse: 'Оберіть', | browse: 'Оберіть', | ||||
| tip: 'Підтримуються {{supportTypes}}. Максимум {{size}} МБ кожен.', | tip: 'Підтримуються {{supportTypes}}. Максимум {{size}} МБ кожен.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: 'Tải lên tệp văn bản', | title: 'Tải lên tệp văn bản', | ||||
| button: 'Kéo và thả tệp, hoặc', | |||||
| button: 'Kéo và thả các tập tin hoặc thư mục, hoặc', | |||||
| browse: 'Chọn tệp', | browse: 'Chọn tệp', | ||||
| tip: 'Hỗ trợ {{supportTypes}}. Tối đa {{size}}MB mỗi tệp.', | tip: 'Hỗ trợ {{supportTypes}}. Tối đa {{size}}MB mỗi tệp.', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: '上传文本文件', | title: '上传文本文件', | ||||
| button: '拖拽文件至此,或者', | |||||
| button: '拖拽文件或文件夹至此,或者', | |||||
| browse: '选择文件', | browse: '选择文件', | ||||
| tip: '已支持 {{supportTypes}},每个文件不超过 {{size}}MB。', | tip: '已支持 {{supportTypes}},每个文件不超过 {{size}}MB。', | ||||
| validation: { | validation: { |
| }, | }, | ||||
| uploader: { | uploader: { | ||||
| title: '上傳文字檔案', | title: '上傳文字檔案', | ||||
| button: '拖拽檔案至此,或者', | |||||
| button: '拖拽檔案或檔案夾至此,或者', | |||||
| browse: '選擇檔案', | browse: '選擇檔案', | ||||
| tip: '已支援 {{supportTypes}},每個檔案不超過 {{size}}MB。', | tip: '已支援 {{supportTypes}},每個檔案不超過 {{size}}MB。', | ||||
| validation: { | validation: { |