diff --git a/k-pop-thumbnail-genie/.gitignore b/k-pop-thumbnail-genie/.gitignore deleted file mode 100644 index a547bf36..00000000 --- a/k-pop-thumbnail-genie/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# Logs -logs -*.log -npm-debug.log* -yarn-debug.log* -yarn-error.log* -pnpm-debug.log* -lerna-debug.log* - -node_modules -dist -dist-ssr -*.local - -# Editor directories and files -.vscode/* -!.vscode/extensions.json -.idea -.DS_Store -*.suo -*.ntvs* -*.njsproj -*.sln -*.sw? diff --git a/k-pop-thumbnail-genie/36c59e60-6f2a-42ae-afa7-7efca47a5217.jpg b/k-pop-thumbnail-genie/36c59e60-6f2a-42ae-afa7-7efca47a5217.jpg deleted file mode 100644 index 0b05ff09..00000000 Binary files a/k-pop-thumbnail-genie/36c59e60-6f2a-42ae-afa7-7efca47a5217.jpg and /dev/null differ diff --git a/k-pop-thumbnail-genie/5932a7dc-c879-4b7e-8b4b-0d12b270b6fa.jpg b/k-pop-thumbnail-genie/5932a7dc-c879-4b7e-8b4b-0d12b270b6fa.jpg deleted file mode 100644 index f89dc962..00000000 Binary files a/k-pop-thumbnail-genie/5932a7dc-c879-4b7e-8b4b-0d12b270b6fa.jpg and /dev/null differ diff --git a/k-pop-thumbnail-genie/61d6edb8-9faa-43a6-aa7b-ca99f1d8cdab.jpg b/k-pop-thumbnail-genie/61d6edb8-9faa-43a6-aa7b-ca99f1d8cdab.jpg deleted file mode 100644 index 787b27cd..00000000 Binary files a/k-pop-thumbnail-genie/61d6edb8-9faa-43a6-aa7b-ca99f1d8cdab.jpg and /dev/null differ diff --git a/k-pop-thumbnail-genie/8deb484b-40bf-461e-80d0-33bb10893acb.jpg b/k-pop-thumbnail-genie/8deb484b-40bf-461e-80d0-33bb10893acb.jpg deleted file mode 100644 index 6161167c..00000000 Binary files a/k-pop-thumbnail-genie/8deb484b-40bf-461e-80d0-33bb10893acb.jpg and /dev/null differ diff --git a/k-pop-thumbnail-genie/App.tsx b/k-pop-thumbnail-genie/App.tsx deleted file mode 100644 index 96b1e564..00000000 --- a/k-pop-thumbnail-genie/App.tsx +++ /dev/null @@ -1,223 +0,0 @@ - -import React, { useState, useCallback } from 'react'; -import { UploadedImage, AppStep, GenerationResult } from './types'; -import { expandPrompt, generateImage, refineImage } from './services/geminiService'; -import ImageUploader from './components/ImageUploader'; -import ImageSegmenter from './components/ImageSegmenter'; -import PromptCustomizer from './components/PromptCustomizer'; -import ImageResult from './components/ImageResult'; -import StepIndicator from './components/StepIndicator'; -import { SparklesIcon } from './components/icons/SparklesIcon'; -import { applyMask } from './utils/canvasUtils'; -import { LoggingProvider, useLogger } from './contexts/LoggingContext'; -import DebugConsole from './components/DebugConsole'; - -const AppContent: React.FC = () => { - const [step, setStep] = useState(AppStep.Upload); - const [uploadedImages, setUploadedImages] = useState([]); - const [masterPrompt, setMasterPrompt] = useState(''); - const [generationResult, setGenerationResult] = useState(null); - const [isLoading, setIsLoading] = useState(false); - const [loadingMessage, setLoadingMessage] = useState(''); - const [error, setError] = useState(null); - const { log } = useLogger(); - - const handleImagesUploaded = (images: UploadedImage[]) => { - log('info', `${images.length} images uploaded. Moving to segmentation step.`); - setUploadedImages(images); - setStep(AppStep.Segment); - setError(null); - }; - - const handleSegmentationComplete = (imagesWithMasks: UploadedImage[]) => { - log('success', `Segmentation complete for all ${imagesWithMasks.length} images. Moving to prompt step.`); - setUploadedImages(imagesWithMasks); - setStep(AppStep.Prompt); - setError(null); - }; - - const handlePromptExpanded = useCallback(async (scenario: string, userInstruction: string) => { - setIsLoading(true); - setLoadingMessage('Expanding your idea into a master prompt...'); - setError(null); - log('info', `Expanding prompt with scenario: "${scenario}"`); - try { - const prompt = await expandPrompt(scenario, userInstruction, uploadedImages); - setMasterPrompt(prompt); - log('success', 'Master prompt created successfully.'); - } catch (e) { - const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during prompt expansion.'; - log('error', `Prompt expansion failed: ${errorMessage}`); - setError(errorMessage); - } finally { - setIsLoading(false); - setLoadingMessage(''); - } - }, [uploadedImages, log]); - - const handleFinalGeneration = useCallback(async (finalPrompt: string) => { - setIsLoading(true); - setLoadingMessage('Generating your K-Pop thumbnail...'); - setError(null); - log('info', 'Starting final image generation.'); - try { - log('info', 'Applying masks to create segmented images...'); - const segmentedImages = await Promise.all( - uploadedImages.map(async (image) => { - if (!image.maskDataUrl) { - throw new Error(`Mask is missing for image: ${image.file.name}`); - } - const segmentedData = await applyMask(image.previewUrl, image.maskDataUrl); - return { ...image, segmentedDataUrl: `data:image/png;base64,${segmentedData}` }; - }) - ); - log('success', 'Masks applied successfully.'); - - const result = await generateImage(finalPrompt, segmentedImages); - setGenerationResult({ - baseImage: result, - currentImage: result, - history: [result], - }); - setStep(AppStep.Result); - log('success', 'Thumbnail generated successfully.'); - } catch (e) { - const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during image generation.'; - log('error', `Final image generation failed: ${errorMessage}`); - setError(errorMessage); - setStep(AppStep.Prompt); - } finally { - setIsLoading(false); - setLoadingMessage(''); - } - }, [uploadedImages, log]); - - const handleImageRefinement = useCallback(async (refinementPrompt: string) => { - if (!generationResult) return; - setIsLoading(true); - setLoadingMessage('Applying your refinements...'); - setError(null); - log('info', `Refining image with prompt: "${refinementPrompt}"`); - try { - const newImage = await refineImage(refinementPrompt, generationResult.currentImage); - setGenerationResult(prev => { - if (!prev) return null; - const newHistory = [...prev.history, newImage]; - return { - baseImage: prev.baseImage, - currentImage: newImage, - history: newHistory, - }; - }); - log('success', 'Image refined successfully.'); - } catch (e) { - const errorMessage = e instanceof Error ? e.message : 'An unknown error occurred during image refinement.'; - log('error', `Image refinement failed: ${errorMessage}`); - setError(errorMessage); - } finally { - setIsLoading(false); - setLoadingMessage(''); - } - }, [generationResult, log]); - - const handleBack = () => { - setError(null); - if (step === AppStep.Result) { - log('info', 'Navigating back from Result to Prompt step.'); - setMasterPrompt(''); - setStep(AppStep.Prompt); - } else if (step === AppStep.Prompt) { - log('info', 'Navigating back from Prompt to Segment step.'); - setMasterPrompt(''); - setStep(AppStep.Segment); - } else if (step === AppStep.Segment) { - log('info', 'Navigating back from Segment to Upload step.'); - setStep(AppStep.Upload); - } - }; - - const handleStartOver = () => { - log('info', 'Starting over. Resetting application state.'); - setStep(AppStep.Upload); - setUploadedImages([]); - setMasterPrompt(''); - setGenerationResult(null); - setIsLoading(false); - setLoadingMessage(''); - setError(null); - } - - const renderStep = () => { - switch (step) { - case AppStep.Upload: - return ; - case AppStep.Segment: - return ; - case AppStep.Prompt: - return ; - case AppStep.Result: - return ; - default: - return ; - } - }; - - return ( -
-
-
- -

