uploadv2 / hooks /useFileUpload.ts
marriedtermiteblyi's picture
Update hooks/useFileUpload.ts
c0659f6 verified
raw
history blame
3.05 kB
import { useState, useCallback } from 'react';
import { FileItem, UploadStatus } from '../types';
import { uploadBatchToHub } from '../services/hfService';
export const useFileUpload = () => {
const [files, setFiles] = useState<FileItem[]>([]);
const [isUploading, setIsUploading] = useState(false);
// --- CONFIGURATION ---
const BATCH_SIZE = 5; // Files per request
const CONCURRENCY_LIMIT = 3; // Parallel requests
// --- UPLOAD LOGIC ---
const addFiles = useCallback((newFilesList: FileItem[]) => {
setFiles((prev) => [...prev, ...newFilesList]);
}, []);
const removeFile = useCallback((id: string) => {
setFiles((prev) => prev.filter((f) => f.id !== id));
}, []);
const updateFilePath = useCallback((id: string, newPath: string) => {
setFiles((prev) => prev.map((f) => (f.id === id ? { ...f, path: newPath } : f)));
}, []);
const startUpload = useCallback(async () => {
const filesToUpload = files.filter(
(f) => f.status === UploadStatus.IDLE || f.status === UploadStatus.ERROR
);
if (filesToUpload.length === 0) return;
setIsUploading(true);
// 1. Create Batches (Chunks)
const batches = [];
for (let i = 0; i < filesToUpload.length; i += BATCH_SIZE) {
batches.push(filesToUpload.slice(i, i + BATCH_SIZE));
}
// 2. Process Batch Function
const processBatch = async (batch: FileItem[]) => {
// Set status UPLOADING for this batch
setFiles((prev) =>
prev.map((f) =>
batch.find((b) => b.id === f.id)
? { ...f, status: UploadStatus.UPLOADING, error: undefined }
: f
)
);
try {
// Prepare payload for service
const batchPayload = batch.map(item => ({
id: item.id,
file: item.file,
path: item.path
}));
// Call API
const urls = await uploadBatchToHub(batchPayload);
// Success: Update status and add URLs
setFiles((prev) =>
prev.map((f) => {
const index = batch.findIndex(b => b.id === f.id);
if (index !== -1) {
return { ...f, status: UploadStatus.SUCCESS, url: urls[index] };
}
return f;
})
);
} catch (err: any) {
// Error: Update status for whole batch
setFiles((prev) =>
prev.map((f) =>
batch.find((b) => b.id === f.id)
? { ...f, status: UploadStatus.ERROR, error: err.message }
: f
)
);
}
};
// 3. Execute with Concurrency Limit
// We process batches in groups of CONCURRENCY_LIMIT
for (let i = 0; i < batches.length; i += CONCURRENCY_LIMIT) {
const activeBatches = batches.slice(i, i + CONCURRENCY_LIMIT);
await Promise.allSettled(activeBatches.map(batch => processBatch(batch)));
}
setIsUploading(false);
}, [files]);
return {
files,
isUploading,
addFiles,
removeFile,
updateFilePath,
startUpload
};
};