sanity-plugin-mux-input 2.0.2 → 2.0.4

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.
Files changed (49) hide show
  1. package/LICENSE +1 -1
  2. package/lib/_chunks/Input-4e0aa2ef.js +2652 -0
  3. package/lib/_chunks/Input-4e0aa2ef.js.map +1 -0
  4. package/lib/_chunks/Input-7fb0dcd2.js +2682 -0
  5. package/lib/_chunks/Input-7fb0dcd2.js.map +1 -0
  6. package/lib/_chunks/Preview-3e4c2ec9.js +26 -0
  7. package/lib/_chunks/{Preview-3195237b.js.map → Preview-3e4c2ec9.js.map} +1 -1
  8. package/lib/_chunks/Preview-e6f7e765.js +28 -0
  9. package/lib/_chunks/Preview-e6f7e765.js.map +1 -0
  10. package/lib/_chunks/VideoSource.styled-70d38762.js +336 -0
  11. package/lib/_chunks/VideoSource.styled-70d38762.js.map +1 -0
  12. package/lib/_chunks/VideoSource.styled-e880b6e4.js +318 -0
  13. package/lib/_chunks/VideoSource.styled-e880b6e4.js.map +1 -0
  14. package/lib/_chunks/index-a9d40189.js +248 -0
  15. package/lib/_chunks/index-a9d40189.js.map +1 -0
  16. package/lib/_chunks/index-adfcd166.js +265 -0
  17. package/lib/_chunks/index-adfcd166.js.map +1 -0
  18. package/lib/{src/index.d.ts → index.d.ts} +0 -0
  19. package/lib/index.esm.js +2 -1
  20. package/lib/index.esm.js.map +1 -1
  21. package/lib/index.js +9 -1
  22. package/lib/index.js.map +1 -1
  23. package/package.json +28 -35
  24. package/src/actions/assets.ts +1 -1
  25. package/src/actions/secrets.ts +12 -3
  26. package/src/actions/upload.ts +1 -1
  27. package/src/components/__legacy__Uploader.tsx +1 -1
  28. package/src/hooks/useSaveSecrets.ts +1 -1
  29. package/src/util/generateJwt.ts +1 -1
  30. package/src/util/getAnimatedPosterSrc.ts +1 -1
  31. package/src/util/getPosterSrc.ts +1 -1
  32. package/src/util/getStoryboardSrc.ts +1 -1
  33. package/src/util/getVideoSrc.ts +1 -1
  34. package/src/util/readSecrets.ts +1 -1
  35. package/lib/_chunks/Input-2ba004d3.js +0 -2
  36. package/lib/_chunks/Input-2ba004d3.js.map +0 -1
  37. package/lib/_chunks/Input-af5a0a66.esm.js +0 -2
  38. package/lib/_chunks/Input-af5a0a66.esm.js.map +0 -1
  39. package/lib/_chunks/Preview-3195237b.js +0 -2
  40. package/lib/_chunks/Preview-bb256342.esm.js +0 -2
  41. package/lib/_chunks/Preview-bb256342.esm.js.map +0 -1
  42. package/lib/_chunks/VideoSource.styled-1b994d90.js +0 -2
  43. package/lib/_chunks/VideoSource.styled-1b994d90.js.map +0 -1
  44. package/lib/_chunks/VideoSource.styled-f92259cd.esm.js +0 -2
  45. package/lib/_chunks/VideoSource.styled-f92259cd.esm.js.map +0 -1
  46. package/lib/_chunks/index-3d8d7583.esm.js +0 -2
  47. package/lib/_chunks/index-3d8d7583.esm.js.map +0 -1
  48. package/lib/_chunks/index-efe6ce48.js +0 -2
  49. package/lib/_chunks/index-efe6ce48.js.map +0 -1
