@strawbinary-io/api-video-strapi-5-plugin
Version:
A powerful Strapi plugin to easily manage your videos and integrate them in your project
1,535 lines • 62.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const jsxRuntime = require("react/jsx-runtime");
const reactRouterDom = require("react-router-dom");
const admin = require("@strapi/strapi/admin");
require("react-dom/client");
const React = require("react");
const designSystem = require("@strapi/design-system");
const icons = require("@strapi/icons");
const rulesEngine = require("./rulesEngine-B1IxUHbK.js");
require("@strapi/icons/symbols");
const reactIntl = require("react-intl");
const getTranslation = require("./getTranslation-DdmT3Dfz.js");
const privateVideoSession = require("@api.video/private-video-session");
const index = require("./index-m2iLaGni.js");
const index$1 = require("./index-DcHw4rkp.js");
const videoUploader = require("@api.video/video-uploader");
const styled = require("styled-components");
const ApiVideoReactPlayer = require("@api.video/react-player");
const _interopDefault = (e) => e && e.__esModule ? e : { default: e };
const styled__default = /* @__PURE__ */ _interopDefault(styled);
const ApiVideoReactPlayer__default = /* @__PURE__ */ _interopDefault(ApiVideoReactPlayer);
const assetsRequests = {
getAllvideos: async () => {
const { get } = admin.getFetchClient();
return await get(`/${index.PLUGIN_ID}/api-video-asset`);
},
getToken: async (videoId) => {
const { get } = admin.getFetchClient();
return await get(`/${index.PLUGIN_ID}/api-video-asset/token/${videoId}`);
},
createVideoId: async (body) => {
const { post } = admin.getFetchClient();
return await post(`/${index.PLUGIN_ID}/api-video-asset/create`, {
body
});
},
create: async (body) => {
const { post } = admin.getFetchClient();
return await post(`/${index.PLUGIN_ID}/api-video-asset`, {
body
});
},
update: async (id, videoId, body) => {
const { put } = admin.getFetchClient();
return await put(`/${index.PLUGIN_ID}/api-video-asset/${id}/${videoId}`, {
body
});
},
delete: async (id, videoId) => {
const { del } = admin.getFetchClient();
return await del(`/${index.PLUGIN_ID}/api-video-asset/${id}/${videoId}`);
}
};
const UploadButton = ({
currentFile,
title,
description,
_public,
tags,
metadata,
update,
close
}) => {
const [progress, setProgress] = React.useState(0);
const [isUploading, setIsUploading] = React.useState(false);
const uploadIsDisabled = currentFile === void 0 || title.trim().length < 1 || description.trim().length < 1;
const { toggleNotification } = admin.useNotification();
const fileInputChange = async () => {
const body = {
title,
description,
_public,
tags,
metadata
};
const { data } = await assetsRequests.createVideoId(body);
if (currentFile) {
setIsUploading(true);
const uploader = new videoUploader.VideoUploader({
file: currentFile,
accessToken: data.token?.accessToken,
refreshToken: data.token?.refreshToken,
videoId: data.newVideo?.videoId
});
try {
uploader.onProgress((e) => setProgress(Math.round(e.uploadedBytes * 100 / e.totalBytes)));
const res = await uploader.upload();
const body2 = {
title: res.title,
description: res.description,
_public: res._public,
videoId: res.videoId,
hls: res.assets.hls,
iframe: res.assets.iframe,
mp4: res?.assets?.mp4,
player: res.assets.player,
thumbnail: res?.assets?.thumbnail,
tags: res.tags,
metadata: res.metadata
};
const data2 = await assetsRequests.create(body2);
if (data2) {
setIsUploading(false);
update();
} else {
toggleNotification({
type: "warning",
message: "Error while creating video"
});
}
} catch (e) {
console.error(e);
}
close();
}
};
return /* @__PURE__ */ jsxRuntime.jsx(
designSystem.Button,
{
endIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.CloudUpload, {}),
loading: isUploading,
onClick: fileInputChange,
disabled: uploadIsDisabled,
children: isUploading ? `Uploading ${progress}%` : `Upload`
}
);
};
const VideoCover = () => {
return /* @__PURE__ */ jsxRuntime.jsxs(
"svg",
{
xmlns: "http://www.w3.org/2000/svg",
"data-name": "Layer 1",
width: "249",
height: "150",
viewBox: "0 0 1008.92047 607.45001",
children: [
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M1104.46,620.305a15.34,15.34,0,0,1-15.25958,15.42H417.8a15.34,15.34,0,0,1-15.26-15.41962V161.695a15.34,15.34,0,0,1,15.25957-15.42H1089.2a15.34,15.34,0,0,1,15.26,15.41959v.00043Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M1096.54,612.795a14.91,14.91,0,0,1-14.91,14.91H425.83a14.91,14.91,0,0,1-14.91-14.91V169.415a14.91,14.91,0,0,1,14.91-14.91h655.83a14.91,14.91,0,0,1,14.88,14.91Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
id: "b9c54412-061c-4155-b289-fb4c23e4a64e-1077",
"data-name": "c6fe725a-3b03-4a96-90af-cfbd2676500a",
d: "M350.43023,27.48h616.22a8.85,8.85,0,0,1,8.85,8.85V451.61a8.85,8.85,0,0,1-8.85,8.85h-616.22a8.85,8.85,0,0,1-8.85-8.85V36.33a8.85,8.85,0,0,1,8.85-8.85Z",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M358.23023,37.44h599.95a8.85,8.85,0,0,1,8.85,8.85V439.41a8.85,8.85,0,0,1-8.85,8.85h-599.95a8.85,8.85,0,0,1-8.85-8.85V46.29A8.85,8.85,0,0,1,358.23023,37.44Z",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M877.37572,456.8078a16.86941,16.86941,0,0,1-6.85316-1.46024,8.31363,8.31363,0,0,1-1.42861-.81184l-43.60186-30.69158h0a16.86934,16.86934,0,0,1-7.15892-13.79065V368.19654a16.86933,16.86933,0,0,1,7.1589-13.79066l43.60186-30.69158a8.31367,8.31367,0,0,1,1.42862-.81183A16.86929,16.86929,0,0,1,894.245,338.31679V439.93323a16.8693,16.8693,0,0,1-16.8693,16.8693Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#3f3d56"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M779.7948,465.03685H658.187c-24.81022-.02033-44.91651-16.0578-44.942-35.84726V349.06042c.0255-19.78946,20.13179-35.82692,44.942-35.84726H780.112c24.63351.02325,44.59564,15.94572,44.62477,35.59423v80.3822C824.71131,448.97905,804.605,465.01652,779.7948,465.03685Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#3f3d56"
}
),
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "900.87945", cy: "386.81368", r: "36.16732", fill: "#e6e6e6" }),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M1015.20446,532.44038l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483l28.82923-16.64456a.74859.74859,0,0,0,0-1.2966l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483l28.82923-16.64456A.74859.74859,0,0,0,1015.20446,532.44038Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M949.46,675.305a15.34,15.34,0,0,1-15.25958,15.42H262.8a15.34,15.34,0,0,1-15.26-15.41962V216.695a15.34,15.34,0,0,1,15.25957-15.42H934.2a15.34,15.34,0,0,1,15.26,15.41959v.00043Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M941.54,667.795a14.91,14.91,0,0,1-14.91,14.91H270.83a14.91,14.91,0,0,1-14.91-14.91V224.415a14.91,14.91,0,0,1,14.91-14.91H926.66a14.91,14.91,0,0,1,14.88,14.91Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
id: "a7242049-80b4-49e1-bd08-67354734c824-1078",
"data-name": "c6fe725a-3b03-4a96-90af-cfbd2676500a",
d: "M195.43022,82.48h616.22a8.85,8.85,0,0,1,8.85,8.85V506.61a8.85,8.85,0,0,1-8.85,8.85h-616.22a8.85,8.85,0,0,1-8.85-8.85V91.33a8.85,8.85,0,0,1,8.85-8.85Z",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M203.23023,92.44h599.95a8.85,8.85,0,0,1,8.85,8.85V494.41a8.85,8.85,0,0,1-8.85,8.85h-599.95a8.85,8.85,0,0,1-8.85-8.85V101.29A8.85,8.85,0,0,1,203.23023,92.44Z",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M722.37572,511.8078a16.86941,16.86941,0,0,1-6.85316-1.46024,8.31363,8.31363,0,0,1-1.42861-.81184l-43.60186-30.69158h0a16.86934,16.86934,0,0,1-7.15892-13.79065V423.19654a16.86933,16.86933,0,0,1,7.1589-13.79066l43.60186-30.69158a8.31367,8.31367,0,0,1,1.42862-.81183A16.86929,16.86929,0,0,1,739.245,393.31679V494.93323a16.8693,16.8693,0,0,1-16.8693,16.8693Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#3f3d56"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M624.7948,520.03685H503.187c-24.81022-.02033-44.91651-16.0578-44.942-35.84726V404.06042c.0255-19.78946,20.13179-35.82692,44.942-35.84726H625.112c24.63351.02325,44.59564,15.94572,44.62477,35.59423v80.3822C669.71131,503.97905,649.605,520.01652,624.7948,520.03685Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#3f3d56"
}
),
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "745.87945", cy: "441.81368", r: "36.16732", fill: "#e6e6e6" }),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M860.20446,587.44038l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483L860.20446,588.737a.74859.74859,0,0,0,0-1.2966l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483L860.20446,588.737A.74859.74859,0,0,0,860.20446,587.44038Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M797.46,738.305a15.34,15.34,0,0,1-15.25958,15.42H110.8a15.34,15.34,0,0,1-15.26-15.41962V279.695a15.34,15.34,0,0,1,15.25957-15.42H782.2a15.34,15.34,0,0,1,15.26,15.41959v.00043Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M789.54,730.795a14.91,14.91,0,0,1-14.91,14.91H118.83a14.91,14.91,0,0,1-14.91-14.91V287.415a14.91,14.91,0,0,1,14.91-14.91H774.66a14.91,14.91,0,0,1,14.88,14.91Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
id: "b7a050eb-0cb2-44a8-b642-35d340850eff-1079",
"data-name": "c6fe725a-3b03-4a96-90af-cfbd2676500a",
d: "M43.43022,145.48h616.22a8.85,8.85,0,0,1,8.85,8.85V569.61a8.85,8.85,0,0,1-8.85,8.85h-616.22a8.85,8.85,0,0,1-8.85-8.85V154.33a8.85,8.85,0,0,1,8.85-8.85Z",
fill: "#e6e6e6"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M51.23023,155.44h599.95a8.85,8.85,0,0,1,8.85,8.85V557.41a8.85,8.85,0,0,1-8.85,8.85h-599.95a8.85,8.85,0,0,1-8.85-8.85V164.29A8.85,8.85,0,0,1,51.23023,155.44Z",
fill: "#fff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M570.37572,574.8078a16.86941,16.86941,0,0,1-6.85316-1.46024,8.31363,8.31363,0,0,1-1.42861-.81184l-43.60186-30.69158h0a16.86934,16.86934,0,0,1-7.15892-13.79065V486.19654a16.86933,16.86933,0,0,1,7.1589-13.79066l43.60186-30.69158a8.31367,8.31367,0,0,1,1.42862-.81183A16.86929,16.86929,0,0,1,587.245,456.31679V557.93323a16.8693,16.8693,0,0,1-16.8693,16.8693Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#6c63ff"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M472.7948,583.03685H351.187c-24.81022-.02033-44.91651-16.0578-44.942-35.84726V467.06042c.0255-19.78946,20.13179-35.82692,44.942-35.84726H473.112c24.63351.02325,44.59564,15.94572,44.62477,35.59423v80.3822C517.71131,566.97905,497.605,583.01652,472.7948,583.03685Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#6c63ff"
}
),
/* @__PURE__ */ jsxRuntime.jsx("circle", { cx: "593.87945", cy: "504.81368", r: "36.16732", fill: "#3f3d56" }),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M708.20446,650.44038l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483L708.20446,651.737a.74859.74859,0,0,0,0-1.2966l-28.82923-16.64457a.7486.7486,0,0,0-1.12289.6483v33.28913a.74859.74859,0,0,0,1.12289.6483L708.20446,651.737A.74859.74859,0,0,0,708.20446,650.44038Z",
transform: "translate(-95.53976 -146.27499)",
fill: "#fff"
}
)
]
}
);
};
function useTheme() {
const [theme, setTheme] = React.useState("dark");
React.useEffect(() => {
if (window && window.localStorage) setTheme(window.localStorage?.STRAPI_THEME);
}, []);
return theme;
}
const ImportZone = React.forwardRef(
({ initialState, onFileSelected }, ref) => {
const localVideoRef = React.useRef(null);
const localSourceRef = React.useRef(null);
React.useImperativeHandle(ref, () => ({
video: localVideoRef.current,
source: localSourceRef.current
}));
const inputFile = React.useRef(null);
const { toggleNotification } = admin.useNotification();
const { formatMessage } = reactIntl.useIntl();
const [file, setFile] = React.useState();
const theme = useTheme();
const openFilePicker = () => {
if (file) {
setFile(void 0);
}
inputFile && inputFile?.current?.click();
};
const fileInputChange = async (e) => {
const { files } = e.target;
if (files && files.length > 0) {
onFileSelected(files[0]);
}
};
const onFileDrop = async (ev) => {
ev.preventDefault();
let file2 = null;
if (ev.dataTransfer.items) {
if (ev.dataTransfer.items.length > 1) {
toggleNotification({
type: "warning",
message: formatMessage({
id: getTranslation.getTranslation("importZone.onlyOneFile"),
defaultMessage: "Only one file is allowed"
})
});
return;
}
const item = ev.dataTransfer.items[0];
if (item.kind === "file") {
file2 = item.getAsFile();
}
} else if (ev.dataTransfer.files) {
if (ev.dataTransfer.files.length > 1) {
toggleNotification({
type: "warning",
message: formatMessage({
id: getTranslation.getTranslation("importZone.onlyOneFile"),
defaultMessage: "Only one file is allowed"
})
});
return;
}
file2 = ev.dataTransfer.files[0];
}
if (file2) {
if (!file2.type.startsWith("video/")) {
toggleNotification({
type: "warning",
message: formatMessage({
id: getTranslation.getTranslation("importZone.onlyVideo"),
defaultMessage: "Only video files are allowed"
})
});
return;
}
onFileSelected(file2);
}
};
return /* @__PURE__ */ jsxRuntime.jsxs(Wrapper$1, { onDrop: onFileDrop, onDragOver: (e) => e.preventDefault(), onClick: openFilePicker, children: [
initialState === 0 && /* @__PURE__ */ jsxRuntime.jsx(VideoCover, {}),
/* @__PURE__ */ jsxRuntime.jsx(ThumbnailImg, { isShowed: initialState === 1, children: /* @__PURE__ */ jsxRuntime.jsx("video", { ref: localVideoRef, children: /* @__PURE__ */ jsxRuntime.jsx("source", { ref: localSourceRef }) }) }),
/* @__PURE__ */ jsxRuntime.jsxs(Title$3, { dark: theme === "dark", children: [
formatMessage({
id: getTranslation.getTranslation("importZone.select"),
defaultMessage: "Select a video file to upload"
}),
/* @__PURE__ */ jsxRuntime.jsx(Asterisk, { children: "*" })
] }),
/* @__PURE__ */ jsxRuntime.jsx(Subtitle, { children: formatMessage({
id: getTranslation.getTranslation("importZone.orDragDrop"),
defaultMessage: "or drag and drop it here"
}) }),
/* @__PURE__ */ jsxRuntime.jsx(
"input",
{
type: "file",
id: "upload",
accept: "video/*",
ref: inputFile,
name: "upload",
onChange: (e) => fileInputChange(e),
style: { display: "none" }
}
)
] });
}
);
const UploadImage = styled__default.default.img`
width: 200px;
height: auto;
opacity: 0.4;
transition: opacity 0.4s ease-in-out;
`;
const ThumbnailImg = styled__default.default.div`
height: ${(props) => props.isShowed ? "150px" : "0px"};
border-radius: 4px;
aspect-ratio: 16 / 9;
display: flex;
justify-content: center;
visibility: ${(props) => props.isShowed ? "visible" : "hidden"};
video {
height: 100%;
border-radius: 4px;
}
`;
const Wrapper$1 = styled__default.default.div`
width: 100%;
height: 300px;
border: 1px dashed #eaeaea;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
cursor: pointer;
transition: border 0.4s ease-in-out;
margin-bottom: 20px;
&:hover {
border: 1px dashed #4642eb;
}
&:hover ${UploadImage} {
opacity: 0.8;
}
`;
const Title$3 = styled__default.default.p`
font-size: 24px;
font-weight: 600;
padding: 20px 0 10px 0;
color: ${(p) => p.dark ? "#ffffff" : "#32324d"};
`;
const Subtitle = styled__default.default.p`
font-size: 16px;
color: #666687;
`;
const Asterisk = styled__default.default.span`
color: red;
`;
const Title$2 = styled__default.default.p`
color: ${(p) => p.dark ? "#ffffff" : "#32324d"};
font-size: 12px;
font-weight: bold;
padding: 0px 0px 5px 0px;
`;
const SubTitle$1 = styled__default.default.p`
color: #666c8e;
font-size: 12px;
padding-bottom: 10px;
`;
styled__default.default.input`
border: 1px solid #eaeaef;
width: 150px;
height: 32px;
padding: 0px 12px;
border-radius: 4px;
color: #32324d;
font-size: 12px;
&:focus {
outline: none;
}
&::placeholder {
color: #cecece;
}
`;
const CustomBadge = styled__default.default(designSystem.Badge)`
margin-left: 10px;
`;
const Tags = ({ tags, handleSetTag, handleRemoveTag, editable }) => {
const [value, setValue] = React.useState("");
const theme = useTheme();
const onCreateOption = (value2) => {
if (value2) {
handleSetTag(value2);
setValue(value2);
}
};
const onClear = () => {
if (tags.find((tag) => tag === value)) {
handleRemoveTag(value);
}
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(Title$2, { dark: theme === "dark", children: [
"Tags",
/* @__PURE__ */ jsxRuntime.jsx(CustomBadge, { active: tags.length > 0, children: tags.length })
] }),
/* @__PURE__ */ jsxRuntime.jsx(SubTitle$1, { children: "A list of tags you want to use to describe your video." }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.Combobox,
{
"aria-label": "Tags",
value,
onInputChange: (e) => setValue(e.target.value),
onCreateOption,
onClear,
disabled: !editable,
creatable: true,
children: tags.map((tag, i) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.ComboboxOption, { value: tag, children: tag }, i))
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {})
] });
};
const MetadataTable = ({
metadata,
handleSetMetadata,
handleRemoveMetadata,
editable
}) => {
const [inputData, setInputData] = React.useState({
key: "",
value: ""
});
const [modalIsVisible, setModalIsVisible] = React.useState(false);
const { key, value } = inputData;
const theme = useTheme();
const clearInputData = () => setInputData({ key: "", value: "" });
const handleChange = (event) => {
const { name, value: value2 } = event.target;
setInputData((prevInputData) => ({ ...prevInputData, [name]: value2 }));
};
const saveMetadata = () => {
handleSetMetadata({
key,
value
});
closeModal();
};
const closeModal = () => {
setModalIsVisible(false);
clearInputData();
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(Title$2, { dark: theme === "dark", children: [
"Metadata",
/* @__PURE__ */ jsxRuntime.jsx(CustomBadge, { active: metadata?.length !== 0, children: metadata?.length })
] }),
/* @__PURE__ */ jsxRuntime.jsx(SubTitle$1, { children: "A list of key value pairs that you use to provide metadata for your video." }),
/* @__PURE__ */ jsxRuntime.jsxs(
designSystem.Table,
{
colCount: 5,
rowCount: 2,
footer: /* @__PURE__ */ jsxRuntime.jsx(designSystem.TFooter, { onClick: () => setModalIsVisible(true), icon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), children: "Add another metadata to this video" }),
children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Id" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Key" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Value" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: "Actions" }) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: metadata?.map((entry, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: index2 + 1 }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.key }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { style: { flex: "1" }, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: entry.value }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: editable && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
designSystem.IconButton,
{
disabled: index2 === 0,
onClick: () => handleRemoveMetadata(entry),
label: index2 === 0 ? "Default value, can't be deleted" : "Delete",
variant: "ghost",
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
}
) }) })
] }, index2)) })
]
}
),
modalIsVisible && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { onOpenChange: closeModal, open: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", variant: "beta", id: "title", children: "Video metadata" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Body, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { gap: 3, children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { grow: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { id: "metadata_key", children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Key" }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.TextInput,
{
placeholder: "Metadata key",
name: "key",
onChange: handleChange,
value: key
}
)
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { grow: "1", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { id: "metadata_value", children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "Value" }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.TextInput,
{
placeholder: "Metadata value",
name: "value",
onChange: handleChange,
value
}
)
] }) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: closeModal, variant: "tertiary", children: "Cancel" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: saveMetadata, children: "Save" })
] })
] }) })
] });
};
const AddVideoModal = ({ update, close }) => {
const [inputData, setInputData] = React.useState({
title: "",
description: "",
_public: true,
tags: [],
metadata: [
{
key: "Upload source",
value: "Strapi"
}
]
});
const [file, setFile] = React.useState();
const [initialState, setInitialState] = React.useState(0);
const { formatMessage } = reactIntl.useIntl();
const videoRef = React.useRef(null);
const sourceRef = React.useRef(null);
const { title, description, _public, tags, metadata } = inputData;
const importZoneRef = React.useRef(null);
const displayVideoFrame = (video, source, file2) => {
source.setAttribute("src", URL.createObjectURL(file2));
video.load();
};
const getSettings = async () => {
const settings = await index$1.settingsRequests.get();
setInputData({ ...inputData, _public: settings.data.defaultPublic });
};
const handleChange = (event) => {
const { name, value } = event.target;
setInputData((prevInputData) => ({ ...prevInputData, [name]: value }));
};
const handleSetPublic = (event) => {
setInputData({ ...inputData, _public: event.target.checked });
};
const handleSetTag = (tag) => {
if (tag) {
setInputData({ ...inputData, tags: [...inputData.tags || [], tag] });
}
};
const handleRemoveTag = (tag) => {
const newTags = inputData.tags && inputData.tags.filter((t) => t !== tag);
setInputData({ ...inputData, tags: newTags });
};
const handleSetMetadata = (metadata2) => {
if (metadata2) {
setInputData({
...inputData,
metadata: [...inputData.metadata || [], metadata2]
});
}
};
const handleRemoveMetadata = (metadata2) => {
const newMetadata = inputData?.metadata && inputData?.metadata.filter((m) => m !== metadata2);
setInputData({ ...inputData, metadata: newMetadata });
};
const onFileSelected = (file2) => {
const video = importZoneRef.current?.video;
const source = importZoneRef.current?.source;
if (video && source) {
displayVideoFrame(video, source, file2);
}
setFile(file2);
setInputData((prevInputData) => ({
...prevInputData,
title: file2.name.replace(/\.[^/.]+$/, "")
}));
if (initialState === 0) {
setInitialState(1);
}
if (videoRef.current && sourceRef.current)
displayVideoFrame(videoRef.current, sourceRef.current, file2);
};
React.useEffect(() => {
getSettings();
}, []);
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { onOpenChange: close, open: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", variant: "beta", id: "title", children: formatMessage({
id: getTranslation.getTranslation("addVideoModal.title"),
defaultMessage: "Upload a video"
}) }) }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
ImportZone,
{
initialState,
onFileSelected,
ref: importZoneRef
}
),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.FieldComp,
{
name: "title",
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.title"),
defaultMessage: "Title"
}),
value: title,
placeholder: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.placeholder.title"),
defaultMessage: "Enter your title"
}),
onChange: handleChange,
required: true
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.FieldComp,
{
name: "description",
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.description"),
defaultMessage: "Description"
}),
value: description || "",
placeholder: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.placeholder.description"),
defaultMessage: "Enter a description"
}),
onChange: handleChange,
required: true
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.Toggle,
{
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public"),
defaultMessage: "Public"
}),
required: true,
checked: _public,
onLabel: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public.on"),
defaultMessage: "True"
}),
offLabel: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public.off"),
defaultMessage: "False"
}),
onChange: handleSetPublic
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
Tags,
{
handleSetTag,
handleRemoveTag,
tags: tags || [],
editable: true
}
),
/* @__PURE__ */ jsxRuntime.jsx(
MetadataTable,
{
metadata,
handleSetMetadata,
handleRemoveMetadata,
editable: true
}
)
] }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: close, variant: "tertiary", children: formatMessage({
id: getTranslation.getTranslation("addVideoModal.cancel"),
defaultMessage: "Cancel"
}) }) }),
/* @__PURE__ */ jsxRuntime.jsx(
UploadButton,
{
currentFile: file,
title,
description,
_public,
tags: tags || [],
metadata: metadata || [],
update,
close
}
)
] })
] }) });
};
const AddButton = ({ update }) => {
const [isVisible, setIsVisible] = React.useState(false);
const { formatMessage } = reactIntl.useIntl();
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { endIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), onClick: () => setIsVisible(true), children: formatMessage({
id: getTranslation.getTranslation("addButton.label"),
defaultMessage: "Add a video"
}) }),
isVisible && /* @__PURE__ */ jsxRuntime.jsx(AddVideoModal, { update, close: () => setIsVisible(false) })
] });
};
const Illo = () => /* @__PURE__ */ jsxRuntime.jsxs("svg", { width: "159", height: "88", viewBox: "0 0 159 88", fill: "none", xmlns: "http://www.w3.org/2000/svg", children: [
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
fillRule: "evenodd",
clipRule: "evenodd",
d: "M134.933 17.417C137.768 17.417 140.067 19.7153 140.067 22.5503C140.067 25.3854 137.768 27.6837 134.933 27.6837H105.6C108.435 27.6837 110.733 29.9819 110.733 32.817C110.733 35.6521 108.435 37.9503 105.6 37.9503H121.733C124.568 37.9503 126.867 40.2486 126.867 43.0837C126.867 45.9187 124.568 48.217 121.733 48.217H114.272C110.698 48.217 107.8 50.5153 107.8 53.3503C107.8 55.2404 109.267 56.9515 112.2 58.4837C115.035 58.4837 117.333 60.7819 117.333 63.617C117.333 66.4521 115.035 68.7503 112.2 68.7503H51.3333C48.4982 68.7503 46.2 66.4521 46.2 63.617C46.2 60.7819 48.4982 58.4837 51.3333 58.4837H22.7333C19.8982 58.4837 17.6 56.1854 17.6 53.3503C17.6 50.5153 19.8982 48.217 22.7333 48.217H52.0666C54.9017 48.217 57.2 45.9187 57.2 43.0837C57.2 40.2486 54.9017 37.9503 52.0666 37.9503H33.7333C30.8982 37.9503 28.6 35.6521 28.6 32.817C28.6 29.9819 30.8982 27.6837 33.7333 27.6837H63.0666C60.2316 27.6837 57.9333 25.3854 57.9333 22.5503C57.9333 19.7153 60.2316 17.417 63.0666 17.417H134.933ZM134.933 37.9503C137.768 37.9503 140.067 40.2486 140.067 43.0837C140.067 45.9187 137.768 48.217 134.933 48.217C132.098 48.217 129.8 45.9187 129.8 43.0837C129.8 40.2486 132.098 37.9503 134.933 37.9503Z",
fill: "#DBDBFA"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
fillRule: "evenodd",
clipRule: "evenodd",
d: "M95.826 16.6834L102.647 66.4348L103.26 71.4261C103.458 73.034 102.314 74.4976 100.706 74.695L57.7621 79.9679C56.1542 80.1653 54.6906 79.0219 54.4932 77.4139L47.8816 23.5671C47.7829 22.7631 48.3546 22.0313 49.1586 21.9326C49.1637 21.932 49.1688 21.9313 49.1739 21.9307L52.7367 21.5311L95.826 16.6834ZM55.6176 21.208L58.9814 20.8306Z",
fill: "white"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M55.6176 21.208L58.9814 20.8306M95.826 16.6834L102.647 66.4348L103.26 71.4261C103.458 73.034 102.314 74.4976 100.706 74.695L57.7621 79.9679C56.1542 80.1653 54.6906 79.0219 54.4932 77.4139L47.8816 23.5671C47.7829 22.7631 48.3546 22.0313 49.1586 21.9326C49.1637 21.932 49.1688 21.9313 49.1739 21.9307L52.7367 21.5311L95.826 16.6834Z",
stroke: "#7E7BF6",
strokeWidth: "2.5"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
fillRule: "evenodd",
clipRule: "evenodd",
d: "M93.9695 19.8144L100.144 64.9025L100.699 69.4258C100.878 70.8831 99.8559 72.2077 98.416 72.3845L59.9585 77.1065C58.5185 77.2833 57.2062 76.2453 57.0272 74.7881L51.0506 26.112C50.9519 25.308 51.5236 24.5762 52.3276 24.4775L57.0851 23.8934",
fill: "#F0F0FF"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
fillRule: "evenodd",
clipRule: "evenodd",
d: "M97.701 7.33301H64.2927C63.7358 7.33301 63.2316 7.55873 62.8667 7.92368C62.5017 8.28862 62.276 8.79279 62.276 9.34967V65.083C62.276 65.6399 62.5017 66.1441 62.8667 66.509C63.2316 66.874 63.7358 67.0997 64.2927 67.0997H107.559C108.116 67.0997 108.62 66.874 108.985 66.509C109.35 66.1441 109.576 65.6399 109.576 65.083V19.202C109.576 18.6669 109.363 18.1537 108.985 17.7755L99.1265 7.92324C98.7484 7.54531 98.2356 7.33301 97.701 7.33301Z",
fill: "white",
stroke: "#7F7CFA",
strokeWidth: "2.5"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M98.026 8.17871V16.6833C98.026 17.8983 99.011 18.8833 100.226 18.8833H106.044",
stroke: "#807EFA",
strokeWidth: "2.5",
strokeLinecap: "round",
strokeLinejoin: "round"
}
),
/* @__PURE__ */ jsxRuntime.jsx(
"path",
{
d: "M70.1594 56.2838H89.2261M70.1594 18.8838H89.2261H70.1594ZM70.1594 27.6838H101.693H70.1594ZM70.1594 37.2171H101.693H70.1594ZM70.1594 46.7505H101.693H70.1594Z",
stroke: "#817FFA",
strokeWidth: "2.5",
strokeLinecap: "round",
strokeLinejoin: "round"
}
)
] });
const EmptyState = ({ update }) => {
const [isVisible, setIsVisible] = React.useState(false);
const { formatMessage } = reactIntl.useIntl();
return /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Box, { padding: 10, background: "neutral100", children: [
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.EmptyStateLayout,
{
icon: /* @__PURE__ */ jsxRuntime.jsx(Illo, {}),
content: formatMessage({
id: getTranslation.getTranslation("emptyState.content"),
defaultMessage: "You don't have any videos yet"
}),
action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "secondary", startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Plus, {}), onClick: () => setIsVisible(true), children: formatMessage({
id: getTranslation.getTranslation("emptyState.action"),
defaultMessage: "Add your first videos"
}) })
}
),
isVisible && /* @__PURE__ */ jsxRuntime.jsx(AddVideoModal, { update, close: () => setIsVisible(false) })
] });
};
const SearchBar = ({ clearSearch, handleSearch, search }) => {
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.SearchForm, { children: /* @__PURE__ */ jsxRuntime.jsx(
designSystem.Searchbar,
{
name: "searchbar",
onClear: clearSearch,
value: search,
onChange: (e) => handleSearch(e.target.value),
clearLabel: "Clearing the plugin search",
placeholder: "Filter by title",
children: "Searching for a plugin"
}
) });
};
const SetupNeeded = () => {
const navigate = reactRouterDom.useNavigate();
const { formatMessage } = reactIntl.useIntl();
const onSettingsClick = () => {
navigate(`/settings/${index.PLUGIN_ID}`);
};
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 10, background: "neutral100", children: /* @__PURE__ */ jsxRuntime.jsx(
designSystem.EmptyStateLayout,
{
icon: /* @__PURE__ */ jsxRuntime.jsx(Illo, {}),
content: formatMessage({
id: getTranslation.getTranslation("setupNeeded.content"),
defaultMessage: "In order for uploads to function, an administrator will need to complete the setup of this plugin by visiting the settings page. Click the button below to be taken there now."
}),
action: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "default", endIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.ArrowRight, {}), onClick: onSettingsClick, children: formatMessage({
id: getTranslation.getTranslation("setupNeeded.action"),
defaultMessage: "Go to settings"
}) })
}
) });
};
const getDayMonthYearHourDate = (dateParam) => {
const dateObject = new Date(dateParam);
const options = {
year: "numeric",
month: "short",
day: "numeric",
hour: "numeric",
minute: "numeric"
};
return dateObject.toLocaleDateString("en-GB", options);
};
const DialogDelete = ({ title, isOpen, close, deleteVideo }) => {
const { formatMessage } = reactIntl.useIntl();
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Root, { onOpenChange: close, defaultOpen: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Header, { children: formatMessage({
id: getTranslation.getTranslation("dialog.confirmation"),
defaultMessage: "Confirmation"
}) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Body, { icon: /* @__PURE__ */ jsxRuntime.jsx(icons.WarningCircle, {}), children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { direction: "column", gap: 2, children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Typography, { id: "confirm-description", textAlign: "center", children: [
formatMessage({
id: getTranslation.getTranslation("dialog.message"),
defaultMessage: "Are you sure you want to delete the video named"
}),
" ",
/* @__PURE__ */ jsxRuntime.jsx(Title$1, { children: title }),
"?"
] }) }) }) }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Dialog.Footer, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Cancel, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "tertiary", children: formatMessage({ id: getTranslation.getTranslation("dialog.cancel"), defaultMessage: "Cancel" }) }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Dialog.Action, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { fullWidth: true, startIcon: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {}), onClick: deleteVideo, variant: "danger-light", children: formatMessage({ id: getTranslation.getTranslation("dialog.confirm"), defaultMessage: "Confirm" }) }) })
] })
] }) });
};
const Title$1 = styled__default.default.span`
font-weight: bold;
`;
const UpdateButton = ({
title,
description,
_public,
tags,
metadata,
id,
videoId,
update,
close
}) => {
const [_isUploading, setIsUploading] = React.useState(false);
const { toggleNotification } = admin.useNotification();
const { formatMessage } = reactIntl.useIntl();
const updateData = async () => {
const body = {
title,
description,
_public,
tags,
metadata
};
setIsUploading(true);
try {
const data = await assetsRequests.update(id, videoId, body);
if (data) {
setIsUploading(false);
update();
close();
} else {
toggleNotification({
type: "warning",
message: "Error while creating video"
});
}
} catch (e) {
console.error(e);
}
};
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: updateData, children: formatMessage({
id: getTranslation.getTranslation("general.update"),
defaultMessage: "Update"
}) });
};
const replacePrivateVideoTokens = async (video, token) => {
if (video._public) {
return video;
}
token = token ?? (await strapi.plugin(index.PLUGIN_ID).service("api-video-asset").token(video.videoId)).token;
return {
...video,
mp4: video.mp4.replace(/token\/[\w-]+\//, `token/${token}/`),
thumbnail: video.thumbnail.replace(/token\/[\w-]+\//, `token/${token}/`),
hls: video.hls.replace(/token\/[\w-]+\//, `token/${token}/`),
iframe: video.iframe.replace(/token=[\w-]+/, `token=${token}`),
player: video.player.replace(/token=[\w-]+/, `token=${token}`)
};
};
const copyClipboard = (entryText) => {
navigator.clipboard.writeText(entryText);
};
const videoToAssets = (video) => {
const assets = {
hls: video.hls,
iframe: video.iframe,
mp4: video.mp4,
player: video.player
};
return assets;
};
const LinksTable = ({ video }) => {
const [assets, setAssets] = React.useState(
!!video?.token ? void 0 : videoToAssets(video)
);
const theme = useTheme();
const COL_COUNT = 4;
const ROW_COUNT = 2;
const isPrivate = !!video?.token;
const generateToken = async () => {
const token = (await assetsRequests.getToken(video.videoId)).data.token;
setAssets(videoToAssets(await replacePrivateVideoTokens(video, token)));
};
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(Title$2, { dark: theme === "dark", style: { marginTop: "20px" }, children: "Links" }),
isPrivate ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
/* @__PURE__ */ jsxRuntime.jsx(SubTitle$1, { children: "The URLs for assets of private videos can only be used once. To obtain new URLs, you can click on the button below to generate fresh links. Each time you access a private video through the Strapi Content API, a new set of private asset URLs will be generated." }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: () => generateToken(), children: "Generate new urls" })
] }) : /* @__PURE__ */ jsxRuntime.jsx(SubTitle$1, { children: "A list of links you can copy by clicking on the copy button." }),
assets && /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Table, { colCount: COL_COUNT, rowCount: ROW_COUNT, children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Thead, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Type" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "sigma", children: "Link" }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Th, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.VisuallyHidden, { children: "Copy" }) })
] }) }),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Tbody, { children: Object.entries(assets).map((links, index2) => /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Tr, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: links[0] }) }),
/* @__PURE__ */ jsxRuntime.jsx(
designSystem.Td,
{
style: {
flex: "1",
overflow: "hidden",
maxWidth: "50ch",
textOverflow: "ellipsis",
whiteSpace: "nowrap"
},
children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { textColor: "neutral800", children: links[1] })
}
),
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Td, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "flex-end", children: /* @__PURE__ */ jsxRuntime.jsx(
designSystem.IconButton,
{
onClick: () => copyClipboard(links[1]),
label: "Copy",
variant: "ghost",
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Link, {})
}
) }) })
] }, index2)) })
] })
] });
};
const PlayerView = ({ video }) => {
const { videoId, token, privateSession } = video;
return /* @__PURE__ */ jsxRuntime.jsx(Wrapper, { children: /* @__PURE__ */ jsxRuntime.jsx(
ApiVideoReactPlayer__default.default,
{
video: video._public ? { id: videoId } : { id: videoId, token, privateSession },
videoStyleObjectFit: "cover",
style: {
width: "auto",
height: 300,
borderRadius: 4,
overflow: "hidden"
}
}
) });
};
const Wrapper = styled__default.default.div`
border-radius: 4px;
padding-bottom: 10px;
`;
const UpdateVideoModal = ({
video,
update,
close,
editable
}) => {
const [inputData, setInputData] = React.useState({
title: video.title,
description: video.description,
_public: video._public,
tags: video.tags,
metadata: video.metadata
});
const { title, description, _public, tags, metadata } = inputData;
const { formatMessage } = reactIntl.useIntl();
const handleChange = (event) => {
const { name, value } = event.target;
setInputData((prevInputData) => ({ ...prevInputData, [name]: value }));
};
const handleSetPublic = (event) => {
setInputData({ ...inputData, _public: event.target.checked });
};
const handleSetTag = (tag) => {
if (tag) {
setInputData({ ...inputData, tags: [...inputData.tags || [], tag] });
}
};
const handleRemoveTag = (tag) => {
const newTags = inputData.tags && inputData.tags.filter((t) => t !== tag);
setInputData({ ...inputData, tags: newTags });
};
const handleSetMetadata = (metadata2) => {
if (metadata2) {
setInputData({
...inputData,
metadata: [...inputData.metadata || [], metadata2]
});
}
};
const handleRemoveMetadata = (metadata2) => {
const newMetadata = inputData?.metadata && inputData?.metadata.filter((m) => m !== metadata2);
setInputData({ ...inputData, metadata: newMetadata });
};
return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Root, { onOpenChange: close, open: true, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Header, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { fontWeight: "bold", textColor: "neutral800", variant: "beta", id: "title", children: formatMessage({
id: getTranslation.getTranslation("updateVideoModal.title"),
defaultMessage: "Update video"
}) }) }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Body, { children: [
/* @__PURE__ */ jsxRuntime.jsx(PlayerView, { video }),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.FieldComp,
{
name: "title",
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.title"),
defaultMessage: "Title"
}),
value: title,
placeholder: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.placeholder.title"),
defaultMessage: "Enter your title"
}),
onChange: handleChange,
editable,
required: true
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.FieldComp,
{
name: "description",
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.description"),
defaultMessage: "Description"
}),
value: description || "",
placeholder: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.placeholder.description"),
defaultMessage: "Enter a description"
}),
onChange: handleChange,
editable
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
index$1.Toggle,
{
label: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public"),
defaultMessage: "Public"
}),
required: true,
checked: inputData._public,
onLabel: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public.on"),
defaultMessage: "True"
}),
offLabel: formatMessage({
id: getTranslation.getTranslation("addVideoModal.field.public.off"),
defaultMessage: "False"
}),
onChange: handleSetPublic
}
),
/* @__PURE__ */ jsxRuntime.jsx("br", {}),
/* @__PURE__ */ jsxRuntime.jsx(
Tags,
{
handleSetTag,
handleRemoveTag,
tags: tags || [],
editable
}
),
/* @__PURE__ */ jsxRuntime.jsx(
MetadataTable,
{
metadata,
handleSetMetadata,
handleRemoveMetadata,
editable
}
),
/* @__PURE__ */ jsxRuntime.jsx(LinksTable, { video })
] }),
/* @__PURE__ */ jsxRuntime.jsxs(designSystem.Modal.Footer, { children: [
/* @__PURE__ */ jsxRuntime.jsx(designSystem.Modal.Close, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: close, variant: "tertiary", children: formatMessage({
id: getTranslation.getTranslation("addVideoModal.cancel"),
defaultMessage: "Cancel"
}) }) }),
editable && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsx(
UpdateButton,
{
title,
description: description || "",
_public,
tags: tags || [],
metadata: metadata || [],
id: video.documentId,
videoId: video.videoId,
update,
close
}
) })
] })
] }) });
};
styled__default.default.div`
padding: 10px;
`;
const DeleteIcon = styled__default.default(designSystem.IconButton)`
position: absolute;
bottom: 10px;
right: 10px;
display: none;
`;
const Container = styled__default.default.div`
display: flex;
flex-direction: column;
border-radius: 4px;
background: #212134;
border: 1px solid #32324d;
cursor: pointer;
box-shadow: 1px 1px 10px rgba(3, 3, 5, 0.2);
&:hover ${DeleteIcon} {
display: flex;
}
`;
const GridBroadcast = styled__default.default.div`
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-gap: 16px;
width: 100%;
padding: 20px 0;
overflow: auto;
`;
const Thumbnail = styled__default.default.img`
width: fit-content;
height: 100%;
`;
const WrapperVideo = styled__default.default.div`
display: flex;
justify-content: center;
position: relative;
width: 100%;
height: 10.25rem;
overflow: hidden;
background: repeating-conic-gradient(#181826 0% 25%, transparent 0% 50%) 50% / 20px 20px;
`;
const TitleWrapper = styled__default.default.div`
display: flex;
flex-direction: column;
padding: 8px 12px;
`;
const Title = styled__default.default.p`
font-size: 0.75rem;
line-height: 1.33;
font-weight: 600;
color: ${(p) => p.dark ? "#ffffff" : "#32324d"};
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
margin-bottom: 4px;
`;
const SubTitle = styled__default.default.p`
color: #606060;
font-size: 0.7rem;
font-style: italic;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
`;
const DateStyle = styled__default.default.p`
color: #666687;
font-size: 0.7rem;
margin-top: 10px;
`;
const VideoView = ({ video, updateData, deletable, editable }) => {
const [isModalOpen, setIsModalOpen] = React.useState(false);
const [isDeleteDialogOpen, setIsDeleteDialogOpen] = React.useState(false);
const [thumbnail, setThumbnail] = React.useState();
const theme = useTheme();
const thumbnailTimout = React.useRef(0);
React.useEffect(() => {
const fetchThumbnail = async () => {
const fetchRes = await fetch(video.thumbnail);
if (fetchRes.status === 200) {
setThumbnail(URL.createObjectURL(await fetchRes.blob()));
return;
}
thumbnailTimout.current = setTimeout(() => fetchThumbnail(), 1e3);
};
setThumbnail(void 0);
fetchThumbnail();
return () => {
setTimeout(() => {
if (thumbnailTimout.current) clearTimeout(thumbnailTimout.current);
}, 1e3);
};
}, [video]);
const deleteVideo = async () => {
await assetsRequests.delete(video.documentId, video.videoId);
setIsDeleteDialogOpen(false);
updateData();
};
const openDeleteDialog = (e) => {
e.stopPropagation();
setIsDeleteDialogOpen(true);
};
const formatedCreatedAt = getDayMonthYearHourDate(video.createdAt);
return /* @__PURE__ */ jsxRuntime.jsxs(Container, { children: [
/* @__PURE__ */ jsxRuntime.jsxs(WrapperVideo, { onClick: () => setIsModalOpen(true), children: [
thumbnail ? /* @__PURE__ */ jsxRuntime.jsx(Thumbnail, { src: thumbnail, alt: "thumbnail" }) : /* @__PURE__ */ jsxRuntime.jsx(VideoCover, {}),
deletable && /* @__PURE__ */ jsxRuntime.jsx(
DeleteIcon,
{
label: "Delete",
variant: "secondary",
onClick: openDeleteDialog,
"aria-label": "Delete",
children: /* @__PURE__ */ jsxRuntime.jsx(icons.Trash, {})
}
)
] }),
/* @__PURE__ */ jsxRuntime.jsxs(TitleWrapper, { children: [
/* @__PURE__ */ jsxRuntime.jsx(Title, { dark: theme === "dark", children: video.title }),
/* @__PURE__ */ jsxRuntime.jsx(SubTitle, { children: video.description }),
/* @__PURE__ */ jsxRuntime.jsx(DateStyle, { children: formatedCreatedAt })
] }),
isModalOpen && /* @__PURE__ */ jsxRuntime.jsx(
UpdateVideoModal,
{
video,
update: updateData,
editable,
close: () => setIsModalOpen(false)
}
),
isDeleteDialogOpen && /* @__PURE__ */ jsxRuntime.jsx(
DialogDelete,
{
title: video.title,
isOpen: isDeleteDialogOpen,
close: () => setIsDeleteDialogOpen(false),
deleteVideo
}
)
] });
};
const HomePage = () => {
const [isLoadingData, setIsLoadingData] = React.useState(true);
const [isLoadingConfiguration, setIsLoadingConfiguration] = React.useState(false);
const [isConfigurated, setIsConfigurated] = React.useState(false);
const [assets, setAssets] = React.useState([]);
const [search, setSearch] = React.useState("");
const { formatMessage } = reactIntl.useIntl();
const { allowedActions, isLoading: isLoadingPermissions } = admin.useRBAC([
{ action: `plugin::${index.PLUGIN_ID}.create`, subject: null },
{ action: `plugin::${index.PLUGIN_ID}.update`, subject: null },
{ action: `plugin::${index.PLUGIN_ID}.delete`, subject: null }
]);
const fetchData = async () => {
if (isLoadingData === false) setIsLoadingData(true);
const data = await Promise.all(
(await assetsRequests.getAllvideos()).data.map(
async (video) => {
video._public = video._public ?? true;
if (video._public) {
return video;
}
const token = (await assetsRequests.getToken(video.videoId)).data.token;
const privateSession = new privateVideoSession.PrivateVideoSession({
token,
videoId: video.videoId
});
return {
...video,
thumbnail: await privateSession.getThumbnailUrl(),
privateSession: await privateSession.getSessionToken(),
token
};
}
)
);
setIsLoadingData(false);
setAssets(data);
};
const getApiKey = async () => {
setIsLoadingConfiguration(true);
const settings = await index$1.settingsRequests.get();
setIsConfigurated(settings?.data.apiKey?.length > 0);
setIsLoadingConfiguration(false);
};
React.useEffect(() => {
fetchData();
}, []);
React.useEffect(() => {
getApiKey();
}, []);
const handleSearch = (value) => {
setSearch(value);
};
if (isLoadingConfiguration || isLoadingPermissions) return /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Loading, {});
return /* @__PURE__ */ jsxRuntime.jsxs(rulesEngine.Layouts.Root, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
rulesEngine.Layouts.BaseHeader,
{
title: formatMessage({
id: getTranslation.getTranslation("homePage.title"),
defaultMessage: "api.video uploader"
}),
subtitle: formatMessage({
id: getTranslation.getTranslation("homePage.subtitle"),
defaultMessage: "Upload to and manage your api.video library directly within Strapi"
}),
variant: "beta",
primaryAction: isConfigurated && allowedActions.canCreate && /* @__PURE__ */ jsxRuntime.jsx(AddButton, { update: fetchData })
}
),
isConfigurated ? !isLoadingData && assets?.length > 0 ? /* @__PURE__ */ jsxRuntime.jsxs(rulesEngine.Layouts.Content, { children: [
/* @__PURE__ */ jsxRuntime.jsx(
SearchBar,
{
search,
handleSearch: (query) => handleSearch(query),
clearSearch: () => setSearch("")
}
),
/* @__PURE__ */ jsxRuntime.jsx(GridBroadcast, { children: assets.filter((item) => item.title.includes(search)).map((video) => {
const { videoId } = video;
return /* @__PURE__ */ jsxRuntime.jsx(
VideoView,
{
video,
updateData: fetchData,
editable: allowedActions.canUpdate,
deletable: allowedActions.canDelete
},
videoId
);
}) })
] }) : /* @__PURE__ */ jsxRuntime.jsx(EmptyState, { update: fetchData }) : /* @__PURE__ */ jsxRuntime.jsx(SetupNeeded, {})
] });
};
const HomePage$1 = () => /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Protect, { permissions: [{ action: "plugin::api-video-strapi-5-plugin.read", subject: null }], children: /* @__PURE__ */ jsxRuntime.jsx(HomePage, {}) });
const App = () => {
return /* @__PURE__ */ jsxRuntime.jsx("div", { children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(HomePage$1, {}) }),
/* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ jsxRuntime.jsx(admin.Page.NoData, {}) })
] }) });
};
exports.default = App;