mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-16 21:37:51 +00:00
feat: adicionando controles de texto
This commit is contained in:
parent
dd9e2f4dd3
commit
51b8fb4088
@ -1,5 +1,5 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { ArrowLeft, ArrowRight, Volume2, Share2, ChevronDown, ChevronUp, Loader2, Pause, Play, Download, RefreshCw, Trash2, TextSelect } from 'lucide-react';
|
||||
import { ArrowLeft, ArrowRight, Share2, ChevronDown, ChevronUp, Loader2, Download, RefreshCw, Trash2, Type } from 'lucide-react';
|
||||
import { useParams, useNavigate } from 'react-router-dom';
|
||||
import { supabase } from '../../lib/supabase';
|
||||
import { AudioRecorder } from '../../components/story/AudioRecorder';
|
||||
@ -9,7 +9,7 @@ import { convertWebmToMp3 } from '../../utils/audioConverter';
|
||||
import * as Dialog from '@radix-ui/react-dialog';
|
||||
import { ExerciseSuggestions } from '../../components/learning/ExerciseSuggestions';
|
||||
import { TextCaseToggle } from '../../components/ui/text-case-toggle';
|
||||
import { AdaptiveText, AdaptiveTitle, AdaptiveParagraph } from '../../components/ui/adaptive-text';
|
||||
import { AdaptiveText } from '../../components/ui/adaptive-text';
|
||||
import { useSession } from '../../hooks/useSession';
|
||||
import { useSyllables } from '../../features/syllables/hooks/useSyllables';
|
||||
import { useUppercasePreference } from '../../hooks/useUppercasePreference';
|
||||
@ -38,7 +38,6 @@ interface StoryRecording {
|
||||
|
||||
function RecordingHistoryCard({ recording }: { recording: StoryRecording }) {
|
||||
const [isExpanded, setIsExpanded] = React.useState(false);
|
||||
const [isPlaying, setIsPlaying] = React.useState(false);
|
||||
const [isAudioSupported, setIsAudioSupported] = React.useState(true);
|
||||
const audioRef = React.useRef<HTMLAudioElement | null>(null);
|
||||
const [isConverting, setIsConverting] = React.useState(false);
|
||||
@ -74,41 +73,33 @@ function RecordingHistoryCard({ recording }: { recording: StoryRecording }) {
|
||||
readyState: audioElement.readyState,
|
||||
src: audioElement.src
|
||||
});
|
||||
setIsPlaying(false);
|
||||
};
|
||||
|
||||
const handlePlayPause = async () => {
|
||||
if (audioRef.current) {
|
||||
try {
|
||||
if (isPlaying) {
|
||||
audioRef.current.pause();
|
||||
} else {
|
||||
if (audioRef.current.ended) {
|
||||
audioRef.current.currentTime = 0;
|
||||
}
|
||||
|
||||
// Verificar se o áudio está pronto
|
||||
if (audioRef.current.readyState === 0) {
|
||||
console.log('Recarregando áudio...');
|
||||
await audioRef.current.load();
|
||||
}
|
||||
|
||||
const playPromise = audioRef.current.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise
|
||||
.then(() => {
|
||||
console.log('Reprodução iniciada com sucesso');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao reproduzir áudio:', error);
|
||||
setIsPlaying(false);
|
||||
});
|
||||
}
|
||||
if (audioRef.current.ended) {
|
||||
audioRef.current.currentTime = 0;
|
||||
}
|
||||
|
||||
// Verificar se o áudio está pronto
|
||||
if (audioRef.current.readyState === 0) {
|
||||
console.log('Recarregando áudio...');
|
||||
await audioRef.current.load();
|
||||
}
|
||||
|
||||
const playPromise = audioRef.current.play();
|
||||
if (playPromise !== undefined) {
|
||||
playPromise
|
||||
.then(() => {
|
||||
console.log('Reprodução iniciada com sucesso');
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Erro ao reproduzir áudio:', error);
|
||||
});
|
||||
}
|
||||
setIsPlaying(!isPlaying);
|
||||
} catch (error) {
|
||||
console.error('Erro ao manipular áudio:', error);
|
||||
setIsPlaying(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -152,10 +143,11 @@ function RecordingHistoryCard({ recording }: { recording: StoryRecording }) {
|
||||
const audio = audioRef.current;
|
||||
|
||||
if (audio) {
|
||||
const handleEnded = () => setIsPlaying(false);
|
||||
const handleEnded = () => {
|
||||
console.log('Reprodução encerrada');
|
||||
};
|
||||
const handleError = (e: ErrorEvent) => {
|
||||
console.error('Erro no áudio:', e);
|
||||
setIsPlaying(false);
|
||||
};
|
||||
|
||||
audio.addEventListener('ended', handleEnded);
|
||||
@ -238,17 +230,7 @@ function RecordingHistoryCard({ recording }: { recording: StoryRecording }) {
|
||||
disabled={!recording.audio_url && !mp3Url}
|
||||
className="flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition disabled:opacity-50 disabled:cursor-not-allowed"
|
||||
>
|
||||
{isPlaying ? (
|
||||
<>
|
||||
<Pause className="h-5 w-5" />
|
||||
Pausar
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<Play className="h-5 w-5" />
|
||||
{recording.audio_url || mp3Url ? 'Ouvir' : 'Carregando...'}
|
||||
</>
|
||||
)}
|
||||
{recording.audio_url || mp3Url ? 'Ouvir' : 'Carregando...'}
|
||||
</button>
|
||||
)}
|
||||
|
||||
@ -394,7 +376,6 @@ export function StoryPage() {
|
||||
const [currentPage, setCurrentPage] = React.useState(0);
|
||||
const [loading, setLoading] = React.useState(true);
|
||||
const [error, setError] = React.useState<string | null>(null);
|
||||
const [isPlaying, setIsPlaying] = React.useState(false);
|
||||
const [recordings, setRecordings] = React.useState<StoryRecording[]>([]);
|
||||
const [loadingRecordings, setLoadingRecordings] = React.useState(true);
|
||||
const [showDeleteModal, setShowDeleteModal] = useState(false);
|
||||
@ -706,7 +687,7 @@ export function StoryPage() {
|
||||
onClick={toggleSyllables}
|
||||
className="flex items-center gap-2 px-3 py-1.5 rounded-lg transition-colors text-gray-600 hover:text-gray-900 hover:bg-gray-100 border border-gray-200"
|
||||
>
|
||||
<TextSelect className="h-4 w-4" />
|
||||
<Type className="h-4 w-4" />
|
||||
<span className="text-sm font-medium">
|
||||
{isSyllablesEnabled ? 'Desativar Sílabas' : 'Ativar Sílabas'}
|
||||
</span>
|
||||
@ -814,8 +795,27 @@ export function StoryPage() {
|
||||
<h2 className="text-lg font-semibold text-gray-900">Gravação de Áudio</h2>
|
||||
<AudioRecorder
|
||||
storyId={story.id}
|
||||
onRecordingComplete={(recording) => {
|
||||
setRecordings(prev => [recording, ...prev]);
|
||||
studentId={session?.user?.id || ''}
|
||||
onAudioUploaded={(audioUrl) => {
|
||||
const newRecording: StoryRecording = {
|
||||
id: crypto.randomUUID(),
|
||||
audio_url: audioUrl,
|
||||
created_at: new Date().toISOString(),
|
||||
processed_at: null,
|
||||
fluency_score: 0,
|
||||
pronunciation_score: 0,
|
||||
accuracy_score: 0,
|
||||
comprehension_score: 0,
|
||||
words_per_minute: 0,
|
||||
pause_count: 0,
|
||||
error_count: 0,
|
||||
self_corrections: 0,
|
||||
strengths: [],
|
||||
improvements: [],
|
||||
suggestions: '',
|
||||
transcription: ''
|
||||
};
|
||||
setRecordings(prev => [newRecording, ...prev]);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user