feat: enhance ChapterPlayer UI and add smooth scrolling for active segments in ChaptersPanel

This commit is contained in:
2026-03-13 16:25:07 +08:00
parent 3393be4967
commit 00ba2e0d40
2 changed files with 16 additions and 6 deletions

View File

@@ -3,7 +3,6 @@ import { useTheme } from '@/contexts/ThemeContext'
import WaveformPlayer from '@arraypress/waveform-player'
import '@arraypress/waveform-player/dist/waveform-player.css'
import { Button } from '@/components/ui/button'
import { Badge } from '@/components/ui/badge'
import { X, Loader2 } from 'lucide-react'
import apiClient from '@/lib/api'
import { audiobookApi, type AudiobookSegment } from '@/lib/api/audiobook'
@@ -187,11 +186,9 @@ const ChapterPlayer = memo(({
<div ref={containerRef} className={styles.waveformContainer} />
</div>
{currentSeg && (
<div className="mt-2 flex items-start gap-2 p-2 rounded-md bg-background border border-border/60">
<Badge variant="outline" className="shrink-0 text-xs font-normal mt-0.5">
{currentSeg.character_name || '未知角色'}
</Badge>
<span className="text-xs leading-relaxed text-foreground/80">{currentSeg.text}</span>
<div className="mt-2 px-1 flex items-baseline gap-1.5">
<span className="text-[11px] font-semibold text-primary shrink-0">{currentSeg.character_name || '旁白'}</span>
<span className="text-xs text-muted-foreground leading-relaxed">{currentSeg.text}</span>
</div>
)}
</>

View File

@@ -1447,6 +1447,7 @@ function ChaptersPanel({
const [chapterPlayerChIdx, setChapterPlayerChIdx] = useState<number | null>(null)
const prevSegStatusRef = useRef<Record<number, string>>({})
const initialExpandDoneRef = useRef(false)
const segRefs = useRef<Record<number, HTMLDivElement | null>>({})
useEffect(() => {
if (!scrollToChapterId) return
@@ -1457,6 +1458,17 @@ function ChaptersPanel({
onScrollToChapterDone()
}, [scrollToChapterId, onScrollToChapterDone])
useEffect(() => {
if (sequentialPlayingId === null || !detail) return
const seg = segments.find(s => s.id === sequentialPlayingId)
if (!seg) return
const ch = detail.chapters.find(c => c.chapter_index === seg.chapter_index)
if (ch) setExpandedChapters(prev => { const n = new Set(prev); n.add(ch.id); return n })
setTimeout(() => {
segRefs.current[sequentialPlayingId]?.scrollIntoView({ behavior: 'smooth', block: 'nearest' })
}, 50)
}, [sequentialPlayingId, detail, segments])
useEffect(() => {
const bumps: Record<number, number> = {}
segments.forEach(seg => {
@@ -1712,6 +1724,7 @@ function ChaptersPanel({
return (
<div
key={seg.id}
ref={el => { segRefs.current[seg.id] = el }}
className={`rounded-lg border overflow-hidden ${sequentialPlayingId === seg.id ? 'border-primary/40 bg-primary/5' : 'bg-card'}`}
>
{/* Card header */}