| import { useState, useRef, useEffect } from 'react'; |
|
|
| const useThoughtGeneration = (canvasRef, isMouthOpen, customPrompt) => { |
| const [thought, setThought] = useState(''); |
| const [isThinking, setIsThinking] = useState(false); |
| const [animateThinking, setAnimateThinking] = useState(false); |
| const lastGenerationTime = useRef(0); |
| const isComponentMounted = useRef(true); |
| |
| |
| useEffect(() => { |
| isComponentMounted.current = true; |
| return () => { |
| isComponentMounted.current = false; |
| }; |
| }, []); |
| |
| |
| useEffect(() => { |
| if (isMouthOpen) { |
| |
| |
| const now = Date.now(); |
| if (!isThinking && now - lastGenerationTime.current > 1000) { |
| generateThought(); |
| lastGenerationTime.current = now; |
| } |
| } |
| }, [isMouthOpen]); |
| |
| |
| useEffect(() => { |
| if (isThinking) { |
| setAnimateThinking(true); |
| |
| |
| const timer = setTimeout(() => { |
| if (isComponentMounted.current) { |
| setAnimateThinking(false); |
| } |
| }, 1200); |
| return () => clearTimeout(timer); |
| } |
| }, [isThinking]); |
| |
| |
| const generateThought = async () => { |
| if (isThinking || !isComponentMounted.current) return; |
| |
| setIsThinking(true); |
| console.log("Generating thought..."); |
| |
| try { |
| |
| const canvas = canvasRef.current; |
| if (!canvas) return; |
| |
| const imageData = canvas.toDataURL('image/jpeg', 0.8); |
| |
| |
| const response = await fetch('/api/gemini', { |
| method: 'POST', |
| headers: { |
| 'Content-Type': 'application/json', |
| }, |
| body: JSON.stringify({ |
| image: imageData, |
| prompt: customPrompt |
| }), |
| }); |
| |
| if (!isComponentMounted.current) return; |
| |
| if (!response.ok) { |
| throw new Error('Failed to generate thought'); |
| } |
| |
| const data = await response.json(); |
| |
| if (!isComponentMounted.current) return; |
| |
| setThought(data.thought); |
| console.log("Thought generated:", data.thought); |
| } catch (error) { |
| console.error('Error generating thought:', error); |
| if (isComponentMounted.current) { |
| setThought('Hmm, I lost my train of thought...'); |
| } |
| } finally { |
| if (isComponentMounted.current) { |
| setIsThinking(false); |
| } |
| } |
| }; |
| |
| return { |
| thought, |
| isThinking, |
| animateThinking, |
| generateThought |
| }; |
| }; |
|
|
| export default useThoughtGeneration; |