sanity-plugin-mux-input 2.1.1 → 2.2.1

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 (67) hide show
  1. package/README.md +1 -1
  2. package/lib/index.cjs +4038 -4
  3. package/lib/index.cjs.map +1 -1
  4. package/lib/index.d.ts +14 -1
  5. package/lib/index.js +4027 -2
  6. package/lib/index.js.map +1 -1
  7. package/package.json +30 -30
  8. package/src/actions/assets.ts +30 -2
  9. package/src/components/ConfigureApi.tsx +9 -1
  10. package/src/components/FormField.tsx +8 -10
  11. package/src/components/IconInfo.tsx +23 -0
  12. package/src/components/Input.styled.tsx +0 -8
  13. package/src/components/Input.tsx +4 -3
  14. package/src/components/InputBrowser.tsx +1 -8
  15. package/src/components/Player.styled.tsx +5 -144
  16. package/src/components/Player.tsx +23 -109
  17. package/src/components/PlayerActionsMenu.tsx +0 -4
  18. package/src/components/SelectAsset.tsx +18 -58
  19. package/src/components/SelectSortOptions.tsx +45 -0
  20. package/src/components/SpinnerBox.tsx +17 -0
  21. package/src/components/StudioTool.tsx +20 -0
  22. package/src/components/VideoDetails/DeleteDialog.tsx +156 -0
  23. package/src/components/VideoDetails/VideoDetails.tsx +298 -0
  24. package/src/components/VideoDetails/VideoReferences.tsx +70 -0
  25. package/src/components/VideoDetails/useVideoDetails.ts +85 -0
  26. package/src/components/VideoInBrowser.tsx +183 -0
  27. package/src/components/VideoMetadata.tsx +43 -0
  28. package/src/components/VideoPlayer.tsx +69 -0
  29. package/src/components/VideoThumbnail.tsx +106 -0
  30. package/src/components/VideosBrowser.tsx +83 -0
  31. package/src/components/__legacy__Uploader.tsx +2 -9
  32. package/src/components/documentPreview/DocumentPreview.tsx +107 -0
  33. package/src/components/documentPreview/DraftStatus.tsx +34 -0
  34. package/src/components/documentPreview/MissingSchemaType.tsx +33 -0
  35. package/src/components/documentPreview/PaneItemPreview.tsx +71 -0
  36. package/src/components/documentPreview/PublishedStatus.tsx +35 -0
  37. package/src/components/documentPreview/TimeAgo.tsx +13 -0
  38. package/src/components/documentPreview/paneItemTypes.ts +7 -0
  39. package/src/components/icons/Resolution.tsx +12 -0
  40. package/src/components/icons/StopWatch.tsx +20 -0
  41. package/src/components/icons/ToolIcon.tsx +21 -0
  42. package/src/hooks/useAssets.ts +61 -0
  43. package/src/hooks/useCancelUpload.ts +2 -2
  44. package/src/hooks/useClient.ts +3 -1
  45. package/src/hooks/useDocReferences.ts +21 -0
  46. package/src/hooks/useInView.ts +45 -0
  47. package/src/index.ts +2 -0
  48. package/src/plugin.tsx +1 -1
  49. package/src/util/constants.ts +7 -0
  50. package/src/util/createSearchFilter.ts +78 -0
  51. package/src/util/formatSeconds.ts +22 -0
  52. package/src/util/getAnimatedPosterSrc.ts +1 -1
  53. package/src/util/getPlaybackId.ts +1 -1
  54. package/src/util/getPlaybackPolicy.ts +1 -1
  55. package/src/util/getVideoMetadata.ts +18 -0
  56. package/src/util/types.ts +16 -1
  57. package/lib/_chunks/Player-547f8e2a.cjs +0 -474
  58. package/lib/_chunks/Player-547f8e2a.cjs.map +0 -1
  59. package/lib/_chunks/Player-bfdb96f6.js +0 -465
  60. package/lib/_chunks/Player-bfdb96f6.js.map +0 -1
  61. package/lib/_chunks/index-39e38243.cjs +0 -3251
  62. package/lib/_chunks/index-39e38243.cjs.map +0 -1
  63. package/lib/_chunks/index-71899191.js +0 -3229
  64. package/lib/_chunks/index-71899191.js.map +0 -1
  65. package/src/components/EditThumbnailDialog.tsx +0 -74
  66. package/src/components/VideoSource.styled.tsx +0 -235
  67. package/src/components/VideoSource.tsx +0 -318
