sanity-plugin-mux-input 2.1.1 → 2.2.0

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