- K-Pop Thumbnail Genie -

-
-

Create stunning, emotional YouTube thumbnails with the magic of AI

-
- -
- -
- {error && ( -
-

Error: {error}

-
- )} - {renderStep()} -
-
-
-

Powered by Google Gemini. Designed for K-Pop content creators.

-
- -
- ); -}; - - -const App: React.FC = () => ( - - - -); - -export default App; diff --git a/k-pop-thumbnail-genie/README.md b/k-pop-thumbnail-genie/README.md deleted file mode 100644 index 1f6c4388..00000000 --- a/k-pop-thumbnail-genie/README.md +++ /dev/null @@ -1,20 +0,0 @@ -
-GHBanner -
- -# Run and deploy your AI Studio app - -This contains everything you need to run your app locally. - -View your app in AI Studio: https://ai.studio/apps/drive/18Jqma41iTUAZu0UduZKdv9IMtoJJI3KW - -## Run Locally - -**Prerequisites:** Node.js - - -1. Install dependencies: - `npm install` -2. Set the `GEMINI_API_KEY` in [.env.local](.env.local) to your Gemini API key -3. Run the app: - `npm run dev` diff --git a/k-pop-thumbnail-genie/a369b71a-3c87-431d-b043-9d6a66600b2d.jpg b/k-pop-thumbnail-genie/a369b71a-3c87-431d-b043-9d6a66600b2d.jpg deleted file mode 100644 index 4ea349f9..00000000 Binary files a/k-pop-thumbnail-genie/a369b71a-3c87-431d-b043-9d6a66600b2d.jpg and /dev/null differ diff --git a/k-pop-thumbnail-genie/components/DebugConsole.tsx b/k-pop-thumbnail-genie/components/DebugConsole.tsx deleted file mode 100644 index cb3eab12..00000000 --- a/k-pop-thumbnail-genie/components/DebugConsole.tsx +++ /dev/null @@ -1,79 +0,0 @@ - -import React, { useState, useEffect, useRef } from 'react'; -import { useLogger, LogMessage, LogType } from '../contexts/LoggingContext'; - -const LOG_COLORS: Record = { - info: 'text-gray-300', - success: 'text-green-400', - error: 'text-red-400', - warn: 'text-yellow-400', -}; - -const DebugConsole: React.FC = () => { - const { logs, clearLogs } = useLogger(); - const [isOpen, setIsOpen] = useState(false); - const [copyStatus, setCopyStatus] = useState('Copy'); - const logsEndRef = useRef(null); - - const scrollToBottom = () => { - logsEndRef.current?.scrollIntoView({ behavior: 'smooth' }); - }; - - useEffect(scrollToBottom, [logs]); - - const handleCopy = () => { - const logText = logs.map(log => `[${log.timestamp}] [${log.type.toUpperCase()}] ${log.message}`).join('\n'); - navigator.clipboard.writeText(logText).then(() => { - setCopyStatus('Copied!'); - setTimeout(() => setCopyStatus('Copy'), 2000); - }, () => { - setCopyStatus('Failed!'); - setTimeout(() => setCopyStatus('Copy'), 2000); - }); - }; - - return ( - <> - - - {isOpen && ( -
-
-

