@geekapps/silo-elements-nextjs 0.2.43 → 0.2.45

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.
@@ -8,17 +8,11 @@ type SourceProps = {
8
8
  type?: VideoSourceType;
9
9
  default?: boolean;
10
10
  };
11
- type SourcesProps = {
12
- children: ReactNode;
13
- };
14
- type SubtitleProps = {
11
+ type CaptionsProps = {
15
12
  src: string;
16
- srclang: string;
17
- label: string;
18
- default?: boolean;
19
13
  };
20
- type SubtitlesProps = {
21
- children: ReactNode;
14
+ type ThumbnailProps = {
15
+ src: string;
22
16
  };
23
17
  type StoryboardFrameProps = {
24
18
  start: number;
@@ -39,7 +33,6 @@ type StoryboardProps = {
39
33
  type VideoProps = {
40
34
  title?: string;
41
35
  description?: string;
42
- poster?: string;
43
36
  children: ReactNode;
44
37
  className?: string;
45
38
  autoHideControls?: boolean;
@@ -48,20 +41,16 @@ type VideoProps = {
48
41
  /** Fixed height — disables aspect-ratio so the player stays at exactly this height regardless of video dimensions */
49
42
  fixedHeight?: string | number;
50
43
  };
51
- declare function Sources(_props: SourcesProps): null;
52
- declare namespace Sources {
53
- var displayName: string;
54
- }
55
44
  declare function Source(_props: SourceProps): null;
56
45
  declare namespace Source {
57
46
  var displayName: string;
58
47
  }
59
- declare function Subtitles(_props: SubtitlesProps): null;
60
- declare namespace Subtitles {
48
+ declare function Captions(_props: CaptionsProps): null;
49
+ declare namespace Captions {
61
50
  var displayName: string;
62
51
  }
63
- declare function Subtitle(_props: SubtitleProps): null;
64
- declare namespace Subtitle {
52
+ declare function VideoThumbnail(_props: ThumbnailProps): null;
53
+ declare namespace VideoThumbnail {
65
54
  var displayName: string;
66
55
  }
67
56
  declare function Storyboard(_props: StoryboardProps): null;
@@ -72,7 +61,7 @@ declare function StoryboardFrame(_props: StoryboardFrameProps): null;
72
61
  declare namespace StoryboardFrame {
73
62
  var displayName: string;
74
63
  }
75
- declare function Video({ title, description, poster, children, className, autoHideControls, defaultVolume, maxHeight, fixedHeight, }: VideoProps): react__default.JSX.Element;
64
+ declare function Video({ title, description, children, className, autoHideControls, defaultVolume, maxHeight, fixedHeight, }: VideoProps): react__default.JSX.Element;
76
65
  declare const VideoPlayer: typeof Video;
77
66
 
78
- export { Source, type SourceProps, Sources, type SourcesProps, Storyboard, StoryboardFrame, type StoryboardFrameProps, type StoryboardProps, Subtitle, type SubtitleProps, Subtitles, type SubtitlesProps, Video, VideoPlayer, type VideoSourceType };
67
+ export { Captions, type CaptionsProps, Source, type SourceProps, Storyboard, StoryboardFrame, type StoryboardFrameProps, type StoryboardProps, type ThumbnailProps, Video, VideoPlayer, type VideoSourceType, VideoThumbnail };
@@ -1,6 +1,6 @@
1
- import React, { useMemo, useRef, useState, useCallback, useEffect } from 'react';
1
+ import React, { useMemo, useState, useEffect, useRef, useCallback } from 'react';
2
2
  import gsap from 'gsap';
3
- import { Pause, Play, VolumeX, Volume2, Captions, Settings, Minimize, Maximize } from 'lucide-react';
3
+ import { Pause, Play, VolumeX, Volume2, Captions as Captions$1, Settings, Minimize, Maximize } from 'lucide-react';
4
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
5
5
 
6
6
  var AUTO_QUALITY = {
@@ -9,22 +9,18 @@ var AUTO_QUALITY = {
9
9
  type: "auto"
10
10
  };
11
11
  var PLAYBACK_SPEEDS = [0.25, 0.5, 0.75, 1, 1.25, 1.5, 2];
12
- function Sources(_props) {
13
- return null;
14
- }
15
- Sources.displayName = "SiloSources";
16
12
  function Source(_props) {
17
13
  return null;
18
14
  }
19
15
  Source.displayName = "SiloSource";
20
- function Subtitles(_props) {
16
+ function Captions(_props) {
21
17
  return null;
22
18
  }
23
- Subtitles.displayName = "SiloSubtitles";
24
- function Subtitle(_props) {
19
+ Captions.displayName = "SiloCaptions";
20
+ function VideoThumbnail(_props) {
25
21
  return null;
26
22
  }
27
- Subtitle.displayName = "SiloSubtitle";
23
+ VideoThumbnail.displayName = "SiloVideoThumbnail";
28
24
  function Storyboard(_props) {
29
25
  return null;
30
26
  }
@@ -36,7 +32,6 @@ StoryboardFrame.displayName = "SiloStoryboardFrame";
36
32
  function Video({
37
33
  title,
38
34
  description,
39
- poster,
40
35
  children,
41
36
  className,
42
37
  autoHideControls = true,
@@ -45,14 +40,40 @@ function Video({
45
40
  fixedHeight
46
41
  }) {
47
42
  const parsed = useMemo(() => parseVideoChildren(children), [children]);
43
+ const [captions, setCaptions] = useState([]);
44
+ const [poster, setPoster] = useState(void 0);
45
+ useEffect(() => {
46
+ if (!parsed.captionsSrc) {
47
+ setCaptions([]);
48
+ return;
49
+ }
50
+ let cancelled = false;
51
+ fetch(parsed.captionsSrc, { cache: "no-store" }).then((r) => r.json()).then((data) => {
52
+ if (!cancelled && Array.isArray(data)) {
53
+ setCaptions(data.map((c, i) => ({ ...c, default: i === 0 })));
54
+ }
55
+ }).catch(() => {
56
+ if (!cancelled) setCaptions([]);
57
+ });
58
+ return () => {
59
+ cancelled = true;
60
+ };
61
+ }, [parsed.captionsSrc]);
62
+ useEffect(() => {
63
+ if (!parsed.thumbnailSrc) {
64
+ setPoster(void 0);
65
+ return;
66
+ }
67
+ setPoster(parsed.thumbnailSrc);
68
+ }, [parsed.thumbnailSrc]);
48
69
  const initialSourceIndex = useMemo(() => {
49
70
  const index = parsed.sources.findIndex((source) => source.default);
50
71
  return index >= 0 ? index : 0;
51
72
  }, [parsed.sources]);
52
73
  const initialSubtitleMode = useMemo(() => {
53
- const track = parsed.subtitles.find((subtitle) => subtitle.default);
74
+ const track = captions.find((c) => c.default);
54
75
  return track?.srclang ?? "off";
55
- }, [parsed.subtitles]);
76
+ }, [captions]);
56
77
  const containerRef = useRef(null);
57
78
  const chromeRef = useRef(null);
58
79
  const playerRef = useRef(null);
@@ -157,10 +178,10 @@ function Video({
157
178
  }
158
179
  }, [sourceIndex, parsed.sources.length, initialSourceIndex]);
159
180
  useEffect(() => {
160
- if (subtitleMode !== "off" && !parsed.subtitles.some((subtitle) => subtitle.srclang === subtitleMode)) {
181
+ if (subtitleMode !== "off" && !captions.some((subtitle) => subtitle.srclang === subtitleMode)) {
161
182
  setSubtitleMode(initialSubtitleMode);
162
183
  }
163
- }, [subtitleMode, parsed.subtitles, initialSubtitleMode]);
184
+ }, [subtitleMode, captions, initialSubtitleMode]);
164
185
  useEffect(() => {
165
186
  const video = videoRef.current;
166
187
  if (!video) return;
@@ -784,7 +805,7 @@ function Video({
784
805
  preload: "metadata",
785
806
  crossOrigin: "anonymous",
786
807
  children: [
787
- parsed.subtitles.map((subtitle) => /* @__PURE__ */ jsx(
808
+ captions.map((subtitle) => /* @__PURE__ */ jsx(
788
809
  "track",
789
810
  {
790
811
  kind: "subtitles",
@@ -891,11 +912,11 @@ function Video({
891
912
  label: "Qualidade",
892
913
  value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto"
893
914
  },
894
- ...parsed.subtitles.length > 0 ? [
915
+ ...captions.length > 0 ? [
895
916
  {
896
917
  id: "subtitles",
897
918
  label: "Legendas",
898
- value: subtitleStyle.track === "off" ? "Desligado" : parsed.subtitles.find(
919
+ value: subtitleStyle.track === "off" ? "Desligado" : captions.find(
899
920
  (s) => s.srclang === subtitleStyle.track
900
921
  )?.label ?? subtitleStyle.track
901
922
  }
@@ -1052,7 +1073,7 @@ function Video({
1052
1073
  ),
1053
1074
  /* @__PURE__ */ jsx("div", { className: "py-1.5", children: [
1054
1075
  { srclang: "off", label: "Desligado" },
1055
- ...parsed.subtitles
1076
+ ...captions
1056
1077
  ].map((s) => /* @__PURE__ */ jsxs(
1057
1078
  "button",
1058
1079
  {
@@ -1452,16 +1473,16 @@ function Video({
1452
1473
  ) })
1453
1474
  ] }),
1454
1475
  /* @__PURE__ */ jsx("div", { className: "mx-0.5 h-4 w-px bg-white/20 @md:mx-1" }),
1455
- parsed.subtitles.length > 0 && /* @__PURE__ */ jsx(
1476
+ captions.length > 0 && /* @__PURE__ */ jsx(
1456
1477
  "button",
1457
1478
  {
1458
1479
  type: "button",
1459
1480
  onClick: () => setSubtitleMode(
1460
- (m) => m === "off" ? parsed.subtitles[0]?.srclang ?? "off" : "off"
1481
+ (m) => m === "off" ? captions[0]?.srclang ?? "off" : "off"
1461
1482
  ),
1462
1483
  className: `grid size-8 place-items-center rounded transition hover:text-white/80 @sm:size-10${subtitleMode !== "off" ? "text-white" : "text-white/60"}`,
1463
1484
  "aria-label": "Captions",
1464
- children: /* @__PURE__ */ jsx(Captions, { className: "size-4 @sm:size-5" })
1485
+ children: /* @__PURE__ */ jsx(Captions$1, { className: "size-4 @sm:size-5" })
1465
1486
  }
1466
1487
  ),
1467
1488
  /* @__PURE__ */ jsx("div", { className: "relative", children: /* @__PURE__ */ jsx(
@@ -1589,8 +1610,7 @@ function Video({
1589
1610
  var VideoPlayer = Video;
1590
1611
  function parseVideoChildren(children) {
1591
1612
  const parsed = {
1592
- sources: [],
1593
- subtitles: []
1613
+ sources: []
1594
1614
  };
1595
1615
  function dn(child) {
1596
1616
  return child.type?.displayName ?? child.type?.name ?? "";
@@ -1598,25 +1618,17 @@ function parseVideoChildren(children) {
1598
1618
  React.Children.forEach(children, (child) => {
1599
1619
  if (!React.isValidElement(child)) return;
1600
1620
  const name = dn(child);
1601
- if (child.type === Sources || name === "SiloSources") {
1621
+ if (child.type === Source || name === "SiloSource") {
1602
1622
  const element = child;
1603
- React.Children.forEach(element.props.children, (sourceChild) => {
1604
- if (!React.isValidElement(sourceChild)) return;
1605
- const sn = dn(sourceChild);
1606
- if (sourceChild.type !== Source && sn !== "SiloSource") return;
1607
- const sourceElement = sourceChild;
1608
- parsed.sources.push(sourceElement.props);
1609
- });
1623
+ parsed.sources.push(element.props);
1610
1624
  }
1611
- if (child.type === Subtitles || name === "SiloSubtitles") {
1625
+ if (child.type === Captions || name === "SiloCaptions") {
1612
1626
  const element = child;
1613
- React.Children.forEach(element.props.children, (subtitleChild) => {
1614
- if (!React.isValidElement(subtitleChild)) return;
1615
- const sn = dn(subtitleChild);
1616
- if (subtitleChild.type !== Subtitle && sn !== "SiloSubtitle") return;
1617
- const subtitleElement = subtitleChild;
1618
- parsed.subtitles.push(subtitleElement.props);
1619
- });
1627
+ parsed.captionsSrc = element.props.src;
1628
+ }
1629
+ if (child.type === VideoThumbnail || name === "SiloVideoThumbnail") {
1630
+ const element = child;
1631
+ parsed.thumbnailSrc = element.props.src;
1620
1632
  }
1621
1633
  if (child.type === Storyboard || name === "SiloStoryboard") {
1622
1634
  const element = child;
@@ -1716,6 +1728,6 @@ function formatTime(seconds) {
1716
1728
  return `${minutes}:${String(secs).padStart(2, "0")}`;
1717
1729
  }
1718
1730
 
1719
- export { Source, Sources, Storyboard, StoryboardFrame, Subtitle, Subtitles, Video, VideoPlayer };
1731
+ export { Captions, Source, Storyboard, StoryboardFrame, Video, VideoPlayer, VideoThumbnail };
1720
1732
  //# sourceMappingURL=VideoPlayer.js.map
1721
1733
  //# sourceMappingURL=VideoPlayer.js.map