Update hooks/useFileUpload.ts
Browse files- hooks/useFileUpload.ts +46 -13
hooks/useFileUpload.ts
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
|
|
| 1 |
import { useState, useCallback } from 'react';
|
| 2 |
import { FileItem, UploadStatus } from '../types';
|
| 3 |
-
import {
|
| 4 |
|
| 5 |
export const useFileUpload = () => {
|
| 6 |
-
// Local Upload State
|
| 7 |
const [files, setFiles] = useState<FileItem[]>([]);
|
| 8 |
const [isUploading, setIsUploading] = useState(false);
|
| 9 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
// --- UPLOAD LOGIC ---
|
| 11 |
|
| 12 |
const addFiles = useCallback((newFilesList: FileItem[]) => {
|
|
@@ -30,34 +34,63 @@ export const useFileUpload = () => {
|
|
| 30 |
|
| 31 |
setIsUploading(true);
|
| 32 |
|
| 33 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
setFiles((prev) =>
|
| 35 |
prev.map((f) =>
|
| 36 |
-
|
|
|
|
|
|
|
| 37 |
)
|
| 38 |
);
|
| 39 |
|
| 40 |
try {
|
| 41 |
-
|
|
|
|
|
|
|
| 42 |
file: item.file,
|
| 43 |
path: item.path
|
| 44 |
-
});
|
|
|
|
|
|
|
|
|
|
| 45 |
|
|
|
|
| 46 |
setFiles((prev) =>
|
| 47 |
-
prev.map((f) =>
|
| 48 |
-
|
| 49 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 50 |
);
|
| 51 |
} catch (err: any) {
|
|
|
|
| 52 |
setFiles((prev) =>
|
| 53 |
prev.map((f) =>
|
| 54 |
-
|
|
|
|
|
|
|
| 55 |
)
|
| 56 |
);
|
| 57 |
}
|
| 58 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 59 |
|
| 60 |
-
await Promise.allSettled(uploadPromises);
|
| 61 |
setIsUploading(false);
|
| 62 |
}, [files]);
|
| 63 |
|
|
@@ -69,4 +102,4 @@ export const useFileUpload = () => {
|
|
| 69 |
updateFilePath,
|
| 70 |
startUpload
|
| 71 |
};
|
| 72 |
-
};
|
|
|
|
| 1 |
+
|
| 2 |
import { useState, useCallback } from 'react';
|
| 3 |
import { FileItem, UploadStatus } from '../types';
|
| 4 |
+
import { uploadBatchToHub } from '../services/hfService';
|
| 5 |
|
| 6 |
export const useFileUpload = () => {
|
|
|
|
| 7 |
const [files, setFiles] = useState<FileItem[]>([]);
|
| 8 |
const [isUploading, setIsUploading] = useState(false);
|
| 9 |
|
| 10 |
+
// --- CONFIGURATION ---
|
| 11 |
+
const BATCH_SIZE = 5; // Files per request
|
| 12 |
+
const CONCURRENCY_LIMIT = 3; // Parallel requests
|
| 13 |
+
|
| 14 |
// --- UPLOAD LOGIC ---
|
| 15 |
|
| 16 |
const addFiles = useCallback((newFilesList: FileItem[]) => {
|
|
|
|
| 34 |
|
| 35 |
setIsUploading(true);
|
| 36 |
|
| 37 |
+
// 1. Create Batches (Chunks)
|
| 38 |
+
const batches = [];
|
| 39 |
+
for (let i = 0; i < filesToUpload.length; i += BATCH_SIZE) {
|
| 40 |
+
batches.push(filesToUpload.slice(i, i + BATCH_SIZE));
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
// 2. Process Batch Function
|
| 44 |
+
const processBatch = async (batch: FileItem[]) => {
|
| 45 |
+
// Set status UPLOADING for this batch
|
| 46 |
setFiles((prev) =>
|
| 47 |
prev.map((f) =>
|
| 48 |
+
batch.find((b) => b.id === f.id)
|
| 49 |
+
? { ...f, status: UploadStatus.UPLOADING, error: undefined }
|
| 50 |
+
: f
|
| 51 |
)
|
| 52 |
);
|
| 53 |
|
| 54 |
try {
|
| 55 |
+
// Prepare payload for service
|
| 56 |
+
const batchPayload = batch.map(item => ({
|
| 57 |
+
id: item.id,
|
| 58 |
file: item.file,
|
| 59 |
path: item.path
|
| 60 |
+
}));
|
| 61 |
+
|
| 62 |
+
// Call API
|
| 63 |
+
const urls = await uploadBatchToHub(batchPayload);
|
| 64 |
|
| 65 |
+
// Success: Update status and add URLs
|
| 66 |
setFiles((prev) =>
|
| 67 |
+
prev.map((f) => {
|
| 68 |
+
const index = batch.findIndex(b => b.id === f.id);
|
| 69 |
+
if (index !== -1) {
|
| 70 |
+
return { ...f, status: UploadStatus.SUCCESS, url: urls[index] };
|
| 71 |
+
}
|
| 72 |
+
return f;
|
| 73 |
+
})
|
| 74 |
);
|
| 75 |
} catch (err: any) {
|
| 76 |
+
// Error: Update status for whole batch
|
| 77 |
setFiles((prev) =>
|
| 78 |
prev.map((f) =>
|
| 79 |
+
batch.find((b) => b.id === f.id)
|
| 80 |
+
? { ...f, status: UploadStatus.ERROR, error: err.message }
|
| 81 |
+
: f
|
| 82 |
)
|
| 83 |
);
|
| 84 |
}
|
| 85 |
+
};
|
| 86 |
+
|
| 87 |
+
// 3. Execute with Concurrency Limit
|
| 88 |
+
// We process batches in groups of CONCURRENCY_LIMIT
|
| 89 |
+
for (let i = 0; i < batches.length; i += CONCURRENCY_LIMIT) {
|
| 90 |
+
const activeBatches = batches.slice(i, i + CONCURRENCY_LIMIT);
|
| 91 |
+
await Promise.allSettled(activeBatches.map(batch => processBatch(batch)));
|
| 92 |
+
}
|
| 93 |
|
|
|
|
| 94 |
setIsUploading(false);
|
| 95 |
}, [files]);
|
| 96 |
|
|
|
|
| 102 |
updateFilePath,
|
| 103 |
startUpload
|
| 104 |
};
|
| 105 |
+
};
|