sanity-plugin-mux-input 3.0.4 → 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.
Files changed (92) hide show
  1. package/README.md +0 -2
  2. package/dist/index.cjs +2876 -4400
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +134 -193
  5. package/dist/index.d.cts.map +1 -0
  6. package/dist/index.d.ts +134 -193
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +2877 -4401
  9. package/dist/index.js.map +1 -1
  10. package/package.json +36 -36
  11. package/src/_exports/index.ts +1 -1
  12. package/src/actions/assets.ts +5 -5
  13. package/src/actions/secrets.ts +5 -6
  14. package/src/actions/upload.ts +32 -34
  15. package/src/components/AddCaptionDialog.tsx +3 -3
  16. package/src/components/ConfigureApi.tsx +7 -7
  17. package/src/components/DraggableWatermark.tsx +15 -7
  18. package/src/components/EditCaptionDialog.tsx +6 -5
  19. package/src/components/EditThumbnailDialog.tsx +4 -5
  20. package/src/components/ErrorBoundaryCard.tsx +1 -0
  21. package/src/components/FileInputButton.tsx +1 -1
  22. package/src/components/FileInputMenuItem.tsx +10 -10
  23. package/src/components/ImportVideosFromMux.tsx +0 -3
  24. package/src/components/MuxLogo.tsx +1 -1
  25. package/src/components/Onboard.tsx +1 -1
  26. package/src/components/PageSelector.tsx +1 -1
  27. package/src/components/Player.styled.tsx +0 -44
  28. package/src/components/Player.tsx +1 -1
  29. package/src/components/PlayerActionsMenu.tsx +3 -2
  30. package/src/components/ResyncMetadata.tsx +4 -6
  31. package/src/components/SelectAsset.tsx +2 -2
  32. package/src/components/SelectSortOptions.tsx +3 -3
  33. package/src/components/TextTracksEditor.tsx +2 -2
  34. package/src/components/TextTracksManager.tsx +5 -4
  35. package/src/components/UploadConfiguration.tsx +17 -15
  36. package/src/components/UploadPlaceholder.tsx +1 -1
  37. package/src/components/UploadProgress.tsx +4 -4
  38. package/src/components/Uploader.styled.tsx +1 -2
  39. package/src/components/Uploader.tsx +15 -14
  40. package/src/components/VideoDetails/DeleteDialog.tsx +2 -1
  41. package/src/components/VideoDetails/VideoDetails.tsx +3 -3
  42. package/src/components/VideoDetails/useVideoDetails.ts +2 -2
  43. package/src/components/VideoInBrowser.tsx +1 -1
  44. package/src/components/VideoMetadata.tsx +1 -1
  45. package/src/components/VideoPlayer.tsx +12 -6
  46. package/src/components/VideoThumbnail.tsx +4 -3
  47. package/src/components/VideosBrowser.tsx +1 -1
  48. package/src/components/documentPreview/DocumentPreview.tsx +4 -3
  49. package/src/components/documentPreview/PaneItemPreview.tsx +5 -12
  50. package/src/components/uploadConfiguration/PlaybackPolicy.tsx +3 -3
  51. package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +2 -2
  52. package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +1 -1
  53. package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +2 -2
  54. package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +4 -4
  55. package/src/components/withFocusRing/withFocusRing.ts +1 -1
  56. package/src/context/DialogStateContext.tsx +3 -6
  57. package/src/context/DrmPlaybackWarningContext.tsx +14 -10
  58. package/src/hooks/useAccessControl.ts +1 -1
  59. package/src/hooks/useAssetDocumentValues.ts +2 -2
  60. package/src/hooks/useAssets.ts +11 -6
  61. package/src/hooks/useCancelUpload.ts +2 -2
  62. package/src/hooks/useDocReferences.ts +2 -2
  63. package/src/hooks/useFetchFileSize.ts +4 -3
  64. package/src/hooks/useImportMuxAssets.ts +3 -3
  65. package/src/hooks/useInView.ts +3 -4
  66. package/src/hooks/useMediaMetadata.ts +5 -4
  67. package/src/hooks/useMuxAssets.ts +15 -15
  68. package/src/hooks/useMuxPolling.ts +6 -3
  69. package/src/hooks/useResyncAsset.ts +1 -1
  70. package/src/hooks/useResyncMuxMetadata.ts +4 -11
  71. package/src/hooks/useSaveSecrets.ts +4 -4
  72. package/src/hooks/useSecretsDocumentValues.ts +1 -1
  73. package/src/util/asserters.ts +0 -13
  74. package/src/util/convertWatermarkToMux.ts +4 -4
  75. package/src/util/createUrlParamsObject.ts +3 -3
  76. package/src/util/extractFiles.ts +3 -3
  77. package/src/util/formatBytes.ts +0 -1
  78. package/src/util/formatSeconds.ts +0 -1
  79. package/src/util/generateJwt.ts +3 -3
  80. package/src/util/getAnimatedPosterSrc.ts +1 -1
  81. package/src/util/getPlaybackPolicy.ts +6 -6
  82. package/src/util/getPosterSrc.ts +1 -1
  83. package/src/util/pluginVersion.ts +5 -1
  84. package/src/util/readSecrets.ts +1 -1
  85. package/src/util/textTracks.ts +5 -5
  86. package/src/util/tryWithSuspend.ts +1 -1
  87. package/src/util/types.ts +2 -32
  88. package/src/components/InputError.tsx +0 -17
  89. package/src/components/documentPreview/paneItemTypes.ts +0 -7
  90. package/src/util/areSecretsSignable.ts +0 -5
  91. package/src/util/getStoryboardSrc.ts +0 -27
  92. package/src/util/isSigned.ts +0 -20
