"use client"; import { useState, useEffect, useCallback } from "react"; import { useTranslations } from "next-intl"; import { Letter, SupportedAlphabets } from "@/lib/interfaces"; import { IconClick, CircleToggleButton, CircleButton, PrimaryButton } from "@/components/ui/buttons"; import { IMAGES } from "@/config/images"; import { ChevronLeft, ChevronRight } from "lucide-react"; import { PageLayout } from "@/components/ui/PageLayout"; import { Card } from "@/components/ui/Card"; interface AlphabetCardProps { alphabet: Letter[]; alphabetType: SupportedAlphabets; onBack: () => void; } export function AlphabetCard({ alphabet, alphabetType, onBack }: AlphabetCardProps) { const t = useTranslations("alphabet"); const [currentIndex, setCurrentIndex] = useState(0); const [showIPA, setShowIPA] = useState(true); const [showLetter, setShowLetter] = useState(true); const [showRoman, setShowRoman] = useState(false); const [isRandomMode, setIsRandomMode] = useState(false); // 只有日语假名显示罗马音按钮 const hasRomanization = alphabetType === "japanese"; const currentLetter = alphabet[currentIndex]; const goToNext = useCallback(() => { if (isRandomMode) { setCurrentIndex(Math.floor(Math.random() * alphabet.length)); } else { setCurrentIndex((prev) => (prev === alphabet.length - 1 ? 0 : prev + 1)); } }, [alphabet.length, isRandomMode]); const goToPrevious = useCallback(() => { if (isRandomMode) { setCurrentIndex(Math.floor(Math.random() * alphabet.length)); } else { setCurrentIndex((prev) => (prev === 0 ? alphabet.length - 1 : prev - 1)); } }, [alphabet.length, isRandomMode]); const goToRandom = useCallback(() => { setCurrentIndex(Math.floor(Math.random() * alphabet.length)); }, [alphabet.length]); // 键盘快捷键支持 useEffect(() => { const handleKeyDown = (e: globalThis.KeyboardEvent) => { if (e.key === "ArrowLeft") { goToPrevious(); } else if (e.key === "ArrowRight") { goToNext(); } else if (e.key === " ") { e.preventDefault(); goToRandom(); } else if (e.key === "Escape") { onBack(); } }; document.addEventListener("keydown", handleKeyDown); return () => document.removeEventListener("keydown", handleKeyDown); }, [goToPrevious, goToNext, goToRandom, onBack]); // 触摸滑动支持 const [touchStart, setTouchStart] = useState(null); const [touchEnd, setTouchEnd] = useState(null); const minSwipeDistance = 50; const onTouchStart = (e: React.TouchEvent) => { setTouchEnd(null); setTouchStart(e.targetTouches[0].clientX); }; const onTouchMove = (e: React.TouchEvent) => { setTouchEnd(e.targetTouches[0].clientX); }; const onTouchEnd = () => { if (!touchStart || !touchEnd) return; const distance = touchStart - touchEnd; const isLeftSwipe = distance > minSwipeDistance; const isRightSwipe = distance < -minSwipeDistance; if (isLeftSwipe) { goToNext(); } if (isRightSwipe) { goToPrevious(); } }; return ( {/* 右上角返回按钮 - outside the white card */}
{/* 白色主卡片容器 */} {/* 顶部进度指示器和显示选项按钮 */}
{/* 当前字母进度 */} {currentIndex + 1} / {alphabet.length} {/* 显示选项切换按钮组 */}
setShowLetter(!showLetter)} > {t("letter")} {/* IPA 音标显示切换 */} setShowIPA(!showIPA)} > IPA {/* 罗马音显示切换(仅日语显示) */} {hasRomanization && ( setShowRoman(!showRoman)} > {t("roman")} )} {/* 随机模式切换 */} setIsRandomMode(!isRandomMode)} > {t("random")}
{/* 字母主要内容显示区域 */}
{/* 字母本身(可隐藏) */} {showLetter ? (
{currentLetter.letter}
) : (
?
)} {/* IPA 音标显示 */} {showIPA && (
{currentLetter.letter_sound_ipa}
)} {/* 罗马音显示(日语) */} {showRoman && hasRomanization && currentLetter.roman_letter && (
{currentLetter.roman_letter}
)}
{/* 底部导航控制区域 */}
{/* 上一个按钮 */} {/* 中间区域:随机按钮 */}
{isRandomMode && ( {t("randomNext")} )}
{/* 下一个按钮 */}
{/* 底部操作提示文字 */}

{isRandomMode ? "使用左右箭头键或空格键随机切换字母,ESC键返回" : "使用左右箭头键或滑动切换字母,ESC键返回" }

{/* 全屏触摸事件监听层(用于滑动切换) */}
); }