prithivMLmods commited on
Commit
653b784
·
verified ·
1 Parent(s): 01b57bd

update app

Browse files
Files changed (1) hide show
  1. Home.tsx +76 -58
Home.tsx CHANGED
@@ -1,9 +1,8 @@
1
  /**
2
  * @license
3
  * SPDX-License-Identifier: Apache-2.0
4
- */
5
  /* tslint:disable */
6
- import {GoogleGenAI, Modality} from '@google/genai';
7
  import {
8
  ChevronDown,
9
  Library,
@@ -19,25 +18,31 @@ import {
19
  } from 'lucide-react';
20
  import {useEffect, useRef, useState} from 'react';
21
 
22
- const ai = new GoogleGenAI({apiKey: process.env.API_KEY});
23
-
24
  function parseError(error: string) {
25
- const regex = /{"error":(.*)}/gm;
26
- const m = regex.exec(error);
27
  try {
28
- const e = m[1];
29
- const err = JSON.parse(e);
30
- return err.message || error;
31
  } catch (e) {
32
- return error;
 
 
 
 
 
 
 
 
 
33
  }
34
  }
35
 
36
  export default function Home() {
37
- const canvasRef = useRef(null);
38
- const fileInputRef = useRef(null);
39
- const backgroundImageRef = useRef(null);
40
- const dropdownRef = useRef(null);
41
  const [isDrawing, setIsDrawing] = useState(false);
42
  const [prompt, setPrompt] = useState('');
43
  const [generatedImage, setGeneratedImage] = useState<string | null>(null);
@@ -119,6 +124,7 @@ export default function Home() {
119
  // Initialize canvas with white background
120
  const initializeCanvas = () => {
121
  const canvas = canvasRef.current;
 
122
  const ctx = canvas.getContext('2d');
123
  ctx.fillStyle = '#FFFFFF';
124
  ctx.fillRect(0, 0, canvas.width, canvas.height);
@@ -182,8 +188,8 @@ export default function Home() {
182
  };
183
 
184
  // Get the correct coordinates based on canvas scaling
185
- const getCoordinates = (e) => {
186
- const canvas = canvasRef.current;
187
  const rect = canvas.getBoundingClientRect();
188
  const scaleX = canvas.width / rect.width;
189
  const scaleY = canvas.height / rect.height;
@@ -197,9 +203,9 @@ export default function Home() {
197
  };
198
  };
199
 
200
- const startDrawing = (e) => {
201
- const canvas = canvasRef.current;
202
- const ctx = canvas.getContext('2d');
203
  const {x, y} = getCoordinates(e);
204
  if (e.type === 'touchstart') {
205
  e.preventDefault();
@@ -209,13 +215,13 @@ export default function Home() {
209
  setIsDrawing(true);
210
  };
211
 
212
- const draw = (e) => {
213
  if (!isDrawing) return;
214
  if (e.type === 'touchmove') {
215
  e.preventDefault();
216
  }
217
- const canvas = canvasRef.current;
218
- const ctx = canvas.getContext('2d');
219
  const {x, y} = getCoordinates(e);
220
  ctx.lineWidth = 5;
221
  ctx.lineCap = 'round';
@@ -275,7 +281,6 @@ export default function Home() {
275
 
276
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
277
  processFiles(e.target.files);
278
- // Reset file input to allow uploading the same file again
279
  e.target.value = '';
280
  };
281
 
@@ -303,7 +308,8 @@ export default function Home() {
303
  );
304
  };
305
 
306
- const handleSubmit = async (e) => {
 
307
  e.preventDefault();
308
  setIsLoading(true);
309
 
@@ -322,30 +328,22 @@ export default function Home() {
322
 
323
  const parts: any[] = [];
324
 
 
325
  if (mode === 'imageGen') {
326
  const tempCanvas = document.createElement('canvas');
327
  tempCanvas.width = 960;
328
  tempCanvas.height = 540;
329
- const tempCtx = tempCanvas.getContext('2d');
330
- // Fill with white
331
  tempCtx.fillStyle = '#FFFFFF';
332
  tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
333
- // Add a tiny, almost invisible pixel to encourage editing behavior
334
- tempCtx.fillStyle = '#FEFEFE'; // A slightly off-white color
335
- tempCtx.fillRect(0, 0, 1, 1); // At the top-left corner
336
  const imageB64 = tempCanvas.toDataURL('image/png').split(',')[1];
337
  parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
338
  } else if (mode === 'canvas') {
339
  if (!canvasRef.current) return;
340
  const canvas = canvasRef.current;
341
- const tempCanvas = document.createElement('canvas');
342
- tempCanvas.width = canvas.width;
343
- tempCanvas.height = canvas.height;
344
- const tempCtx = tempCanvas.getContext('2d');
345
- tempCtx.fillStyle = '#FFFFFF';
346
- tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
347
- tempCtx.drawImage(canvas, 0, 0);
348
- const imageB64 = tempCanvas.toDataURL('image/png').split(',')[1];
349
  parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
350
  } else if (mode === 'editor' && generatedImage) {
351
  const mimeType = generatedImage.substring(
@@ -364,30 +362,50 @@ export default function Home() {
364
 
365
  parts.push({text: prompt});
366
 
367
- const response = await ai.models.generateContent({
368
- model: 'gemini-2.5-flash-image-preview',
369
- contents: { parts },
370
- config: {
371
- responseModalities: [Modality.TEXT, Modality.IMAGE],
 
 
 
 
 
 
 
 
 
372
  },
 
373
  });
374
 
375
- const data = {
376
- success: true,
377
- message: '',
378
- imageData: null,
379
- error: undefined,
380
- };
381
- for (const part of response.candidates[0].content.parts) {
382
- if (part.text) {
383
- data.message = part.text;
384
- } else if (part.inlineData) {
385
- data.imageData = part.inlineData.data;
 
 
 
 
 
 
 
 
386
  }
 
 
387
  }
388
 
389
- if (data.imageData) {
390
- const imageUrl = `data:image/png;base64,${data.imageData}`;
391
  if (mode === 'multi-img-edit') {
392
  setGeneratedImage(imageUrl);
393
  setMultiImages([]);
@@ -397,11 +415,11 @@ export default function Home() {
397
  }
398
  } else {
399
  setErrorMessage(
400
- data.message || 'Failed to generate image. Please try again.',
401
  );
402
  setShowErrorModal(true);
403
  }
404
- } catch (error) {
405
  console.error('Error submitting:', error);
406
  setErrorMessage(error.message || 'An unexpected error occurred.');
407
  setShowErrorModal(true);
@@ -418,7 +436,7 @@ export default function Home() {
418
  const canvas = canvasRef.current;
419
  if (!canvas) return;
420
 
421
- const preventTouchDefault = (e) => {
422
  if (isDrawing) {
423
  e.preventDefault();
424
  }
 
1
  /**
2
  * @license
3
  * SPDX-License-Identifier: Apache-2.0
4
+ */
5
  /* tslint:disable */
 
6
  import {
7
  ChevronDown,
8
  Library,
 
18
  } from 'lucide-react';
19
  import {useEffect, useRef, useState} from 'react';
20
 
21
+ // This function remains useful for parsing potential error messages
 
22
  function parseError(error: string) {
 
 
23
  try {
24
+ // Attempt to parse the error as a JSON object which the proxy might send
25
+ const errObj = JSON.parse(error);
26
+ return errObj.message || error;
27
  } catch (e) {
28
+ // If it's not JSON, return the original error string
29
+ const regex = /{"error":(.*)}/gm;
30
+ const m = regex.exec(error);
31
+ try {
32
+ const e = m[1];
33
+ const err = JSON.parse(e);
34
+ return err.message || error;
35
+ } catch (e) {
36
+ return error;
37
+ }
38
  }
39
  }
40
 
41
  export default function Home() {
42
+ const canvasRef = useRef<HTMLCanvasElement>(null);
43
+ const fileInputRef = useRef<HTMLInputElement>(null);
44
+ const backgroundImageRef = useRef<HTMLImageElement | null>(null);
45
+ const dropdownRef = useRef<HTMLDivElement>(null);
46
  const [isDrawing, setIsDrawing] = useState(false);
47
  const [prompt, setPrompt] = useState('');
48
  const [generatedImage, setGeneratedImage] = useState<string | null>(null);
 
124
  // Initialize canvas with white background
125
  const initializeCanvas = () => {
126
  const canvas = canvasRef.current;
127
+ if (!canvas) return;
128
  const ctx = canvas.getContext('2d');
129
  ctx.fillStyle = '#FFFFFF';
130
  ctx.fillRect(0, 0, canvas.width, canvas.height);
 
188
  };
189
 
190
  // Get the correct coordinates based on canvas scaling
191
+ const getCoordinates = (e: any) => {
192
+ const canvas = canvasRef.current!;
193
  const rect = canvas.getBoundingClientRect();
194
  const scaleX = canvas.width / rect.width;
195
  const scaleY = canvas.height / rect.height;
 
203
  };
204
  };
205
 
206
+ const startDrawing = (e: any) => {
207
+ const canvas = canvasRef.current!;
208
+ const ctx = canvas.getContext('2d')!;
209
  const {x, y} = getCoordinates(e);
210
  if (e.type === 'touchstart') {
211
  e.preventDefault();
 
215
  setIsDrawing(true);
216
  };
217
 
218
+ const draw = (e: any) => {
219
  if (!isDrawing) return;
220
  if (e.type === 'touchmove') {
221
  e.preventDefault();
222
  }
223
+ const canvas = canvasRef.current!;
224
+ const ctx = canvas.getContext('2d')!;
225
  const {x, y} = getCoordinates(e);
226
  ctx.lineWidth = 5;
227
  ctx.lineCap = 'round';
 
281
 
282
  const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
283
  processFiles(e.target.files);
 
284
  e.target.value = '';
285
  };
286
 
 
308
  );
309
  };
310
 
311
+ // *** MODIFIED FUNCTION ***
312
+ const handleSubmit = async (e: React.FormEvent) => {
313
  e.preventDefault();
314
  setIsLoading(true);
315
 
 
328
 
329
  const parts: any[] = [];
330
 
331
+ // This logic for building the 'parts' array is correct.
332
  if (mode === 'imageGen') {
333
  const tempCanvas = document.createElement('canvas');
334
  tempCanvas.width = 960;
335
  tempCanvas.height = 540;
336
+ const tempCtx = tempCanvas.getContext('2d')!;
 
337
  tempCtx.fillStyle = '#FFFFFF';
338
  tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
339
+ tempCtx.fillStyle = '#FEFEFE';
340
+ tempCtx.fillRect(0, 0, 1, 1);
 
341
  const imageB64 = tempCanvas.toDataURL('image/png').split(',')[1];
342
  parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
343
  } else if (mode === 'canvas') {
344
  if (!canvasRef.current) return;
345
  const canvas = canvasRef.current;
346
+ const imageB64 = canvas.toDataURL('image/png').split(',')[1];
 
 
 
 
 
 
 
347
  parts.push({inlineData: {data: imageB64, mimeType: 'image/png'}});
348
  } else if (mode === 'editor' && generatedImage) {
349
  const mimeType = generatedImage.substring(
 
362
 
363
  parts.push({text: prompt});
364
 
365
+ // Construct the request body for the Gemini REST API
366
+ const requestBody = {
367
+ contents: [{role: 'USER', parts}],
368
+ };
369
+
370
+ // Define the proxy endpoint
371
+ const proxyUrl =
372
+ '/api-proxy/v1beta/models/gemini-2.5-flash-image-preview:generateContent';
373
+
374
+ // Use fetch to send the request to your proxy server
375
+ const response = await fetch(proxyUrl, {
376
+ method: 'POST',
377
+ headers: {
378
+ 'Content-Type': 'application/json',
379
  },
380
+ body: JSON.stringify(requestBody),
381
  });
382
 
383
+ if (!response.ok) {
384
+ const errorData = await response.json();
385
+ throw new Error(
386
+ errorData.error?.message || `HTTP error! status: ${response.status}`,
387
+ );
388
+ }
389
+
390
+ const responseData = await response.json();
391
+
392
+ // Process the response
393
+ const result = {message: '', imageData: null};
394
+
395
+ if (responseData.candidates && responseData.candidates.length > 0) {
396
+ for (const part of responseData.candidates[0].content.parts) {
397
+ if (part.text) {
398
+ result.message = part.text;
399
+ } else if (part.inlineData) {
400
+ result.imageData = part.inlineData.data;
401
+ }
402
  }
403
+ } else {
404
+ throw new Error('Invalid response structure from API.');
405
  }
406
 
407
+ if (result.imageData) {
408
+ const imageUrl = `data:image/png;base64,${result.imageData}`;
409
  if (mode === 'multi-img-edit') {
410
  setGeneratedImage(imageUrl);
411
  setMultiImages([]);
 
415
  }
416
  } else {
417
  setErrorMessage(
418
+ result.message || 'Failed to generate image. Please try again.',
419
  );
420
  setShowErrorModal(true);
421
  }
422
+ } catch (error: any) {
423
  console.error('Error submitting:', error);
424
  setErrorMessage(error.message || 'An unexpected error occurred.');
425
  setShowErrorModal(true);
 
436
  const canvas = canvasRef.current;
437
  if (!canvas) return;
438
 
439
+ const preventTouchDefault = (e: TouchEvent) => {
440
  if (isDrawing) {
441
  e.preventDefault();
442
  }