@geekapps/silo-elements-nextjs 0.1.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/FileUploader.d.ts +2 -2
- package/dist/ImageUploader.d.ts +2 -2
- package/dist/MediaUploader.d.ts +2 -2
- package/dist/VideoPlayer.d.ts +2 -3
- package/dist/VideoPlayer.js +157 -105
- package/dist/VideoPlayer.js.map +1 -1
- package/dist/VideoUploader.d.ts +2 -2
- package/dist/components/DropZone.d.ts +2 -2
- package/dist/components/ProgressBar.d.ts +2 -2
- package/dist/index.d.ts +9 -9
- package/dist/index.js +157 -105
- package/dist/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ export { MediaUploader } from './MediaUploader.js';
|
|
|
5
5
|
export { Source, SourceProps, Sources, SourcesProps, Storyboard, StoryboardFrame, StoryboardFrameProps, StoryboardProps, Subtitle, SubtitleProps, Subtitles, SubtitlesProps, Video, VideoPlayer, VideoSourceType } from './VideoPlayer.js';
|
|
6
6
|
export { DropZone } from './components/DropZone.js';
|
|
7
7
|
export { ProgressBar } from './components/ProgressBar.js';
|
|
8
|
-
import * as
|
|
8
|
+
import * as react from 'react';
|
|
9
9
|
import { CSSProperties, ReactNode } from 'react';
|
|
10
10
|
import { ImageUploadOptions, VideoUploadOptions } from '@geekapps/silo-nextjs';
|
|
11
11
|
export { BatchFileState, BatchUploadOptions, BatchUploadState, FileUploadStatus, ImageUploadOptions, MultipartUploadState, SiloProvider, VideoUploadOptions, useBatchUpload, useFileStatus, useMultipartUpload, useSignedUrl, useSiloClient } from '@geekapps/silo-nextjs';
|
|
@@ -17,14 +17,14 @@ interface ImageOptionsProps {
|
|
|
17
17
|
onChange: (opts: ImageUploadOptions) => void;
|
|
18
18
|
style?: CSSProperties;
|
|
19
19
|
}
|
|
20
|
-
declare function ImageOptions({ value, onChange, style }: ImageOptionsProps):
|
|
20
|
+
declare function ImageOptions({ value, onChange, style }: ImageOptionsProps): react.JSX.Element;
|
|
21
21
|
|
|
22
22
|
interface VideoOptionsProps {
|
|
23
23
|
value: VideoUploadOptions;
|
|
24
24
|
onChange: (opts: VideoUploadOptions) => void;
|
|
25
25
|
style?: CSSProperties;
|
|
26
26
|
}
|
|
27
|
-
declare function VideoOptions({ value, onChange, style }: VideoOptionsProps):
|
|
27
|
+
declare function VideoOptions({ value, onChange, style }: VideoOptionsProps): react.JSX.Element;
|
|
28
28
|
|
|
29
29
|
interface AvatarProps {
|
|
30
30
|
/** Silo file key for the avatar image */
|
|
@@ -41,7 +41,7 @@ interface AvatarProps {
|
|
|
41
41
|
style?: CSSProperties;
|
|
42
42
|
alt?: string;
|
|
43
43
|
}
|
|
44
|
-
declare function Avatar({ fileKey, bucket, initials, size, shape, className, style, alt, }: AvatarProps):
|
|
44
|
+
declare function Avatar({ fileKey, bucket, initials, size, shape, className, style, alt, }: AvatarProps): react.JSX.Element;
|
|
45
45
|
|
|
46
46
|
interface ThumbnailProps {
|
|
47
47
|
/** Silo file key */
|
|
@@ -64,7 +64,7 @@ interface ThumbnailProps {
|
|
|
64
64
|
style?: CSSProperties;
|
|
65
65
|
alt?: string;
|
|
66
66
|
}
|
|
67
|
-
declare function Thumbnail({ fileKey, bucket, mimeType, width, height, fit, borderRadius, placeholder, className, style, alt, }: ThumbnailProps):
|
|
67
|
+
declare function Thumbnail({ fileKey, bucket, mimeType, width, height, fit, borderRadius, placeholder, className, style, alt, }: ThumbnailProps): react.JSX.Element;
|
|
68
68
|
|
|
69
69
|
interface BackgroundProps {
|
|
70
70
|
/** Silo file key for the background image */
|
|
@@ -81,7 +81,7 @@ interface BackgroundProps {
|
|
|
81
81
|
className?: string;
|
|
82
82
|
style?: CSSProperties;
|
|
83
83
|
}
|
|
84
|
-
declare function Background({ fileKey, bucket, size, position, overlay, children, className, style, }: BackgroundProps):
|
|
84
|
+
declare function Background({ fileKey, bucket, size, position, overlay, children, className, style, }: BackgroundProps): react.JSX.Element;
|
|
85
85
|
|
|
86
86
|
interface FileIconProps {
|
|
87
87
|
/** MIME type of the file */
|
|
@@ -99,7 +99,7 @@ interface FileIconProps {
|
|
|
99
99
|
className?: string;
|
|
100
100
|
style?: CSSProperties;
|
|
101
101
|
}
|
|
102
|
-
declare function FileIcon({ mimeType, name, size, iconSize, showName, showSize, className, style, }: FileIconProps):
|
|
102
|
+
declare function FileIcon({ mimeType, name, size, iconSize, showName, showSize, className, style, }: FileIconProps): react.JSX.Element;
|
|
103
103
|
|
|
104
104
|
interface FileCardProps {
|
|
105
105
|
fileId: string;
|
|
@@ -113,7 +113,7 @@ interface FileCardProps {
|
|
|
113
113
|
className?: string;
|
|
114
114
|
style?: CSSProperties;
|
|
115
115
|
}
|
|
116
|
-
declare function FileCard({ fileId, pollInterval, actions, onPreview, onCopyUrl, onDelete, className, style, }: FileCardProps):
|
|
116
|
+
declare function FileCard({ fileId, pollInterval, actions, onPreview, onCopyUrl, onDelete, className, style, }: FileCardProps): react.JSX.Element | null;
|
|
117
117
|
|
|
118
118
|
interface FilePreviewProps {
|
|
119
119
|
fileId: string | null;
|
|
@@ -121,6 +121,6 @@ interface FilePreviewProps {
|
|
|
121
121
|
/** Poll interval while processing (ms, default: 3000) */
|
|
122
122
|
pollInterval?: number;
|
|
123
123
|
}
|
|
124
|
-
declare function FilePreview({ fileId, onClose, pollInterval }: FilePreviewProps):
|
|
124
|
+
declare function FilePreview({ fileId, onClose, pollInterval }: FilePreviewProps): react.JSX.Element | null;
|
|
125
125
|
|
|
126
126
|
export { Avatar, type AvatarProps, Background, type BackgroundProps, FileCard, type FileCardProps, FileIcon, type FileIconProps, FilePreview, type FilePreviewProps, ImageOptions, Thumbnail, type ThumbnailProps, VideoOptions };
|
package/dist/index.js
CHANGED
|
@@ -1260,7 +1260,7 @@ function Video({
|
|
|
1260
1260
|
const [audioTracks, setAudioTracks] = useState([]);
|
|
1261
1261
|
const [selectedAudio, setSelectedAudio] = useState(0);
|
|
1262
1262
|
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
1263
|
-
const [settingsTab, setSettingsTab] = useState("
|
|
1263
|
+
const [settingsTab, setSettingsTab] = useState("root");
|
|
1264
1264
|
const [playbackRate, setPlaybackRate] = useState(1);
|
|
1265
1265
|
const [subtitleStyle, setSubtitleStyle] = useState({
|
|
1266
1266
|
track: initialSubtitleMode,
|
|
@@ -1286,6 +1286,7 @@ function Video({
|
|
|
1286
1286
|
const [volume, setVolume] = useState(defaultVolume);
|
|
1287
1287
|
const [isMuted, setIsMuted] = useState(false);
|
|
1288
1288
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
1289
|
+
const [playerHeight, setPlayerHeight] = useState(0);
|
|
1289
1290
|
const [error, setError] = useState(null);
|
|
1290
1291
|
const activeSource = parsed.sources[sourceIndex] ?? parsed.sources[0] ?? null;
|
|
1291
1292
|
const progressPercent = duration ? currentTime / duration * 100 : 0;
|
|
@@ -1466,6 +1467,16 @@ function Video({
|
|
|
1466
1467
|
video?.removeEventListener("webkitendfullscreen", onFullscreenChange);
|
|
1467
1468
|
};
|
|
1468
1469
|
}, []);
|
|
1470
|
+
useEffect(() => {
|
|
1471
|
+
const player = playerRef.current;
|
|
1472
|
+
if (!player) return;
|
|
1473
|
+
const ro = new ResizeObserver((entries) => {
|
|
1474
|
+
const entry = entries[0];
|
|
1475
|
+
if (entry) setPlayerHeight(entry.contentRect.height);
|
|
1476
|
+
});
|
|
1477
|
+
ro.observe(player);
|
|
1478
|
+
return () => ro.disconnect();
|
|
1479
|
+
}, []);
|
|
1469
1480
|
useEffect(() => {
|
|
1470
1481
|
let cancelled = false;
|
|
1471
1482
|
async function loadStoryboard() {
|
|
@@ -1937,8 +1948,8 @@ function Video({
|
|
|
1937
1948
|
/* @__PURE__ */ jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 h-40 bg-linear-to-t from-black/80 to-transparent" }),
|
|
1938
1949
|
/* @__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: [
|
|
1939
1950
|
/* @__PURE__ */ jsxs("div", { children: [
|
|
1940
|
-
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 }),
|
|
1941
|
-
description && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
|
|
1951
|
+
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 }),
|
|
1952
|
+
description && isFullscreen && /* @__PURE__ */ jsx("p", { className: "mt-1 text-xs font-medium text-white/85 @sm:text-sm", children: description })
|
|
1942
1953
|
] }),
|
|
1943
1954
|
parsed.sources.length > 1 && /* @__PURE__ */ jsx(
|
|
1944
1955
|
"select",
|
|
@@ -1954,111 +1965,143 @@ function Video({
|
|
|
1954
1965
|
/* @__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: [
|
|
1955
1966
|
settingsOpen && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1956
1967
|
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 z-40", onClick: () => setSettingsOpen(false) }),
|
|
1957
|
-
/* @__PURE__ */ jsxs("div", { className: "absolute bottom-full right-3 z-50 mb-2 w-
|
|
1958
|
-
/* @__PURE__ */
|
|
1959
|
-
"
|
|
1968
|
+
/* @__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: [
|
|
1969
|
+
/* @__PURE__ */ jsxs(
|
|
1970
|
+
"div",
|
|
1960
1971
|
{
|
|
1961
|
-
|
|
1962
|
-
|
|
1963
|
-
|
|
1964
|
-
children: tab
|
|
1965
|
-
},
|
|
1966
|
-
tab
|
|
1967
|
-
)) }),
|
|
1968
|
-
/* @__PURE__ */ jsxs("div", { className: "max-h-48 overflow-y-auto py-1", children: [
|
|
1969
|
-
settingsTab === "quality" && /* @__PURE__ */ jsx(Fragment, { children: [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(
|
|
1970
|
-
SettingsItem,
|
|
1971
|
-
{
|
|
1972
|
-
active: selectedQuality === quality.id,
|
|
1973
|
-
onClick: () => changeQuality(quality.id),
|
|
1974
|
-
children: [
|
|
1975
|
-
quality.label,
|
|
1976
|
-
quality.id === "auto" && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-white/40", children: "ABR" })
|
|
1977
|
-
]
|
|
1972
|
+
style: {
|
|
1973
|
+
display: settingsTab === "root" ? "block" : "none",
|
|
1974
|
+
animation: settingsTab === "root" ? "settingsSlideIn 0.18s ease" : void 0
|
|
1978
1975
|
},
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
|
|
1983
|
-
|
|
1984
|
-
|
|
1985
|
-
"
|
|
1986
|
-
|
|
1987
|
-
type: "button",
|
|
1988
|
-
onClick: () => {
|
|
1989
|
-
const next = s.srclang === "off" ? "off" : s.srclang;
|
|
1990
|
-
setSubtitleMode(next);
|
|
1991
|
-
setSubtitleStyle((st) => ({ ...st, track: next }));
|
|
1992
|
-
},
|
|
1993
|
-
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"}`,
|
|
1994
|
-
children: s.label
|
|
1995
|
-
},
|
|
1996
|
-
s.srclang
|
|
1997
|
-
)) })
|
|
1998
|
-
] }),
|
|
1999
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2000
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wider text-white/40", children: "Size" }),
|
|
2001
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["small", "medium", "large"].map((s) => /* @__PURE__ */ jsx(
|
|
2002
|
-
"button",
|
|
2003
|
-
{
|
|
2004
|
-
type: "button",
|
|
2005
|
-
onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
|
|
2006
|
-
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"}`,
|
|
2007
|
-
children: s
|
|
2008
|
-
},
|
|
2009
|
-
s
|
|
2010
|
-
)) })
|
|
2011
|
-
] }),
|
|
2012
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
2013
|
-
/* @__PURE__ */ jsx("p", { className: "mb-1 text-[10px] font-semibold uppercase tracking-wider text-white/40", children: "Color" }),
|
|
2014
|
-
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: [["white", "#fff"], ["yellow", "#facc15"], ["cyan", "#22d3ee"]].map(([c, hex]) => /* @__PURE__ */ jsx(
|
|
1976
|
+
children: [
|
|
1977
|
+
/* @__PURE__ */ jsx("div", { className: "px-3 py-2 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Settings" }),
|
|
1978
|
+
[
|
|
1979
|
+
{ id: "quality", label: "Quality", value: qualities.find((q) => q.id === selectedQuality)?.label ?? "Auto" },
|
|
1980
|
+
...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 }] : [],
|
|
1981
|
+
...audioTracks.length > 1 ? [{ id: "audio", label: "Audio", value: audioTracks.find((t) => t.id === selectedAudio)?.label ?? "" }] : [],
|
|
1982
|
+
{ id: "playback", label: "Speed", value: playbackRate === 1 ? "Normal" : `${playbackRate}x` }
|
|
1983
|
+
].map((item) => /* @__PURE__ */ jsxs(
|
|
2015
1984
|
"button",
|
|
2016
1985
|
{
|
|
2017
1986
|
type: "button",
|
|
2018
|
-
onClick: () =>
|
|
2019
|
-
className:
|
|
2020
|
-
|
|
1987
|
+
onClick: () => setSettingsTab(item.id),
|
|
1988
|
+
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",
|
|
1989
|
+
children: [
|
|
1990
|
+
/* @__PURE__ */ jsx("span", { children: item.label }),
|
|
1991
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-1 text-xs text-white/40", children: [
|
|
1992
|
+
item.value,
|
|
1993
|
+
/* @__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" }) })
|
|
1994
|
+
] })
|
|
1995
|
+
]
|
|
2021
1996
|
},
|
|
2022
|
-
|
|
2023
|
-
))
|
|
2024
|
-
]
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
1997
|
+
item.id
|
|
1998
|
+
))
|
|
1999
|
+
]
|
|
2000
|
+
},
|
|
2001
|
+
"root"
|
|
2002
|
+
),
|
|
2003
|
+
["quality", "subtitles", "audio", "playback"].map((tab) => /* @__PURE__ */ jsxs(
|
|
2004
|
+
"div",
|
|
2005
|
+
{
|
|
2006
|
+
style: {
|
|
2007
|
+
display: settingsTab === tab ? "block" : "none",
|
|
2008
|
+
animation: settingsTab === tab ? "settingsSlideIn 0.18s ease" : void 0
|
|
2009
|
+
},
|
|
2010
|
+
children: [
|
|
2011
|
+
/* @__PURE__ */ jsxs(
|
|
2028
2012
|
"button",
|
|
2029
2013
|
{
|
|
2030
2014
|
type: "button",
|
|
2031
|
-
onClick: () =>
|
|
2032
|
-
className:
|
|
2033
|
-
children:
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2051
|
-
|
|
2052
|
-
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2015
|
+
onClick: () => setSettingsTab("root"),
|
|
2016
|
+
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",
|
|
2017
|
+
children: [
|
|
2018
|
+
/* @__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" }) }),
|
|
2019
|
+
tab === "quality" ? "Quality" : tab === "subtitles" ? "Subtitles / CC" : tab === "audio" ? "Audio" : "Speed"
|
|
2020
|
+
]
|
|
2021
|
+
}
|
|
2022
|
+
),
|
|
2023
|
+
/* @__PURE__ */ jsxs("div", { className: "max-h-52 overflow-y-auto py-1", children: [
|
|
2024
|
+
tab === "quality" && [...qualities].reverse().map((quality) => /* @__PURE__ */ jsxs(SettingsItem, { active: selectedQuality === quality.id, onClick: () => {
|
|
2025
|
+
changeQuality(quality.id);
|
|
2026
|
+
setSettingsTab("root");
|
|
2027
|
+
}, children: [
|
|
2028
|
+
quality.label,
|
|
2029
|
+
quality.id === "auto" && /* @__PURE__ */ jsx("span", { className: "ml-1 text-[10px] text-white/40", children: "ABR" })
|
|
2030
|
+
] }, quality.id)),
|
|
2031
|
+
tab === "subtitles" && /* @__PURE__ */ jsxs("div", { className: "px-3 py-2 space-y-3", children: [
|
|
2032
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2033
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Track" }),
|
|
2034
|
+
/* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-1", children: [{ srclang: "off", label: "Off" }, ...parsed.subtitles].map((s) => /* @__PURE__ */ jsx(
|
|
2035
|
+
"button",
|
|
2036
|
+
{
|
|
2037
|
+
type: "button",
|
|
2038
|
+
onClick: () => {
|
|
2039
|
+
const next = s.srclang === "off" ? "off" : s.srclang;
|
|
2040
|
+
setSubtitleMode(next);
|
|
2041
|
+
setSubtitleStyle((st) => ({ ...st, track: next }));
|
|
2042
|
+
},
|
|
2043
|
+
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"}`,
|
|
2044
|
+
children: s.label
|
|
2045
|
+
},
|
|
2046
|
+
s.srclang
|
|
2047
|
+
)) })
|
|
2048
|
+
] }),
|
|
2049
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2050
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Size" }),
|
|
2051
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: ["small", "medium", "large", "xlarge"].map((s) => /* @__PURE__ */ jsx(
|
|
2052
|
+
"button",
|
|
2053
|
+
{
|
|
2054
|
+
type: "button",
|
|
2055
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, size: s })),
|
|
2056
|
+
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"}`,
|
|
2057
|
+
children: s === "xlarge" ? "XL" : s.charAt(0).toUpperCase() + s.slice(1)
|
|
2058
|
+
},
|
|
2059
|
+
s
|
|
2060
|
+
)) })
|
|
2061
|
+
] }),
|
|
2062
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2063
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Color" }),
|
|
2064
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-2", children: [["white", "#fff"], ["yellow", "#facc15"], ["cyan", "#22d3ee"]].map(([c, hex]) => /* @__PURE__ */ jsx(
|
|
2065
|
+
"button",
|
|
2066
|
+
{
|
|
2067
|
+
type: "button",
|
|
2068
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, color: c })),
|
|
2069
|
+
className: `size-5 rounded-full ring-2 transition ${subtitleStyle.color === c ? "ring-white" : "ring-transparent"}`,
|
|
2070
|
+
style: { backgroundColor: hex }
|
|
2071
|
+
},
|
|
2072
|
+
c
|
|
2073
|
+
)) })
|
|
2074
|
+
] }),
|
|
2075
|
+
/* @__PURE__ */ jsxs("div", { children: [
|
|
2076
|
+
/* @__PURE__ */ jsx("p", { className: "mb-1.5 text-[10px] font-semibold uppercase tracking-wider text-white/35", children: "Background" }),
|
|
2077
|
+
/* @__PURE__ */ jsx("div", { className: "flex gap-1", children: [["none", "None"], ["semi", "Semi"], ["solid", "Solid"]].map(([v, label]) => /* @__PURE__ */ jsx(
|
|
2078
|
+
"button",
|
|
2079
|
+
{
|
|
2080
|
+
type: "button",
|
|
2081
|
+
onClick: () => setSubtitleStyle((st) => ({ ...st, bg: v })),
|
|
2082
|
+
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"}`,
|
|
2083
|
+
children: label
|
|
2084
|
+
},
|
|
2085
|
+
v
|
|
2086
|
+
)) })
|
|
2087
|
+
] })
|
|
2088
|
+
] }),
|
|
2089
|
+
tab === "audio" && audioTracks.map((track) => /* @__PURE__ */ jsx(SettingsItem, { active: selectedAudio === track.id, onClick: () => {
|
|
2090
|
+
changeAudio(track.id);
|
|
2091
|
+
setSettingsTab("root");
|
|
2092
|
+
}, children: track.label }, track.id)),
|
|
2093
|
+
tab === "playback" && PLAYBACK_SPEEDS.map((speed) => /* @__PURE__ */ jsx(SettingsItem, { active: playbackRate === speed, onClick: () => {
|
|
2094
|
+
setPlaybackRate(speed);
|
|
2095
|
+
setSettingsOpen(false);
|
|
2096
|
+
setSettingsTab("root");
|
|
2097
|
+
}, children: speed === 1 ? "Normal" : `${speed}x` }, speed))
|
|
2098
|
+
] })
|
|
2099
|
+
]
|
|
2100
|
+
},
|
|
2101
|
+
tab
|
|
2102
|
+
))
|
|
2103
|
+
] }),
|
|
2104
|
+
/* @__PURE__ */ jsx("style", { children: `@keyframes settingsSlideIn{from{opacity:0;transform:translateX(8px)}to{opacity:1;transform:translateX(0)}}` })
|
|
2062
2105
|
] }),
|
|
2063
2106
|
/* @__PURE__ */ jsxs(
|
|
2064
2107
|
"div",
|
|
@@ -2193,7 +2236,10 @@ function Video({
|
|
|
2193
2236
|
"button",
|
|
2194
2237
|
{
|
|
2195
2238
|
type: "button",
|
|
2196
|
-
onClick: () =>
|
|
2239
|
+
onClick: () => {
|
|
2240
|
+
setSettingsOpen((v) => !v);
|
|
2241
|
+
setSettingsTab("root");
|
|
2242
|
+
},
|
|
2197
2243
|
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"}`,
|
|
2198
2244
|
"aria-label": "Settings",
|
|
2199
2245
|
children: [
|
|
@@ -2233,13 +2279,19 @@ function Video({
|
|
|
2233
2279
|
children: /* @__PURE__ */ jsx(
|
|
2234
2280
|
"div",
|
|
2235
2281
|
{
|
|
2236
|
-
className: "max-w-
|
|
2282
|
+
className: "max-w-[80%] rounded-lg px-4 py-1.5 text-center font-medium leading-snug",
|
|
2237
2283
|
style: {
|
|
2238
|
-
fontSize:
|
|
2284
|
+
fontSize: (() => {
|
|
2285
|
+
const base = Math.max(12, Math.min(playerHeight * 0.028, 32));
|
|
2286
|
+
if (subtitleStyle.size === "small") return `${base * 0.75}px`;
|
|
2287
|
+
if (subtitleStyle.size === "large") return `${base * 1.35}px`;
|
|
2288
|
+
if (subtitleStyle.size === "xlarge") return `${base * 1.8}px`;
|
|
2289
|
+
return `${base}px`;
|
|
2290
|
+
})(),
|
|
2239
2291
|
color: subtitleStyle.color === "yellow" ? "#facc15" : subtitleStyle.color === "cyan" ? "#22d3ee" : "#ffffff",
|
|
2240
|
-
backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.
|
|
2241
|
-
backdropFilter: subtitleStyle.bg === "semi" ? "blur(
|
|
2242
|
-
textShadow: subtitleStyle.bg === "none" ? "0 1px
|
|
2292
|
+
backgroundColor: subtitleStyle.bg === "none" ? "transparent" : subtitleStyle.bg === "solid" ? "rgba(0,0,0,0.9)" : "rgba(0,0,0,0.55)",
|
|
2293
|
+
backdropFilter: subtitleStyle.bg === "semi" ? "blur(6px)" : void 0,
|
|
2294
|
+
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)"
|
|
2243
2295
|
},
|
|
2244
2296
|
children: activeCue
|
|
2245
2297
|
}
|