sanity-plugin-mux-input 3.0.3 → 3.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -2
- package/dist/index.cjs +2876 -4400
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +134 -193
- package/dist/index.d.cts.map +1 -0
- package/dist/index.d.ts +134 -193
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +2877 -4401
- package/dist/index.js.map +1 -1
- package/package.json +40 -40
- package/src/_exports/index.ts +1 -1
- package/src/actions/assets.ts +5 -5
- package/src/actions/secrets.ts +5 -6
- package/src/actions/upload.ts +32 -34
- package/src/components/AddCaptionDialog.tsx +3 -3
- package/src/components/ConfigureApi.tsx +7 -7
- package/src/components/DraggableWatermark.tsx +15 -7
- package/src/components/EditCaptionDialog.tsx +6 -5
- package/src/components/EditThumbnailDialog.tsx +4 -5
- package/src/components/ErrorBoundaryCard.tsx +1 -0
- package/src/components/FileInputButton.tsx +1 -1
- package/src/components/FileInputMenuItem.tsx +10 -10
- package/src/components/ImportVideosFromMux.tsx +0 -3
- package/src/components/MuxLogo.tsx +1 -1
- package/src/components/Onboard.tsx +1 -1
- package/src/components/PageSelector.tsx +1 -1
- package/src/components/Player.styled.tsx +0 -44
- package/src/components/Player.tsx +1 -1
- package/src/components/PlayerActionsMenu.tsx +3 -2
- package/src/components/ResyncMetadata.tsx +4 -6
- package/src/components/SelectAsset.tsx +2 -2
- package/src/components/SelectSortOptions.tsx +3 -3
- package/src/components/TextTracksEditor.tsx +2 -2
- package/src/components/TextTracksManager.tsx +5 -4
- package/src/components/UploadConfiguration.tsx +17 -15
- package/src/components/UploadPlaceholder.tsx +1 -1
- package/src/components/UploadProgress.tsx +4 -4
- package/src/components/Uploader.styled.tsx +1 -2
- package/src/components/Uploader.tsx +15 -14
- package/src/components/VideoDetails/DeleteDialog.tsx +2 -1
- package/src/components/VideoDetails/VideoDetails.tsx +3 -3
- package/src/components/VideoDetails/useVideoDetails.ts +2 -2
- package/src/components/VideoInBrowser.tsx +1 -1
- package/src/components/VideoMetadata.tsx +1 -1
- package/src/components/VideoPlayer.tsx +12 -6
- package/src/components/VideoThumbnail.tsx +4 -3
- package/src/components/VideosBrowser.tsx +1 -1
- package/src/components/documentPreview/DocumentPreview.tsx +4 -3
- package/src/components/documentPreview/PaneItemPreview.tsx +5 -12
- package/src/components/uploadConfiguration/PlaybackPolicy.tsx +3 -3
- package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +2 -2
- package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +1 -1
- package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +2 -2
- package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +4 -4
- package/src/components/withFocusRing/withFocusRing.ts +1 -1
- package/src/context/DialogStateContext.tsx +3 -6
- package/src/context/DrmPlaybackWarningContext.tsx +14 -10
- package/src/hooks/useAccessControl.ts +1 -1
- package/src/hooks/useAssetDocumentValues.ts +2 -2
- package/src/hooks/useAssets.ts +11 -6
- package/src/hooks/useCancelUpload.ts +2 -2
- package/src/hooks/useDocReferences.ts +2 -2
- package/src/hooks/useFetchFileSize.ts +4 -3
- package/src/hooks/useImportMuxAssets.ts +3 -3
- package/src/hooks/useInView.ts +3 -4
- package/src/hooks/useMediaMetadata.ts +5 -4
- package/src/hooks/useMuxAssets.ts +15 -15
- package/src/hooks/useMuxPolling.ts +6 -3
- package/src/hooks/useResyncAsset.ts +1 -1
- package/src/hooks/useResyncMuxMetadata.ts +4 -11
- package/src/hooks/useSaveSecrets.ts +4 -4
- package/src/hooks/useSecretsDocumentValues.ts +1 -1
- package/src/util/asserters.ts +0 -13
- package/src/util/convertWatermarkToMux.ts +4 -4
- package/src/util/createUrlParamsObject.ts +3 -3
- package/src/util/extractFiles.ts +3 -3
- package/src/util/formatBytes.ts +0 -1
- package/src/util/formatSeconds.ts +0 -1
- package/src/util/generateJwt.ts +3 -3
- package/src/util/getAnimatedPosterSrc.ts +1 -1
- package/src/util/getPlaybackPolicy.ts +6 -6
- package/src/util/getPosterSrc.ts +1 -1
- package/src/util/pluginVersion.ts +5 -1
- package/src/util/readSecrets.ts +1 -1
- package/src/util/textTracks.ts +5 -5
- package/src/util/tryWithSuspend.ts +1 -1
- package/src/util/types.ts +2 -32
- package/src/components/InputError.tsx +0 -17
- package/src/components/documentPreview/paneItemTypes.ts +0 -7
- package/src/util/areSecretsSignable.ts +0 -5
- package/src/util/getStoryboardSrc.ts +0 -27
- package/src/util/isSigned.ts +0 -20
package/package.json
CHANGED
|
@@ -1,80 +1,82 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sanity-plugin-mux-input",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.5",
|
|
4
4
|
"description": "An input component that integrates Sanity Studio with Mux video encoding/hosting service.",
|
|
5
5
|
"keywords": [
|
|
6
|
-
"sanity",
|
|
7
|
-
"video",
|
|
8
|
-
"mux",
|
|
9
6
|
"input",
|
|
7
|
+
"media",
|
|
8
|
+
"mux",
|
|
10
9
|
"plugin",
|
|
10
|
+
"sanity",
|
|
11
11
|
"sanity-plugin",
|
|
12
|
-
"
|
|
12
|
+
"video"
|
|
13
13
|
],
|
|
14
14
|
"homepage": "https://github.com/sanity-io/plugins/tree/main/plugins/sanity-plugin-mux-input#readme",
|
|
15
15
|
"bugs": {
|
|
16
16
|
"url": "https://github.com/sanity-io/plugins/issues"
|
|
17
17
|
},
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"author": "Sanity.io <hello@sanity.io>",
|
|
18
20
|
"repository": {
|
|
19
21
|
"type": "git",
|
|
20
22
|
"url": "git+ssh://git@github.com/sanity-io/plugins.git",
|
|
21
23
|
"directory": "plugins/sanity-plugin-mux-input"
|
|
22
24
|
},
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
25
|
+
"files": [
|
|
26
|
+
"src",
|
|
27
|
+
"dist",
|
|
28
|
+
"sanity.json",
|
|
29
|
+
"v2-incompatible.js"
|
|
30
|
+
],
|
|
26
31
|
"type": "module",
|
|
32
|
+
"sideEffects": false,
|
|
33
|
+
"main": "./dist/index.cjs",
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
27
35
|
"exports": {
|
|
28
36
|
".": {
|
|
29
|
-
"source": "./src/_exports/index.ts",
|
|
30
37
|
"import": "./dist/index.js",
|
|
31
38
|
"require": "./dist/index.cjs",
|
|
32
39
|
"default": "./dist/index.js"
|
|
33
40
|
},
|
|
34
41
|
"./package.json": "./package.json"
|
|
35
42
|
},
|
|
36
|
-
"main": "./dist/index.cjs",
|
|
37
|
-
"types": "./dist/index.d.ts",
|
|
38
|
-
"files": [
|
|
39
|
-
"src",
|
|
40
|
-
"dist",
|
|
41
|
-
"sanity.json",
|
|
42
|
-
"v2-incompatible.js"
|
|
43
|
-
],
|
|
44
43
|
"dependencies": {
|
|
45
|
-
"@mux/mux-player": "^3.
|
|
46
|
-
"@mux/mux-player-react": "^3.
|
|
47
|
-
"@mux/upchunk": "^3.
|
|
44
|
+
"@mux/mux-player": "^3.13.0",
|
|
45
|
+
"@mux/mux-player-react": "^3.13.0",
|
|
46
|
+
"@mux/upchunk": "^3.5.0",
|
|
48
47
|
"@sanity/icons": "^3.7.4",
|
|
49
|
-
"@sanity/incompatible-plugin": "^1.0.
|
|
48
|
+
"@sanity/incompatible-plugin": "^1.0.5",
|
|
50
49
|
"@sanity/ui": "^3.2.0",
|
|
51
|
-
"@sanity/uuid": "^3.0.
|
|
52
|
-
"iso-639-1": "^3.1.
|
|
50
|
+
"@sanity/uuid": "^3.0.3",
|
|
51
|
+
"iso-639-1": "^3.1.5",
|
|
53
52
|
"jsonwebtoken-esm": "^1.0.5",
|
|
54
53
|
"lodash": "^4.17.21",
|
|
55
|
-
"react-rx": "^4.
|
|
56
|
-
"rxjs": "^7.8.
|
|
54
|
+
"react-rx": "^4.2.2",
|
|
55
|
+
"rxjs": "^7.8.2",
|
|
57
56
|
"scroll-into-view-if-needed": "^3.1.0",
|
|
58
57
|
"suspend-react": "^0.1.3",
|
|
59
|
-
"swr": "^2.
|
|
60
|
-
"type-fest": "^4.
|
|
58
|
+
"swr": "^2.4.1",
|
|
59
|
+
"type-fest": "^4.41.0",
|
|
61
60
|
"use-device-pixel-ratio": "^1.1.2",
|
|
62
61
|
"use-error-boundary": "^2.0.6"
|
|
63
62
|
},
|
|
64
63
|
"devDependencies": {
|
|
65
|
-
"@sanity/client": "^7.
|
|
64
|
+
"@sanity/client": "^7.23.0",
|
|
66
65
|
"@sanity/pkg-utils": "^10.5.7",
|
|
67
|
-
"@types/lodash": "^4.17.
|
|
66
|
+
"@types/lodash": "^4.17.24",
|
|
68
67
|
"@types/node": "^24.13.2",
|
|
69
|
-
"@types/react": "^19.
|
|
70
|
-
"@types/react-is": "^19.
|
|
71
|
-
"
|
|
72
|
-
"react
|
|
73
|
-
"react-
|
|
68
|
+
"@types/react": "^19.2.17",
|
|
69
|
+
"@types/react-is": "^19.2.0",
|
|
70
|
+
"babel-plugin-styled-components": "^2.3.0",
|
|
71
|
+
"react": "^19.2.7",
|
|
72
|
+
"react-dom": "^19.2.7",
|
|
73
|
+
"react-is": "^19.2.7",
|
|
74
74
|
"sanity": "^6.1.0",
|
|
75
|
-
"styled-components": "^6.
|
|
75
|
+
"styled-components": "^6.4.2",
|
|
76
76
|
"typescript": "5.9.3",
|
|
77
|
-
"@
|
|
77
|
+
"@repo/package.config": "0.0.0",
|
|
78
|
+
"@repo/tsconfig": "0.0.0",
|
|
79
|
+
"@sanity/plugin-kit": "5.0.2"
|
|
78
80
|
},
|
|
79
81
|
"peerDependencies": {
|
|
80
82
|
"react": "^18.3 || ^19",
|
|
@@ -85,13 +87,11 @@
|
|
|
85
87
|
"engines": {
|
|
86
88
|
"node": ">=20.19 <22 || >=22.12"
|
|
87
89
|
},
|
|
88
|
-
"publishConfig": {
|
|
89
|
-
"access": "public"
|
|
90
|
-
},
|
|
91
90
|
"sanityExchangeUrl": "https://www.sanity.io/plugins/sanity-plugin-mux-input",
|
|
92
|
-
"browserslist": "extends @sanity/browserslist-config",
|
|
93
91
|
"sanityPlugin": {
|
|
94
92
|
"verifyPackage": {
|
|
93
|
+
"tsc": false,
|
|
94
|
+
"tsconfig": false,
|
|
95
95
|
"srcIndex": false,
|
|
96
96
|
"scripts": false,
|
|
97
97
|
"eslintImports": false
|
package/src/_exports/index.ts
CHANGED
package/src/actions/assets.ts
CHANGED
|
@@ -26,14 +26,14 @@ export async function deleteAsset({
|
|
|
26
26
|
|
|
27
27
|
try {
|
|
28
28
|
await client.delete(asset._id)
|
|
29
|
-
} catch
|
|
29
|
+
} catch {
|
|
30
30
|
return 'failed-sanity'
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (deleteOnMux && asset?.assetId) {
|
|
34
34
|
try {
|
|
35
35
|
await deleteAssetOnMux(client, asset.assetId)
|
|
36
|
-
} catch
|
|
36
|
+
} catch {
|
|
37
37
|
return 'failed-mux'
|
|
38
38
|
}
|
|
39
39
|
}
|
|
@@ -53,7 +53,7 @@ export function getAsset(client: SanityClient, assetId: string) {
|
|
|
53
53
|
|
|
54
54
|
export function listAssets(
|
|
55
55
|
client: SanityClient,
|
|
56
|
-
options: {limit?: number; cursor?: string | null}
|
|
56
|
+
options: {limit?: number; cursor?: string | null},
|
|
57
57
|
) {
|
|
58
58
|
const {dataset} = client.config()
|
|
59
59
|
const query: {limit?: string; cursor?: string} = {}
|
|
@@ -84,7 +84,7 @@ export function addTextTrackFromUrl(
|
|
|
84
84
|
language_code: string
|
|
85
85
|
name: string
|
|
86
86
|
text_type?: 'subtitles'
|
|
87
|
-
}
|
|
87
|
+
},
|
|
88
88
|
) {
|
|
89
89
|
const {dataset} = client.config()
|
|
90
90
|
|
|
@@ -116,7 +116,7 @@ export function generateSubtitles(
|
|
|
116
116
|
options: {
|
|
117
117
|
language_code: string
|
|
118
118
|
name: string
|
|
119
|
-
}
|
|
119
|
+
},
|
|
120
120
|
) {
|
|
121
121
|
const {dataset} = client.config()
|
|
122
122
|
return client.request<{data: MuxAsset}>({
|
package/src/actions/secrets.ts
CHANGED
|
@@ -13,7 +13,6 @@ interface SecretsDocument {
|
|
|
13
13
|
signingKeyPrivate: string
|
|
14
14
|
drmConfigId: string
|
|
15
15
|
}
|
|
16
|
-
// eslint-disable-next-line max-params
|
|
17
16
|
export function saveSecrets(
|
|
18
17
|
client: SanityClient,
|
|
19
18
|
token: string,
|
|
@@ -21,7 +20,7 @@ export function saveSecrets(
|
|
|
21
20
|
enableSignedUrls: boolean,
|
|
22
21
|
signingKeyId: string,
|
|
23
22
|
signingKeyPrivate: string,
|
|
24
|
-
drmConfigId: string
|
|
23
|
+
drmConfigId: string,
|
|
25
24
|
): Promise<SecretsDocument> {
|
|
26
25
|
const doc: SecretsDocument = {
|
|
27
26
|
_id: 'secrets.mux',
|
|
@@ -57,7 +56,7 @@ export async function createSigningKeys(client: SanityClient) {
|
|
|
57
56
|
error.response?.statusCode === 401
|
|
58
57
|
? 'Unauthorized - Failed to create the Signing Key. Please ensure that the token has "System" permissions'
|
|
59
58
|
: error.message
|
|
60
|
-
throw new Error(message)
|
|
59
|
+
throw new Error(message, {cause: error})
|
|
61
60
|
}
|
|
62
61
|
}
|
|
63
62
|
|
|
@@ -74,7 +73,7 @@ export function testSecrets(client: SanityClient) {
|
|
|
74
73
|
export async function haveValidSigningKeys(
|
|
75
74
|
client: SanityClient,
|
|
76
75
|
signingKeyId: string,
|
|
77
|
-
signingKeyPrivate: string
|
|
76
|
+
signingKeyPrivate: string,
|
|
78
77
|
) {
|
|
79
78
|
if (!(signingKeyId && signingKeyPrivate)) {
|
|
80
79
|
return false
|
|
@@ -93,7 +92,7 @@ export async function haveValidSigningKeys(
|
|
|
93
92
|
//
|
|
94
93
|
return !!(res.data && res.data.id)
|
|
95
94
|
} catch (e) {
|
|
96
|
-
console.error('Error fetching signingKeyId', signingKeyId, 'assuming it is not valid')
|
|
95
|
+
console.error('Error fetching signingKeyId', signingKeyId, 'assuming it is not valid', e)
|
|
97
96
|
return false
|
|
98
97
|
}
|
|
99
98
|
}
|
|
@@ -106,6 +105,6 @@ export function testSecretsObservable(client: SanityClient) {
|
|
|
106
105
|
withCredentials: true,
|
|
107
106
|
method: 'GET',
|
|
108
107
|
query: PLUGIN_VERSION_QUERY,
|
|
109
|
-
})
|
|
108
|
+
}),
|
|
110
109
|
)
|
|
111
110
|
}
|
package/src/actions/upload.ts
CHANGED
|
@@ -18,13 +18,13 @@ function sanitizeOverlaySettingsInPlace(settings: MuxNewAssetSettings) {
|
|
|
18
18
|
const overlay = (input as {overlay_settings?: Record<string, unknown>}).overlay_settings
|
|
19
19
|
if (!overlay) continue
|
|
20
20
|
|
|
21
|
-
const hm = roundPxString(overlay
|
|
22
|
-
const vm = roundPxString(overlay
|
|
23
|
-
const w = roundPxString(overlay
|
|
21
|
+
const hm = roundPxString(overlay['horizontal_margin'])
|
|
22
|
+
const vm = roundPxString(overlay['vertical_margin'])
|
|
23
|
+
const w = roundPxString(overlay['width'])
|
|
24
24
|
|
|
25
|
-
if (hm) overlay
|
|
26
|
-
if (vm) overlay
|
|
27
|
-
if (w) overlay
|
|
25
|
+
if (hm) overlay['horizontal_margin'] = hm
|
|
26
|
+
if (vm) overlay['vertical_margin'] = vm
|
|
27
|
+
if (w) overlay['width'] = w
|
|
28
28
|
}
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -38,7 +38,7 @@ function sanitizePxStringsInJson(json: string): string {
|
|
|
38
38
|
})
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
function cancelUpload(client: SanityClient, uuid: string) {
|
|
42
42
|
return client.observable.request({
|
|
43
43
|
url: `/addons/mux/uploads/${client.config().dataset}/${uuid}`,
|
|
44
44
|
withCredentials: true,
|
|
@@ -51,7 +51,6 @@ export function uploadUrl({
|
|
|
51
51
|
url,
|
|
52
52
|
settings,
|
|
53
53
|
client,
|
|
54
|
-
watermark,
|
|
55
54
|
}: {
|
|
56
55
|
url: string
|
|
57
56
|
settings: MuxNewAssetSettings
|
|
@@ -70,12 +69,15 @@ export function uploadUrl({
|
|
|
70
69
|
const uuid = generateUuid()
|
|
71
70
|
const muxBody = settings
|
|
72
71
|
if (!muxBody.input) muxBody.input = [{type: 'video'}]
|
|
73
|
-
muxBody.input[0]
|
|
72
|
+
muxBody.input[0]!.url = validUrl
|
|
74
73
|
sanitizeOverlaySettingsInPlace(muxBody)
|
|
75
74
|
|
|
76
|
-
const query = {
|
|
75
|
+
const query: Record<string, string> = {
|
|
77
76
|
muxBody: sanitizePxStringsInJson(JSON.stringify(muxBody)),
|
|
78
|
-
|
|
77
|
+
}
|
|
78
|
+
const filename = validUrl.split('/').slice(-1)[0]
|
|
79
|
+
if (filename) {
|
|
80
|
+
query['filename'] = filename
|
|
79
81
|
}
|
|
80
82
|
|
|
81
83
|
const dataset = client.config().dataset
|
|
@@ -89,7 +91,7 @@ export function uploadUrl({
|
|
|
89
91
|
'Content-Type': 'application/json',
|
|
90
92
|
},
|
|
91
93
|
query: {...query, ...PLUGIN_VERSION_QUERY},
|
|
92
|
-
})
|
|
94
|
+
}),
|
|
93
95
|
).pipe(
|
|
94
96
|
mergeMap((result) => {
|
|
95
97
|
const asset =
|
|
@@ -100,12 +102,12 @@ export function uploadUrl({
|
|
|
100
102
|
return throwError(new Error('No asset document returned'))
|
|
101
103
|
}
|
|
102
104
|
return of({type: 'success' as const, id: uuid, asset})
|
|
103
|
-
})
|
|
105
|
+
}),
|
|
104
106
|
)
|
|
105
|
-
})
|
|
106
|
-
)
|
|
107
|
+
}),
|
|
108
|
+
),
|
|
107
109
|
)
|
|
108
|
-
})
|
|
110
|
+
}),
|
|
109
111
|
)
|
|
110
112
|
}
|
|
111
113
|
|
|
@@ -156,35 +158,31 @@ export function uploadFile({
|
|
|
156
158
|
},
|
|
157
159
|
body,
|
|
158
160
|
query: PLUGIN_VERSION_QUERY,
|
|
159
|
-
})
|
|
161
|
+
}),
|
|
160
162
|
).pipe(
|
|
161
163
|
mergeMap((result) => {
|
|
162
164
|
return createUpChunkObservable(uuid, result.upload.url, file).pipe(
|
|
163
|
-
// eslint-disable-next-line no-warning-comments
|
|
164
165
|
// @TODO type the observable events
|
|
165
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
166
166
|
mergeMap((event) => {
|
|
167
167
|
if (event.type !== 'success') {
|
|
168
168
|
return of(event)
|
|
169
169
|
}
|
|
170
170
|
return from(updateAssetDocumentFromUpload(client, uuid, watermark)).pipe(
|
|
171
|
-
|
|
172
|
-
mergeMap((doc) => of({...event, asset: doc}))
|
|
171
|
+
mergeMap((doc) => of({...event, asset: doc})),
|
|
173
172
|
)
|
|
174
173
|
}),
|
|
175
|
-
// eslint-disable-next-line max-nested-callbacks
|
|
176
174
|
catchError((err) => {
|
|
177
175
|
// Delete asset document
|
|
178
176
|
return cancelUpload(client, uuid).pipe(mergeMapTo(throwError(err)))
|
|
179
|
-
})
|
|
177
|
+
}),
|
|
180
178
|
)
|
|
181
|
-
})
|
|
182
|
-
)
|
|
179
|
+
}),
|
|
180
|
+
),
|
|
183
181
|
)
|
|
184
|
-
})
|
|
185
|
-
)
|
|
182
|
+
}),
|
|
183
|
+
),
|
|
186
184
|
)
|
|
187
|
-
})
|
|
185
|
+
}),
|
|
188
186
|
)
|
|
189
187
|
}
|
|
190
188
|
|
|
@@ -202,7 +200,7 @@ type UploadResponse = {
|
|
|
202
200
|
timeout: number
|
|
203
201
|
}
|
|
204
202
|
}
|
|
205
|
-
|
|
203
|
+
function getUpload(client: SanityClient, assetId: string) {
|
|
206
204
|
const {dataset} = client.config()
|
|
207
205
|
return client.request<UploadResponse>({
|
|
208
206
|
url: `/addons/mux/uploads/${dataset}/${assetId}`,
|
|
@@ -243,7 +241,7 @@ function pollUpload(client: SanityClient, uuid: string): Promise<UploadResponse>
|
|
|
243
241
|
async function updateAssetDocumentFromUpload(
|
|
244
242
|
client: SanityClient,
|
|
245
243
|
uuid: string,
|
|
246
|
-
_watermark?: WatermarkConfig
|
|
244
|
+
_watermark?: WatermarkConfig,
|
|
247
245
|
) {
|
|
248
246
|
let upload: UploadResponse
|
|
249
247
|
let asset: {data: MuxAsset}
|
|
@@ -264,7 +262,7 @@ async function updateAssetDocumentFromUpload(
|
|
|
264
262
|
status: asset.data.status,
|
|
265
263
|
data: asset.data,
|
|
266
264
|
assetId: asset.data.id,
|
|
267
|
-
playbackId: asset.data.playback_ids[0]
|
|
265
|
+
playbackId: asset.data.playback_ids[0]?.id,
|
|
268
266
|
uploadId: upload.data.id,
|
|
269
267
|
}
|
|
270
268
|
return client.createOrReplace(doc).then(() => {
|
|
@@ -272,7 +270,7 @@ async function updateAssetDocumentFromUpload(
|
|
|
272
270
|
})
|
|
273
271
|
}
|
|
274
272
|
|
|
275
|
-
|
|
273
|
+
function testFile(file: File) {
|
|
276
274
|
if (typeof window !== 'undefined' && file instanceof window.File) {
|
|
277
275
|
const fileOptions = optionsFromFile({}, file)
|
|
278
276
|
return of(fileOptions)
|
|
@@ -280,7 +278,7 @@ export function testFile(file: File) {
|
|
|
280
278
|
return throwError(new Error('Invalid file'))
|
|
281
279
|
}
|
|
282
280
|
|
|
283
|
-
|
|
281
|
+
function testUrl(url: string): Observable<string> {
|
|
284
282
|
const error = new Error('Invalid URL')
|
|
285
283
|
if (typeof url !== 'string') {
|
|
286
284
|
return throwError(error)
|
|
@@ -290,7 +288,7 @@ export function testUrl(url: string): Observable<string> {
|
|
|
290
288
|
let parsed
|
|
291
289
|
try {
|
|
292
290
|
parsed = new URL(formattedUrl)
|
|
293
|
-
} catch
|
|
291
|
+
} catch {
|
|
294
292
|
return throwError(error)
|
|
295
293
|
}
|
|
296
294
|
if (parsed && !parsed.protocol.match(/http:|https:/)) {
|
|
@@ -47,7 +47,7 @@ export default function AddCaptionDialog({asset, onAdd, onClose}: Props) {
|
|
|
47
47
|
const [vttUrl, setVttUrl] = useState('')
|
|
48
48
|
const [languageCode, setLanguageCode] = useState('')
|
|
49
49
|
const [selectedLanguage, setSelectedLanguage] = useState<{value: string; label: string} | null>(
|
|
50
|
-
null
|
|
50
|
+
null,
|
|
51
51
|
)
|
|
52
52
|
const [name, setName] = useState('')
|
|
53
53
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
@@ -326,7 +326,7 @@ export default function AddCaptionDialog({asset, onAdd, onClose}: Props) {
|
|
|
326
326
|
style={{display: 'none'}}
|
|
327
327
|
onChange={(e) => {
|
|
328
328
|
if (e.target.files && e.target.files.length > 0 && !isSubmitting) {
|
|
329
|
-
setSelectedFile(e.target.files[0])
|
|
329
|
+
setSelectedFile(e.target.files[0]!)
|
|
330
330
|
setVttUrl('')
|
|
331
331
|
}
|
|
332
332
|
}}
|
|
@@ -376,7 +376,7 @@ export default function AddCaptionDialog({asset, onAdd, onClose}: Props) {
|
|
|
376
376
|
openButton
|
|
377
377
|
renderValue={(value) =>
|
|
378
378
|
(isAutogenerated ? MUX_LANGUAGE_OPTIONS : LANGUAGE_OPTIONS).find(
|
|
379
|
-
(l) => l.value === value
|
|
379
|
+
(l) => l.value === value,
|
|
380
380
|
)?.label || value
|
|
381
381
|
}
|
|
382
382
|
renderOption={(option) => (
|
|
@@ -46,12 +46,12 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
46
46
|
secrets.secretKey !== state.secretKey ||
|
|
47
47
|
secrets.enableSignedUrls !== state.enableSignedUrls ||
|
|
48
48
|
secrets.drmConfigId !== state.drmConfigId,
|
|
49
|
-
[secrets, state]
|
|
49
|
+
[secrets, state],
|
|
50
50
|
)
|
|
51
51
|
const id = `ConfigureApi${useId()}`
|
|
52
52
|
const [tokenId, secretKeyId, enableSignedUrlsId, drmConfigIdId] = useMemo<typeof fieldNames>(
|
|
53
53
|
() => fieldNames.map((field) => `${id}-${field}`) as unknown as typeof fieldNames,
|
|
54
|
-
[id]
|
|
54
|
+
[id],
|
|
55
55
|
)
|
|
56
56
|
const firstField = useRef<HTMLInputElement>(null)
|
|
57
57
|
const handleSaveSecrets = useSaveSecrets(client, secrets)
|
|
@@ -78,7 +78,7 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
78
78
|
})
|
|
79
79
|
}
|
|
80
80
|
},
|
|
81
|
-
[client, dispatch, handleSaveSecrets, setDialogState, state]
|
|
81
|
+
[client, dispatch, handleSaveSecrets, setDialogState, state],
|
|
82
82
|
)
|
|
83
83
|
const handleChangeToken = useCallback(
|
|
84
84
|
(event: React.FormEvent<HTMLInputElement>) => {
|
|
@@ -87,7 +87,7 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
87
87
|
payload: {name: 'token', value: event.currentTarget.value},
|
|
88
88
|
})
|
|
89
89
|
},
|
|
90
|
-
[dispatch]
|
|
90
|
+
[dispatch],
|
|
91
91
|
)
|
|
92
92
|
const handleChangeSecretKey = useCallback(
|
|
93
93
|
(event: React.FormEvent<HTMLInputElement>) => {
|
|
@@ -96,7 +96,7 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
96
96
|
payload: {name: 'secretKey', value: event.currentTarget.value},
|
|
97
97
|
})
|
|
98
98
|
},
|
|
99
|
-
[dispatch]
|
|
99
|
+
[dispatch],
|
|
100
100
|
)
|
|
101
101
|
const handleChangeEnableSignedUrls = useCallback(
|
|
102
102
|
(event: React.FormEvent<HTMLInputElement>) => {
|
|
@@ -105,7 +105,7 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
105
105
|
payload: {name: 'enableSignedUrls', value: event.currentTarget.checked},
|
|
106
106
|
})
|
|
107
107
|
},
|
|
108
|
-
[dispatch]
|
|
108
|
+
[dispatch],
|
|
109
109
|
)
|
|
110
110
|
const handleChangeDrmConfigId = useCallback(
|
|
111
111
|
(event: React.FormEvent<HTMLInputElement>) => {
|
|
@@ -114,7 +114,7 @@ export function ConfigureApiDialog({secrets, setDialogState}: ConfigureApiDialog
|
|
|
114
114
|
payload: {name: 'drmConfigId', value: event.currentTarget.value},
|
|
115
115
|
})
|
|
116
116
|
},
|
|
117
|
-
[dispatch]
|
|
117
|
+
[dispatch],
|
|
118
118
|
)
|
|
119
119
|
|
|
120
120
|
useEffect(() => {
|
|
@@ -208,7 +208,7 @@ export default function DraggableWatermark({
|
|
|
208
208
|
onChange(newWatermark)
|
|
209
209
|
}, 300)
|
|
210
210
|
},
|
|
211
|
-
[onChange]
|
|
211
|
+
[onChange],
|
|
212
212
|
)
|
|
213
213
|
|
|
214
214
|
useEffect(() => {
|
|
@@ -221,6 +221,7 @@ export default function DraggableWatermark({
|
|
|
221
221
|
|
|
222
222
|
useEffect(() => {
|
|
223
223
|
if (!isDragging && watermark.position) {
|
|
224
|
+
// oxlint-disable-next-line react/react-compiler
|
|
224
225
|
setLocalPosition(watermark.position)
|
|
225
226
|
}
|
|
226
227
|
}, [watermark.position, isDragging])
|
|
@@ -232,7 +233,7 @@ export default function DraggableWatermark({
|
|
|
232
233
|
setDragStart({x: e.clientX, y: e.clientY})
|
|
233
234
|
setStartPosition({x: position.x, y: position.y})
|
|
234
235
|
},
|
|
235
|
-
[position]
|
|
236
|
+
[position],
|
|
236
237
|
)
|
|
237
238
|
|
|
238
239
|
const handleMouseMove = useCallback(
|
|
@@ -271,7 +272,7 @@ export default function DraggableWatermark({
|
|
|
271
272
|
watermark,
|
|
272
273
|
debouncedOnChange,
|
|
273
274
|
getVideoContentBox,
|
|
274
|
-
]
|
|
275
|
+
],
|
|
275
276
|
)
|
|
276
277
|
|
|
277
278
|
const handleMouseUp = useCallback(() => {
|
|
@@ -306,6 +307,7 @@ export default function DraggableWatermark({
|
|
|
306
307
|
const opacityForRender = hasManualOverlay
|
|
307
308
|
? (parseOpacityPercent(watermark.overlay_settings?.opacity) ?? opacity)
|
|
308
309
|
: opacity
|
|
310
|
+
// oxlint-disable-next-line react/react-compiler
|
|
309
311
|
const contentBox = getVideoContentBox()
|
|
310
312
|
const hasContentBox = contentBox.width > 0 && contentBox.height > 0
|
|
311
313
|
|
|
@@ -336,6 +338,7 @@ export default function DraggableWatermark({
|
|
|
336
338
|
ref={watermarkRef}
|
|
337
339
|
$opacity={opacityForRender}
|
|
338
340
|
onMouseDown={hasManualOverlay ? undefined : handleMouseDown}
|
|
341
|
+
// oxlint-disable-next-line react/react-compiler
|
|
339
342
|
style={computeWatermarkStyle()}
|
|
340
343
|
>
|
|
341
344
|
<img src={watermark.imageUrl} alt="Watermark" draggable={false} />
|
|
@@ -364,14 +367,14 @@ export function WatermarkControls({
|
|
|
364
367
|
const [isValid, setIsValid] = useState<boolean | null>(null)
|
|
365
368
|
const validationTimeoutRef = useRef<NodeJS.Timeout | null>(null)
|
|
366
369
|
const [mode, setMode] = useState<'canvas' | 'manual'>(
|
|
367
|
-
watermark.overlay_settings ? 'manual' : 'canvas'
|
|
370
|
+
watermark.overlay_settings ? 'manual' : 'canvas',
|
|
368
371
|
)
|
|
369
372
|
|
|
370
373
|
const isUpdatingRef = useRef(false)
|
|
371
374
|
|
|
372
|
-
const isValidExtension = (extension: string) => {
|
|
375
|
+
const isValidExtension = useCallback((extension: string) => {
|
|
373
376
|
return extension.endsWith('.png') || extension.endsWith('.jpg') || extension.endsWith('.jpeg')
|
|
374
|
-
}
|
|
377
|
+
}, [])
|
|
375
378
|
|
|
376
379
|
const validateUrl = useCallback(
|
|
377
380
|
(url: string) => {
|
|
@@ -461,7 +464,7 @@ export function WatermarkControls({
|
|
|
461
464
|
}
|
|
462
465
|
}, 500)
|
|
463
466
|
},
|
|
464
|
-
[watermark, onChange, onValidationChange]
|
|
467
|
+
[watermark, onChange, onValidationChange, isValidExtension],
|
|
465
468
|
)
|
|
466
469
|
|
|
467
470
|
useEffect(() => {
|
|
@@ -473,6 +476,7 @@ export function WatermarkControls({
|
|
|
473
476
|
}, [])
|
|
474
477
|
|
|
475
478
|
useEffect(() => {
|
|
479
|
+
// oxlint-disable-next-line react/react-compiler
|
|
476
480
|
setMode(watermark.overlay_settings ? 'manual' : 'canvas')
|
|
477
481
|
}, [watermark.overlay_settings])
|
|
478
482
|
|
|
@@ -802,6 +806,7 @@ export function WatermarkControls({
|
|
|
802
806
|
<>
|
|
803
807
|
<Box>
|
|
804
808
|
<Text size={1} weight="medium">
|
|
809
|
+
{/* oxlint-disable-next-line react/react-compiler */}
|
|
805
810
|
{(() => {
|
|
806
811
|
const sizePct = watermark.size || 20
|
|
807
812
|
const contentW = getVideoContentBox().width
|
|
@@ -812,17 +817,20 @@ export function WatermarkControls({
|
|
|
812
817
|
</Text>
|
|
813
818
|
<RangeInput
|
|
814
819
|
type="range"
|
|
820
|
+
// oxlint-disable-next-line react/react-compiler
|
|
815
821
|
value={(() => {
|
|
816
822
|
const sizePct = watermark.size || 20
|
|
817
823
|
const contentW = getVideoContentBox().width
|
|
818
824
|
if (!contentW) return sizePct
|
|
819
825
|
return Math.max(1, Math.round((sizePct / 100) * contentW))
|
|
820
826
|
})()}
|
|
827
|
+
// oxlint-disable-next-line react/react-compiler
|
|
821
828
|
min={(() => {
|
|
822
829
|
const contentW = getVideoContentBox().width
|
|
823
830
|
if (!contentW) return 5
|
|
824
831
|
return Math.max(1, Math.round(contentW * 0.05))
|
|
825
832
|
})()}
|
|
833
|
+
// oxlint-disable-next-line react/react-compiler
|
|
826
834
|
max={(() => {
|
|
827
835
|
const contentW = getVideoContentBox().width
|
|
828
836
|
if (!contentW) return 50
|
|
@@ -52,7 +52,7 @@ export default function EditCaptionDialog({asset, track, onUpdate, onClose}: Pro
|
|
|
52
52
|
() => {
|
|
53
53
|
const baseCode = track.language_code?.split('-')[0]
|
|
54
54
|
const found = LANGUAGE_OPTIONS.find(
|
|
55
|
-
(opt) => opt.value === track.language_code || opt.value === baseCode
|
|
55
|
+
(opt) => opt.value === track.language_code || opt.value === baseCode,
|
|
56
56
|
)
|
|
57
57
|
if (found) return found
|
|
58
58
|
if (track.name) {
|
|
@@ -60,7 +60,7 @@ export default function EditCaptionDialog({asset, track, onUpdate, onClose}: Pro
|
|
|
60
60
|
if (foundByName) return foundByName
|
|
61
61
|
}
|
|
62
62
|
return null
|
|
63
|
-
}
|
|
63
|
+
},
|
|
64
64
|
)
|
|
65
65
|
const [name, setName] = useState(track.name || '')
|
|
66
66
|
const [isSubmitting, setIsSubmitting] = useState(false)
|
|
@@ -69,12 +69,13 @@ export default function EditCaptionDialog({asset, track, onUpdate, onClose}: Pro
|
|
|
69
69
|
const fileInputRef = useRef<HTMLInputElement>(null)
|
|
70
70
|
|
|
71
71
|
useEffect(() => {
|
|
72
|
+
// oxlint-disable-next-line react/react-compiler
|
|
72
73
|
setLanguageCode(track.language_code || '')
|
|
73
74
|
setName(track.name || '')
|
|
74
75
|
setVttUrl('')
|
|
75
76
|
const baseCode = track.language_code?.split('-')[0]
|
|
76
77
|
const foundByCode = LANGUAGE_OPTIONS.find(
|
|
77
|
-
(opt) => opt.value === track.language_code || opt.value === baseCode
|
|
78
|
+
(opt) => opt.value === track.language_code || opt.value === baseCode,
|
|
78
79
|
)
|
|
79
80
|
const foundByName = track.name ? LANGUAGE_OPTIONS.find((opt) => opt.label === track.name) : null
|
|
80
81
|
setSelectedLanguage(foundByCode || foundByName || null)
|
|
@@ -94,7 +95,7 @@ export default function EditCaptionDialog({asset, track, onUpdate, onClose}: Pro
|
|
|
94
95
|
title = 'Cannot download'
|
|
95
96
|
}
|
|
96
97
|
} else if (error === 'Track ID is missing' || error === 'Track is not ready yet') {
|
|
97
|
-
errorMessage =
|
|
98
|
+
errorMessage = error
|
|
98
99
|
title = 'Cannot download'
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -398,7 +399,7 @@ export default function EditCaptionDialog({asset, track, onUpdate, onClose}: Pro
|
|
|
398
399
|
style={{display: 'none'}}
|
|
399
400
|
onChange={(e) => {
|
|
400
401
|
if (e.target.files && e.target.files.length > 0 && !isSubmitting) {
|
|
401
|
-
setSelectedFile(e.target.files[0])
|
|
402
|
+
setSelectedFile(e.target.files[0]!)
|
|
402
403
|
setVttUrl('')
|
|
403
404
|
}
|
|
404
405
|
}}
|