Skip to content

Commit 838f4f1

Browse files
authored
Merge pull request #355 from GTBitsOfGood/joseph-max-file-size
add max video size and max image size
2 parents 1ce458b + 4372e13 commit 838f4f1

File tree

1 file changed

+95
-2
lines changed

1 file changed

+95
-2
lines changed

web/components/PostCreationModal/FileUpload/FileDropZone.tsx

+95-2
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,59 @@ function FileDropZone(props: PropsType) {
7171
lg: <FullDropZone />,
7272
});
7373

74+
const MAX_VIDEO_SIZE = 50 * 1024 * 1024; // 50MB
75+
const MAX_IMAGE_SIZE = 3 * 1024 * 1024; // 3MB
76+
77+
async function resizeImage(file: File): Promise<File> {
78+
return new Promise((resolve, reject) => {
79+
const reader = new FileReader();
80+
reader.readAsDataURL(file);
81+
reader.onload = () => {
82+
const img = new Image();
83+
img.src = reader.result as string;
84+
img.onload = () => {
85+
const canvas = document.createElement("canvas");
86+
const ctx = canvas.getContext("2d");
87+
if (!ctx) return reject(new Error("Canvas context not available"));
88+
89+
const MAX_WIDTH = 4096;
90+
const MAX_HEIGHT = 4096;
91+
let width = img.width;
92+
let height = img.height;
93+
94+
if (width > MAX_WIDTH || height > MAX_HEIGHT) {
95+
if (width > height) {
96+
height = (height * MAX_WIDTH) / width;
97+
width = MAX_WIDTH;
98+
} else {
99+
width = (width * MAX_HEIGHT) / height;
100+
height = MAX_HEIGHT;
101+
}
102+
}
103+
104+
canvas.width = width;
105+
canvas.height = height;
106+
ctx.drawImage(img, 0, 0, width, height);
107+
108+
canvas.toBlob(
109+
(blob) => {
110+
if (blob) {
111+
resolve(new File([blob], file.name, { type: "image/jpeg" }));
112+
} else {
113+
reject(new Error("Failed to resize image"));
114+
}
115+
},
116+
"image/jpeg",
117+
0.8
118+
);
119+
};
120+
};
121+
reader.onerror = (error) => reject(error);
122+
});
123+
}
124+
74125
const onDrop = useCallback(
75-
(acceptedFiles: File[], fileRejections: FileRejection[]) => {
126+
async (acceptedFiles: File[], fileRejections: FileRejection[]) => {
76127
if (fileRejections.length > 0) {
77128
toast({
78129
status: "error",
@@ -104,7 +155,49 @@ function FileDropZone(props: PropsType) {
104155
return;
105156
}
106157

107-
setFileArr([...fileArr, ...acceptedFiles]);
158+
let newFiles: File[] = [];
159+
160+
const processedFiles = await Promise.all(
161+
acceptedFiles.map(async (file) => {
162+
console.log(file.size);
163+
if (file.type.startsWith("video/")) {
164+
if (file.size > MAX_VIDEO_SIZE) {
165+
toast({
166+
status: "error",
167+
position: "top",
168+
title: "Error",
169+
description: `The video ${file.name} exceeds the 50MB limit.`,
170+
duration: 4000,
171+
isClosable: true,
172+
});
173+
return null;
174+
}
175+
return file;
176+
} else if (file.type.startsWith("image/")) {
177+
if (file.size > MAX_IMAGE_SIZE) {
178+
try {
179+
return await resizeImage(file);
180+
} catch (error) {
181+
console.error(`Failed to resize image ${file.name}`, error);
182+
toast({
183+
status: "error",
184+
position: "top",
185+
title: "Error",
186+
description: `Failed to resize image ${file.name}.`,
187+
duration: 4000,
188+
isClosable: true,
189+
});
190+
return null;
191+
}
192+
}
193+
return file;
194+
}
195+
return null;
196+
})
197+
);
198+
199+
newFiles = processedFiles.filter((file): file is File => file !== null);
200+
setFileArr([...fileArr, ...newFiles]);
108201
},
109202
[fileArr, setFileArr]
110203
);

0 commit comments

Comments
 (0)