- "frontend/src/components/ChapterMarkers.tsx" - "frontend/src/components/PlayerControls.tsx" - "frontend/src/components/AudioWaveform.tsx" - "frontend/src/pages/WatchPage.tsx" - "frontend/src/App.css" GSD-Task: S05/T03
39 lines
1.1 KiB
TypeScript
39 lines
1.1 KiB
TypeScript
import type { Chapter } from "../api/videos";
|
|
|
|
interface ChapterMarkersProps {
|
|
chapters: Chapter[];
|
|
duration: number;
|
|
onSeek: (time: number) => void;
|
|
}
|
|
|
|
/**
|
|
* Absolutely-positioned overlay that renders tick marks on the seek bar
|
|
* for each chapter. Ticks are clickable and show a tooltip on hover.
|
|
*/
|
|
export default function ChapterMarkers({ chapters, duration, onSeek }: ChapterMarkersProps) {
|
|
if (!duration || chapters.length === 0) return null;
|
|
|
|
return (
|
|
<div className="chapter-markers">
|
|
{chapters.map((ch) => {
|
|
const leftPct = (ch.start_time / duration) * 100;
|
|
return (
|
|
<button
|
|
key={ch.id}
|
|
className="chapter-marker__tick"
|
|
style={{ left: `${leftPct}%` }}
|
|
onClick={(e) => {
|
|
e.stopPropagation();
|
|
onSeek(ch.start_time);
|
|
}}
|
|
aria-label={`Jump to chapter: ${ch.title}`}
|
|
title={ch.title}
|
|
type="button"
|
|
>
|
|
<span className="chapter-marker__tooltip">{ch.title}</span>
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|