feat: implement ChapterPlayer styling and refactor UI components for improved layout and functionality

This commit is contained in:
2026-03-13 16:40:54 +08:00
parent d7d86adbd5
commit 6a5eae86ce
3 changed files with 174 additions and 55 deletions

View File

@@ -6,7 +6,7 @@ import { Button } from '@/components/ui/button'
import { X, Loader2 } from 'lucide-react'
import apiClient from '@/lib/api'
import { audiobookApi, type AudiobookSegment } from '@/lib/api/audiobook'
import styles from './AudioPlayer.module.css'
import styles from './ChapterPlayer.module.css'
interface TimelineItem {
seg: AudiobookSegment
@@ -117,15 +117,15 @@ const ChapterPlayer = memo(({
}
const waveformColor = theme === 'dark' ? '#4b5563' : '#d1d5db'
const progressColor = theme === 'dark' ? '#a78bfa' : '#7c3aed'
const progressColor = '#f97316'
const player = new WaveformPlayer(containerRef.current, {
url: blobUrl,
waveformStyle: 'mirror',
height: 60,
barWidth: 3,
height: 56,
barWidth: 2,
barSpacing: 1,
samples: 200,
samples: 260,
waveformColor,
progressColor,
showTime: true,
@@ -161,17 +161,16 @@ const ChapterPlayer = memo(({
}, [])
return (
<div className="px-3 py-2.5 border-b bg-primary/5">
<div className="flex items-center justify-between mb-2">
<span className="text-xs font-medium flex items-center gap-2 min-w-0">
<span className="truncate text-foreground/80">{chapterTitle}</span>
{isLoadingTimeline && !isLoadingChapter && (
<span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground shrink-0">
<Loader2 className="h-2.5 w-2.5 animate-spin" />
</span>
)}
</span>
<Button type="button" size="icon" variant="ghost" className="h-5 w-5" onClick={onClose}>
<div className={styles.panel}>
<div className={styles.header}>
<span className={styles.title}></span>
<span className={styles.chapterName}>{chapterTitle}</span>
{isLoadingTimeline && !isLoadingChapter && (
<span className="inline-flex items-center gap-1 text-[11px] text-muted-foreground shrink-0 ml-auto">
<Loader2 className="h-2.5 w-2.5 animate-spin" />
</span>
)}
<Button type="button" size="icon" variant="ghost" className="h-5 w-5 shrink-0" onClick={onClose}>
<X className="h-3 w-3" />
</Button>
</div>
@@ -182,13 +181,13 @@ const ChapterPlayer = memo(({
</div>
) : (
<>
<div className={styles.audioPlayerWrapper}>
<div ref={containerRef} className={styles.waveformContainer} />
<div className={styles.waveformWrapper}>
<div ref={containerRef} className={styles.waveformInner} />
</div>
{currentSeg && (
<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 className={styles.subtitle}>
<span className={styles.subtitleName}>{currentSeg.character_name || '旁白'}</span>
<span className={styles.subtitleText}>{currentSeg.text}</span>
</div>
)}
</>