Skip to content

Commit 1642bc0

Browse files
committed
feat: fix uploading larger files
1 parent ad21ea0 commit 1642bc0

File tree

2 files changed

+62
-3
lines changed

2 files changed

+62
-3
lines changed

apps/frontend/src/components/media/new.uploader.tsx

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import '@uppy/dashboard/dist/style.min.css';
1212
import { useVariables } from '@gitroom/react/helpers/variable.context';
1313
import Compressor from '@uppy/compressor';
1414
import { useT } from '@gitroom/react/translation/get.transation.service.client';
15+
import { useToaster } from '@gitroom/react/toaster/toaster';
1516

1617
export function MultipartFileUploader({
1718
onUploadSuccess,
@@ -58,6 +59,7 @@ export function useUppyUploader(props: {
5859
onUploadSuccess: (result: UploadResult) => void;
5960
allowedFileTypes: string;
6061
}) {
62+
const toast = useToaster();
6163
const { storageProvider, backendUrl, disableImageCompression } =
6264
useVariables();
6365
const { onUploadSuccess, allowedFileTypes } = props;
@@ -68,9 +70,55 @@ export function useUppyUploader(props: {
6870
restrictions: {
6971
maxNumberOfFiles: 5,
7072
allowedFileTypes: allowedFileTypes.split(','),
71-
maxFileSize: 1000000000,
73+
maxFileSize: 1000000000, // Default 1GB, but we'll override with custom validation
7274
},
7375
});
76+
77+
// Custom file size validation based on file type
78+
uppy2.addPreProcessor((fileIDs) => {
79+
return new Promise<void>((resolve, reject) => {
80+
const files = uppy2.getFiles();
81+
82+
for (const file of files) {
83+
if (fileIDs.includes(file.id)) {
84+
const isImage = file.type?.startsWith('image/');
85+
const isVideo = file.type?.startsWith('video/');
86+
87+
const maxImageSize = 30 * 1024 * 1024; // 30MB
88+
const maxVideoSize = 30 * 1024 * 1024; // 1000 * 1024 * 1024; // 1GB
89+
90+
if (isImage && file.size > maxImageSize) {
91+
const error = new Error(
92+
`Image file "${file.name}" is too large. Maximum size allowed is 30MB.`
93+
);
94+
uppy2.log(error.message, 'error');
95+
uppy2.info(error.message, 'error', 5000);
96+
toast.show(
97+
`Image file is too large. Maximum size allowed is 30MB.`
98+
);
99+
uppy2.removeFile(file.id); // Remove file from queue
100+
return reject(error);
101+
}
102+
103+
if (isVideo && file.size > maxVideoSize) {
104+
const error = new Error(
105+
`Video file "${file.name}" is too large. Maximum size allowed is 1GB.`
106+
);
107+
uppy2.log(error.message, 'error');
108+
uppy2.info(error.message, 'error', 5000);
109+
toast.show(
110+
`Video file is too large. Maximum size allowed is 1GB.`
111+
);
112+
uppy2.removeFile(file.id); // Remove file from queue
113+
return reject(error);
114+
}
115+
}
116+
}
117+
118+
resolve();
119+
});
120+
});
121+
74122
const { plugin, options } = getUppyUploadPlugin(
75123
storageProvider,
76124
fetch,

libraries/react-shared-libraries/src/helpers/uppy.upload.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,20 @@ export const getUppyUploadPlugin = (
3131
shouldUseMultipart: (file: any) => true,
3232
endpoint: '',
3333
createMultipartUpload: async (file: any) => {
34-
const arrayBuffer = await new Response(file.data).arrayBuffer();
35-
const fileHash = sha256(Buffer.from(arrayBuffer));
34+
let fileHash = '';
3635
const contentType = file.type;
36+
37+
// Skip hash calculation for files larger than 100MB to avoid "Invalid array length" error
38+
if (file.size <= 100 * 1024 * 1024) {
39+
try {
40+
const arrayBuffer = await new Response(file.data).arrayBuffer();
41+
fileHash = sha256(Buffer.from(arrayBuffer));
42+
} catch (error) {
43+
console.warn('Failed to calculate file hash, proceeding without hash:', error);
44+
fileHash = '';
45+
}
46+
}
47+
3748
return fetchUploadApiEndpoint(fetch, 'create-multipart-upload', {
3849
file,
3950
fileHash,

0 commit comments

Comments
 (0)