← back to Dear Bubbe Nextjs

components/SimpleTTS.tsx

85 lines

'use client'

import { useEffect } from 'react'

interface SimpleTTSProps {
  text: string | null
  onEnd?: () => void
}

export default function SimpleTTS({ text, onEnd }: SimpleTTSProps) {
  useEffect(() => {
    if (!text || typeof window === 'undefined') return
    
    // Use browser's built-in speech synthesis
    if (!('speechSynthesis' in window)) {
      console.error('Speech synthesis not supported')
      return
    }
    
    console.log('🔊 SPEAKING:', text.substring(0, 50))
    
    // Cancel any ongoing speech
    window.speechSynthesis.cancel()
    
    // Create and configure utterance
    const utterance = new SpeechSynthesisUtterance(text)
    utterance.rate = 0.95 // Slightly slower
    utterance.pitch = 1.1 // Slightly higher for Bubbe
    utterance.volume = 1.0 // Full volume
    utterance.lang = 'en-US'
    
    // Get voices and try to use a female one
    const setVoice = () => {
      const voices = window.speechSynthesis.getVoices()
      if (voices.length > 0) {
        // Try to find a female voice
        const femaleVoice = voices.find(v => 
          v.name.toLowerCase().includes('female') ||
          v.name.toLowerCase().includes('samantha') ||
          v.name.toLowerCase().includes('victoria') ||
          v.name.toLowerCase().includes('karen')
        ) || voices.find(v => v.lang === 'en-US') || voices[0]
        
        if (femaleVoice) {
          utterance.voice = femaleVoice
          console.log('Using voice:', femaleVoice.name)
        }
      }
    }
    
    // Try to set voice immediately
    setVoice()
    
    // Also try when voices are loaded
    window.speechSynthesis.onvoiceschanged = setVoice
    
    // Event handlers
    utterance.onstart = () => {
      console.log('🎤 Speech started')
    }
    
    utterance.onend = () => {
      console.log('✅ Speech finished')
      if (onEnd) onEnd()
    }
    
    utterance.onerror = (event) => {
      console.error('❌ Speech error:', event.error)
      if (onEnd) onEnd()
    }
    
    // Small delay to ensure everything is ready
    setTimeout(() => {
      window.speechSynthesis.speak(utterance)
      console.log('🗣️ Bubbe is kvetching!')
    }, 100)
    
    // Cleanup
    return () => {
      window.speechSynthesis.cancel()
    }
  }, [text, onEnd])
  
  return null // This component doesn't render anything
}