@geekapps/silo-elements-nextjs 0.2.24 → 0.2.26
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.
- package/dist/VideoPlayer.js +157 -105
- package/dist/VideoPlayer.js.map +1 -1
- package/dist/index.js +157 -105
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
package/dist/VideoPlayer.js
CHANGED
|
@@ -60,7 +60,7 @@ function Video({
|
|
|
60
60
|
const [audioTracks, setAudioTracks] = useState([]);
|
|
61
61
|
const [selectedAudio, setSelectedAudio] = useState(0);
|
|
62
62
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
63
|
-
const [settingsTab, setSettingsTab] = useState("
|
|
63
|
+
const [settingsTab, setSettingsTab] = useState("root");
|
|
64
64
|
const [playbackRate, setPlaybackRate] = useState(1);
|
|
65
65
|
const [subtitleStyle, setSubtitleStyle] = useState({
|
|
66
66
|
track: initialSubtitleMode,
|
|
@@ -86,6 +86,7 @@ function Video({
|
|
|
86
86
|
const [volume, setVolume] = useState(defaultVolume);
|
|
87
87
|
const [isMuted, setIsMuted] = useState(false);
|
|
88
88
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
89
|
+
const [playerHeight, setPlayerHeight] = useState(0);
|
|
89
90
|
const [error, setError] = useState(null);
|
|
90
91
|
const activeSource = parsed.sources[sourceIndex] ?? parsed.sources[0] ?? null;
|
|
91
92
|
const progressPercent = duration ? currentTime / duration * 100 : 0;
|
|
@@ -266,6 +267,16 @@ function Video({
|
|
|
266
267
|
video?.removeEventListener("webkitendfullscreen", onFullscreenChange);
|
|
267
268
|
};
|
|
268
269
|
}, []);
|
|
270
|
+
useEffect(() => {
|
|
271
|
+
const player = playerRef.current;
|
|
272
|
+
if (!player) return;
|
|
273
|
+
const ro = new ResizeObserver((entries) => {
|
|
274
|
+
const entry = entries[0];
|
|
275
|
+
if (entry) setPlayerHeight(entry.contentRect.height);
|
|
276
|
+
});
|
|
277
|
+
ro.observe(player);
|
|
278
|
+
return () => ro.disconnect();
|
|
279
|
+
}, []);
|
|
269
280
|
useEffect(() => {
|
|
270
281
|
let cancelled = false;
|
|
271
282
|
async function loadStoryboard() {
|
|
@@ -737,8 +748,8 @@ function Video({
|
|
|
737
748
|
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-black/80 to-transparent" }),
|
|
738
749
|
/* @__PURE__ */ jsxs("header", { onClick: (e) => e.stopPropagation(), className: "relative z-10 flex items-start justify-between gap-4 px-4 pt-4 text-white @sm:px-7 @sm:pt-7 @lg:px-9 @lg:pt-8", children: [
|
|
739
750
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
740
|
-
title && /* @__PURE__ */ jsx("h1", { className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl", style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" }, children: title }),
|
|
741
|
-
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
|
|
751
|
+
title && isFullscreen && /* @__PURE__ */ jsx("h1", { className: "text-sm font-bold tracking-wide @sm:text-base @md:text-lg @lg:text-xl", style: { textShadow: "0 1px 6px rgba(0,0,0,0.6)" }, children: title }),
|
|
752
|
+
description && isFullscreen && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
|
|
742
753
|
] }),
|
|
743
754
|
parsed.sources.length > 1 && /* @__PURE__ */ jsx(
|
|
744
755
|
"select",
|
|
@@ -754,111 +765,143 @@ function Video({
|
|
|
754
765
|
/* @__PURE__ */ jsxs("footer", { onClick: (e) => e.stopPropagation(), className: "relative z-10 px-3 pb-3 text-white @sm:px-5 @sm:pb-5 @lg:px-9 @lg:pb-8", children: [
|
|
755
766
|
settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
756
767
|
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-40", onClick: () => setSettingsOpen(false) }),
|
|
757
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-3 z-50 mb-2 w-
|
|
758
|
-
/* @__PURE__ */
|
|
759
|
-
"
|
|
768
|
+
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-3 z-50 mb-2 w-56 overflow-hidden rounded-xl border border-white/10 bg-black/90 shadow-2xl backdrop-blur-xl @sm:right-5 @lg:right-9", children: [
|
|
769
|
+
/* @__PURE__ */ jsxs(
|
|
770
|
+
"div",
|
|
760
771
|
{
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
children: tab
|
|
765
|
-
},
|
|
766
|
-
tab
|
|
767
|
-
)) }),
|
|
768
|
-
/* @__PURE__ */ jsxs("div", { className: "max-h-48 overflow-y-auto py-1", children: [
|
|
769
|
-
settingsTab === "quality" && /* @__PURE__ */ jsx(Fragment, { children: [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(
|
|
770
|
-
SettingsItem,
|
|
771
|
-
{
|
|
772
|
-
active: selectedQuality === quality.id,
|
|
773
|
-
onClick: () => changeQuality(quality.id),
|
|
774
|
-
children: [
|
|
775
|
-
quality.label,
|
|
776
|
-
quality.id === "auto" && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-white/40", children: "ABR" })
|
|
777
|
-
]
|
|
772
|
+
style: {
|
|
773
|
+
display: settingsTab === "root" ? "block" : "none",
|
|
774
|
+
animation: settingsTab === "root" ? "settingsSlideIn 0.18s ease" : void 0
|
|
778
775
|
},
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
"
|
|
786
|
-
|
|
787
|
-
type: "button",
|
|
788
|
-
onClick: () => {
|
|
789
|
-
const next = s.srclang === "off" ? "off" : s.srclang;
|
|
790
|
-
setSubtitleMode(next);
|
|
791
|
-
setSubtitleStyle((st) => ({ ...st, track: next }));
|
|
792
|
-
},
|
|
793
|
-
className: `rounded-md px-2 py-1 text-xs font-medium transition ${subtitleStyle.track === s.srclang ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
|
|
794
|
-
children: s.label
|
|
795
|
-
},
|
|
796
|
-
s.srclang
|
|
797
|
-
)) })
|
|
798
|
-
] }),
|
|
799
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
800
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wider text-white/40", children: "Size" }),
|
|
801
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["small", "medium", "large"].map((s) => /* @__PURE__ */ jsx(
|
|
802
|
-
"button",
|
|
803
|
-
{
|
|
804
|
-
type: "button",
|
|
805
|
-
onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
|
|
806
|
-
className: `rounded-md px-2 py-1 text-xs font-medium capitalize transition ${subtitleStyle.size === s ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
|
|
807
|
-
children: s
|
|
808
|
-
},
|
|
809
|
-
s
|
|
810
|
-
)) })
|
|
811
|
-
] }),
|
|
812
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
813
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wider text-white/40", children: "Color" }),
|
|
814
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: [["white", "#fff"], ["yellow", "#facc15"], ["cyan", "#22d3ee"]].map(([c, hex]) => /* @__PURE__ */ jsx(
|
|
776
|
+
children: [
|
|
777
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Settings" }),
|
|
778
|
+
[
|
|
779
|
+
{ id: "quality", label: "Quality", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
|
|
780
|
+
...parsed.subtitles.length > 0 ? [{ id: "subtitles", label: "Subtitles / CC", value: subtitleStyle.track === "off" ? "Off" : parsed.subtitles.find((s) => s.srclang === subtitleStyle.track)?.label ?? subtitleStyle.track }] : [],
|
|
781
|
+
...audioTracks.length > 1 ? [{ id: "audio", label: "Audio", value: audioTracks.find((t) => t.id === selectedAudio)?.label ?? "" }] : [],
|
|
782
|
+
{ id: "playback", label: "Speed", value: playbackRate === 1 ? "Normal" : `${playbackRate}x` }
|
|
783
|
+
].map((item) => /* @__PURE__ */ jsxs(
|
|
815
784
|
"button",
|
|
816
785
|
{
|
|
817
786
|
type: "button",
|
|
818
|
-
onClick: () =>
|
|
819
|
-
className:
|
|
820
|
-
|
|
787
|
+
onClick: () => setSettingsTab(item.id),
|
|
788
|
+
className: "flex w-full items-center justify-between gap-3 px-4 py-2.5 text-left text-sm font-medium text-white/80 transition hover:bg-white/10 hover:text-white",
|
|
789
|
+
children: [
|
|
790
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
791
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs text-white/40", children: [
|
|
792
|
+
item.value,
|
|
793
|
+
/* @__PURE__ */ jsx("svg", { className: "size-3.5 opacity-50", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M6 4l4 4-4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) })
|
|
794
|
+
] })
|
|
795
|
+
]
|
|
821
796
|
},
|
|
822
|
-
|
|
823
|
-
))
|
|
824
|
-
]
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
797
|
+
item.id
|
|
798
|
+
))
|
|
799
|
+
]
|
|
800
|
+
},
|
|
801
|
+
"root"
|
|
802
|
+
),
|
|
803
|
+
["quality", "subtitles", "audio", "playback"].map((tab) => /* @__PURE__ */ jsxs(
|
|
804
|
+
"div",
|
|
805
|
+
{
|
|
806
|
+
style: {
|
|
807
|
+
display: settingsTab === tab ? "block" : "none",
|
|
808
|
+
animation: settingsTab === tab ? "settingsSlideIn 0.18s ease" : void 0
|
|
809
|
+
},
|
|
810
|
+
children: [
|
|
811
|
+
/* @__PURE__ */ jsxs(
|
|
828
812
|
"button",
|
|
829
813
|
{
|
|
830
814
|
type: "button",
|
|
831
|
-
onClick: () =>
|
|
832
|
-
className:
|
|
833
|
-
children:
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
|
|
815
|
+
onClick: () => setSettingsTab("root"),
|
|
816
|
+
className: "flex w-full items-center gap-2 border-b border-white/10 px-3 py-2.5 text-xs font-semibold text-white/60 transition hover:text-white",
|
|
817
|
+
children: [
|
|
818
|
+
/* @__PURE__ */ jsx("svg", { className: "size-3.5", viewBox: "0 0 16 16", fill: "none", children: /* @__PURE__ */ jsx("path", { d: "M10 4L6 8l4 4", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }),
|
|
819
|
+
tab === "quality" ? "Quality" : tab === "subtitles" ? "Subtitles / CC" : tab === "audio" ? "Audio" : "Speed"
|
|
820
|
+
]
|
|
821
|
+
}
|
|
822
|
+
),
|
|
823
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-52 overflow-y-auto py-1", children: [
|
|
824
|
+
tab === "quality" && [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(SettingsItem, { active: selectedQuality === quality.id, onClick: () => {
|
|
825
|
+
changeQuality(quality.id);
|
|
826
|
+
setSettingsTab("root");
|
|
827
|
+
}, children: [
|
|
828
|
+
quality.label,
|
|
829
|
+
quality.id === "auto" && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-white/40", children: "ABR" })
|
|
830
|
+
] }, quality.id)),
|
|
831
|
+
tab === "subtitles" && /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 space-y-3", children: [
|
|
832
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
833
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Track" }),
|
|
834
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: [{ srclang: "off", label: "Off" }, ...parsed.subtitles].map((s) => /* @__PURE__ */ jsx(
|
|
835
|
+
"button",
|
|
836
|
+
{
|
|
837
|
+
type: "button",
|
|
838
|
+
onClick: () => {
|
|
839
|
+
const next = s.srclang === "off" ? "off" : s.srclang;
|
|
840
|
+
setSubtitleMode(next);
|
|
841
|
+
setSubtitleStyle((st) => ({ ...st, track: next }));
|
|
842
|
+
},
|
|
843
|
+
className: `rounded-md px-2 py-1 text-xs font-medium transition ${subtitleStyle.track === s.srclang ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
|
|
844
|
+
children: s.label
|
|
845
|
+
},
|
|
846
|
+
s.srclang
|
|
847
|
+
)) })
|
|
848
|
+
] }),
|
|
849
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
850
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Size" }),
|
|
851
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
|
|
852
|
+
"button",
|
|
853
|
+
{
|
|
854
|
+
type: "button",
|
|
855
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
|
|
856
|
+
className: `rounded-md px-2 py-1 text-xs font-medium capitalize transition ${subtitleStyle.size === s ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
|
|
857
|
+
children: s === "xlarge" ? "XL" : s.charAt(0).toUpperCase() + s.slice(1)
|
|
858
|
+
},
|
|
859
|
+
s
|
|
860
|
+
)) })
|
|
861
|
+
] }),
|
|
862
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
863
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Color" }),
|
|
864
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: [["white", "#fff"], ["yellow", "#facc15"], ["cyan", "#22d3ee"]].map(([c, hex]) => /* @__PURE__ */ jsx(
|
|
865
|
+
"button",
|
|
866
|
+
{
|
|
867
|
+
type: "button",
|
|
868
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, color: c })),
|
|
869
|
+
className: `size-5 rounded-full ring-2 transition ${subtitleStyle.color === c ? "ring-white" : "ring-transparent"}`,
|
|
870
|
+
style: { backgroundColor: hex }
|
|
871
|
+
},
|
|
872
|
+
c
|
|
873
|
+
)) })
|
|
874
|
+
] }),
|
|
875
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
876
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Background" }),
|
|
877
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: [["none", "None"], ["semi", "Semi"], ["solid", "Solid"]].map(([v, label]) => /* @__PURE__ */ jsx(
|
|
878
|
+
"button",
|
|
879
|
+
{
|
|
880
|
+
type: "button",
|
|
881
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, bg: v })),
|
|
882
|
+
className: `rounded-md px-2 py-1 text-xs font-medium transition ${subtitleStyle.bg === v ? "bg-white text-black" : "bg-white/10 text-white hover:bg-white/20"}`,
|
|
883
|
+
children: label
|
|
884
|
+
},
|
|
885
|
+
v
|
|
886
|
+
)) })
|
|
887
|
+
] })
|
|
888
|
+
] }),
|
|
889
|
+
tab === "audio" && audioTracks.map((track) => /* @__PURE__ */ jsx(SettingsItem, { active: selectedAudio === track.id, onClick: () => {
|
|
890
|
+
changeAudio(track.id);
|
|
891
|
+
setSettingsTab("root");
|
|
892
|
+
}, children: track.label }, track.id)),
|
|
893
|
+
tab === "playback" && PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsx(SettingsItem, { active: playbackRate === speed, onClick: () => {
|
|
894
|
+
setPlaybackRate(speed);
|
|
895
|
+
setSettingsOpen(false);
|
|
896
|
+
setSettingsTab("root");
|
|
897
|
+
}, children: speed === 1 ? "Normal" : `${speed}x` }, speed))
|
|
898
|
+
] })
|
|
899
|
+
]
|
|
900
|
+
},
|
|
901
|
+
tab
|
|
902
|
+
))
|
|
903
|
+
] }),
|
|
904
|
+
/* @__PURE__ */ jsx("style", { children: `@keyframes settingsSlideIn{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:translateX(0)}}` })
|
|
862
905
|
] }),
|
|
863
906
|
/* @__PURE__ */ jsxs(
|
|
864
907
|
"div",
|
|
@@ -993,7 +1036,10 @@ function Video({
|
|
|
993
1036
|
"button",
|
|
994
1037
|
{
|
|
995
1038
|
type: "button",
|
|
996
|
-
onClick: () =>
|
|
1039
|
+
onClick: () => {
|
|
1040
|
+
setSettingsOpen((v) => !v);
|
|
1041
|
+
setSettingsTab("root");
|
|
1042
|
+
},
|
|
997
1043
|
className: `flex h-6 items-center gap-1 rounded px-1.5 text-xs font-semibold transition hover:text-white/80 @sm:h-8 @sm:px-2 ${settingsOpen ? "text-white" : "text-white/60"}`,
|
|
998
1044
|
"aria-label": "Settings",
|
|
999
1045
|
children: [
|
|
@@ -1033,13 +1079,19 @@ function Video({
|
|
|
1033
1079
|
children: /* @__PURE__ */ jsx(
|
|
1034
1080
|
"div",
|
|
1035
1081
|
{
|
|
1036
|
-
className: "max-w-
|
|
1082
|
+
className: "max-w-[80%] rounded-lg px-4 py-1.5 text-center font-medium leading-snug",
|
|
1037
1083
|
style: {
|
|
1038
|
-
fontSize:
|
|
1084
|
+
fontSize: (() => {
|
|
1085
|
+
const base = Math.max(12, Math.min(playerHeight * 0.028, 32));
|
|
1086
|
+
if (subtitleStyle.size === "small") return `${base * 0.75}px`;
|
|
1087
|
+
if (subtitleStyle.size === "large") return `${base * 1.35}px`;
|
|
1088
|
+
if (subtitleStyle.size === "xlarge") return `${base * 1.8}px`;
|
|
1089
|
+
return `${base}px`;
|
|
1090
|
+
})(),
|
|
1039
1091
|
color: subtitleStyle.color === "yellow" ? "#facc15" : subtitleStyle.color === "cyan" ? "#22d3ee" : "#ffffff",
|
|
1040
|
-
backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.
|
|
1041
|
-
backdropFilter: subtitleStyle.bg === "semi" ? "blur(
|
|
1042
|
-
textShadow: subtitleStyle.bg === "none" ? "0 1px
|
|
1092
|
+
backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.55)",
|
|
1093
|
+
backdropFilter: subtitleStyle.bg === "semi" ? "blur(6px)" : void 0,
|
|
1094
|
+
textShadow: subtitleStyle.bg === "none" ? "0 1px 8px rgba(0,0,0,1), 0 0 16px rgba(0,0,0,0.9)" : "0 1px 3px rgba(0,0,0,0.5)"
|
|
1043
1095
|
},
|
|
1044
1096
|
children: activeCue
|
|
1045
1097
|
}
|