@geekapps/silo-elements-nextjs 0.2.61 → 0.2.63
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 +1 -1
- package/dist/FileUploader.js +16 -3
- package/dist/FileUploader.js.map +1 -1
- package/dist/MediaUploader.js +16 -3
- package/dist/MediaUploader.js.map +1 -1
- package/dist/VideoPlayer.d.ts +17 -2
- package/dist/VideoPlayer.js +150 -42
- package/dist/VideoPlayer.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +166 -45
- package/dist/index.js.map +1 -1
- package/dist/types.d.ts +4 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { ImageUploader } from './ImageUploader.js';
|
|
|
2
2
|
export { VideoUploader } from './VideoUploader.js';
|
|
3
3
|
export { FileUploader } from './FileUploader.js';
|
|
4
4
|
export { MediaUploader } from './MediaUploader.js';
|
|
5
|
-
export { AgeRating, AgeRatingProps, Captions, CaptionsProps, Chapters, ChaptersProps, Rating, RatingProps, Source, SourceProps, Storyboard, StoryboardFrame, StoryboardFrameProps, StoryboardProps, Video, VideoPlayer, VideoSourceType, VideoThumbnail, ThumbnailProps as VideoThumbnailProps } from './VideoPlayer.js';
|
|
5
|
+
export { AgeRating, AgeRatingProps, Captions, CaptionsProps, Chapters, ChaptersProps, Rating, RatingProps, Source, SourceProps, Storyboard, StoryboardFrame, StoryboardFrameProps, StoryboardProps, StoryboardResolution, Video, VideoPlayer, VideoSourceType, VideoThumbnail, ThumbnailProps as VideoThumbnailProps } from './VideoPlayer.js';
|
|
6
6
|
export { DropZone } from './components/DropZone.js';
|
|
7
7
|
export { ProgressBar } from './components/ProgressBar.js';
|
|
8
8
|
import * as react from 'react';
|
package/dist/index.js
CHANGED
|
@@ -759,6 +759,8 @@ function FileUploader({
|
|
|
759
759
|
showVideoOptions = false,
|
|
760
760
|
image,
|
|
761
761
|
video,
|
|
762
|
+
isPrivate,
|
|
763
|
+
captionLanguage,
|
|
762
764
|
theme,
|
|
763
765
|
renderIcon,
|
|
764
766
|
renderProgress,
|
|
@@ -804,7 +806,13 @@ function FileUploader({
|
|
|
804
806
|
const effectiveVideo = showVideoOptions ? resolvedVideo : video ?? resolvedVideo;
|
|
805
807
|
if (multiple && files.length > 1) {
|
|
806
808
|
try {
|
|
807
|
-
const results = await batch.upload(files, {
|
|
809
|
+
const results = await batch.upload(files, {
|
|
810
|
+
...bucket !== void 0 && { bucket },
|
|
811
|
+
image: effectiveImage,
|
|
812
|
+
video: effectiveVideo,
|
|
813
|
+
...isPrivate !== void 0 && { isPrivate },
|
|
814
|
+
...captionLanguage && { captionLanguage }
|
|
815
|
+
});
|
|
808
816
|
onBatchUpload?.(results);
|
|
809
817
|
results.forEach((r) => onUpload?.(r));
|
|
810
818
|
} catch (err) {
|
|
@@ -814,13 +822,18 @@ function FileUploader({
|
|
|
814
822
|
const file = files[0];
|
|
815
823
|
if (!file) return;
|
|
816
824
|
try {
|
|
817
|
-
const result = await single.upload(file, {
|
|
825
|
+
const result = await single.upload(file, {
|
|
826
|
+
...bucket !== void 0 && { bucket },
|
|
827
|
+
image: effectiveImage,
|
|
828
|
+
video: effectiveVideo,
|
|
829
|
+
...isPrivate !== void 0 && { isPrivate }
|
|
830
|
+
});
|
|
818
831
|
if (result) onUpload?.(result);
|
|
819
832
|
} catch (err) {
|
|
820
833
|
onError?.(err instanceof Error ? err : new Error(String(err)));
|
|
821
834
|
}
|
|
822
835
|
}
|
|
823
|
-
}, [single, batch, multiple, bucket, image, video, imageOpts, videoOpts, showImageOptions, showVideoOptions, onUpload, onBatchUpload, onError]);
|
|
836
|
+
}, [single, batch, multiple, bucket, image, video, isPrivate, captionLanguage, imageOpts, videoOpts, showImageOptions, showVideoOptions, onUpload, onBatchUpload, onError]);
|
|
824
837
|
const handleFiles = useCallback(async (files) => {
|
|
825
838
|
const needsStaging = allowRename || showImageOptions && files.some((f) => f.type.startsWith("image/")) || showVideoOptions && files.some((f) => f.type.startsWith("video/"));
|
|
826
839
|
if (needsStaging) {
|
|
@@ -1234,13 +1247,6 @@ function Video({
|
|
|
1234
1247
|
cancelled = true;
|
|
1235
1248
|
};
|
|
1236
1249
|
}, [parsed.chaptersSrc, parsed.chaptersData]);
|
|
1237
|
-
useEffect(() => {
|
|
1238
|
-
if (!parsed.thumbnailSrc) {
|
|
1239
|
-
setPoster(void 0);
|
|
1240
|
-
return;
|
|
1241
|
-
}
|
|
1242
|
-
setPoster(parsed.thumbnailSrc);
|
|
1243
|
-
}, [parsed.thumbnailSrc]);
|
|
1244
1250
|
const initialSourceIndex = useMemo(() => {
|
|
1245
1251
|
const index = parsed.sources.findIndex((source) => source.default);
|
|
1246
1252
|
return index >= 0 ? index : 0;
|
|
@@ -1277,9 +1283,10 @@ function Video({
|
|
|
1277
1283
|
const [activeCue, setActiveCue] = useState(null);
|
|
1278
1284
|
const [storyboardSheetSize, setStoryboardSheetSize] = useState(null);
|
|
1279
1285
|
const storyboardSheetUrlRef = useRef("");
|
|
1280
|
-
const [storyboardCues, setStoryboardCues] = useState(
|
|
1281
|
-
|
|
1282
|
-
);
|
|
1286
|
+
const [storyboardCues, setStoryboardCues] = useState([]);
|
|
1287
|
+
const storyboardCacheRef = useRef(/* @__PURE__ */ new Map());
|
|
1288
|
+
const [activeStoryboardRes, setActiveStoryboardRes] = useState(null);
|
|
1289
|
+
const preloadedSpritesRef = useRef(/* @__PURE__ */ new Set());
|
|
1283
1290
|
const [ratingCounts, setRatingCounts] = useState(
|
|
1284
1291
|
() => ({ LOVE: parsed.rating?.counts?.LOVE ?? 0, LIKE: parsed.rating?.counts?.LIKE ?? 0, DISLIKE: parsed.rating?.counts?.DISLIKE ?? 0 })
|
|
1285
1292
|
);
|
|
@@ -1322,6 +1329,24 @@ function Video({
|
|
|
1322
1329
|
const [isFullscreen, setIsFullscreen] = useState(false);
|
|
1323
1330
|
const [playerHeight, setPlayerHeight] = useState(0);
|
|
1324
1331
|
const [playerWidth, setPlayerWidth] = useState(0);
|
|
1332
|
+
useEffect(() => {
|
|
1333
|
+
const urls = parsed.thumbnailUrls;
|
|
1334
|
+
if (!urls || Object.keys(urls).length === 0) {
|
|
1335
|
+
setPoster(parsed.thumbnailSrc ?? void 0);
|
|
1336
|
+
return;
|
|
1337
|
+
}
|
|
1338
|
+
const sorted = Object.entries(urls).map(([label, url]) => ({ px: parseInt(label.replace("w", ""), 10) || 0, url })).filter((e) => e.px > 0).sort((a, b) => a.px - b.px);
|
|
1339
|
+
if (sorted.length === 0) {
|
|
1340
|
+
setPoster(parsed.thumbnailSrc ?? void 0);
|
|
1341
|
+
return;
|
|
1342
|
+
}
|
|
1343
|
+
const dpr = typeof window !== "undefined" ? window.devicePixelRatio ?? 1 : 1;
|
|
1344
|
+
const conn = typeof navigator !== "undefined" ? navigator.connection : null;
|
|
1345
|
+
const connFactor = conn?.effectiveType === "4g" ? 1 : conn?.effectiveType === "3g" ? 0.5 : 0.25;
|
|
1346
|
+
const targetPx = (playerWidth || 640) * dpr * (conn ? connFactor : 1);
|
|
1347
|
+
const best = sorted.find((e) => e.px >= targetPx) ?? sorted[sorted.length - 1];
|
|
1348
|
+
setPoster(best.url);
|
|
1349
|
+
}, [parsed.thumbnailUrls, parsed.thumbnailSrc, playerWidth]);
|
|
1325
1350
|
const activeSource = parsed.sources[sourceIndex] ?? parsed.sources[0] ?? null;
|
|
1326
1351
|
const progressPercent = duration ? currentTime / duration * 100 : 0;
|
|
1327
1352
|
const bufferedPercent = duration ? bufferedTime / duration * 100 : 0;
|
|
@@ -1570,40 +1595,71 @@ function Video({
|
|
|
1570
1595
|
async function loadStoryboard() {
|
|
1571
1596
|
if (!parsed.storyboard) {
|
|
1572
1597
|
setStoryboardCues([]);
|
|
1598
|
+
setActiveStoryboardRes(null);
|
|
1573
1599
|
return;
|
|
1574
1600
|
}
|
|
1575
1601
|
if (parsed.storyboard.frames.length > 0) {
|
|
1576
1602
|
setStoryboardCues(parsed.storyboard.frames);
|
|
1577
1603
|
return;
|
|
1578
1604
|
}
|
|
1605
|
+
const resolutions = parsed.storyboard.resolutions;
|
|
1606
|
+
if (resolutions && Object.keys(resolutions).length > 0) {
|
|
1607
|
+
storyboardCacheRef.current.clear();
|
|
1608
|
+
preloadedSpritesRef.current.clear();
|
|
1609
|
+
const RES_ORDER = ["180p", "240p", "360p", "480p", "default"];
|
|
1610
|
+
const keys = Object.keys(resolutions).sort((a, b) => {
|
|
1611
|
+
const ai = RES_ORDER.indexOf(a);
|
|
1612
|
+
const bi = RES_ORDER.indexOf(b);
|
|
1613
|
+
return (ai === -1 ? 99 : ai) - (bi === -1 ? 99 : bi);
|
|
1614
|
+
});
|
|
1615
|
+
const loadRes = async (key) => {
|
|
1616
|
+
if (cancelled) return;
|
|
1617
|
+
const res = resolutions[key];
|
|
1618
|
+
if (!res) return;
|
|
1619
|
+
let cues = [];
|
|
1620
|
+
if (res.vttText) {
|
|
1621
|
+
cues = parseStoryboardVtt(res.vttText, res.spriteUrl);
|
|
1622
|
+
} else {
|
|
1623
|
+
cues = [{ start: 0, end: Number.MAX_SAFE_INTEGER, image: res.spriteUrl, w: res.tileW, h: res.tileH }];
|
|
1624
|
+
}
|
|
1625
|
+
storyboardCacheRef.current.set(key, cues);
|
|
1626
|
+
if (!preloadedSpritesRef.current.has(res.spriteUrl)) {
|
|
1627
|
+
preloadedSpritesRef.current.add(res.spriteUrl);
|
|
1628
|
+
const img = new window.Image();
|
|
1629
|
+
img.src = res.spriteUrl;
|
|
1630
|
+
}
|
|
1631
|
+
return cues;
|
|
1632
|
+
};
|
|
1633
|
+
const firstKey = keys[0];
|
|
1634
|
+
const firstCues = await loadRes(firstKey);
|
|
1635
|
+
if (!cancelled && firstCues) {
|
|
1636
|
+
setStoryboardCues(firstCues);
|
|
1637
|
+
setActiveStoryboardRes(firstKey);
|
|
1638
|
+
}
|
|
1639
|
+
for (const key of keys.slice(1)) {
|
|
1640
|
+
await loadRes(key);
|
|
1641
|
+
}
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1579
1644
|
if (!parsed.storyboard.src) {
|
|
1580
1645
|
setStoryboardCues([]);
|
|
1581
1646
|
return;
|
|
1582
1647
|
}
|
|
1583
1648
|
try {
|
|
1584
1649
|
const response = await fetch(parsed.storyboard.src);
|
|
1585
|
-
if (!response.ok)
|
|
1586
|
-
throw new Error("Storyboard not found");
|
|
1587
|
-
}
|
|
1650
|
+
if (!response.ok) throw new Error("Storyboard not found");
|
|
1588
1651
|
const text = await response.text();
|
|
1589
|
-
const cues = parseStoryboardVtt(
|
|
1590
|
-
|
|
1591
|
-
new URL(parsed.storyboard.src, window.location.href).href
|
|
1592
|
-
);
|
|
1593
|
-
if (!cancelled) {
|
|
1594
|
-
setStoryboardCues(cues);
|
|
1595
|
-
}
|
|
1652
|
+
const cues = parseStoryboardVtt(text, new URL(parsed.storyboard.src, window.location.href).href);
|
|
1653
|
+
if (!cancelled) setStoryboardCues(cues);
|
|
1596
1654
|
} catch {
|
|
1597
1655
|
if (!cancelled && parsed.storyboard.fallbackImage) {
|
|
1598
|
-
setStoryboardCues([
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
}
|
|
1606
|
-
]);
|
|
1656
|
+
setStoryboardCues([{
|
|
1657
|
+
start: 0,
|
|
1658
|
+
end: Number.MAX_SAFE_INTEGER,
|
|
1659
|
+
image: parsed.storyboard.fallbackImage,
|
|
1660
|
+
w: parsed.storyboard.width ?? 160,
|
|
1661
|
+
h: parsed.storyboard.height ?? 90
|
|
1662
|
+
}]);
|
|
1607
1663
|
}
|
|
1608
1664
|
}
|
|
1609
1665
|
}
|
|
@@ -1914,6 +1970,63 @@ function Video({
|
|
|
1914
1970
|
},
|
|
1915
1971
|
[duration]
|
|
1916
1972
|
);
|
|
1973
|
+
const upgradeStoryboardResolution = useCallback((hoverTime) => {
|
|
1974
|
+
const resolutions = parsed.storyboard?.resolutions;
|
|
1975
|
+
if (!resolutions || storyboardCacheRef.current.size === 0) return;
|
|
1976
|
+
const RES_ORDER = ["480p", "360p", "240p", "180p", "default"];
|
|
1977
|
+
const conn = typeof navigator !== "undefined" ? navigator.connection : null;
|
|
1978
|
+
const maxRes = conn?.effectiveType === "2g" ? "180p" : conn?.effectiveType === "3g" ? "240p" : "480p";
|
|
1979
|
+
const maxIdx = RES_ORDER.indexOf(maxRes);
|
|
1980
|
+
for (let i = 0; i <= maxIdx; i++) {
|
|
1981
|
+
const key = RES_ORDER[i];
|
|
1982
|
+
if (storyboardCacheRef.current.has(key)) {
|
|
1983
|
+
if (activeStoryboardRes !== key) {
|
|
1984
|
+
setStoryboardCues(storyboardCacheRef.current.get(key));
|
|
1985
|
+
setActiveStoryboardRes(key);
|
|
1986
|
+
const spriteUrl = resolutions[key]?.spriteUrl;
|
|
1987
|
+
if (spriteUrl && !preloadedSpritesRef.current.has(spriteUrl)) {
|
|
1988
|
+
preloadedSpritesRef.current.add(spriteUrl);
|
|
1989
|
+
const img = new window.Image();
|
|
1990
|
+
img.src = spriteUrl;
|
|
1991
|
+
}
|
|
1992
|
+
}
|
|
1993
|
+
break;
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
const bestKey = [...storyboardCacheRef.current.keys()].sort((a, b) => {
|
|
1997
|
+
const order = ["480p", "360p", "240p", "180p", "default"];
|
|
1998
|
+
return order.indexOf(a) - order.indexOf(b);
|
|
1999
|
+
})[0];
|
|
2000
|
+
if (bestKey) {
|
|
2001
|
+
const cues = storyboardCacheRef.current.get(bestKey) ?? [];
|
|
2002
|
+
const nearIdx = cues.findIndex((c) => c.start > hoverTime);
|
|
2003
|
+
const window2 = cues.slice(Math.max(0, nearIdx - 2), nearIdx + 3);
|
|
2004
|
+
for (const c of window2) {
|
|
2005
|
+
if (!preloadedSpritesRef.current.has(c.image)) {
|
|
2006
|
+
preloadedSpritesRef.current.add(c.image);
|
|
2007
|
+
const img = new window.Image();
|
|
2008
|
+
img.src = c.image;
|
|
2009
|
+
}
|
|
2010
|
+
}
|
|
2011
|
+
}
|
|
2012
|
+
}, [parsed.storyboard?.resolutions, activeStoryboardRes]);
|
|
2013
|
+
useEffect(() => {
|
|
2014
|
+
const resolutions = parsed.storyboard?.resolutions;
|
|
2015
|
+
if (!resolutions || storyboardCacheRef.current.size === 0 || !duration) return;
|
|
2016
|
+
const RES_ORDER = ["180p", "240p", "360p", "480p", "default"];
|
|
2017
|
+
const lowestKey = RES_ORDER.find((k) => storyboardCacheRef.current.has(k));
|
|
2018
|
+
if (!lowestKey) return;
|
|
2019
|
+
const cues = storyboardCacheRef.current.get(lowestKey) ?? [];
|
|
2020
|
+
const playheadIdx = cues.findIndex((c) => c.start > currentTime);
|
|
2021
|
+
const nearby = cues.slice(Math.max(0, playheadIdx - 2), playheadIdx + 6);
|
|
2022
|
+
for (const c of nearby) {
|
|
2023
|
+
if (!preloadedSpritesRef.current.has(c.image)) {
|
|
2024
|
+
preloadedSpritesRef.current.add(c.image);
|
|
2025
|
+
const img = new window.Image();
|
|
2026
|
+
img.src = c.image;
|
|
2027
|
+
}
|
|
2028
|
+
}
|
|
2029
|
+
}, [Math.floor(currentTime / 10), parsed.storyboard?.resolutions, duration]);
|
|
1917
2030
|
const updatePreview = useCallback(
|
|
1918
2031
|
(clientX) => {
|
|
1919
2032
|
const progress = progressRef.current;
|
|
@@ -1924,6 +2037,7 @@ function Video({
|
|
|
1924
2037
|
const rect = progress.getBoundingClientRect();
|
|
1925
2038
|
const x = Math.max(0, Math.min(clientX - rect.left, rect.width));
|
|
1926
2039
|
const time = x / rect.width * duration;
|
|
2040
|
+
upgradeStoryboardResolution(time);
|
|
1927
2041
|
const cue = findStoryboardCue(storyboardCues, time);
|
|
1928
2042
|
if (!cue) {
|
|
1929
2043
|
setPreview(null);
|
|
@@ -1935,7 +2049,7 @@ function Video({
|
|
|
1935
2049
|
left: Math.max(80, Math.min(x, rect.width - 80))
|
|
1936
2050
|
});
|
|
1937
2051
|
},
|
|
1938
|
-
[duration, storyboardCues]
|
|
2052
|
+
[duration, storyboardCues, upgradeStoryboardResolution]
|
|
1939
2053
|
);
|
|
1940
2054
|
const handleProgressPointerMove = useCallback(
|
|
1941
2055
|
(event) => {
|
|
@@ -1949,8 +2063,19 @@ function Video({
|
|
|
1949
2063
|
}, []);
|
|
1950
2064
|
const handleProgressPointerLeave = useCallback(() => {
|
|
1951
2065
|
setIsHoveringProgress(false);
|
|
1952
|
-
if (!isDragging)
|
|
1953
|
-
|
|
2066
|
+
if (!isDragging) {
|
|
2067
|
+
setPreview(null);
|
|
2068
|
+
const resolutions = parsed.storyboard?.resolutions;
|
|
2069
|
+
if (resolutions && storyboardCacheRef.current.size > 0) {
|
|
2070
|
+
const RES_ORDER = ["180p", "240p", "360p", "480p", "default"];
|
|
2071
|
+
const lowestKey = RES_ORDER.find((k) => storyboardCacheRef.current.has(k));
|
|
2072
|
+
if (lowestKey && activeStoryboardRes !== lowestKey) {
|
|
2073
|
+
setStoryboardCues(storyboardCacheRef.current.get(lowestKey));
|
|
2074
|
+
setActiveStoryboardRes(lowestKey);
|
|
2075
|
+
}
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
}, [isDragging, parsed.storyboard?.resolutions, activeStoryboardRes]);
|
|
1954
2079
|
const handleProgressPointerDown = useCallback(
|
|
1955
2080
|
(event) => {
|
|
1956
2081
|
const progress = progressRef.current;
|
|
@@ -3099,7 +3224,8 @@ function parseVideoChildren(children) {
|
|
|
3099
3224
|
}
|
|
3100
3225
|
if (child.type === VideoThumbnail || name === "SiloVideoThumbnail") {
|
|
3101
3226
|
const element = child;
|
|
3102
|
-
parsed.
|
|
3227
|
+
if (element.props.urls) parsed.thumbnailUrls = element.props.urls;
|
|
3228
|
+
if (element.props.src) parsed.thumbnailSrc = element.props.src;
|
|
3103
3229
|
}
|
|
3104
3230
|
if (child.type === AgeRating || name === "SiloAgeRating") {
|
|
3105
3231
|
const element = child;
|
|
@@ -3122,15 +3248,10 @@ function parseVideoChildren(children) {
|
|
|
3122
3248
|
});
|
|
3123
3249
|
parsed.storyboard = {
|
|
3124
3250
|
...element.props.src !== void 0 && { src: element.props.src },
|
|
3125
|
-
...element.props.fallbackImage !== void 0 && {
|
|
3126
|
-
|
|
3127
|
-
},
|
|
3128
|
-
...element.props.
|
|
3129
|
-
width: element.props.width
|
|
3130
|
-
},
|
|
3131
|
-
...element.props.height !== void 0 && {
|
|
3132
|
-
height: element.props.height
|
|
3133
|
-
},
|
|
3251
|
+
...element.props.fallbackImage !== void 0 && { fallbackImage: element.props.fallbackImage },
|
|
3252
|
+
...element.props.width !== void 0 && { width: element.props.width },
|
|
3253
|
+
...element.props.height !== void 0 && { height: element.props.height },
|
|
3254
|
+
...element.props.resolutions !== void 0 && { resolutions: element.props.resolutions },
|
|
3134
3255
|
frames
|
|
3135
3256
|
};
|
|
3136
3257
|
}
|