@@ -0,0 +1,2652 @@
1
+ var _templateObject, _templateObject2, _templateObject3, _templateObject4, _templateObject5, _templateObject6, _templateObject7, _templateObject8, _templateObject9, _templateObject10, _templateObject11, _templateObject12, _templateObject13, _templateObject14, _templateObject15, _templateObject16, _templateObject17, _templateObject18, _templateObject19;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
4
+ import React, { useState, useMemo, memo, useRef, useLayoutEffect, useCallback, useId, useEffect, isValidElement, createElement, forwardRef, Component, useReducer } from 'react';
5
+ import { useClient, VideoThumbnail, AnimatedVideoThumbnail, ThumbGrid, CardLoadMore, getPlaybackId, getPlaybackPolicy, generateJwt, getPosterSrc, _id, useAssetDocumentValues } from './VideoSource.styled-e880b6e4.js';
6
+ import { useProjectId, useDataset, useDocumentValues, PatchEvent, setIfMissing, set, unset, LinearProgress } from 'sanity';
7
+ import useSWR from 'swr';
8
+ import { muxSecretsDocumentId, cacheNs, InputFallback } from './index-a9d40189.js';
9
+ import { Observable, defer, concat, of, throwError, from, Subject } from 'rxjs';
10
+ import { switchMap, mergeMap, catchError, mergeMapTo, takeUntil, tap } from 'rxjs/operators';
11
+ import { uuid } from '@sanity/uuid';
12
+ import * as UpChunk from '@mux/upchunk';
13
+ import { Card, Box, Flex, Spinner, Text, Button, useClickOutside, MenuButton, Menu, MenuItem, useToast, Dialog, Grid, Stack, Checkbox, Code, Inline, Tooltip, Popover, Label as Label$1, MenuDivider, rem, TextInput, Heading } from '@sanity/ui';
14
+ import { DownloadIcon, EllipsisVerticalIcon, TrashIcon, LockIcon, EditIcon, UploadIcon, SearchIcon, PlugIcon, ResetIcon, DocumentVideoIcon } from '@sanity/icons';
15
+ import { animate } from 'motion';
16
+ import styled, { css } from 'styled-components';
17
+ import { getDevicePixelRatio } from 'use-device-pixel-ratio';
18
+ import { generatePlayerInitTime, initialize } from '@mux/playback-core';
19
+ import { MediaControlBar, MediaPosterImage, MediaController, MediaLoadingIndicator, MediaPlayButton, MediaMuteButton, MediaTimeDisplay, MediaTimeRange, MediaDurationDisplay, MediaFullscreenButton } from 'media-chrome/dist/react';
20
+ import { isValidElementType } from 'react-is';
21
+ import { clear, preload } from 'suspend-react';
22
+ function useDialogState() {
23
+ return useState(false);
24
+ }
25
+ const useMuxPolling = asset => {
26
+ var _a, _b;
27
+ const client = useClient();
28
+ const projectId = useProjectId();
29
+ const dataset = useDataset();
30
+ const shouldFetch = useMemo(() => {
31
+ var _a2, _b2;
32
+ return !!(asset == null ? void 0 : asset.assetId) && ((asset == null ? void 0 : asset.status) === "preparing" || ((_b2 = (_a2 = asset == null ? void 0 : asset.data) == null ? void 0 : _a2.static_renditions) == null ? void 0 : _b2.status) === "preparing");
33
+ }, [asset == null ? void 0 : asset.assetId, (_b = (_a = asset == null ? void 0 : asset.data) == null ? void 0 : _a.static_renditions) == null ? void 0 : _b.status, asset == null ? void 0 : asset.status]);
34
+ return useSWR(shouldFetch ? "/".concat(projectId, "/addons/mux/assets/").concat(dataset, "/data/").concat(asset == null ? void 0 : asset.assetId) : null, async () => {
35
+ const {
36
+ data
37
+ } = await client.request({
38
+ url: "/addons/mux/assets/".concat(dataset, "/data/").concat(asset.assetId),
39
+ withCredentials: true,
40
+ method: "GET"
41
+ });
42
+ client.patch(asset._id).set({
43
+ status: data.status,
44
+ data
45
+ }).commit({
46
+ returnDocuments: false
47
+ });
48
+ }, {
49
+ refreshInterval: 2e3,
50
+ refreshWhenHidden: true,
51
+ dedupingInterval: 1e3
52
+ });
53
+ };
54
+ const path = ["token", "secretKey", "enableSignedUrls", "signingKeyId", "signingKeyPrivate"];
55
+ const useSecretsDocumentValues = () => {
56
+ const {
57
+ error,
58
+ isLoading,
59
+ value
60
+ } = useDocumentValues(muxSecretsDocumentId, path);
61
+ const cache = useMemo(() => {
62
+ const exists = Boolean(value);
63
+ const secrets = {
64
+ token: (value == null ? void 0 : value.token) || null,
65
+ secretKey: (value == null ? void 0 : value.secretKey) || null,
66
+ enableSignedUrls: (value == null ? void 0 : value.enableSignedUrls) || false,
67
+ signingKeyId: (value == null ? void 0 : value.signingKeyId) || null,
68
+ signingKeyPrivate: (value == null ? void 0 : value.signingKeyPrivate) || null
69
+ };
70
+ return {
71
+ isInitialSetup: !exists,
72
+ needsSetup: !(secrets == null ? void 0 : secrets.token) || !(secrets == null ? void 0 : secrets.secretKey),
73
+ secrets
74
+ };
75
+ }, [value]);
76
+ return {
77
+ error,
78
+ isLoading,
79
+ value: cache
80
+ };
81
+ };
82
+ function createUpChunkObservable(uuid, uploadUrl, source) {
83
+ return new Observable(subscriber => {
84
+ const upchunk = UpChunk.createUpload({
85
+ endpoint: uploadUrl,
86
+ file: source,
87
+ dynamicChunkSize: true
88
+ // changes the chunk size based on network speeds
89
+ });
90
+
91
+ const successHandler = () => {
92
+ subscriber.next({
93
+ type: "success",
94
+ id: uuid
95
+ });
96
+ subscriber.complete();
97
+ };
98
+ const errorHandler = data => subscriber.error(new Error(data.detail.message));
99
+ const progressHandler = data => {
100
+ return subscriber.next({
101
+ type: "progress",
102
+ percent: data.detail
103
+ });
104
+ };
105
+ const offlineHandler = () => {
106
+ upchunk.pause();
107
+ subscriber.next({
108
+ type: "pause",
109
+ id: uuid
110
+ });
111
+ };
112
+ const onlineHandler = () => {
113
+ upchunk.resume();
114
+ subscriber.next({
115
+ type: "resume",
116
+ id: uuid
117
+ });
118
+ };
119
+ upchunk.on("success", successHandler);
120
+ upchunk.on("error", errorHandler);
121
+ upchunk.on("progress", progressHandler);
122
+ upchunk.on("offline", offlineHandler);
123
+ upchunk.on("online", onlineHandler);
124
+ return () => upchunk.abort();
125
+ });
126
+ }
127
+ function deleteAsset(client, assetId) {
128
+ const {
129
+ dataset
130
+ } = client.config();
131
+ return client.request({
132
+ url: "/addons/mux/assets/".concat(dataset, "/").concat(assetId),
133
+ withCredentials: true,
134
+ method: "DELETE"
135
+ });
136
+ }
137
+ function getAsset(client, assetId) {
138
+ const {
139
+ dataset
140
+ } = client.config();
141
+ return client.request({
142
+ url: "/addons/mux/assets/".concat(dataset, "/data/").concat(assetId),
143
+ withCredentials: true,
144
+ method: "GET"
145
+ });
146
+ }
147
+ function saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate) {
148
+ const doc = {
149
+ _id: "secrets.mux",
150
+ _type: "mux.apiKey",
151
+ token,
152
+ secretKey,
153
+ enableSignedUrls,
154
+ signingKeyId,
155
+ signingKeyPrivate
156
+ };
157
+ return client.createOrReplace(doc);
158
+ }
159
+ function createSigningKeys(client) {
160
+ const {
161
+ dataset
162
+ } = client.config();
163
+ return client.request({
164
+ url: "/addons/mux/signing-keys/".concat(dataset),
165
+ withCredentials: true,
166
+ method: "POST"
167
+ });
168
+ }
169
+ function testSecrets(client) {
170
+ const {
171
+ dataset
172
+ } = client.config();
173
+ return client.request({
174
+ url: "/addons/mux/secrets/".concat(dataset, "/test"),
175
+ withCredentials: true,
176
+ method: "GET"
177
+ });
178
+ }
179
+ async function haveValidSigningKeys(client, signingKeyId, signingKeyPrivate) {
180
+ if (!(signingKeyId && signingKeyPrivate)) {
181
+ return false;
182
+ }
183
+ const {
184
+ dataset
185
+ } = client.config();
186
+ try {
187
+ const res = await client.request({
188
+ url: "/addons/mux/signing-keys/".concat(dataset, "/").concat(signingKeyId),
189
+ withCredentials: true,
190
+ method: "GET"
191
+ });
192
+ return !!(res.data && res.data.id);
193
+ } catch (e) {
194
+ console.error("Error fetching signingKeyId", signingKeyId, "assuming it is not valid");
195
+ return false;
196
+ }
197
+ }
198
+ function testSecretsObservable(client) {
199
+ const {
200
+ dataset
201
+ } = client.config();
202
+ return defer(() => client.observable.request({
203
+ url: "/addons/mux/secrets/".concat(dataset, "/test"),
204
+ withCredentials: true,
205
+ method: "GET"
206
+ }));
207
+ }
208
+ function cancelUpload(client, uuid) {
209
+ return client.observable.request({
210
+ url: "/addons/mux/uploads/".concat(client.clientConfig.dataset, "/").concat(uuid),
211
+ withCredentials: true,
212
+ method: "DELETE"
213
+ });
214
+ }
215
+ function uploadUrl(config, client, url) {
216
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
217
+ return testUrl(url).pipe(switchMap(validUrl => {
218
+ return concat(of({
219
+ type: "url",
220
+ url: validUrl
221
+ }), testSecretsObservable(client).pipe(switchMap(json => {
222
+ if (!json || !json.status) {
223
+ return throwError(new Error("Invalid credentials"));
224
+ }
225
+ const uuid$1 = uuid();
226
+ const {
227
+ enableSignedUrls
228
+ } = options;
229
+ const muxBody = {
230
+ input: validUrl,
231
+ playback_policy: [enableSignedUrls ? "signed" : "public"],
232
+ mp4_support: config.mp4_support
233
+ };
234
+ const query = {
235
+ muxBody: JSON.stringify(muxBody),
236
+ filename: validUrl.split("/").slice(-1)[0]
237
+ };
238
+ const dataset = client.clientConfig.dataset;
239
+ return defer(() => client.observable.request({
240
+ url: "/addons/mux/assets/".concat(dataset),
241
+ withCredentials: true,
242
+ method: "POST",
243
+ headers: {
244
+ "MUX-Proxy-UUID": uuid$1,
245
+ "Content-Type": "application/json"
246
+ },
247
+ query
248
+ })).pipe(mergeMap(result => {
249
+ const asset = result && result.results && result.results[0] && result.results[0].document || null;
250
+ if (!asset) {
251
+ return throwError(new Error("No asset document returned"));
252
+ }
253
+ return of({
254
+ type: "success",
255
+ id: uuid$1,
256
+ asset
257
+ });
258
+ }));
259
+ })));
260
+ }));
261
+ }
262
+ function uploadFile(config, client, file) {
263
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
264
+ return testFile(file).pipe(switchMap(fileOptions => {
265
+ return concat(of({
266
+ type: "file",
267
+ file: fileOptions
268
+ }), testSecretsObservable(client).pipe(switchMap(json => {
269
+ if (!json || !json.status) {
270
+ return throwError(new Error("Invalid credentials"));
271
+ }
272
+ const uuid$1 = uuid();
273
+ const {
274
+ enableSignedUrls
275
+ } = options;
276
+ const body = {
277
+ mp4_support: config.mp4_support,
278
+ playback_policy: [enableSignedUrls ? "signed" : "public"]
279
+ };
280
+ return concat(of({
281
+ type: "uuid",
282
+ uuid: uuid$1
283
+ }), defer(() => client.observable.request({
284
+ url: "/addons/mux/uploads/".concat(client.clientConfig.dataset),
285
+ withCredentials: true,
286
+ method: "POST",
287
+ headers: {
288
+ "MUX-Proxy-UUID": uuid$1,
289
+ "Content-Type": "application/json"
290
+ },
291
+ body
292
+ })).pipe(mergeMap(result => {
293
+ return createUpChunkObservable(uuid$1, result.upload.url, file).pipe(
294
+ // eslint-disable-next-line no-warning-comments
295
+ // @TODO type the observable events
296
+ // eslint-disable-next-line max-nested-callbacks
297
+ mergeMap(event => {
298
+ if (event.type !== "success") {
299
+ return of(event);
300
+ }
301
+ return from(updateAssetDocumentFromUpload(client, uuid$1)).pipe(
302
+ // eslint-disable-next-line max-nested-callbacks
303
+ mergeMap(doc => of({
304
+ ...event,
305
+ asset: doc
306
+ })));
307
+ }),
308
+ // eslint-disable-next-line max-nested-callbacks
309
+ catchError(err => {
310
+ return cancelUpload(client, uuid$1).pipe(mergeMapTo(throwError(err)));
311
+ }));
312
+ })));
313
+ })));
314
+ }));
315
+ }
316
+ function getUpload(client, assetId) {
317
+ const {
318
+ dataset
319
+ } = client.config();
320
+ return client.request({
321
+ url: "/addons/mux/uploads/".concat(dataset, "/").concat(assetId),
322
+ withCredentials: true,
323
+ method: "GET"
324
+ });
325
+ }
326
+ function pollUpload(client, uuid) {
327
+ const maxTries = 10;
328
+ let pollInterval;
329
+ let tries = 0;
330
+ let assetId;
331
+ let upload;
332
+ return new Promise((resolve, reject) => {
333
+ pollInterval = setInterval(async () => {
334
+ try {
335
+ upload = await getUpload(client, uuid);
336
+ } catch (err) {
337
+ reject(err);
338
+ return;
339
+ }
340
+ assetId = upload && upload.data && upload.data.asset_id;
341
+ if (assetId) {
342
+ clearInterval(pollInterval);
343
+ resolve(upload);
344
+ }
345
+ if (tries > maxTries) {
346
+ clearInterval(pollInterval);
347
+ reject(new Error("Upload did not finish"));
348
+ }
349
+ tries++;
350
+ }, 2e3);
351
+ });
352
+ }
353
+ async function updateAssetDocumentFromUpload(client, uuid) {
354
+ let upload;
355
+ let asset;
356
+ try {
357
+ upload = await pollUpload(client, uuid);
358
+ } catch (err) {
359
+ return Promise.reject(err);
360
+ }
361
+ try {
362
+ asset = await getAsset(client, upload.data.asset_id);
363
+ } catch (err) {
364
+ return Promise.reject(err);
365
+ }
366
+ const doc = {
367
+ _id: uuid,
368
+ _type: "mux.videoAsset",
369
+ status: asset.data.status,
370
+ data: asset.data,
371
+ assetId: asset.data.id,
372
+ playbackId: asset.data.playback_ids[0].id,
373
+ uploadId: upload.data.id
374
+ };
375
+ return client.createOrReplace(doc).then(() => {
376
+ return doc;
377
+ });
378
+ }
379
+ function testFile(file) {
380
+ if (typeof window !== "undefined" && file instanceof window.File) {
381
+ const fileOptions = optionsFromFile({}, file);
382
+ return of(fileOptions);
383
+ }
384
+ return throwError(new Error("Invalid file"));
385
+ }
386
+ function testUrl(url) {
387
+ const error = new Error("Invalid URL");
388
+ if (typeof url !== "string") {
389
+ return throwError(error);
390
+ }
391
+ let parsed;
392
+ try {
393
+ parsed = new URL(url);
394
+ } catch (err) {
395
+ return throwError(error);
396
+ }
397
+ if (parsed && !parsed.protocol.match(/http:|https:/)) {
398
+ return throwError(error);
399
+ }
400
+ return of(url);
401
+ }
402
+ function optionsFromFile(opts, file) {
403
+ if (typeof window === "undefined" || !(file instanceof window.File)) {
404
+ return opts;
405
+ }
406
+ return {
407
+ name: opts.preserveFilename === false ? void 0 : file.name,
408
+ type: file.type
409
+ };
410
+ }
411
+ function extractDroppedFiles(dataTransfer) {
412
+ const files = Array.from(dataTransfer.files || []);
413
+ const items = Array.from(dataTransfer.items || []);
414
+ if (files && files.length > 0) {
415
+ return Promise.resolve(files);
416
+ }
417
+ return normalizeItems(items).then(arr => arr.flat());
418
+ }
419
+ function normalizeItems(items) {
420
+ return Promise.all(items.map(item => {
421
+ if (item.kind === "file" && item.webkitGetAsEntry) {
422
+ let entry;
423
+ try {
424
+ entry = item.webkitGetAsEntry();
425
+ } catch (err) {
426
+ return [item.getAsFile()];
427
+ }
428
+ if (!entry) {
429
+ return [];
430
+ }
431
+ return entry.isDirectory ? walk(entry) : [item.getAsFile()];
432
+ }
433
+ if (item.kind === "file") {
434
+ const file = item.getAsFile();
435
+ return Promise.resolve(file ? [file] : []);
436
+ }
437
+ return new Promise(resolve => item.getAsString(resolve)).then(str => str ? [new File([str], "unknown.txt", {
438
+ type: item.type
439
+ })] : []);
440
+ }));
441
+ }
442
+ function isFile(entry) {
443
+ return entry.isFile;
444
+ }
445
+ function isDirectory(entry) {
446
+ return entry.isDirectory;
447
+ }
448
+ function walk(entry) {
449
+ if (isFile(entry)) {
450
+ return new Promise(resolve => entry.file(resolve)).then(file => [file]);
451
+ }
452
+ if (isDirectory(entry)) {
453
+ const dir = entry.createReader();
454
+ return new Promise(resolve => dir.readEntries(resolve)).then(entries => entries.filter(entr => !entr.name.startsWith("."))).then(entries => Promise.all(entries.map(walk)).then(arr => arr.flat()));
455
+ }
456
+ return Promise.resolve([]);
457
+ }
458
+ function AssetActionsMenu(props) {
459
+ const {
460
+ asset
461
+ } = props;
462
+ const id = useId();
463
+ const [dialogState, setDialogState] = useState();
464
+ const [open, setOpen] = useState(false);
465
+ const [menuElement, setMenuRef] = useState(null);
466
+ const handleDelete = useCallback(() => setDialogState("confirm-delete"), []);
467
+ const handleClick = useCallback(() => {
468
+ setDialogState(false);
469
+ setOpen(true);
470
+ }, [setDialogState]);
471
+ const handleClose = useCallback(() => {
472
+ setDialogState(false);
473
+ setOpen(false);
474
+ }, [setDialogState]);
475
+ useEffect(() => {
476
+ if (open && dialogState) {
477
+ setOpen(false);
478
+ }
479
+ }, [dialogState, open]);
480
+ useClickOutside(useCallback(() => setOpen(false), []), [menuElement]);
481
+ return /* @__PURE__ */jsxs(Fragment, {
482
+ children: [/* @__PURE__ */jsx(MenuButton, {
483
+ id: "".concat(id, "-asset-menu"),
484
+ button: /* @__PURE__ */jsx(Button, {
485
+ icon: EllipsisVerticalIcon,
486
+ mode: "ghost",
487
+ onClick: handleClick,
488
+ padding: 2
489
+ }),
490
+ menu: /* @__PURE__ */jsx(Menu, {
491
+ ref: setMenuRef,
492
+ children: /* @__PURE__ */jsx(MenuItem, {
493
+ tone: "critical",
494
+ icon: TrashIcon,
495
+ text: "Delete",
496
+ onClick: handleDelete
497
+ })
498
+ }),
499
+ portal: true,
500
+ placement: "right"
501
+ }), dialogState === "confirm-delete" && /* @__PURE__ */jsx(DeleteDialog, {
502
+ asset,
503
+ onClose: handleClose
504
+ })]
505
+ });
506
+ }
507
+ function DeleteDialog(props) {
508
+ const {
509
+ asset,
510
+ onClose
511
+ } = props;
512
+ const client = useClient();
513
+ const {
514
+ push: pushToast
515
+ } = useToast();
516
+ const [deleting, setDeleting] = useState(false);
517
+ const [deleteOnMux, setDeleteOnMux] = useState(false);
518
+ const id = useId();
519
+ const width = 200 * getDevicePixelRatio({
520
+ maxDpr: 2
521
+ });
522
+ const handleDelete = useCallback(async () => {
523
+ var _a, _b, _c;
524
+ setDeleting(true);
525
+ try {
526
+ if (asset == null ? void 0 : asset._id) {
527
+ await client.delete(asset._id);
528
+ }
529
+ if (deleteOnMux && (asset == null ? void 0 : asset.assetId)) {
530
+ await deleteAsset(client, asset.assetId);
531
+ }
532
+ (_c = (_b = (_a = document.querySelector("[data-id=\"".concat(asset._id, "\"]"))) == null ? void 0 : _a.parentElement) == null ? void 0 : _b.setAttribute) == null ? void 0 : _c.call(_b, "hidden", "true");
533
+ } catch (err) {
534
+ console.error("Failed during delete", err);
535
+ pushToast({
536
+ closable: true,
537
+ description: err == null ? void 0 : err.message,
538
+ duration: 5e3,
539
+ title: "Uncaught error",
540
+ status: "error"
541
+ });
542
+ } finally {
543
+ setDeleting(false);
544
+ onClose();
545
+ }
546
+ }, [asset._id, asset.assetId, client, deleteOnMux, onClose, pushToast]);
547
+ return /* @__PURE__ */jsx(Dialog, {
548
+ onClose,
549
+ id: "".concat(id, "-confirm-delete"),
550
+ header: "Delete video",
551
+ footer: /* @__PURE__ */jsxs(Grid, {
552
+ padding: 2,
553
+ gap: 2,
554
+ columns: 2,
555
+ children: [/* @__PURE__ */jsx(Button, {
556
+ mode: "bleed",
557
+ text: "Cancel",
558
+ onClick: onClose
559
+ }), /* @__PURE__ */jsx(Button, {
560
+ text: "Delete",
561
+ tone: "critical",
562
+ icon: TrashIcon,
563
+ onClick: handleDelete,
564
+ loading: deleting
565
+ })]
566
+ }),
567
+ width: 1,
568
+ children: /* @__PURE__ */jsx(Stack, {
569
+ paddingX: 0,
570
+ paddingY: 0,
571
+ space: 1,
572
+ children: /* @__PURE__ */jsx(Card, {
573
+ paddingX: [2, 3, 4],
574
+ paddingY: [3, 3, 3, 4],
575
+ children: /* @__PURE__ */jsxs(Grid, {
576
+ columns: 3,
577
+ gap: 3,
578
+ children: [/* @__PURE__ */jsx(Flex, {
579
+ style: {
580
+ gridColumn: "span 2"
581
+ },
582
+ align: "center",
583
+ children: /* @__PURE__ */jsx(Box, {
584
+ padding: 4,
585
+ children: /* @__PURE__ */jsxs(Stack, {
586
+ space: 4,
587
+ children: [/* @__PURE__ */jsxs(Flex, {
588
+ align: "center",
589
+ as: "label",
590
+ children: [/* @__PURE__ */jsx(Checkbox, {
591
+ checked: deleteOnMux,
592
+ onChange: () => setDeleteOnMux(prev => !prev)
593
+ }), /* @__PURE__ */jsx(Text, {
594
+ style: {
595
+ margin: "0 10px"
596
+ },
597
+ children: "Delete asset on Mux"
598
+ })]
599
+ }), /* @__PURE__ */jsxs(Flex, {
600
+ align: "center",
601
+ as: "label",
602
+ children: [/* @__PURE__ */jsx(Checkbox, {
603
+ disabled: true,
604
+ checked: true
605
+ }), /* @__PURE__ */jsx(Text, {
606
+ style: {
607
+ margin: "0 10px"
608
+ },
609
+ children: "Delete video from dataset"
610
+ })]
611
+ })]
612
+ })
613
+ })
614
+ }), /* @__PURE__ */jsx(VideoThumbnail, {
615
+ asset,
616
+ width,
617
+ showTip: true
618
+ })]
619
+ })
620
+ })
621
+ })
622
+ });
623
+ }
624
+ function VideoSource(_ref) {
625
+ let {
626
+ assets,
627
+ isLoading,
628
+ isLastPage,
629
+ onSelect,
630
+ onLoadMore
631
+ } = _ref;
632
+ const handleClick = useCallback(event => onSelect(event.currentTarget.dataset.id), [onSelect]);
633
+ const handleKeyPress = useCallback(event => {
634
+ if (event.key === "Enter") {
635
+ onSelect(event.currentTarget.dataset.id);
636
+ }
637
+ }, [onSelect]);
638
+ const width = 200 * getDevicePixelRatio({
639
+ maxDpr: 2
640
+ });
641
+ return /* @__PURE__ */jsxs(Fragment, {
642
+ children: [/* @__PURE__ */jsxs(Box, {
643
+ padding: 4,
644
+ children: [/* @__PURE__ */jsx(ThumbGrid, {
645
+ gap: 2,
646
+ children: assets.map(asset => /* @__PURE__ */jsx(VideoSourceItem, {
647
+ asset,
648
+ onClick: handleClick,
649
+ onKeyPress: handleKeyPress,
650
+ width
651
+ }, asset._id))
652
+ }), isLoading && assets.length === 0 && /* @__PURE__ */jsx(Flex, {
653
+ justify: "center",
654
+ children: /* @__PURE__ */jsx(Spinner, {
655
+ muted: true
656
+ })
657
+ }), !isLoading && assets.length === 0 && /* @__PURE__ */jsx(Text, {
658
+ align: "center",
659
+ muted: true,
660
+ children: "No videos"
661
+ })]
662
+ }), assets.length > 0 && !isLastPage && /* @__PURE__ */jsx(CardLoadMore, {
663
+ tone: "default",
664
+ padding: 4,
665
+ children: /* @__PURE__ */jsx(Flex, {
666
+ direction: "column",
667
+ children: /* @__PURE__ */jsx(Button, {
668
+ type: "button",
669
+ icon: DownloadIcon,
670
+ loading: isLoading,
671
+ onClick: onLoadMore,
672
+ text: "Load more",
673
+ tone: "primary"
674
+ })
675
+ })
676
+ })]
677
+ });
678
+ }
679
+ const _VideoSourceItem = _ref2 => {
680
+ let {
681
+ asset,
682
+ onClick,
683
+ onKeyPress,
684
+ width
685
+ } = _ref2;
686
+ const [hover, setHover] = useState(null);
687
+ const ref = useRef(null);
688
+ useLayoutEffect(() => {
689
+ if (!ref.current || hover === null) {
690
+ return;
691
+ }
692
+ if (hover) {
693
+ animate(ref.current, {
694
+ opacity: 1
695
+ });
696
+ } else {
697
+ animate(ref.current, {
698
+ opacity: 0
699
+ });
700
+ }
701
+ }, [hover]);
702
+ return /* @__PURE__ */jsxs(Box, {
703
+ height: "fill",
704
+ style: {
705
+ position: "relative"
706
+ },
707
+ children: [/* @__PURE__ */jsxs(Card, {
708
+ as: "button",
709
+ "data-id": asset._id,
710
+ onClick,
711
+ onKeyPress,
712
+ tabIndex: 0,
713
+ radius: 2,
714
+ padding: 1,
715
+ style: {
716
+ lineHeight: 0,
717
+ position: "relative"
718
+ },
719
+ __unstable_focusRing: true,
720
+ onMouseEnter: () => setHover(true),
721
+ onMouseLeave: () => setHover(false),
722
+ children: [/* @__PURE__ */jsx(VideoThumbnail, {
723
+ asset,
724
+ width,
725
+ showTip: true
726
+ }), (asset == null ? void 0 : asset.playbackId) && /* @__PURE__ */jsx(AnimateWrapper, {
727
+ tone: "transparent",
728
+ ref,
729
+ margin: 1,
730
+ radius: 1,
731
+ children: hover !== null && /* @__PURE__ */jsx(AnimatedVideoThumbnail, {
732
+ asset,
733
+ width
734
+ })
735
+ })]
736
+ }), /* @__PURE__ */jsx(ActionsAssetsContainer, {
737
+ children: /* @__PURE__ */jsx(AssetActionsMenu, {
738
+ asset
739
+ })
740
+ })]
741
+ });
742
+ };
743
+ const VideoSourceItem = memo(_VideoSourceItem);
744
+ const AnimateWrapper = styled(Card)(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n top: 0;\n left: 0;\n right: 0;\n bottom: 0;\n will-change: opacity;\n background: transparent;\n background-color: hsl(0deg 0% 0% / 33%);\n opacity: 0;\n pointer-events: none;\n"])));
745
+ const ActionsAssetsContainer = styled.div(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n box-sizing: border-box;\n position: absolute;\n z-index: 300;\n opacity: 0;\n top: 7px;\n right: 7px;\n\n button:hover + &,\n button:focus-visible + &,\n &:hover,\n &:focus-visible {\n opacity: 1;\n }\n"])));
746
+ const PER_PAGE = 200;
747
+ function createQuery() {
748
+ let start = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 0;
749
+ let end = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : PER_PAGE;
750
+ return (/* groq */"*[_type == \"mux.videoAsset\"] | order(_updatedAt desc) [".concat(start, "...").concat(end, "]")
751
+ );
752
+ }
753
+ function SelectAssets(_ref3) {
754
+ let {
755
+ asset,
756
+ onChange,
757
+ setDialogState
758
+ } = _ref3;
759
+ const client = useClient();
760
+ const pageNoRef = useRef(0);
761
+ const [isLastPage, setLastPage] = useState(false);
762
+ const [isLoading, setLoading] = useState(false);
763
+ const [assets, setAssets] = useState([]);
764
+ const fetchPage = useCallback(pageNo => {
765
+ const start = pageNo * PER_PAGE;
766
+ const end = start + PER_PAGE;
767
+ setLoading(true);
768
+ return client.fetch(createQuery(start, end)).then(result => {
769
+ setLastPage(result.length < PER_PAGE);
770
+ setAssets(prev => prev.concat(result));
771
+ }).finally(() => setLoading(false));
772
+ }, [client]);
773
+ const handleSelect = useCallback(id => {
774
+ const selected = assets.find(doc => doc._id === id);
775
+ if (!selected) {
776
+ throw new TypeError("Failed to find video asset with id: ".concat(id));
777
+ }
778
+ onChange(PatchEvent.from([setIfMissing({
779
+ asset: {}
780
+ }), set({
781
+ _type: "reference",
782
+ _weak: true,
783
+ _ref: selected._id
784
+ }, ["asset"])]));
785
+ setDialogState(false);
786
+ }, [assets, onChange, setDialogState]);
787
+ const handleLoadMore = useCallback(() => {
788
+ fetchPage(++pageNoRef.current);
789
+ }, [fetchPage]);
790
+ useEffect(() => void fetchPage(pageNoRef.current), [fetchPage]);
791
+ return /* @__PURE__ */jsx(VideoSource, {
792
+ onSelect: handleSelect,
793
+ assets,
794
+ isLastPage,
795
+ isLoading,
796
+ onLoadMore: handleLoadMore
797
+ });
798
+ }
799
+ function InputBrowser(_ref4) {
800
+ let {
801
+ setDialogState,
802
+ asset,
803
+ onChange
804
+ } = _ref4;
805
+ const id = "InputBrowser".concat(useId());
806
+ const handleClose = useCallback(() => setDialogState(false), [setDialogState]);
807
+ return /* @__PURE__ */jsx(Dialog, {
808
+ scheme: "dark",
809
+ __unstable_autoFocus: true,
810
+ header: "Select video",
811
+ id,
812
+ onClose: handleClose,
813
+ width: 2,
814
+ children: /* @__PURE__ */jsx(SelectAssets, {
815
+ asset,
816
+ onChange,
817
+ setDialogState
818
+ })
819
+ });
820
+ }
821
+ const useCancelUpload = (asset, onChange) => {
822
+ const client = useClient();
823
+ return useCallback(() => {
824
+ if (!asset) {
825
+ return;
826
+ }
827
+ onChange(PatchEvent.from(unset()));
828
+ if (asset.assetId) {
829
+ deleteAsset(client, asset.assetId);
830
+ }
831
+ if (asset._id) {
832
+ client.delete(asset._id);
833
+ }
834
+ }, [asset, client, onChange]);
835
+ };
836
+ function getVideoSrc(_ref5) {
837
+ let {
838
+ asset,
839
+ client
840
+ } = _ref5;
841
+ const playbackId = getPlaybackId(asset);
842
+ const searchParams = new URLSearchParams();
843
+ if (getPlaybackPolicy(asset) === "signed") {
844
+ const token = generateJwt(client, playbackId, "v");
845
+ searchParams.set("token", token);
846
+ }
847
+ return "https://stream.mux.com/".concat(playbackId, ".m3u8?").concat(searchParams);
848
+ }
849
+ function EditThumbnailDialog(_ref6) {
850
+ let {
851
+ asset,
852
+ getCurrentTime,
853
+ setDialogState
854
+ } = _ref6;
855
+ const client = useClient();
856
+ const dialogId = "EditThumbnailDialog".concat(useId());
857
+ const nextTime = useMemo(() => getCurrentTime(), [getCurrentTime]);
858
+ const assetWithNewThumbnail = useMemo(() => ({
859
+ ...asset,
860
+ thumbTime: nextTime
861
+ }), [asset, nextTime]);
862
+ const [saving, setSaving] = useState(false);
863
+ const [error, setError] = useState(null);
864
+ const handleSave = useCallback(() => {
865
+ setSaving(true);
866
+ client.patch(asset._id).set({
867
+ thumbTime: nextTime
868
+ }).commit({
869
+ returnDocuments: false
870
+ }).then(() => void setDialogState(false)).catch(setError).finally(() => void setSaving(false));
871
+ }, [client, asset._id, nextTime, setDialogState]);
872
+ const width = 300 * getDevicePixelRatio({
873
+ maxDpr: 2
874
+ });
875
+ if (error) {
876
+ throw error;
877
+ }
878
+ return /* @__PURE__ */jsx(Dialog, {
879
+ id: dialogId,
880
+ header: "Edit thumbnail",
881
+ onClose: () => setDialogState(false),
882
+ footer: /* @__PURE__ */jsx(Stack, {
883
+ padding: 3,
884
+ children: /* @__PURE__ */jsx(Button, {
885
+ mode: "ghost",
886
+ tone: "primary",
887
+ loading: saving,
888
+ onClick: handleSave,
889
+ text: "Set new thumbnail"
890
+ }, "thumbnail")
891
+ }),
892
+ children: /* @__PURE__ */jsxs(Stack, {
893
+ space: 3,
894
+ padding: 3,
895
+ children: [/* @__PURE__ */jsxs(Stack, {
896
+ space: 2,
897
+ children: [/* @__PURE__ */jsx(Text, {
898
+ size: 1,
899
+ weight: "semibold",
900
+ children: "Current:"
901
+ }), /* @__PURE__ */jsx(VideoThumbnail, {
902
+ asset,
903
+ width
904
+ })]
905
+ }), /* @__PURE__ */jsxs(Stack, {
906
+ space: 2,
907
+ children: [/* @__PURE__ */jsx(Text, {
908
+ size: 1,
909
+ weight: "semibold",
910
+ children: "New:"
911
+ }), /* @__PURE__ */jsx(VideoThumbnail, {
912
+ asset: assetWithNewThumbnail,
913
+ width
914
+ })]
915
+ })]
916
+ })
917
+ });
918
+ }
919
+ function getStoryboardSrc(_ref7) {
920
+ let {
921
+ asset,
922
+ client
923
+ } = _ref7;
924
+ const playbackId = getPlaybackId(asset);
925
+ const searchParams = new URLSearchParams();
926
+ if (getPlaybackPolicy(asset) === "signed") {
927
+ const token = generateJwt(client, playbackId, "s");
928
+ searchParams.set("token", token);
929
+ }
930
+ return "https://image.mux.com/".concat(playbackId, "/storyboard.vtt?").concat(searchParams);
931
+ }
932
+ const VideoContainer = styled(Card)(_templateObject3 || (_templateObject3 = _taggedTemplateLiteral(["\n position: relative;\n min-height: 150px;\n aspect-ratio: 16 / 9;\n overflow: hidden;\n border-radius: 1px;\n media-airplay-button[media-airplay-unavailable] {\n display: none;\n }\n media-volume-range[media-volume-unavailable] {\n display: none;\n }\n media-pip-button[media-pip-unavailable] {\n display: none;\n }\n media-controller {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n --media-range-track-background-color: rgba(255, 255, 255, 0.5);\n --media-range-track-border-radius: 3px;\n width: 100%;\n height: 100%;\n background-color: transparent;\n }\n media-control-bar {\n --media-button-icon-width: 18px;\n --media-preview-time-margin: 0px;\n }\n media-control-bar:not([slot]) :is([role='button'], [role='switch'], button) {\n height: 44px;\n }\n .size-extra-small media-control-bar [role='button'],\n .size-extra-small media-control-bar [role='switch'] {\n height: auto;\n padding: 4.4% 3.2%;\n }\n .mxp-spacer {\n flex-grow: 1;\n height: 100%;\n background-color: var(--media-control-background, rgba(20, 20, 30, 0.7));\n }\n media-controller::part(vertical-layer) {\n transition: background-color 1s;\n }\n media-controller:is([media-paused], :not([user-inactive]))::part(vertical-layer) {\n background-color: rgba(0, 0, 0, 0.6);\n transition: background-color 0.25s;\n }\n .mxp-center-controls {\n --media-background-color: transparent;\n --media-button-icon-width: 100%;\n --media-button-icon-height: auto;\n pointer-events: none;\n width: 100%;\n display: flex;\n flex-flow: row;\n align-items: center;\n justify-content: center;\n }\n .mxp-center-controls media-play-button {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n padding: 0;\n width: max(27px, min(9%, 90px));\n }\n .mxp-center-controls media-seek-backward-button,\n .mxp-center-controls media-seek-forward-button {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n padding: 0;\n margin: 0 10%;\n width: min(7%, 70px);\n }\n media-loading-indicator {\n --media-loading-icon-width: 100%;\n --media-button-icon-height: auto;\n pointer-events: none;\n position: absolute;\n width: min(15%, 150px);\n display: flex;\n flex-flow: row;\n align-items: center;\n justify-content: center;\n }\n /* Intentionally don't target the div for transition but the children\n of the div. Prevents messing with media-chrome's autohide feature. */\n media-loading-indicator + div * {\n transition: opacity 0.15s;\n opacity: 1;\n }\n media-loading-indicator[media-loading]:not([media-paused]) ~ div > * {\n opacity: 0;\n transition-delay: 400ms;\n }\n media-volume-range {\n width: min(100%, 100px);\n }\n media-time-display {\n white-space: nowrap;\n }\n :is(media-time-display, media-text-display, media-playback-rate-button) {\n color: inherit;\n }\n media-controller:fullscreen media-control-bar[slot='top-chrome'] {\n /* Hide menus and buttons that trigger modals when in full-screen */\n display: none;\n }\n video {\n background: transparent;\n }\n media-controller:not(:fullscreen) video {\n aspect-ratio: 16 / 9;\n }\n media-controller:not(:-webkit-full-screen) video {\n aspect-ratio: 16 / 9;\n }\n"])));
933
+ const StyledCenterControls = styled.div(_templateObject4 || (_templateObject4 = _taggedTemplateLiteral(["\n && {\n --media-background-color: transparent;\n --media-button-icon-width: 100%;\n --media-button-icon-height: auto;\n pointer-events: none;\n width: 100%;\n display: flex;\n flex-flow: row;\n align-items: center;\n justify-content: center;\n media-play-button {\n --media-control-background: transparent;\n --media-control-hover-background: transparent;\n padding: 0;\n width: max(27px, min(9%, 90px));\n }\n }\n"])));
934
+ const TopControls = styled(MediaControlBar)(_templateObject5 || (_templateObject5 = _taggedTemplateLiteral(["\n justify-content: flex-end;\n button {\n height: auto;\n }\n"])));
935
+ function PosterImage(_ref8) {
936
+ let {
937
+ asset
938
+ } = _ref8;
939
+ const client = useClient();
940
+ const ref = useRef(null);
941
+ const src = useMemo(() => getPosterSrc({
942
+ client,
943
+ asset,
944
+ width: 1920,
945
+ height: 1080
946
+ }), [client, asset]);
947
+ useEffect(() => {
948
+ var _a;
949
+ if (ref.current) {
950
+ const style = document.createElement("style");
951
+ style.innerHTML = "img { object-fit: contain; }";
952
+ if ((_a = ref.current) == null ? void 0 : _a.shadowRoot) {
953
+ ref.current.shadowRoot.appendChild(style);
954
+ }
955
+ }
956
+ }, []);
957
+ return /* @__PURE__ */jsx(MediaPosterImage, {
958
+ ref,
959
+ slot: "poster",
960
+ src
961
+ });
962
+ }
963
+ function ThumbnailsMetadataTrack(_ref9) {
964
+ let {
965
+ asset
966
+ } = _ref9;
967
+ const client = useClient();
968
+ const [src] = useState(() => getStoryboardSrc({
969
+ asset,
970
+ client
971
+ }));
972
+ return /* @__PURE__ */jsx("track", {
973
+ label: "thumbnails",
974
+ default: true,
975
+ kind: "metadata",
976
+ src
977
+ });
978
+ }
979
+ const CardWrapper = styled(Card)(_templateObject6 || (_templateObject6 = _taggedTemplateLiteral(["\n min-height: 82px;\n box-sizing: border-box;\n"])));
980
+ const FlexWrapper = styled(Flex)(_templateObject7 || (_templateObject7 = _taggedTemplateLiteral(["\n text-overflow: ellipsis;\n overflow: hidden;\n"])));
981
+ const LeftSection = styled(Stack)(_templateObject8 || (_templateObject8 = _taggedTemplateLiteral(["\n position: relative;\n width: 60%;\n"])));
982
+ const CodeWrapper = styled(Code)(_templateObject9 || (_templateObject9 = _taggedTemplateLiteral(["\n position: relative;\n width: 100%;\n\n code {\n overflow: hidden;\n text-overflow: ellipsis;\n position: relative;\n max-width: 200px;\n }\n"])));
983
+ const UploadProgress = _ref10 => {
984
+ let {
985
+ progress = 100,
986
+ onCancel,
987
+ filename,
988
+ text = "Uploading"
989
+ } = _ref10;
990
+ return /* @__PURE__ */jsx(CardWrapper, {
991
+ tone: "primary",
992
+ padding: 4,
993
+ border: true,
994
+ height: "fill",
995
+ children: /* @__PURE__ */jsxs(FlexWrapper, {
996
+ align: "center",
997
+ justify: "space-between",
998
+ height: "fill",
999
+ direction: "row",
1000
+ gap: 2,
1001
+ children: [/* @__PURE__ */jsxs(LeftSection, {
1002
+ children: [/* @__PURE__ */jsx(Flex, {
1003
+ justify: "center",
1004
+ gap: [3, 3, 2, 2],
1005
+ direction: ["column", "column", "row"],
1006
+ children: /* @__PURE__ */jsx(Text, {
1007
+ size: 1,
1008
+ children: /* @__PURE__ */jsxs(Inline, {
1009
+ space: 2,
1010
+ children: [text, /* @__PURE__ */jsx(CodeWrapper, {
1011
+ size: 1,
1012
+ children: filename ? filename : "..."
1013
+ })]
1014
+ })
1015
+ })
1016
+ }), /* @__PURE__ */jsx(Card, {
1017
+ marginTop: 3,
1018
+ radius: 5,
1019
+ shadow: 1,
1020
+ children: /* @__PURE__ */jsx(LinearProgress, {
1021
+ value: progress
1022
+ })
1023
+ })]
1024
+ }), onCancel ? /* @__PURE__ */jsx(Button, {
1025
+ fontSize: 2,
1026
+ text: "Cancel upload",
1027
+ mode: "ghost",
1028
+ tone: "critical",
1029
+ onClick: onCancel
1030
+ }) : null]
1031
+ })
1032
+ });
1033
+ };
1034
+ const MuxVideo = _ref11 => {
1035
+ let {
1036
+ asset,
1037
+ buttons,
1038
+ readOnly,
1039
+ onChange,
1040
+ dialogState,
1041
+ setDialogState
1042
+ } = _ref11;
1043
+ var _a, _b, _c, _d;
1044
+ const client = useClient();
1045
+ const isLoading = useMemo(() => {
1046
+ if ((asset == null ? void 0 : asset.status) === "preparing") {
1047
+ return "Preparing the video";
1048
+ }
1049
+ if ((asset == null ? void 0 : asset.status) === "waiting_for_upload") {
1050
+ return "Waiting for upload to start";
1051
+ }
1052
+ if ((asset == null ? void 0 : asset.status) === "waiting") {
1053
+ return "Processing upload";
1054
+ }
1055
+ if ((asset == null ? void 0 : asset.status) === "ready") {
1056
+ return false;
1057
+ }
1058
+ if (typeof (asset == null ? void 0 : asset.status) === "undefined") {
1059
+ return false;
1060
+ }
1061
+ return true;
1062
+ }, [asset]);
1063
+ const isPreparingStaticRenditions = useMemo(() => {
1064
+ var _a2, _b2, _c2, _d2;
1065
+ if (((_b2 = (_a2 = asset == null ? void 0 : asset.data) == null ? void 0 : _a2.static_renditions) == null ? void 0 : _b2.status) === "preparing") {
1066
+ return true;
1067
+ }
1068
+ if (((_d2 = (_c2 = asset == null ? void 0 : asset.data) == null ? void 0 : _c2.static_renditions) == null ? void 0 : _d2.status) === "ready") {
1069
+ return false;
1070
+ }
1071
+ return false;
1072
+ }, [(_b = (_a = asset == null ? void 0 : asset.data) == null ? void 0 : _a.static_renditions) == null ? void 0 : _b.status]);
1073
+ const videoSrc = useMemo(() => asset.playbackId && getVideoSrc({
1074
+ client,
1075
+ asset
1076
+ }), [asset, client]);
1077
+ const [error, setError] = useState(null);
1078
+ const handleError = useCallback(event => setError(event.currentTarget.error), []);
1079
+ const playRef = useRef(null);
1080
+ const muteRef = useRef(null);
1081
+ const video = useRef(null);
1082
+ const getCurrentTime = useCallback(() => {
1083
+ var _a2, _b2;
1084
+ return (_b2 = (_a2 = video.current) == null ? void 0 : _a2.currentTime) != null ? _b2 : 0;
1085
+ }, [video]);
1086
+ const handleCancelUpload = useCancelUpload(asset, onChange);
1087
+ useEffect(() => {
1088
+ var _a2, _b2;
1089
+ const style = document.createElement("style");
1090
+ style.innerHTML = "button svg { vertical-align: middle; }";
1091
+ if ((_a2 = playRef.current) == null ? void 0 : _a2.shadowRoot) {
1092
+ playRef.current.shadowRoot.appendChild(style);
1093
+ }
1094
+ if ((_b2 = muteRef == null ? void 0 : muteRef.current) == null ? void 0 : _b2.shadowRoot) {
1095
+ muteRef.current.shadowRoot.appendChild(style.cloneNode(true));
1096
+ }
1097
+ }, []);
1098
+ const [playerInitTime] = useState(() => generatePlayerInitTime());
1099
+ const playbackEngineRef = useRef(void 0);
1100
+ useEffect(() => {
1101
+ if (isLoading || !videoSrc) {
1102
+ return;
1103
+ }
1104
+ const nextPlaybackEngineRef = initialize({
1105
+ src: videoSrc,
1106
+ playerInitTime,
1107
+ playerSoftwareName: "sanity-plugin-mux-input",
1108
+ playerSoftwareVersion: "dev-preview"
1109
+ }, video.current, playbackEngineRef.current);
1110
+ playbackEngineRef.current = nextPlaybackEngineRef;
1111
+ }, [videoSrc, isLoading, playerInitTime]);
1112
+ useEffect(() => {
1113
+ var _a2, _b2, _c2;
1114
+ if ((asset == null ? void 0 : asset.status) === "errored") {
1115
+ handleCancelUpload();
1116
+ throw new Error((_c2 = (_b2 = (_a2 = asset.data) == null ? void 0 : _a2.errors) == null ? void 0 : _b2.messages) == null ? void 0 : _c2.join(" "));
1117
+ }
1118
+ }, [(_d = (_c = asset.data) == null ? void 0 : _c.errors) == null ? void 0 : _d.messages, asset == null ? void 0 : asset.status, handleCancelUpload]);
1119
+ if (error) {
1120
+ throw error;
1121
+ }
1122
+ if (!asset || !asset.status) {
1123
+ return null;
1124
+ }
1125
+ if (isLoading) {
1126
+ return /* @__PURE__ */jsx(UploadProgress, {
1127
+ progress: 100,
1128
+ filename: asset == null ? void 0 : asset.filename,
1129
+ text: isLoading !== true && isLoading || "Waiting for Mux to complete the file",
1130
+ onCancel: readOnly ? void 0 : () => handleCancelUpload()
1131
+ });
1132
+ }
1133
+ return /* @__PURE__ */jsxs(Fragment, {
1134
+ children: [/* @__PURE__ */jsxs(VideoContainer, {
1135
+ shadow: 1,
1136
+ tone: "transparent",
1137
+ scheme: "dark",
1138
+ children: [/* @__PURE__ */jsxs(MediaController, {
1139
+ children: [/* @__PURE__ */jsx("video", {
1140
+ playsInline: true,
1141
+ ref: video,
1142
+ onError: handleError,
1143
+ slot: "media",
1144
+ preload: "metadata",
1145
+ crossOrigin: "anonomous",
1146
+ children: /* @__PURE__ */jsx(ThumbnailsMetadataTrack, {
1147
+ asset
1148
+ })
1149
+ }), /* @__PURE__ */jsx(PosterImage, {
1150
+ asset
1151
+ }), /* @__PURE__ */jsx(MediaLoadingIndicator, {
1152
+ slot: "centered-chrome",
1153
+ noAutoHide: true
1154
+ }), /* @__PURE__ */jsx(StyledCenterControls, {
1155
+ slot: "centered-chrome",
1156
+ children: /* @__PURE__ */jsx(MediaPlayButton, {})
1157
+ }), buttons && /* @__PURE__ */jsx(TopControls, {
1158
+ slot: "top-chrome",
1159
+ children: buttons
1160
+ }), /* @__PURE__ */jsxs(MediaControlBar, {
1161
+ children: [/* @__PURE__ */jsx(MediaMuteButton, {}), /* @__PURE__ */jsx(MediaTimeDisplay, {}), /* @__PURE__ */jsx(MediaTimeRange, {}), /* @__PURE__ */jsx(MediaDurationDisplay, {}), /* @__PURE__ */jsx(MediaFullscreenButton, {})]
1162
+ })]
1163
+ }), isPreparingStaticRenditions && /* @__PURE__ */jsx(Card, {
1164
+ padding: 2,
1165
+ radius: 1,
1166
+ style: {
1167
+ background: "var(--card-fg-color)",
1168
+ position: "absolute",
1169
+ top: "0.5em",
1170
+ left: "0.5em"
1171
+ },
1172
+ children: /* @__PURE__ */jsx(Text, {
1173
+ size: 1,
1174
+ style: {
1175
+ color: "var(--card-bg-color)"
1176
+ },
1177
+ children: "MUX is preparing static renditions, please stand by"
1178
+ })
1179
+ })]
1180
+ }), dialogState === "edit-thumbnail" && /* @__PURE__ */jsx(EditThumbnailDialog, {
1181
+ asset,
1182
+ getCurrentTime,
1183
+ setDialogState
1184
+ })]
1185
+ });
1186
+ };
1187
+ function focusRingBorderStyle(border) {
1188
+ return "inset 0 0 0 ".concat(border.width, "px ").concat(border.color);
1189
+ }
1190
+ function focusRingStyle(opts) {
1191
+ const {
1192
+ base,
1193
+ border,
1194
+ focusRing
1195
+ } = opts;
1196
+ const focusRingOutsetWidth = focusRing.offset + focusRing.width;
1197
+ const focusRingInsetWidth = 0 - focusRing.offset;
1198
+ const bgColor = base ? base.bg : "var(--card-bg-color)";
1199
+ return [focusRingInsetWidth > 0 && "inset 0 0 0 ".concat(focusRingInsetWidth, "px var(--card-focus-ring-color)"), border && focusRingBorderStyle(border), focusRingInsetWidth < 0 && "0 0 0 ".concat(0 - focusRingInsetWidth, "px ").concat(bgColor), focusRingOutsetWidth > 0 && "0 0 0 ".concat(focusRingOutsetWidth, "px var(--card-focus-ring-color)")].filter(Boolean).join(",");
1200
+ }
1201
+ const FileButton = styled(MenuItem)(_ref12 => {
1202
+ let {
1203
+ theme
1204
+ } = _ref12;
1205
+ const {
1206
+ focusRing
1207
+ } = theme.sanity;
1208
+ const base = theme.sanity.color.base;
1209
+ const border = {
1210
+ width: 1,
1211
+ color: "var(--card-border-color)"
1212
+ };
1213
+ return css(_templateObject10 || (_templateObject10 = _taggedTemplateLiteral(["\n position: relative;\n\n &:not([data-disabled='true']) {\n &:focus-within {\n box-shadow: ", ";\n }\n }\n\n & input {\n overflow: hidden;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n position: absolute;\n min-width: 0;\n display: block;\n appearance: none;\n padding: 0;\n margin: 0;\n border: 0;\n opacity: 0;\n }\n "])), focusRingStyle({
1214
+ base,
1215
+ border,
1216
+ focusRing
1217
+ }));
1218
+ });
1219
+ const FileInputMenuItem = React.forwardRef(function FileInputMenuItem2(props, forwardedRef) {
1220
+ const {
1221
+ icon,
1222
+ id: idProp,
1223
+ accept,
1224
+ capture,
1225
+ fontSize,
1226
+ multiple,
1227
+ onSelect,
1228
+ padding = 3,
1229
+ space = 3,
1230
+ textAlign,
1231
+ text,
1232
+ disabled,
1233
+ ...rest
1234
+ } = props;
1235
+ const idHook = useId();
1236
+ const id = idProp || idHook;
1237
+ const handleChange = React.useCallback(event => {
1238
+ if (onSelect && event.target.files) {
1239
+ onSelect(Array.from(event.target.files));
1240
+ }
1241
+ }, [onSelect]);
1242
+ const content = /* @__PURE__ */jsxs(Flex, {
1243
+ align: "center",
1244
+ justify: "flex-start",
1245
+ padding,
1246
+ children: [icon && /* @__PURE__ */jsx(Box, {
1247
+ marginRight: text ? space : void 0,
1248
+ children: /* @__PURE__ */jsxs(Text, {
1249
+ size: fontSize,
1250
+ children: [isValidElement(icon) && icon, isValidElementType(icon) && createElement(icon)]
1251
+ })
1252
+ }), text && /* @__PURE__ */jsx(Text, {
1253
+ align: textAlign,
1254
+ size: fontSize,
1255
+ textOverflow: "ellipsis",
1256
+ children: text
1257
+ })]
1258
+ });
1259
+ return /* @__PURE__ */jsxs(FileButton, {
1260
+ ...rest,
1261
+ htmlFor: id,
1262
+ padding: 0,
1263
+ fontSize: 2,
1264
+ disabled,
1265
+ ref: forwardedRef,
1266
+ children: [content, /* @__PURE__ */jsx("input", {
1267
+ "data-testid": "file-button-input",
1268
+ accept,
1269
+ capture,
1270
+ id,
1271
+ multiple,
1272
+ onChange: handleChange,
1273
+ type: "file",
1274
+ value: "",
1275
+ disabled
1276
+ })]
1277
+ });
1278
+ });
1279
+ const LockCard = styled(Card)(_templateObject11 || (_templateObject11 = _taggedTemplateLiteral(["\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0.6;\n mix-blend-mode: screen;\n background: transparent;\n"])));
1280
+ const LockButton = styled(Button)(_templateObject12 || (_templateObject12 = _taggedTemplateLiteral(["\n background: transparent;\n color: white;\n"])));
1281
+ function PlayerActionsMenu(props) {
1282
+ const {
1283
+ asset,
1284
+ readOnly,
1285
+ dialogState,
1286
+ setDialogState,
1287
+ onChange,
1288
+ onUpload
1289
+ } = props;
1290
+ const [open, setOpen] = useState(false);
1291
+ const [menuElement, setMenuRef] = useState(null);
1292
+ const isSigned = useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]);
1293
+ const onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange]);
1294
+ useEffect(() => {
1295
+ if (open && dialogState) {
1296
+ setOpen(false);
1297
+ }
1298
+ }, [dialogState, open]);
1299
+ useClickOutside(useCallback(() => setOpen(false), []), [menuElement]);
1300
+ return /* @__PURE__ */jsxs(Inline, {
1301
+ space: 1,
1302
+ padding: 2,
1303
+ children: [isSigned && /* @__PURE__ */jsx(Tooltip, {
1304
+ content: /* @__PURE__ */jsx(Box, {
1305
+ padding: 2,
1306
+ children: /* @__PURE__ */jsx(Text, {
1307
+ muted: true,
1308
+ size: 1,
1309
+ children: "Signed playback policy"
1310
+ })
1311
+ }),
1312
+ placement: "right",
1313
+ portal: true,
1314
+ children: /* @__PURE__ */jsx(LockCard, {
1315
+ radius: 2,
1316
+ margin: 2,
1317
+ scheme: "dark",
1318
+ tone: "positive",
1319
+ children: /* @__PURE__ */jsx(LockButton, {
1320
+ icon: LockIcon,
1321
+ mode: "bleed",
1322
+ tone: "positive"
1323
+ })
1324
+ })
1325
+ }), !readOnly && /* @__PURE__ */jsx(Button, {
1326
+ icon: EditIcon,
1327
+ mode: "ghost",
1328
+ onClick: () => setDialogState("edit-thumbnail")
1329
+ }), /* @__PURE__ */jsx(Popover, {
1330
+ content: /* @__PURE__ */jsxs(Menu, {
1331
+ ref: setMenuRef,
1332
+ children: [/* @__PURE__ */jsx(Box, {
1333
+ padding: 2,
1334
+ children: /* @__PURE__ */jsx(Label$1, {
1335
+ muted: true,
1336
+ size: 1,
1337
+ children: "Replace"
1338
+ })
1339
+ }), /* @__PURE__ */jsx(FileInputMenuItem, {
1340
+ accept: "video/*",
1341
+ icon: UploadIcon,
1342
+ mode: "bleed",
1343
+ onSelect: onUpload,
1344
+ text: "Upload",
1345
+ disabled: readOnly,
1346
+ fontSize: 2
1347
+ }), /* @__PURE__ */jsx(MenuItem, {
1348
+ icon: SearchIcon,
1349
+ text: "Browse",
1350
+ onClick: () => setDialogState("select-video")
1351
+ }), /* @__PURE__ */jsx(MenuDivider, {}), /* @__PURE__ */jsx(MenuItem, {
1352
+ icon: PlugIcon,
1353
+ text: "Configure API",
1354
+ onClick: () => setDialogState("secrets")
1355
+ }), /* @__PURE__ */jsx(MenuDivider, {}), /* @__PURE__ */jsx(MenuItem, {
1356
+ tone: "critical",
1357
+ icon: ResetIcon,
1358
+ text: "Clear field",
1359
+ onClick: onReset,
1360
+ disabled: readOnly
1361
+ })]
1362
+ }),
1363
+ portal: true,
1364
+ open,
1365
+ children: /* @__PURE__ */jsx(Button, {
1366
+ icon: EllipsisVerticalIcon,
1367
+ mode: "ghost",
1368
+ onClick: () => {
1369
+ setDialogState(false);
1370
+ setOpen(true);
1371
+ }
1372
+ })
1373
+ })]
1374
+ });
1375
+ }
1376
+ var PlayerActionsMenu$1 = memo(PlayerActionsMenu);
1377
+ function withFocusRing(component) {
1378
+ return styled(component)(props => {
1379
+ const border = {
1380
+ width: props.$border ? 1 : 0,
1381
+ color: "var(--card-border-color)"
1382
+ };
1383
+ return css(_templateObject13 || (_templateObject13 = _taggedTemplateLiteral(["\n --card-focus-box-shadow: ", ";\n\n border-radius: ", ";\n outline: none;\n box-shadow: var(--card-focus-box-shadow);\n\n &:focus {\n --card-focus-box-shadow: ", ";\n }\n "])), focusRingBorderStyle(border), rem(props.theme.sanity.radius[1]), focusRingStyle({
1384
+ base: props.theme.sanity.color.base,
1385
+ border,
1386
+ focusRing: props.theme.sanity.focusRing
1387
+ }));
1388
+ });
1389
+ }
1390
+ const ctrlKey = 17;
1391
+ const cmdKey = 91;
1392
+ const UploadCardWithFocusRing = withFocusRing(Card);
1393
+ const UploadCard$1 = forwardRef((_ref13, forwardedRef) => {
1394
+ let {
1395
+ children,
1396
+ tone,
1397
+ onPaste,
1398
+ onDrop,
1399
+ onDragEnter,
1400
+ onDragLeave,
1401
+ onDragOver
1402
+ } = _ref13;
1403
+ const ctrlDown = useRef(false);
1404
+ const inputRef = useRef(null);
1405
+ const handleKeyDown = useCallback(event => {
1406
+ if (event.keyCode == ctrlKey || event.keyCode == cmdKey) {
1407
+ ctrlDown.current = true;
1408
+ }
1409
+ const vKey = 86;
1410
+ if (ctrlDown.current && event.keyCode == vKey) {
1411
+ inputRef.current.focus();
1412
+ }
1413
+ }, []);
1414
+ const handleKeyUp = useCallback(event => {
1415
+ if (event.keyCode == ctrlKey || event.keyCode == cmdKey) {
1416
+ ctrlDown.current = false;
1417
+ }
1418
+ }, []);
1419
+ return /* @__PURE__ */jsxs(UploadCardWithFocusRing, {
1420
+ tone,
1421
+ height: "fill",
1422
+ ref: forwardedRef,
1423
+ padding: 0,
1424
+ radius: 2,
1425
+ shadow: 0,
1426
+ tabIndex: 0,
1427
+ onKeyDown: handleKeyDown,
1428
+ onKeyUp: handleKeyUp,
1429
+ onPaste,
1430
+ onDrop,
1431
+ onDragEnter,
1432
+ onDragLeave,
1433
+ onDragOver,
1434
+ children: [/* @__PURE__ */jsx(HiddenInput$1, {
1435
+ ref: inputRef,
1436
+ onPaste
1437
+ }), children]
1438
+ });
1439
+ });
1440
+ const HiddenInput$1 = styled.input.attrs({
1441
+ type: "text"
1442
+ })(_templateObject14 || (_templateObject14 = _taggedTemplateLiteral(["\n position: absolute;\n border: 0;\n color: white;\n opacity: 0;\n\n &:focus {\n outline: none;\n }\n"])));
1443
+ const HiddenInput = styled.input(_templateObject15 || (_templateObject15 = _taggedTemplateLiteral(["\n overflow: hidden;\n width: 0.1px;\n height: 0.1px;\n opacity: 0;\n position: absolute;\n z-index: -1;\n"])));
1444
+ const Label = styled.label(_templateObject16 || (_templateObject16 = _taggedTemplateLiteral(["\n position: relative;\n"])));
1445
+ const FileInputButton = _ref14 => {
1446
+ let {
1447
+ onSelect,
1448
+ ...props
1449
+ } = _ref14;
1450
+ const inputId = "FileSelect".concat(useId());
1451
+ const inputRef = useRef(null);
1452
+ const handleSelect = useCallback(event => {
1453
+ if (onSelect) {
1454
+ onSelect(event.target.files);
1455
+ }
1456
+ }, [onSelect]);
1457
+ const handleButtonClick = useCallback(() => {
1458
+ var _a;
1459
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
1460
+ }, []);
1461
+ return /* @__PURE__ */jsxs(Label, {
1462
+ htmlFor: inputId,
1463
+ children: [/* @__PURE__ */jsx(HiddenInput, {
1464
+ accept: "video/*",
1465
+ ref: inputRef,
1466
+ tabIndex: 0,
1467
+ type: "file",
1468
+ id: inputId,
1469
+ onChange: handleSelect,
1470
+ value: ""
1471
+ }), /* @__PURE__ */jsx(Button, {
1472
+ onClick: handleButtonClick,
1473
+ mode: "default",
1474
+ tone: "primary",
1475
+ style: {
1476
+ width: "100%"
1477
+ },
1478
+ ...props
1479
+ })]
1480
+ });
1481
+ };
1482
+ const UploadCard = styled(Card)(_templateObject17 || (_templateObject17 = _taggedTemplateLiteral(["\n && {\n border-style: dashed;\n }\n"])));
1483
+ const ConfigureApiBox = styled(Box)(_templateObject18 || (_templateObject18 = _taggedTemplateLiteral(["\n position: absolute;\n top: 0;\n right: 0;\n"])));
1484
+ function UploadPlaceholder(props) {
1485
+ const {
1486
+ setDialogState,
1487
+ readOnly,
1488
+ onSelect,
1489
+ hovering,
1490
+ needsSetup
1491
+ } = props;
1492
+ const handleBrowse = useCallback(() => setDialogState("select-video"), [setDialogState]);
1493
+ const handleConfigureApi = useCallback(() => setDialogState("secrets"), [setDialogState]);
1494
+ return /* @__PURE__ */jsx(Box, {
1495
+ style: {
1496
+ padding: 1,
1497
+ position: "relative"
1498
+ },
1499
+ height: "stretch",
1500
+ children: /* @__PURE__ */jsxs(UploadCard, {
1501
+ sizing: "border",
1502
+ height: "fill",
1503
+ tone: readOnly ? "transparent" : "inherit",
1504
+ border: true,
1505
+ padding: 3,
1506
+ style: hovering ? {
1507
+ borderColor: "transparent"
1508
+ } : void 0,
1509
+ children: [/* @__PURE__ */jsx(ConfigureApiBox, {
1510
+ padding: 3,
1511
+ children: /* @__PURE__ */jsx(Button, {
1512
+ padding: 3,
1513
+ radius: 3,
1514
+ tone: needsSetup ? "critical" : void 0,
1515
+ onClick: handleConfigureApi,
1516
+ icon: PlugIcon,
1517
+ mode: "bleed"
1518
+ })
1519
+ }), /* @__PURE__ */jsxs(Flex, {
1520
+ align: "center",
1521
+ justify: "space-between",
1522
+ gap: 4,
1523
+ direction: ["column", "column", "row"],
1524
+ paddingY: [2, 2, 0],
1525
+ sizing: "border",
1526
+ height: "fill",
1527
+ children: [/* @__PURE__ */jsxs(Flex, {
1528
+ align: "center",
1529
+ justify: "center",
1530
+ gap: 2,
1531
+ flex: 1,
1532
+ children: [/* @__PURE__ */jsx(Flex, {
1533
+ justify: "center",
1534
+ children: /* @__PURE__ */jsx(Text, {
1535
+ muted: true,
1536
+ children: /* @__PURE__ */jsx(DocumentVideoIcon, {})
1537
+ })
1538
+ }), /* @__PURE__ */jsx(Flex, {
1539
+ justify: "center",
1540
+ children: /* @__PURE__ */jsx(Text, {
1541
+ size: 1,
1542
+ muted: true,
1543
+ children: "Drag video or paste URL here"
1544
+ })
1545
+ })]
1546
+ }), /* @__PURE__ */jsxs(Inline, {
1547
+ space: 2,
1548
+ children: [/* @__PURE__ */jsx(FileInputButton, {
1549
+ mode: "ghost",
1550
+ tone: "default",
1551
+ icon: UploadIcon,
1552
+ text: "Upload",
1553
+ onSelect
1554
+ }), /* @__PURE__ */jsx(Button, {
1555
+ mode: "ghost",
1556
+ icon: SearchIcon,
1557
+ text: "Select",
1558
+ onClick: handleBrowse
1559
+ })]
1560
+ })]
1561
+ })]
1562
+ })
1563
+ });
1564
+ }
1565
+ class MuxVideoInputUploader extends Component {
1566
+ constructor() {
1567
+ super(...arguments);
1568
+ this.state = {
1569
+ isDraggingOver: false,
1570
+ invalidPaste: false,
1571
+ invalidFile: false,
1572
+ uploadProgress: null,
1573
+ fileInfo: null,
1574
+ uuid: null,
1575
+ error: null,
1576
+ url: null
1577
+ };
1578
+ this.dragEnteredEls = [];
1579
+ this.ctrlDown = false;
1580
+ // eslint-disable-next-line no-warning-comments
1581
+ // @TODO add proper typings for the return values of uploadFile and uploadUrl
1582
+ this.upload = null;
1583
+ this.container = React.createRef();
1584
+ this.handleProgress = evt => {
1585
+ this.setState({
1586
+ uploadProgress: evt.percent
1587
+ });
1588
+ };
1589
+ this.onUpload = files => {
1590
+ this.setState({
1591
+ uploadProgress: 0,
1592
+ fileInfo: null,
1593
+ uuid: null
1594
+ });
1595
+ this.upload = uploadFile(this.props.config, this.props.client, files[0], {
1596
+ enableSignedUrls: this.props.secrets.enableSignedUrls
1597
+ }).pipe(takeUntil(this.onCancelUploadButtonClick$.pipe(tap(() => {
1598
+ if (this.state.uuid) {
1599
+ this.props.client.delete(this.state.uuid);
1600
+ }
1601
+ })))).subscribe({
1602
+ complete: () => {
1603
+ this.setState({
1604
+ error: null,
1605
+ uploadProgress: null,
1606
+ uuid: null
1607
+ });
1608
+ },
1609
+ next: event => {
1610
+ this.handleUploadEvent(event);
1611
+ },
1612
+ error: err => {
1613
+ this.setState({
1614
+ error: err,
1615
+ uploadProgress: null,
1616
+ uuid: null
1617
+ });
1618
+ }
1619
+ });
1620
+ };
1621
+ // eslint-disable-next-line no-warning-comments
1622
+ // @TODO add proper typings for the Observable events
1623
+ this.handleUploadEvent = event => {
1624
+ switch (event.type) {
1625
+ case "success":
1626
+ return this.handleUploadSuccess(event.asset);
1627
+ case "progress":
1628
+ return this.handleProgress(event);
1629
+ case "file":
1630
+ return this.setState({
1631
+ fileInfo: event.file
1632
+ });
1633
+ case "uuid":
1634
+ return this.setState({
1635
+ uuid: event.uuid
1636
+ });
1637
+ case "url":
1638
+ return this.setState({
1639
+ url: event.url,
1640
+ uploadProgress: 100
1641
+ });
1642
+ default:
1643
+ return null;
1644
+ }
1645
+ };
1646
+ this.handleUploadSuccess = asset => {
1647
+ this.setState({
1648
+ uploadProgress: 100
1649
+ });
1650
+ this.props.onChange(PatchEvent.from([setIfMissing({
1651
+ asset: {}
1652
+ }), set({
1653
+ _type: "reference",
1654
+ _weak: true,
1655
+ _ref: asset._id
1656
+ }, ["asset"])]));
1657
+ };
1658
+ this.handlePaste = event => {
1659
+ const clipboardData = event.clipboardData || window.clipboardData;
1660
+ const url = clipboardData.getData("text");
1661
+ const options = {
1662
+ enableSignedUrls: this.props.secrets.enableSignedUrls
1663
+ };
1664
+ this.upload = uploadUrl(this.props.config, this.props.client, url, options).subscribe({
1665
+ complete: () => {
1666
+ this.setState({
1667
+ error: null,
1668
+ uploadProgress: null,
1669
+ url: null
1670
+ });
1671
+ },
1672
+ next: sEvent => {
1673
+ this.handleUploadEvent(sEvent);
1674
+ },
1675
+ error: err => {
1676
+ let error;
1677
+ if (!err.message.toLowerCase().match("invalid url")) {
1678
+ error = err;
1679
+ }
1680
+ this.setState({
1681
+ invalidPaste: true,
1682
+ error
1683
+ }, () => {
1684
+ setTimeout(() => {
1685
+ this.setState({
1686
+ invalidPaste: false,
1687
+ uploadProgress: null
1688
+ });
1689
+ }, 2e3);
1690
+ });
1691
+ }
1692
+ });
1693
+ };
1694
+ this.handleDrop = event => {
1695
+ this.setState({
1696
+ isDraggingOver: false
1697
+ });
1698
+ event.preventDefault();
1699
+ event.stopPropagation();
1700
+ extractDroppedFiles(event.nativeEvent.dataTransfer).then(files => {
1701
+ if (files) {
1702
+ this.onUpload(files);
1703
+ }
1704
+ });
1705
+ };
1706
+ this.handleDragOver = event => {
1707
+ event.preventDefault();
1708
+ event.stopPropagation();
1709
+ };
1710
+ this.handleDragEnter = event => {
1711
+ var _a, _b;
1712
+ event.stopPropagation();
1713
+ this.dragEnteredEls.push(event.target);
1714
+ this.setState({
1715
+ isDraggingOver: true
1716
+ });
1717
+ const type = (_b = (_a = event.dataTransfer.items) == null ? void 0 : _a[0]) == null ? void 0 : _b.type;
1718
+ this.setState({
1719
+ invalidFile: !type.startsWith("video/")
1720
+ });
1721
+ };
1722
+ this.handleDragLeave = event => {
1723
+ event.stopPropagation();
1724
+ const idx = this.dragEnteredEls.indexOf(event.target);
1725
+ if (idx > -1) {
1726
+ this.dragEnteredEls.splice(idx, 1);
1727
+ }
1728
+ if (this.dragEnteredEls.length === 0) {
1729
+ this.setState({
1730
+ isDraggingOver: false
1731
+ });
1732
+ }
1733
+ };
1734
+ }
1735
+ componentWillUnmount() {
1736
+ this.unSubscribeToUpload();
1737
+ }
1738
+ componentDidMount() {
1739
+ const events$ = new Subject();
1740
+ this.onCancelUploadButtonClick$ = events$.asObservable();
1741
+ this.handleCancelUploadButtonClick = event => events$.next(event);
1742
+ }
1743
+ unSubscribeToUpload() {
1744
+ if (this.upload && !this.upload.closed) {
1745
+ this.upload.unsubscribe();
1746
+ }
1747
+ }
1748
+ render() {
1749
+ var _a;
1750
+ if (this.state.uploadProgress !== null) {
1751
+ return /* @__PURE__ */jsx(UploadProgress, {
1752
+ onCancel: this.handleCancelUploadButtonClick,
1753
+ progress: this.state.uploadProgress,
1754
+ filename: ((_a = this.state.fileInfo) == null ? void 0 : _a.name) || this.state.url
1755
+ });
1756
+ }
1757
+ if (this.state.error) {
1758
+ throw this.state.error;
1759
+ }
1760
+ return /* @__PURE__ */jsxs(Fragment, {
1761
+ children: [/* @__PURE__ */jsx(UploadCard$1, {
1762
+ tone: this.state.isDraggingOver && (this.state.invalidPaste || this.state.invalidFile) ? "critical" : this.state.isDraggingOver ? "positive" : void 0,
1763
+ onDrop: this.handleDrop,
1764
+ onDragOver: this.handleDragOver,
1765
+ onDragLeave: this.handleDragLeave,
1766
+ onDragEnter: this.handleDragEnter,
1767
+ onPaste: this.handlePaste,
1768
+ ref: this.container,
1769
+ children: this.props.asset ? /* @__PURE__ */jsx(MuxVideo, {
1770
+ readOnly: this.props.readOnly,
1771
+ asset: this.props.asset,
1772
+ onChange: this.props.onChange,
1773
+ dialogState: this.props.dialogState,
1774
+ setDialogState: this.props.setDialogState,
1775
+ buttons: /* @__PURE__ */jsx(PlayerActionsMenu$1, {
1776
+ asset: this.props.asset,
1777
+ dialogState: this.props.dialogState,
1778
+ setDialogState: this.props.setDialogState,
1779
+ onChange: this.props.onChange,
1780
+ onUpload: this.onUpload,
1781
+ readOnly: this.props.readOnly
1782
+ })
1783
+ }) : /* @__PURE__ */jsx(UploadPlaceholder, {
1784
+ hovering: this.state.isDraggingOver,
1785
+ onSelect: this.onUpload,
1786
+ readOnly: this.props.readOnly,
1787
+ setDialogState: this.props.setDialogState,
1788
+ needsSetup: this.props.needsSetup
1789
+ })
1790
+ }), this.props.dialogState === "select-video" && /* @__PURE__ */jsx(InputBrowser, {
1791
+ asset: this.props.asset,
1792
+ onChange: this.props.onChange,
1793
+ setDialogState: this.props.setDialogState
1794
+ })]
1795
+ });
1796
+ }
1797
+ }
1798
+ const useSaveSecrets = (client, secrets) => {
1799
+ return useCallback(async _ref15 => {
1800
+ let {
1801
+ token,
1802
+ secretKey,
1803
+ enableSignedUrls
1804
+ } = _ref15;
1805
+ let {
1806
+ signingKeyId,
1807
+ signingKeyPrivate
1808
+ } = secrets;
1809
+ try {
1810
+ await saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate);
1811
+ const valid = await testSecrets(client);
1812
+ if (!(valid == null ? void 0 : valid.status) && token && secretKey) {
1813
+ throw new Error("Invalid secrets");
1814
+ }
1815
+ } catch (err) {
1816
+ console.error("Error while trying to save secrets:", err);
1817
+ throw err;
1818
+ }
1819
+ if (enableSignedUrls) {
1820
+ const hasValidSigningKeys = await haveValidSigningKeys(client, signingKeyId, signingKeyPrivate);
1821
+ if (!hasValidSigningKeys) {
1822
+ try {
1823
+ const {
1824
+ data
1825
+ } = await createSigningKeys(client);
1826
+ signingKeyId = data.id;
1827
+ signingKeyPrivate = data.private_key;
1828
+ await saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate);
1829
+ } catch (err) {
1830
+ console.log("Error while creating and saving signing key:", err == null ? void 0 : err.message);
1831
+ throw err;
1832
+ }
1833
+ }
1834
+ }
1835
+ return {
1836
+ token,
1837
+ secretKey,
1838
+ enableSignedUrls,
1839
+ signingKeyId,
1840
+ signingKeyPrivate
1841
+ };
1842
+ }, [client, secrets]);
1843
+ };
1844
+ function init(_ref16) {
1845
+ let {
1846
+ token,
1847
+ secretKey,
1848
+ enableSignedUrls
1849
+ } = _ref16;
1850
+ return {
1851
+ submitting: false,
1852
+ error: null,
1853
+ // Form inputs don't set the state back to null when clearing a field, but uses empty strings
1854
+ // This ensures the `dirty` check works correctly
1855
+ token: token != null ? token : "",
1856
+ secretKey: secretKey != null ? secretKey : "",
1857
+ enableSignedUrls: enableSignedUrls != null ? enableSignedUrls : false
1858
+ };
1859
+ }
1860
+ function reducer(state, action) {
1861
+ switch (action == null ? void 0 : action.type) {
1862
+ case "submit":
1863
+ return {
1864
+ ...state,
1865
+ submitting: true,
1866
+ error: null
1867
+ };
1868
+ case "error":
1869
+ return {
1870
+ ...state,
1871
+ submitting: false,
1872
+ error: action.payload
1873
+ };
1874
+ case "reset":
1875
+ return init(action.payload);
1876
+ case "change":
1877
+ return {
1878
+ ...state,
1879
+ [action.payload.name]: action.payload.value
1880
+ };
1881
+ default:
1882
+ throw new Error("Unknown action type: ".concat(action == null ? void 0 : action.type));
1883
+ }
1884
+ }
1885
+ const useSecretsFormState = secrets => useReducer(reducer, secrets, init);
1886
+ const ids = ["title", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r"];
1887
+ function MuxLogo(_ref17) {
1888
+ let {
1889
+ height = 26
1890
+ } = _ref17;
1891
+ const id = useId();
1892
+ const [titleId, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r] = useMemo(() => ids.map(field => "".concat(id, "-").concat(field)), [id]);
1893
+ return /* @__PURE__ */jsxs("svg", {
1894
+ "aria-labelledby": titleId,
1895
+ role: "img",
1896
+ xmlns: "http://www.w3.org/2000/svg",
1897
+ xmlSpace: "preserve",
1898
+ viewBox: "92.08878326416016 102.66712188720703 692.76123046875 219.99948120117188",
1899
+ style: {
1900
+ height: "".concat(height, "px")
1901
+ },
1902
+ children: [/* @__PURE__ */jsx("title", {
1903
+ id: titleId,
1904
+ children: "Mux Logo"
1905
+ }), /* @__PURE__ */jsxs("defs", {
1906
+ children: [/* @__PURE__ */jsxs("linearGradient", {
1907
+ id: c,
1908
+ spreadMethod: "pad",
1909
+ gradientTransform: "matrix(528.38055 0 0 -528.38055 63.801 159.5)",
1910
+ gradientUnits: "userSpaceOnUse",
1911
+ y2: 0,
1912
+ x2: 1,
1913
+ y1: 0,
1914
+ x1: 0,
1915
+ children: [/* @__PURE__ */jsx("stop", {
1916
+ offset: 0,
1917
+ style: {
1918
+ stopOpacity: 1,
1919
+ stopColor: "#ff4e00"
1920
+ }
1921
+ }), /* @__PURE__ */jsx("stop", {
1922
+ offset: 1,
1923
+ style: {
1924
+ stopOpacity: 1,
1925
+ stopColor: "#ff1791"
1926
+ }
1927
+ })]
1928
+ }), /* @__PURE__ */jsxs("linearGradient", {
1929
+ id: d,
1930
+ spreadMethod: "pad",
1931
+ gradientTransform: "matrix(523.66766 0 0 -523.66766 67.897 159.5)",
1932
+ gradientUnits: "userSpaceOnUse",
1933
+ y2: 0,
1934
+ x2: 1,
1935
+ y1: 0,
1936
+ x1: 0,
1937
+ children: [/* @__PURE__ */jsx("stop", {
1938
+ offset: 0,
1939
+ style: {
1940
+ stopOpacity: 1,
1941
+ stopColor: "#ff4e00"
1942
+ }
1943
+ }), /* @__PURE__ */jsx("stop", {
1944
+ offset: 1,
1945
+ style: {
1946
+ stopOpacity: 1,
1947
+ stopColor: "#ff1791"
1948
+ }
1949
+ })]
1950
+ }), /* @__PURE__ */jsxs("linearGradient", {
1951
+ id: g,
1952
+ spreadMethod: "pad",
1953
+ gradientTransform: "rotate(180 296.075 79.75) scale(524.84045)",
1954
+ gradientUnits: "userSpaceOnUse",
1955
+ y2: 0,
1956
+ x2: 1,
1957
+ y1: 0,
1958
+ x1: 0,
1959
+ children: [/* @__PURE__ */jsx("stop", {
1960
+ offset: 0,
1961
+ style: {
1962
+ stopOpacity: 1,
1963
+ stopColor: "#ff4e00"
1964
+ }
1965
+ }), /* @__PURE__ */jsx("stop", {
1966
+ offset: 1,
1967
+ style: {
1968
+ stopOpacity: 1,
1969
+ stopColor: "#ff1791"
1970
+ }
1971
+ })]
1972
+ }), /* @__PURE__ */jsxs("linearGradient", {
1973
+ id: i,
1974
+ spreadMethod: "pad",
1975
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
1976
+ gradientUnits: "userSpaceOnUse",
1977
+ y2: 0,
1978
+ x2: 1,
1979
+ y1: 0,
1980
+ x1: 0,
1981
+ children: [/* @__PURE__ */jsx("stop", {
1982
+ offset: 0,
1983
+ style: {
1984
+ stopOpacity: 1,
1985
+ stopColor: "#ff4e00"
1986
+ }
1987
+ }), /* @__PURE__ */jsx("stop", {
1988
+ offset: 1,
1989
+ style: {
1990
+ stopOpacity: 1,
1991
+ stopColor: "#ff1791"
1992
+ }
1993
+ })]
1994
+ }), /* @__PURE__ */jsxs("linearGradient", {
1995
+ id: j,
1996
+ spreadMethod: "pad",
1997
+ gradientTransform: "matrix(523.08514 0 0 -523.08514 67.897 224.446)",
1998
+ gradientUnits: "userSpaceOnUse",
1999
+ y2: 0,
2000
+ x2: 1,
2001
+ y1: 0,
2002
+ x1: 0,
2003
+ children: [/* @__PURE__ */jsx("stop", {
2004
+ offset: 0,
2005
+ style: {
2006
+ stopOpacity: 1,
2007
+ stopColor: "#ff4e00"
2008
+ }
2009
+ }), /* @__PURE__ */jsx("stop", {
2010
+ offset: 1,
2011
+ style: {
2012
+ stopOpacity: 1,
2013
+ stopColor: "#ff1791"
2014
+ }
2015
+ })]
2016
+ }), /* @__PURE__ */jsxs("linearGradient", {
2017
+ id: k,
2018
+ spreadMethod: "pad",
2019
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 94.553)",
2020
+ gradientUnits: "userSpaceOnUse",
2021
+ y2: 0,
2022
+ x2: 1,
2023
+ y1: 0,
2024
+ x1: 0,
2025
+ children: [/* @__PURE__ */jsx("stop", {
2026
+ offset: 0,
2027
+ style: {
2028
+ stopOpacity: 1,
2029
+ stopColor: "#ff4e00"
2030
+ }
2031
+ }), /* @__PURE__ */jsx("stop", {
2032
+ offset: 1,
2033
+ style: {
2034
+ stopOpacity: 1,
2035
+ stopColor: "#ff1791"
2036
+ }
2037
+ })]
2038
+ }), /* @__PURE__ */jsxs("linearGradient", {
2039
+ id: l,
2040
+ spreadMethod: "pad",
2041
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
2042
+ gradientUnits: "userSpaceOnUse",
2043
+ y2: 0,
2044
+ x2: 1,
2045
+ y1: 0,
2046
+ x1: 0,
2047
+ children: [/* @__PURE__ */jsx("stop", {
2048
+ offset: 0,
2049
+ style: {
2050
+ stopOpacity: 1,
2051
+ stopColor: "#ff4e00"
2052
+ }
2053
+ }), /* @__PURE__ */jsx("stop", {
2054
+ offset: 1,
2055
+ style: {
2056
+ stopOpacity: 1,
2057
+ stopColor: "#ff1791"
2058
+ }
2059
+ })]
2060
+ }), /* @__PURE__ */jsxs("linearGradient", {
2061
+ id: m,
2062
+ spreadMethod: "pad",
2063
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 94.554)",
2064
+ gradientUnits: "userSpaceOnUse",
2065
+ y2: 0,
2066
+ x2: 1,
2067
+ y1: 0,
2068
+ x1: 0,
2069
+ children: [/* @__PURE__ */jsx("stop", {
2070
+ offset: 0,
2071
+ style: {
2072
+ stopOpacity: 1,
2073
+ stopColor: "#ff4e00"
2074
+ }
2075
+ }), /* @__PURE__ */jsx("stop", {
2076
+ offset: 1,
2077
+ style: {
2078
+ stopOpacity: 1,
2079
+ stopColor: "#ff1791"
2080
+ }
2081
+ })]
2082
+ }), /* @__PURE__ */jsxs("linearGradient", {
2083
+ id: p,
2084
+ spreadMethod: "pad",
2085
+ gradientTransform: "matrix(521.97632 0 0 -521.97632 69.067 191.973)",
2086
+ gradientUnits: "userSpaceOnUse",
2087
+ y2: 0,
2088
+ x2: 1,
2089
+ y1: 0,
2090
+ x1: 0,
2091
+ children: [/* @__PURE__ */jsx("stop", {
2092
+ offset: 0,
2093
+ style: {
2094
+ stopOpacity: 1,
2095
+ stopColor: "#ff4e00"
2096
+ }
2097
+ }), /* @__PURE__ */jsx("stop", {
2098
+ offset: 1,
2099
+ style: {
2100
+ stopOpacity: 1,
2101
+ stopColor: "#ff1791"
2102
+ }
2103
+ })]
2104
+ }), /* @__PURE__ */jsxs("linearGradient", {
2105
+ id: q,
2106
+ spreadMethod: "pad",
2107
+ gradientTransform: "matrix(523.09039 0 0 -523.09039 67.312 191.973)",
2108
+ gradientUnits: "userSpaceOnUse",
2109
+ y2: 0,
2110
+ x2: 1,
2111
+ y1: 0,
2112
+ x1: 0,
2113
+ children: [/* @__PURE__ */jsx("stop", {
2114
+ offset: 0,
2115
+ style: {
2116
+ stopOpacity: 1,
2117
+ stopColor: "#ff4e00"
2118
+ }
2119
+ }), /* @__PURE__ */jsx("stop", {
2120
+ offset: 1,
2121
+ style: {
2122
+ stopOpacity: 1,
2123
+ stopColor: "#ff1791"
2124
+ }
2125
+ })]
2126
+ }), /* @__PURE__ */jsxs("linearGradient", {
2127
+ id: r,
2128
+ spreadMethod: "pad",
2129
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
2130
+ gradientUnits: "userSpaceOnUse",
2131
+ y2: 0,
2132
+ x2: 1,
2133
+ y1: 0,
2134
+ x1: 0,
2135
+ children: [/* @__PURE__ */jsx("stop", {
2136
+ offset: 0,
2137
+ style: {
2138
+ stopOpacity: 1,
2139
+ stopColor: "#ff4e00"
2140
+ }
2141
+ }), /* @__PURE__ */jsx("stop", {
2142
+ offset: 1,
2143
+ style: {
2144
+ stopOpacity: 1,
2145
+ stopColor: "#ff1791"
2146
+ }
2147
+ })]
2148
+ }), /* @__PURE__ */jsx("clipPath", {
2149
+ id: a,
2150
+ clipPathUnits: "userSpaceOnUse",
2151
+ children: /* @__PURE__ */jsx("path", {
2152
+ d: "M0 319h657.706V0H0Z"
2153
+ })
2154
+ }), /* @__PURE__ */jsx("clipPath", {
2155
+ id: b,
2156
+ clipPathUnits: "userSpaceOnUse",
2157
+ children: /* @__PURE__ */jsx("path", {
2158
+ d: "M423.64 242h164.999V77H423.64Z"
2159
+ })
2160
+ }), /* @__PURE__ */jsx("clipPath", {
2161
+ id: e,
2162
+ clipPathUnits: "userSpaceOnUse",
2163
+ children: /* @__PURE__ */jsx("path", {
2164
+ d: "M0 319h657.706V0H0Z"
2165
+ })
2166
+ }), /* @__PURE__ */jsx("clipPath", {
2167
+ id: f,
2168
+ clipPathUnits: "userSpaceOnUse",
2169
+ children: /* @__PURE__ */jsx("path", {
2170
+ d: "M311.3 242h93.031V77H311.3Z"
2171
+ })
2172
+ }), /* @__PURE__ */jsx("clipPath", {
2173
+ id: h,
2174
+ clipPathUnits: "userSpaceOnUse",
2175
+ children: /* @__PURE__ */jsx("path", {
2176
+ d: "M198.96 242h35.106V77H198.96Z"
2177
+ })
2178
+ }), /* @__PURE__ */jsx("clipPath", {
2179
+ id: n,
2180
+ clipPathUnits: "userSpaceOnUse",
2181
+ children: /* @__PURE__ */jsx("path", {
2182
+ d: "M0 319h657.706V0H0Z"
2183
+ })
2184
+ }), /* @__PURE__ */jsx("clipPath", {
2185
+ id: o,
2186
+ clipPathUnits: "userSpaceOnUse",
2187
+ children: /* @__PURE__ */jsx("path", {
2188
+ d: "M69.067 242H169.12V141.947H69.067Z"
2189
+ })
2190
+ })]
2191
+ }), /* @__PURE__ */jsx("g", {
2192
+ clipPath: "url(#".concat(a, ")"),
2193
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
2194
+ children: /* @__PURE__ */jsx("g", {
2195
+ style: {
2196
+ opacity: 0.69999701
2197
+ },
2198
+ clipPath: "url(#".concat(b, ")"),
2199
+ children: /* @__PURE__ */jsx("path", {
2200
+ style: {
2201
+ fill: "url(#".concat(c, ")"),
2202
+ stroke: "none"
2203
+ },
2204
+ d: "M558.674 82.142c6.855-6.855 17.969-6.855 24.824 0 6.854 6.855 6.854 17.969 0 24.823L453.605 236.858c-6.855 6.855-17.969 6.855-24.824 0s-6.855-17.969 0-24.823z"
2205
+ })
2206
+ })
2207
+ }), /* @__PURE__ */jsx("path", {
2208
+ style: {
2209
+ fill: "url(#".concat(d, ")"),
2210
+ stroke: "none"
2211
+ },
2212
+ d: "M558.674 236.858 428.781 106.966c-6.855-6.855-6.855-17.969 0-24.825 6.855-6.854 17.969-6.854 24.823 0l129.894 129.894c6.854 6.855 6.854 17.968 0 24.823A17.498 17.498 0 0 1 571.086 242a17.495 17.495 0 0 1-12.412-5.142",
2213
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2214
+ }), /* @__PURE__ */jsxs("g", {
2215
+ clipPath: "url(#".concat(e, ")"),
2216
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
2217
+ children: [/* @__PURE__ */jsx("g", {
2218
+ style: {
2219
+ opacity: 0.69999701
2220
+ },
2221
+ clipPath: "url(#".concat(f, ")"),
2222
+ children: /* @__PURE__ */jsx("path", {
2223
+ style: {
2224
+ fill: "url(#".concat(g, ")"),
2225
+ stroke: "none"
2226
+ },
2227
+ d: "M328.853 112.107c22.297 0 40.372 18.075 40.372 40.372v71.315c0 10.054 7.505 18.206 17.554 18.206 10.048 0 17.552-8.152 17.552-18.206v-71.315c0-41.686-33.793-75.479-75.478-75.479-9.694 0-17.553 7.859-17.553 17.554 0 9.694 7.859 17.553 17.553 17.553"
2228
+ })
2229
+ }), /* @__PURE__ */jsx("g", {
2230
+ style: {
2231
+ opacity: 0.69999701
2232
+ },
2233
+ clipPath: "url(#".concat(h, ")"),
2234
+ children: /* @__PURE__ */jsx("path", {
2235
+ style: {
2236
+ fill: "url(#".concat(i, ")"),
2237
+ stroke: "none"
2238
+ },
2239
+ d: "M216.513 242c-10.049 0-17.553-8.152-17.553-18.206V95.206c0-10.054 7.504-18.206 17.553-18.206 10.048 0 17.553 8.152 17.553 18.206v128.588c0 10.054-7.505 18.206-17.553 18.206"
2240
+ })
2241
+ })]
2242
+ }), /* @__PURE__ */jsx("path", {
2243
+ style: {
2244
+ fill: "url(#".concat(j, ")"),
2245
+ stroke: "none"
2246
+ },
2247
+ d: "M369.225 224.447c0-9.694 7.859-17.553 17.553-17.553 9.695 0 17.553 7.859 17.553 17.553s-7.858 17.552-17.553 17.552c-9.694 0-17.553-7.858-17.553-17.552",
2248
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2249
+ }), /* @__PURE__ */jsx("path", {
2250
+ style: {
2251
+ fill: "url(#".concat(k, ")"),
2252
+ stroke: "none"
2253
+ },
2254
+ d: "M553.532 94.554c0-9.695 7.859-17.554 17.553-17.554 9.695 0 17.554 7.859 17.554 17.554 0 9.694-7.859 17.552-17.554 17.552-9.694 0-17.553-7.858-17.553-17.552",
2255
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2256
+ }), /* @__PURE__ */jsx("path", {
2257
+ style: {
2258
+ fill: "url(#".concat(l, ")"),
2259
+ stroke: "none"
2260
+ },
2261
+ d: "M69.067 223.794V95.206C69.067 85.152 76.571 77 86.62 77c10.048 0 17.553 8.152 17.553 18.206v128.588c0 10.055-7.505 18.205-17.553 18.205-10.049 0-17.553-8.15-17.553-18.205",
2262
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2263
+ }), /* @__PURE__ */jsx("path", {
2264
+ style: {
2265
+ fill: "url(#".concat(m, ")"),
2266
+ stroke: "none"
2267
+ },
2268
+ d: "M198.96 94.554c0-9.695 7.859-17.554 17.553-17.554 9.695 0 17.554 7.859 17.554 17.554 0 9.694-7.859 17.553-17.554 17.553-9.694 0-17.553-7.859-17.553-17.553",
2269
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2270
+ }), /* @__PURE__ */jsx("g", {
2271
+ clipPath: "url(#".concat(n, ")"),
2272
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
2273
+ children: /* @__PURE__ */jsx("g", {
2274
+ style: {
2275
+ opacity: 0.69999701
2276
+ },
2277
+ clipPath: "url(#".concat(o, ")"),
2278
+ children: /* @__PURE__ */jsx("path", {
2279
+ style: {
2280
+ fill: "url(#".concat(p, ")"),
2281
+ stroke: "none"
2282
+ },
2283
+ d: "M139.155 147.088c6.855-6.855 17.969-6.855 24.824 0s6.855 17.969 0 24.824l-64.947 64.946c-6.855 6.855-17.969 6.855-24.824 0s-6.855-17.969 0-24.823z"
2284
+ })
2285
+ })
2286
+ }), /* @__PURE__ */jsx("path", {
2287
+ style: {
2288
+ fill: "url(#".concat(q, ")"),
2289
+ stroke: "none"
2290
+ },
2291
+ d: "m204.101 236.858-64.947-64.946c-6.854-6.855-6.854-17.969 0-24.824 6.856-6.855 17.97-6.855 24.824 0l64.947 64.947c6.855 6.855 6.855 17.968 0 24.823A17.495 17.495 0 0 1 216.513 242a17.498 17.498 0 0 1-12.412-5.142",
2292
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2293
+ }), /* @__PURE__ */jsx("path", {
2294
+ style: {
2295
+ fill: "url(#".concat(r, ")"),
2296
+ stroke: "none"
2297
+ },
2298
+ d: "M253.374 223.794v-71.315c0-41.685 33.793-75.479 75.479-75.479 9.695 0 17.553 7.859 17.553 17.554 0 9.694-7.858 17.553-17.553 17.553-22.297 0-40.372 18.075-40.372 40.372v71.315c0 10.055-7.505 18.205-17.554 18.205s-17.553-8.15-17.553-18.205",
2299
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
2300
+ })]
2301
+ });
2302
+ }
2303
+ const Logo = styled.span(_templateObject19 || (_templateObject19 = _taggedTemplateLiteral(["\n display: inline-block;\n height: 0.8em;\n margin-right: 1em;\n transform: translate(0.3em, -0.2em);\n"])));
2304
+ const Header = () => /* @__PURE__ */jsxs(Fragment, {
2305
+ children: [/* @__PURE__ */jsx(Logo, {
2306
+ children: /* @__PURE__ */jsx(MuxLogo, {
2307
+ height: 13
2308
+ })
2309
+ }), "API Credentials"]
2310
+ });
2311
+ function FormField(props) {
2312
+ const {
2313
+ children,
2314
+ title,
2315
+ description,
2316
+ inputId
2317
+ } = props;
2318
+ return /* @__PURE__ */jsxs(Stack, {
2319
+ space: 1,
2320
+ children: [/* @__PURE__ */jsx(Flex, {
2321
+ align: "flex-end",
2322
+ children: /* @__PURE__ */jsx(Box, {
2323
+ flex: 1,
2324
+ paddingY: 2,
2325
+ children: /* @__PURE__ */jsx(Stack, {
2326
+ space: 2,
2327
+ children: /* @__PURE__ */jsxs(Flex, {
2328
+ children: [/* @__PURE__ */jsx(Text, {
2329
+ as: "label",
2330
+ htmlFor: inputId,
2331
+ weight: "semibold",
2332
+ size: 1,
2333
+ children: title || /* @__PURE__ */jsx("em", {
2334
+ children: "Untitled"
2335
+ })
2336
+ }), description && /* @__PURE__ */jsx(Text, {
2337
+ muted: true,
2338
+ size: 1,
2339
+ children: description
2340
+ })]
2341
+ })
2342
+ })
2343
+ })
2344
+ }), /* @__PURE__ */jsx("div", {
2345
+ children
2346
+ })]
2347
+ });
2348
+ }
2349
+ var FormField$1 = memo(FormField);
2350
+ const fieldNames = ["token", "secretKey", "enableSignedUrls"];
2351
+ function ConfigureApi(_ref18) {
2352
+ let {
2353
+ secrets,
2354
+ setDialogState
2355
+ } = _ref18;
2356
+ var _a, _b;
2357
+ const client = useClient();
2358
+ const [state, dispatch] = useSecretsFormState(secrets);
2359
+ const hasSecretsInitially = useMemo(() => secrets.token && secrets.secretKey, [secrets]);
2360
+ const handleClose = useCallback(() => setDialogState(false), [setDialogState]);
2361
+ const dirty = useMemo(() => secrets.token !== state.token || secrets.secretKey !== state.secretKey || secrets.enableSignedUrls !== state.enableSignedUrls, [secrets, state]);
2362
+ const id = "ConfigureApi".concat(useId());
2363
+ const [tokenId, secretKeyId, enableSignedUrlsId] = useMemo(() => fieldNames.map(field => "".concat(id, "-").concat(field)), [id]);
2364
+ const firstField = useRef(null);
2365
+ const handleSaveSecrets = useSaveSecrets(client, secrets);
2366
+ const saving = useRef(false);
2367
+ const handleSubmit = useCallback(event => {
2368
+ event.preventDefault();
2369
+ if (!saving.current && event.currentTarget.reportValidity()) {
2370
+ saving.current = true;
2371
+ dispatch({
2372
+ type: "submit"
2373
+ });
2374
+ const {
2375
+ token,
2376
+ secretKey,
2377
+ enableSignedUrls
2378
+ } = state;
2379
+ handleSaveSecrets({
2380
+ token,
2381
+ secretKey,
2382
+ enableSignedUrls
2383
+ }).then(savedSecrets => {
2384
+ const {
2385
+ projectId,
2386
+ dataset
2387
+ } = client.config();
2388
+ clear([cacheNs, _id, projectId, dataset]);
2389
+ preload(() => Promise.resolve(savedSecrets), [cacheNs, _id, projectId, dataset]);
2390
+ setDialogState(false);
2391
+ }).catch(err => dispatch({
2392
+ type: "error",
2393
+ payload: err.message
2394
+ })).finally(() => {
2395
+ saving.current = false;
2396
+ });
2397
+ }
2398
+ }, [client, dispatch, handleSaveSecrets, setDialogState, state]);
2399
+ const handleChangeToken = useCallback(event => {
2400
+ dispatch({
2401
+ type: "change",
2402
+ payload: {
2403
+ name: "token",
2404
+ value: event.currentTarget.value
2405
+ }
2406
+ });
2407
+ }, [dispatch]);
2408
+ const handleChangeSecretKey = useCallback(event => {
2409
+ dispatch({
2410
+ type: "change",
2411
+ payload: {
2412
+ name: "secretKey",
2413
+ value: event.currentTarget.value
2414
+ }
2415
+ });
2416
+ }, [dispatch]);
2417
+ const handleChangeEnableSignedUrls = useCallback(event => {
2418
+ dispatch({
2419
+ type: "change",
2420
+ payload: {
2421
+ name: "enableSignedUrls",
2422
+ value: event.currentTarget.checked
2423
+ }
2424
+ });
2425
+ }, [dispatch]);
2426
+ useEffect(() => {
2427
+ if (firstField.current) {
2428
+ firstField.current.focus();
2429
+ }
2430
+ }, [firstField]);
2431
+ return /* @__PURE__ */jsx(Dialog, {
2432
+ id,
2433
+ onClose: handleClose,
2434
+ header: /* @__PURE__ */jsx(Header, {}),
2435
+ width: 0,
2436
+ children: /* @__PURE__ */jsx(Box, {
2437
+ padding: 4,
2438
+ style: {
2439
+ position: "relative"
2440
+ },
2441
+ children: /* @__PURE__ */jsx("form", {
2442
+ onSubmit: handleSubmit,
2443
+ noValidate: true,
2444
+ children: /* @__PURE__ */jsxs(Stack, {
2445
+ space: 4,
2446
+ children: [!hasSecretsInitially && /* @__PURE__ */jsx(Card, {
2447
+ padding: [3, 3, 3],
2448
+ radius: 2,
2449
+ shadow: 1,
2450
+ tone: "primary",
2451
+ children: /* @__PURE__ */jsxs(Stack, {
2452
+ space: 3,
2453
+ children: [/* @__PURE__ */jsxs(Text, {
2454
+ size: 1,
2455
+ children: ["To set up a new access token, go to your", " ", /* @__PURE__ */jsx("a", {
2456
+ href: "https://dashboard.mux.com/settings/access-tokens",
2457
+ target: "_blank",
2458
+ rel: "noreferrer noopener",
2459
+ children: "account on mux.com"
2460
+ }), "."]
2461
+ }), /* @__PURE__ */jsxs(Text, {
2462
+ size: 1,
2463
+ children: ["The access token needs permissions: ", /* @__PURE__ */jsx("strong", {
2464
+ children: "Mux Video "
2465
+ }), "(Full Access) and ", /* @__PURE__ */jsx("strong", {
2466
+ children: "Mux Data"
2467
+ }), " (Read)", /* @__PURE__ */jsx("br", {}), "The credentials will be stored safely in a hidden document only available to editors."]
2468
+ })]
2469
+ })
2470
+ }), /* @__PURE__ */jsx(FormField$1, {
2471
+ title: "Access Token",
2472
+ inputId: tokenId,
2473
+ children: /* @__PURE__ */jsx(TextInput, {
2474
+ id: tokenId,
2475
+ ref: firstField,
2476
+ onChange: handleChangeToken,
2477
+ type: "text",
2478
+ value: (_a = state.token) != null ? _a : "",
2479
+ required: !!state.secretKey || state.enableSignedUrls
2480
+ })
2481
+ }), /* @__PURE__ */jsx(FormField$1, {
2482
+ title: "Secret Key",
2483
+ inputId: secretKeyId,
2484
+ children: /* @__PURE__ */jsx(TextInput, {
2485
+ id: secretKeyId,
2486
+ onChange: handleChangeSecretKey,
2487
+ type: "text",
2488
+ value: (_b = state.secretKey) != null ? _b : "",
2489
+ required: !!state.token || state.enableSignedUrls
2490
+ })
2491
+ }), /* @__PURE__ */jsxs(Stack, {
2492
+ space: 4,
2493
+ children: [/* @__PURE__ */jsxs(Flex, {
2494
+ align: "center",
2495
+ children: [/* @__PURE__ */jsx(Checkbox, {
2496
+ id: enableSignedUrlsId,
2497
+ onChange: handleChangeEnableSignedUrls,
2498
+ checked: state.enableSignedUrls,
2499
+ style: {
2500
+ display: "block"
2501
+ }
2502
+ }), /* @__PURE__ */jsx(Box, {
2503
+ flex: 1,
2504
+ paddingLeft: 3,
2505
+ children: /* @__PURE__ */jsx(Text, {
2506
+ children: /* @__PURE__ */jsx("label", {
2507
+ htmlFor: enableSignedUrlsId,
2508
+ children: "Enable Signed Urls"
2509
+ })
2510
+ })
2511
+ })]
2512
+ }), secrets.signingKeyId && state.enableSignedUrls ? /* @__PURE__ */jsx(Card, {
2513
+ padding: [3, 3, 3],
2514
+ radius: 2,
2515
+ shadow: 1,
2516
+ tone: "caution",
2517
+ children: /* @__PURE__ */jsxs(Stack, {
2518
+ space: 3,
2519
+ children: [/* @__PURE__ */jsx(Text, {
2520
+ size: 1,
2521
+ children: "The signing key ID that Sanity will use is:"
2522
+ }), /* @__PURE__ */jsx(Code, {
2523
+ size: 1,
2524
+ children: secrets.signingKeyId
2525
+ }), /* @__PURE__ */jsxs(Text, {
2526
+ size: 1,
2527
+ children: ["This key is only used for previewing content in the Sanity UI.", /* @__PURE__ */jsx("br", {}), "You should generate a different key to use in your application server."]
2528
+ })]
2529
+ })
2530
+ }) : null]
2531
+ }), /* @__PURE__ */jsxs(Inline, {
2532
+ space: 2,
2533
+ children: [/* @__PURE__ */jsx(Button, {
2534
+ text: "Save",
2535
+ disabled: !dirty,
2536
+ loading: state.submitting,
2537
+ tone: "primary",
2538
+ mode: "default",
2539
+ type: "submit"
2540
+ }), /* @__PURE__ */jsx(Button, {
2541
+ disabled: state.submitting,
2542
+ text: "Cancel",
2543
+ mode: "bleed",
2544
+ onClick: handleClose
2545
+ })]
2546
+ }), state.error && /* @__PURE__ */jsx(Card, {
2547
+ padding: [3, 3, 3],
2548
+ radius: 2,
2549
+ shadow: 1,
2550
+ tone: "critical",
2551
+ children: /* @__PURE__ */jsx(Text, {
2552
+ children: state.error
2553
+ })
2554
+ })]
2555
+ })
2556
+ })
2557
+ })
2558
+ });
2559
+ }
2560
+ var ConfigureApi$1 = memo(ConfigureApi);
2561
+ function Onboard(props) {
2562
+ const {
2563
+ setDialogState
2564
+ } = props;
2565
+ const handleOpen = useCallback(() => setDialogState("secrets"), [setDialogState]);
2566
+ return /* @__PURE__ */jsx(Fragment, {
2567
+ children: /* @__PURE__ */jsx("div", {
2568
+ style: {
2569
+ padding: 2
2570
+ },
2571
+ children: /* @__PURE__ */jsx(Card, {
2572
+ display: "flex",
2573
+ sizing: "border",
2574
+ style: {
2575
+ aspectRatio: "16/9",
2576
+ width: "100%",
2577
+ boxShadow: "var(--card-bg-color) 0 0 0 2px"
2578
+ },
2579
+ paddingX: [2, 3, 4, 4],
2580
+ radius: 1,
2581
+ tone: "transparent",
2582
+ children: /* @__PURE__ */jsx(Flex, {
2583
+ justify: "flex-start",
2584
+ align: "center",
2585
+ children: /* @__PURE__ */jsxs(Grid, {
2586
+ columns: 1,
2587
+ gap: [2, 3, 4, 4],
2588
+ children: [/* @__PURE__ */jsx(Inline, {
2589
+ paddingY: 1,
2590
+ children: /* @__PURE__ */jsx("div", {
2591
+ style: {
2592
+ height: "32px"
2593
+ },
2594
+ children: /* @__PURE__ */jsx(MuxLogo, {})
2595
+ })
2596
+ }), /* @__PURE__ */jsx(Inline, {
2597
+ paddingY: 1,
2598
+ children: /* @__PURE__ */jsx(Heading, {
2599
+ size: [0, 1, 2, 2],
2600
+ children: "Upload and preview videos directly from your studio."
2601
+ })
2602
+ }), /* @__PURE__ */jsx(Inline, {
2603
+ paddingY: 1,
2604
+ children: /* @__PURE__ */jsx(Button, {
2605
+ mode: "ghost",
2606
+ icon: PlugIcon,
2607
+ text: "Configure API",
2608
+ onClick: handleOpen
2609
+ })
2610
+ })]
2611
+ })
2612
+ })
2613
+ })
2614
+ })
2615
+ });
2616
+ }
2617
+ const Input = props => {
2618
+ var _a;
2619
+ const client = useClient();
2620
+ const secretDocumentValues = useSecretsDocumentValues();
2621
+ const assetDocumentValues = useAssetDocumentValues((_a = props.value) == null ? void 0 : _a.asset);
2622
+ const poll = useMuxPolling(props.readOnly ? void 0 : (assetDocumentValues == null ? void 0 : assetDocumentValues.value) || void 0);
2623
+ const [dialogState, setDialogState] = useDialogState();
2624
+ const error = secretDocumentValues.error || assetDocumentValues.error || poll.error;
2625
+ if (error) {
2626
+ throw error;
2627
+ }
2628
+ const isLoading = secretDocumentValues.isLoading || assetDocumentValues.isLoading;
2629
+ return /* @__PURE__ */jsx(Fragment, {
2630
+ children: isLoading ? /* @__PURE__ */jsx(InputFallback, {}) : /* @__PURE__ */jsxs(Fragment, {
2631
+ children: [secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? /* @__PURE__ */jsx(Onboard, {
2632
+ setDialogState
2633
+ }) : /* @__PURE__ */jsx(MuxVideoInputUploader, {
2634
+ ...props,
2635
+ config: props.config,
2636
+ onChange: props.onChange,
2637
+ client,
2638
+ secrets: secretDocumentValues.value.secrets,
2639
+ asset: assetDocumentValues.value,
2640
+ dialogState,
2641
+ setDialogState,
2642
+ needsSetup: secretDocumentValues.value.needsSetup
2643
+ }), dialogState === "secrets" && /* @__PURE__ */jsx(ConfigureApi$1, {
2644
+ setDialogState,
2645
+ secrets: secretDocumentValues.value.secrets
2646
+ })]
2647
+ })
2648
+ });
2649
+ };
2650
+ var Input$1 = memo(Input);
2651
+ export { Input$1 as default };
2652
+ //# sourceMappingURL=Input-4e0aa2ef.js.map