From dae20a8259b52444032aaac1549db871ed7d14c9 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Oct 2025 15:47:31 +0000 Subject: [PATCH 1/2] Enable auto-deploy for claude/google-nanobanano-image-tool branch MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлена ветка в автоматический деплой на GitHub Pages. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .github/workflows/deploy.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index ff6c8ca..b68cc1c 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -5,6 +5,7 @@ on: branches: - main - master + - claude/google-nanobanano-image-tool-011CULCaAxWF92Lzs45Tp9pm workflow_dispatch: permissions: From e47ae95535be5f0bf8a211921f2b476e79c5e5c4 Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 21 Oct 2025 16:49:59 +0000 Subject: [PATCH 2/2] Fix file upload button and add ZIP download for all images MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Исправления: 1. Исправлена кнопка "Выбрать файлы" - заменили button на span внутри label, теперь клик по тексту кнопки тоже открывает диалог выбора файлов 2. Добавлен JSZip для создания архивов 3. Кнопка "Сохранить все" теперь сохраняет все изображения в один ZIP файл вместо множественных отдельных загрузок Changes: - Replace button with span in ImageUploader label to fix click handling - Add jszip dependency to package.json - Modify saveAllImages to create and download ZIP archive with all processed images - ZIP filename includes timestamp: processed_images_{timestamp}.zip 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- package.json | 1 + src/components/ImageGallery.jsx | 30 ++++++++++++++++++++++++++---- src/components/ImageUploader.jsx | 4 ++-- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 7ee8d96..c275dc0 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ }, "dependencies": { "@google/generative-ai": "^0.21.0", + "jszip": "^3.10.1", "react": "^18.3.1", "react-dom": "^18.3.1" }, diff --git a/src/components/ImageGallery.jsx b/src/components/ImageGallery.jsx index 3c8d691..ca7c927 100644 --- a/src/components/ImageGallery.jsx +++ b/src/components/ImageGallery.jsx @@ -1,4 +1,5 @@ import { useState } from 'react'; +import JSZip from 'jszip'; export default function ImageGallery({ results, onRegenerate, onSaveAll, onRetryErrors }) { const [selectedImage, setSelectedImage] = useState(null); @@ -12,14 +13,35 @@ export default function ImageGallery({ results, onRegenerate, onSaveAll, onRetry document.body.removeChild(link); }; - const saveAllImages = () => { + const saveAllImages = async () => { + const zip = new JSZip(); + + // Добавляем все обработанные изображения в ZIP results.forEach((result, index) => { if (result.result) { - setTimeout(() => { - downloadImage(result.result, `processed_${result.originalName || `image_${index}`}`); - }, index * 100); + // Извлекаем base64 данные из data URL + const base64Data = result.result.split(',')[1]; + const filename = `processed_${result.originalName || `image_${index}.png`}`; + + // Добавляем файл в ZIP + zip.file(filename, base64Data, { base64: true }); } }); + + // Генерируем ZIP файл + const blob = await zip.generateAsync({ type: 'blob' }); + + // Создаем ссылку для скачивания + const link = document.createElement('a'); + link.href = URL.createObjectURL(blob); + link.download = `processed_images_${Date.now()}.zip`; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + + // Освобождаем память + URL.revokeObjectURL(link.href); + if (onSaveAll) onSaveAll(); }; diff --git a/src/components/ImageUploader.jsx b/src/components/ImageUploader.jsx index 6135734..c9ba46a 100644 --- a/src/components/ImageUploader.jsx +++ b/src/components/ImageUploader.jsx @@ -97,9 +97,9 @@ export default function ImageUploader({ onImagesLoad }) { Перетащите изображения сюда

или

- +