package/lib/index.js CHANGED
@@ -1,3 +1,4028 @@
1
- import 'sanity';
2
- export { defaultConfig, muxInput } from './_chunks/index-71899191.js';
1
+ import { useClient as useClient$1, createHookFromObservableFactory, useDocumentStore, collate, SanityDefaultPreview, useTimeAgo, TextWithTone, isRecord, getPreviewStateObservable, getPreviewValueWithFallback, DocumentPreviewPresence, useDocumentPreviewStore, useSchema, useDocumentPresence, PreviewCard, useDocumentValues, isReference, useProjectId, useDataset, PatchEvent, unset, setIfMissing, set, LinearProgress, definePlugin } from 'sanity';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { SortIcon, WarningOutlineIcon, EditIcon, PublishIcon, DocumentIcon, TrashIcon, CheckmarkIcon, ErrorOutlineIcon, RevertIcon, SearchIcon, ClockIcon, CropIcon, CalendarIcon, LockIcon, PlayIcon, UploadIcon, PlugIcon, ResetIcon, EllipsisVerticalIcon, DocumentVideoIcon } from '@sanity/icons';
4
+ import { MenuButton, Button, Menu, MenuItem, Box, Spinner, Stack, Flex, Text, Card, Tooltip, Inline, useToast, Dialog, Heading, Checkbox, TabList, Tab, TabPanel, TextInput, Label as Label$1, Grid, Code, useClickOutside, Popover, MenuDivider, rem } from '@sanity/ui';
5
+ import React, { useState, useMemo, useId, memo, isValidElement, useEffect, useRef, useCallback, createElement, forwardRef, Component, useReducer, Suspense } from 'react';
6
+ import { words, trim, toLower, uniq, compact, isString, isNumber } from 'lodash';
7
+ import MuxPlayer from '@mux/mux-player-react';
8
+ import { suspend, clear, preload } from 'suspend-react';
9
+ import styled, { css } from 'styled-components';
10
+ import { usePaneRouter } from 'sanity/desk';
11
+ import { IntentLink } from 'sanity/router';
12
+ import { useMemoObservable } from 'react-rx';
13
+ import useSWR from 'swr';
14
+ import { Observable, defer, concat, of, throwError, from, Subject } from 'rxjs';
15
+ import { switchMap, mergeMap, catchError, mergeMapTo, takeUntil, tap } from 'rxjs/operators';
16
+ import { uuid } from '@sanity/uuid';
17
+ import { UpChunk } from '@mux/upchunk';
18
+ import { isValidElementType } from 'react-is';
19
+ import scrollIntoView from 'scroll-into-view-if-needed';
20
+ import { useErrorBoundary } from 'use-error-boundary';
21
+ const ToolIcon = () => /* @__PURE__ */jsx("svg", {
22
+ stroke: "currentColor",
23
+ fill: "currentColor",
24
+ strokeWidth: "0",
25
+ viewBox: "0 0 24 24",
26
+ height: "1em",
27
+ width: "1em",
28
+ xmlns: "http://www.w3.org/2000/svg",
29
+ children: /* @__PURE__ */jsx("path", {
30
+ d: "M21 3H3c-1.11 0-2 .89-2 2v12c0 1.1.89 2 2 2h5v2h8v-2h5c1.1 0 1.99-.9 1.99-2L23 5c0-1.11-.9-2-2-2zm0 14H3V5h18v12zm-5-6l-7 4V7z"
31
+ })
32
+ });
33
+ const SANITY_API_VERSION = "2022-09-14";
34
+ function useClient() {
35
+ return useClient$1({
36
+ apiVersion: SANITY_API_VERSION
37
+ });
38
+ }
39
+ const SPECIAL_CHARS = /([^!@#$%^&*(),\\/?";:{}|[\]+<>\s-])+/g;
40
+ const STRIP_EDGE_CHARS = /(^[.]+)|([.]+$)/;
41
+ function tokenize(string) {
42
+ return (string.match(SPECIAL_CHARS) || []).map(token => token.replace(STRIP_EDGE_CHARS, ""));
43
+ }
44
+ function toGroqParams(terms) {
45
+ const params = {};
46
+ return terms.reduce((acc, term, i) => {
47
+ acc["t".concat(i)] = "*".concat(term, "*");
48
+ return acc;
49
+ }, params);
50
+ }
51
+ function extractTermsFromQuery(query) {
52
+ const quotedQueries = [];
53
+ const unquotedQuery = query.replace(/("[^"]*")/g, match => {
54
+ if (words(match).length > 1) {
55
+ quotedQueries.push(match);
56
+ return "";
57
+ }
58
+ return match;
59
+ });
60
+ const quotedTerms = quotedQueries.map(str => trim(toLower(str)));
61
+ const remainingTerms = uniq(compact(tokenize(toLower(unquotedQuery))));
62
+ return [...quotedTerms, ...remainingTerms];
63
+ }
64
+ const SEARCH_PATHS = ["filename", "assetId", "_id"];
65
+ function createConstraints(terms) {
66
+ const constraints = terms.map((_term, i) => SEARCH_PATHS.map(joinedPath => "".concat(joinedPath, " match $t").concat(i))).filter(constraint => constraint.length > 0);
67
+ return constraints.map(constraint => "(".concat(constraint.join(" || "), ")"));
68
+ }
69
+ function createSearchFilter(query) {
70
+ const terms = extractTermsFromQuery(query);
71
+ return {
72
+ filter: createConstraints(terms),
73
+ params: {
74
+ ...toGroqParams(terms)
75
+ }
76
+ };
77
+ }
78
+ const ASSET_SORT_OPTIONS = {
79
+ createdDesc: {
80
+ groq: "_createdAt desc",
81
+ label: "Newest first"
82
+ },
83
+ createdAsc: {
84
+ groq: "_createdAt asc",
85
+ label: "First created (oldest)"
86
+ },
87
+ filenameAsc: {
88
+ groq: "filename asc",
89
+ label: "By filename (A-Z)"
90
+ },
91
+ filenameDesc: {
92
+ groq: "filename desc",
93
+ label: "By filename (Z-A)"
94
+ }
95
+ };
96
+ const useAssetDocuments = createHookFromObservableFactory(_ref => {
97
+ let {
98
+ documentStore,
99
+ sort,
100
+ searchQuery
101
+ } = _ref;
102
+ const search = createSearchFilter(searchQuery);
103
+ const filter = ['_type == "mux.videoAsset"', ...search.filter].filter(Boolean).join(" && ");
104
+ const query = ASSET_SORT_OPTIONS[sort].groq;
105
+ return documentStore.listenQuery( /* groq */
106
+ "*[".concat(filter, "] | order(").concat(query, ")"), search.params, {
107
+ apiVersion: SANITY_API_VERSION
108
+ });
109
+ });
110
+ function useAssets() {
111
+ const documentStore = useDocumentStore();
112
+ const [sort, setSort] = useState("createdDesc");
113
+ const [searchQuery, setSearchQuery] = useState("");
114
+ const [assetDocuments = [], isLoading] = useAssetDocuments({
115
+ documentStore,
116
+ sort,
117
+ searchQuery
118
+ });
119
+ const assets = useMemo(() =>
120
+ // Avoid displaying both drafts & published assets by collating them together and giving preference to drafts
121
+ collate(assetDocuments).map(collated => ({
122
+ ...(collated.draft || collated.published || {}),
123
+ _id: collated.id
124
+ })), [assetDocuments]);
125
+ return {
126
+ assets,
127
+ isLoading,
128
+ sort,
129
+ searchQuery,
130
+ setSort,
131
+ setSearchQuery
132
+ };
133
+ }
134
+ const CONTEXT_MENU_POPOVER_PROPS = {
135
+ constrainSize: true,
136
+ placement: "bottom",
137
+ portal: true,
138
+ width: 0
139
+ };
140
+ function SelectSortOptions(props) {
141
+ const id = useId();
142
+ return /* @__PURE__ */jsx(MenuButton, {
143
+ button: /* @__PURE__ */jsx(Button, {
144
+ text: "Sort",
145
+ icon: SortIcon,
146
+ mode: "bleed",
147
+ padding: 3,
148
+ style: {
149
+ cursor: "pointer"
150
+ }
151
+ }),
152
+ id,
153
+ menu: /* @__PURE__ */jsx(Menu, {
154
+ children: Object.entries(ASSET_SORT_OPTIONS).map(_ref2 => {
155
+ let [type, {
156
+ label
157
+ }] = _ref2;
158
+ return /* @__PURE__ */jsx(MenuItem, {
159
+ "data-as": "button",
160
+ onClick: () => props.setSort(type),
161
+ padding: 3,
162
+ tone: "default",
163
+ text: label,
164
+ pressed: type === props.sort
165
+ }, type);
166
+ })
167
+ }),
168
+ popover: CONTEXT_MENU_POPOVER_PROPS
169
+ });
170
+ }
171
+ const SpinnerBox = () => /* @__PURE__ */jsx(Box, {
172
+ style: {
173
+ display: "flex",
174
+ alignItems: "center",
175
+ justifyContent: "center",
176
+ minHeight: "150px"
177
+ },
178
+ children: /* @__PURE__ */jsx(Spinner, {})
179
+ });
180
+ const name$1 = "mux-input";
181
+ const cacheNs = "sanity-plugin-mux-input";
182
+ const muxSecretsDocumentId = "secrets.mux";
183
+ const DIALOGS_Z_INDEX = 6e4;
184
+ const THUMBNAIL_ASPECT_RATIO = 16 / 9;
185
+ const MIN_ASPECT_RATIO = 1;
186
+ function FormField(props) {
187
+ const {
188
+ children,
189
+ title,
190
+ description,
191
+ inputId
192
+ } = props;
193
+ return /* @__PURE__ */jsxs(Stack, {
194
+ space: 1,
195
+ children: [/* @__PURE__ */jsx(Flex, {
196
+ align: "flex-end",
197
+ children: /* @__PURE__ */jsx(Box, {
198
+ flex: 1,
199
+ paddingY: 2,
200
+ children: /* @__PURE__ */jsxs(Stack, {
201
+ space: 2,
202
+ children: [/* @__PURE__ */jsx(Text, {
203
+ as: "label",
204
+ htmlFor: inputId,
205
+ weight: "semibold",
206
+ size: 1,
207
+ children: title || /* @__PURE__ */jsx("em", {
208
+ children: "Untitled"
209
+ })
210
+ }), description && /* @__PURE__ */jsx(Text, {
211
+ muted: true,
212
+ size: 1,
213
+ children: description
214
+ })]
215
+ })
216
+ })
217
+ }), /* @__PURE__ */jsx("div", {
218
+ children
219
+ })]
220
+ });
221
+ }
222
+ var FormField$1 = memo(FormField);
223
+ const IconInfo = props => {
224
+ const Icon = props.icon;
225
+ return /* @__PURE__ */jsxs(Flex, {
226
+ gap: 2,
227
+ align: "center",
228
+ padding: 1,
229
+ children: [/* @__PURE__ */jsx(Text, {
230
+ size: (props.size || 1) + 1,
231
+ muted: true,
232
+ children: /* @__PURE__ */jsx(Icon, {})
233
+ }), /* @__PURE__ */jsx(Text, {
234
+ size: props.size || 1,
235
+ muted: props.muted,
236
+ children: props.text
237
+ })]
238
+ });
239
+ };
240
+ function ResolutionIcon(props) {
241
+ return /* @__PURE__ */jsx("svg", {
242
+ xmlns: "http://www.w3.org/2000/svg",
243
+ width: "1em",
244
+ height: "1em",
245
+ viewBox: "0 0 24 24",
246
+ ...props,
247
+ children: /* @__PURE__ */jsx("path", {
248
+ fill: "currentColor",
249
+ d: "M20 9V6h-3V4h5v5h-2ZM2 9V4h5v2H4v3H2Zm15 11v-2h3v-3h2v5h-5ZM2 20v-5h2v3h3v2H2Zm4-4V8h12v8H6Zm2-2h8v-4H8v4Zm0 0v-4v4Z"
250
+ })
251
+ });
252
+ }
253
+ function StopWatchIcon(props) {
254
+ return /* @__PURE__ */jsxs("svg", {
255
+ xmlns: "http://www.w3.org/2000/svg",
256
+ width: "1em",
257
+ height: "1em",
258
+ viewBox: "0 0 512 512",
259
+ ...props,
260
+ children: [/* @__PURE__ */jsx("path", {
261
+ d: "M232 306.667h48V176h-48v130.667z",
262
+ fill: "currentColor"
263
+ }), /* @__PURE__ */jsx("path", {
264
+ d: "M407.67 170.271l30.786-30.786-33.942-33.941-30.785 30.786C341.217 111.057 300.369 96 256 96 149.961 96 64 181.961 64 288s85.961 192 192 192 192-85.961 192-192c0-44.369-15.057-85.217-40.33-117.729zm-45.604 223.795C333.734 422.398 296.066 438 256 438s-77.735-15.602-106.066-43.934C121.602 365.735 106 328.066 106 288s15.602-77.735 43.934-106.066C178.265 153.602 215.934 138 256 138s77.734 15.602 106.066 43.934C390.398 210.265 406 247.934 406 288s-15.602 77.735-43.934 106.066z",
265
+ fill: "currentColor"
266
+ }), /* @__PURE__ */jsx("path", {
267
+ d: "M192 32h128v48H192z",
268
+ fill: "currentColor"
269
+ })]
270
+ });
271
+ }
272
+ const _id = "secrets.mux";
273
+ function readSecrets(client) {
274
+ const {
275
+ projectId,
276
+ dataset
277
+ } = client.config();
278
+ return suspend(async () => {
279
+ const data = await client.fetch( /* groq */
280
+ "*[_id == $_id][0]{\n token,\n secretKey,\n enableSignedUrls,\n signingKeyId,\n signingKeyPrivate\n }", {
281
+ _id
282
+ });
283
+ return {
284
+ token: (data == null ? void 0 : data.token) || null,
285
+ secretKey: (data == null ? void 0 : data.secretKey) || null,
286
+ enableSignedUrls: Boolean(data == null ? void 0 : data.enableSignedUrls) || false,
287
+ signingKeyId: (data == null ? void 0 : data.signingKeyId) || null,
288
+ signingKeyPrivate: (data == null ? void 0 : data.signingKeyPrivate) || null
289
+ };
290
+ }, [cacheNs, _id, projectId, dataset]);
291
+ }
292
+ function generateJwt(client, playbackId, aud, payload) {
293
+ const {
294
+ signingKeyId,
295
+ signingKeyPrivate
296
+ } = readSecrets(client);
297
+ if (!signingKeyId) {
298
+ throw new TypeError("Missing signingKeyId");
299
+ }
300
+ if (!signingKeyPrivate) {
301
+ throw new TypeError("Missing signingKeyPrivate");
302
+ }
303
+ const {
304
+ default: sign
305
+ } = suspend(() => import('jsonwebtoken-esm/sign'), ["jsonwebtoken-esm/sign"]);
306
+ return sign(payload ? JSON.parse(JSON.stringify(payload, (_, v) => v != null ? v : void 0)) : {}, atob(signingKeyPrivate), {
307
+ algorithm: "RS256",
308
+ keyid: signingKeyId,
309
+ audience: aud,
310
+ subject: playbackId,
311
+ noTimestamp: true,
312
+ expiresIn: "12h"
313
+ });
314
+ }
315
+ function getPlaybackId(asset) {
316
+ if (!(asset == null ? void 0 : asset.playbackId)) {
317
+ console.error("Asset is missing a playbackId", {
318
+ asset
319
+ });
320
+ throw new TypeError("Missing playbackId");
321
+ }
322
+ return asset.playbackId;
323
+ }
324
+ function getPlaybackPolicy(asset) {
325
+ var _a, _b, _c, _d;
326
+ return (_d = (_c = (_b = (_a = asset.data) == null ? void 0 : _a.playback_ids) == null ? void 0 : _b[0]) == null ? void 0 : _c.policy) != null ? _d : "public";
327
+ }
328
+ function getVideoSrc(_ref3) {
329
+ let {
330
+ asset,
331
+ client
332
+ } = _ref3;
333
+ const playbackId = getPlaybackId(asset);
334
+ const searchParams = new URLSearchParams();
335
+ if (getPlaybackPolicy(asset) === "signed") {
336
+ const token = generateJwt(client, playbackId, "v");
337
+ searchParams.set("token", token);
338
+ }
339
+ return "https://stream.mux.com/".concat(playbackId, ".m3u8?").concat(searchParams);
340
+ }
341
+ var name = "sanity-plugin-mux-input";
342
+ var version = "2.2.1";
343
+ var description = "An input component that integrates Sanity Studio with Mux video encoding/hosting service.";
344
+ var keywords = ["sanity", "video", "mux", "input", "plugin", "sanity-plugin", "media"];
345
+ var homepage = "https://github.com/sanity-io/sanity-plugin-mux-input#readme";
346
+ var bugs = {
347
+ url: "https://github.com/sanity-io/sanity-plugin-mux-input/issues"
348
+ };
349
+ var repository = {
350
+ type: "git",
351
+ url: "git@github.com:sanity-io/sanity-plugin-mux-input.git"
352
+ };
353
+ var license = "MIT";
354
+ var author = "Sanity.io <hello@sanity.io>";
355
+ var sideEffects = false;
356
+ var type = "module";
357
+ var exports = {
358
+ ".": {
359
+ types: "./lib/index.d.ts",
360
+ source: "./src/index.ts",
361
+ require: "./lib/index.cjs",
362
+ node: {
363
+ "import": "./lib/index.cjs.js",
364
+ require: "./lib/index.cjs"
365
+ },
366
+ "import": "./lib/index.js",
367
+ "default": "./lib/index.js"
368
+ },
369
+ "./package.json": "./package.json"
370
+ };
371
+ var main = "./lib/index.cjs";
372
+ var module = "./lib/index.js";
373
+ var source = "./src/index.ts";
374
+ var types = "./lib/index.d.ts";
375
+ var files = ["src", "lib", "sanity.json", "v2-incompatible.js"];
376
+ var scripts = {
377
+ build: "run-s clean && plugin-kit verify-package --silent && pkg-utils build --strict && pkg-utils --strict",
378
+ clean: "rimraf lib",
379
+ dev: "next dev",
380
+ format: "prettier --write --cache --ignore-unknown .",
381
+ "link-watch": "plugin-kit link-watch",
382
+ lint: "eslint .",
383
+ prepare: "husky install || true",
384
+ prepublishOnly: "run-s build",
385
+ test: "npm run lint && npm run type-check && npm run build",
386
+ "type-check": "tsc --noEmit",
387
+ watch: "pkg-utils watch --strict"
388
+ };
389
+ var dependencies = {
390
+ "@mux/mux-player-react": "^1.11.4",
391
+ "@mux/upchunk": "^3",
392
+ "@sanity/icons": "^2",
393
+ "@sanity/incompatible-plugin": "^1",
394
+ "@sanity/ui": "^1",
395
+ "@sanity/uuid": "^3",
396
+ "jsonwebtoken-esm": "^1.0.5",
397
+ lodash: "^4",
398
+ "react-rx": "^2.1.3",
399
+ rxjs: "^7",
400
+ "scroll-into-view-if-needed": "^3",
401
+ "suspend-react": "^0.1.0",
402
+ swr: "^2.1.0",
403
+ "type-fest": "^4.0.0",
404
+ "use-error-boundary": "^2.0.6"
405
+ };
406
+ var devDependencies = {
407
+ "@commitlint/cli": "^17.6.7",
408
+ "@commitlint/config-conventional": "^17.6.7",
409
+ "@sanity/pkg-utils": "^2.3.10",
410
+ "@sanity/plugin-kit": "^3.1.7",
411
+ "@sanity/semantic-release-preset": "^4.1.2",
412
+ "@sanity/vision": "^3.14.5",
413
+ "@types/react": "^18.2.18",
414
+ "@types/styled-components": "^5.1.26",
415
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
416
+ "@typescript-eslint/parser": "^5.62.0",
417
+ "cz-conventional-changelog": "^3.3.0",
418
+ eslint: "^8.46.0",
419
+ "eslint-config-prettier": "^8.10.0",
420
+ "eslint-config-react-app": "^7.0.1",
421
+ "eslint-config-sanity": "^6.0.0",
422
+ "eslint-plugin-import": "^2.28.0",
423
+ "eslint-plugin-prettier": "^5.0.0",
424
+ "eslint-plugin-react": "^7.33.1",
425
+ "eslint-plugin-react-hooks": "^4.6.0",
426
+ "eslint-plugin-simple-import-sort": "^10.0.0",
427
+ husky: "^8.0.3",
428
+ "lint-staged": "^13.2.3",
429
+ next: "^13.4.12",
430
+ "next-sanity": "^5.1.3",
431
+ "npm-run-all": "^4.1.5",
432
+ prettier: "^3.0.1",
433
+ "prettier-plugin-packagejson": "^2.4.5",
434
+ react: "^18.2.0",
435
+ "react-dom": "^18.2.0",
436
+ "react-is": "^18.2.0",
437
+ rimraf: "^5.0.0",
438
+ sanity: "^3.14.5",
439
+ "styled-components": "^5.3.11",
440
+ typescript: "^5.1.6"
441
+ };
442
+ var peerDependencies = {
443
+ react: "^18",
444
+ "react-is": "^18",
445
+ sanity: "^3",
446
+ "styled-components": "^5.2"
447
+ };
448
+ var engines = {
449
+ node: ">=14"
450
+ };
451
+ var publishConfig = {
452
+ access: "public",
453
+ provenance: true
454
+ };
455
+ var sanityExchangeUrl = "https://www.sanity.io/plugins/sanity-plugin-mux-input";
456
+ var pluginPkg = {
457
+ name: name,
458
+ version: version,
459
+ description: description,
460
+ keywords: keywords,
461
+ homepage: homepage,
462
+ bugs: bugs,
463
+ repository: repository,
464
+ license: license,
465
+ author: author,
466
+ sideEffects: sideEffects,
467
+ type: type,
468
+ exports: exports,
469
+ main: main,
470
+ module: module,
471
+ source: source,
472
+ types: types,
473
+ files: files,
474
+ scripts: scripts,
475
+ dependencies: dependencies,
476
+ devDependencies: devDependencies,
477
+ peerDependencies: peerDependencies,
478
+ engines: engines,
479
+ publishConfig: publishConfig,
480
+ sanityExchangeUrl: sanityExchangeUrl
481
+ };
482
+ function VideoPlayer(_ref4) {
483
+ let {
484
+ asset,
485
+ children,
486
+ ...props
487
+ } = _ref4;
488
+ var _a, _b;
489
+ const client = useClient();
490
+ const videoSrc = useMemo(() => (asset == null ? void 0 : asset.playbackId) && getVideoSrc({
491
+ client,
492
+ asset
493
+ }), [asset, client]);
494
+ const signedToken = useMemo(() => {
495
+ try {
496
+ const url = new URL(videoSrc);
497
+ return url.searchParams.get("token");
498
+ } catch {
499
+ return false;
500
+ }
501
+ }, [videoSrc]);
502
+ const [width, height] = ((_b = (_a = asset == null ? void 0 : asset.data) == null ? void 0 : _a.aspect_ratio) != null ? _b : "16:9").split(":").map(Number);
503
+ const targetAspectRatio = props.forceAspectRatio || (Number.isNaN(width) ? 16 / 9 : width / height);
504
+ const aspectRatio = Math.max(MIN_ASPECT_RATIO, targetAspectRatio);
505
+ return /* @__PURE__ */jsx(Card, {
506
+ tone: "transparent",
507
+ style: {
508
+ aspectRatio,
509
+ position: "relative"
510
+ },
511
+ children: videoSrc && /* @__PURE__ */jsxs(Fragment, {
512
+ children: [/* @__PURE__ */jsx(MuxPlayer, {
513
+ ...props,
514
+ playsInline: true,
515
+ playbackId: asset.playbackId,
516
+ tokens: signedToken ? {
517
+ playback: signedToken,
518
+ thumbnail: signedToken,
519
+ storyboard: signedToken
520
+ } : void 0,
521
+ streamType: "on-demand",
522
+ preload: "metadata",
523
+ crossOrigin: "anonymous",
524
+ metadata: {
525
+ player_name: "Sanity Admin Dashboard",
526
+ player_version: pluginPkg.version,
527
+ page_type: "Preview Player"
528
+ },
529
+ style: {
530
+ height: "100%",
531
+ width: "100%",
532
+ display: "block",
533
+ objectFit: "contain"
534
+ }
535
+ }), children]
536
+ })
537
+ });
538
+ }
539
+ function deleteAssetOnMux(client, assetId) {
540
+ const {
541
+ dataset
542
+ } = client.config();
543
+ return client.request({
544
+ url: "/addons/mux/assets/".concat(dataset, "/").concat(assetId),
545
+ withCredentials: true,
546
+ method: "DELETE"
547
+ });
548
+ }
549
+ async function deleteAsset(_ref5) {
550
+ let {
551
+ client,
552
+ asset,
553
+ deleteOnMux
554
+ } = _ref5;
555
+ if (!(asset == null ? void 0 : asset._id)) return true;
556
+ try {
557
+ await client.delete(asset._id);
558
+ } catch (error) {
559
+ return "failed-sanity";
560
+ }
561
+ if (deleteOnMux && (asset == null ? void 0 : asset.assetId)) {
562
+ try {
563
+ await deleteAssetOnMux(client, asset.assetId);
564
+ } catch (error) {
565
+ return "failed-mux";
566
+ }
567
+ }
568
+ return true;
569
+ }
570
+ function getAsset(client, assetId) {
571
+ const {
572
+ dataset
573
+ } = client.config();
574
+ return client.request({
575
+ url: "/addons/mux/assets/".concat(dataset, "/data/").concat(assetId),
576
+ withCredentials: true,
577
+ method: "GET"
578
+ });
579
+ }
580
+ const getUnknownTypeFallback = (id, typeName) => ({
581
+ title: /* @__PURE__ */jsxs("em", {
582
+ children: ["No schema found for type ", /* @__PURE__ */jsx("code", {
583
+ children: typeName
584
+ })]
585
+ }),
586
+ subtitle: /* @__PURE__ */jsxs("em", {
587
+ children: ["Document: ", /* @__PURE__ */jsx("code", {
588
+ children: id
589
+ })]
590
+ }),
591
+ media: () => /* @__PURE__ */jsx(WarningOutlineIcon, {})
592
+ });
593
+ function MissingSchemaType(props) {
594
+ const {
595
+ layout,
596
+ value
597
+ } = props;
598
+ return /* @__PURE__ */jsx(SanityDefaultPreview, {
599
+ ...getUnknownTypeFallback(value._id, value._type),
600
+ layout
601
+ });
602
+ }
603
+ function TimeAgo(_ref6) {
604
+ let {
605
+ time
606
+ } = _ref6;
607
+ const timeAgo = useTimeAgo(time);
608
+ return /* @__PURE__ */jsxs("span", {
609
+ title: timeAgo,
610
+ children: [timeAgo, " ago"]
611
+ });
612
+ }
613
+ function DraftStatus(props) {
614
+ const {
615
+ document
616
+ } = props;
617
+ const updatedAt = document && "_updatedAt" in document && document._updatedAt;
618
+ return /* @__PURE__ */jsx(Tooltip, {
619
+ portal: true,
620
+ content: /* @__PURE__ */jsx(Box, {
621
+ padding: 2,
622
+ children: /* @__PURE__ */jsx(Text, {
623
+ size: 1,
624
+ children: document ? /* @__PURE__ */jsxs(Fragment, {
625
+ children: ["Edited ", updatedAt && /* @__PURE__ */jsx(TimeAgo, {
626
+ time: updatedAt
627
+ })]
628
+ }) : /* @__PURE__ */jsx(Fragment, {
629
+ children: "No unpublished edits"
630
+ })
631
+ })
632
+ }),
633
+ children: /* @__PURE__ */jsx(TextWithTone, {
634
+ tone: "caution",
635
+ dimmed: !document,
636
+ muted: !document,
637
+ size: 1,
638
+ children: /* @__PURE__ */jsx(EditIcon, {})
639
+ })
640
+ });
641
+ }
642
+ function PublishedStatus(props) {
643
+ const {
644
+ document
645
+ } = props;
646
+ const updatedAt = document && "_updatedAt" in document && document._updatedAt;
647
+ return /* @__PURE__ */jsx(Tooltip, {
648
+ portal: true,
649
+ content: /* @__PURE__ */jsx(Box, {
650
+ padding: 2,
651
+ children: /* @__PURE__ */jsx(Text, {
652
+ size: 1,
653
+ children: document ? /* @__PURE__ */jsxs(Fragment, {
654
+ children: ["Published ", updatedAt && /* @__PURE__ */jsx(TimeAgo, {
655
+ time: updatedAt
656
+ })]
657
+ }) : /* @__PURE__ */jsx(Fragment, {
658
+ children: "Not published"
659
+ })
660
+ })
661
+ }),
662
+ children: /* @__PURE__ */jsx(TextWithTone, {
663
+ tone: "positive",
664
+ dimmed: !document,
665
+ muted: !document,
666
+ size: 1,
667
+ children: /* @__PURE__ */jsx(PublishIcon, {})
668
+ })
669
+ });
670
+ }
671
+ function PaneItemPreview(props) {
672
+ const {
673
+ icon,
674
+ layout,
675
+ presence,
676
+ schemaType,
677
+ value
678
+ } = props;
679
+ const title = isRecord(value.title) && isValidElement(value.title) || isString(value.title) || isNumber(value.title) ? value.title : null;
680
+ const {
681
+ draft,
682
+ published,
683
+ isLoading
684
+ } = useMemoObservable(() => getPreviewStateObservable(props.documentPreviewStore, schemaType, value._id, title), [props.documentPreviewStore, schemaType, value._id, title]);
685
+ const status = isLoading ? null : /* @__PURE__ */jsxs(Inline, {
686
+ space: 4,
687
+ children: [presence && presence.length > 0 && /* @__PURE__ */jsx(DocumentPreviewPresence, {
688
+ presence
689
+ }), /* @__PURE__ */jsx(PublishedStatus, {
690
+ document: published
691
+ }), /* @__PURE__ */jsx(DraftStatus, {
692
+ document: draft
693
+ })]
694
+ });
695
+ return /* @__PURE__ */jsx(SanityDefaultPreview, {
696
+ ...getPreviewValueWithFallback({
697
+ value,
698
+ draft,
699
+ published
700
+ }),
701
+ isPlaceholder: isLoading,
702
+ icon,
703
+ layout,
704
+ status
705
+ });
706
+ }
707
+ function getIconWithFallback(icon, schemaType, defaultIcon) {
708
+ if (icon === false) {
709
+ return false;
710
+ }
711
+ return icon || schemaType && schemaType.icon || defaultIcon || false;
712
+ }
713
+ function DocumentPreviewInInput(props) {
714
+ const {
715
+ ChildLink
716
+ } = usePaneRouter();
717
+ return linkProps => /* @__PURE__ */jsx(ChildLink, {
718
+ childId: props.documentPair.id,
719
+ childParameters: {
720
+ type: props.documentPair.type
721
+ },
722
+ children: linkProps.children
723
+ });
724
+ }
725
+ function DocumentPreviewInRool(props) {
726
+ return linkProps => /* @__PURE__ */jsx(IntentLink, {
727
+ intent: "edit",
728
+ params: {
729
+ id: props.documentPair.id
730
+ },
731
+ children: linkProps.children
732
+ });
733
+ }
734
+ function DocumentPreview(props) {
735
+ const {
736
+ schemaType,
737
+ documentPair
738
+ } = props;
739
+ const doc = (documentPair == null ? void 0 : documentPair.draft) || (documentPair == null ? void 0 : documentPair.published);
740
+ const id = documentPair.id || "";
741
+ const documentPreviewStore = useDocumentPreviewStore();
742
+ const schema = useSchema();
743
+ const documentPresence = useDocumentPresence(id);
744
+ const hasSchemaType = Boolean(schemaType && schemaType.name && schema.get(schemaType.name));
745
+ const PreviewComponent = useMemo(() => {
746
+ if (!doc) return null;
747
+ if (!schemaType || !hasSchemaType) {
748
+ return /* @__PURE__ */jsx(MissingSchemaType, {
749
+ value: doc
750
+ });
751
+ }
752
+ return /* @__PURE__ */jsx(PaneItemPreview, {
753
+ documentPreviewStore,
754
+ icon: getIconWithFallback(void 0, schemaType, DocumentIcon),
755
+ schemaType,
756
+ layout: "default",
757
+ value: doc,
758
+ presence: documentPresence
759
+ });
760
+ }, [hasSchemaType, schemaType, documentPresence, doc, documentPreviewStore]);
761
+ return /* @__PURE__ */jsx(PreviewCard, {
762
+ __unstable_focusRing: true,
763
+ as: props.placement === "input" ? DocumentPreviewInInput(props) : DocumentPreviewInRool(props),
764
+ "data-as": "a",
765
+ "data-ui": "PaneItem",
766
+ padding: 2,
767
+ radius: 2,
768
+ tone: "inherit",
769
+ children: PreviewComponent
770
+ });
771
+ }
772
+ var __freeze$b = Object.freeze;
773
+ var __defProp$c = Object.defineProperty;
774
+ var __template$b = (cooked, raw) => __freeze$b(__defProp$c(cooked, "raw", {
775
+ value: __freeze$b(raw || cooked.slice())
776
+ }));
777
+ var _a$b;
778
+ const Container = styled(Box)(_a$b || (_a$b = __template$b(["\n * {\n color: ", ";\n }\n a {\n text-decoration: none;\n }\n h2 {\n font-size: ", ";\n }\n"])), props => props.theme.sanity.color.base.fg, props => props.theme.sanity.fonts.text.sizes[1]);
779
+ const FileReferences = props => {
780
+ var _a2;
781
+ const schema = useSchema();
782
+ if (!props.isLoaded) {
783
+ return /* @__PURE__ */jsx(SpinnerBox, {});
784
+ }
785
+ if (!((_a2 = props.references) == null ? void 0 : _a2.length)) {
786
+ return /* @__PURE__ */jsx(Text, {
787
+ size: 2,
788
+ weight: "bold",
789
+ muted: true,
790
+ style: {
791
+ marginTop: "1.5rem",
792
+ textAlign: "center"
793
+ },
794
+ children: "No documents are using this file"
795
+ });
796
+ }
797
+ const documentPairs = collate(props.references || []);
798
+ return /* @__PURE__ */jsx(Container, {
799
+ children: documentPairs == null ? void 0 : documentPairs.map(documentPair => {
800
+ const schemaType = schema.get(documentPair.type);
801
+ return /* @__PURE__ */jsx(Card, {
802
+ marginBottom: 2,
803
+ padding: 2,
804
+ radius: 2,
805
+ shadow: 1,
806
+ style: {
807
+ overflow: "hidden"
808
+ },
809
+ children: /* @__PURE__ */jsx(Box, {
810
+ children: /* @__PURE__ */jsx(DocumentPreview, {
811
+ documentPair,
812
+ schemaType,
813
+ placement: props.placement
814
+ })
815
+ })
816
+ }, documentPair.id);
817
+ })
818
+ });
819
+ };
820
+ function DeleteDialog(_ref7) {
821
+ let {
822
+ asset,
823
+ references,
824
+ referencesLoading,
825
+ cancelDelete,
826
+ placement,
827
+ succeededDeleting
828
+ } = _ref7;
829
+ const client = useClient();
830
+ const [state, setState] = useState("checkingReferences");
831
+ const [deleteOnMux, setDeleteOnMux] = useState(true);
832
+ const toast = useToast();
833
+ useEffect(() => {
834
+ if (state !== "checkingReferences" || referencesLoading) return;
835
+ setState((references == null ? void 0 : references.length) ? "cantDelete" : "confirm");
836
+ }, [state, references, referencesLoading]);
837
+ async function confirmDelete() {
838
+ if (state !== "confirm") return;
839
+ setState("processing_deletion");
840
+ const worked = await deleteAsset({
841
+ client,
842
+ asset,
843
+ deleteOnMux
844
+ });
845
+ if (worked === true) {
846
+ toast.push({
847
+ title: "Successfully deleted video",
848
+ status: "success"
849
+ });
850
+ succeededDeleting();
851
+ } else if (worked === "failed-mux") {
852
+ toast.push({
853
+ title: "Deleted video in Sanity",
854
+ description: "But it wasn't deleted in Mux",
855
+ status: "warning"
856
+ });
857
+ succeededDeleting();
858
+ } else {
859
+ toast.push({
860
+ title: "Failed deleting video",
861
+ status: "error"
862
+ });
863
+ setState("error_deleting");
864
+ }
865
+ }
866
+ return /* @__PURE__ */jsx(Dialog, {
867
+ header: "Delete file",
868
+ zOffset: DIALOGS_Z_INDEX,
869
+ id: "deleting-file-details-dialog",
870
+ onClose: cancelDelete,
871
+ onClickOutside: cancelDelete,
872
+ width: 1,
873
+ position: "fixed",
874
+ footer: /* @__PURE__ */jsx(Card, {
875
+ padding: 3,
876
+ children: /* @__PURE__ */jsx(Flex, {
877
+ justify: "space-between",
878
+ align: "center",
879
+ children: /* @__PURE__ */jsx(Button, {
880
+ icon: TrashIcon,
881
+ fontSize: 2,
882
+ padding: 3,
883
+ text: "Delete file",
884
+ tone: "critical",
885
+ onClick: confirmDelete,
886
+ disabled: ["processing_deletion", "checkingReferences", "cantDelete"].some(s => s === state)
887
+ })
888
+ })
889
+ }),
890
+ children: /* @__PURE__ */jsx(Card, {
891
+ padding: 5,
892
+ style: {
893
+ minHeight: "150px",
894
+ display: "flex",
895
+ alignItems: "center",
896
+ justifyContent: "center"
897
+ },
898
+ children: /* @__PURE__ */jsxs(Stack, {
899
+ space: 3,
900
+ children: [state === "checkingReferences" && /* @__PURE__ */jsxs(Fragment, {
901
+ children: [/* @__PURE__ */jsx(Heading, {
902
+ size: 2,
903
+ children: "Checking if file can be deleted"
904
+ }), /* @__PURE__ */jsx(SpinnerBox, {})]
905
+ }), state === "cantDelete" && /* @__PURE__ */jsxs(Fragment, {
906
+ children: [/* @__PURE__ */jsx(Heading, {
907
+ size: 2,
908
+ children: "Video can't be deleted"
909
+ }), /* @__PURE__ */jsxs(Text, {
910
+ size: 2,
911
+ style: {
912
+ marginBottom: "2rem"
913
+ },
914
+ children: ["There are ", references == null ? void 0 : references.length, " document", references && references.length > 0 && "s", " ", "pointing to this file. Remove their references to this file or delete them before proceeding."]
915
+ }), /* @__PURE__ */jsx(FileReferences, {
916
+ references,
917
+ isLoaded: !referencesLoading,
918
+ placement
919
+ })]
920
+ }), state === "confirm" && /* @__PURE__ */jsxs(Fragment, {
921
+ children: [/* @__PURE__ */jsx(Heading, {
922
+ size: 2,
923
+ children: "Are you sure you want to delete this file?"
924
+ }), /* @__PURE__ */jsx(Text, {
925
+ size: 2,
926
+ children: "This action is irreversible"
927
+ }), /* @__PURE__ */jsxs(Stack, {
928
+ space: 4,
929
+ marginTop: 4,
930
+ children: [/* @__PURE__ */jsxs(Flex, {
931
+ align: "center",
932
+ as: "label",
933
+ children: [/* @__PURE__ */jsx(Checkbox, {
934
+ checked: deleteOnMux,
935
+ onChange: () => setDeleteOnMux(prev => !prev)
936
+ }), /* @__PURE__ */jsx(Text, {
937
+ style: {
938
+ margin: "0 10px"
939
+ },
940
+ children: "Delete asset on Mux"
941
+ })]
942
+ }), /* @__PURE__ */jsxs(Flex, {
943
+ align: "center",
944
+ as: "label",
945
+ children: [/* @__PURE__ */jsx(Checkbox, {
946
+ disabled: true,
947
+ checked: true
948
+ }), /* @__PURE__ */jsx(Text, {
949
+ style: {
950
+ margin: "0 10px"
951
+ },
952
+ children: "Delete video from dataset"
953
+ })]
954
+ })]
955
+ })]
956
+ }), state === "processing_deletion" && /* @__PURE__ */jsxs(Fragment, {
957
+ children: [/* @__PURE__ */jsx(Heading, {
958
+ size: 2,
959
+ children: "Deleting file..."
960
+ }), /* @__PURE__ */jsx(SpinnerBox, {})]
961
+ }), state === "error_deleting" && /* @__PURE__ */jsxs(Fragment, {
962
+ children: [/* @__PURE__ */jsx(Heading, {
963
+ size: 2,
964
+ children: "Something went wrong!"
965
+ }), /* @__PURE__ */jsx(Text, {
966
+ size: 2,
967
+ children: "Try deleting the file again by clicking the button below"
968
+ })]
969
+ })]
970
+ })
971
+ })
972
+ });
973
+ }
974
+ const useDocReferences = createHookFromObservableFactory(_ref8 => {
975
+ let {
976
+ documentStore,
977
+ id
978
+ } = _ref8;
979
+ return documentStore.listenQuery( /* groq */
980
+ "*[references($id)]{_id, _type, _rev, _updatedAt, _createdAt}", {
981
+ id
982
+ }, {
983
+ apiVersion: SANITY_API_VERSION
984
+ });
985
+ });
986
+ function formatSeconds(seconds) {
987
+ if (typeof seconds !== "number" || Number.isNaN(seconds)) {
988
+ return "";
989
+ }
990
+ const hrs = ~~(seconds / 3600);
991
+ const mins = ~~(seconds % 3600 / 60);
992
+ const secs = ~~seconds % 60;
993
+ let ret = "";
994
+ if (hrs > 0) {
995
+ ret += "" + hrs + ":" + (mins < 10 ? "0" : "");
996
+ }
997
+ ret += "" + mins + ":" + (secs < 10 ? "0" : "");
998
+ ret += "" + secs;
999
+ return ret;
1000
+ }
1001
+ function getVideoMetadata(doc) {
1002
+ var _a, _b, _c, _d, _e, _f;
1003
+ const id = doc.assetId || doc._id || "";
1004
+ const date = ((_a = doc.data) == null ? void 0 : _a.created_at) ? new Date(Number(doc.data.created_at) * 1e3) : new Date(doc._createdAt || doc._updatedAt || Date.now());
1005
+ return {
1006
+ title: doc.filename || id.slice(0, 10),
1007
+ createdAt: date,
1008
+ duration: ((_b = doc.data) == null ? void 0 : _b.duration) ? formatSeconds((_c = doc.data) == null ? void 0 : _c.duration) : void 0,
1009
+ aspect_ratio: (_d = doc.data) == null ? void 0 : _d.aspect_ratio,
1010
+ max_stored_resolution: (_e = doc.data) == null ? void 0 : _e.max_stored_resolution,
1011
+ max_stored_frame_rate: (_f = doc.data) == null ? void 0 : _f.max_stored_frame_rate
1012
+ };
1013
+ }
1014
+ function useFileDetails(props) {
1015
+ const documentStore = useDocumentStore();
1016
+ const toast = useToast();
1017
+ const client = useClient();
1018
+ const [references, referencesLoading] = useDocReferences({
1019
+ documentStore,
1020
+ id: props.asset._id
1021
+ });
1022
+ const [originalAsset, setOriginalAsset] = useState(() => props.asset);
1023
+ const [filename, setFilename] = useState(props.asset.filename);
1024
+ const modified = filename !== originalAsset.filename;
1025
+ const displayInfo = getVideoMetadata({
1026
+ ...props.asset,
1027
+ filename
1028
+ });
1029
+ const [state, setState] = useState("idle");
1030
+ function handleClose() {
1031
+ if (state !== "idle") return;
1032
+ if (modified) {
1033
+ setState("closing");
1034
+ return;
1035
+ }
1036
+ props.closeDialog();
1037
+ }
1038
+ function confirmClose(shouldClose) {
1039
+ if (state !== "closing") return;
1040
+ if (shouldClose) props.closeDialog();
1041
+ setState("idle");
1042
+ }
1043
+ async function saveChanges() {
1044
+ if (state !== "idle") return;
1045
+ setState("saving");
1046
+ try {
1047
+ await client.patch(props.asset._id).set({
1048
+ filename
1049
+ }).commit();
1050
+ setOriginalAsset(prev => ({
1051
+ ...prev,
1052
+ filename
1053
+ }));
1054
+ toast.push({
1055
+ title: "File name updated",
1056
+ status: "success"
1057
+ });
1058
+ } catch (error) {
1059
+ toast.push({
1060
+ title: "Failed updating file name",
1061
+ status: "error",
1062
+ description: typeof error === "string" ? error : "Please try again"
1063
+ });
1064
+ setFilename(originalAsset.filename);
1065
+ }
1066
+ setState("idle");
1067
+ }
1068
+ return {
1069
+ references,
1070
+ referencesLoading,
1071
+ modified,
1072
+ filename,
1073
+ setFilename,
1074
+ displayInfo,
1075
+ state,
1076
+ setState,
1077
+ handleClose,
1078
+ confirmClose,
1079
+ saveChanges
1080
+ };
1081
+ }
1082
+ const AssetInput = props => /* @__PURE__ */jsx(FormField$1, {
1083
+ title: props.label,
1084
+ description: props.description,
1085
+ inputId: props.label,
1086
+ children: /* @__PURE__ */jsx(TextInput, {
1087
+ id: props.label,
1088
+ value: props.value,
1089
+ placeholder: props.placeholder,
1090
+ onInput: props.onInput,
1091
+ disabled: props.disabled
1092
+ })
1093
+ });
1094
+ const VideoDetails = props => {
1095
+ const [tab, setTab] = useState("details");
1096
+ const {
1097
+ displayInfo,
1098
+ filename,
1099
+ modified,
1100
+ references,
1101
+ referencesLoading,
1102
+ setFilename,
1103
+ state,
1104
+ setState,
1105
+ handleClose,
1106
+ confirmClose,
1107
+ saveChanges
1108
+ } = useFileDetails(props);
1109
+ const isSaving = state === "saving";
1110
+ const [containerHeight, setContainerHeight] = useState(null);
1111
+ const contentsRef = React.useRef(null);
1112
+ useEffect(() => {
1113
+ if (!contentsRef.current || !("getBoundingClientRect" in contentsRef.current)) return;
1114
+ setContainerHeight(contentsRef.current.getBoundingClientRect().height);
1115
+ }, []);
1116
+ return /* @__PURE__ */jsxs(Dialog, {
1117
+ header: displayInfo.title,
1118
+ zOffset: DIALOGS_Z_INDEX,
1119
+ id: "file-details-dialog",
1120
+ onClose: handleClose,
1121
+ onClickOutside: handleClose,
1122
+ width: 2,
1123
+ style: {
1124
+ minHeight: "50vh"
1125
+ },
1126
+ position: "fixed",
1127
+ footer: /* @__PURE__ */jsx(Card, {
1128
+ padding: 3,
1129
+ children: /* @__PURE__ */jsxs(Flex, {
1130
+ justify: "space-between",
1131
+ align: "center",
1132
+ children: [/* @__PURE__ */jsx(Button, {
1133
+ icon: TrashIcon,
1134
+ fontSize: 2,
1135
+ padding: 3,
1136
+ mode: "bleed",
1137
+ text: "Delete",
1138
+ tone: "critical",
1139
+ onClick: () => setState("deleting"),
1140
+ disabled: isSaving
1141
+ }), modified && /* @__PURE__ */jsx(Button, {
1142
+ icon: CheckmarkIcon,
1143
+ fontSize: 2,
1144
+ padding: 3,
1145
+ mode: "ghost",
1146
+ text: "Save and close",
1147
+ tone: "positive",
1148
+ onClick: saveChanges,
1149
+ iconRight: isSaving && Spinner,
1150
+ disabled: isSaving
1151
+ })]
1152
+ })
1153
+ }),
1154
+ children: [state === "deleting" && /* @__PURE__ */jsx(DeleteDialog, {
1155
+ asset: props.asset,
1156
+ cancelDelete: () => setState("idle"),
1157
+ placement: props.placement,
1158
+ referencesLoading,
1159
+ references,
1160
+ succeededDeleting: () => {
1161
+ props.closeDialog();
1162
+ }
1163
+ }), state === "closing" && /* @__PURE__ */jsx(Dialog, {
1164
+ header: "You have unsaved changes",
1165
+ zOffset: DIALOGS_Z_INDEX,
1166
+ id: "closing-file-details-dialog",
1167
+ onClose: () => confirmClose(false),
1168
+ onClickOutside: () => confirmClose(false),
1169
+ width: 1,
1170
+ position: "fixed",
1171
+ footer: /* @__PURE__ */jsx(Card, {
1172
+ padding: 3,
1173
+ children: /* @__PURE__ */jsxs(Flex, {
1174
+ justify: "space-between",
1175
+ align: "center",
1176
+ children: [/* @__PURE__ */jsx(Button, {
1177
+ icon: ErrorOutlineIcon,
1178
+ fontSize: 2,
1179
+ padding: 3,
1180
+ text: "Discard changes",
1181
+ tone: "critical",
1182
+ onClick: () => confirmClose(true)
1183
+ }), modified && /* @__PURE__ */jsx(Button, {
1184
+ icon: RevertIcon,
1185
+ fontSize: 2,
1186
+ padding: 3,
1187
+ mode: "ghost",
1188
+ text: "Keep editing",
1189
+ tone: "primary",
1190
+ onClick: () => confirmClose(false)
1191
+ })]
1192
+ })
1193
+ }),
1194
+ children: /* @__PURE__ */jsx(Card, {
1195
+ padding: 5,
1196
+ children: /* @__PURE__ */jsxs(Stack, {
1197
+ style: {
1198
+ textAlign: "center"
1199
+ },
1200
+ space: 3,
1201
+ children: [/* @__PURE__ */jsx(Heading, {
1202
+ size: 2,
1203
+ children: "Unsaved changes will be lost"
1204
+ }), /* @__PURE__ */jsx(Text, {
1205
+ size: 2,
1206
+ children: "Are you sure you want to discard them?"
1207
+ })]
1208
+ })
1209
+ })
1210
+ }), /* @__PURE__ */jsx(Card, {
1211
+ padding: 4,
1212
+ sizing: "border",
1213
+ style: {
1214
+ containerType: "inline-size"
1215
+ },
1216
+ children: /* @__PURE__ */jsxs(Flex, {
1217
+ sizing: "border",
1218
+ gap: 4,
1219
+ direction: ["column", "column", "row"],
1220
+ align: "flex-start",
1221
+ ref: contentsRef,
1222
+ style: typeof containerHeight === "number" ? {
1223
+ minHeight: containerHeight
1224
+ } : void 0,
1225
+ children: [/* @__PURE__ */jsx(Stack, {
1226
+ space: 4,
1227
+ flex: 1,
1228
+ sizing: "border",
1229
+ children: /* @__PURE__ */jsx(VideoPlayer, {
1230
+ asset: props.asset,
1231
+ autoPlay: props.asset.autoPlay || false
1232
+ })
1233
+ }), /* @__PURE__ */jsxs(Stack, {
1234
+ space: 4,
1235
+ flex: 1,
1236
+ sizing: "border",
1237
+ children: [/* @__PURE__ */jsxs(TabList, {
1238
+ space: 2,
1239
+ children: [/* @__PURE__ */jsx(Tab, {
1240
+ "aria-controls": "details-panel",
1241
+ icon: EditIcon,
1242
+ id: "details-tab",
1243
+ label: "Details",
1244
+ onClick: () => setTab("details"),
1245
+ selected: tab === "details"
1246
+ }), references && references.length > 0 && /* @__PURE__ */jsx(Tab, {
1247
+ "aria-controls": "references-panel",
1248
+ icon: SearchIcon,
1249
+ id: "references-tab",
1250
+ label: "Used by (".concat(references.length, ")"),
1251
+ onClick: () => setTab("references"),
1252
+ selected: tab === "references"
1253
+ })]
1254
+ }), /* @__PURE__ */jsx(TabPanel, {
1255
+ "aria-labelledby": "details-tab",
1256
+ id: "details-panel",
1257
+ hidden: tab !== "details",
1258
+ children: /* @__PURE__ */jsxs(Stack, {
1259
+ space: 4,
1260
+ children: [/* @__PURE__ */jsx(AssetInput, {
1261
+ label: "File name",
1262
+ description: "Not visible to users. Useful for finding files later.",
1263
+ value: filename || "",
1264
+ onInput: e => setFilename(e.currentTarget.value),
1265
+ disabled: state !== "idle"
1266
+ }), /* @__PURE__ */jsxs(Stack, {
1267
+ space: 3,
1268
+ children: [(displayInfo == null ? void 0 : displayInfo.duration) && /* @__PURE__ */jsx(IconInfo, {
1269
+ text: "Duration: ".concat(displayInfo.duration),
1270
+ icon: ClockIcon,
1271
+ size: 2
1272
+ }), (displayInfo == null ? void 0 : displayInfo.max_stored_resolution) && /* @__PURE__ */jsx(IconInfo, {
1273
+ text: "Max Resolution: ".concat(displayInfo.max_stored_resolution),
1274
+ icon: ResolutionIcon,
1275
+ size: 2
1276
+ }), (displayInfo == null ? void 0 : displayInfo.max_stored_frame_rate) && /* @__PURE__ */jsx(IconInfo, {
1277
+ text: "Frame rate: ".concat(displayInfo.max_stored_frame_rate),
1278
+ icon: StopWatchIcon,
1279
+ size: 2
1280
+ }), (displayInfo == null ? void 0 : displayInfo.aspect_ratio) && /* @__PURE__ */jsx(IconInfo, {
1281
+ text: "Aspect Ratio: ".concat(displayInfo.aspect_ratio),
1282
+ icon: CropIcon,
1283
+ size: 2
1284
+ }), /* @__PURE__ */jsx(IconInfo, {
1285
+ text: "Uploaded on: ".concat(displayInfo.createdAt.toLocaleDateString("en", {
1286
+ year: "numeric",
1287
+ month: "2-digit",
1288
+ day: "2-digit",
1289
+ hour: "2-digit",
1290
+ minute: "2-digit",
1291
+ hour12: true
1292
+ })),
1293
+ icon: CalendarIcon,
1294
+ size: 2
1295
+ })]
1296
+ })]
1297
+ })
1298
+ }), /* @__PURE__ */jsx(TabPanel, {
1299
+ "aria-labelledby": "references-tab",
1300
+ id: "references-panel",
1301
+ hidden: tab !== "references",
1302
+ children: /* @__PURE__ */jsx(FileReferences, {
1303
+ references,
1304
+ isLoaded: !referencesLoading,
1305
+ placement: props.placement
1306
+ })
1307
+ })]
1308
+ })]
1309
+ })
1310
+ })]
1311
+ });
1312
+ };
1313
+ const VideoMetadata = props => {
1314
+ if (!props.asset) {
1315
+ return null;
1316
+ }
1317
+ const displayInfo = getVideoMetadata(props.asset);
1318
+ return /* @__PURE__ */jsxs(Stack, {
1319
+ space: 2,
1320
+ children: [displayInfo.title && /* @__PURE__ */jsx(Text, {
1321
+ size: 1,
1322
+ weight: "semibold",
1323
+ style: {
1324
+ wordWrap: "break-word"
1325
+ },
1326
+ children: displayInfo.title
1327
+ }), /* @__PURE__ */jsxs(Inline, {
1328
+ space: 3,
1329
+ children: [(displayInfo == null ? void 0 : displayInfo.duration) && /* @__PURE__ */jsx(IconInfo, {
1330
+ text: displayInfo.duration,
1331
+ icon: ClockIcon,
1332
+ size: 1,
1333
+ muted: true
1334
+ }), /* @__PURE__ */jsx(IconInfo, {
1335
+ text: displayInfo.createdAt.toISOString().split("T")[0],
1336
+ icon: CalendarIcon,
1337
+ size: 1,
1338
+ muted: true
1339
+ })]
1340
+ })]
1341
+ });
1342
+ };
1343
+ function useInView() {
1344
+ let options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
1345
+ const [inView, setInView] = useState(false);
1346
+ const ref = useRef(null);
1347
+ useEffect(() => {
1348
+ if (!ref.current) return;
1349
+ const observer = new IntersectionObserver((_ref9, obs) => {
1350
+ let [entry] = _ref9;
1351
+ var _a;
1352
+ const nowInView = entry.isIntersecting && obs.thresholds.some(threshold => entry.intersectionRatio >= threshold);
1353
+ setInView(nowInView);
1354
+ (_a = options == null ? void 0 : options.onChange) == null ? void 0 : _a.call(options, nowInView);
1355
+ }, options);
1356
+ const toObserve = ref.current;
1357
+ observer.observe(toObserve);
1358
+ return () => {
1359
+ if (toObserve) observer.unobserve(toObserve);
1360
+ };
1361
+ }, [options]);
1362
+ return {
1363
+ inView,
1364
+ ref
1365
+ };
1366
+ }
1367
+ function getAnimatedPosterSrc(_ref10) {
1368
+ let {
1369
+ asset,
1370
+ client,
1371
+ height,
1372
+ width,
1373
+ start = asset.thumbTime ? Math.max(0, asset.thumbTime - 2.5) : 0,
1374
+ end = start + 5,
1375
+ fps = 15
1376
+ } = _ref10;
1377
+ const params = {
1378
+ height,
1379
+ width,
1380
+ start,
1381
+ end,
1382
+ fps
1383
+ };
1384
+ const playbackId = getPlaybackId(asset);
1385
+ let searchParams = new URLSearchParams(JSON.parse(JSON.stringify(params, (_, v) => v != null ? v : void 0)));
1386
+ if (getPlaybackPolicy(asset) === "signed") {
1387
+ const token = generateJwt(client, playbackId, "g", params);
1388
+ searchParams = new URLSearchParams({
1389
+ token
1390
+ });
1391
+ }
1392
+ return "https://image.mux.com/".concat(playbackId, "/animated.gif?").concat(searchParams);
1393
+ }
1394
+ var __freeze$a = Object.freeze;
1395
+ var __defProp$b = Object.defineProperty;
1396
+ var __template$a = (cooked, raw) => __freeze$a(__defProp$b(cooked, "raw", {
1397
+ value: __freeze$a(raw || cooked.slice())
1398
+ }));
1399
+ var _a$a;
1400
+ const Image = styled.img(_a$a || (_a$a = __template$a(["\n transition: opacity 0.175s ease-out 0s;\n display: block;\n width: 100%;\n height: 100%;\n object-fit: contain;\n object-position: center center;\n"])));
1401
+ const STATUS_TO_TONE = {
1402
+ loading: "transparent",
1403
+ error: "critical",
1404
+ loaded: "default"
1405
+ };
1406
+ function VideoThumbnail(_ref11) {
1407
+ let {
1408
+ asset,
1409
+ width = 250
1410
+ } = _ref11;
1411
+ const {
1412
+ inView,
1413
+ ref
1414
+ } = useInView();
1415
+ const [status, setStatus] = useState("loading");
1416
+ const client = useClient();
1417
+ const animatedSrc = useMemo(() => {
1418
+ try {
1419
+ return getAnimatedPosterSrc({
1420
+ asset,
1421
+ client,
1422
+ width
1423
+ });
1424
+ } catch {
1425
+ if (status !== "error") setStatus("error");
1426
+ return void 0;
1427
+ }
1428
+ }, [asset, client, width, status, setStatus]);
1429
+ function handleLoad() {
1430
+ setStatus("loaded");
1431
+ }
1432
+ function handleError() {
1433
+ setStatus("error");
1434
+ }
1435
+ return /* @__PURE__ */jsx(Card, {
1436
+ style: {
1437
+ aspectRatio: THUMBNAIL_ASPECT_RATIO,
1438
+ position: "relative"
1439
+ },
1440
+ border: true,
1441
+ radius: 2,
1442
+ ref,
1443
+ tone: STATUS_TO_TONE[status],
1444
+ children: inView ? /* @__PURE__ */jsxs(Fragment, {
1445
+ children: [status === "loading" && /* @__PURE__ */jsx(SpinnerBox, {}), status === "error" && /* @__PURE__ */jsxs(Stack, {
1446
+ space: 4,
1447
+ style: {
1448
+ position: "absolute",
1449
+ width: "100%",
1450
+ left: 0,
1451
+ top: "50%",
1452
+ transform: "translateY(-50%)",
1453
+ justifyItems: "center"
1454
+ },
1455
+ children: [/* @__PURE__ */jsx(Text, {
1456
+ size: 4,
1457
+ muted: true,
1458
+ children: /* @__PURE__ */jsx(ErrorOutlineIcon, {
1459
+ style: {
1460
+ fontSize: "1.75em"
1461
+ }
1462
+ })
1463
+ }), /* @__PURE__ */jsx(Text, {
1464
+ muted: true,
1465
+ align: "center",
1466
+ children: "Failed loading thumbnail"
1467
+ })]
1468
+ }), /* @__PURE__ */jsx(Image, {
1469
+ src: animatedSrc,
1470
+ alt: "Preview for video ".concat(asset.filename || asset.assetId),
1471
+ onLoad: handleLoad,
1472
+ onError: handleError,
1473
+ style: {
1474
+ opacity: status === "loaded" ? 1 : 0
1475
+ }
1476
+ })]
1477
+ }) : null
1478
+ });
1479
+ }
1480
+ var __freeze$9 = Object.freeze;
1481
+ var __defProp$a = Object.defineProperty;
1482
+ var __template$9 = (cooked, raw) => __freeze$9(__defProp$a(cooked, "raw", {
1483
+ value: __freeze$9(raw || cooked.slice())
1484
+ }));
1485
+ var _a$9;
1486
+ const PlayButton = styled.button(_a$9 || (_a$9 = __template$9(["\n display: block;\n padding: 0;\n margin: 0;\n border: none;\n border-radius: 0.1875rem;\n position: relative;\n cursor: pointer;\n\n &::after {\n content: '';\n background: var(--card-fg-color);\n opacity: 0;\n display: block;\n position: absolute;\n inset: 0;\n z-index: 10;\n transition: 0.15s ease-out;\n border-radius: inherit;\n }\n\n > div[data-play] {\n z-index: 11;\n opacity: 0;\n transition: 0.15s 0.05s ease-out;\n position: absolute;\n left: 50%;\n top: 50%;\n transform: translate(-50%, -50%);\n color: var(--card-fg-color);\n background: var(--card-bg-color);\n width: auto;\n height: 30%;\n aspect-ratio: 1;\n border-radius: 100%;\n display: flex;\n justify-content: center;\n align-items: center;\n box-sizing: border-box;\n > svg {\n display: block;\n width: 70%;\n height: auto;\n // Visual balance to center-align the icon\n transform: translateX(5%);\n }\n }\n\n &:hover,\n &:focus {\n &::after {\n opacity: 0.3;\n }\n > div[data-play] {\n opacity: 1;\n }\n }\n"])));
1487
+ function VideoInBrowser(_ref12) {
1488
+ let {
1489
+ onSelect,
1490
+ onEdit,
1491
+ asset
1492
+ } = _ref12;
1493
+ const [renderVideo, setRenderVideo] = useState(false);
1494
+ const select = React.useCallback(() => onSelect == null ? void 0 : onSelect(asset), [onSelect, asset]);
1495
+ const edit = React.useCallback(() => onEdit == null ? void 0 : onEdit(asset), [onEdit, asset]);
1496
+ if (!asset) {
1497
+ return null;
1498
+ }
1499
+ const playbackPolicy = getPlaybackPolicy(asset);
1500
+ return /* @__PURE__ */jsxs(Card, {
1501
+ border: true,
1502
+ padding: 2,
1503
+ sizing: "border",
1504
+ radius: 2,
1505
+ style: {
1506
+ position: "relative"
1507
+ },
1508
+ children: [playbackPolicy === "signed" && /* @__PURE__ */jsx(Tooltip, {
1509
+ content: /* @__PURE__ */jsx(Card, {
1510
+ padding: 2,
1511
+ radius: 2,
1512
+ children: /* @__PURE__ */jsx(IconInfo, {
1513
+ icon: LockIcon,
1514
+ text: "Signed playback policy",
1515
+ size: 2
1516
+ })
1517
+ }),
1518
+ placement: "right",
1519
+ fallbackPlacements: ["top", "bottom"],
1520
+ portal: true,
1521
+ children: /* @__PURE__ */jsx(Card, {
1522
+ tone: "caution",
1523
+ style: {
1524
+ borderRadius: "100%",
1525
+ position: "absolute",
1526
+ left: "1em",
1527
+ top: "1em",
1528
+ zIndex: 10
1529
+ },
1530
+ padding: 2,
1531
+ border: true,
1532
+ children: /* @__PURE__ */jsx(Text, {
1533
+ muted: true,
1534
+ size: 1,
1535
+ children: /* @__PURE__ */jsx(LockIcon, {})
1536
+ })
1537
+ })
1538
+ }), /* @__PURE__ */jsxs(Stack, {
1539
+ space: 3,
1540
+ height: "fill",
1541
+ style: {
1542
+ gridTemplateRows: "min-content min-content 1fr"
1543
+ },
1544
+ children: [renderVideo ? /* @__PURE__ */jsx(VideoPlayer, {
1545
+ asset,
1546
+ autoPlay: true,
1547
+ forceAspectRatio: THUMBNAIL_ASPECT_RATIO
1548
+ }) : /* @__PURE__ */jsxs(PlayButton, {
1549
+ onClick: () => setRenderVideo(true),
1550
+ children: [/* @__PURE__ */jsx("div", {
1551
+ "data-play": true,
1552
+ children: /* @__PURE__ */jsx(PlayIcon, {})
1553
+ }), /* @__PURE__ */jsx(VideoThumbnail, {
1554
+ asset
1555
+ })]
1556
+ }), /* @__PURE__ */jsx(VideoMetadata, {
1557
+ asset
1558
+ }), /* @__PURE__ */jsxs("div", {
1559
+ style: {
1560
+ display: "flex",
1561
+ width: "100%",
1562
+ alignItems: "flex-end",
1563
+ justifyContent: "flex-start",
1564
+ gap: ".35rem"
1565
+ },
1566
+ children: [onSelect && /* @__PURE__ */jsx(Button, {
1567
+ icon: CheckmarkIcon,
1568
+ fontSize: 2,
1569
+ padding: 2,
1570
+ mode: "ghost",
1571
+ text: "Select",
1572
+ style: {
1573
+ flex: 1
1574
+ },
1575
+ tone: "positive",
1576
+ onClick: select
1577
+ }), /* @__PURE__ */jsx(Button, {
1578
+ icon: EditIcon,
1579
+ fontSize: 2,
1580
+ padding: 2,
1581
+ mode: "ghost",
1582
+ text: "Details",
1583
+ style: {
1584
+ flex: 1
1585
+ },
1586
+ onClick: edit
1587
+ })]
1588
+ })]
1589
+ })]
1590
+ });
1591
+ }
1592
+ function VideosBrowser(_ref13) {
1593
+ let {
1594
+ onSelect
1595
+ } = _ref13;
1596
+ const {
1597
+ assets,
1598
+ isLoading,
1599
+ searchQuery,
1600
+ setSearchQuery,
1601
+ setSort,
1602
+ sort
1603
+ } = useAssets();
1604
+ const [editedAsset, setEditedAsset] = React.useState(null);
1605
+ const freshEditedAsset = React.useMemo(() => assets.find(a => a._id === (editedAsset == null ? void 0 : editedAsset._id)) || editedAsset, [editedAsset, assets]);
1606
+ return /* @__PURE__ */jsxs(Fragment, {
1607
+ children: [/* @__PURE__ */jsxs(Stack, {
1608
+ padding: 4,
1609
+ space: 4,
1610
+ children: [/* @__PURE__ */jsx(Flex, {
1611
+ justify: "space-between",
1612
+ align: "center",
1613
+ children: /* @__PURE__ */jsxs(Flex, {
1614
+ align: "center",
1615
+ gap: 3,
1616
+ children: [/* @__PURE__ */jsx(TextInput, {
1617
+ value: searchQuery,
1618
+ icon: SearchIcon,
1619
+ onInput: e => setSearchQuery(e.currentTarget.value),
1620
+ placeholder: "Search files"
1621
+ }), /* @__PURE__ */jsx(SelectSortOptions, {
1622
+ setSort,
1623
+ sort
1624
+ })]
1625
+ })
1626
+ }), /* @__PURE__ */jsxs(Stack, {
1627
+ space: 3,
1628
+ children: [(assets == null ? void 0 : assets.length) > 0 && /* @__PURE__ */jsxs(Label$1, {
1629
+ muted: true,
1630
+ children: [assets.length, " video", assets.length > 1 ? "s" : null, " ", searchQuery ? 'matching "'.concat(searchQuery, '"') : "found"]
1631
+ }), /* @__PURE__ */jsx(Grid, {
1632
+ gap: 2,
1633
+ style: {
1634
+ gridTemplateColumns: "repeat(auto-fill, minmax(250px, 1fr))"
1635
+ },
1636
+ children: assets.map(asset => /* @__PURE__ */jsx(VideoInBrowser, {
1637
+ asset,
1638
+ onEdit: setEditedAsset,
1639
+ onSelect
1640
+ }, asset._id))
1641
+ })]
1642
+ }), isLoading && /* @__PURE__ */jsx(SpinnerBox, {}), !isLoading && assets.length === 0 && /* @__PURE__ */jsx(Card, {
1643
+ padding: 2,
1644
+ marginY: 4,
1645
+ border: true,
1646
+ radius: 2,
1647
+ children: /* @__PURE__ */jsx(Text, {
1648
+ align: "center",
1649
+ muted: true,
1650
+ children: searchQuery ? 'No videos found for "'.concat(searchQuery, '"') : "No videos in this dataset"
1651
+ })
1652
+ })]
1653
+ }), freshEditedAsset && /* @__PURE__ */jsx(VideoDetails, {
1654
+ closeDialog: () => setEditedAsset(null),
1655
+ asset: freshEditedAsset,
1656
+ placement: onSelect ? "input" : "tool"
1657
+ })]
1658
+ });
1659
+ }
1660
+ const StudioTool = () => {
1661
+ return /* @__PURE__ */jsx(VideosBrowser, {});
1662
+ };
1663
+ function createStudioTool(config) {
1664
+ const toolConfig = typeof config.tool === "object" ? config.tool : {};
1665
+ return {
1666
+ name: "mux",
1667
+ title: toolConfig.title || "Videos",
1668
+ component: props => /* @__PURE__ */jsx(StudioTool, {
1669
+ ...config,
1670
+ ...props
1671
+ }),
1672
+ icon: toolConfig.icon || ToolIcon
1673
+ };
1674
+ }
1675
+ const path$1 = ["assetId", "data", "playbackId", "status", "thumbTime", "filename"];
1676
+ const useAssetDocumentValues = asset => useDocumentValues(isReference(asset) ? asset._ref : "", path$1);
1677
+ function useDialogState() {
1678
+ return useState(false);
1679
+ }
1680
+ const useMuxPolling = asset => {
1681
+ var _a, _b;
1682
+ const client = useClient();
1683
+ const projectId = useProjectId();
1684
+ const dataset = useDataset();
1685
+ const shouldFetch = useMemo(() => {
1686
+ var _a2, _b2;
1687
+ 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");
1688
+ }, [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]);
1689
+ return useSWR(shouldFetch ? "/".concat(projectId, "/addons/mux/assets/").concat(dataset, "/data/").concat(asset == null ? void 0 : asset.assetId) : null, async () => {
1690
+ const {
1691
+ data
1692
+ } = await client.request({
1693
+ url: "/addons/mux/assets/".concat(dataset, "/data/").concat(asset.assetId),
1694
+ withCredentials: true,
1695
+ method: "GET"
1696
+ });
1697
+ client.patch(asset._id).set({
1698
+ status: data.status,
1699
+ data
1700
+ }).commit({
1701
+ returnDocuments: false
1702
+ });
1703
+ }, {
1704
+ refreshInterval: 2e3,
1705
+ refreshWhenHidden: true,
1706
+ dedupingInterval: 1e3
1707
+ });
1708
+ };
1709
+ const path = ["token", "secretKey", "enableSignedUrls", "signingKeyId", "signingKeyPrivate"];
1710
+ const useSecretsDocumentValues = () => {
1711
+ const {
1712
+ error,
1713
+ isLoading,
1714
+ value
1715
+ } = useDocumentValues(muxSecretsDocumentId, path);
1716
+ const cache = useMemo(() => {
1717
+ const exists = Boolean(value);
1718
+ const secrets = {
1719
+ token: (value == null ? void 0 : value.token) || null,
1720
+ secretKey: (value == null ? void 0 : value.secretKey) || null,
1721
+ enableSignedUrls: (value == null ? void 0 : value.enableSignedUrls) || false,
1722
+ signingKeyId: (value == null ? void 0 : value.signingKeyId) || null,
1723
+ signingKeyPrivate: (value == null ? void 0 : value.signingKeyPrivate) || null
1724
+ };
1725
+ return {
1726
+ isInitialSetup: !exists,
1727
+ needsSetup: !(secrets == null ? void 0 : secrets.token) || !(secrets == null ? void 0 : secrets.secretKey),
1728
+ secrets
1729
+ };
1730
+ }, [value]);
1731
+ return {
1732
+ error,
1733
+ isLoading,
1734
+ value: cache
1735
+ };
1736
+ };
1737
+ function createUpChunkObservable(uuid, uploadUrl, source) {
1738
+ return new Observable(subscriber => {
1739
+ const upchunk = UpChunk.createUpload({
1740
+ endpoint: uploadUrl,
1741
+ file: source,
1742
+ dynamicChunkSize: true
1743
+ // changes the chunk size based on network speeds
1744
+ });
1745
+
1746
+ const successHandler = () => {
1747
+ subscriber.next({
1748
+ type: "success",
1749
+ id: uuid
1750
+ });
1751
+ subscriber.complete();
1752
+ };
1753
+ const errorHandler = data => subscriber.error(new Error(data.detail.message));
1754
+ const progressHandler = data => {
1755
+ return subscriber.next({
1756
+ type: "progress",
1757
+ percent: data.detail
1758
+ });
1759
+ };
1760
+ const offlineHandler = () => {
1761
+ upchunk.pause();
1762
+ subscriber.next({
1763
+ type: "pause",
1764
+ id: uuid
1765
+ });
1766
+ };
1767
+ const onlineHandler = () => {
1768
+ upchunk.resume();
1769
+ subscriber.next({
1770
+ type: "resume",
1771
+ id: uuid
1772
+ });
1773
+ };
1774
+ upchunk.on("success", successHandler);
1775
+ upchunk.on("error", errorHandler);
1776
+ upchunk.on("progress", progressHandler);
1777
+ upchunk.on("offline", offlineHandler);
1778
+ upchunk.on("online", onlineHandler);
1779
+ return () => upchunk.abort();
1780
+ });
1781
+ }
1782
+ function saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate) {
1783
+ const doc = {
1784
+ _id: "secrets.mux",
1785
+ _type: "mux.apiKey",
1786
+ token,
1787
+ secretKey,
1788
+ enableSignedUrls,
1789
+ signingKeyId,
1790
+ signingKeyPrivate
1791
+ };
1792
+ return client.createOrReplace(doc);
1793
+ }
1794
+ function createSigningKeys(client) {
1795
+ const {
1796
+ dataset
1797
+ } = client.config();
1798
+ return client.request({
1799
+ url: "/addons/mux/signing-keys/".concat(dataset),
1800
+ withCredentials: true,
1801
+ method: "POST"
1802
+ });
1803
+ }
1804
+ function testSecrets(client) {
1805
+ const {
1806
+ dataset
1807
+ } = client.config();
1808
+ return client.request({
1809
+ url: "/addons/mux/secrets/".concat(dataset, "/test"),
1810
+ withCredentials: true,
1811
+ method: "GET"
1812
+ });
1813
+ }
1814
+ async function haveValidSigningKeys(client, signingKeyId, signingKeyPrivate) {
1815
+ if (!(signingKeyId && signingKeyPrivate)) {
1816
+ return false;
1817
+ }
1818
+ const {
1819
+ dataset
1820
+ } = client.config();
1821
+ try {
1822
+ const res = await client.request({
1823
+ url: "/addons/mux/signing-keys/".concat(dataset, "/").concat(signingKeyId),
1824
+ withCredentials: true,
1825
+ method: "GET"
1826
+ });
1827
+ return !!(res.data && res.data.id);
1828
+ } catch (e) {
1829
+ console.error("Error fetching signingKeyId", signingKeyId, "assuming it is not valid");
1830
+ return false;
1831
+ }
1832
+ }
1833
+ function testSecretsObservable(client) {
1834
+ const {
1835
+ dataset
1836
+ } = client.config();
1837
+ return defer(() => client.observable.request({
1838
+ url: "/addons/mux/secrets/".concat(dataset, "/test"),
1839
+ withCredentials: true,
1840
+ method: "GET"
1841
+ }));
1842
+ }
1843
+ function cancelUpload(client, uuid) {
1844
+ return client.observable.request({
1845
+ url: "/addons/mux/uploads/".concat(client.config().dataset, "/").concat(uuid),
1846
+ withCredentials: true,
1847
+ method: "DELETE"
1848
+ });
1849
+ }
1850
+ function uploadUrl(config, client, url) {
1851
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1852
+ return testUrl(url).pipe(switchMap(validUrl => {
1853
+ return concat(of({
1854
+ type: "url",
1855
+ url: validUrl
1856
+ }), testSecretsObservable(client).pipe(switchMap(json => {
1857
+ if (!json || !json.status) {
1858
+ return throwError(new Error("Invalid credentials"));
1859
+ }
1860
+ const uuid$1 = uuid();
1861
+ const {
1862
+ enableSignedUrls
1863
+ } = options;
1864
+ const muxBody = {
1865
+ input: validUrl,
1866
+ playback_policy: [enableSignedUrls ? "signed" : "public"],
1867
+ mp4_support: config.mp4_support
1868
+ };
1869
+ const query = {
1870
+ muxBody: JSON.stringify(muxBody),
1871
+ filename: validUrl.split("/").slice(-1)[0]
1872
+ };
1873
+ const dataset = client.config().dataset;
1874
+ return defer(() => client.observable.request({
1875
+ url: "/addons/mux/assets/".concat(dataset),
1876
+ withCredentials: true,
1877
+ method: "POST",
1878
+ headers: {
1879
+ "MUX-Proxy-UUID": uuid$1,
1880
+ "Content-Type": "application/json"
1881
+ },
1882
+ query
1883
+ })).pipe(mergeMap(result => {
1884
+ const asset = result && result.results && result.results[0] && result.results[0].document || null;
1885
+ if (!asset) {
1886
+ return throwError(new Error("No asset document returned"));
1887
+ }
1888
+ return of({
1889
+ type: "success",
1890
+ id: uuid$1,
1891
+ asset
1892
+ });
1893
+ }));
1894
+ })));
1895
+ }));
1896
+ }
1897
+ function uploadFile(config, client, file) {
1898
+ let options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
1899
+ return testFile(file).pipe(switchMap(fileOptions => {
1900
+ return concat(of({
1901
+ type: "file",
1902
+ file: fileOptions
1903
+ }), testSecretsObservable(client).pipe(switchMap(json => {
1904
+ if (!json || !json.status) {
1905
+ return throwError(new Error("Invalid credentials"));
1906
+ }
1907
+ const uuid$1 = uuid();
1908
+ const {
1909
+ enableSignedUrls
1910
+ } = options;
1911
+ const body = {
1912
+ mp4_support: config.mp4_support,
1913
+ playback_policy: [enableSignedUrls ? "signed" : "public"]
1914
+ };
1915
+ return concat(of({
1916
+ type: "uuid",
1917
+ uuid: uuid$1
1918
+ }), defer(() => client.observable.request({
1919
+ url: "/addons/mux/uploads/".concat(client.config().dataset),
1920
+ withCredentials: true,
1921
+ method: "POST",
1922
+ headers: {
1923
+ "MUX-Proxy-UUID": uuid$1,
1924
+ "Content-Type": "application/json"
1925
+ },
1926
+ body
1927
+ })).pipe(mergeMap(result => {
1928
+ return createUpChunkObservable(uuid$1, result.upload.url, file).pipe(
1929
+ // eslint-disable-next-line no-warning-comments
1930
+ // @TODO type the observable events
1931
+ // eslint-disable-next-line max-nested-callbacks
1932
+ mergeMap(event => {
1933
+ if (event.type !== "success") {
1934
+ return of(event);
1935
+ }
1936
+ return from(updateAssetDocumentFromUpload(client, uuid$1)).pipe(
1937
+ // eslint-disable-next-line max-nested-callbacks
1938
+ mergeMap(doc => of({
1939
+ ...event,
1940
+ asset: doc
1941
+ })));
1942
+ }),
1943
+ // eslint-disable-next-line max-nested-callbacks
1944
+ catchError(err => {
1945
+ return cancelUpload(client, uuid$1).pipe(mergeMapTo(throwError(err)));
1946
+ }));
1947
+ })));
1948
+ })));
1949
+ }));
1950
+ }
1951
+ function getUpload(client, assetId) {
1952
+ const {
1953
+ dataset
1954
+ } = client.config();
1955
+ return client.request({
1956
+ url: "/addons/mux/uploads/".concat(dataset, "/").concat(assetId),
1957
+ withCredentials: true,
1958
+ method: "GET"
1959
+ });
1960
+ }
1961
+ function pollUpload(client, uuid) {
1962
+ const maxTries = 10;
1963
+ let pollInterval;
1964
+ let tries = 0;
1965
+ let assetId;
1966
+ let upload;
1967
+ return new Promise((resolve, reject) => {
1968
+ pollInterval = setInterval(async () => {
1969
+ try {
1970
+ upload = await getUpload(client, uuid);
1971
+ } catch (err) {
1972
+ reject(err);
1973
+ return;
1974
+ }
1975
+ assetId = upload && upload.data && upload.data.asset_id;
1976
+ if (assetId) {
1977
+ clearInterval(pollInterval);
1978
+ resolve(upload);
1979
+ }
1980
+ if (tries > maxTries) {
1981
+ clearInterval(pollInterval);
1982
+ reject(new Error("Upload did not finish"));
1983
+ }
1984
+ tries++;
1985
+ }, 2e3);
1986
+ });
1987
+ }
1988
+ async function updateAssetDocumentFromUpload(client, uuid) {
1989
+ let upload;
1990
+ let asset;
1991
+ try {
1992
+ upload = await pollUpload(client, uuid);
1993
+ } catch (err) {
1994
+ return Promise.reject(err);
1995
+ }
1996
+ try {
1997
+ asset = await getAsset(client, upload.data.asset_id);
1998
+ } catch (err) {
1999
+ return Promise.reject(err);
2000
+ }
2001
+ const doc = {
2002
+ _id: uuid,
2003
+ _type: "mux.videoAsset",
2004
+ status: asset.data.status,
2005
+ data: asset.data,
2006
+ assetId: asset.data.id,
2007
+ playbackId: asset.data.playback_ids[0].id,
2008
+ uploadId: upload.data.id
2009
+ };
2010
+ return client.createOrReplace(doc).then(() => {
2011
+ return doc;
2012
+ });
2013
+ }
2014
+ function testFile(file) {
2015
+ if (typeof window !== "undefined" && file instanceof window.File) {
2016
+ const fileOptions = optionsFromFile({}, file);
2017
+ return of(fileOptions);
2018
+ }
2019
+ return throwError(new Error("Invalid file"));
2020
+ }
2021
+ function testUrl(url) {
2022
+ const error = new Error("Invalid URL");
2023
+ if (typeof url !== "string") {
2024
+ return throwError(error);
2025
+ }
2026
+ let parsed;
2027
+ try {
2028
+ parsed = new URL(url);
2029
+ } catch (err) {
2030
+ return throwError(error);
2031
+ }
2032
+ if (parsed && !parsed.protocol.match(/http:|https:/)) {
2033
+ return throwError(error);
2034
+ }
2035
+ return of(url);
2036
+ }
2037
+ function optionsFromFile(opts, file) {
2038
+ if (typeof window === "undefined" || !(file instanceof window.File)) {
2039
+ return opts;
2040
+ }
2041
+ return {
2042
+ name: opts.preserveFilename === false ? void 0 : file.name,
2043
+ type: file.type
2044
+ };
2045
+ }
2046
+ function extractDroppedFiles(dataTransfer) {
2047
+ const files = Array.from(dataTransfer.files || []);
2048
+ const items = Array.from(dataTransfer.items || []);
2049
+ if (files && files.length > 0) {
2050
+ return Promise.resolve(files);
2051
+ }
2052
+ return normalizeItems(items).then(arr => arr.flat());
2053
+ }
2054
+ function normalizeItems(items) {
2055
+ return Promise.all(items.map(item => {
2056
+ if (item.kind === "file" && item.webkitGetAsEntry) {
2057
+ let entry;
2058
+ try {
2059
+ entry = item.webkitGetAsEntry();
2060
+ } catch (err) {
2061
+ return [item.getAsFile()];
2062
+ }
2063
+ if (!entry) {
2064
+ return [];
2065
+ }
2066
+ return entry.isDirectory ? walk(entry) : [item.getAsFile()];
2067
+ }
2068
+ if (item.kind === "file") {
2069
+ const file = item.getAsFile();
2070
+ return Promise.resolve(file ? [file] : []);
2071
+ }
2072
+ return new Promise(resolve => item.getAsString(resolve)).then(str => str ? [new File([str], "unknown.txt", {
2073
+ type: item.type
2074
+ })] : []);
2075
+ }));
2076
+ }
2077
+ function isFile(entry) {
2078
+ return entry.isFile;
2079
+ }
2080
+ function isDirectory(entry) {
2081
+ return entry.isDirectory;
2082
+ }
2083
+ function walk(entry) {
2084
+ if (isFile(entry)) {
2085
+ return new Promise(resolve => entry.file(resolve)).then(file => [file]);
2086
+ }
2087
+ if (isDirectory(entry)) {
2088
+ const dir = entry.createReader();
2089
+ 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()));
2090
+ }
2091
+ return Promise.resolve([]);
2092
+ }
2093
+ function SelectAssets(_ref14) {
2094
+ let {
2095
+ asset: selectedAsset,
2096
+ onChange,
2097
+ setDialogState
2098
+ } = _ref14;
2099
+ const handleSelect = useCallback(chosenAsset => {
2100
+ if (!(chosenAsset == null ? void 0 : chosenAsset._id)) {
2101
+ onChange(PatchEvent.from([unset(["asset"])]));
2102
+ }
2103
+ if (chosenAsset._id !== (selectedAsset == null ? void 0 : selectedAsset._id)) {
2104
+ onChange(PatchEvent.from([setIfMissing({
2105
+ asset: {}
2106
+ }), set({
2107
+ _type: "reference",
2108
+ _weak: true,
2109
+ _ref: chosenAsset._id
2110
+ }, ["asset"])]));
2111
+ }
2112
+ setDialogState(false);
2113
+ }, [onChange, setDialogState, selectedAsset]);
2114
+ return /* @__PURE__ */jsx(VideosBrowser, {
2115
+ onSelect: handleSelect
2116
+ });
2117
+ }
2118
+ function InputBrowser(_ref15) {
2119
+ let {
2120
+ setDialogState,
2121
+ asset,
2122
+ onChange
2123
+ } = _ref15;
2124
+ const id = "InputBrowser".concat(useId());
2125
+ const handleClose = useCallback(() => setDialogState(false), [setDialogState]);
2126
+ return /* @__PURE__ */jsx(Dialog, {
2127
+ __unstable_autoFocus: true,
2128
+ header: "Select video",
2129
+ id,
2130
+ onClose: handleClose,
2131
+ width: 2,
2132
+ children: /* @__PURE__ */jsx(SelectAssets, {
2133
+ asset,
2134
+ onChange,
2135
+ setDialogState
2136
+ })
2137
+ });
2138
+ }
2139
+ const useCancelUpload = (asset, onChange) => {
2140
+ const client = useClient();
2141
+ return useCallback(() => {
2142
+ if (!asset) {
2143
+ return;
2144
+ }
2145
+ onChange(PatchEvent.from(unset()));
2146
+ if (asset.assetId) {
2147
+ deleteAssetOnMux(client, asset.assetId);
2148
+ }
2149
+ if (asset._id) {
2150
+ client.delete(asset._id);
2151
+ }
2152
+ }, [asset, client, onChange]);
2153
+ };
2154
+ var __freeze$8 = Object.freeze;
2155
+ var __defProp$9 = Object.defineProperty;
2156
+ var __template$8 = (cooked, raw) => __freeze$8(__defProp$9(cooked, "raw", {
2157
+ value: __freeze$8(raw || cooked.slice())
2158
+ }));
2159
+ var _a$8, _b$4;
2160
+ styled.div(_a$8 || (_a$8 = __template$8(["\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"])));
2161
+ const TopControls = styled.div(_b$4 || (_b$4 = __template$8(["\n position: absolute;\n top: 0;\n right: 0;\n justify-content: flex-end;\n button {\n height: auto;\n }\n"])));
2162
+ var __freeze$7 = Object.freeze;
2163
+ var __defProp$8 = Object.defineProperty;
2164
+ var __template$7 = (cooked, raw) => __freeze$7(__defProp$8(cooked, "raw", {
2165
+ value: __freeze$7(raw || cooked.slice())
2166
+ }));
2167
+ var _a$7, _b$3, _c, _d;
2168
+ const CardWrapper = styled(Card)(_a$7 || (_a$7 = __template$7(["\n min-height: 82px;\n box-sizing: border-box;\n"])));
2169
+ const FlexWrapper = styled(Flex)(_b$3 || (_b$3 = __template$7(["\n text-overflow: ellipsis;\n overflow: hidden;\n"])));
2170
+ const LeftSection = styled(Stack)(_c || (_c = __template$7(["\n position: relative;\n width: 60%;\n"])));
2171
+ const CodeWrapper = styled(Code)(_d || (_d = __template$7(["\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"])));
2172
+ const UploadProgress = _ref16 => {
2173
+ let {
2174
+ progress = 100,
2175
+ onCancel,
2176
+ filename,
2177
+ text = "Uploading"
2178
+ } = _ref16;
2179
+ return /* @__PURE__ */jsx(CardWrapper, {
2180
+ tone: "primary",
2181
+ padding: 4,
2182
+ border: true,
2183
+ height: "fill",
2184
+ children: /* @__PURE__ */jsxs(FlexWrapper, {
2185
+ align: "center",
2186
+ justify: "space-between",
2187
+ height: "fill",
2188
+ direction: "row",
2189
+ gap: 2,
2190
+ children: [/* @__PURE__ */jsxs(LeftSection, {
2191
+ children: [/* @__PURE__ */jsx(Flex, {
2192
+ justify: "center",
2193
+ gap: [3, 3, 2, 2],
2194
+ direction: ["column", "column", "row"],
2195
+ children: /* @__PURE__ */jsx(Text, {
2196
+ size: 1,
2197
+ children: /* @__PURE__ */jsxs(Inline, {
2198
+ space: 2,
2199
+ children: [text, /* @__PURE__ */jsx(CodeWrapper, {
2200
+ size: 1,
2201
+ children: filename ? filename : "..."
2202
+ })]
2203
+ })
2204
+ })
2205
+ }), /* @__PURE__ */jsx(Card, {
2206
+ marginTop: 3,
2207
+ radius: 5,
2208
+ shadow: 1,
2209
+ children: /* @__PURE__ */jsx(LinearProgress, {
2210
+ value: progress
2211
+ })
2212
+ })]
2213
+ }), onCancel ? /* @__PURE__ */jsx(Button, {
2214
+ fontSize: 2,
2215
+ text: "Cancel upload",
2216
+ mode: "ghost",
2217
+ tone: "critical",
2218
+ onClick: onCancel
2219
+ }) : null]
2220
+ })
2221
+ });
2222
+ };
2223
+ const Player = _ref17 => {
2224
+ let {
2225
+ asset,
2226
+ buttons,
2227
+ readOnly,
2228
+ onChange
2229
+ } = _ref17;
2230
+ var _a, _b, _c, _d;
2231
+ const isLoading = useMemo(() => {
2232
+ if ((asset == null ? void 0 : asset.status) === "preparing") {
2233
+ return "Preparing the video";
2234
+ }
2235
+ if ((asset == null ? void 0 : asset.status) === "waiting_for_upload") {
2236
+ return "Waiting for upload to start";
2237
+ }
2238
+ if ((asset == null ? void 0 : asset.status) === "waiting") {
2239
+ return "Processing upload";
2240
+ }
2241
+ if ((asset == null ? void 0 : asset.status) === "ready") {
2242
+ return false;
2243
+ }
2244
+ if (typeof (asset == null ? void 0 : asset.status) === "undefined") {
2245
+ return false;
2246
+ }
2247
+ return true;
2248
+ }, [asset]);
2249
+ const isPreparingStaticRenditions = useMemo(() => {
2250
+ var _a2, _b2, _c2, _d2;
2251
+ if (((_b2 = (_a2 = asset == null ? void 0 : asset.data) == null ? void 0 : _a2.static_renditions) == null ? void 0 : _b2.status) === "preparing") {
2252
+ return true;
2253
+ }
2254
+ if (((_d2 = (_c2 = asset == null ? void 0 : asset.data) == null ? void 0 : _c2.static_renditions) == null ? void 0 : _d2.status) === "ready") {
2255
+ return false;
2256
+ }
2257
+ return false;
2258
+ }, [(_b = (_a = asset == null ? void 0 : asset.data) == null ? void 0 : _a.static_renditions) == null ? void 0 : _b.status]);
2259
+ const playRef = useRef(null);
2260
+ const muteRef = useRef(null);
2261
+ const handleCancelUpload = useCancelUpload(asset, onChange);
2262
+ useEffect(() => {
2263
+ var _a2, _b2;
2264
+ const style = document.createElement("style");
2265
+ style.innerHTML = "button svg { vertical-align: middle; }";
2266
+ if ((_a2 = playRef.current) == null ? void 0 : _a2.shadowRoot) {
2267
+ playRef.current.shadowRoot.appendChild(style);
2268
+ }
2269
+ if ((_b2 = muteRef == null ? void 0 : muteRef.current) == null ? void 0 : _b2.shadowRoot) {
2270
+ muteRef.current.shadowRoot.appendChild(style.cloneNode(true));
2271
+ }
2272
+ }, []);
2273
+ useEffect(() => {
2274
+ var _a2, _b2, _c2;
2275
+ if ((asset == null ? void 0 : asset.status) === "errored") {
2276
+ handleCancelUpload();
2277
+ throw new Error((_c2 = (_b2 = (_a2 = asset.data) == null ? void 0 : _a2.errors) == null ? void 0 : _b2.messages) == null ? void 0 : _c2.join(" "));
2278
+ }
2279
+ }, [(_d = (_c = asset.data) == null ? void 0 : _c.errors) == null ? void 0 : _d.messages, asset == null ? void 0 : asset.status, handleCancelUpload]);
2280
+ if (!asset || !asset.status) {
2281
+ return null;
2282
+ }
2283
+ if (isLoading) {
2284
+ return /* @__PURE__ */jsx(UploadProgress, {
2285
+ progress: 100,
2286
+ filename: asset == null ? void 0 : asset.filename,
2287
+ text: isLoading !== true && isLoading || "Waiting for Mux to complete the file",
2288
+ onCancel: readOnly ? void 0 : () => handleCancelUpload()
2289
+ });
2290
+ }
2291
+ return /* @__PURE__ */jsxs(VideoPlayer, {
2292
+ asset,
2293
+ children: [buttons && /* @__PURE__ */jsx(TopControls, {
2294
+ slot: "top-chrome",
2295
+ children: buttons
2296
+ }), isPreparingStaticRenditions && /* @__PURE__ */jsx(Card, {
2297
+ padding: 2,
2298
+ radius: 1,
2299
+ style: {
2300
+ background: "var(--card-fg-color)",
2301
+ position: "absolute",
2302
+ top: "0.5em",
2303
+ left: "0.5em"
2304
+ },
2305
+ children: /* @__PURE__ */jsx(Text, {
2306
+ size: 1,
2307
+ style: {
2308
+ color: "var(--card-bg-color)"
2309
+ },
2310
+ children: "MUX is preparing static renditions, please stand by"
2311
+ })
2312
+ })]
2313
+ });
2314
+ };
2315
+ function focusRingBorderStyle(border) {
2316
+ return "inset 0 0 0 ".concat(border.width, "px ").concat(border.color);
2317
+ }
2318
+ function focusRingStyle(opts) {
2319
+ const {
2320
+ base,
2321
+ border,
2322
+ focusRing
2323
+ } = opts;
2324
+ const focusRingOutsetWidth = focusRing.offset + focusRing.width;
2325
+ const focusRingInsetWidth = 0 - focusRing.offset;
2326
+ const bgColor = base ? base.bg : "var(--card-bg-color)";
2327
+ 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(",");
2328
+ }
2329
+ var __freeze$6 = Object.freeze;
2330
+ var __defProp$7 = Object.defineProperty;
2331
+ var __template$6 = (cooked, raw) => __freeze$6(__defProp$7(cooked, "raw", {
2332
+ value: __freeze$6(raw || cooked.slice())
2333
+ }));
2334
+ var _a$6;
2335
+ const FileButton = styled(MenuItem)(_ref18 => {
2336
+ let {
2337
+ theme
2338
+ } = _ref18;
2339
+ const {
2340
+ focusRing
2341
+ } = theme.sanity;
2342
+ const base = theme.sanity.color.base;
2343
+ const border = {
2344
+ width: 1,
2345
+ color: "var(--card-border-color)"
2346
+ };
2347
+ return css(_a$6 || (_a$6 = __template$6(["\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({
2348
+ base,
2349
+ border,
2350
+ focusRing
2351
+ }));
2352
+ });
2353
+ const FileInputMenuItem = React.forwardRef(function FileInputMenuItem2(props, forwardedRef) {
2354
+ const {
2355
+ icon,
2356
+ id: idProp,
2357
+ accept,
2358
+ capture,
2359
+ fontSize,
2360
+ multiple,
2361
+ onSelect,
2362
+ padding = 3,
2363
+ space = 3,
2364
+ textAlign,
2365
+ text,
2366
+ disabled,
2367
+ ...rest
2368
+ } = props;
2369
+ const idHook = useId();
2370
+ const id = idProp || idHook;
2371
+ const handleChange = React.useCallback(event => {
2372
+ if (onSelect && event.target.files) {
2373
+ onSelect(Array.from(event.target.files));
2374
+ }
2375
+ }, [onSelect]);
2376
+ const content = /* @__PURE__ */jsxs(Flex, {
2377
+ align: "center",
2378
+ justify: "flex-start",
2379
+ padding,
2380
+ children: [icon && /* @__PURE__ */jsx(Box, {
2381
+ marginRight: text ? space : void 0,
2382
+ children: /* @__PURE__ */jsxs(Text, {
2383
+ size: fontSize,
2384
+ children: [isValidElement(icon) && icon, isValidElementType(icon) && createElement(icon)]
2385
+ })
2386
+ }), text && /* @__PURE__ */jsx(Text, {
2387
+ align: textAlign,
2388
+ size: fontSize,
2389
+ textOverflow: "ellipsis",
2390
+ children: text
2391
+ })]
2392
+ });
2393
+ return /* @__PURE__ */jsxs(FileButton, {
2394
+ ...rest,
2395
+ htmlFor: id,
2396
+ padding: 0,
2397
+ fontSize: 2,
2398
+ disabled,
2399
+ ref: forwardedRef,
2400
+ children: [content, /* @__PURE__ */jsx("input", {
2401
+ "data-testid": "file-button-input",
2402
+ accept,
2403
+ capture,
2404
+ id,
2405
+ multiple,
2406
+ onChange: handleChange,
2407
+ type: "file",
2408
+ value: "",
2409
+ disabled
2410
+ })]
2411
+ });
2412
+ });
2413
+ var __freeze$5 = Object.freeze;
2414
+ var __defProp$6 = Object.defineProperty;
2415
+ var __template$5 = (cooked, raw) => __freeze$5(__defProp$6(cooked, "raw", {
2416
+ value: __freeze$5(raw || cooked.slice())
2417
+ }));
2418
+ var _a$5, _b$2;
2419
+ const LockCard = styled(Card)(_a$5 || (_a$5 = __template$5(["\n position: absolute;\n top: 0;\n left: 0;\n opacity: 0.6;\n mix-blend-mode: screen;\n background: transparent;\n"])));
2420
+ const LockButton = styled(Button)(_b$2 || (_b$2 = __template$5(["\n background: transparent;\n color: white;\n"])));
2421
+ function PlayerActionsMenu(props) {
2422
+ const {
2423
+ asset,
2424
+ readOnly,
2425
+ dialogState,
2426
+ setDialogState,
2427
+ onChange,
2428
+ onUpload
2429
+ } = props;
2430
+ const [open, setOpen] = useState(false);
2431
+ const [menuElement, setMenuRef] = useState(null);
2432
+ const isSigned = useMemo(() => getPlaybackPolicy(asset) === "signed", [asset]);
2433
+ const onReset = useCallback(() => onChange(PatchEvent.from(unset([]))), [onChange]);
2434
+ useEffect(() => {
2435
+ if (open && dialogState) {
2436
+ setOpen(false);
2437
+ }
2438
+ }, [dialogState, open]);
2439
+ useClickOutside(useCallback(() => setOpen(false), []), [menuElement]);
2440
+ return /* @__PURE__ */jsxs(Inline, {
2441
+ space: 1,
2442
+ padding: 2,
2443
+ children: [isSigned && /* @__PURE__ */jsx(Tooltip, {
2444
+ content: /* @__PURE__ */jsx(Box, {
2445
+ padding: 2,
2446
+ children: /* @__PURE__ */jsx(Text, {
2447
+ muted: true,
2448
+ size: 1,
2449
+ children: "Signed playback policy"
2450
+ })
2451
+ }),
2452
+ placement: "right",
2453
+ portal: true,
2454
+ children: /* @__PURE__ */jsx(LockCard, {
2455
+ radius: 2,
2456
+ margin: 2,
2457
+ scheme: "dark",
2458
+ tone: "positive",
2459
+ children: /* @__PURE__ */jsx(LockButton, {
2460
+ icon: LockIcon,
2461
+ mode: "bleed",
2462
+ tone: "positive"
2463
+ })
2464
+ })
2465
+ }), /* @__PURE__ */jsx(Popover, {
2466
+ content: /* @__PURE__ */jsxs(Menu, {
2467
+ ref: setMenuRef,
2468
+ children: [/* @__PURE__ */jsx(Box, {
2469
+ padding: 2,
2470
+ children: /* @__PURE__ */jsx(Label$1, {
2471
+ muted: true,
2472
+ size: 1,
2473
+ children: "Replace"
2474
+ })
2475
+ }), /* @__PURE__ */jsx(FileInputMenuItem, {
2476
+ accept: "video/*",
2477
+ icon: UploadIcon,
2478
+ mode: "bleed",
2479
+ onSelect: onUpload,
2480
+ text: "Upload",
2481
+ disabled: readOnly,
2482
+ fontSize: 2
2483
+ }), /* @__PURE__ */jsx(MenuItem, {
2484
+ icon: SearchIcon,
2485
+ text: "Browse",
2486
+ onClick: () => setDialogState("select-video")
2487
+ }), /* @__PURE__ */jsx(MenuDivider, {}), /* @__PURE__ */jsx(MenuItem, {
2488
+ icon: PlugIcon,
2489
+ text: "Configure API",
2490
+ onClick: () => setDialogState("secrets")
2491
+ }), /* @__PURE__ */jsx(MenuDivider, {}), /* @__PURE__ */jsx(MenuItem, {
2492
+ tone: "critical",
2493
+ icon: ResetIcon,
2494
+ text: "Clear field",
2495
+ onClick: onReset,
2496
+ disabled: readOnly
2497
+ })]
2498
+ }),
2499
+ portal: true,
2500
+ open,
2501
+ children: /* @__PURE__ */jsx(Button, {
2502
+ icon: EllipsisVerticalIcon,
2503
+ mode: "ghost",
2504
+ onClick: () => {
2505
+ setDialogState(false);
2506
+ setOpen(true);
2507
+ }
2508
+ })
2509
+ })]
2510
+ });
2511
+ }
2512
+ var PlayerActionsMenu$1 = memo(PlayerActionsMenu);
2513
+ var __freeze$4 = Object.freeze;
2514
+ var __defProp$5 = Object.defineProperty;
2515
+ var __template$4 = (cooked, raw) => __freeze$4(__defProp$5(cooked, "raw", {
2516
+ value: __freeze$4(raw || cooked.slice())
2517
+ }));
2518
+ var _a$4;
2519
+ function withFocusRing(component) {
2520
+ return styled(component)(props => {
2521
+ const border = {
2522
+ width: props.$border ? 1 : 0,
2523
+ color: "var(--card-border-color)"
2524
+ };
2525
+ return css(_a$4 || (_a$4 = __template$4(["\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({
2526
+ base: props.theme.sanity.color.base,
2527
+ border,
2528
+ focusRing: props.theme.sanity.focusRing
2529
+ }));
2530
+ });
2531
+ }
2532
+ var __freeze$3 = Object.freeze;
2533
+ var __defProp$4 = Object.defineProperty;
2534
+ var __template$3 = (cooked, raw) => __freeze$3(__defProp$4(cooked, "raw", {
2535
+ value: __freeze$3(raw || cooked.slice())
2536
+ }));
2537
+ var _a$3;
2538
+ const ctrlKey = 17;
2539
+ const cmdKey = 91;
2540
+ const UploadCardWithFocusRing = withFocusRing(Card);
2541
+ const UploadCard$1 = forwardRef((_ref19, forwardedRef) => {
2542
+ let {
2543
+ children,
2544
+ tone,
2545
+ onPaste,
2546
+ onDrop,
2547
+ onDragEnter,
2548
+ onDragLeave,
2549
+ onDragOver
2550
+ } = _ref19;
2551
+ const ctrlDown = useRef(false);
2552
+ const inputRef = useRef(null);
2553
+ const handleKeyDown = useCallback(event => {
2554
+ if (event.keyCode == ctrlKey || event.keyCode == cmdKey) {
2555
+ ctrlDown.current = true;
2556
+ }
2557
+ const vKey = 86;
2558
+ if (ctrlDown.current && event.keyCode == vKey) {
2559
+ inputRef.current.focus();
2560
+ }
2561
+ }, []);
2562
+ const handleKeyUp = useCallback(event => {
2563
+ if (event.keyCode == ctrlKey || event.keyCode == cmdKey) {
2564
+ ctrlDown.current = false;
2565
+ }
2566
+ }, []);
2567
+ return /* @__PURE__ */jsxs(UploadCardWithFocusRing, {
2568
+ tone,
2569
+ height: "fill",
2570
+ ref: forwardedRef,
2571
+ padding: 0,
2572
+ radius: 2,
2573
+ shadow: 0,
2574
+ tabIndex: 0,
2575
+ onKeyDown: handleKeyDown,
2576
+ onKeyUp: handleKeyUp,
2577
+ onPaste,
2578
+ onDrop,
2579
+ onDragEnter,
2580
+ onDragLeave,
2581
+ onDragOver,
2582
+ children: [/* @__PURE__ */jsx(HiddenInput$1, {
2583
+ ref: inputRef,
2584
+ onPaste
2585
+ }), children]
2586
+ });
2587
+ });
2588
+ const HiddenInput$1 = styled.input.attrs({
2589
+ type: "text"
2590
+ })(_a$3 || (_a$3 = __template$3(["\n position: absolute;\n border: 0;\n color: white;\n opacity: 0;\n\n &:focus {\n outline: none;\n }\n"])));
2591
+ var __freeze$2 = Object.freeze;
2592
+ var __defProp$3 = Object.defineProperty;
2593
+ var __template$2 = (cooked, raw) => __freeze$2(__defProp$3(cooked, "raw", {
2594
+ value: __freeze$2(raw || cooked.slice())
2595
+ }));
2596
+ var _a$2, _b$1;
2597
+ const HiddenInput = styled.input(_a$2 || (_a$2 = __template$2(["\n overflow: hidden;\n width: 0.1px;\n height: 0.1px;\n opacity: 0;\n position: absolute;\n z-index: -1;\n"])));
2598
+ const Label = styled.label(_b$1 || (_b$1 = __template$2(["\n position: relative;\n"])));
2599
+ const FileInputButton = _ref20 => {
2600
+ let {
2601
+ onSelect,
2602
+ ...props
2603
+ } = _ref20;
2604
+ const inputId = "FileSelect".concat(useId());
2605
+ const inputRef = useRef(null);
2606
+ const handleSelect = useCallback(event => {
2607
+ if (onSelect) {
2608
+ onSelect(event.target.files);
2609
+ }
2610
+ }, [onSelect]);
2611
+ const handleButtonClick = useCallback(() => {
2612
+ var _a2;
2613
+ return (_a2 = inputRef.current) == null ? void 0 : _a2.click();
2614
+ }, []);
2615
+ return /* @__PURE__ */jsxs(Label, {
2616
+ htmlFor: inputId,
2617
+ children: [/* @__PURE__ */jsx(HiddenInput, {
2618
+ accept: "video/*",
2619
+ ref: inputRef,
2620
+ tabIndex: 0,
2621
+ type: "file",
2622
+ id: inputId,
2623
+ onChange: handleSelect,
2624
+ value: ""
2625
+ }), /* @__PURE__ */jsx(Button, {
2626
+ onClick: handleButtonClick,
2627
+ mode: "default",
2628
+ tone: "primary",
2629
+ style: {
2630
+ width: "100%"
2631
+ },
2632
+ ...props
2633
+ })]
2634
+ });
2635
+ };
2636
+ var __freeze$1 = Object.freeze;
2637
+ var __defProp$2 = Object.defineProperty;
2638
+ var __template$1 = (cooked, raw) => __freeze$1(__defProp$2(cooked, "raw", {
2639
+ value: __freeze$1(raw || cooked.slice())
2640
+ }));
2641
+ var _a$1, _b;
2642
+ const UploadCard = styled(Card)(_a$1 || (_a$1 = __template$1(["\n && {\n border-style: dashed;\n }\n"])));
2643
+ const ConfigureApiBox = styled(Box)(_b || (_b = __template$1(["\n position: absolute;\n top: 0;\n right: 0;\n"])));
2644
+ function UploadPlaceholder(props) {
2645
+ const {
2646
+ setDialogState,
2647
+ readOnly,
2648
+ onSelect,
2649
+ hovering,
2650
+ needsSetup
2651
+ } = props;
2652
+ const handleBrowse = useCallback(() => setDialogState("select-video"), [setDialogState]);
2653
+ const handleConfigureApi = useCallback(() => setDialogState("secrets"), [setDialogState]);
2654
+ return /* @__PURE__ */jsx(Box, {
2655
+ style: {
2656
+ padding: 1,
2657
+ position: "relative"
2658
+ },
2659
+ height: "stretch",
2660
+ children: /* @__PURE__ */jsxs(UploadCard, {
2661
+ sizing: "border",
2662
+ height: "fill",
2663
+ tone: readOnly ? "transparent" : "inherit",
2664
+ border: true,
2665
+ padding: 3,
2666
+ style: hovering ? {
2667
+ borderColor: "transparent"
2668
+ } : void 0,
2669
+ children: [/* @__PURE__ */jsx(ConfigureApiBox, {
2670
+ padding: 3,
2671
+ children: /* @__PURE__ */jsx(Button, {
2672
+ padding: 3,
2673
+ radius: 3,
2674
+ tone: needsSetup ? "critical" : void 0,
2675
+ onClick: handleConfigureApi,
2676
+ icon: PlugIcon,
2677
+ mode: "bleed"
2678
+ })
2679
+ }), /* @__PURE__ */jsxs(Flex, {
2680
+ align: "center",
2681
+ justify: "space-between",
2682
+ gap: 4,
2683
+ direction: ["column", "column", "row"],
2684
+ paddingY: [2, 2, 0],
2685
+ sizing: "border",
2686
+ height: "fill",
2687
+ children: [/* @__PURE__ */jsxs(Flex, {
2688
+ align: "center",
2689
+ justify: "center",
2690
+ gap: 2,
2691
+ flex: 1,
2692
+ children: [/* @__PURE__ */jsx(Flex, {
2693
+ justify: "center",
2694
+ children: /* @__PURE__ */jsx(Text, {
2695
+ muted: true,
2696
+ children: /* @__PURE__ */jsx(DocumentVideoIcon, {})
2697
+ })
2698
+ }), /* @__PURE__ */jsx(Flex, {
2699
+ justify: "center",
2700
+ children: /* @__PURE__ */jsx(Text, {
2701
+ size: 1,
2702
+ muted: true,
2703
+ children: "Drag video or paste URL here"
2704
+ })
2705
+ })]
2706
+ }), /* @__PURE__ */jsxs(Inline, {
2707
+ space: 2,
2708
+ children: [/* @__PURE__ */jsx(FileInputButton, {
2709
+ mode: "ghost",
2710
+ tone: "default",
2711
+ icon: UploadIcon,
2712
+ text: "Upload",
2713
+ onSelect
2714
+ }), /* @__PURE__ */jsx(Button, {
2715
+ mode: "ghost",
2716
+ icon: SearchIcon,
2717
+ text: "Select",
2718
+ onClick: handleBrowse
2719
+ })]
2720
+ })]
2721
+ })]
2722
+ })
2723
+ });
2724
+ }
2725
+ var __defProp$1 = Object.defineProperty;
2726
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp$1(obj, key, {
2727
+ enumerable: true,
2728
+ configurable: true,
2729
+ writable: true,
2730
+ value
2731
+ }) : obj[key] = value;
2732
+ var __publicField = (obj, key, value) => {
2733
+ __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
2734
+ return value;
2735
+ };
2736
+ class MuxVideoInputUploader extends Component {
2737
+ constructor() {
2738
+ super(...arguments);
2739
+ __publicField(this, "state", {
2740
+ isDraggingOver: false,
2741
+ invalidPaste: false,
2742
+ invalidFile: false,
2743
+ uploadProgress: null,
2744
+ fileInfo: null,
2745
+ uuid: null,
2746
+ error: null,
2747
+ url: null
2748
+ });
2749
+ __publicField(this, "dragEnteredEls", []);
2750
+ __publicField(this, "ctrlDown", false);
2751
+ // eslint-disable-next-line no-warning-comments
2752
+ // @TODO add proper typings for the return values of uploadFile and uploadUrl
2753
+ __publicField(this, "upload", null);
2754
+ __publicField(this, "container", React.createRef());
2755
+ __publicField(this, "onCancelUploadButtonClick$");
2756
+ __publicField(this, "handleCancelUploadButtonClick");
2757
+ __publicField(this, "handleProgress", evt => {
2758
+ this.setState({
2759
+ uploadProgress: evt.percent
2760
+ });
2761
+ });
2762
+ __publicField(this, "onUpload", files => {
2763
+ this.setState({
2764
+ uploadProgress: 0,
2765
+ fileInfo: null,
2766
+ uuid: null
2767
+ });
2768
+ this.upload = uploadFile(this.props.config, this.props.client, files[0], {
2769
+ enableSignedUrls: this.props.secrets.enableSignedUrls
2770
+ }).pipe(takeUntil(this.onCancelUploadButtonClick$.pipe(tap(() => {
2771
+ if (this.state.uuid) {
2772
+ this.props.client.delete(this.state.uuid);
2773
+ }
2774
+ })))).subscribe({
2775
+ complete: () => {
2776
+ this.setState({
2777
+ error: null,
2778
+ uploadProgress: null,
2779
+ uuid: null
2780
+ });
2781
+ },
2782
+ next: event => {
2783
+ this.handleUploadEvent(event);
2784
+ },
2785
+ error: err => {
2786
+ this.setState({
2787
+ error: err,
2788
+ uploadProgress: null,
2789
+ uuid: null
2790
+ });
2791
+ }
2792
+ });
2793
+ });
2794
+ // eslint-disable-next-line no-warning-comments
2795
+ // @TODO add proper typings for the Observable events
2796
+ __publicField(this, "handleUploadEvent", event => {
2797
+ switch (event.type) {
2798
+ case "success":
2799
+ return this.handleUploadSuccess(event.asset);
2800
+ case "progress":
2801
+ return this.handleProgress(event);
2802
+ case "file":
2803
+ return this.setState({
2804
+ fileInfo: event.file
2805
+ });
2806
+ case "uuid":
2807
+ return this.setState({
2808
+ uuid: event.uuid
2809
+ });
2810
+ case "url":
2811
+ return this.setState({
2812
+ url: event.url,
2813
+ uploadProgress: 100
2814
+ });
2815
+ default:
2816
+ return null;
2817
+ }
2818
+ });
2819
+ __publicField(this, "handleUploadSuccess", asset => {
2820
+ this.setState({
2821
+ uploadProgress: 100
2822
+ });
2823
+ this.props.onChange(PatchEvent.from([setIfMissing({
2824
+ asset: {}
2825
+ }), set({
2826
+ _type: "reference",
2827
+ _weak: true,
2828
+ _ref: asset._id
2829
+ }, ["asset"])]));
2830
+ });
2831
+ __publicField(this, "handlePaste", event => {
2832
+ const clipboardData = event.clipboardData || window.clipboardData;
2833
+ const url = clipboardData.getData("text");
2834
+ const options = {
2835
+ enableSignedUrls: this.props.secrets.enableSignedUrls
2836
+ };
2837
+ this.upload = uploadUrl(this.props.config, this.props.client, url, options).subscribe({
2838
+ complete: () => {
2839
+ this.setState({
2840
+ error: null,
2841
+ uploadProgress: null,
2842
+ url: null
2843
+ });
2844
+ },
2845
+ next: sEvent => {
2846
+ this.handleUploadEvent(sEvent);
2847
+ },
2848
+ error: err => {
2849
+ let error;
2850
+ if (!err.message.toLowerCase().match("invalid url")) {
2851
+ error = err;
2852
+ }
2853
+ this.setState({
2854
+ invalidPaste: true,
2855
+ error
2856
+ }, () => {
2857
+ setTimeout(() => {
2858
+ this.setState({
2859
+ invalidPaste: false,
2860
+ uploadProgress: null
2861
+ });
2862
+ }, 2e3);
2863
+ });
2864
+ }
2865
+ });
2866
+ });
2867
+ __publicField(this, "handleDrop", event => {
2868
+ this.setState({
2869
+ isDraggingOver: false
2870
+ });
2871
+ event.preventDefault();
2872
+ event.stopPropagation();
2873
+ extractDroppedFiles(event.nativeEvent.dataTransfer).then(files => {
2874
+ if (files) {
2875
+ this.onUpload(files);
2876
+ }
2877
+ });
2878
+ });
2879
+ __publicField(this, "handleDragOver", event => {
2880
+ event.preventDefault();
2881
+ event.stopPropagation();
2882
+ });
2883
+ __publicField(this, "handleDragEnter", event => {
2884
+ var _a, _b;
2885
+ event.stopPropagation();
2886
+ this.dragEnteredEls.push(event.target);
2887
+ this.setState({
2888
+ isDraggingOver: true
2889
+ });
2890
+ const type = (_b = (_a = event.dataTransfer.items) == null ? void 0 : _a[0]) == null ? void 0 : _b.type;
2891
+ this.setState({
2892
+ invalidFile: !type.startsWith("video/")
2893
+ });
2894
+ });
2895
+ __publicField(this, "handleDragLeave", event => {
2896
+ event.stopPropagation();
2897
+ const idx = this.dragEnteredEls.indexOf(event.target);
2898
+ if (idx > -1) {
2899
+ this.dragEnteredEls.splice(idx, 1);
2900
+ }
2901
+ if (this.dragEnteredEls.length === 0) {
2902
+ this.setState({
2903
+ isDraggingOver: false
2904
+ });
2905
+ }
2906
+ });
2907
+ }
2908
+ componentWillUnmount() {
2909
+ this.unSubscribeToUpload();
2910
+ }
2911
+ componentDidMount() {
2912
+ const events$ = new Subject();
2913
+ this.onCancelUploadButtonClick$ = events$.asObservable();
2914
+ this.handleCancelUploadButtonClick = event => events$.next(event);
2915
+ }
2916
+ unSubscribeToUpload() {
2917
+ if (this.upload && !this.upload.closed) {
2918
+ this.upload.unsubscribe();
2919
+ }
2920
+ }
2921
+ render() {
2922
+ var _a;
2923
+ if (this.state.uploadProgress !== null) {
2924
+ return /* @__PURE__ */jsx(UploadProgress, {
2925
+ onCancel: this.handleCancelUploadButtonClick,
2926
+ progress: this.state.uploadProgress,
2927
+ filename: ((_a = this.state.fileInfo) == null ? void 0 : _a.name) || this.state.url
2928
+ });
2929
+ }
2930
+ if (this.state.error) {
2931
+ throw this.state.error;
2932
+ }
2933
+ return /* @__PURE__ */jsxs(Fragment, {
2934
+ children: [/* @__PURE__ */jsx(UploadCard$1, {
2935
+ tone: this.state.isDraggingOver && (this.state.invalidPaste || this.state.invalidFile) ? "critical" : this.state.isDraggingOver ? "positive" : void 0,
2936
+ onDrop: this.handleDrop,
2937
+ onDragOver: this.handleDragOver,
2938
+ onDragLeave: this.handleDragLeave,
2939
+ onDragEnter: this.handleDragEnter,
2940
+ onPaste: this.handlePaste,
2941
+ ref: this.container,
2942
+ children: this.props.asset ? /* @__PURE__ */jsx(Player, {
2943
+ readOnly: this.props.readOnly,
2944
+ asset: this.props.asset,
2945
+ onChange: this.props.onChange,
2946
+ buttons: /* @__PURE__ */jsx(PlayerActionsMenu$1, {
2947
+ asset: this.props.asset,
2948
+ dialogState: this.props.dialogState,
2949
+ setDialogState: this.props.setDialogState,
2950
+ onChange: this.props.onChange,
2951
+ onUpload: this.onUpload,
2952
+ readOnly: this.props.readOnly
2953
+ })
2954
+ }) : /* @__PURE__ */jsx(UploadPlaceholder, {
2955
+ hovering: this.state.isDraggingOver,
2956
+ onSelect: this.onUpload,
2957
+ readOnly: this.props.readOnly,
2958
+ setDialogState: this.props.setDialogState,
2959
+ needsSetup: this.props.needsSetup
2960
+ })
2961
+ }), this.props.dialogState === "select-video" && /* @__PURE__ */jsx(InputBrowser, {
2962
+ asset: this.props.asset,
2963
+ onChange: this.props.onChange,
2964
+ setDialogState: this.props.setDialogState
2965
+ })]
2966
+ });
2967
+ }
2968
+ }
2969
+ const useSaveSecrets = (client, secrets) => {
2970
+ return useCallback(async _ref21 => {
2971
+ let {
2972
+ token,
2973
+ secretKey,
2974
+ enableSignedUrls
2975
+ } = _ref21;
2976
+ let {
2977
+ signingKeyId,
2978
+ signingKeyPrivate
2979
+ } = secrets;
2980
+ try {
2981
+ await saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate);
2982
+ const valid = await testSecrets(client);
2983
+ if (!(valid == null ? void 0 : valid.status) && token && secretKey) {
2984
+ throw new Error("Invalid secrets");
2985
+ }
2986
+ } catch (err) {
2987
+ console.error("Error while trying to save secrets:", err);
2988
+ throw err;
2989
+ }
2990
+ if (enableSignedUrls) {
2991
+ const hasValidSigningKeys = await haveValidSigningKeys(client, signingKeyId, signingKeyPrivate);
2992
+ if (!hasValidSigningKeys) {
2993
+ try {
2994
+ const {
2995
+ data
2996
+ } = await createSigningKeys(client);
2997
+ signingKeyId = data.id;
2998
+ signingKeyPrivate = data.private_key;
2999
+ await saveSecrets(client, token, secretKey, enableSignedUrls, signingKeyId, signingKeyPrivate);
3000
+ } catch (err) {
3001
+ console.log("Error while creating and saving signing key:", err == null ? void 0 : err.message);
3002
+ throw err;
3003
+ }
3004
+ }
3005
+ }
3006
+ return {
3007
+ token,
3008
+ secretKey,
3009
+ enableSignedUrls,
3010
+ signingKeyId,
3011
+ signingKeyPrivate
3012
+ };
3013
+ }, [client, secrets]);
3014
+ };
3015
+ function init(_ref22) {
3016
+ let {
3017
+ token,
3018
+ secretKey,
3019
+ enableSignedUrls
3020
+ } = _ref22;
3021
+ return {
3022
+ submitting: false,
3023
+ error: null,
3024
+ // Form inputs don't set the state back to null when clearing a field, but uses empty strings
3025
+ // This ensures the `dirty` check works correctly
3026
+ token: token != null ? token : "",
3027
+ secretKey: secretKey != null ? secretKey : "",
3028
+ enableSignedUrls: enableSignedUrls != null ? enableSignedUrls : false
3029
+ };
3030
+ }
3031
+ function reducer(state, action) {
3032
+ switch (action == null ? void 0 : action.type) {
3033
+ case "submit":
3034
+ return {
3035
+ ...state,
3036
+ submitting: true,
3037
+ error: null
3038
+ };
3039
+ case "error":
3040
+ return {
3041
+ ...state,
3042
+ submitting: false,
3043
+ error: action.payload
3044
+ };
3045
+ case "reset":
3046
+ return init(action.payload);
3047
+ case "change":
3048
+ return {
3049
+ ...state,
3050
+ [action.payload.name]: action.payload.value
3051
+ };
3052
+ default:
3053
+ throw new Error("Unknown action type: ".concat(action == null ? void 0 : action.type));
3054
+ }
3055
+ }
3056
+ const useSecretsFormState = secrets => useReducer(reducer, secrets, init);
3057
+ const ids = ["title", "a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r"];
3058
+ function MuxLogo(_ref23) {
3059
+ let {
3060
+ height = 26
3061
+ } = _ref23;
3062
+ const id = useId();
3063
+ 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]);
3064
+ return /* @__PURE__ */jsxs("svg", {
3065
+ "aria-labelledby": titleId,
3066
+ role: "img",
3067
+ xmlns: "http://www.w3.org/2000/svg",
3068
+ xmlSpace: "preserve",
3069
+ viewBox: "92.08878326416016 102.66712188720703 692.76123046875 219.99948120117188",
3070
+ style: {
3071
+ height: "".concat(height, "px")
3072
+ },
3073
+ children: [/* @__PURE__ */jsx("title", {
3074
+ id: titleId,
3075
+ children: "Mux Logo"
3076
+ }), /* @__PURE__ */jsxs("defs", {
3077
+ children: [/* @__PURE__ */jsxs("linearGradient", {
3078
+ id: c,
3079
+ spreadMethod: "pad",
3080
+ gradientTransform: "matrix(528.38055 0 0 -528.38055 63.801 159.5)",
3081
+ gradientUnits: "userSpaceOnUse",
3082
+ y2: 0,
3083
+ x2: 1,
3084
+ y1: 0,
3085
+ x1: 0,
3086
+ children: [/* @__PURE__ */jsx("stop", {
3087
+ offset: 0,
3088
+ style: {
3089
+ stopOpacity: 1,
3090
+ stopColor: "#ff4e00"
3091
+ }
3092
+ }), /* @__PURE__ */jsx("stop", {
3093
+ offset: 1,
3094
+ style: {
3095
+ stopOpacity: 1,
3096
+ stopColor: "#ff1791"
3097
+ }
3098
+ })]
3099
+ }), /* @__PURE__ */jsxs("linearGradient", {
3100
+ id: d,
3101
+ spreadMethod: "pad",
3102
+ gradientTransform: "matrix(523.66766 0 0 -523.66766 67.897 159.5)",
3103
+ gradientUnits: "userSpaceOnUse",
3104
+ y2: 0,
3105
+ x2: 1,
3106
+ y1: 0,
3107
+ x1: 0,
3108
+ children: [/* @__PURE__ */jsx("stop", {
3109
+ offset: 0,
3110
+ style: {
3111
+ stopOpacity: 1,
3112
+ stopColor: "#ff4e00"
3113
+ }
3114
+ }), /* @__PURE__ */jsx("stop", {
3115
+ offset: 1,
3116
+ style: {
3117
+ stopOpacity: 1,
3118
+ stopColor: "#ff1791"
3119
+ }
3120
+ })]
3121
+ }), /* @__PURE__ */jsxs("linearGradient", {
3122
+ id: g,
3123
+ spreadMethod: "pad",
3124
+ gradientTransform: "rotate(180 296.075 79.75) scale(524.84045)",
3125
+ gradientUnits: "userSpaceOnUse",
3126
+ y2: 0,
3127
+ x2: 1,
3128
+ y1: 0,
3129
+ x1: 0,
3130
+ children: [/* @__PURE__ */jsx("stop", {
3131
+ offset: 0,
3132
+ style: {
3133
+ stopOpacity: 1,
3134
+ stopColor: "#ff4e00"
3135
+ }
3136
+ }), /* @__PURE__ */jsx("stop", {
3137
+ offset: 1,
3138
+ style: {
3139
+ stopOpacity: 1,
3140
+ stopColor: "#ff1791"
3141
+ }
3142
+ })]
3143
+ }), /* @__PURE__ */jsxs("linearGradient", {
3144
+ id: i,
3145
+ spreadMethod: "pad",
3146
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
3147
+ gradientUnits: "userSpaceOnUse",
3148
+ y2: 0,
3149
+ x2: 1,
3150
+ y1: 0,
3151
+ x1: 0,
3152
+ children: [/* @__PURE__ */jsx("stop", {
3153
+ offset: 0,
3154
+ style: {
3155
+ stopOpacity: 1,
3156
+ stopColor: "#ff4e00"
3157
+ }
3158
+ }), /* @__PURE__ */jsx("stop", {
3159
+ offset: 1,
3160
+ style: {
3161
+ stopOpacity: 1,
3162
+ stopColor: "#ff1791"
3163
+ }
3164
+ })]
3165
+ }), /* @__PURE__ */jsxs("linearGradient", {
3166
+ id: j,
3167
+ spreadMethod: "pad",
3168
+ gradientTransform: "matrix(523.08514 0 0 -523.08514 67.897 224.446)",
3169
+ gradientUnits: "userSpaceOnUse",
3170
+ y2: 0,
3171
+ x2: 1,
3172
+ y1: 0,
3173
+ x1: 0,
3174
+ children: [/* @__PURE__ */jsx("stop", {
3175
+ offset: 0,
3176
+ style: {
3177
+ stopOpacity: 1,
3178
+ stopColor: "#ff4e00"
3179
+ }
3180
+ }), /* @__PURE__ */jsx("stop", {
3181
+ offset: 1,
3182
+ style: {
3183
+ stopOpacity: 1,
3184
+ stopColor: "#ff1791"
3185
+ }
3186
+ })]
3187
+ }), /* @__PURE__ */jsxs("linearGradient", {
3188
+ id: k,
3189
+ spreadMethod: "pad",
3190
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 94.553)",
3191
+ gradientUnits: "userSpaceOnUse",
3192
+ y2: 0,
3193
+ x2: 1,
3194
+ y1: 0,
3195
+ x1: 0,
3196
+ children: [/* @__PURE__ */jsx("stop", {
3197
+ offset: 0,
3198
+ style: {
3199
+ stopOpacity: 1,
3200
+ stopColor: "#ff4e00"
3201
+ }
3202
+ }), /* @__PURE__ */jsx("stop", {
3203
+ offset: 1,
3204
+ style: {
3205
+ stopOpacity: 1,
3206
+ stopColor: "#ff1791"
3207
+ }
3208
+ })]
3209
+ }), /* @__PURE__ */jsxs("linearGradient", {
3210
+ id: l,
3211
+ spreadMethod: "pad",
3212
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
3213
+ gradientUnits: "userSpaceOnUse",
3214
+ y2: 0,
3215
+ x2: 1,
3216
+ y1: 0,
3217
+ x1: 0,
3218
+ children: [/* @__PURE__ */jsx("stop", {
3219
+ offset: 0,
3220
+ style: {
3221
+ stopOpacity: 1,
3222
+ stopColor: "#ff4e00"
3223
+ }
3224
+ }), /* @__PURE__ */jsx("stop", {
3225
+ offset: 1,
3226
+ style: {
3227
+ stopOpacity: 1,
3228
+ stopColor: "#ff1791"
3229
+ }
3230
+ })]
3231
+ }), /* @__PURE__ */jsxs("linearGradient", {
3232
+ id: m,
3233
+ spreadMethod: "pad",
3234
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 94.554)",
3235
+ gradientUnits: "userSpaceOnUse",
3236
+ y2: 0,
3237
+ x2: 1,
3238
+ y1: 0,
3239
+ x1: 0,
3240
+ children: [/* @__PURE__ */jsx("stop", {
3241
+ offset: 0,
3242
+ style: {
3243
+ stopOpacity: 1,
3244
+ stopColor: "#ff4e00"
3245
+ }
3246
+ }), /* @__PURE__ */jsx("stop", {
3247
+ offset: 1,
3248
+ style: {
3249
+ stopOpacity: 1,
3250
+ stopColor: "#ff1791"
3251
+ }
3252
+ })]
3253
+ }), /* @__PURE__ */jsxs("linearGradient", {
3254
+ id: p,
3255
+ spreadMethod: "pad",
3256
+ gradientTransform: "matrix(521.97632 0 0 -521.97632 69.067 191.973)",
3257
+ gradientUnits: "userSpaceOnUse",
3258
+ y2: 0,
3259
+ x2: 1,
3260
+ y1: 0,
3261
+ x1: 0,
3262
+ children: [/* @__PURE__ */jsx("stop", {
3263
+ offset: 0,
3264
+ style: {
3265
+ stopOpacity: 1,
3266
+ stopColor: "#ff4e00"
3267
+ }
3268
+ }), /* @__PURE__ */jsx("stop", {
3269
+ offset: 1,
3270
+ style: {
3271
+ stopOpacity: 1,
3272
+ stopColor: "#ff1791"
3273
+ }
3274
+ })]
3275
+ }), /* @__PURE__ */jsxs("linearGradient", {
3276
+ id: q,
3277
+ spreadMethod: "pad",
3278
+ gradientTransform: "matrix(523.09039 0 0 -523.09039 67.312 191.973)",
3279
+ gradientUnits: "userSpaceOnUse",
3280
+ y2: 0,
3281
+ x2: 1,
3282
+ y1: 0,
3283
+ x1: 0,
3284
+ children: [/* @__PURE__ */jsx("stop", {
3285
+ offset: 0,
3286
+ style: {
3287
+ stopOpacity: 1,
3288
+ stopColor: "#ff4e00"
3289
+ }
3290
+ }), /* @__PURE__ */jsx("stop", {
3291
+ offset: 1,
3292
+ style: {
3293
+ stopOpacity: 1,
3294
+ stopColor: "#ff1791"
3295
+ }
3296
+ })]
3297
+ }), /* @__PURE__ */jsxs("linearGradient", {
3298
+ id: r,
3299
+ spreadMethod: "pad",
3300
+ gradientTransform: "matrix(524.84045 0 0 -524.84045 63.801 159.5)",
3301
+ gradientUnits: "userSpaceOnUse",
3302
+ y2: 0,
3303
+ x2: 1,
3304
+ y1: 0,
3305
+ x1: 0,
3306
+ children: [/* @__PURE__ */jsx("stop", {
3307
+ offset: 0,
3308
+ style: {
3309
+ stopOpacity: 1,
3310
+ stopColor: "#ff4e00"
3311
+ }
3312
+ }), /* @__PURE__ */jsx("stop", {
3313
+ offset: 1,
3314
+ style: {
3315
+ stopOpacity: 1,
3316
+ stopColor: "#ff1791"
3317
+ }
3318
+ })]
3319
+ }), /* @__PURE__ */jsx("clipPath", {
3320
+ id: a,
3321
+ clipPathUnits: "userSpaceOnUse",
3322
+ children: /* @__PURE__ */jsx("path", {
3323
+ d: "M0 319h657.706V0H0Z"
3324
+ })
3325
+ }), /* @__PURE__ */jsx("clipPath", {
3326
+ id: b,
3327
+ clipPathUnits: "userSpaceOnUse",
3328
+ children: /* @__PURE__ */jsx("path", {
3329
+ d: "M423.64 242h164.999V77H423.64Z"
3330
+ })
3331
+ }), /* @__PURE__ */jsx("clipPath", {
3332
+ id: e,
3333
+ clipPathUnits: "userSpaceOnUse",
3334
+ children: /* @__PURE__ */jsx("path", {
3335
+ d: "M0 319h657.706V0H0Z"
3336
+ })
3337
+ }), /* @__PURE__ */jsx("clipPath", {
3338
+ id: f,
3339
+ clipPathUnits: "userSpaceOnUse",
3340
+ children: /* @__PURE__ */jsx("path", {
3341
+ d: "M311.3 242h93.031V77H311.3Z"
3342
+ })
3343
+ }), /* @__PURE__ */jsx("clipPath", {
3344
+ id: h,
3345
+ clipPathUnits: "userSpaceOnUse",
3346
+ children: /* @__PURE__ */jsx("path", {
3347
+ d: "M198.96 242h35.106V77H198.96Z"
3348
+ })
3349
+ }), /* @__PURE__ */jsx("clipPath", {
3350
+ id: n,
3351
+ clipPathUnits: "userSpaceOnUse",
3352
+ children: /* @__PURE__ */jsx("path", {
3353
+ d: "M0 319h657.706V0H0Z"
3354
+ })
3355
+ }), /* @__PURE__ */jsx("clipPath", {
3356
+ id: o,
3357
+ clipPathUnits: "userSpaceOnUse",
3358
+ children: /* @__PURE__ */jsx("path", {
3359
+ d: "M69.067 242H169.12V141.947H69.067Z"
3360
+ })
3361
+ })]
3362
+ }), /* @__PURE__ */jsx("g", {
3363
+ clipPath: "url(#".concat(a, ")"),
3364
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
3365
+ children: /* @__PURE__ */jsx("g", {
3366
+ style: {
3367
+ opacity: 0.69999701
3368
+ },
3369
+ clipPath: "url(#".concat(b, ")"),
3370
+ children: /* @__PURE__ */jsx("path", {
3371
+ style: {
3372
+ fill: "url(#".concat(c, ")"),
3373
+ stroke: "none"
3374
+ },
3375
+ 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"
3376
+ })
3377
+ })
3378
+ }), /* @__PURE__ */jsx("path", {
3379
+ style: {
3380
+ fill: "url(#".concat(d, ")"),
3381
+ stroke: "none"
3382
+ },
3383
+ 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",
3384
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3385
+ }), /* @__PURE__ */jsxs("g", {
3386
+ clipPath: "url(#".concat(e, ")"),
3387
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
3388
+ children: [/* @__PURE__ */jsx("g", {
3389
+ style: {
3390
+ opacity: 0.69999701
3391
+ },
3392
+ clipPath: "url(#".concat(f, ")"),
3393
+ children: /* @__PURE__ */jsx("path", {
3394
+ style: {
3395
+ fill: "url(#".concat(g, ")"),
3396
+ stroke: "none"
3397
+ },
3398
+ 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"
3399
+ })
3400
+ }), /* @__PURE__ */jsx("g", {
3401
+ style: {
3402
+ opacity: 0.69999701
3403
+ },
3404
+ clipPath: "url(#".concat(h, ")"),
3405
+ children: /* @__PURE__ */jsx("path", {
3406
+ style: {
3407
+ fill: "url(#".concat(i, ")"),
3408
+ stroke: "none"
3409
+ },
3410
+ 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"
3411
+ })
3412
+ })]
3413
+ }), /* @__PURE__ */jsx("path", {
3414
+ style: {
3415
+ fill: "url(#".concat(j, ")"),
3416
+ stroke: "none"
3417
+ },
3418
+ 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",
3419
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3420
+ }), /* @__PURE__ */jsx("path", {
3421
+ style: {
3422
+ fill: "url(#".concat(k, ")"),
3423
+ stroke: "none"
3424
+ },
3425
+ 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",
3426
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3427
+ }), /* @__PURE__ */jsx("path", {
3428
+ style: {
3429
+ fill: "url(#".concat(l, ")"),
3430
+ stroke: "none"
3431
+ },
3432
+ 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",
3433
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3434
+ }), /* @__PURE__ */jsx("path", {
3435
+ style: {
3436
+ fill: "url(#".concat(m, ")"),
3437
+ stroke: "none"
3438
+ },
3439
+ 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",
3440
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3441
+ }), /* @__PURE__ */jsx("g", {
3442
+ clipPath: "url(#".concat(n, ")"),
3443
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)",
3444
+ children: /* @__PURE__ */jsx("g", {
3445
+ style: {
3446
+ opacity: 0.69999701
3447
+ },
3448
+ clipPath: "url(#".concat(o, ")"),
3449
+ children: /* @__PURE__ */jsx("path", {
3450
+ style: {
3451
+ fill: "url(#".concat(p, ")"),
3452
+ stroke: "none"
3453
+ },
3454
+ 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"
3455
+ })
3456
+ })
3457
+ }), /* @__PURE__ */jsx("path", {
3458
+ style: {
3459
+ fill: "url(#".concat(q, ")"),
3460
+ stroke: "none"
3461
+ },
3462
+ 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",
3463
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3464
+ }), /* @__PURE__ */jsx("path", {
3465
+ style: {
3466
+ fill: "url(#".concat(r, ")"),
3467
+ stroke: "none"
3468
+ },
3469
+ 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",
3470
+ transform: "matrix(1.33333 0 0 -1.33333 0 425.333)"
3471
+ })]
3472
+ });
3473
+ }
3474
+ var __freeze = Object.freeze;
3475
+ var __defProp = Object.defineProperty;
3476
+ var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", {
3477
+ value: __freeze(raw || cooked.slice())
3478
+ }));
3479
+ var _a;
3480
+ const Logo = styled.span(_a || (_a = __template(["\n display: inline-block;\n height: 0.8em;\n margin-right: 1em;\n transform: translate(0.3em, -0.2em);\n"])));
3481
+ const Header = () => /* @__PURE__ */jsxs(Fragment, {
3482
+ children: [/* @__PURE__ */jsx(Logo, {
3483
+ children: /* @__PURE__ */jsx(MuxLogo, {
3484
+ height: 13
3485
+ })
3486
+ }), "API Credentials"]
3487
+ });
3488
+ const fieldNames = ["token", "secretKey", "enableSignedUrls"];
3489
+ function ConfigureApi(_ref24) {
3490
+ let {
3491
+ secrets,
3492
+ setDialogState
3493
+ } = _ref24;
3494
+ var _a, _b;
3495
+ const client = useClient();
3496
+ const [state, dispatch] = useSecretsFormState(secrets);
3497
+ const hasSecretsInitially = useMemo(() => secrets.token && secrets.secretKey, [secrets]);
3498
+ const handleClose = useCallback(() => setDialogState(false), [setDialogState]);
3499
+ const dirty = useMemo(() => secrets.token !== state.token || secrets.secretKey !== state.secretKey || secrets.enableSignedUrls !== state.enableSignedUrls, [secrets, state]);
3500
+ const id = "ConfigureApi".concat(useId());
3501
+ const [tokenId, secretKeyId, enableSignedUrlsId] = useMemo(() => fieldNames.map(field => "".concat(id, "-").concat(field)), [id]);
3502
+ const firstField = useRef(null);
3503
+ const handleSaveSecrets = useSaveSecrets(client, secrets);
3504
+ const saving = useRef(false);
3505
+ const handleSubmit = useCallback(event => {
3506
+ event.preventDefault();
3507
+ if (!saving.current && event.currentTarget.reportValidity()) {
3508
+ saving.current = true;
3509
+ dispatch({
3510
+ type: "submit"
3511
+ });
3512
+ const {
3513
+ token,
3514
+ secretKey,
3515
+ enableSignedUrls
3516
+ } = state;
3517
+ handleSaveSecrets({
3518
+ token,
3519
+ secretKey,
3520
+ enableSignedUrls
3521
+ }).then(savedSecrets => {
3522
+ const {
3523
+ projectId,
3524
+ dataset
3525
+ } = client.config();
3526
+ clear([cacheNs, _id, projectId, dataset]);
3527
+ preload(() => Promise.resolve(savedSecrets), [cacheNs, _id, projectId, dataset]);
3528
+ setDialogState(false);
3529
+ }).catch(err => dispatch({
3530
+ type: "error",
3531
+ payload: err.message
3532
+ })).finally(() => {
3533
+ saving.current = false;
3534
+ });
3535
+ }
3536
+ }, [client, dispatch, handleSaveSecrets, setDialogState, state]);
3537
+ const handleChangeToken = useCallback(event => {
3538
+ dispatch({
3539
+ type: "change",
3540
+ payload: {
3541
+ name: "token",
3542
+ value: event.currentTarget.value
3543
+ }
3544
+ });
3545
+ }, [dispatch]);
3546
+ const handleChangeSecretKey = useCallback(event => {
3547
+ dispatch({
3548
+ type: "change",
3549
+ payload: {
3550
+ name: "secretKey",
3551
+ value: event.currentTarget.value
3552
+ }
3553
+ });
3554
+ }, [dispatch]);
3555
+ const handleChangeEnableSignedUrls = useCallback(event => {
3556
+ dispatch({
3557
+ type: "change",
3558
+ payload: {
3559
+ name: "enableSignedUrls",
3560
+ value: event.currentTarget.checked
3561
+ }
3562
+ });
3563
+ }, [dispatch]);
3564
+ useEffect(() => {
3565
+ if (firstField.current) {
3566
+ firstField.current.focus();
3567
+ }
3568
+ }, [firstField]);
3569
+ return /* @__PURE__ */jsx(Dialog, {
3570
+ id,
3571
+ onClose: handleClose,
3572
+ header: /* @__PURE__ */jsx(Header, {}),
3573
+ width: 1,
3574
+ style: {
3575
+ maxWidth: "550px"
3576
+ },
3577
+ children: /* @__PURE__ */jsx(Box, {
3578
+ padding: 4,
3579
+ style: {
3580
+ position: "relative"
3581
+ },
3582
+ children: /* @__PURE__ */jsx("form", {
3583
+ onSubmit: handleSubmit,
3584
+ noValidate: true,
3585
+ children: /* @__PURE__ */jsxs(Stack, {
3586
+ space: 4,
3587
+ children: [!hasSecretsInitially && /* @__PURE__ */jsx(Card, {
3588
+ padding: [3, 3, 3],
3589
+ radius: 2,
3590
+ shadow: 1,
3591
+ tone: "primary",
3592
+ children: /* @__PURE__ */jsxs(Stack, {
3593
+ space: 3,
3594
+ children: [/* @__PURE__ */jsxs(Text, {
3595
+ size: 1,
3596
+ children: ["To set up a new access token, go to your", " ", /* @__PURE__ */jsx("a", {
3597
+ href: "https://dashboard.mux.com/settings/access-tokens",
3598
+ target: "_blank",
3599
+ rel: "noreferrer noopener",
3600
+ children: "account on mux.com"
3601
+ }), "."]
3602
+ }), /* @__PURE__ */jsxs(Text, {
3603
+ size: 1,
3604
+ children: ["The access token needs permissions: ", /* @__PURE__ */jsx("strong", {
3605
+ children: "Mux Video "
3606
+ }), "(Full Access) and ", /* @__PURE__ */jsx("strong", {
3607
+ children: "Mux Data"
3608
+ }), " (Read)", /* @__PURE__ */jsx("br", {}), "The credentials will be stored safely in a hidden document only available to editors."]
3609
+ })]
3610
+ })
3611
+ }), /* @__PURE__ */jsx(FormField$1, {
3612
+ title: "Access Token",
3613
+ inputId: tokenId,
3614
+ children: /* @__PURE__ */jsx(TextInput, {
3615
+ id: tokenId,
3616
+ ref: firstField,
3617
+ onChange: handleChangeToken,
3618
+ type: "text",
3619
+ value: (_a = state.token) != null ? _a : "",
3620
+ required: !!state.secretKey || state.enableSignedUrls
3621
+ })
3622
+ }), /* @__PURE__ */jsx(FormField$1, {
3623
+ title: "Secret Key",
3624
+ inputId: secretKeyId,
3625
+ children: /* @__PURE__ */jsx(TextInput, {
3626
+ id: secretKeyId,
3627
+ onChange: handleChangeSecretKey,
3628
+ type: "text",
3629
+ value: (_b = state.secretKey) != null ? _b : "",
3630
+ required: !!state.token || state.enableSignedUrls
3631
+ })
3632
+ }), /* @__PURE__ */jsxs(Stack, {
3633
+ space: 4,
3634
+ children: [/* @__PURE__ */jsxs(Flex, {
3635
+ align: "center",
3636
+ children: [/* @__PURE__ */jsx(Checkbox, {
3637
+ id: enableSignedUrlsId,
3638
+ onChange: handleChangeEnableSignedUrls,
3639
+ checked: state.enableSignedUrls,
3640
+ style: {
3641
+ display: "block"
3642
+ }
3643
+ }), /* @__PURE__ */jsx(Box, {
3644
+ flex: 1,
3645
+ paddingLeft: 3,
3646
+ children: /* @__PURE__ */jsx(Text, {
3647
+ children: /* @__PURE__ */jsx("label", {
3648
+ htmlFor: enableSignedUrlsId,
3649
+ children: "Enable Signed Urls"
3650
+ })
3651
+ })
3652
+ })]
3653
+ }), secrets.signingKeyId && state.enableSignedUrls ? /* @__PURE__ */jsx(Card, {
3654
+ padding: [3, 3, 3],
3655
+ radius: 2,
3656
+ shadow: 1,
3657
+ tone: "caution",
3658
+ children: /* @__PURE__ */jsxs(Stack, {
3659
+ space: 3,
3660
+ children: [/* @__PURE__ */jsx(Text, {
3661
+ size: 1,
3662
+ children: "The signing key ID that Sanity will use is:"
3663
+ }), /* @__PURE__ */jsx(Code, {
3664
+ size: 1,
3665
+ children: secrets.signingKeyId
3666
+ }), /* @__PURE__ */jsxs(Text, {
3667
+ size: 1,
3668
+ 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."]
3669
+ })]
3670
+ })
3671
+ }) : null]
3672
+ }), /* @__PURE__ */jsxs(Inline, {
3673
+ space: 2,
3674
+ children: [/* @__PURE__ */jsx(Button, {
3675
+ text: "Save",
3676
+ disabled: !dirty,
3677
+ loading: state.submitting,
3678
+ tone: "primary",
3679
+ mode: "default",
3680
+ type: "submit"
3681
+ }), /* @__PURE__ */jsx(Button, {
3682
+ disabled: state.submitting,
3683
+ text: "Cancel",
3684
+ mode: "bleed",
3685
+ onClick: handleClose
3686
+ })]
3687
+ }), state.error && /* @__PURE__ */jsx(Card, {
3688
+ padding: [3, 3, 3],
3689
+ radius: 2,
3690
+ shadow: 1,
3691
+ tone: "critical",
3692
+ children: /* @__PURE__ */jsx(Text, {
3693
+ children: state.error
3694
+ })
3695
+ })]
3696
+ })
3697
+ })
3698
+ })
3699
+ });
3700
+ }
3701
+ var ConfigureApi$1 = memo(ConfigureApi);
3702
+ function ErrorBoundaryCard(props) {
3703
+ const {
3704
+ children,
3705
+ schemaType
3706
+ } = props;
3707
+ const {
3708
+ push: pushToast
3709
+ } = useToast();
3710
+ const errorRef = useRef(null);
3711
+ const {
3712
+ ErrorBoundary,
3713
+ didCatch,
3714
+ error,
3715
+ reset
3716
+ } = useErrorBoundary({
3717
+ onDidCatch: (err, errorInfo) => {
3718
+ console.group(err.toString());
3719
+ console.groupCollapsed("console.error");
3720
+ console.error(err);
3721
+ console.groupEnd();
3722
+ if (err.stack) {
3723
+ console.groupCollapsed("error.stack");
3724
+ console.log(err.stack);
3725
+ console.groupEnd();
3726
+ }
3727
+ if (errorInfo == null ? void 0 : errorInfo.componentStack) {
3728
+ console.groupCollapsed("errorInfo.componentStack");
3729
+ console.log(errorInfo.componentStack);
3730
+ console.groupEnd();
3731
+ }
3732
+ console.groupEnd();
3733
+ pushToast({
3734
+ status: "error",
3735
+ title: "Plugin crashed",
3736
+ description: /* @__PURE__ */jsx(Flex, {
3737
+ align: "center",
3738
+ children: /* @__PURE__ */jsxs(Inline, {
3739
+ space: 1,
3740
+ children: ["An error happened while rendering", /* @__PURE__ */jsx(Button, {
3741
+ padding: 1,
3742
+ fontSize: 1,
3743
+ style: {
3744
+ transform: "translateY(1px)"
3745
+ },
3746
+ mode: "ghost",
3747
+ text: schemaType.title,
3748
+ onClick: () => {
3749
+ if (errorRef.current) {
3750
+ scrollIntoView(errorRef.current, {
3751
+ behavior: "smooth",
3752
+ scrollMode: "if-needed",
3753
+ block: "center"
3754
+ });
3755
+ }
3756
+ }
3757
+ })]
3758
+ })
3759
+ })
3760
+ });
3761
+ }
3762
+ });
3763
+ const handleRetry = useCallback(() => {
3764
+ clear([name$1]);
3765
+ reset();
3766
+ }, [reset]);
3767
+ if (didCatch) {
3768
+ return /* @__PURE__ */jsx(Card, {
3769
+ ref: errorRef,
3770
+ paddingX: [2, 3, 4, 4],
3771
+ height: "fill",
3772
+ shadow: 1,
3773
+ overflow: "auto",
3774
+ children: /* @__PURE__ */jsx(Flex, {
3775
+ justify: "flex-start",
3776
+ align: "center",
3777
+ height: "fill",
3778
+ children: /* @__PURE__ */jsxs(Grid, {
3779
+ columns: 1,
3780
+ gap: [2, 3, 4, 4],
3781
+ children: [/* @__PURE__ */jsxs(Heading, {
3782
+ as: "h1",
3783
+ children: ["The ", /* @__PURE__ */jsx("code", {
3784
+ children: name$1
3785
+ }), " plugin crashed"]
3786
+ }), (error == null ? void 0 : error.message) && /* @__PURE__ */jsx(Card, {
3787
+ padding: 3,
3788
+ tone: "critical",
3789
+ shadow: 1,
3790
+ radius: 2,
3791
+ children: /* @__PURE__ */jsx(Text, {
3792
+ children: error.message
3793
+ })
3794
+ }), /* @__PURE__ */jsx(Inline, {
3795
+ children: /* @__PURE__ */jsx(Button, {
3796
+ onClick: handleRetry,
3797
+ text: "Retry"
3798
+ })
3799
+ })]
3800
+ })
3801
+ })
3802
+ });
3803
+ }
3804
+ return /* @__PURE__ */jsx(ErrorBoundary, {
3805
+ children
3806
+ });
3807
+ }
3808
+ var ErrorBoundaryCard$1 = memo(ErrorBoundaryCard);
3809
+ const InputFallback = () => {
3810
+ return /* @__PURE__ */jsx("div", {
3811
+ style: {
3812
+ padding: 1
3813
+ },
3814
+ children: /* @__PURE__ */jsx(Card, {
3815
+ shadow: 1,
3816
+ sizing: "border",
3817
+ style: {
3818
+ aspectRatio: "16/9",
3819
+ width: "100%",
3820
+ borderRadius: "1px"
3821
+ },
3822
+ children: /* @__PURE__ */jsxs(Flex, {
3823
+ align: "center",
3824
+ direction: "column",
3825
+ height: "fill",
3826
+ justify: "center",
3827
+ children: [/* @__PURE__ */jsx(Spinner, {
3828
+ muted: true
3829
+ }), /* @__PURE__ */jsx(Box, {
3830
+ marginTop: 3,
3831
+ children: /* @__PURE__ */jsx(Text, {
3832
+ align: "center",
3833
+ muted: true,
3834
+ size: 1,
3835
+ children: "Loading\u2026"
3836
+ })
3837
+ })]
3838
+ })
3839
+ })
3840
+ });
3841
+ };
3842
+ function Onboard(props) {
3843
+ const {
3844
+ setDialogState
3845
+ } = props;
3846
+ const handleOpen = useCallback(() => setDialogState("secrets"), [setDialogState]);
3847
+ return /* @__PURE__ */jsx(Fragment, {
3848
+ children: /* @__PURE__ */jsx("div", {
3849
+ style: {
3850
+ padding: 2
3851
+ },
3852
+ children: /* @__PURE__ */jsx(Card, {
3853
+ display: "flex",
3854
+ sizing: "border",
3855
+ style: {
3856
+ aspectRatio: "16/9",
3857
+ width: "100%",
3858
+ boxShadow: "var(--card-bg-color) 0 0 0 2px"
3859
+ },
3860
+ paddingX: [2, 3, 4, 4],
3861
+ radius: 1,
3862
+ tone: "transparent",
3863
+ children: /* @__PURE__ */jsx(Flex, {
3864
+ justify: "flex-start",
3865
+ align: "center",
3866
+ children: /* @__PURE__ */jsxs(Grid, {
3867
+ columns: 1,
3868
+ gap: [2, 3, 4, 4],
3869
+ children: [/* @__PURE__ */jsx(Inline, {
3870
+ paddingY: 1,
3871
+ children: /* @__PURE__ */jsx("div", {
3872
+ style: {
3873
+ height: "32px"
3874
+ },
3875
+ children: /* @__PURE__ */jsx(MuxLogo, {})
3876
+ })
3877
+ }), /* @__PURE__ */jsx(Inline, {
3878
+ paddingY: 1,
3879
+ children: /* @__PURE__ */jsx(Heading, {
3880
+ size: [0, 1, 2, 2],
3881
+ children: "Upload and preview videos directly from your studio."
3882
+ })
3883
+ }), /* @__PURE__ */jsx(Inline, {
3884
+ paddingY: 1,
3885
+ children: /* @__PURE__ */jsx(Button, {
3886
+ mode: "ghost",
3887
+ icon: PlugIcon,
3888
+ text: "Configure API",
3889
+ onClick: handleOpen
3890
+ })
3891
+ })]
3892
+ })
3893
+ })
3894
+ })
3895
+ })
3896
+ });
3897
+ }
3898
+ const Input = props => {
3899
+ var _a;
3900
+ const client = useClient();
3901
+ const secretDocumentValues = useSecretsDocumentValues();
3902
+ const assetDocumentValues = useAssetDocumentValues((_a = props.value) == null ? void 0 : _a.asset);
3903
+ const poll = useMuxPolling(props.readOnly ? void 0 : (assetDocumentValues == null ? void 0 : assetDocumentValues.value) || void 0);
3904
+ const [dialogState, setDialogState] = useDialogState();
3905
+ const error = secretDocumentValues.error || assetDocumentValues.error || poll.error;
3906
+ if (error) {
3907
+ throw error;
3908
+ }
3909
+ const isLoading = secretDocumentValues.isLoading || assetDocumentValues.isLoading;
3910
+ return /* @__PURE__ */jsx(Card, {
3911
+ children: /* @__PURE__ */jsx(ErrorBoundaryCard$1, {
3912
+ schemaType: props.schemaType,
3913
+ children: /* @__PURE__ */jsx(Suspense, {
3914
+ fallback: /* @__PURE__ */jsx(InputFallback, {}),
3915
+ children: isLoading ? /* @__PURE__ */jsx(InputFallback, {}) : /* @__PURE__ */jsxs(Fragment, {
3916
+ children: [secretDocumentValues.value.needsSetup && !assetDocumentValues.value ? /* @__PURE__ */jsx(Onboard, {
3917
+ setDialogState
3918
+ }) : /* @__PURE__ */jsx(MuxVideoInputUploader, {
3919
+ ...props,
3920
+ config: props.config,
3921
+ onChange: props.onChange,
3922
+ client,
3923
+ secrets: secretDocumentValues.value.secrets,
3924
+ asset: assetDocumentValues.value,
3925
+ dialogState,
3926
+ setDialogState,
3927
+ needsSetup: secretDocumentValues.value.needsSetup
3928
+ }), dialogState === "secrets" && /* @__PURE__ */jsx(ConfigureApi$1, {
3929
+ setDialogState,
3930
+ secrets: secretDocumentValues.value.secrets
3931
+ })]
3932
+ })
3933
+ })
3934
+ })
3935
+ });
3936
+ };
3937
+ var Input$1 = memo(Input);
3938
+ function muxVideoCustomRendering(config) {
3939
+ return {
3940
+ components: {
3941
+ input: props => /* @__PURE__ */jsx(Input$1, {
3942
+ config,
3943
+ ...props
3944
+ })
3945
+ },
3946
+ preview: {
3947
+ select: {
3948
+ filename: "asset.filename",
3949
+ playbackId: "asset.playbackId",
3950
+ status: "asset.status",
3951
+ assetId: "asset.assetId",
3952
+ thumbTime: "asset.thumbTime",
3953
+ data: "asset.data"
3954
+ },
3955
+ prepare: asset => {
3956
+ const {
3957
+ filename,
3958
+ playbackId,
3959
+ status
3960
+ } = asset;
3961
+ return {
3962
+ title: filename || playbackId || "",
3963
+ subtitle: status ? "status: ".concat(status) : null,
3964
+ media: asset.playbackId ? /* @__PURE__ */jsx(VideoThumbnail, {
3965
+ asset,
3966
+ width: 64
3967
+ }) : null
3968
+ };
3969
+ }
3970
+ }
3971
+ };
3972
+ }
3973
+ const muxVideo = {
3974
+ name: "mux.video",
3975
+ type: "object",
3976
+ title: "Video asset reference",
3977
+ fields: [{
3978
+ title: "Video",
3979
+ name: "asset",
3980
+ type: "reference",
3981
+ weak: true,
3982
+ to: [{
3983
+ type: "mux.videoAsset"
3984
+ }]
3985
+ }]
3986
+ };
3987
+ const muxVideoAsset = {
3988
+ name: "mux.videoAsset",
3989
+ type: "object",
3990
+ title: "Video asset",
3991
+ fields: [{
3992
+ type: "string",
3993
+ name: "status"
3994
+ }, {
3995
+ type: "string",
3996
+ name: "assetId"
3997
+ }, {
3998
+ type: "string",
3999
+ name: "playbackId"
4000
+ }, {
4001
+ type: "string",
4002
+ name: "filename"
4003
+ }, {
4004
+ type: "number",
4005
+ name: "thumbTime"
4006
+ }]
4007
+ };
4008
+ const defaultConfig = {
4009
+ mp4_support: "none"
4010
+ };
4011
+ const muxInput = definePlugin(userConfig => {
4012
+ const config = {
4013
+ ...defaultConfig,
4014
+ ...userConfig
4015
+ };
4016
+ return {
4017
+ name: "mux-input",
4018
+ schema: {
4019
+ types: [muxVideoAsset, {
4020
+ ...muxVideo,
4021
+ ...muxVideoCustomRendering(config)
4022
+ }]
4023
+ },
4024
+ tools: config.tool === false ? void 0 : [createStudioTool(config)]
4025
+ };
4026
+ });
4027
+ export { defaultConfig, muxInput };
3
4028
  //# sourceMappingURL=index.js.map