sanity-plugin-mux-input 2.16.0 → 2.17.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/dist/index.js +866 -60
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +866 -60
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/actions/upload.ts +42 -4
- package/src/components/DraggableWatermark.tsx +877 -0
- package/src/components/UploadConfiguration.tsx +259 -59
- package/src/components/Uploader.tsx +7 -1
- package/src/components/VideoPlayer.tsx +2 -0
- package/src/hooks/useMediaMetadata.ts +3 -0
- package/src/util/convertWatermarkToMux.ts +160 -0
- package/src/util/roundPxString.ts +16 -0
- package/src/util/types.ts +43 -1
package/dist/index.mjs
CHANGED
|
@@ -973,7 +973,7 @@ function tryWithSuspend(block, onError) {
|
|
|
973
973
|
return onError ? onError(errorOrPromise) : void 0;
|
|
974
974
|
}
|
|
975
975
|
}
|
|
976
|
-
const Image = styled.img`
|
|
976
|
+
const Image$1 = styled.img`
|
|
977
977
|
transition: opacity 0.175s ease-out 0s;
|
|
978
978
|
display: block;
|
|
979
979
|
width: 100%;
|
|
@@ -1051,7 +1051,7 @@ function VideoThumbnail({
|
|
|
1051
1051
|
}
|
|
1052
1052
|
),
|
|
1053
1053
|
/* @__PURE__ */ jsx(
|
|
1054
|
-
Image,
|
|
1054
|
+
Image$1,
|
|
1055
1055
|
{
|
|
1056
1056
|
src: thumbnailSrc ?? void 0,
|
|
1057
1057
|
alt: `Preview for ${staticImage ? "image" : "video"} ${asset.filename || asset.assetId}`,
|
|
@@ -3059,7 +3059,7 @@ function VideoPlayer({
|
|
|
3059
3059
|
hlsConfig,
|
|
3060
3060
|
...props
|
|
3061
3061
|
}) {
|
|
3062
|
-
const client = useClient(), { dialogState } = useDialogStateContext(), isAudio = assetIsAudio(asset), muxPlayer = useRef(null), [error, setError] = useState(), playbackId = useMemo(() => {
|
|
3062
|
+
const client = useClient(), { dialogState } = useDialogStateContext(), isAudio = assetIsAudio(asset), muxPlayer = useRef(null), playerContainerRef = useRef(null), [error, setError] = useState(), playbackId = useMemo(() => {
|
|
3063
3063
|
try {
|
|
3064
3064
|
return getPlaybackId(asset, ["public", "signed", "drm"]);
|
|
3065
3065
|
} catch {
|
|
@@ -3117,6 +3117,7 @@ function VideoPlayer({
|
|
|
3117
3117
|
/* @__PURE__ */ jsxs(
|
|
3118
3118
|
Card,
|
|
3119
3119
|
{
|
|
3120
|
+
ref: playerContainerRef,
|
|
3120
3121
|
tone: "transparent",
|
|
3121
3122
|
style: {
|
|
3122
3123
|
aspectRatio,
|
|
@@ -3153,7 +3154,7 @@ function VideoPlayer({
|
|
|
3153
3154
|
crossOrigin: "anonymous",
|
|
3154
3155
|
metadata: {
|
|
3155
3156
|
player_name: "Sanity Admin Dashboard",
|
|
3156
|
-
player_version: "2.
|
|
3157
|
+
player_version: "2.17.0",
|
|
3157
3158
|
page_type: "Preview Player"
|
|
3158
3159
|
},
|
|
3159
3160
|
audio: isAudio,
|
|
@@ -4315,6 +4316,33 @@ function createUpChunkObservable(uuid2, uploadUrl2, source) {
|
|
|
4315
4316
|
return upchunk.on("success", successHandler), upchunk.on("error", errorHandler), upchunk.on("progress", progressHandler), upchunk.on("offline", offlineHandler), upchunk.on("online", onlineHandler), () => upchunk.abort();
|
|
4316
4317
|
});
|
|
4317
4318
|
}
|
|
4319
|
+
function roundPxString(value) {
|
|
4320
|
+
if (typeof value != "string") return;
|
|
4321
|
+
const trimmed = value.trim();
|
|
4322
|
+
if (!trimmed.endsWith("px")) return;
|
|
4323
|
+
const n = Number(trimmed.slice(0, -2));
|
|
4324
|
+
if (!Number.isFinite(n)) return;
|
|
4325
|
+
let rounded = Math.round(n);
|
|
4326
|
+
return rounded === 0 && (rounded = n < 0 ? -1 : 1), `${rounded}px`;
|
|
4327
|
+
}
|
|
4328
|
+
function sanitizeOverlaySettingsInPlace(settings) {
|
|
4329
|
+
const inputs = settings.input;
|
|
4330
|
+
if (inputs)
|
|
4331
|
+
for (const input of inputs) {
|
|
4332
|
+
const overlay = input.overlay_settings;
|
|
4333
|
+
if (!overlay) continue;
|
|
4334
|
+
const hm = roundPxString(overlay.horizontal_margin), vm = roundPxString(overlay.vertical_margin), w = roundPxString(overlay.width);
|
|
4335
|
+
hm && (overlay.horizontal_margin = hm), vm && (overlay.vertical_margin = vm), w && (overlay.width = w);
|
|
4336
|
+
}
|
|
4337
|
+
}
|
|
4338
|
+
function sanitizePxStringsInJson(json) {
|
|
4339
|
+
return json.replace(/"(-?\d+(?:\.\d+)?)px"/g, (_match, num) => {
|
|
4340
|
+
const n = Number(num);
|
|
4341
|
+
if (!Number.isFinite(n)) return _match;
|
|
4342
|
+
let rounded = Math.round(n);
|
|
4343
|
+
return rounded === 0 && (rounded = n < 0 ? -1 : 1), `"${rounded}px"`;
|
|
4344
|
+
});
|
|
4345
|
+
}
|
|
4318
4346
|
function cancelUpload(client, uuid2) {
|
|
4319
4347
|
return client.observable.request({
|
|
4320
4348
|
url: `/addons/mux/uploads/${client.config().dataset}/${uuid2}`,
|
|
@@ -4325,7 +4353,8 @@ function cancelUpload(client, uuid2) {
|
|
|
4325
4353
|
function uploadUrl({
|
|
4326
4354
|
url,
|
|
4327
4355
|
settings,
|
|
4328
|
-
client
|
|
4356
|
+
client,
|
|
4357
|
+
watermark
|
|
4329
4358
|
}) {
|
|
4330
4359
|
return testUrl(url).pipe(
|
|
4331
4360
|
switchMap((validUrl) => concat(
|
|
@@ -4335,9 +4364,9 @@ function uploadUrl({
|
|
|
4335
4364
|
if (!json || !json.status)
|
|
4336
4365
|
return throwError(new Error("Invalid credentials"));
|
|
4337
4366
|
const uuid$1 = uuid(), muxBody = settings;
|
|
4338
|
-
muxBody.input || (muxBody.input = [{ type: "video" }]), muxBody.input[0].url = validUrl;
|
|
4367
|
+
muxBody.input || (muxBody.input = [{ type: "video" }]), muxBody.input[0].url = validUrl, sanitizeOverlaySettingsInPlace(muxBody);
|
|
4339
4368
|
const query = {
|
|
4340
|
-
muxBody: JSON.stringify(muxBody),
|
|
4369
|
+
muxBody: sanitizePxStringsInJson(JSON.stringify(muxBody)),
|
|
4341
4370
|
filename: validUrl.split("/").slice(-1)[0]
|
|
4342
4371
|
}, dataset = client.config().dataset;
|
|
4343
4372
|
return defer(
|
|
@@ -4365,7 +4394,8 @@ function uploadUrl({
|
|
|
4365
4394
|
function uploadFile({
|
|
4366
4395
|
settings,
|
|
4367
4396
|
client,
|
|
4368
|
-
file
|
|
4397
|
+
file,
|
|
4398
|
+
watermark
|
|
4369
4399
|
}) {
|
|
4370
4400
|
return testFile(file).pipe(
|
|
4371
4401
|
switchMap((fileOptions) => concat(
|
|
@@ -4375,7 +4405,7 @@ function uploadFile({
|
|
|
4375
4405
|
if (!json || !json.status)
|
|
4376
4406
|
return throwError(() => new Error("Invalid credentials"));
|
|
4377
4407
|
const uuid$1 = uuid(), body = settings;
|
|
4378
|
-
return concat(
|
|
4408
|
+
return sanitizeOverlaySettingsInPlace(body), concat(
|
|
4379
4409
|
of({ type: "uuid", uuid: uuid$1 }),
|
|
4380
4410
|
defer(
|
|
4381
4411
|
() => client.observable.request({
|
|
@@ -4429,7 +4459,7 @@ function pollUpload(client, uuid2) {
|
|
|
4429
4459
|
}, 2e3);
|
|
4430
4460
|
});
|
|
4431
4461
|
}
|
|
4432
|
-
async function updateAssetDocumentFromUpload(client, uuid2) {
|
|
4462
|
+
async function updateAssetDocumentFromUpload(client, uuid2, _watermark) {
|
|
4433
4463
|
let upload, asset;
|
|
4434
4464
|
try {
|
|
4435
4465
|
upload = await pollUpload(client, uuid2);
|
|
@@ -4951,13 +4981,14 @@ function useMediaMetadata(stagedUpload) {
|
|
|
4951
4981
|
setIsLoadingMetadata(!1);
|
|
4952
4982
|
},
|
|
4953
4983
|
() => {
|
|
4954
|
-
const duration = videoElement.duration, width = videoElement.videoWidth, height = videoElement.videoHeight, isAudioOnly = width <= 0 && height <= 0;
|
|
4984
|
+
const duration = videoElement.duration, width = videoElement.videoWidth, height = videoElement.videoHeight, isAudioOnly = width <= 0 && height <= 0, aspectRatio = width / height;
|
|
4955
4985
|
setVideoAssetMetadata((old) => ({
|
|
4956
4986
|
...old,
|
|
4957
4987
|
duration,
|
|
4958
4988
|
width,
|
|
4959
4989
|
height,
|
|
4960
|
-
isAudioOnly
|
|
4990
|
+
isAudioOnly,
|
|
4991
|
+
aspectRatio
|
|
4961
4992
|
}));
|
|
4962
4993
|
}
|
|
4963
4994
|
], cleanupVideo = (videoEl) => {
|
|
@@ -4979,6 +5010,51 @@ function useMediaMetadata(stagedUpload) {
|
|
|
4979
5010
|
isLoadingMetadata
|
|
4980
5011
|
};
|
|
4981
5012
|
}
|
|
5013
|
+
function convertWatermarkToMuxOverlay(watermark, options) {
|
|
5014
|
+
if (!watermark.enabled || !watermark.imageUrl)
|
|
5015
|
+
return null;
|
|
5016
|
+
const size = watermark.size || 20, opacity = watermark.opacity ?? 0.7, toPxString = (valuePercent, axis) => {
|
|
5017
|
+
const videoAspectRatio2 = options?.videoAspectRatio ?? 1.7777777777777777, isVertical = videoAspectRatio2 > 0 && videoAspectRatio2 < 1, base = axis === "x" ? isVertical ? 1080 : 1920 : isVertical ? 1920 : 1080, px = valuePercent / 100 * base;
|
|
5018
|
+
let rounded = Math.round(px);
|
|
5019
|
+
return rounded === 0 && (rounded = px < 0 ? -1 : 1), `${rounded}px`;
|
|
5020
|
+
}, normalizeToPixels = (value, axis) => {
|
|
5021
|
+
if (!value) return value;
|
|
5022
|
+
const trimmed = value.trim();
|
|
5023
|
+
if (trimmed.endsWith("px"))
|
|
5024
|
+
return roundPxString(trimmed);
|
|
5025
|
+
if (trimmed.endsWith("%")) {
|
|
5026
|
+
const n = Number(trimmed.slice(0, -1));
|
|
5027
|
+
return Number.isFinite(n) ? toPxString(n, axis) : value;
|
|
5028
|
+
}
|
|
5029
|
+
return value;
|
|
5030
|
+
};
|
|
5031
|
+
if (watermark.overlay_settings) {
|
|
5032
|
+
const widthValue = watermark.overlay_settings.width, widthNormalized = options?.units === "px" ? normalizeToPixels(widthValue, "x") : widthValue;
|
|
5033
|
+
return {
|
|
5034
|
+
...watermark.overlay_settings,
|
|
5035
|
+
horizontal_margin: options?.units === "px" ? normalizeToPixels(watermark.overlay_settings.horizontal_margin, "x") ?? watermark.overlay_settings.horizontal_margin : watermark.overlay_settings.horizontal_margin,
|
|
5036
|
+
vertical_margin: options?.units === "px" ? normalizeToPixels(watermark.overlay_settings.vertical_margin, "y") ?? watermark.overlay_settings.vertical_margin : watermark.overlay_settings.vertical_margin,
|
|
5037
|
+
width: widthNormalized ?? `${size}%`,
|
|
5038
|
+
opacity: watermark.overlay_settings.opacity ?? `${Math.round(opacity * 100)}%`
|
|
5039
|
+
};
|
|
5040
|
+
}
|
|
5041
|
+
const position = watermark.position || { x: 50, y: 50 }, clampPercent = (value) => Math.max(-100, Math.min(100, value)), toPercentString = (value) => `${value === 0 || Object.is(value, -0) || Math.abs(value) < 1e-9 ? 0.01 : value}%`, watermarkWidthPercentOfVideoWidth = size, videoAspectRatio = options?.videoAspectRatio ?? 16 / 9, imageAspectRatio = watermark.imageAspectRatio ?? 1, watermarkHeightPercentOfVideoHeight = Math.max(
|
|
5042
|
+
0,
|
|
5043
|
+
Math.min(100, size * videoAspectRatio / imageAspectRatio)
|
|
5044
|
+
), halfWidth = watermarkWidthPercentOfVideoWidth / 2, halfHeight = watermarkHeightPercentOfVideoHeight / 2, leftMargin = clampPercent(
|
|
5045
|
+
Math.min(position.x - halfWidth, 100 - watermarkWidthPercentOfVideoWidth)
|
|
5046
|
+
), topMargin = clampPercent(
|
|
5047
|
+
Math.min(position.y - halfHeight, 100 - watermarkHeightPercentOfVideoHeight)
|
|
5048
|
+
), units = options?.units ?? "%", marginX = units === "px" ? toPxString(leftMargin, "x") : toPercentString(leftMargin), marginY = units === "px" ? toPxString(topMargin, "y") : toPercentString(topMargin), width = units === "px" ? toPxString(size, "x") : `${size}%`;
|
|
5049
|
+
return {
|
|
5050
|
+
vertical_align: "top",
|
|
5051
|
+
vertical_margin: marginY,
|
|
5052
|
+
horizontal_align: "left",
|
|
5053
|
+
horizontal_margin: marginX,
|
|
5054
|
+
width,
|
|
5055
|
+
opacity: `${Math.round(opacity * 100)}%`
|
|
5056
|
+
};
|
|
5057
|
+
}
|
|
4982
5058
|
function formatBytes(bytes, si = !1, dp = 1) {
|
|
4983
5059
|
const thresh = si ? 1e3 : 1024;
|
|
4984
5060
|
if (Math.abs(bytes) < thresh)
|
|
@@ -4991,6 +5067,566 @@ function formatBytes(bytes, si = !1, dp = 1) {
|
|
|
4991
5067
|
while (Math.round(Math.abs(bytes) * r) / r >= thresh && u2 < units.length - 1);
|
|
4992
5068
|
return bytes.toFixed(dp) + " " + units[u2];
|
|
4993
5069
|
}
|
|
5070
|
+
const RangeInput = styled.input`
|
|
5071
|
+
width: 100%;
|
|
5072
|
+
height: 4px;
|
|
5073
|
+
border-radius: 2px;
|
|
5074
|
+
background: var(--card-border-color);
|
|
5075
|
+
outline: none;
|
|
5076
|
+
-webkit-appearance: none;
|
|
5077
|
+
appearance: none;
|
|
5078
|
+
|
|
5079
|
+
&::-webkit-slider-thumb {
|
|
5080
|
+
-webkit-appearance: none;
|
|
5081
|
+
appearance: none;
|
|
5082
|
+
width: 16px;
|
|
5083
|
+
height: 16px;
|
|
5084
|
+
border-radius: 50%;
|
|
5085
|
+
background: var(--card-focus-ring-color, #2276fc);
|
|
5086
|
+
cursor: pointer;
|
|
5087
|
+
border: 2px solid white;
|
|
5088
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
5089
|
+
}
|
|
5090
|
+
|
|
5091
|
+
&::-moz-range-thumb {
|
|
5092
|
+
width: 16px;
|
|
5093
|
+
height: 16px;
|
|
5094
|
+
border-radius: 50%;
|
|
5095
|
+
background: var(--card-focus-ring-color, #2276fc);
|
|
5096
|
+
cursor: pointer;
|
|
5097
|
+
border: 2px solid white;
|
|
5098
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);
|
|
5099
|
+
}
|
|
5100
|
+
|
|
5101
|
+
&:hover::-webkit-slider-thumb {
|
|
5102
|
+
background: var(--card-focus-ring-color, #1a5fc7);
|
|
5103
|
+
}
|
|
5104
|
+
|
|
5105
|
+
&:hover::-moz-range-thumb {
|
|
5106
|
+
background: var(--card-focus-ring-color, #1a5fc7);
|
|
5107
|
+
}
|
|
5108
|
+
`, WatermarkOverlay = styled.div`
|
|
5109
|
+
position: absolute;
|
|
5110
|
+
max-width: 200px;
|
|
5111
|
+
opacity: ${(props) => props.$opacity};
|
|
5112
|
+
cursor: move;
|
|
5113
|
+
user-select: none;
|
|
5114
|
+
z-index: 10;
|
|
5115
|
+
pointer-events: auto;
|
|
5116
|
+
|
|
5117
|
+
img {
|
|
5118
|
+
width: 100%;
|
|
5119
|
+
height: auto;
|
|
5120
|
+
display: block;
|
|
5121
|
+
pointer-events: none;
|
|
5122
|
+
}
|
|
5123
|
+
|
|
5124
|
+
&:hover {
|
|
5125
|
+
outline: 2px dashed rgba(255, 255, 255, 0.8);
|
|
5126
|
+
outline-offset: 4px;
|
|
5127
|
+
}
|
|
5128
|
+
`;
|
|
5129
|
+
function DraggableWatermark({
|
|
5130
|
+
watermark,
|
|
5131
|
+
onChange,
|
|
5132
|
+
containerRef,
|
|
5133
|
+
videoElementRef
|
|
5134
|
+
}) {
|
|
5135
|
+
const [isDragging, setIsDragging] = useState(!1), [dragStart, setDragStart] = useState({ x: 0, y: 0 }), [startPosition, setStartPosition] = useState({ x: 0, y: 0 }), watermarkRef = useRef(null), debounceTimeoutRef = useRef(null), [localPosition, setLocalPosition] = useState(watermark.position || { x: 50, y: 50 }), position = localPosition, size = watermark.size || 20, opacity = watermark.opacity ?? 0.7, parseOpacityPercent = (value) => {
|
|
5136
|
+
if (!value) return null;
|
|
5137
|
+
const trimmed = value.trim();
|
|
5138
|
+
if (!trimmed.endsWith("%")) return null;
|
|
5139
|
+
const num = Number(trimmed.slice(0, -1));
|
|
5140
|
+
return Number.isFinite(num) ? Math.max(0, Math.min(1, num / 100)) : null;
|
|
5141
|
+
}, getVideoContentBox = useCallback(() => {
|
|
5142
|
+
const container = containerRef?.current;
|
|
5143
|
+
if (!container) return { x: 0, y: 0, width: 0, height: 0 };
|
|
5144
|
+
const rect = container.getBoundingClientRect(), containerW = rect.width, containerH = rect.height, videoEl = videoElementRef?.current, videoW = videoEl?.videoWidth || 0, videoH = videoEl?.videoHeight || 0;
|
|
5145
|
+
if (!videoW || !videoH || !containerW || !containerH)
|
|
5146
|
+
return { x: 0, y: 0, width: containerW, height: containerH };
|
|
5147
|
+
const scale = Math.min(containerW / videoW, containerH / videoH), contentW = videoW * scale, contentH = videoH * scale, offsetX = (containerW - contentW) / 2, offsetY = (containerH - contentH) / 2;
|
|
5148
|
+
return { x: offsetX, y: offsetY, width: contentW, height: contentH };
|
|
5149
|
+
}, [containerRef, videoElementRef]), parseOverlayValue = (value) => {
|
|
5150
|
+
if (!value) return null;
|
|
5151
|
+
const trimmed = value.trim(), px = trimmed.endsWith("px"), pct = trimmed.endsWith("%"), num = Number(trimmed.replace(/px|%/g, ""));
|
|
5152
|
+
return Number.isFinite(num) ? px ? { n: num, unit: "px" } : pct ? { n: num, unit: "%" } : null : null;
|
|
5153
|
+
}, computeManualStyle = (overlay) => {
|
|
5154
|
+
const rect = containerRef?.current?.getBoundingClientRect(), w = rect?.width ?? 0, h = rect?.height ?? 0, isVertical = h > w, baseW = isVertical ? 1080 : 1920, baseH = isVertical ? 1920 : 1080, hm = parseOverlayValue(overlay.horizontal_margin), vm = parseOverlayValue(overlay.vertical_margin), ww = parseOverlayValue(overlay.width), manualOpacity = parseOpacityPercent(overlay.opacity), toCss = (v, axis) => {
|
|
5155
|
+
if (v)
|
|
5156
|
+
return v.unit === "%" ? `${v.n}%` : axis === "x" ? `${v.n * w / baseW}px` : `${v.n * h / baseH}px`;
|
|
5157
|
+
}, computeHorizontalStyle = () => overlay.horizontal_align === "left" ? { left: toCss(hm, "x"), right: void 0, transform: "translate(0, 0)" } : overlay.horizontal_align === "right" ? { right: toCss(hm, "x"), left: void 0, transform: "translate(0, 0)" } : { left: "50%", right: void 0, transform: "translate(-50%, 0)" }, computeVerticalStyle = () => overlay.vertical_align === "top" ? { top: toCss(vm, "y"), bottom: void 0 } : overlay.vertical_align === "bottom" ? { bottom: toCss(vm, "y"), top: void 0 } : { top: "50%", bottom: void 0 }, hStyle = computeHorizontalStyle(), vStyle = computeVerticalStyle();
|
|
5158
|
+
let transform = hStyle.transform;
|
|
5159
|
+
return overlay.vertical_align === "middle" && (transform = overlay.horizontal_align === "center" ? "translate(-50%, -50%)" : "translate(0, -50%)"), {
|
|
5160
|
+
position: "absolute",
|
|
5161
|
+
...hStyle,
|
|
5162
|
+
...vStyle,
|
|
5163
|
+
transform,
|
|
5164
|
+
width: ww ? toCss(ww, "x") : `${size}%`,
|
|
5165
|
+
opacity: manualOpacity ?? opacity,
|
|
5166
|
+
cursor: "default"
|
|
5167
|
+
};
|
|
5168
|
+
}, debouncedOnChange = useCallback(
|
|
5169
|
+
(newWatermark) => {
|
|
5170
|
+
debounceTimeoutRef.current && clearTimeout(debounceTimeoutRef.current), debounceTimeoutRef.current = setTimeout(() => {
|
|
5171
|
+
onChange(newWatermark);
|
|
5172
|
+
}, 300);
|
|
5173
|
+
},
|
|
5174
|
+
[onChange]
|
|
5175
|
+
);
|
|
5176
|
+
useEffect(() => () => {
|
|
5177
|
+
debounceTimeoutRef.current && clearTimeout(debounceTimeoutRef.current);
|
|
5178
|
+
}, []), useEffect(() => {
|
|
5179
|
+
!isDragging && watermark.position && setLocalPosition(watermark.position);
|
|
5180
|
+
}, [watermark.position, isDragging]);
|
|
5181
|
+
const handleMouseDown = useCallback(
|
|
5182
|
+
(e) => {
|
|
5183
|
+
e.preventDefault(), setIsDragging(!0), setDragStart({ x: e.clientX, y: e.clientY }), setStartPosition({ x: position.x, y: position.y });
|
|
5184
|
+
},
|
|
5185
|
+
[position]
|
|
5186
|
+
), handleMouseMove = useCallback(
|
|
5187
|
+
(e) => {
|
|
5188
|
+
if (!isDragging || !containerRef?.current) return;
|
|
5189
|
+
const rect = containerRef.current.getBoundingClientRect(), content = getVideoContentBox(), contentW = content.width || rect.width, contentH = content.height || rect.height, dx = e.clientX - dragStart.x, dy = e.clientY - dragStart.y, deltaXPercent = dx / contentW * 100, deltaYPercent = dy / contentH * 100;
|
|
5190
|
+
let newX = startPosition.x + deltaXPercent, newY = startPosition.y + deltaYPercent;
|
|
5191
|
+
newX = Math.max(0, Math.min(100, newX)), newY = Math.max(0, Math.min(100, newY)), setLocalPosition({ x: newX, y: newY }), debouncedOnChange({
|
|
5192
|
+
...watermark,
|
|
5193
|
+
position: { x: newX, y: newY }
|
|
5194
|
+
});
|
|
5195
|
+
},
|
|
5196
|
+
[
|
|
5197
|
+
isDragging,
|
|
5198
|
+
dragStart,
|
|
5199
|
+
startPosition,
|
|
5200
|
+
containerRef,
|
|
5201
|
+
watermark,
|
|
5202
|
+
debouncedOnChange,
|
|
5203
|
+
getVideoContentBox
|
|
5204
|
+
]
|
|
5205
|
+
), handleMouseUp = useCallback(() => {
|
|
5206
|
+
setIsDragging(!1), debounceTimeoutRef.current && (clearTimeout(debounceTimeoutRef.current), debounceTimeoutRef.current = null), onChange({
|
|
5207
|
+
...watermark,
|
|
5208
|
+
position: localPosition
|
|
5209
|
+
});
|
|
5210
|
+
}, [watermark, localPosition, onChange]);
|
|
5211
|
+
if (useEffect(() => {
|
|
5212
|
+
if (isDragging)
|
|
5213
|
+
return document.addEventListener("mousemove", handleMouseMove), document.addEventListener("mouseup", handleMouseUp), () => {
|
|
5214
|
+
document.removeEventListener("mousemove", handleMouseMove), document.removeEventListener("mouseup", handleMouseUp);
|
|
5215
|
+
};
|
|
5216
|
+
}, [isDragging, handleMouseMove, handleMouseUp]), !watermark.imageUrl)
|
|
5217
|
+
return null;
|
|
5218
|
+
const hasManualOverlay = !!watermark.overlay_settings, opacityForRender = hasManualOverlay ? parseOpacityPercent(watermark.overlay_settings?.opacity) ?? opacity : opacity, contentBox = getVideoContentBox(), hasContentBox = contentBox.width > 0 && contentBox.height > 0;
|
|
5219
|
+
return /* @__PURE__ */ jsx(
|
|
5220
|
+
WatermarkOverlay,
|
|
5221
|
+
{
|
|
5222
|
+
ref: watermarkRef,
|
|
5223
|
+
$opacity: opacityForRender,
|
|
5224
|
+
onMouseDown: hasManualOverlay ? void 0 : handleMouseDown,
|
|
5225
|
+
style: hasManualOverlay ? computeManualStyle(watermark.overlay_settings) : hasContentBox ? {
|
|
5226
|
+
left: `${contentBox.x + position.x / 100 * contentBox.width}px`,
|
|
5227
|
+
top: `${contentBox.y + position.y / 100 * contentBox.height}px`,
|
|
5228
|
+
transform: "translate(-50%, -50%)",
|
|
5229
|
+
width: `${Math.max(1, size / 100 * contentBox.width)}px`,
|
|
5230
|
+
cursor: isDragging ? "grabbing" : "grab"
|
|
5231
|
+
} : {
|
|
5232
|
+
left: `${position.x}%`,
|
|
5233
|
+
top: `${position.y}%`,
|
|
5234
|
+
transform: "translate(-50%, -50%)",
|
|
5235
|
+
width: `${size}%`,
|
|
5236
|
+
cursor: isDragging ? "grabbing" : "grab"
|
|
5237
|
+
},
|
|
5238
|
+
children: /* @__PURE__ */ jsx("img", { src: watermark.imageUrl, alt: "Watermark", draggable: !1 })
|
|
5239
|
+
}
|
|
5240
|
+
);
|
|
5241
|
+
}
|
|
5242
|
+
function WatermarkControls({
|
|
5243
|
+
watermark,
|
|
5244
|
+
onChange,
|
|
5245
|
+
onValidationChange,
|
|
5246
|
+
previewContainerRef,
|
|
5247
|
+
previewVideoRef
|
|
5248
|
+
}) {
|
|
5249
|
+
const [urlInput, setUrlInput] = useState(watermark.imageUrl || ""), [urlError, setUrlError] = useState(null), [isValidating, setIsValidating] = useState(!1), [isValid, setIsValid] = useState(null), validationTimeoutRef = useRef(null), [mode, setMode] = useState(
|
|
5250
|
+
watermark.overlay_settings ? "manual" : "canvas"
|
|
5251
|
+
), isUpdatingRef = useRef(!1), isValidExtension = (extension) => extension.endsWith(".png") || extension.endsWith(".jpg") || extension.endsWith(".jpeg"), validateUrl = useCallback(
|
|
5252
|
+
(url) => {
|
|
5253
|
+
if (validationTimeoutRef.current && clearTimeout(validationTimeoutRef.current), !url) {
|
|
5254
|
+
setUrlError(null), setIsValid(null), setIsValidating(!1), onValidationChange?.(null), isUpdatingRef.current = !0, onChange({
|
|
5255
|
+
...watermark,
|
|
5256
|
+
enabled: !1,
|
|
5257
|
+
imageUrl: void 0,
|
|
5258
|
+
overlay_settings: void 0
|
|
5259
|
+
});
|
|
5260
|
+
return;
|
|
5261
|
+
}
|
|
5262
|
+
setIsValidating(!0), setIsValid(null), setUrlError(null), validationTimeoutRef.current = setTimeout(() => {
|
|
5263
|
+
try {
|
|
5264
|
+
const pathname = new URL(url).pathname.toLowerCase();
|
|
5265
|
+
if (isValidExtension(pathname)) {
|
|
5266
|
+
setIsValid(!0), setUrlError(null), onValidationChange?.(null);
|
|
5267
|
+
const img = new Image();
|
|
5268
|
+
img.onload = () => {
|
|
5269
|
+
const imageAspectRatio = img.naturalWidth && img.naturalHeight ? img.naturalWidth / img.naturalHeight : 1;
|
|
5270
|
+
isUpdatingRef.current = !0, onChange({
|
|
5271
|
+
...watermark,
|
|
5272
|
+
enabled: !0,
|
|
5273
|
+
imageUrl: url,
|
|
5274
|
+
imageAspectRatio
|
|
5275
|
+
});
|
|
5276
|
+
}, img.onerror = () => {
|
|
5277
|
+
isUpdatingRef.current = !0, onChange({
|
|
5278
|
+
...watermark,
|
|
5279
|
+
enabled: !0,
|
|
5280
|
+
imageUrl: url,
|
|
5281
|
+
imageAspectRatio: watermark.imageAspectRatio
|
|
5282
|
+
});
|
|
5283
|
+
}, img.src = url;
|
|
5284
|
+
} else {
|
|
5285
|
+
const errorMsg = "Mux only supports PNG and JPG watermark images. Please use a .png or .jpg file.";
|
|
5286
|
+
setIsValid(!1), setUrlError(errorMsg), onValidationChange?.(errorMsg), isUpdatingRef.current = !0, onChange({
|
|
5287
|
+
...watermark,
|
|
5288
|
+
enabled: !1,
|
|
5289
|
+
imageUrl: void 0,
|
|
5290
|
+
imageAspectRatio: void 0,
|
|
5291
|
+
overlay_settings: void 0
|
|
5292
|
+
});
|
|
5293
|
+
}
|
|
5294
|
+
} catch {
|
|
5295
|
+
setIsValid(!1);
|
|
5296
|
+
const errorMsg = "Please enter a valid URL (e.g., https://example.com/watermark.png)";
|
|
5297
|
+
setUrlError(errorMsg), onValidationChange?.(errorMsg), isUpdatingRef.current = !0, onChange({
|
|
5298
|
+
...watermark,
|
|
5299
|
+
enabled: !1,
|
|
5300
|
+
imageUrl: void 0,
|
|
5301
|
+
imageAspectRatio: void 0,
|
|
5302
|
+
overlay_settings: void 0
|
|
5303
|
+
});
|
|
5304
|
+
} finally {
|
|
5305
|
+
setIsValidating(!1);
|
|
5306
|
+
}
|
|
5307
|
+
}, 500);
|
|
5308
|
+
},
|
|
5309
|
+
[watermark, onChange, onValidationChange]
|
|
5310
|
+
);
|
|
5311
|
+
useEffect(() => () => {
|
|
5312
|
+
validationTimeoutRef.current && clearTimeout(validationTimeoutRef.current);
|
|
5313
|
+
}, []), useEffect(() => {
|
|
5314
|
+
setMode(watermark.overlay_settings ? "manual" : "canvas");
|
|
5315
|
+
}, [watermark.overlay_settings]);
|
|
5316
|
+
const handleUrlChange = (e) => {
|
|
5317
|
+
const url = e.target.value;
|
|
5318
|
+
setUrlInput(url), watermark.imageUrl && url !== watermark.imageUrl && (isUpdatingRef.current = !0, onChange({
|
|
5319
|
+
...watermark,
|
|
5320
|
+
enabled: !1,
|
|
5321
|
+
imageUrl: void 0,
|
|
5322
|
+
imageAspectRatio: void 0,
|
|
5323
|
+
overlay_settings: void 0
|
|
5324
|
+
})), validateUrl(url);
|
|
5325
|
+
}, normalizeZeroPercent = (value) => {
|
|
5326
|
+
if (!value) return value;
|
|
5327
|
+
const trimmed = value.trim();
|
|
5328
|
+
if (!trimmed.endsWith("%")) return value;
|
|
5329
|
+
const n = Number(trimmed.slice(0, -1));
|
|
5330
|
+
return Number.isFinite(n) ? n === 0 || Object.is(n, -0) || Math.abs(n) < 1e-9 ? "0.01%" : `${n}%` : value;
|
|
5331
|
+
}, updateOverlaySettings = (next) => {
|
|
5332
|
+
const merged = {
|
|
5333
|
+
...watermark.overlay_settings ?? {
|
|
5334
|
+
vertical_align: "bottom",
|
|
5335
|
+
vertical_margin: "2%",
|
|
5336
|
+
horizontal_align: "right",
|
|
5337
|
+
horizontal_margin: "2%",
|
|
5338
|
+
width: `${watermark.size ?? 20}%`,
|
|
5339
|
+
opacity: `${Math.round((watermark.opacity ?? 0.7) * 100)}%`
|
|
5340
|
+
},
|
|
5341
|
+
...next
|
|
5342
|
+
};
|
|
5343
|
+
onChange({
|
|
5344
|
+
...watermark,
|
|
5345
|
+
enabled: !0,
|
|
5346
|
+
overlay_settings: {
|
|
5347
|
+
...merged,
|
|
5348
|
+
horizontal_margin: normalizeZeroPercent(merged.horizontal_margin) || merged.horizontal_margin,
|
|
5349
|
+
vertical_margin: normalizeZeroPercent(merged.vertical_margin) || merged.vertical_margin
|
|
5350
|
+
}
|
|
5351
|
+
});
|
|
5352
|
+
}, getVideoContentBox = () => {
|
|
5353
|
+
const container = previewContainerRef?.current;
|
|
5354
|
+
if (!container) return { x: 0, y: 0, width: 0, height: 0 };
|
|
5355
|
+
const rect = container.getBoundingClientRect(), containerW = rect.width, containerH = rect.height, videoEl = previewVideoRef?.current, videoW = videoEl?.videoWidth || 0, videoH = videoEl?.videoHeight || 0;
|
|
5356
|
+
if (!videoW || !videoH || !containerW || !containerH)
|
|
5357
|
+
return { x: 0, y: 0, width: containerW, height: containerH };
|
|
5358
|
+
const scale = Math.min(containerW / videoW, containerH / videoH), contentW = videoW * scale, contentH = videoH * scale, offsetX = (containerW - contentW) / 2, offsetY = (containerH - contentH) / 2;
|
|
5359
|
+
return { x: offsetX, y: offsetY, width: contentW, height: contentH };
|
|
5360
|
+
};
|
|
5361
|
+
return /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
5362
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
5363
|
+
/* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: "Watermark Image URL" }),
|
|
5364
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "Enter a URL to a PNG or JPG image. Mux will download this image and overlay it on your video." }),
|
|
5365
|
+
/* @__PURE__ */ jsxs(Box, { style: { position: "relative", width: "100%" }, children: [
|
|
5366
|
+
/* @__PURE__ */ jsx(
|
|
5367
|
+
"input",
|
|
5368
|
+
{
|
|
5369
|
+
type: "url",
|
|
5370
|
+
value: urlInput,
|
|
5371
|
+
onChange: handleUrlChange,
|
|
5372
|
+
placeholder: "https://example.com/watermark.png",
|
|
5373
|
+
style: {
|
|
5374
|
+
padding: "8px 12px",
|
|
5375
|
+
paddingRight: urlInput ? "96px" : isValid !== null ? "36px" : "12px",
|
|
5376
|
+
border: urlError || isValid === !1 ? "1px solid #e74c3c" : isValid === !0 ? "1px solid #4caf50" : "1px solid #ccc",
|
|
5377
|
+
borderRadius: "4px",
|
|
5378
|
+
width: "100%",
|
|
5379
|
+
maxWidth: "100%",
|
|
5380
|
+
boxSizing: "border-box",
|
|
5381
|
+
fontSize: "14px"
|
|
5382
|
+
}
|
|
5383
|
+
}
|
|
5384
|
+
),
|
|
5385
|
+
(urlInput || isValidating || isValid !== null) && /* @__PURE__ */ jsxs(
|
|
5386
|
+
Box,
|
|
5387
|
+
{
|
|
5388
|
+
style: {
|
|
5389
|
+
position: "absolute",
|
|
5390
|
+
right: "8px",
|
|
5391
|
+
top: "50%",
|
|
5392
|
+
transform: "translateY(-50%)",
|
|
5393
|
+
display: "flex",
|
|
5394
|
+
alignItems: "center",
|
|
5395
|
+
gap: "4px"
|
|
5396
|
+
},
|
|
5397
|
+
children: [
|
|
5398
|
+
urlInput && /* @__PURE__ */ jsx(
|
|
5399
|
+
Button,
|
|
5400
|
+
{
|
|
5401
|
+
text: "Clear",
|
|
5402
|
+
mode: "bleed",
|
|
5403
|
+
tone: "critical",
|
|
5404
|
+
onClick: () => {
|
|
5405
|
+
setUrlInput(""), validateUrl("");
|
|
5406
|
+
},
|
|
5407
|
+
disabled: isValidating,
|
|
5408
|
+
style: { fontSize: "11px", height: "24px" }
|
|
5409
|
+
}
|
|
5410
|
+
),
|
|
5411
|
+
isValidating && /* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "Validating..." }),
|
|
5412
|
+
isValid === !0 && !isValidating && /* @__PURE__ */ jsx(CheckmarkCircleIcon, { style: { color: "#4caf50", fontSize: "18px" } }),
|
|
5413
|
+
isValid === !1 && !isValidating && /* @__PURE__ */ jsx(ErrorOutlineIcon, { style: { color: "#e74c3c", fontSize: "18px" } })
|
|
5414
|
+
]
|
|
5415
|
+
}
|
|
5416
|
+
)
|
|
5417
|
+
] }),
|
|
5418
|
+
urlError && /* @__PURE__ */ jsx(Card, { padding: 2, tone: "critical", radius: 2, children: /* @__PURE__ */ jsxs(Flex, { align: "center", gap: 2, children: [
|
|
5419
|
+
/* @__PURE__ */ jsx(ErrorOutlineIcon, { style: { color: "#e74c3c", flexShrink: 0 } }),
|
|
5420
|
+
/* @__PURE__ */ jsx(Text, { size: 0, style: { color: "#e74c3c" }, children: urlError })
|
|
5421
|
+
] }) })
|
|
5422
|
+
] }),
|
|
5423
|
+
watermark.imageUrl && /* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
5424
|
+
/* @__PURE__ */ jsx(Card, { padding: 3, tone: "transparent", border: !0, radius: 2, children: /* @__PURE__ */ jsxs(
|
|
5425
|
+
Flex,
|
|
5426
|
+
{
|
|
5427
|
+
align: "center",
|
|
5428
|
+
justify: "space-between",
|
|
5429
|
+
gap: 3,
|
|
5430
|
+
style: { flexWrap: "wrap", alignItems: "flex-start" },
|
|
5431
|
+
children: [
|
|
5432
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 240, flex: 1 }, children: [
|
|
5433
|
+
/* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: "Positioning mode" }),
|
|
5434
|
+
/* @__PURE__ */ jsxs(Text, { size: 0, muted: !0, children: [
|
|
5435
|
+
"Choose between dragging on the canvas or manually editing the Mux",
|
|
5436
|
+
" ",
|
|
5437
|
+
/* @__PURE__ */ jsx("code", { children: "overlay_settings" }),
|
|
5438
|
+
" fields (as in",
|
|
5439
|
+
" ",
|
|
5440
|
+
/* @__PURE__ */ jsx(
|
|
5441
|
+
"a",
|
|
5442
|
+
{
|
|
5443
|
+
href: "https://www.mux.com/docs/guides/add-watermarks-to-your-videos",
|
|
5444
|
+
target: "_blank",
|
|
5445
|
+
rel: "noopener noreferrer",
|
|
5446
|
+
children: "the docs"
|
|
5447
|
+
}
|
|
5448
|
+
),
|
|
5449
|
+
")."
|
|
5450
|
+
] })
|
|
5451
|
+
] }),
|
|
5452
|
+
/* @__PURE__ */ jsxs(Flex, { gap: 2, style: { flexWrap: "wrap" }, children: [
|
|
5453
|
+
/* @__PURE__ */ jsx(
|
|
5454
|
+
Button,
|
|
5455
|
+
{
|
|
5456
|
+
text: "Canvas",
|
|
5457
|
+
mode: mode === "canvas" ? "default" : "ghost",
|
|
5458
|
+
onClick: () => {
|
|
5459
|
+
setMode("canvas"), onChange({ ...watermark, enabled: !0, overlay_settings: void 0 });
|
|
5460
|
+
}
|
|
5461
|
+
}
|
|
5462
|
+
),
|
|
5463
|
+
/* @__PURE__ */ jsx(
|
|
5464
|
+
Button,
|
|
5465
|
+
{
|
|
5466
|
+
text: "Manual",
|
|
5467
|
+
mode: mode === "manual" ? "default" : "ghost",
|
|
5468
|
+
onClick: () => {
|
|
5469
|
+
setMode("manual");
|
|
5470
|
+
const overlay = convertWatermarkToMuxOverlay({ ...watermark, enabled: !0 });
|
|
5471
|
+
updateOverlaySettings(overlay ?? {});
|
|
5472
|
+
}
|
|
5473
|
+
}
|
|
5474
|
+
)
|
|
5475
|
+
] })
|
|
5476
|
+
]
|
|
5477
|
+
}
|
|
5478
|
+
) }),
|
|
5479
|
+
mode === "manual" && /* @__PURE__ */ jsx(Card, { padding: 3, tone: "transparent", border: !0, radius: 2, children: /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
5480
|
+
/* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: "Mux overlay_settings" }),
|
|
5481
|
+
/* @__PURE__ */ jsxs(Grid, { columns: [1, 2], gap: 3, style: { width: "100%" }, children: [
|
|
5482
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5483
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "horizontal_align" }),
|
|
5484
|
+
/* @__PURE__ */ jsxs(
|
|
5485
|
+
"select",
|
|
5486
|
+
{
|
|
5487
|
+
value: watermark.overlay_settings?.horizontal_align || "right",
|
|
5488
|
+
onChange: (e) => updateOverlaySettings({
|
|
5489
|
+
horizontal_align: e.target.value || "right"
|
|
5490
|
+
}),
|
|
5491
|
+
style: {
|
|
5492
|
+
width: "100%",
|
|
5493
|
+
padding: "8px 10px",
|
|
5494
|
+
border: "1px solid #ccc",
|
|
5495
|
+
borderRadius: 4
|
|
5496
|
+
},
|
|
5497
|
+
children: [
|
|
5498
|
+
/* @__PURE__ */ jsx("option", { value: "left", children: "left" }),
|
|
5499
|
+
/* @__PURE__ */ jsx("option", { value: "center", children: "center" }),
|
|
5500
|
+
/* @__PURE__ */ jsx("option", { value: "right", children: "right" })
|
|
5501
|
+
]
|
|
5502
|
+
}
|
|
5503
|
+
)
|
|
5504
|
+
] }),
|
|
5505
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5506
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "horizontal_margin (e.g. 2% or 40px)" }),
|
|
5507
|
+
/* @__PURE__ */ jsx(
|
|
5508
|
+
TextInput,
|
|
5509
|
+
{
|
|
5510
|
+
value: watermark.overlay_settings?.horizontal_margin || "2%",
|
|
5511
|
+
onChange: (e) => updateOverlaySettings({ horizontal_margin: e.currentTarget.value })
|
|
5512
|
+
}
|
|
5513
|
+
)
|
|
5514
|
+
] }),
|
|
5515
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5516
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "vertical_align" }),
|
|
5517
|
+
/* @__PURE__ */ jsxs(
|
|
5518
|
+
"select",
|
|
5519
|
+
{
|
|
5520
|
+
value: watermark.overlay_settings?.vertical_align || "bottom",
|
|
5521
|
+
onChange: (e) => updateOverlaySettings({
|
|
5522
|
+
vertical_align: e.target.value || "bottom"
|
|
5523
|
+
}),
|
|
5524
|
+
style: {
|
|
5525
|
+
width: "100%",
|
|
5526
|
+
padding: "8px 10px",
|
|
5527
|
+
border: "1px solid #ccc",
|
|
5528
|
+
borderRadius: 4
|
|
5529
|
+
},
|
|
5530
|
+
children: [
|
|
5531
|
+
/* @__PURE__ */ jsx("option", { value: "top", children: "top" }),
|
|
5532
|
+
/* @__PURE__ */ jsx("option", { value: "middle", children: "middle" }),
|
|
5533
|
+
/* @__PURE__ */ jsx("option", { value: "bottom", children: "bottom" })
|
|
5534
|
+
]
|
|
5535
|
+
}
|
|
5536
|
+
)
|
|
5537
|
+
] }),
|
|
5538
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5539
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "vertical_margin (e.g. 2% or 40px)" }),
|
|
5540
|
+
/* @__PURE__ */ jsx(
|
|
5541
|
+
TextInput,
|
|
5542
|
+
{
|
|
5543
|
+
value: watermark.overlay_settings?.vertical_margin || "2%",
|
|
5544
|
+
onChange: (e) => updateOverlaySettings({ vertical_margin: e.currentTarget.value })
|
|
5545
|
+
}
|
|
5546
|
+
)
|
|
5547
|
+
] }),
|
|
5548
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5549
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "width (e.g. 25% or 80px)" }),
|
|
5550
|
+
/* @__PURE__ */ jsx(
|
|
5551
|
+
TextInput,
|
|
5552
|
+
{
|
|
5553
|
+
value: watermark.overlay_settings?.width || `${watermark.size ?? 20}%`,
|
|
5554
|
+
onChange: (e) => updateOverlaySettings({ width: e.currentTarget.value })
|
|
5555
|
+
}
|
|
5556
|
+
)
|
|
5557
|
+
] }),
|
|
5558
|
+
/* @__PURE__ */ jsxs(Stack, { space: 2, style: { minWidth: 0 }, children: [
|
|
5559
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "opacity (e.g. 90%)" }),
|
|
5560
|
+
/* @__PURE__ */ jsx(
|
|
5561
|
+
TextInput,
|
|
5562
|
+
{
|
|
5563
|
+
value: watermark.overlay_settings?.opacity || `${Math.round((watermark.opacity ?? 0.7) * 100)}%`,
|
|
5564
|
+
onChange: (e) => updateOverlaySettings({ opacity: e.currentTarget.value })
|
|
5565
|
+
}
|
|
5566
|
+
)
|
|
5567
|
+
] })
|
|
5568
|
+
] }),
|
|
5569
|
+
/* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: "Margins and width accept either percentages or pixels, per the Mux guide." })
|
|
5570
|
+
] }) }),
|
|
5571
|
+
mode === "canvas" && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
5572
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
5573
|
+
/* @__PURE__ */ jsx(Text, { size: 1, weight: "medium", children: (() => {
|
|
5574
|
+
const sizePct = watermark.size || 20, contentW = getVideoContentBox().width;
|
|
5575
|
+
return contentW ? `Size: ${Math.max(1, Math.round(sizePct / 100 * contentW))}px` : `Size: ${sizePct}%`;
|
|
5576
|
+
})() }),
|
|
5577
|
+
/* @__PURE__ */ jsx(
|
|
5578
|
+
RangeInput,
|
|
5579
|
+
{
|
|
5580
|
+
type: "range",
|
|
5581
|
+
value: (() => {
|
|
5582
|
+
const sizePct = watermark.size || 20, contentW = getVideoContentBox().width;
|
|
5583
|
+
return contentW ? Math.max(1, Math.round(sizePct / 100 * contentW)) : sizePct;
|
|
5584
|
+
})(),
|
|
5585
|
+
min: (() => {
|
|
5586
|
+
const contentW = getVideoContentBox().width;
|
|
5587
|
+
return contentW ? Math.max(1, Math.round(contentW * 0.05)) : 5;
|
|
5588
|
+
})(),
|
|
5589
|
+
max: (() => {
|
|
5590
|
+
const contentW = getVideoContentBox().width;
|
|
5591
|
+
return contentW ? Math.max(1, Math.round(contentW * 0.5)) : 50;
|
|
5592
|
+
})(),
|
|
5593
|
+
step: 1,
|
|
5594
|
+
onChange: (e) => {
|
|
5595
|
+
const raw = Number(e.target.value), contentW = getVideoContentBox().width, nextPct = contentW ? raw / contentW * 100 : raw, clampedPct = Math.max(5, Math.min(50, nextPct));
|
|
5596
|
+
onChange({
|
|
5597
|
+
...watermark,
|
|
5598
|
+
size: clampedPct
|
|
5599
|
+
});
|
|
5600
|
+
}
|
|
5601
|
+
}
|
|
5602
|
+
)
|
|
5603
|
+
] }),
|
|
5604
|
+
/* @__PURE__ */ jsxs(Box, { children: [
|
|
5605
|
+
/* @__PURE__ */ jsxs(Text, { size: 1, weight: "medium", children: [
|
|
5606
|
+
"Opacity: ",
|
|
5607
|
+
Math.round((watermark.opacity ?? 0.7) * 100),
|
|
5608
|
+
"%"
|
|
5609
|
+
] }),
|
|
5610
|
+
/* @__PURE__ */ jsx(
|
|
5611
|
+
RangeInput,
|
|
5612
|
+
{
|
|
5613
|
+
type: "range",
|
|
5614
|
+
value: watermark.opacity ?? 0.7,
|
|
5615
|
+
min: 0,
|
|
5616
|
+
max: 1,
|
|
5617
|
+
step: 0.05,
|
|
5618
|
+
onChange: (e) => onChange({
|
|
5619
|
+
...watermark,
|
|
5620
|
+
opacity: Number(e.target.value)
|
|
5621
|
+
})
|
|
5622
|
+
}
|
|
5623
|
+
)
|
|
5624
|
+
] })
|
|
5625
|
+
] }),
|
|
5626
|
+
/* @__PURE__ */ jsx(Card, { padding: 2, tone: "transparent", border: !0, radius: 2, children: /* @__PURE__ */ jsx(Text, { size: 0, muted: !0, children: mode === "manual" ? "Manual mode: edit the overlay_settings fields above" : "\u{1F4A1} Drag the watermark on the preview to position it" }) })
|
|
5627
|
+
] })
|
|
5628
|
+
] });
|
|
5629
|
+
}
|
|
4994
5630
|
const ALL_LANGUAGE_CODES = LanguagesList.getAllCodes().map((code) => ({
|
|
4995
5631
|
value: code,
|
|
4996
5632
|
label: LanguagesList.getNativeName(code)
|
|
@@ -5432,7 +6068,7 @@ function UploadConfiguration({
|
|
|
5432
6068
|
startUpload,
|
|
5433
6069
|
onClose
|
|
5434
6070
|
}) {
|
|
5435
|
-
const id = useId(), autoTextTracks = useRef(
|
|
6071
|
+
const id = useId(), [watermarkValidationError, setWatermarkValidationError] = useState(null), watermarkPreviewContainerRef = useRef(null), watermarkPreviewVideoRef = useRef(null), autoTextTracks = useRef(
|
|
5436
6072
|
pluginConfig.video_quality === "plus" && pluginConfig.defaultAutogeneratedSubtitleLang ? [
|
|
5437
6073
|
{
|
|
5438
6074
|
_id: uuid(),
|
|
@@ -5468,6 +6104,8 @@ function UploadConfiguration({
|
|
|
5468
6104
|
return Object.assign({}, prev, { [action.action]: action.value });
|
|
5469
6105
|
case "drm_policy":
|
|
5470
6106
|
return Object.assign({}, prev, { [action.action]: action.value });
|
|
6107
|
+
case "watermark":
|
|
6108
|
+
return Object.assign({}, prev, { watermark: action.value });
|
|
5471
6109
|
// Updating individual tracks
|
|
5472
6110
|
case "track": {
|
|
5473
6111
|
const text_tracks = [...prev.text_tracks], target_track_i = text_tracks.findIndex(({ _id: _id2 }) => _id2 === action.id);
|
|
@@ -5535,7 +6173,12 @@ function UploadConfiguration({
|
|
|
5535
6173
|
]);
|
|
5536
6174
|
const { disableTextTrackConfig, disableUploadConfig } = pluginConfig, skipConfig = disableTextTrackConfig && disableUploadConfig;
|
|
5537
6175
|
if (useEffect(() => {
|
|
5538
|
-
|
|
6176
|
+
if (skipConfig) {
|
|
6177
|
+
const { settings, watermark } = formatUploadConfig(config, secrets, {
|
|
6178
|
+
videoAspectRatio: videoAssetMetadata?.aspectRatio
|
|
6179
|
+
});
|
|
6180
|
+
startUpload(settings, watermark);
|
|
6181
|
+
}
|
|
5539
6182
|
}, []), skipConfig) return null;
|
|
5540
6183
|
const basicConfig = config.video_quality !== "plus" && config.video_quality !== "premium", playbackPolicySelected = config.public_policy || config.signed_policy || config.drm_policy, maxSupportedResolution = RESOLUTION_TIERS.findIndex(
|
|
5541
6184
|
(rt) => rt.value === pluginConfig.max_resolution_tier
|
|
@@ -5551,11 +6194,11 @@ function UploadConfiguration({
|
|
|
5551
6194
|
header: "Configure Mux Upload",
|
|
5552
6195
|
onClose,
|
|
5553
6196
|
children: /* @__PURE__ */ jsxs(Stack, { padding: 4, space: 2, children: [
|
|
5554
|
-
validationError && /* @__PURE__ */ jsx(Card, { padding: 3, tone: "critical", radius: 2, marginBottom: 2, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, align: "flex-start", children: [
|
|
6197
|
+
(validationError || watermarkValidationError) && /* @__PURE__ */ jsx(Card, { padding: 3, tone: "critical", radius: 2, marginBottom: 2, children: /* @__PURE__ */ jsxs(Flex, { gap: 2, align: "flex-start", children: [
|
|
5555
6198
|
/* @__PURE__ */ jsx(ErrorOutlineIcon, { width: 20, height: 20 }),
|
|
5556
6199
|
/* @__PURE__ */ jsxs(Stack, { space: 2, children: [
|
|
5557
6200
|
/* @__PURE__ */ jsx(Text, { size: 1, weight: "semibold", children: "Validation Error" }),
|
|
5558
|
-
/* @__PURE__ */ jsx(Text, { size: 1, children: validationError })
|
|
6201
|
+
/* @__PURE__ */ jsx(Text, { size: 1, children: validationError || watermarkValidationError })
|
|
5559
6202
|
] })
|
|
5560
6203
|
] }) }),
|
|
5561
6204
|
/* @__PURE__ */ jsx(Label$1, { size: 3, children: "FILE TO UPLOAD" }),
|
|
@@ -5622,27 +6265,41 @@ function UploadConfiguration({
|
|
|
5622
6265
|
}) })
|
|
5623
6266
|
}
|
|
5624
6267
|
),
|
|
5625
|
-
!basicConfig && /* @__PURE__ */
|
|
5626
|
-
/* @__PURE__ */ jsx(
|
|
5627
|
-
|
|
5628
|
-
|
|
6268
|
+
!basicConfig && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6269
|
+
/* @__PURE__ */ jsx(FormField$2, { title: "Additional Configuration", children: /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
6270
|
+
/* @__PURE__ */ jsx(PlaybackPolicy, { id, config, secrets, dispatch }),
|
|
6271
|
+
maxSupportedResolution > 0 && /* @__PURE__ */ jsx(
|
|
6272
|
+
ResolutionTierSelector,
|
|
6273
|
+
{
|
|
6274
|
+
id,
|
|
6275
|
+
config,
|
|
6276
|
+
dispatch,
|
|
6277
|
+
maxSupportedResolution
|
|
6278
|
+
}
|
|
6279
|
+
),
|
|
6280
|
+
/* @__PURE__ */ jsx(StaticRenditionSelector, { id, config, dispatch }),
|
|
6281
|
+
!disableTextTrackConfig && /* @__PURE__ */ jsx(
|
|
6282
|
+
TextTracksEditor,
|
|
6283
|
+
{
|
|
6284
|
+
tracks: config.text_tracks,
|
|
6285
|
+
dispatch,
|
|
6286
|
+
defaultLang: pluginConfig.defaultAutogeneratedSubtitleLang
|
|
6287
|
+
}
|
|
6288
|
+
)
|
|
6289
|
+
] }) }),
|
|
6290
|
+
/* @__PURE__ */ jsx(
|
|
6291
|
+
WatermarkSection,
|
|
5629
6292
|
{
|
|
5630
|
-
id,
|
|
5631
6293
|
config,
|
|
5632
6294
|
dispatch,
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5638
|
-
TextTracksEditor,
|
|
5639
|
-
{
|
|
5640
|
-
tracks: config.text_tracks,
|
|
5641
|
-
dispatch,
|
|
5642
|
-
defaultLang: pluginConfig.defaultAutogeneratedSubtitleLang
|
|
6295
|
+
stagedUpload,
|
|
6296
|
+
videoAssetMetadata,
|
|
6297
|
+
watermarkPreviewContainerRef,
|
|
6298
|
+
watermarkPreviewVideoRef,
|
|
6299
|
+
onValidationChange: setWatermarkValidationError
|
|
5643
6300
|
}
|
|
5644
6301
|
)
|
|
5645
|
-
] })
|
|
6302
|
+
] })
|
|
5646
6303
|
] }),
|
|
5647
6304
|
/* @__PURE__ */ jsx(Box, { marginTop: 4, children: /* @__PURE__ */ jsx(
|
|
5648
6305
|
Button,
|
|
@@ -5652,7 +6309,12 @@ function UploadConfiguration({
|
|
|
5652
6309
|
text: "Upload",
|
|
5653
6310
|
tone: "positive",
|
|
5654
6311
|
onClick: () => {
|
|
5655
|
-
|
|
6312
|
+
if (!validationError) {
|
|
6313
|
+
const { settings, watermark } = formatUploadConfig(config, secrets, {
|
|
6314
|
+
videoAspectRatio: videoAssetMetadata?.aspectRatio
|
|
6315
|
+
});
|
|
6316
|
+
startUpload(settings, watermark);
|
|
6317
|
+
}
|
|
5656
6318
|
}
|
|
5657
6319
|
}
|
|
5658
6320
|
) })
|
|
@@ -5667,36 +6329,178 @@ function setAdvancedPlaybackPolicy(config, secrets) {
|
|
|
5667
6329
|
drm_configuration_id: secrets.drmConfigId ?? void 0
|
|
5668
6330
|
}) : console.error("Selected DRM Policy but missing DRM Configuration Id")), advanced_playback_policies;
|
|
5669
6331
|
}
|
|
5670
|
-
function formatUploadConfig(config, secrets) {
|
|
6332
|
+
function formatUploadConfig(config, secrets, options) {
|
|
5671
6333
|
const generated_subtitles = config.text_tracks.filter(isAutogeneratedTrack).map((track) => ({
|
|
5672
6334
|
name: track.name,
|
|
5673
6335
|
language_code: track.language_code
|
|
5674
|
-
}))
|
|
6336
|
+
})), inputs = [
|
|
6337
|
+
{
|
|
6338
|
+
type: "video",
|
|
6339
|
+
generated_subtitles: generated_subtitles.length > 0 ? generated_subtitles : void 0
|
|
6340
|
+
},
|
|
6341
|
+
...config.text_tracks.filter(isCustomTextTrack).reduce(
|
|
6342
|
+
(acc, track) => (track.language_code && track.file && track.name && acc.push({
|
|
6343
|
+
url: track.file.contents,
|
|
6344
|
+
type: "text",
|
|
6345
|
+
text_type: track.type === "subtitles" ? "subtitles" : void 0,
|
|
6346
|
+
language_code: track.language_code,
|
|
6347
|
+
name: track.name,
|
|
6348
|
+
closed_captions: track.type === "captions"
|
|
6349
|
+
}), acc),
|
|
6350
|
+
[]
|
|
6351
|
+
)
|
|
6352
|
+
];
|
|
6353
|
+
if (config.watermark?.imageUrl) {
|
|
6354
|
+
const watermarkForMux = { ...config.watermark, enabled: !0 }, overlaySettings = convertWatermarkToMuxOverlay(watermarkForMux, {
|
|
6355
|
+
videoAspectRatio: options?.videoAspectRatio ?? void 0,
|
|
6356
|
+
units: "px"
|
|
6357
|
+
});
|
|
6358
|
+
overlaySettings && inputs.push({
|
|
6359
|
+
url: config.watermark.imageUrl,
|
|
6360
|
+
overlay_settings: overlaySettings
|
|
6361
|
+
});
|
|
6362
|
+
}
|
|
5675
6363
|
return {
|
|
5676
|
-
|
|
5677
|
-
|
|
5678
|
-
|
|
5679
|
-
|
|
5680
|
-
|
|
5681
|
-
|
|
5682
|
-
|
|
5683
|
-
|
|
5684
|
-
|
|
5685
|
-
text_type: track.type === "subtitles" ? "subtitles" : void 0,
|
|
5686
|
-
language_code: track.language_code,
|
|
5687
|
-
name: track.name,
|
|
5688
|
-
closed_captions: track.type === "captions"
|
|
5689
|
-
}), acc),
|
|
5690
|
-
[]
|
|
5691
|
-
)
|
|
5692
|
-
],
|
|
5693
|
-
static_renditions: config.static_renditions.length > 0 ? config.static_renditions.map((resolution) => ({ resolution })) : void 0,
|
|
5694
|
-
advanced_playback_policies: setAdvancedPlaybackPolicy(config, secrets),
|
|
5695
|
-
max_resolution_tier: config.max_resolution_tier,
|
|
5696
|
-
video_quality: config.video_quality,
|
|
5697
|
-
normalize_audio: config.normalize_audio
|
|
6364
|
+
settings: {
|
|
6365
|
+
input: inputs,
|
|
6366
|
+
static_renditions: config.static_renditions.length > 0 ? config.static_renditions.map((resolution) => ({ resolution })) : void 0,
|
|
6367
|
+
advanced_playback_policies: setAdvancedPlaybackPolicy(config, secrets),
|
|
6368
|
+
max_resolution_tier: config.max_resolution_tier,
|
|
6369
|
+
video_quality: config.video_quality,
|
|
6370
|
+
normalize_audio: config.normalize_audio
|
|
6371
|
+
},
|
|
6372
|
+
watermark: config.watermark?.imageUrl ? { ...config.watermark, enabled: !0 } : void 0
|
|
5698
6373
|
};
|
|
5699
6374
|
}
|
|
6375
|
+
function WatermarkSection({
|
|
6376
|
+
config,
|
|
6377
|
+
dispatch,
|
|
6378
|
+
stagedUpload,
|
|
6379
|
+
videoAssetMetadata,
|
|
6380
|
+
watermarkPreviewContainerRef,
|
|
6381
|
+
watermarkPreviewVideoRef,
|
|
6382
|
+
onValidationChange
|
|
6383
|
+
}) {
|
|
6384
|
+
return videoAssetMetadata?.isAudioOnly !== !1 ? null : /* @__PURE__ */ jsx(
|
|
6385
|
+
FormField$2,
|
|
6386
|
+
{
|
|
6387
|
+
title: "Watermark",
|
|
6388
|
+
description: /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
6389
|
+
"Add a watermark overlay to your video using Mux's native watermark support.",
|
|
6390
|
+
" ",
|
|
6391
|
+
/* @__PURE__ */ jsx(
|
|
6392
|
+
"a",
|
|
6393
|
+
{
|
|
6394
|
+
href: "https://www.mux.com/docs/guides/add-watermarks-to-your-videos",
|
|
6395
|
+
target: "_blank",
|
|
6396
|
+
rel: "noopener noreferrer",
|
|
6397
|
+
children: "Learn more about Mux watermarks."
|
|
6398
|
+
}
|
|
6399
|
+
)
|
|
6400
|
+
] }),
|
|
6401
|
+
children: /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
6402
|
+
/* @__PURE__ */ jsx(
|
|
6403
|
+
WatermarkControls,
|
|
6404
|
+
{
|
|
6405
|
+
watermark: config.watermark || { enabled: !1 },
|
|
6406
|
+
onChange: (watermark) => {
|
|
6407
|
+
dispatch({ action: "watermark", value: watermark });
|
|
6408
|
+
},
|
|
6409
|
+
onValidationChange,
|
|
6410
|
+
previewContainerRef: watermarkPreviewContainerRef,
|
|
6411
|
+
previewVideoRef: watermarkPreviewVideoRef
|
|
6412
|
+
}
|
|
6413
|
+
),
|
|
6414
|
+
config.watermark?.imageUrl && stagedUpload.type === "file" && // Canvas preview is only shown in "Canvas" mode (no explicit overlay_settings)
|
|
6415
|
+
!config.watermark.overlay_settings && /* @__PURE__ */ jsx(
|
|
6416
|
+
WatermarkPreview,
|
|
6417
|
+
{
|
|
6418
|
+
stagedUpload,
|
|
6419
|
+
watermark: config.watermark,
|
|
6420
|
+
videoAspectRatio: videoAssetMetadata.aspectRatio,
|
|
6421
|
+
onWatermarkChange: (watermark) => {
|
|
6422
|
+
dispatch({ action: "watermark", value: watermark });
|
|
6423
|
+
},
|
|
6424
|
+
previewContainerRef: watermarkPreviewContainerRef,
|
|
6425
|
+
videoRef: watermarkPreviewVideoRef
|
|
6426
|
+
}
|
|
6427
|
+
)
|
|
6428
|
+
] })
|
|
6429
|
+
}
|
|
6430
|
+
);
|
|
6431
|
+
}
|
|
6432
|
+
const WatermarkPreview = memo(function({
|
|
6433
|
+
stagedUpload,
|
|
6434
|
+
watermark,
|
|
6435
|
+
onWatermarkChange,
|
|
6436
|
+
videoAspectRatio,
|
|
6437
|
+
previewContainerRef,
|
|
6438
|
+
videoRef
|
|
6439
|
+
}) {
|
|
6440
|
+
useEffect(() => {
|
|
6441
|
+
if (videoRef.current && stagedUpload.type === "file") {
|
|
6442
|
+
const file = stagedUpload.files[0], url = URL.createObjectURL(file);
|
|
6443
|
+
return videoRef.current.src = url, () => {
|
|
6444
|
+
URL.revokeObjectURL(url);
|
|
6445
|
+
};
|
|
6446
|
+
}
|
|
6447
|
+
}, [stagedUpload, videoRef]);
|
|
6448
|
+
const isVertical = videoAspectRatio != null && videoAspectRatio < 1;
|
|
6449
|
+
return /* @__PURE__ */ jsx(
|
|
6450
|
+
Card,
|
|
6451
|
+
{
|
|
6452
|
+
tone: "transparent",
|
|
6453
|
+
border: !0,
|
|
6454
|
+
style: {
|
|
6455
|
+
overflow: "hidden",
|
|
6456
|
+
// For vertical videos, center the preview and limit its width
|
|
6457
|
+
display: "flex",
|
|
6458
|
+
justifyContent: "center"
|
|
6459
|
+
},
|
|
6460
|
+
children: /* @__PURE__ */ jsxs(
|
|
6461
|
+
"div",
|
|
6462
|
+
{
|
|
6463
|
+
ref: previewContainerRef,
|
|
6464
|
+
style: {
|
|
6465
|
+
position: "relative",
|
|
6466
|
+
// For vertical videos: limit width so the preview doesn't get too tall
|
|
6467
|
+
// For horizontal videos: use full width
|
|
6468
|
+
width: isVertical ? "auto" : "100%",
|
|
6469
|
+
aspectRatio: videoAspectRatio ? String(videoAspectRatio) : "16/9",
|
|
6470
|
+
...isVertical ? { height: "400px", maxHeight: "50vh" } : { minHeight: "200px" },
|
|
6471
|
+
overflow: "hidden"
|
|
6472
|
+
},
|
|
6473
|
+
children: [
|
|
6474
|
+
/* @__PURE__ */ jsx(
|
|
6475
|
+
"video",
|
|
6476
|
+
{
|
|
6477
|
+
ref: videoRef,
|
|
6478
|
+
style: {
|
|
6479
|
+
position: "absolute",
|
|
6480
|
+
top: 0,
|
|
6481
|
+
left: 0,
|
|
6482
|
+
width: "100%",
|
|
6483
|
+
height: "100%",
|
|
6484
|
+
objectFit: "fill",
|
|
6485
|
+
display: "block"
|
|
6486
|
+
}
|
|
6487
|
+
}
|
|
6488
|
+
),
|
|
6489
|
+
/* @__PURE__ */ jsx(
|
|
6490
|
+
DraggableWatermark,
|
|
6491
|
+
{
|
|
6492
|
+
watermark,
|
|
6493
|
+
onChange: onWatermarkChange,
|
|
6494
|
+
containerRef: previewContainerRef,
|
|
6495
|
+
videoElementRef: videoRef
|
|
6496
|
+
}
|
|
6497
|
+
)
|
|
6498
|
+
]
|
|
6499
|
+
}
|
|
6500
|
+
)
|
|
6501
|
+
}
|
|
6502
|
+
);
|
|
6503
|
+
});
|
|
5700
6504
|
function withFocusRing(component) {
|
|
5701
6505
|
return styled(component)((props) => {
|
|
5702
6506
|
const border = {
|
|
@@ -5935,7 +6739,7 @@ function Uploader(props) {
|
|
|
5935
6739
|
window.removeEventListener("beforeunload", handleBeforeUnload), window.removeEventListener("pagehide", handleBeforeUnload), cleanup();
|
|
5936
6740
|
};
|
|
5937
6741
|
}, [props.client, props.asset?._id]);
|
|
5938
|
-
const startUpload = (settings) => {
|
|
6742
|
+
const startUpload = (settings, watermark) => {
|
|
5939
6743
|
const { stagedUpload } = state;
|
|
5940
6744
|
if (!stagedUpload || uploadRef.current) return;
|
|
5941
6745
|
dispatch({ action: "commitUpload" });
|
|
@@ -5945,14 +6749,16 @@ function Uploader(props) {
|
|
|
5945
6749
|
uploadObservable = uploadUrl({
|
|
5946
6750
|
client: props.client,
|
|
5947
6751
|
url: stagedUpload.url,
|
|
5948
|
-
settings
|
|
6752
|
+
settings,
|
|
6753
|
+
watermark
|
|
5949
6754
|
});
|
|
5950
6755
|
break;
|
|
5951
6756
|
case "file":
|
|
5952
6757
|
uploadObservable = uploadFile({
|
|
5953
6758
|
client: props.client,
|
|
5954
6759
|
file: stagedUpload.files[0],
|
|
5955
|
-
settings
|
|
6760
|
+
settings,
|
|
6761
|
+
watermark
|
|
5956
6762
|
}).pipe(
|
|
5957
6763
|
takeUntil(
|
|
5958
6764
|
cancelUploadButton.observable.pipe(
|