fix: implement chunked file uploading to bypass proxy size limits
Build and Deploy / build-and-push (push) Successful in 27s
Build and Deploy / build-and-push (push) Successful in 27s
This commit is contained in:
+56
-13
@@ -112,19 +112,62 @@ export const api = {
|
||||
|
||||
// Storage
|
||||
uploadAsset: async (fileBlob) => {
|
||||
const formData = new FormData();
|
||||
formData.append('file', fileBlob);
|
||||
|
||||
const chunkSize = 10 * 1024 * 1024; // 10MB chunks
|
||||
const token = localStorage.getItem('auth_token');
|
||||
const headers = token ? { Authorization: `Bearer ${token}` } : {};
|
||||
|
||||
const res = await fetch(`${API_URL}/upload`, {
|
||||
method: 'POST',
|
||||
headers,
|
||||
body: formData
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.error);
|
||||
return data.url;
|
||||
const authHeaders = token ? { Authorization: `Bearer ${token}` } : {};
|
||||
|
||||
if (fileBlob.size <= chunkSize) {
|
||||
// Standard upload for small files
|
||||
const formData = new FormData();
|
||||
formData.append('file', fileBlob);
|
||||
|
||||
const res = await fetch(`${API_URL}/upload`, {
|
||||
method: 'POST',
|
||||
headers: authHeaders,
|
||||
body: formData
|
||||
});
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.error);
|
||||
return data.url;
|
||||
} else {
|
||||
// Chunked upload for large files
|
||||
const uploadId = Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
|
||||
const totalChunks = Math.ceil(fileBlob.size / chunkSize);
|
||||
|
||||
for (let i = 0; i < totalChunks; i++) {
|
||||
const chunk = fileBlob.slice(i * chunkSize, (i + 1) * chunkSize);
|
||||
const formData = new FormData();
|
||||
formData.append('file', chunk);
|
||||
formData.append('uploadId', uploadId);
|
||||
formData.append('chunkIndex', i.toString());
|
||||
formData.append('totalChunks', totalChunks.toString());
|
||||
|
||||
const res = await fetch(`${API_URL}/upload/chunk`, {
|
||||
method: 'POST',
|
||||
headers: authHeaders,
|
||||
body: formData
|
||||
});
|
||||
if (!res.ok) throw new Error(`Failed to upload chunk ${i}`);
|
||||
}
|
||||
|
||||
const completeHeaders = {
|
||||
'Content-Type': 'application/json',
|
||||
...authHeaders
|
||||
};
|
||||
|
||||
const res = await fetch(`${API_URL}/upload/complete`, {
|
||||
method: 'POST',
|
||||
headers: completeHeaders,
|
||||
body: JSON.stringify({
|
||||
uploadId,
|
||||
fileName: fileBlob.name || 'uploaded_file',
|
||||
totalChunks
|
||||
})
|
||||
});
|
||||
|
||||
const data = await res.json();
|
||||
if (!res.ok) throw new Error(data.error);
|
||||
return data.url;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -5,8 +5,12 @@ export const uploadAssetToStorage = async (file: Blob | File, bucket: string, pa
|
||||
const url = await api.uploadAsset(file);
|
||||
return url;
|
||||
} catch (err) {
|
||||
console.warn("Storage upload exception, falling back to data URL.", err);
|
||||
return await fileToDataUrl(file);
|
||||
console.warn("Storage upload exception.", err);
|
||||
if (file.size < 5 * 1024 * 1024) {
|
||||
console.warn("Falling back to data URL for small file.");
|
||||
return await fileToDataUrl(file);
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user