|
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; |