@geekapps/silo-elements-nextjs 0.2.53 → 0.2.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -36,6 +36,14 @@ type StoryboardProps = {
36
36
  height?: number;
37
37
  children?: ReactNode;
38
38
  };
39
+ type ChaptersProps = {
40
+ src?: string;
41
+ data?: Array<{
42
+ startTime: number;
43
+ title: string;
44
+ endTime?: number;
45
+ }>;
46
+ };
39
47
  type VideoProps = {
40
48
  title?: string;
41
49
  description?: string;
@@ -55,6 +63,10 @@ declare function Captions(_props: CaptionsProps): null;
55
63
  declare namespace Captions {
56
64
  var displayName: string;
57
65
  }
66
+ declare function Chapters(_props: ChaptersProps): null;
67
+ declare namespace Chapters {
68
+ var displayName: string;
69
+ }
58
70
  declare function VideoThumbnail(_props: ThumbnailProps): null;
59
71
  declare namespace VideoThumbnail {
60
72
  var displayName: string;
@@ -70,4 +82,4 @@ declare namespace StoryboardFrame {
70
82
  declare function Video({ title, description, children, className, autoHideControls, defaultVolume, maxHeight, fixedHeight, }: VideoProps): react__default.JSX.Element;
71
83
  declare const VideoPlayer: typeof Video;
72
84
 
73
- export { Captions, type CaptionsProps, Source, type SourceProps, Storyboard, StoryboardFrame, type StoryboardFrameProps, type StoryboardProps, type ThumbnailProps, Video, VideoPlayer, type VideoSourceType, VideoThumbnail };
85
+ export { Captions, type CaptionsProps, Chapters, type ChaptersProps, Source, type SourceProps, Storyboard, StoryboardFrame, type StoryboardFrameProps, type StoryboardProps, type ThumbnailProps, Video, VideoPlayer, type VideoSourceType, VideoThumbnail };
@@ -17,6 +17,10 @@ function Captions(_props) {
17
17
  return null;
18
18
  }
19
19
  Captions.displayName = "SiloCaptions";
20
+ function Chapters(_props) {
21
+ return null;
22
+ }
23
+ Chapters.displayName = "SiloChapters";
20
24
  function VideoThumbnail(_props) {
21
25
  return null;
22
26
  }
@@ -41,6 +45,7 @@ function Video({
41
45
  }) {
42
46
  const parsed = useMemo(() => parseVideoChildren(children), [children]);
43
47
  const [captions, setCaptions] = useState([]);
48
+ const [chapters, setChapters] = useState([]);
44
49
  const [poster, setPoster] = useState(void 0);
45
50
  const captionsSourceRef = useRef("");
46
51
  useEffect(() => {
@@ -75,6 +80,25 @@ function Video({
75
80
  cancelled = true;
76
81
  };
77
82
  }, [parsed.captionsSrc, parsed.captionsData]);
83
+ useEffect(() => {
84
+ if (parsed.chaptersData) {
85
+ setChapters(parsed.chaptersData);
86
+ return;
87
+ }
88
+ if (!parsed.chaptersSrc) {
89
+ setChapters([]);
90
+ return;
91
+ }
92
+ let cancelled = false;
93
+ fetch(parsed.chaptersSrc, { cache: "no-store" }).then((r) => r.json()).then((data) => {
94
+ if (!cancelled && Array.isArray(data)) setChapters(data);
95
+ }).catch(() => {
96
+ if (!cancelled) setChapters([]);
97
+ });
98
+ return () => {
99
+ cancelled = true;
100
+ };
101
+ }, [parsed.chaptersSrc, parsed.chaptersData]);
78
102
  useEffect(() => {
79
103
  if (!parsed.thumbnailSrc) {
80
104
  setPoster(void 0);
@@ -1481,6 +1505,14 @@ function Video({
1481
1505
  }
1482
1506
  }
1483
1507
  ),
1508
+ chapters.length > 0 && duration > 0 && chapters.map((ch, i) => /* @__PURE__ */ jsx(
1509
+ "div",
1510
+ {
1511
+ className: "pointer-events-none absolute top-1/2 -translate-y-1/2 w-0.5 rounded-full bg-white/50",
1512
+ style: { left: `${ch.startTime / duration * 100}%`, height: isDragging ? "7px" : isHoveringProgress ? "5px" : "3px", transition: "height 0.15s ease" }
1513
+ },
1514
+ i
1515
+ )),
1484
1516
  preview && (() => {
1485
1517
  const frameW = preview.cue.w ?? 160;
1486
1518
  const frameH = preview.cue.h ?? 90;
@@ -1573,7 +1605,12 @@ function Video({
1573
1605
  formatTime(currentTime),
1574
1606
  /* @__PURE__ */ jsx("span", { className: "text-white/30", children: "/" }),
1575
1607
  /* @__PURE__ */ jsx("span", { className: "text-white/45", children: formatTime(duration) })
1576
- ] })
1608
+ ] }),
1609
+ (() => {
1610
+ if (chapters.length === 0) return null;
1611
+ const ch = [...chapters].reverse().find((c) => currentTime >= c.startTime);
1612
+ return ch ? /* @__PURE__ */ jsx("span", { className: "hidden max-w-40 truncate text-[11px] text-white/50 @sm:block", children: ch.title }) : null;
1613
+ })()
1577
1614
  ] }),
1578
1615
  /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-0.5 @sm:gap-1", children: [
1579
1616
  /* @__PURE__ */ jsx(
@@ -1789,6 +1826,14 @@ function parseVideoChildren(children) {
1789
1826
  parsed.captionsSrc = element.props.src;
1790
1827
  }
1791
1828
  }
1829
+ if (child.type === Chapters || name === "SiloChapters") {
1830
+ const element = child;
1831
+ if (element.props.data) {
1832
+ parsed.chaptersData = element.props.data;
1833
+ } else if (element.props.src) {
1834
+ parsed.chaptersSrc = element.props.src;
1835
+ }
1836
+ }
1792
1837
  if (child.type === VideoThumbnail || name === "SiloVideoThumbnail") {
1793
1838
  const element = child;
1794
1839
  parsed.thumbnailSrc = element.props.src;
@@ -1829,7 +1874,13 @@ function inferSourceType(source) {
1829
1874
  return "file";
1830
1875
  }
1831
1876
  function findStoryboardCue(cues, time) {
1832
- return cues.find((cue) => time >= cue.start && time <= cue.end) ?? null;
1877
+ if (cues.length === 0) return null;
1878
+ let best = null;
1879
+ for (const cue of cues) {
1880
+ if (cue.start <= time) best = cue;
1881
+ else break;
1882
+ }
1883
+ return best;
1833
1884
  }
1834
1885
  function parseStoryboardVtt(text, baseUrl) {
1835
1886
  const lines = text.split(/\r?\n/).map((line) => line.trim()).filter(Boolean);
@@ -1891,6 +1942,6 @@ function formatTime(seconds) {
1891
1942
  return `${minutes}:${String(secs).padStart(2, "0")}`;
1892
1943
  }
1893
1944
 
1894
- export { Captions, Source, Storyboard, StoryboardFrame, Video, VideoPlayer, VideoThumbnail };
1945
+ export { Captions, Chapters, Source, Storyboard, StoryboardFrame, Video, VideoPlayer, VideoThumbnail };
1895
1946
  //# sourceMappingURL=VideoPlayer.js.map
1896
1947
  //# sourceMappingURL=VideoPlayer.js.map