Files
v10/dist/dev/ui/thumbnail/thumbnail.js

82 lines
2.9 KiB
JavaScript

"use client";
import { useOptionalPlayer } from "../../player/context.js";
import { useDestroy } from "../../utils/use-destroy.js";
import { renderElement } from "../../utils/use-render.js";
import { createThumbnail, selectTextTrack } from "@videojs/core/dom";
import { forwardRef, useMemo, useRef, useState } from "react";
import { jsx } from "react/jsx-runtime";
import { ThumbnailCore, ThumbnailDataAttrs, mapCuesToThumbnails } from "@videojs/core";
//#region src/ui/thumbnail/thumbnail.tsx
const Thumbnail = forwardRef(function Thumbnail(componentProps, forwardedRef) {
const { render, className, style, time = 0, thumbnails: externalThumbnails, crossOrigin, loading, fetchPriority, ...elementProps } = componentProps;
const [core] = useState(() => new ThumbnailCore());
const divRef = useRef(null);
const imgRef = useRef(null);
const textTrack = useOptionalPlayer(selectTextTrack);
const [, setRenderToken] = useState(0);
const [handle] = useState(() => createThumbnail({
getContainer: () => divRef.current,
getImg: () => imgRef.current,
onStateChange: () => setRenderToken((n) => n + 1)
}));
useDestroy(handle, () => handle.connect());
const thumbnails = useMemo(() => {
if (externalThumbnails && externalThumbnails.length > 0) return externalThumbnails;
return textTrack && textTrack.thumbnailCues.length > 0 ? mapCuesToThumbnails(textTrack.thumbnailCues, textTrack.thumbnailTrackSrc ?? void 0) : [];
}, [externalThumbnails, textTrack]);
const thumbnail = useMemo(() => core.findActiveThumbnail(thumbnails, time), [
core,
thumbnails,
time
]);
handle.updateSrc(thumbnail?.url);
const state = core.getState(handle.loading, handle.error, thumbnail);
let containerStyle = { overflow: "hidden" };
let imgStyle;
if (thumbnail && handle.naturalWidth && handle.naturalHeight) {
const constraints = handle.readConstraints();
const result = core.resize(thumbnail, handle.naturalWidth, handle.naturalHeight, constraints);
if (result) {
containerStyle = {
overflow: "hidden",
width: result.containerWidth,
height: result.containerHeight
};
imgStyle = {
width: result.imageWidth,
height: result.imageHeight,
maxWidth: "none",
transform: result.offsetX || result.offsetY ? `translate(-${result.offsetX}px, -${result.offsetY}px)` : void 0
};
}
}
return renderElement("div", {
render,
className,
style
}, {
state,
stateAttrMap: ThumbnailDataAttrs,
ref: [forwardedRef, divRef],
props: [
core.getAttrs(state),
{ style: containerStyle },
elementProps,
{ children: /* @__PURE__ */ jsx("img", {
ref: imgRef,
alt: "",
"aria-hidden": "true",
decoding: "async",
src: thumbnail?.url,
crossOrigin: crossOrigin === "" || crossOrigin === null ? void 0 : crossOrigin,
loading,
style: imgStyle,
fetchPriority
}) }
]
});
});
//#endregion
export { Thumbnail };
//# sourceMappingURL=thumbnail.js.map