saq1b commited on
Commit
66210a8
·
1 Parent(s): 23841ca

refactor App component to manage temporary URLs and prevent memory leaks

Browse files
Files changed (1) hide show
  1. src/App.jsx +39 -12
src/App.jsx CHANGED
@@ -25,14 +25,6 @@ import axios from 'axios';
25
  import JSZip from 'jszip';
26
  import { saveAs } from 'file-saver';
27
 
28
- // Function to convert file to base64
29
- const toBase64 = file => new Promise((resolve, reject) => {
30
- const reader = new FileReader();
31
- reader.readAsDataURL(file);
32
- reader.onload = () => resolve(reader.result.split(',')[1]);
33
- reader.onerror = error => reject(error);
34
- });
35
-
36
  // Function to get file extension
37
  const getFileExtension = filename => {
38
  return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
@@ -51,6 +43,7 @@ const App = () => {
51
  const [progress, setProgress] = useState(0);
52
  const fileInputRef = useRef(null);
53
  const toast = useToast();
 
54
 
55
  const handleFileChange = async (e) => {
56
  const files = Array.from(e.target.files);
@@ -97,6 +90,10 @@ const App = () => {
97
  setProcessing(true);
98
  const pendingImages = uploadedImages.filter(img => img.status === 'pending');
99
 
 
 
 
 
100
  for (let i = 0; i < pendingImages.length; i++) {
101
  const image = pendingImages[i];
102
 
@@ -108,12 +105,13 @@ const App = () => {
108
  ));
109
 
110
  try {
111
- // Convert image to base64
112
- const base64Image = await toBase64(image.file);
 
113
 
114
- // Call the GLIF API
115
  const response = await axios.post('https://simple-api.glif.app/cm7yya7850000la0ckalxpix2', {
116
- image: base64Image
117
  }, {
118
  headers: {
119
  'Authorization': `Bearer ${apiKey}`,
@@ -144,6 +142,10 @@ const App = () => {
144
  }
145
  }
146
 
 
 
 
 
147
  setProgress(100);
148
  setProcessing(false);
149
 
@@ -210,14 +212,39 @@ const App = () => {
210
  };
211
 
212
  const removeImage = (id) => {
 
 
 
 
 
 
 
213
  setUploadedImages(prev => prev.filter(img => img.id !== id));
214
  };
215
 
216
  const clearAll = () => {
 
 
 
 
 
217
  setUploadedImages([]);
218
  if (fileInputRef.current) fileInputRef.current.value = '';
219
  };
220
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  const getStatusBadge = (status) => {
222
  switch (status) {
223
  case 'pending':
 
25
  import JSZip from 'jszip';
26
  import { saveAs } from 'file-saver';
27
 
 
 
 
 
 
 
 
 
28
  // Function to get file extension
29
  const getFileExtension = filename => {
30
  return filename.slice((filename.lastIndexOf(".") - 1 >>> 0) + 2);
 
43
  const [progress, setProgress] = useState(0);
44
  const fileInputRef = useRef(null);
45
  const toast = useToast();
46
+ const temporaryUrlsRef = useRef([]);
47
 
48
  const handleFileChange = async (e) => {
49
  const files = Array.from(e.target.files);
 
90
  setProcessing(true);
91
  const pendingImages = uploadedImages.filter(img => img.status === 'pending');
92
 
93
+ // Clean up any previous temporary URLs
94
+ temporaryUrlsRef.current.forEach(url => URL.revokeObjectURL(url));
95
+ temporaryUrlsRef.current = [];
96
+
97
  for (let i = 0; i < pendingImages.length; i++) {
98
  const image = pendingImages[i];
99
 
 
105
  ));
106
 
107
  try {
108
+ // Create a URL for the image file
109
+ const imageUrl = URL.createObjectURL(image.file);
110
+ temporaryUrlsRef.current.push(imageUrl);
111
 
112
+ // Call the GLIF API with the image URL
113
  const response = await axios.post('https://simple-api.glif.app/cm7yya7850000la0ckalxpix2', {
114
+ image: imageUrl
115
  }, {
116
  headers: {
117
  'Authorization': `Bearer ${apiKey}`,
 
142
  }
143
  }
144
 
145
+ // Clean up temporary URLs after processing is done
146
+ temporaryUrlsRef.current.forEach(url => URL.revokeObjectURL(url));
147
+ temporaryUrlsRef.current = [];
148
+
149
  setProgress(100);
150
  setProcessing(false);
151
 
 
212
  };
213
 
214
  const removeImage = (id) => {
215
+ // Find the image to remove
216
+ const imageToRemove = uploadedImages.find(img => img.id === id);
217
+ if (imageToRemove && imageToRemove.preview) {
218
+ // Revoke the object URL to prevent memory leaks
219
+ URL.revokeObjectURL(imageToRemove.preview);
220
+ }
221
+
222
  setUploadedImages(prev => prev.filter(img => img.id !== id));
223
  };
224
 
225
  const clearAll = () => {
226
+ // Revoke all preview URLs to prevent memory leaks
227
+ uploadedImages.forEach(img => {
228
+ if (img.preview) URL.revokeObjectURL(img.preview);
229
+ });
230
+
231
  setUploadedImages([]);
232
  if (fileInputRef.current) fileInputRef.current.value = '';
233
  };
234
 
235
+ // Clean up URLs when component unmounts
236
+ React.useEffect(() => {
237
+ return () => {
238
+ // Clean up all preview URLs
239
+ uploadedImages.forEach(img => {
240
+ if (img.preview) URL.revokeObjectURL(img.preview);
241
+ });
242
+
243
+ // Clean up temporary URLs
244
+ temporaryUrlsRef.current.forEach(url => URL.revokeObjectURL(url));
245
+ };
246
+ }, []);
247
+
248
  const getStatusBadge = (status) => {
249
  switch (status) {
250
  case 'pending':