import React, { useState, useRef } from 'react'; import { Article, VoiceName } from '../types'; import { Sparkles, Play, Pause, Loader2, Clock, Brain } from 'lucide-react'; import { generateSpeechFromText } from '../services/geminiService'; import { base64ToUint8Array, createWavBlob } from '../services/audioUtils'; interface SummaryCardProps { article: Article; selectedVoice: VoiceName; onPlayFull: () => void; } export const SummaryCard: React.FC = ({ article, selectedVoice, onPlayFull }) => { const [isPlayingSummary, setIsPlayingSummary] = useState(false); const [isLoadingAudio, setIsLoadingAudio] = useState(false); const audioRef = useRef(null); const handlePlaySummary = async () => { if (!article.summary) return; if (isPlayingSummary && audioRef.current) { audioRef.current.pause(); setIsPlayingSummary(false); return; } // If we already have the audio URL cached if (article.summaryAudioUrl && audioRef.current) { audioRef.current.src = article.summaryAudioUrl; await audioRef.current.play(); setIsPlayingSummary(true); return; } // Generate audio setIsLoadingAudio(true); try { const base64Audio = await generateSpeechFromText(article.summary, selectedVoice); const pcmData = base64ToUint8Array(base64Audio); const wavBlob = createWavBlob(pcmData); const audioUrl = URL.createObjectURL(wavBlob); if (!audioRef.current) { audioRef.current = new Audio(); } audioRef.current.src = audioUrl; audioRef.current.onended = () => setIsPlayingSummary(false); await audioRef.current.play(); setIsPlayingSummary(true); } catch (e) { console.error('Failed to play summary:', e); } finally { setIsLoadingAudio(false); } }; if (!article.summary && !article.isSummaryLoading) { return null; } const complexityColors = { simple: 'text-green-500 bg-green-50 dark:bg-green-900/30', moderate: 'text-yellow-500 bg-yellow-50 dark:bg-yellow-900/30', complex: 'text-red-500 bg-red-50 dark:bg-red-900/30' }; return (
30-Second Summary
{article.complexity && ( {article.complexity} )} {article.estimatedReadTime && ( {article.estimatedReadTime}m read )}
{article.isSummaryLoading ? (
Generating summary...
) : ( <>

{article.summary}

)}
); };