sanity-plugin-mux-input 2.12.1 → 2.13.0
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/LICENSE +1 -1
- package/README.md +133 -0
- package/dist/index.d.mts +41 -0
- package/dist/index.d.ts +41 -0
- package/dist/index.js +188 -72
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +188 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/_exports/index.ts +1 -0
- package/src/components/FileInputButton.tsx +2 -2
- package/src/components/Player.tsx +4 -3
- package/src/components/PlayerActionsMenu.tsx +4 -3
- package/src/components/UploadConfiguration.tsx +181 -4
- package/src/components/UploadPlaceholder.tsx +14 -6
- package/src/components/Uploader.tsx +54 -6
- package/src/components/VideoInBrowser.tsx +2 -7
- package/src/components/VideoPlayer.tsx +33 -6
- package/src/components/icons/Audio.tsx +13 -0
- package/src/util/types.ts +45 -0
- package/src/components/FileInputArea.tsx +0 -93
package/dist/index.mjs
CHANGED
|
@@ -1482,10 +1482,21 @@ function EditThumbnailDialog({ asset, currentTime = 0 }) {
|
|
|
1482
1482
|
}
|
|
1483
1483
|
);
|
|
1484
1484
|
}
|
|
1485
|
+
function AudioIcon(props) {
|
|
1486
|
+
return /* @__PURE__ */ jsx("svg", { xmlns: "http://www.w3.org/2000/svg", width: "1em", height: "1em", viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx(
|
|
1487
|
+
"path",
|
|
1488
|
+
{
|
|
1489
|
+
fill: "currentColor",
|
|
1490
|
+
style: { opacity: "0.65" },
|
|
1491
|
+
d: "M10.75 19q.95 0 1.6-.65t.65-1.6V13h3v-2h-4v3.875q-.275-.2-.587-.288t-.663-.087q-.95 0-1.6.65t-.65 1.6t.65 1.6t1.6.65M6 22q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z"
|
|
1492
|
+
}
|
|
1493
|
+
) });
|
|
1494
|
+
}
|
|
1485
1495
|
function VideoPlayer({
|
|
1486
1496
|
asset,
|
|
1487
1497
|
thumbnailWidth = 250,
|
|
1488
1498
|
children,
|
|
1499
|
+
hlsConfig,
|
|
1489
1500
|
...props
|
|
1490
1501
|
}) {
|
|
1491
1502
|
const client = useClient(), { dialogState } = useDialogStateContext(), isAudio = assetIsAudio(asset), muxPlayer = useRef(null), {
|
|
@@ -1511,52 +1522,79 @@ function VideoPlayer({
|
|
|
1511
1522
|
// Make it wider when forcing aspect ratio to balance with videos' rendering height (audio players overflow a bit)
|
|
1512
1523
|
props.forceAspectRatio * 1.2
|
|
1513
1524
|
) : AUDIO_ASPECT_RATIO), /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1514
|
-
/* @__PURE__ */ jsxs(
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1525
|
+
/* @__PURE__ */ jsxs(
|
|
1526
|
+
Card,
|
|
1527
|
+
{
|
|
1528
|
+
tone: "transparent",
|
|
1529
|
+
style: {
|
|
1530
|
+
aspectRatio,
|
|
1531
|
+
position: "relative",
|
|
1532
|
+
...isAudio && { display: "flex", alignItems: "flex-end" }
|
|
1533
|
+
},
|
|
1534
|
+
children: [
|
|
1535
|
+
videoSrc && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1536
|
+
isAudio && /* @__PURE__ */ jsx(
|
|
1537
|
+
AudioIcon,
|
|
1538
|
+
{
|
|
1539
|
+
style: {
|
|
1540
|
+
padding: "0.5em",
|
|
1541
|
+
width: "2.2em",
|
|
1542
|
+
height: "2.2em",
|
|
1543
|
+
position: "absolute",
|
|
1544
|
+
top: 0,
|
|
1545
|
+
left: 0,
|
|
1546
|
+
zIndex: 1
|
|
1547
|
+
}
|
|
1548
|
+
}
|
|
1549
|
+
),
|
|
1550
|
+
/* @__PURE__ */ jsx(
|
|
1551
|
+
MuxPlayer,
|
|
1552
|
+
{
|
|
1553
|
+
poster: isAudio ? void 0 : thumbnailSrc,
|
|
1554
|
+
ref: muxPlayer,
|
|
1555
|
+
...props,
|
|
1556
|
+
playsInline: !0,
|
|
1557
|
+
playbackId: asset.playbackId,
|
|
1558
|
+
tokens: signedToken ? { playback: signedToken, thumbnail: signedToken, storyboard: signedToken } : void 0,
|
|
1559
|
+
preload: "metadata",
|
|
1560
|
+
crossOrigin: "anonymous",
|
|
1561
|
+
metadata: {
|
|
1562
|
+
player_name: "Sanity Admin Dashboard",
|
|
1563
|
+
player_version: "2.13.0",
|
|
1564
|
+
page_type: "Preview Player"
|
|
1565
|
+
},
|
|
1566
|
+
audio: isAudio,
|
|
1567
|
+
_hlsConfig: hlsConfig,
|
|
1568
|
+
style: {
|
|
1569
|
+
...!isAudio && { height: "100%" },
|
|
1570
|
+
width: "100%",
|
|
1571
|
+
display: "block",
|
|
1572
|
+
objectFit: "contain",
|
|
1573
|
+
...isAudio && { alignSelf: "end" }
|
|
1574
|
+
}
|
|
1575
|
+
}
|
|
1576
|
+
),
|
|
1577
|
+
children
|
|
1578
|
+
] }),
|
|
1579
|
+
error ? /* @__PURE__ */ jsx(
|
|
1580
|
+
"div",
|
|
1581
|
+
{
|
|
1582
|
+
style: {
|
|
1583
|
+
position: "absolute",
|
|
1584
|
+
top: "50%",
|
|
1585
|
+
left: "50%",
|
|
1586
|
+
transform: "translate(-50%, -50%)"
|
|
1587
|
+
},
|
|
1588
|
+
children: /* @__PURE__ */ jsxs(Text, { muted: !0, children: [
|
|
1589
|
+
/* @__PURE__ */ jsx(ErrorOutlineIcon, { style: { marginRight: "0.15em" } }),
|
|
1590
|
+
typeof error == "object" && "message" in error && typeof error.message == "string" ? error.message : "Error loading video"
|
|
1591
|
+
] })
|
|
1538
1592
|
}
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
"div",
|
|
1545
|
-
{
|
|
1546
|
-
style: {
|
|
1547
|
-
position: "absolute",
|
|
1548
|
-
top: "50%",
|
|
1549
|
-
left: "50%",
|
|
1550
|
-
transform: "translate(-50%, -50%)"
|
|
1551
|
-
},
|
|
1552
|
-
children: /* @__PURE__ */ jsxs(Text, { muted: !0, children: [
|
|
1553
|
-
/* @__PURE__ */ jsx(ErrorOutlineIcon, { style: { marginRight: "0.15em" } }),
|
|
1554
|
-
typeof error == "object" && "message" in error && typeof error.message == "string" ? error.message : "Error loading video"
|
|
1555
|
-
] })
|
|
1556
|
-
}
|
|
1557
|
-
) : null,
|
|
1558
|
-
children
|
|
1559
|
-
] }),
|
|
1593
|
+
) : null,
|
|
1594
|
+
children
|
|
1595
|
+
]
|
|
1596
|
+
}
|
|
1597
|
+
),
|
|
1560
1598
|
dialogState === "edit-thumbnail" && /* @__PURE__ */ jsx(EditThumbnailDialog, { asset, currentTime: muxPlayer?.current?.currentTime })
|
|
1561
1599
|
] });
|
|
1562
1600
|
}
|
|
@@ -2299,14 +2337,7 @@ function VideoInBrowser({
|
|
|
2299
2337
|
alignItems: "center",
|
|
2300
2338
|
justifyContent: "center"
|
|
2301
2339
|
},
|
|
2302
|
-
children: /* @__PURE__ */ jsx(
|
|
2303
|
-
"path",
|
|
2304
|
-
{
|
|
2305
|
-
fill: "currentColor",
|
|
2306
|
-
style: { opacity: "0.65" },
|
|
2307
|
-
d: "M10.75 19q.95 0 1.6-.65t.65-1.6V13h3v-2h-4v3.875q-.275-.2-.587-.288t-.663-.087q-.95 0-1.6.65t-.65 1.6t.65 1.6t1.6.65M6 22q-.825 0-1.412-.587T4 20V4q0-.825.588-1.412T6 2h8l6 6v12q0 .825-.587 1.413T18 22zm7-13V4H6v16h12V9zM6 4v5zv16z"
|
|
2308
|
-
}
|
|
2309
|
-
) })
|
|
2340
|
+
children: /* @__PURE__ */ jsx(AudioIcon, { width: "3em", height: "3em" })
|
|
2310
2341
|
}
|
|
2311
2342
|
) : /* @__PURE__ */ jsx(VideoThumbnail, { asset })
|
|
2312
2343
|
] }),
|
|
@@ -2931,7 +2962,7 @@ const TopControls = styled.div`
|
|
|
2931
2962
|
}
|
|
2932
2963
|
) : null
|
|
2933
2964
|
] }) });
|
|
2934
|
-
}, Player = ({ asset, buttons, readOnly, onChange }) => {
|
|
2965
|
+
}, Player = ({ asset, buttons, readOnly, onChange, config }) => {
|
|
2935
2966
|
const isLoading = useMemo(() => asset?.status === "preparing" ? "Preparing the video" : asset?.status === "waiting_for_upload" ? "Waiting for upload to start" : asset?.status === "waiting" ? "Processing upload" : !(asset?.status === "ready" || typeof asset?.status > "u"), [asset]), isPreparingStaticRenditions = useMemo(() => {
|
|
2936
2967
|
if (asset?.data?.static_renditions?.status && asset?.data?.static_renditions?.status !== "disabled")
|
|
2937
2968
|
return !1;
|
|
@@ -2952,7 +2983,7 @@ const TopControls = styled.div`
|
|
|
2952
2983
|
text: isLoading !== !0 && isLoading || "Waiting for Mux to complete the upload",
|
|
2953
2984
|
onCancel: readOnly ? void 0 : () => handleCancelUpload()
|
|
2954
2985
|
}
|
|
2955
|
-
) : /* @__PURE__ */ jsxs(VideoPlayer, { asset, children: [
|
|
2986
|
+
) : /* @__PURE__ */ jsxs(VideoPlayer, { asset, hlsConfig: config?.hlsConfig, children: [
|
|
2956
2987
|
buttons && /* @__PURE__ */ jsx(TopControls, { slot: "top-chrome", children: buttons }),
|
|
2957
2988
|
isPreparingStaticRenditions && /* @__PURE__ */ jsx(
|
|
2958
2989
|
Card,
|
|
@@ -3064,7 +3095,7 @@ const FileButton = styled(MenuItem)(({ theme }) => {
|
|
|
3064
3095
|
color: white;
|
|
3065
3096
|
`, isVideoAsset = (asset) => asset._type === "mux.videoAsset";
|
|
3066
3097
|
function PlayerActionsMenu(props) {
|
|
3067
|
-
const { asset, readOnly, dialogState, setDialogState, onChange, onSelect } = props, [open, setOpen] = useState(!1), [menuElement, setMenuRef] = useState(null), isSigned = useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]), { hasConfigAccess } = useAccessControl(props.config), onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange]);
|
|
3098
|
+
const { asset, readOnly, dialogState, setDialogState, onChange, onSelect, accept } = props, [open, setOpen] = useState(!1), [menuElement, setMenuRef] = useState(null), isSigned = useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]), { hasConfigAccess } = useAccessControl(props.config), onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange]);
|
|
3068
3099
|
return useEffect(() => {
|
|
3069
3100
|
open && dialogState && setOpen(!1);
|
|
3070
3101
|
}, [dialogState, open]), useClickOutsideEvent(
|
|
@@ -3090,7 +3121,7 @@ function PlayerActionsMenu(props) {
|
|
|
3090
3121
|
/* @__PURE__ */ jsx(
|
|
3091
3122
|
FileInputMenuItem,
|
|
3092
3123
|
{
|
|
3093
|
-
accept
|
|
3124
|
+
accept,
|
|
3094
3125
|
icon: UploadIcon,
|
|
3095
3126
|
onSelect,
|
|
3096
3127
|
text: "Upload",
|
|
@@ -3454,7 +3485,47 @@ function UploadConfiguration({
|
|
|
3454
3485
|
(r) => r !== "highest" && r !== "audio-only"
|
|
3455
3486
|
).length > 0, [config.static_renditions]), [renditionMode, setRenditionMode] = useState(
|
|
3456
3487
|
isAdvancedMode ? "advanced" : "standard"
|
|
3457
|
-
),
|
|
3488
|
+
), [videoDuration, setVideoDuration] = useState(null), [urlFileSize, setUrlFileSize] = useState(null), [isLoadingDuration, setIsLoadingDuration] = useState(!1), [isLoadingFileSize, setIsLoadingFileSize] = useState(!1), [validationError, setValidationError] = useState(null), [canSkipFileSizeValidation, setCanSkipFileSizeValidation] = useState(!1), MAX_FILE_SIZE = pluginConfig.maxAssetFileSize, MAX_DURATION_SECONDS = pluginConfig.maxAssetDuration;
|
|
3489
|
+
useEffect(() => {
|
|
3490
|
+
setVideoDuration(null), setUrlFileSize(null), setIsLoadingDuration(!1), setIsLoadingFileSize(!1), setValidationError(null), setCanSkipFileSizeValidation(!1);
|
|
3491
|
+
let videoElement = null, currentVideoSrc = null;
|
|
3492
|
+
const cleanupVideo = (shouldRevokeUrl) => {
|
|
3493
|
+
videoElement && (videoElement.onloadedmetadata = null, videoElement.onerror = null, videoElement.src = "", videoElement.load(), videoElement = null), shouldRevokeUrl && currentVideoSrc?.startsWith("blob:") && URL.revokeObjectURL(currentVideoSrc), currentVideoSrc = null;
|
|
3494
|
+
}, validateDuration = (videoSrc, shouldRevokeUrl = !1) => {
|
|
3495
|
+
!MAX_DURATION_SECONDS || MAX_DURATION_SECONDS <= 0 || (setIsLoadingDuration(!0), videoElement = document.createElement("video"), videoElement.preload = "metadata", currentVideoSrc = videoSrc, videoElement.onloadedmetadata = () => {
|
|
3496
|
+
const duration = videoElement.duration;
|
|
3497
|
+
setVideoDuration(duration), setIsLoadingDuration(!1), duration > MAX_DURATION_SECONDS && setValidationError(
|
|
3498
|
+
`Video duration (${formatSeconds(duration)}) exceeds maximum allowed duration of ${formatSeconds(MAX_DURATION_SECONDS)}`
|
|
3499
|
+
), cleanupVideo(shouldRevokeUrl);
|
|
3500
|
+
}, videoElement.onerror = () => {
|
|
3501
|
+
setIsLoadingDuration(!1), console.warn("Could not read video metadata for validation"), cleanupVideo(shouldRevokeUrl);
|
|
3502
|
+
}, videoElement.src = videoSrc);
|
|
3503
|
+
}, validateFileSize = (size) => MAX_FILE_SIZE === void 0 || size <= MAX_FILE_SIZE ? !0 : (setValidationError(
|
|
3504
|
+
`File size (${formatBytes(size)}) exceeds maximum allowed size of ${formatBytes(MAX_FILE_SIZE)}`
|
|
3505
|
+
), !1);
|
|
3506
|
+
if (stagedUpload.type === "file") {
|
|
3507
|
+
const file = stagedUpload.files[0];
|
|
3508
|
+
validateFileSize(file.size) && validateDuration(URL.createObjectURL(file), !0);
|
|
3509
|
+
}
|
|
3510
|
+
if (stagedUpload.type === "url") {
|
|
3511
|
+
const url = stagedUpload.url;
|
|
3512
|
+
(async () => {
|
|
3513
|
+
setIsLoadingFileSize(!0);
|
|
3514
|
+
try {
|
|
3515
|
+
const contentLength = (await fetch(url, { method: "HEAD" })).headers.get("content-length"), fileSize = contentLength ? parseInt(contentLength, 10) : null;
|
|
3516
|
+
setIsLoadingFileSize(!1), fileSize && setUrlFileSize(fileSize);
|
|
3517
|
+
const shouldValidateDuration = MAX_FILE_SIZE === void 0 || fileSize === null || validateFileSize(fileSize);
|
|
3518
|
+
fileSize === null && MAX_FILE_SIZE !== void 0 && setCanSkipFileSizeValidation(!0), shouldValidateDuration && validateDuration(url);
|
|
3519
|
+
} catch {
|
|
3520
|
+
setIsLoadingFileSize(!1), console.warn("Could not validate file size from URL"), setCanSkipFileSizeValidation(!0), validateDuration(url);
|
|
3521
|
+
}
|
|
3522
|
+
})();
|
|
3523
|
+
}
|
|
3524
|
+
return () => {
|
|
3525
|
+
cleanupVideo(!0);
|
|
3526
|
+
};
|
|
3527
|
+
}, [stagedUpload, MAX_FILE_SIZE, MAX_DURATION_SECONDS]);
|
|
3528
|
+
const toggleRendition = (rendition) => {
|
|
3458
3529
|
const current = config.static_renditions, hasRendition = current.includes(rendition);
|
|
3459
3530
|
dispatch(hasRendition ? {
|
|
3460
3531
|
action: "static_renditions",
|
|
@@ -3489,6 +3560,13 @@ function UploadConfiguration({
|
|
|
3489
3560
|
header: "Configure Mux Upload",
|
|
3490
3561
|
onClose,
|
|
3491
3562
|
children: /* @__PURE__ */ jsxs(Stack, { padding: 4, space: 2, children: [
|
|
3563
|
+
validationError && /* @__PURE__ */ jsx(Card, { padding: 3, tone: "critical", radius: 2, marginBottom: 2, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, align: "flex-start", children: [
|
|
3564
|
+
/* @__PURE__ */ jsx(ErrorOutlineIcon, { width: 20, height: 20 }),
|
|
3565
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
3566
|
+
/* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: "Validation Error" }),
|
|
3567
|
+
/* @__PURE__ */ jsx(Text, { size: 1, children: validationError })
|
|
3568
|
+
] })
|
|
3569
|
+
] }) }),
|
|
3492
3570
|
/* @__PURE__ */ jsx(Label$1, { size: 3, children: "FILE TO UPLOAD" }),
|
|
3493
3571
|
/* @__PURE__ */ jsx(
|
|
3494
3572
|
Card,
|
|
@@ -3502,7 +3580,14 @@ function UploadConfiguration({
|
|
|
3502
3580
|
/* @__PURE__ */ jsx(DocumentVideoIcon, { fontSize: "2em" }),
|
|
3503
3581
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
3504
3582
|
/* @__PURE__ */ jsx(Text, { textOverflow: "ellipsis", as: "h2", size: 3, children: stagedUpload.type === "file" ? stagedUpload.files[0].name : stagedUpload.url }),
|
|
3505
|
-
/* @__PURE__ */ jsx(Text, { as: "p", size: 1, muted: !0, children: stagedUpload.type === "file" ? `Direct File Upload (${formatBytes(stagedUpload.files[0].size)})` : "File From URL (Unknown size)" })
|
|
3583
|
+
/* @__PURE__ */ jsx(Text, { as: "p", size: 1, muted: !0, children: stagedUpload.type === "file" ? `Direct File Upload (${formatBytes(stagedUpload.files[0].size)})` : urlFileSize ? `File From URL (${formatBytes(urlFileSize)})` : isLoadingFileSize ? "File From URL (Loading size...)" : "File From URL (Unknown size)" }),
|
|
3584
|
+
stagedUpload.type === "file" && /* @__PURE__ */ jsxs(Stack, { space: 1, children: [
|
|
3585
|
+
isLoadingDuration && /* @__PURE__ */ jsx(Text, { as: "p", size: 1, muted: !0, children: "Reading video metadata..." }),
|
|
3586
|
+
videoDuration !== null && !validationError && /* @__PURE__ */ jsxs(Text, { as: "p", size: 1, muted: !0, children: [
|
|
3587
|
+
"Duration: ",
|
|
3588
|
+
formatSeconds(videoDuration)
|
|
3589
|
+
] })
|
|
3590
|
+
] })
|
|
3506
3591
|
] })
|
|
3507
3592
|
] })
|
|
3508
3593
|
}
|
|
@@ -3694,11 +3779,13 @@ function UploadConfiguration({
|
|
|
3694
3779
|
/* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(
|
|
3695
3780
|
Button,
|
|
3696
3781
|
{
|
|
3697
|
-
disabled: !basicConfig && !config.public_policy && !config.signed_policy,
|
|
3782
|
+
disabled: !basicConfig && !config.public_policy && !config.signed_policy || validationError !== null || isLoadingDuration || isLoadingFileSize && !canSkipFileSizeValidation,
|
|
3698
3783
|
icon: UploadIcon,
|
|
3699
3784
|
text: "Upload",
|
|
3700
3785
|
tone: "positive",
|
|
3701
|
-
onClick: () =>
|
|
3786
|
+
onClick: () => {
|
|
3787
|
+
validationError || startUpload(formatUploadConfig(config));
|
|
3788
|
+
}
|
|
3702
3789
|
}
|
|
3703
3790
|
) })
|
|
3704
3791
|
] })
|
|
@@ -3821,7 +3908,7 @@ const ctrlKey = 17, cmdKey = 91, UploadCardWithFocusRing = withFocusRing(Card),
|
|
|
3821
3908
|
/* @__PURE__ */ jsx(
|
|
3822
3909
|
HiddenInput,
|
|
3823
3910
|
{
|
|
3824
|
-
accept
|
|
3911
|
+
accept,
|
|
3825
3912
|
ref: inputRef,
|
|
3826
3913
|
tabIndex: 0,
|
|
3827
3914
|
type: "file",
|
|
@@ -3842,8 +3929,11 @@ const ctrlKey = 17, cmdKey = 91, UploadCardWithFocusRing = withFocusRing(Card),
|
|
|
3842
3929
|
)
|
|
3843
3930
|
] });
|
|
3844
3931
|
};
|
|
3932
|
+
function formatAcceptString(accept) {
|
|
3933
|
+
return accept.split(",").map((type) => type.trim().replace("/*", "")).join(" or ");
|
|
3934
|
+
}
|
|
3845
3935
|
function UploadPlaceholder(props) {
|
|
3846
|
-
const { setDialogState, readOnly, onSelect, hovering, needsSetup } = props, handleBrowse = useCallback(() => setDialogState("select-video"), [setDialogState]), handleConfigureApi = useCallback(() => setDialogState("secrets"), [setDialogState]), { hasConfigAccess } = useAccessControl(props.config);
|
|
3936
|
+
const { setDialogState, readOnly, onSelect, hovering, needsSetup, accept } = props, handleBrowse = useCallback(() => setDialogState("select-video"), [setDialogState]), handleConfigureApi = useCallback(() => setDialogState("secrets"), [setDialogState]), { hasConfigAccess } = useAccessControl(props.config);
|
|
3847
3937
|
return /* @__PURE__ */ jsx(
|
|
3848
3938
|
Card,
|
|
3849
3939
|
{
|
|
@@ -3866,12 +3956,17 @@ function UploadPlaceholder(props) {
|
|
|
3866
3956
|
children: [
|
|
3867
3957
|
/* @__PURE__ */ jsxs(Flex, { align: "center", justify: "flex-start", gap: 2, flex: 1, children: [
|
|
3868
3958
|
/* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */ jsx(Text, { muted: !0, children: /* @__PURE__ */ jsx(DocumentVideoIcon, {}) }) }),
|
|
3869
|
-
/* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */
|
|
3959
|
+
/* @__PURE__ */ jsx(Flex, { justify: "center", children: /* @__PURE__ */ jsxs(Text, { size: 1, muted: !0, children: [
|
|
3960
|
+
"Drag ",
|
|
3961
|
+
formatAcceptString(accept),
|
|
3962
|
+
" file or paste URL here"
|
|
3963
|
+
] }) })
|
|
3870
3964
|
] }),
|
|
3871
3965
|
/* @__PURE__ */ jsxs(Inline, { space: 2, children: [
|
|
3872
3966
|
/* @__PURE__ */ jsx(
|
|
3873
3967
|
FileInputButton,
|
|
3874
3968
|
{
|
|
3969
|
+
accept,
|
|
3875
3970
|
mode: "bleed",
|
|
3876
3971
|
tone: "default",
|
|
3877
3972
|
icon: UploadIcon,
|
|
@@ -4022,21 +4117,33 @@ function Uploader(props) {
|
|
|
4022
4117
|
complete: () => dispatch({ action: "complete" }),
|
|
4023
4118
|
error: (error) => dispatch({ action: "error", error })
|
|
4024
4119
|
});
|
|
4025
|
-
},
|
|
4026
|
-
|
|
4120
|
+
}, invalidFileToast = useCallback(() => {
|
|
4121
|
+
toast.push({
|
|
4122
|
+
status: "error",
|
|
4123
|
+
title: `Invalid file type. Accepted types: ${props.config.acceptedMimeTypes?.join(", ")}`
|
|
4124
|
+
});
|
|
4125
|
+
}, [props.config.acceptedMimeTypes, toast]), isInvalidFile = (files) => Array.from(files).some((file) => !props.config.acceptedMimeTypes?.some((acceptedType) => {
|
|
4126
|
+
const pattern = `^${acceptedType.replace("*", ".*")}$`;
|
|
4127
|
+
return new RegExp(pattern).test(file.type);
|
|
4128
|
+
})), handleUpload = (files) => {
|
|
4129
|
+
isInvalidFile(files) || dispatch({
|
|
4027
4130
|
action: "stageUpload",
|
|
4028
4131
|
input: { type: "file", files }
|
|
4029
4132
|
});
|
|
4030
4133
|
}, handlePaste = (event) => {
|
|
4031
4134
|
event.preventDefault(), event.stopPropagation();
|
|
4032
|
-
const url = (event.clipboardData || window.clipboardData)
|
|
4135
|
+
const url = (event.clipboardData || window.clipboardData)?.getData("text")?.trim();
|
|
4033
4136
|
if (!isValidUrl(url)) {
|
|
4034
4137
|
toast.push({ status: "error", title: "Invalid URL for Mux video input." });
|
|
4035
4138
|
return;
|
|
4036
4139
|
}
|
|
4037
4140
|
dispatch({ action: "stageUpload", input: { type: "url", url } });
|
|
4038
4141
|
}, handleDrop = (event) => {
|
|
4039
|
-
|
|
4142
|
+
if (event.preventDefault(), event.stopPropagation(), dragState === "invalid") {
|
|
4143
|
+
invalidFileToast(), setDragState(null);
|
|
4144
|
+
return;
|
|
4145
|
+
}
|
|
4146
|
+
setDragState(null), extractDroppedFiles(event.nativeEvent.dataTransfer).then((files) => {
|
|
4040
4147
|
dispatch({
|
|
4041
4148
|
action: "stageUpload",
|
|
4042
4149
|
input: { type: "file", files }
|
|
@@ -4046,8 +4153,11 @@ function Uploader(props) {
|
|
|
4046
4153
|
event.preventDefault(), event.stopPropagation();
|
|
4047
4154
|
}, handleDragEnter = (event) => {
|
|
4048
4155
|
event.stopPropagation(), dragEnteredEls.current.push(event.target);
|
|
4049
|
-
const type = event.dataTransfer.items?.[0]?.type
|
|
4050
|
-
|
|
4156
|
+
const type = event.dataTransfer.items?.[0]?.type, isValidType = props.config.acceptedMimeTypes?.some((acceptedType) => {
|
|
4157
|
+
const pattern = `^${acceptedType.replace("*", ".*")}$`;
|
|
4158
|
+
return new RegExp(pattern).test(type);
|
|
4159
|
+
});
|
|
4160
|
+
setDragState(isValidType ? "valid" : "invalid");
|
|
4051
4161
|
}, handleDragLeave = (event) => {
|
|
4052
4162
|
event.stopPropagation();
|
|
4053
4163
|
const idx = dragEnteredEls.current.indexOf(event.target);
|
|
@@ -4085,7 +4195,9 @@ function Uploader(props) {
|
|
|
4085
4195
|
}
|
|
4086
4196
|
);
|
|
4087
4197
|
let tone;
|
|
4088
|
-
|
|
4198
|
+
dragState && (tone = dragState === "valid" ? "positive" : "critical");
|
|
4199
|
+
const acceptMimeString = props.config?.acceptedMimeTypes?.length ? props.config.acceptedMimeTypes.join(",") : "video/*, audio/*";
|
|
4200
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
4089
4201
|
/* @__PURE__ */ jsx(
|
|
4090
4202
|
UploadCard,
|
|
4091
4203
|
{
|
|
@@ -4107,9 +4219,11 @@ function Uploader(props) {
|
|
|
4107
4219
|
readOnly: props.readOnly,
|
|
4108
4220
|
asset: props.asset,
|
|
4109
4221
|
onChange: props.onChange,
|
|
4222
|
+
config: props.config,
|
|
4110
4223
|
buttons: /* @__PURE__ */ jsx(
|
|
4111
4224
|
PlayerActionsMenu$1,
|
|
4112
4225
|
{
|
|
4226
|
+
accept: acceptMimeString,
|
|
4113
4227
|
asset: props.asset,
|
|
4114
4228
|
dialogState: props.dialogState,
|
|
4115
4229
|
setDialogState: props.setDialogState,
|
|
@@ -4125,6 +4239,7 @@ function Uploader(props) {
|
|
|
4125
4239
|
) : /* @__PURE__ */ jsx(
|
|
4126
4240
|
UploadPlaceholder,
|
|
4127
4241
|
{
|
|
4242
|
+
accept: acceptMimeString,
|
|
4128
4243
|
hovering: dragState !== null,
|
|
4129
4244
|
onSelect: handleUpload,
|
|
4130
4245
|
readOnly: !!props.readOnly,
|
|
@@ -4385,7 +4500,8 @@ const muxVideoSchema = {
|
|
|
4385
4500
|
defaultPublic: !0,
|
|
4386
4501
|
defaultSigned: !1,
|
|
4387
4502
|
tool: DEFAULT_TOOL_CONFIG,
|
|
4388
|
-
allowedRolesForConfiguration: []
|
|
4503
|
+
allowedRolesForConfiguration: [],
|
|
4504
|
+
acceptedMimeTypes: ["video/*", "audio/*"]
|
|
4389
4505
|
};
|
|
4390
4506
|
function convertLegacyConfig(config) {
|
|
4391
4507
|
return config.static_renditions && config.static_renditions.length > 0 ? { static_renditions: config.static_renditions } : config.mp4_support === "standard" ? { static_renditions: ["highest"] } : { static_renditions: [] };
|