Spaces:
Running
Running
api recycling with refresh timeouts (#4)
Browse files- api recycling with refresh timeouts (484d16141fb459f21a28d2b2d8c3800e59d2fa87)
Home.tsx
CHANGED
|
@@ -56,6 +56,8 @@ export default function Home() {
|
|
| 56 |
'canvas' | 'editor' | 'imageGen' | 'multi-img-edit'
|
| 57 |
>('editor');
|
| 58 |
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
|
|
|
|
|
|
| 59 |
|
| 60 |
// State for canvas history
|
| 61 |
const [history, setHistory] = useState<string[]>([]);
|
|
@@ -256,6 +258,10 @@ export default function Home() {
|
|
| 256 |
);
|
| 257 |
if (fileArray.length === 0) return;
|
| 258 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 259 |
if (mode === 'multi-img-edit') {
|
| 260 |
const readers = fileArray.map((file) => {
|
| 261 |
return new Promise<{url: string; type: string}>((resolve, reject) => {
|
|
@@ -311,6 +317,12 @@ export default function Home() {
|
|
| 311 |
// *** MODIFIED FUNCTION ***
|
| 312 |
const handleSubmit = async (e: React.FormEvent) => {
|
| 313 |
e.preventDefault();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 314 |
setIsLoading(true);
|
| 315 |
|
| 316 |
try {
|
|
@@ -368,8 +380,7 @@ export default function Home() {
|
|
| 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, {
|
|
@@ -432,6 +443,15 @@ export default function Home() {
|
|
| 432 |
setShowErrorModal(false);
|
| 433 |
};
|
| 434 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 435 |
useEffect(() => {
|
| 436 |
const canvas = canvasRef.current;
|
| 437 |
if (!canvas) return;
|
|
@@ -777,6 +797,41 @@ export default function Home() {
|
|
| 777 |
</div>
|
| 778 |
</div>
|
| 779 |
)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 780 |
</div>
|
| 781 |
</>
|
| 782 |
);
|
|
|
|
| 56 |
'canvas' | 'editor' | 'imageGen' | 'multi-img-edit'
|
| 57 |
>('editor');
|
| 58 |
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
| 59 |
+
const [apiKey, setApiKey] = useState('');
|
| 60 |
+
const [showApiKeyModal, setShowApiKeyModal] = useState(false);
|
| 61 |
|
| 62 |
// State for canvas history
|
| 63 |
const [history, setHistory] = useState<string[]>([]);
|
|
|
|
| 258 |
);
|
| 259 |
if (fileArray.length === 0) return;
|
| 260 |
|
| 261 |
+
if (!apiKey) {
|
| 262 |
+
setShowApiKeyModal(true);
|
| 263 |
+
}
|
| 264 |
+
|
| 265 |
if (mode === 'multi-img-edit') {
|
| 266 |
const readers = fileArray.map((file) => {
|
| 267 |
return new Promise<{url: string; type: string}>((resolve, reject) => {
|
|
|
|
| 317 |
// *** MODIFIED FUNCTION ***
|
| 318 |
const handleSubmit = async (e: React.FormEvent) => {
|
| 319 |
e.preventDefault();
|
| 320 |
+
|
| 321 |
+
if (!apiKey) {
|
| 322 |
+
setShowApiKeyModal(true);
|
| 323 |
+
return;
|
| 324 |
+
}
|
| 325 |
+
|
| 326 |
setIsLoading(true);
|
| 327 |
|
| 328 |
try {
|
|
|
|
| 380 |
};
|
| 381 |
|
| 382 |
// Define the proxy endpoint
|
| 383 |
+
const proxyUrl = `/api-proxy/v1beta/models/gemini-2.5-flash-image-preview:generateContent?key=${apiKey}`;
|
|
|
|
| 384 |
|
| 385 |
// Use fetch to send the request to your proxy server
|
| 386 |
const response = await fetch(proxyUrl, {
|
|
|
|
| 443 |
setShowErrorModal(false);
|
| 444 |
};
|
| 445 |
|
| 446 |
+
const handleApiKeySubmit = (e: React.FormEvent) => {
|
| 447 |
+
e.preventDefault();
|
| 448 |
+
const newApiKey = (e.target as any).apiKey.value;
|
| 449 |
+
if (newApiKey) {
|
| 450 |
+
setApiKey(newApiKey);
|
| 451 |
+
setShowApiKeyModal(false);
|
| 452 |
+
}
|
| 453 |
+
};
|
| 454 |
+
|
| 455 |
useEffect(() => {
|
| 456 |
const canvas = canvasRef.current;
|
| 457 |
if (!canvas) return;
|
|
|
|
| 797 |
</div>
|
| 798 |
</div>
|
| 799 |
)}
|
| 800 |
+
{/* API Key Modal */}
|
| 801 |
+
{showApiKeyModal && (
|
| 802 |
+
<div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
|
| 803 |
+
<div className="bg-white rounded-lg shadow-xl max-w-md w-full p-6">
|
| 804 |
+
<div className="flex justify-between items-start mb-4">
|
| 805 |
+
<h3 className="text-xl font-bold text-gray-700">
|
| 806 |
+
Add Gemini API Key
|
| 807 |
+
</h3>
|
| 808 |
+
<button
|
| 809 |
+
onClick={() => setShowApiKeyModal(false)}
|
| 810 |
+
className="text-gray-400 hover:text-gray-500">
|
| 811 |
+
<X className="w-5 h-5" />
|
| 812 |
+
</button>
|
| 813 |
+
</div>
|
| 814 |
+
<p className="text-gray-600 mb-4">
|
| 815 |
+
Add the API key to process the request. The API key will be
|
| 816 |
+
removed if the app page is refreshed or closed.
|
| 817 |
+
</p>
|
| 818 |
+
<form onSubmit={handleApiKeySubmit}>
|
| 819 |
+
<input
|
| 820 |
+
type="password"
|
| 821 |
+
name="apiKey"
|
| 822 |
+
className="w-full p-2 border-2 border-gray-300 rounded-md mb-4"
|
| 823 |
+
placeholder="Enter your Gemini API Key"
|
| 824 |
+
required
|
| 825 |
+
/>
|
| 826 |
+
<button
|
| 827 |
+
type="submit"
|
| 828 |
+
className="w-full bg-black text-white p-2 rounded-md hover:bg-gray-800 transition-colors">
|
| 829 |
+
Submit
|
| 830 |
+
</button>
|
| 831 |
+
</form>
|
| 832 |
+
</div>
|
| 833 |
+
</div>
|
| 834 |
+
)}
|
| 835 |
</div>
|
| 836 |
</>
|
| 837 |
);
|