feat: enhance ChapterPlayer UI and add smooth scrolling for active segments in ChaptersPanel
This commit is contained in:
@@ -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>
|
||||
)}
|
||||
</>
|
||||
|
||||
@@ -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 */}
|
||||
|
||||
Reference in New Issue
Block a user