diff --git a/frontend/app/learn/page.tsx b/frontend/app/learn/page.tsx index 62f3f0e..4abe386 100644 --- a/frontend/app/learn/page.tsx +++ b/frontend/app/learn/page.tsx @@ -73,12 +73,12 @@ export default function LearnPage() { // Quiz mode options - dynamically generate from current cards const quizOptions = [ - cards[currentCardIndex].translation, + cards[currentCardIndex].word, ...cards .filter((_, idx) => idx !== currentCardIndex) - .map(card => card.translation) + .map(card => card.word) .slice(0, 2), - '建議、提議' // additional wrong option + 'negotiate' // additional wrong option ].sort(() => Math.random() - 0.5) // shuffle options const handleFlip = () => { @@ -130,7 +130,7 @@ export default function LearnPage() { const handleQuizAnswer = (answer: string) => { setSelectedAnswer(answer) setShowResult(true) - if (answer === currentCard.translation) { + if (answer === currentCard.word) { setScore({ ...score, correct: score.correct + 1, total: score.total + 1 }) } else { setScore({ ...score, total: score.total + 1 }) @@ -281,12 +281,12 @@ export default function LearnPage() {
{/* Front of card */}
{currentCard.word} @@ -311,10 +314,6 @@ export default function LearnPage() {
@@ -325,39 +324,36 @@ export default function LearnPage() { {/* Back of card */}
-
-
+
+
翻譯
-
{currentCard.translation}
+
{currentCard.translation}
-
+
定義
-
{currentCard.definition}
+
{currentCard.definition}
-
+
例句
-
{currentCard.example}
-
{currentCard.exampleTranslation}
+
{currentCard.example}
+
{currentCard.exampleTranslation}
-
+
同義詞
{currentCard.synonyms.map((syn, idx) => ( - + {syn} ))} @@ -419,21 +415,19 @@ export default function LearnPage() {
-
根據定義選擇正確的中文翻譯
-
- {currentCard.definition} +
根據英文定義選擇正確的英文詞彙
+
+
+ {currentCard.definition} +
+
+ ({currentCard.partOfSpeech}) +
+
-
- ({currentCard.partOfSpeech}) -
-
@@ -443,9 +437,9 @@ export default function LearnPage() { onClick={() => !showResult && handleQuizAnswer(option)} disabled={showResult} className={`w-full p-4 text-left rounded-lg border-2 transition-all ${ - showResult && option === currentCard.translation + showResult && option === currentCard.word ? 'border-green-500 bg-green-50' - : showResult && option === selectedAnswer && option !== currentCard.translation + : showResult && option === selectedAnswer && option !== currentCard.word ? 'border-red-500 bg-red-50' : selectedAnswer === option ? 'border-primary bg-primary-light' @@ -454,12 +448,12 @@ export default function LearnPage() { >
{option} - {showResult && option === currentCard.translation && ( + {showResult && option === currentCard.word && ( )} - {showResult && option === selectedAnswer && option !== currentCard.translation && ( + {showResult && option === selectedAnswer && option !== currentCard.word && ( @@ -598,10 +592,6 @@ export default function LearnPage() {
{currentCard.exampleTranslation}
@@ -637,10 +627,6 @@ export default function LearnPage() {
@@ -674,7 +660,6 @@ export default function LearnPage() { {/* Result Display */} {showResult && (
-
單字詳情
{currentCard.word} - {currentCard.translation} @@ -728,10 +713,6 @@ export default function LearnPage() { {currentCard.pronunciation}
@@ -739,10 +720,6 @@ export default function LearnPage() {
完整例句發音:
diff --git a/frontend/components/AudioPlayer.tsx b/frontend/components/AudioPlayer.tsx index c3e2b0c..d1ffbbc 100644 --- a/frontend/components/AudioPlayer.tsx +++ b/frontend/components/AudioPlayer.tsx @@ -6,11 +6,7 @@ import { Play, Pause, Volume2, VolumeX, Settings } from 'lucide-react'; export interface AudioPlayerProps { text: string; audioUrl?: string; - accent?: 'us' | 'uk'; - speed?: number; autoPlay?: boolean; - showAccentSelector?: boolean; - showSpeedControl?: boolean; onPlayStart?: () => void; onPlayEnd?: () => void; onError?: (error: string) => void; @@ -27,11 +23,7 @@ export interface TTSResponse { export default function AudioPlayer({ text, audioUrl: providedAudioUrl, - accent = 'us', - speed = 1.0, autoPlay = false, - showAccentSelector = true, - showSpeedControl = true, onPlayStart, onPlayEnd, onError, @@ -39,18 +31,13 @@ export default function AudioPlayer({ }: AudioPlayerProps) { const [isPlaying, setIsPlaying] = useState(false); const [isLoading, setIsLoading] = useState(false); - const [isMuted, setIsMuted] = useState(false); - const [volume, setVolume] = useState(1); - const [currentAccent, setCurrentAccent] = useState<'us' | 'uk'>(accent); - const [currentSpeed, setCurrentSpeed] = useState(speed); const [audioUrl, setAudioUrl] = useState(providedAudioUrl || null); - const [showSettings, setShowSettings] = useState(false); const [error, setError] = useState(null); const audioRef = useRef(null); // 生成音頻 - const generateAudio = async (textToSpeak: string, accent: 'us' | 'uk', speed: number) => { + const generateAudio = async (textToSpeak: string) => { try { setIsLoading(true); setError(null); @@ -63,8 +50,8 @@ export default function AudioPlayer({ }, body: JSON.stringify({ text: textToSpeak, - accent: accent, - speed: speed, + accent: 'us', + speed: 1.0, voice: '' }) }); @@ -103,7 +90,7 @@ export default function AudioPlayer({ // 如果沒有音頻 URL,先生成 if (!urlToPlay) { - urlToPlay = await generateAudio(text, currentAccent, currentSpeed); + urlToPlay = await generateAudio(text); if (!urlToPlay) return; } @@ -111,8 +98,6 @@ export default function AudioPlayer({ if (!audio) return; audio.src = urlToPlay; - audio.playbackRate = currentSpeed; - audio.volume = isMuted ? 0 : volume; await audio.play(); setIsPlaying(true); @@ -134,7 +119,8 @@ export default function AudioPlayer({ }; // 切換播放/暫停 - const togglePlayPause = () => { + const togglePlayPause = (e?: React.MouseEvent) => { + e?.stopPropagation(); // 阻止事件冒泡 if (isPlaying) { pauseAudio(); } else { @@ -155,58 +141,10 @@ export default function AudioPlayer({ onError?.(errorMessage); }; - // 切換口音 - const handleAccentChange = async (newAccent: 'us' | 'uk') => { - if (newAccent === currentAccent) return; - - setCurrentAccent(newAccent); - setAudioUrl(null); // 清除現有音頻,強制重新生成 - - // 如果正在播放,停止並重新生成 - if (isPlaying) { - pauseAudio(); - await generateAudio(text, newAccent, currentSpeed); - } - }; - - // 切換速度 - const handleSpeedChange = async (newSpeed: number) => { - if (newSpeed === currentSpeed) return; - - setCurrentSpeed(newSpeed); - - // 如果音頻正在播放,直接調整播放速度 - const audio = audioRef.current; - if (audio && isPlaying) { - audio.playbackRate = newSpeed; - } else { - // 否則清除音頻,重新生成 - setAudioUrl(null); - } - }; - - // 音量控制 - const handleVolumeChange = (newVolume: number) => { - setVolume(newVolume); - const audio = audioRef.current; - if (audio) { - audio.volume = isMuted ? 0 : newVolume; - } - }; - - const toggleMute = () => { - const newMuted = !isMuted; - setIsMuted(newMuted); - const audio = audioRef.current; - if (audio) { - audio.volume = newMuted ? 0 : volume; - } - }; - // 自動播放 useEffect(() => { if (autoPlay && text && !audioUrl) { - generateAudio(text, currentAccent, currentSpeed); + generateAudio(text); } }, [autoPlay, text]); @@ -242,75 +180,6 @@ export default function AudioPlayer({ )} - {/* 口音選擇器 */} - {showAccentSelector && ( -
- - -
- )} - - {/* 速度控制 */} - {showSpeedControl && ( -
- Speed: - -
- )} - - {/* 音量控制 */} -
- - handleVolumeChange(parseFloat(e.target.value))} - className="w-16 h-1" - /> -
- {/* 錯誤顯示 */} {error && (
diff --git a/frontend/components/FlashcardForm.tsx b/frontend/components/FlashcardForm.tsx index 40f7234..5ec9a90 100644 --- a/frontend/components/FlashcardForm.tsx +++ b/frontend/components/FlashcardForm.tsx @@ -168,10 +168,6 @@ export function FlashcardForm({ cardSets, initialData, isEdit = false, onSuccess