@@ -24,7 +24,7 @@ export default function EditThumbnailDialog({asset, currentTime = 0}: Props) {
24
24
  const dialogId = `EditThumbnailDialog${useId()}`
25
25
 
26
26
  const [timeFormatted, setTimeFormatted] = useState<string>(() =>
27
- formatSecondsToHHMMSS(currentTime)
27
+ formatSecondsToHHMMSS(currentTime),
28
28
  )
29
29
  const [nextTime, setNextTime] = useState<number>(currentTime)
30
30
  const [inputError, setInputError] = useState<string>('')
@@ -35,17 +35,16 @@ export default function EditThumbnailDialog({asset, currentTime = 0}: Props) {
35
35
  const handleSave = () => {
36
36
  setSaving(true)
37
37
  client
38
- .patch(asset._id!)
38
+ .patch(asset._id)
39
39
  .set({thumbTime: nextTime})
40
40
  .commit({returnDocuments: false})
41
- .then(() => void setDialogState(false))
41
+ .then(() => setDialogState(false))
42
42
  .catch(setSaveThumbnailError)
43
- .finally(() => void setSaving(false))
43
+ .finally(() => setSaving(false))
44
44
  }
45
45
  const width = 300 * getDevicePixelRatio({maxDpr: 2})
46
46
 
47
47
  if (saveThumbnailError) {
48
- // eslint-disable-next-line no-warning-comments
49
48
  // @TODO handle errors more gracefully
50
49
  throw saveThumbnailError
51
50
  }
@@ -16,6 +16,7 @@ function ErrorBoundaryCard(props: Props) {
16
16
  const {push: pushToast} = useToast()
17
17
  const errorRef = useRef(null)
18
18
  const {ErrorBoundary, didCatch, error, reset} = useErrorBoundary({
19
+ // oxlint-disable-next-line no-unstable-nested-components
19
20
  onDidCatch: (err, errorInfo) => {
20
21
  console.group(err.toString())
21
22
  console.groupCollapsed('console.error')
@@ -28,7 +28,7 @@ export const FileInputButton = ({onSelect, accept, ...props}: FileInputButtonPro
28
28
  onSelect(event.target.files!)
29
29
  }
30
30
  },
31
- [onSelect]
31
+ [onSelect],
32
32
  )
33
33
  const handleButtonClick = useCallback(() => inputRef.current?.click(), [])
34
34
  return (
@@ -1,5 +1,5 @@
1
- import {Box, ButtonProps, Flex, Text} from '@sanity/ui'
2
- import React, {createElement, isValidElement, useId} from 'react'
1
+ import {Box, type ButtonProps, Flex, Text} from '@sanity/ui'
2
+ import {isValidElement, useId, forwardRef, useCallback} from 'react'
3
3
  import {isValidElementType} from 'react-is'
4
4
 
5
5
  import {FileButton} from './FileInputMenuItem.styled'
@@ -12,13 +12,13 @@ export interface FileInputMenuItemProps extends ButtonProps {
12
12
  disabled?: boolean
13
13
  }
14
14
 
15
- export const FileInputMenuItem = React.forwardRef(function FileInputMenuItem(
15
+ export const FileInputMenuItem = forwardRef(function FileInputMenuItem(
16
16
  props: FileInputMenuItemProps &
17
17
  Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'ref' | 'type' | 'value' | 'onSelect'>,
18
- forwardedRef: React.ForwardedRef<HTMLInputElement>
18
+ forwardedRef: React.ForwardedRef<HTMLInputElement>,
19
19
  ) {
20
20
  const {
21
- icon,
21
+ icon: Icon,
22
22
  id: idProp,
23
23
  accept,
24
24
  capture,
@@ -34,23 +34,23 @@ export const FileInputMenuItem = React.forwardRef(function FileInputMenuItem(
34
34
  const idHook = useId()
35
35
  const id = idProp || idHook
36
36
 
37
- const handleChange = React.useCallback(
37
+ const handleChange = useCallback(
38
38
  (event: React.ChangeEvent<HTMLInputElement>) => {
39
39
  if (onSelect && event.target.files) {
40
40
  onSelect(Array.from(event.target.files))
41
41
  }
42
42
  },
43
- [onSelect]
43
+ [onSelect],
44
44
  )
45
45
 
46
46
  const content = (
47
47
  <Flex align="center" justify="flex-start">
48
48
  {/* Icon */}
49
- {icon && (
49
+ {Icon && (
50
50
  <Box marginRight={text ? space : undefined}>
51
51
  <Text size={fontSize}>
52
- {isValidElement(icon) && icon}
53
- {isValidElementType(icon) && createElement(icon)}
52
+ {isValidElement(Icon) && Icon}
53
+ {isValidElementType(Icon) && <Icon />}
54
54
  </Text>
55
55
  </Box>
56
56
  )}
@@ -98,7 +98,6 @@ function MissingAsset({
98
98
  )
99
99
  }
100
100
 
101
- // eslint-disable-next-line complexity
102
101
  function ImportVideosDialog(props: ReturnType<typeof useImportMuxAssets>) {
103
102
  const {importState} = props
104
103
 
@@ -333,10 +332,8 @@ export default function ImportVideosFromMux() {
333
332
  }
334
333
 
335
334
  if (importAssets.dialogOpen) {
336
- // eslint-disable-next-line consistent-return
337
335
  return <ImportVideosDialog {...importAssets} />
338
336
  }
339
337
 
340
- // eslint-disable-next-line consistent-return
341
338
  return <Button mode="bleed" text="Import from Mux" onClick={importAssets.openDialog} />
342
339
  }
@@ -1,5 +1,5 @@
1
1
  import {useTheme_v2} from '@sanity/ui'
2
- import {CSSProperties, useId, useMemo} from 'react'
2
+ import {type CSSProperties, useId, useMemo} from 'react'
3
3
 
4
4
  export interface Props {
5
5
  height?: number
@@ -4,7 +4,7 @@ import {useCallback} from 'react'
4
4
 
5
5
  import {useAccessControl} from '../hooks/useAccessControl'
6
6
  import type {SetDialogState} from '../hooks/useDialogState'
7
- import {PluginConfig} from '../util/types'
7
+ import {type PluginConfig} from '../util/types'
8
8
  import MuxLogo from './MuxLogo'
9
9
 
10
10
  interface OnboardProps {
@@ -1,6 +1,6 @@
1
1
  import {ChevronLeftIcon, ChevronRightIcon} from '@sanity/icons'
2
2
  import {Button, Label} from '@sanity/ui'
3
- import {Dispatch, SetStateAction, useEffect} from 'react'
3
+ import {type Dispatch, type SetStateAction, useEffect} from 'react'
4
4
 
5
5
  const PageSelector = (props: {
6
6
  page: number
@@ -1,30 +1,5 @@
1
- import {Suspense, useState} from 'react'
2
1
  import {styled} from 'styled-components'
3
2
 
4
- import {useClient} from '../hooks/useClient'
5
- import {getStoryboardSrc} from '../util/getStoryboardSrc'
6
- import type {VideoAssetDocument} from '../util/types'
7
-
8
- export const StyledCenterControls = styled.div`
9
- && {
10
- --media-background-color: transparent;
11
- --media-button-icon-width: 100%;
12
- --media-button-icon-height: auto;
13
- pointer-events: none;
14
- width: 100%;
15
- display: flex;
16
- flex-flow: row;
17
- align-items: center;
18
- justify-content: center;
19
- media-play-button {
20
- --media-control-background: transparent;
21
- --media-control-hover-background: transparent;
22
- padding: 0;
23
- width: max(27px, min(9%, 90px));
24
- }
25
- }
26
- `
27
-
28
3
  export const TopControls = styled.div`
29
4
  position: absolute;
30
5
  top: 0;
@@ -34,22 +9,3 @@ export const TopControls = styled.div`
34
9
  height: auto;
35
10
  }
36
11
  `
37
-
38
- export interface PosterImageProps {
39
- asset: VideoAssetDocument
40
- }
41
- export interface ThumbnailsMetadataTrackProps {
42
- asset: VideoAssetDocument
43
- }
44
- export function ThumbnailsMetadataTrack({asset}: ThumbnailsMetadataTrackProps) {
45
- const client = useClient()
46
- // Why useState instead of useMemo? Because we really really only want to run it exactly once and useMemo doesn't make that guarantee
47
- const [src] = useState<string>(() => getStoryboardSrc({asset, client}))
48
-
49
- return (
50
- /* We use Suspense here because `getStoryboardSrc` uses suspend() under the hood */
51
- <Suspense fallback={null}>
52
- <track label="thumbnails" default kind="metadata" src={src} />
53
- </Suspense>
54
- )
55
- }
@@ -33,6 +33,7 @@ const Player = ({asset, buttons, readOnly, onChange, config}: Props) => {
33
33
 
34
34
  return true
35
35
  }, [asset])
36
+ // oxlint-disable-next-line react/react-compiler
36
37
  const isPreparingStaticRenditions = useMemo<boolean>(() => {
37
38
  // Legacy: If static_renditions has a status field, it was created with mp4_support (deprecated)
38
39
  // We don't process this old format, just return false
@@ -70,7 +71,6 @@ const Player = ({asset, buttons, readOnly, onChange, config}: Props) => {
70
71
  useEffect(() => {
71
72
  if (asset?.status === 'errored') {
72
73
  handleCancelUpload()
73
- // eslint-disable-next-line no-warning-comments
74
74
  // @TODO use better error handling
75
75
  throw new Error(asset.data?.errors?.messages?.join(' '))
76
76
  }
@@ -61,7 +61,7 @@ function PlayerActionsMenu(
61
61
  setDialogState: SetDialogState
62
62
  config: PluginConfig
63
63
  accept: string
64
- }
64
+ },
65
65
  ) {
66
66
  const {asset, readOnly, dialogState, setDialogState, onChange, onSelect, accept} = props
67
67
  const [open, setOpen] = useState(false)
@@ -79,13 +79,14 @@ function PlayerActionsMenu(
79
79
 
80
80
  useEffect(() => {
81
81
  if (open && dialogState) {
82
+ // oxlint-disable-next-line react/react-compiler
82
83
  setOpen(false)
83
84
  }
84
85
  }, [dialogState, open])
85
86
 
86
87
  useClickOutsideEvent(
87
88
  () => setOpen(false),
88
- () => [menuElement]
89
+ () => [menuElement],
89
90
  )
90
91
 
91
92
  return (
@@ -69,7 +69,7 @@ function ResyncMetadataDialog(props: ReturnType<typeof useResyncMuxMetadata>) {
69
69
  const videosToUpdate = props.matchedAssets?.filter((m) => m.muxAsset).length || 0
70
70
  const videosWithEmptyOrPlaceholder =
71
71
  props.matchedAssets?.filter(
72
- (m) => m.muxAsset && m.muxTitle && isEmptyOrPlaceholderTitle(m.currentTitle, m.muxAsset.id)
72
+ (m) => m.muxAsset && m.muxTitle && isEmptyOrPlaceholderTitle(m.currentTitle, m.muxAsset.id),
73
73
  ).length || 0
74
74
 
75
75
  const hasEmptyTitles = videosWithEmptyOrPlaceholder > 0
@@ -84,13 +84,13 @@ function ResyncMetadataDialog(props: ReturnType<typeof useResyncMuxMetadata>) {
84
84
  const handleSync = () => {
85
85
  switch (selectedOption) {
86
86
  case 'fillEmpty':
87
- props.syncOnlyEmpty()
87
+ void props.syncOnlyEmpty()
88
88
  break
89
89
  case 'syncTitles':
90
- props.syncAllVideos()
90
+ void props.syncAllVideos()
91
91
  break
92
92
  case 'fullResync':
93
- props.syncFullData()
93
+ void props.syncFullData()
94
94
  break
95
95
  default:
96
96
  break
@@ -271,10 +271,8 @@ export default function ResyncMetadata() {
271
271
  }
272
272
 
273
273
  if (resyncMetadata.dialogOpen) {
274
- // eslint-disable-next-line consistent-return
275
274
  return <ResyncMetadataDialog {...resyncMetadata} />
276
275
  }
277
276
 
278
- // eslint-disable-next-line consistent-return
279
277
  return <Button mode="bleed" text="Sync with Mux" onClick={resyncMetadata.openDialog} />
280
278
  }
@@ -27,12 +27,12 @@ export default function SelectAssets({
27
27
  PatchEvent.from([
28
28
  setIfMissing({asset: {}, _type: 'mux.video'}),
29
29
  set({_type: 'reference', _weak: true, _ref: chosenAsset._id}, ['asset']),
30
- ])
30
+ ]),
31
31
  )
32
32
  }
33
33
  setDialogState(false)
34
34
  },
35
- [onChange, setDialogState, selectedAsset]
35
+ [onChange, setDialogState, selectedAsset],
36
36
  )
37
37
 
38
38
  return <VideosBrowser onSelect={handleSelect} config={config} />
@@ -1,10 +1,10 @@
1
1
  import {SortIcon} from '@sanity/icons'
2
- import {Button, Menu, MenuButton, MenuItem, PopoverProps} from '@sanity/ui'
2
+ import {Button, Menu, MenuButton, MenuItem, type PopoverProps} from '@sanity/ui'
3
3
  import {useId} from 'react'
4
4
 
5
- import {ASSET_SORT_OPTIONS, SortOption} from '../hooks/useAssets'
5
+ import {ASSET_SORT_OPTIONS, type SortOption} from '../hooks/useAssets'
6
6
 
7
- export const CONTEXT_MENU_POPOVER_PROPS: PopoverProps = {
7
+ const CONTEXT_MENU_POPOVER_PROPS: PopoverProps = {
8
8
  constrainSize: true,
9
9
  placement: 'bottom',
10
10
  portal: true,
@@ -2,10 +2,10 @@ import {TranslateIcon} from '@sanity/icons'
2
2
  import {Autocomplete, Box, Card, Checkbox, Flex, Stack, Text} from '@sanity/ui'
3
3
  import {uuid} from '@sanity/uuid'
4
4
  import LanguagesList from 'iso-639-1'
5
- import {Dispatch} from 'react'
5
+ import {type Dispatch} from 'react'
6
6
  import {FormField} from 'sanity'
7
7
 
8
- import {type PluginConfig, SUPPORTED_MUX_LANGUAGES, UploadTextTrack} from '../util/types'
8
+ import {type PluginConfig, SUPPORTED_MUX_LANGUAGES, type UploadTextTrack} from '../util/types'
9
9
 
10
10
  const ALL_LANGUAGE_CODES = LanguagesList.getAllCodes().map((code) => ({
11
11
  value: code,
@@ -225,7 +225,7 @@ export default function TextTracksManager({
225
225
  const activeTracks = realTracks.filter(
226
226
  (track) =>
227
227
  track.id &&
228
- (track.status === 'ready' || track.status === 'preparing' || track.status === 'errored')
228
+ (track.status === 'ready' || track.status === 'preparing' || track.status === 'errored'),
229
229
  )
230
230
 
231
231
  const allTracks = useMemo(() => {
@@ -260,7 +260,7 @@ export default function TextTracksManager({
260
260
 
261
261
  const isTrackAlreadyInRealTracks = (
262
262
  addedTrack: MuxTextTrack,
263
- realTracksList: MuxTextTrack[]
263
+ realTracksList: MuxTextTrack[],
264
264
  ) => {
265
265
  if (!addedTrack.id) return false
266
266
  if (addedTrack.id.startsWith('generating-')) {
@@ -306,6 +306,7 @@ export default function TextTracksManager({
306
306
  }
307
307
  })
308
308
 
309
+ // oxlint-disable-next-line react/react-compiler
309
310
  setAutogeneratedTrackIds((prev) => {
310
311
  let hasNew = false
311
312
  const updated = new Set(prev)
@@ -335,7 +336,7 @@ export default function TextTracksManager({
335
336
 
336
337
  const isMockTrackReplaced = (
337
338
  mockTrack: MuxTextTrack,
338
- fetchedTracksList: MuxTextTrack[]
339
+ fetchedTracksList: MuxTextTrack[],
339
340
  ) => {
340
341
  if (!mockTrack.id || !mockTrack.id.startsWith('generating-')) {
341
342
  return false
@@ -423,7 +424,7 @@ export default function TextTracksManager({
423
424
  const visibleTracks = allTracks
424
425
  .filter(
425
426
  (track) =>
426
- track.status === 'ready' || track.status === 'preparing' || track.status === 'errored'
427
+ track.status === 'ready' || track.status === 'preparing' || track.status === 'errored',
427
428
  )
428
429
  .sort((a, b) => {
429
430
  const orderA = trackActivityOrder.get(a.id) || 0
@@ -22,7 +22,7 @@ import {
22
22
  type SupportedMuxLanguage,
23
23
  type UploadConfig,
24
24
  type UploadTextTrack,
25
- WatermarkConfig,
25
+ type WatermarkConfig,
26
26
  } from '../util/types'
27
27
  import DraggableWatermark, {WatermarkControls} from './DraggableWatermark'
28
28
  import TextTracksEditor, {type TrackAction} from './TextTracksEditor'
@@ -56,7 +56,7 @@ const VIDEO_QUALITY_LEVELS = [
56
56
  * If both are present, only 'highest' (and 'audio-only' if present) will be kept.
57
57
  */
58
58
  function sanitizeStaticRenditions(
59
- renditions: StaticRenditionResolution[]
59
+ renditions: StaticRenditionResolution[],
60
60
  ): StaticRenditionResolution[] {
61
61
  const hasHighest = renditions.includes('highest')
62
62
  const hasSpecificResolutions = renditions.some((r) => r !== 'highest' && r !== 'audio-only')
@@ -91,6 +91,7 @@ export default function UploadConfiguration({
91
91
  const [watermarkValidationError, setWatermarkValidationError] = useState<string | null>(null)
92
92
  const watermarkPreviewContainerRef = useRef<HTMLDivElement>(null)
93
93
  const watermarkPreviewVideoRef = useRef<HTMLVideoElement>(null)
94
+ // oxlint-disable-next-line react/react-compiler
94
95
  const autoTextTracks = useRef<NonNullable<UploadConfig['text_tracks']>>(
95
96
  pluginConfig.video_quality === 'plus' && pluginConfig.defaultAutogeneratedSubtitleLang
96
97
  ? [
@@ -101,10 +102,11 @@ export default function UploadConfiguration({
101
102
  name: LanguagesList.getNativeName(pluginConfig.defaultAutogeneratedSubtitleLang),
102
103
  } satisfies AutogeneratedTextTrack,
103
104
  ]
104
- : []
105
+ : [],
105
106
  ).current
106
107
 
107
108
  const [config, dispatch] = useReducer(
109
+ // oxlint-disable-next-line react/react-compiler
108
110
  (prev: UploadConfig, action: UploadConfigurationStateAction) => {
109
111
  switch (action.action) {
110
112
  case 'video_quality':
@@ -143,7 +145,6 @@ export default function UploadConfiguration({
143
145
  case 'track': {
144
146
  const text_tracks = [...prev.text_tracks]
145
147
  const target_track_i = text_tracks.findIndex(({_id}) => _id === action.id)
146
- // eslint-disable-next-line default-case
147
148
  switch (action.subAction) {
148
149
  case 'add':
149
150
  // Exit early if track already exists
@@ -180,7 +181,7 @@ export default function UploadConfiguration({
180
181
  drm_policy: pluginConfig.defaultDrm && !!secrets.drmConfigId,
181
182
  normalize_audio: pluginConfig.normalize_audio,
182
183
  text_tracks: autoTextTracks,
183
- } as UploadConfig
184
+ } as UploadConfig,
184
185
  )
185
186
 
186
187
  // Video validations
@@ -190,7 +191,7 @@ export default function UploadConfiguration({
190
191
 
191
192
  const {fileSize, isLoadingFileSize, canSkipFileSizeValidation} = useFetchFileSize(
192
193
  stagedUpload,
193
- MAX_FILE_SIZE
194
+ MAX_FILE_SIZE,
194
195
  )
195
196
  const {videoAssetMetadata, setVideoAssetMetadata, isLoadingMetadata} =
196
197
  useMediaMetadata(stagedUpload)
@@ -205,7 +206,7 @@ export default function UploadConfiguration({
205
206
  const validateDuration = (duration: number) => {
206
207
  if (MAX_DURATION_SECONDS && duration > MAX_DURATION_SECONDS) {
207
208
  setValidationError(
208
- `Video duration (${formatSeconds(duration)}) exceeds maximum allowed duration of ${formatSeconds(MAX_DURATION_SECONDS)}`
209
+ `Video duration (${formatSeconds(duration)}) exceeds maximum allowed duration of ${formatSeconds(MAX_DURATION_SECONDS)}`,
209
210
  )
210
211
  return false
211
212
  }
@@ -218,7 +219,7 @@ export default function UploadConfiguration({
218
219
  }
219
220
 
220
221
  setValidationError(
221
- `File size (${formatBytes(size)}) exceeds maximum allowed size of ${formatBytes(MAX_FILE_SIZE)}`
222
+ `File size (${formatBytes(size)}) exceeds maximum allowed size of ${formatBytes(MAX_FILE_SIZE)}`,
222
223
  )
223
224
  return false
224
225
  }
@@ -242,6 +243,7 @@ export default function UploadConfiguration({
242
243
  valid = valid && validateDrmAvailability(videoAssetMetadata.isAudioOnly)
243
244
  }
244
245
  if (valid) {
246
+ // oxlint-disable-next-line react/react-compiler
245
247
  setValidationError(null)
246
248
  }
247
249
  }, [
@@ -276,7 +278,7 @@ export default function UploadConfiguration({
276
278
  const basicConfig = config.video_quality !== 'plus' && config.video_quality !== 'premium'
277
279
  const playbackPolicySelected = config.public_policy || config.signed_policy || config.drm_policy
278
280
  const maxSupportedResolution = RESOLUTION_TIERS.findIndex(
279
- (rt) => rt.value === pluginConfig.max_resolution_tier
281
+ (rt) => rt.value === pluginConfig.max_resolution_tier,
280
282
  )
281
283
  return (
282
284
  <Dialog
@@ -314,11 +316,11 @@ export default function UploadConfiguration({
314
316
  <DocumentVideoIcon fontSize="2em" />
315
317
  <Stack space={2}>
316
318
  <Text textOverflow="ellipsis" as="h2" size={3}>
317
- {stagedUpload.type === 'file' ? stagedUpload.files[0].name : stagedUpload.url}
319
+ {stagedUpload.type === 'file' ? stagedUpload.files[0]!.name : stagedUpload.url}
318
320
  </Text>
319
321
  <Text as="p" size={1} muted>
320
322
  {stagedUpload.type === 'file'
321
- ? `Direct File Upload (${formatBytes(stagedUpload.files[0].size)})`
323
+ ? `Direct File Upload (${formatBytes(stagedUpload.files[0]!.size)})`
322
324
  : (() => {
323
325
  if (videoAssetMetadata?.size) {
324
326
  return `File From URL (${formatBytes(videoAssetMetadata.size)})`
@@ -456,7 +458,7 @@ export default function UploadConfiguration({
456
458
 
457
459
  function setAdvancedPlaybackPolicy(
458
460
  config: UploadConfig,
459
- secrets: Secrets
461
+ secrets: Secrets,
460
462
  ): MuxNewAssetSettings['advanced_playback_policies'] {
461
463
  const advanced_playback_policies: MuxNewAssetSettings['advanced_playback_policies'] = []
462
464
  if (config.public_policy) {
@@ -481,7 +483,7 @@ function setAdvancedPlaybackPolicy(
481
483
  function formatUploadConfig(
482
484
  config: UploadConfig,
483
485
  secrets: Secrets,
484
- options?: {videoAspectRatio?: number | null}
486
+ options?: {videoAspectRatio?: number | null},
485
487
  ): {
486
488
  settings: MuxNewAssetSettings
487
489
  watermark?: WatermarkConfig
@@ -512,7 +514,7 @@ function formatUploadConfig(
512
514
  }
513
515
  return acc
514
516
  },
515
- [] as NonNullable<MuxNewAssetSettings['input']>
517
+ [] as NonNullable<MuxNewAssetSettings['input']>,
516
518
  ),
517
519
  ]
518
520
 
@@ -633,7 +635,7 @@ const WatermarkPreview = memo(function WatermarkPreview({
633
635
  useEffect(() => {
634
636
  if (videoRef.current && stagedUpload.type === 'file') {
635
637
  const file = stagedUpload.files[0]
636
- const url = URL.createObjectURL(file)
638
+ const url = URL.createObjectURL(file!)
637
639
  videoRef.current.src = url
638
640
 
639
641
  return () => {
@@ -4,7 +4,7 @@ import {useCallback} from 'react'
4
4
 
5
5
  import {useAccessControl} from '../hooks/useAccessControl'
6
6
  import type {SetDialogState} from '../hooks/useDialogState'
7
- import {PluginConfig} from '../util/types'
7
+ import {type PluginConfig} from '../util/types'
8
8
  import {FileInputButton, type FileInputButtonProps} from './FileInputButton'
9
9
 
10
10
  function formatAcceptString(accept: string): string {
@@ -4,22 +4,22 @@ import {Button, Card, Code, Flex, Inline, Stack, Text} from '@sanity/ui'
4
4
  import {LinearProgress} from 'sanity'
5
5
  import {styled} from 'styled-components'
6
6
 
7
- export const CardWrapper = styled(Card)`
7
+ const CardWrapper = styled(Card)`
8
8
  min-height: 82px;
9
9
  box-sizing: border-box;
10
10
  `
11
11
 
12
- export const FlexWrapper = styled(Flex)`
12
+ const FlexWrapper = styled(Flex)`
13
13
  text-overflow: ellipsis;
14
14
  overflow: hidden;
15
15
  `
16
16
 
17
- export const LeftSection = styled(Stack)`
17
+ const LeftSection = styled(Stack)`
18
18
  position: relative;
19
19
  width: 60%;
20
20
  `
21
21
 
22
- export const CodeWrapper = styled(Code)`
22
+ const CodeWrapper = styled(Code)`
23
23
  position: relative;
24
24
  width: 100%;
25
25
 
@@ -1,4 +1,3 @@
1
- /* eslint-disable no-nested-ternary */
2
1
  import {Card, type CardTone} from '@sanity/ui'
3
2
  import React, {forwardRef, useCallback, useRef} from 'react'
4
3
  import {styled} from 'styled-components'
@@ -51,7 +50,7 @@ export const UploadCard = forwardRef<HTMLDivElement, UploadCardProps>(
51
50
  {children}
52
51
  </UploadCardWithFocusRing>
53
52
  )
54
- }
53
+ },
55
54
  )
56
55
 
57
56
  const HiddenInput = styled.input.attrs({type: 'text'})`