import { useState, useEffect, useRef } from 'react'; import { Music, ChevronLeft, ChevronRight, Play, Pause, Volume2, VolumeX } from 'lucide-react'; export default function Home() { const [currentSlide, setCurrentSlide] = useState(0); const [isPlaying, setIsPlaying] = useState(false); const [isAnimating, setIsAnimating] = useState(false); const [isSpeaking, setIsSpeaking] = useState(false); const [currentWordIndex, setCurrentWordIndex] = useState(-1); const speechSynthRef = useRef(null); const isInitialRender = useRef(true); // Store text content as words for highlighting const [contentWords, setContentWords] = useState([]); const slides = [ { title: "The History of Jazz", subtitle: "America's Original Art Form", content: "An interactive journey through the evolution of jazz music from its roots to modern interpretations.", color: "bg-indigo-900", textColor: "text-yellow-300" }, { title: "Origins: 1890s - 1910s", subtitle: "New Orleans & Ragtime", content: "Jazz emerged from a blend of African rhythms, European harmony, and blues expressions in New Orleans. Ragtime, developed by composers like Scott Joplin, laid essential groundwork with its syncopated rhythms.", color: "bg-amber-900", textColor: "text-amber-200" }, { title: "The Jazz Age: 1920s", subtitle: "The Birth of Swing", content: "The 1920s saw jazz spread nationwide. Louis Armstrong revolutionized the art with his virtuosic trumpet playing and scat singing. Big bands began to form, setting the stage for the Swing Era.", color: "bg-red-900", textColor: "text-red-100" }, { title: "Swing Era: 1930s - 1940s", subtitle: "The Golden Age of Big Bands", content: "Duke Ellington, Count Basie, and Benny Goodman led popular big bands during this era. Swing became America's popular music, with danceable rhythms and sophisticated arrangements.", color: "bg-purple-900", textColor: "text-purple-100" }, { title: "Bebop Revolution: 1940s", subtitle: "The Birth of Modern Jazz", content: "Charlie Parker, Dizzy Gillespie, and Thelonious Monk pioneered bebop, featuring complex harmonies, breakneck tempos, and virtuosic improvisation that transformed jazz from dance music to art form.", color: "bg-blue-900", textColor: "text-blue-100" }, { title: "Cool & Hard Bop: 1950s", subtitle: "Multiple Directions", content: "Miles Davis introduced 'cool jazz' with a more relaxed, measured approach. Meanwhile, Art Blakey and Horace Silver developed hard bop, combining bebop's complexity with elements of gospel and blues.", color: "bg-teal-900", textColor: "text-teal-100" }, { title: "Free Jazz & Fusion: 1960s - 1970s", subtitle: "Breaking Boundaries", content: "Ornette Coleman and John Coltrane pushed jazz into avant-garde territory with free improvisation. Miles Davis later pioneered fusion, incorporating rock and funk elements with albums like 'Bitches Brew'.", color: "bg-orange-900", textColor: "text-orange-100" }, { title: "Neo-Classical & Beyond: 1980s - Present", subtitle: "Tradition & Innovation", content: "Wynton Marsalis led a return to traditional jazz values, while artists like Kamasi Washington, Robert Glasper, and Esperanza Spalding continue to expand jazz's boundaries by incorporating hip-hop, R&B, and global influences.", color: "bg-green-900", textColor: "text-green-100" } ]; // Initialize speech synthesis useEffect(() => { if (typeof window !== 'undefined' && window.speechSynthesis) { speechSynthRef.current = window.speechSynthesis; } return () => { if (speechSynthRef.current) { speechSynthRef.current.cancel(); } }; }, []); // Prepare text content for highlighting useEffect(() => { const words = slides[currentSlide].content.split(' '); setContentWords(words); setCurrentWordIndex(-1); // Reset word index when slide changes }, [currentSlide]); // Auto-advance slides when playing useEffect(() => { let interval; if (isPlaying && !isSpeaking) { interval = setInterval(() => { setCurrentSlide((prev) => (prev === slides.length - 1 ? 0 : prev + 1)); }, 5000); } return () => clearInterval(interval); }, [isPlaying, isSpeaking, slides.length]); // Handle animation when slide changes useEffect(() => { setIsAnimating(true); const timer = setTimeout(() => { setIsAnimating(false); }, 800); return () => clearTimeout(timer); }, [currentSlide]); // Automatically start speaking when slide changes useEffect(() => { // Skip auto-speech on initial render if (isInitialRender.current) { isInitialRender.current = false; return; } // Wait for animation to complete before speaking const timer = setTimeout(() => { if (!isAnimating) { speakText(); } }, 800); return () => clearTimeout(timer); }, [currentSlide, isAnimating]); const speakText = () => { if (!speechSynthRef.current) return; // Cancel any ongoing speech speechSynthRef.current.cancel(); const utterance = new SpeechSynthesisUtterance(slides[currentSlide].content); utterance.rate = 0.9; // Slightly slower for clarity utterance.pitch = 1; // Handle word boundaries for highlighting utterance.onboundary = (event) => { if (event.name === 'word') { // Calculate which word we're on const text = slides[currentSlide].content; const upToIndex = event.charIndex; const words = text.substring(0, upToIndex).split(' ').length - 1; setCurrentWordIndex(words); } }; utterance.onstart = () => { setIsSpeaking(true); }; utterance.onend = () => { setIsSpeaking(false); setCurrentWordIndex(-1); // Automatically advance to next slide if in playing mode if (isPlaying && !isAnimating) { const timer = setTimeout(() => { setCurrentSlide((prev) => (prev === slides.length - 1 ? 0 : prev + 1)); }, 1000); // Wait 1 second after speech ends before advancing return () => clearTimeout(timer); } }; speechSynthRef.current.speak(utterance); }; const stopSpeaking = () => { if (speechSynthRef.current) { speechSynthRef.current.cancel(); setIsSpeaking(false); setCurrentWordIndex(-1); } }; const nextSlide = () => { if (!isAnimating) { stopSpeaking(); setCurrentSlide((prev) => (prev === slides.length - 1 ? 0 : prev + 1)); } }; const prevSlide = () => { if (!isAnimating) { stopSpeaking(); setCurrentSlide((prev) => (prev === 0 ? slides.length - 1 : prev - 1)); } }; const goToSlide = (index) => { if (!isAnimating && currentSlide !== index) { stopSpeaking(); setCurrentSlide(index); } }; // Toggle play mode const togglePlay = () => { if (isPlaying) { // If playing, stop everything setIsPlaying(false); stopSpeaking(); } else { // If not playing, start playing and speak current slide setIsPlaying(true); speakText(); } }; // Render words with highlighting for current word const renderHighlightedContent = () => { return contentWords.map((word, index) => ( {word}{' '} )); }; return (