DEBUG CONSOLE

-
- - - -
-
-
- {logs.length === 0 ? ( -

No logs yet. Start using the app to see messages here.

- ) : ( - logs.map((log, index) => ( -
- {log.timestamp} - - [{log.type.toUpperCase()}] - {log.message} - -
- )) - )} -
-
-
- )} - - ); -}; - -export default DebugConsole; diff --git a/k-pop-thumbnail-genie/components/ImageResult.tsx b/k-pop-thumbnail-genie/components/ImageResult.tsx deleted file mode 100644 index 51a24e22..00000000 --- a/k-pop-thumbnail-genie/components/ImageResult.tsx +++ /dev/null @@ -1,103 +0,0 @@ - -import React, { useState } from 'react'; -import { GenerationResult } from '../types'; -import { DownloadIcon } from './icons/DownloadIcon'; -import { MagicIcon } from './icons/MagicIcon'; - -interface ImageResultProps { - result: GenerationResult | null; - onRefine: (refinementPrompt: string) => void; - masterPrompt: string; - isLoading: boolean; - loadingMessage: string; - onStartOver: () => void; -} - -const ImageResult: React.FC = ({ result, onRefine, masterPrompt, isLoading, loadingMessage, onStartOver }) => { - const [refinementPrompt, setRefinementPrompt] = useState(''); - - const handleRefineSubmit = (e: React.FormEvent) => { - e.preventDefault(); - if (refinementPrompt.trim()) { - onRefine(refinementPrompt); - setRefinementPrompt(''); - } - }; - - if (!result) { - return ( -
-

Something went wrong. No image was generated.

- -
- ); - } - - return ( -
-
-
- Generated thumbnail -
- {isLoading && ( -
-
-

{loadingMessage}

-
- )} -
- -
-

Your Masterpiece

- -
-
- -