sanity-plugin-mux-input 3.0.5 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/index.js +20 -92
  2. package/dist/index.js.map +1 -1
  3. package/package.json +5 -15
  4. package/dist/index.cjs +0 -5746
  5. package/dist/index.cjs.map +0 -1
  6. package/dist/index.d.cts +0 -288
  7. package/dist/index.d.cts.map +0 -1
  8. package/sanity.json +0 -8
  9. package/src/_exports/index.ts +0 -73
  10. package/src/actions/assets.ts +0 -152
  11. package/src/actions/secrets.ts +0 -110
  12. package/src/actions/upload.ts +0 -308
  13. package/src/clients/upChunkObservable.ts +0 -54
  14. package/src/components/AddCaptionDialog.tsx +0 -440
  15. package/src/components/CaptionsDialog.tsx +0 -23
  16. package/src/components/ConfigureApi.styled.tsx +0 -19
  17. package/src/components/ConfigureApi.tsx +0 -296
  18. package/src/components/DraggableWatermark.tsx +0 -885
  19. package/src/components/EditCaptionDialog.tsx +0 -511
  20. package/src/components/EditThumbnailDialog.tsx +0 -121
  21. package/src/components/ErrorBoundaryCard.tsx +0 -97
  22. package/src/components/FileInputButton.tsx +0 -54
  23. package/src/components/FileInputMenuItem.styled.tsx +0 -36
  24. package/src/components/FileInputMenuItem.tsx +0 -85
  25. package/src/components/FormField.tsx +0 -38
  26. package/src/components/IconInfo.tsx +0 -22
  27. package/src/components/ImportVideosFromMux.tsx +0 -339
  28. package/src/components/Input.styled.tsx +0 -22
  29. package/src/components/Input.tsx +0 -78
  30. package/src/components/InputBrowser.tsx +0 -41
  31. package/src/components/MuxLogo.tsx +0 -42
  32. package/src/components/Onboard.tsx +0 -65
  33. package/src/components/PageSelector.tsx +0 -54
  34. package/src/components/Player.styled.tsx +0 -11
  35. package/src/components/Player.tsx +0 -117
  36. package/src/components/PlayerActionsMenu.tsx +0 -191
  37. package/src/components/ResyncMetadata.tsx +0 -278
  38. package/src/components/SelectAsset.tsx +0 -39
  39. package/src/components/SelectSortOptions.tsx +0 -45
  40. package/src/components/SpinnerBox.tsx +0 -16
  41. package/src/components/StudioTool.tsx +0 -24
  42. package/src/components/TextTracksEditor.tsx +0 -117
  43. package/src/components/TextTracksManager.tsx +0 -738
  44. package/src/components/UploadConfiguration.tsx +0 -696
  45. package/src/components/UploadPlaceholder.tsx +0 -88
  46. package/src/components/UploadProgress.tsx +0 -80
  47. package/src/components/Uploader.styled.tsx +0 -65
  48. package/src/components/Uploader.tsx +0 -499
  49. package/src/components/VideoDetails/DeleteDialog.tsx +0 -148
  50. package/src/components/VideoDetails/VideoDetails.tsx +0 -358
  51. package/src/components/VideoDetails/VideoReferences.tsx +0 -63
  52. package/src/components/VideoDetails/useVideoDetails.ts +0 -103
  53. package/src/components/VideoInBrowser.tsx +0 -245
  54. package/src/components/VideoMetadata.tsx +0 -45
  55. package/src/components/VideoPlayer.tsx +0 -241
  56. package/src/components/VideoThumbnail.tsx +0 -139
  57. package/src/components/VideosBrowser.tsx +0 -100
  58. package/src/components/documentPreview/DocumentPreview.tsx +0 -84
  59. package/src/components/documentPreview/DraftStatus.tsx +0 -34
  60. package/src/components/documentPreview/MissingSchemaType.tsx +0 -32
  61. package/src/components/documentPreview/PaneItemPreview.tsx +0 -67
  62. package/src/components/documentPreview/PublishedStatus.tsx +0 -35
  63. package/src/components/documentPreview/TimeAgo.tsx +0 -12
  64. package/src/components/icons/Audio.tsx +0 -13
  65. package/src/components/icons/Resolution.tsx +0 -12
  66. package/src/components/icons/StopWatch.tsx +0 -20
  67. package/src/components/icons/ToolIcon.tsx +0 -19
  68. package/src/components/uploadConfiguration/PlaybackPolicy.tsx +0 -133
  69. package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +0 -76
  70. package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +0 -29
  71. package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +0 -72
  72. package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +0 -180
  73. package/src/components/withFocusRing/helpers.ts +0 -24
  74. package/src/components/withFocusRing/index.ts +0 -1
  75. package/src/components/withFocusRing/withFocusRing.ts +0 -30
  76. package/src/context/DialogStateContext.tsx +0 -33
  77. package/src/context/DrmPlaybackWarningContext.tsx +0 -97
  78. package/src/hooks/useAccessControl.ts +0 -13
  79. package/src/hooks/useAssetDocumentValues.ts +0 -11
  80. package/src/hooks/useAssets.ts +0 -73
  81. package/src/hooks/useCancelUpload.ts +0 -22
  82. package/src/hooks/useClient.ts +0 -8
  83. package/src/hooks/useDialogState.ts +0 -11
  84. package/src/hooks/useDocReferences.ts +0 -21
  85. package/src/hooks/useFetchFileSize.ts +0 -55
  86. package/src/hooks/useImportMuxAssets.ts +0 -132
  87. package/src/hooks/useInView.ts +0 -41
  88. package/src/hooks/useMediaMetadata.ts +0 -104
  89. package/src/hooks/useMuxAssets.ts +0 -179
  90. package/src/hooks/useMuxPolling.ts +0 -52
  91. package/src/hooks/useResyncAsset.ts +0 -110
  92. package/src/hooks/useResyncMuxMetadata.ts +0 -169
  93. package/src/hooks/useSaveSecrets.ts +0 -78
  94. package/src/hooks/useSecretsDocumentValues.ts +0 -38
  95. package/src/hooks/useSecretsFormState.ts +0 -47
  96. package/src/plugin.tsx +0 -31
  97. package/src/sanity-ui.d.ts +0 -5
  98. package/src/schema.ts +0 -196
  99. package/src/util/addKeysToMuxData.ts +0 -30
  100. package/src/util/asserters.ts +0 -23
  101. package/src/util/assetTitlePlaceholder.ts +0 -31
  102. package/src/util/constants.ts +0 -15
  103. package/src/util/convertWatermarkToMux.ts +0 -160
  104. package/src/util/createSearchFilter.ts +0 -76
  105. package/src/util/createUrlParamsObject.ts +0 -29
  106. package/src/util/extractFiles.ts +0 -67
  107. package/src/util/formatBytes.ts +0 -31
  108. package/src/util/formatDriveShareLink.ts +0 -64
  109. package/src/util/formatSeconds.ts +0 -48
  110. package/src/util/generateJwt.ts +0 -57
  111. package/src/util/getAnimatedPosterSrc.ts +0 -26
  112. package/src/util/getPlaybackPolicy.ts +0 -69
  113. package/src/util/getPosterSrc.ts +0 -28
  114. package/src/util/getVideoMetadata.ts +0 -23
  115. package/src/util/getVideoSrc.ts +0 -23
  116. package/src/util/parsers.ts +0 -5
  117. package/src/util/pluginVersion.ts +0 -5
  118. package/src/util/readSecrets.ts +0 -38
  119. package/src/util/roundPxString.ts +0 -16
  120. package/src/util/textTracks.ts +0 -222
  121. package/src/util/tryWithSuspend.ts +0 -22
  122. package/src/util/types.ts +0 -566
  123. package/v2-incompatible.js +0 -11
@@ -1,278 +0,0 @@
1
- import {CheckmarkCircleIcon, ErrorOutlineIcon, SyncIcon} from '@sanity/icons'
2
- import {Box, Button, Card, Dialog, Flex, Heading, Radio, Spinner, Stack, Text} from '@sanity/ui'
3
- import {useState} from 'react'
4
-
5
- import useResyncMuxMetadata from '../hooks/useResyncMuxMetadata'
6
- import {isEmptyOrPlaceholderTitle} from '../util/assetTitlePlaceholder'
7
- import {DIALOGS_Z_INDEX} from '../util/constants'
8
-
9
- type SyncOption = 'fillEmpty' | 'syncTitles' | 'fullResync'
10
-
11
- interface OptionCardProps {
12
- id: SyncOption
13
- selected: boolean
14
- onSelect: (id: SyncOption) => void
15
- title: string
16
- count: number
17
- description: string
18
- disabled?: boolean
19
- }
20
-
21
- function OptionCard({
22
- id,
23
- selected,
24
- onSelect,
25
- title,
26
- count,
27
- description,
28
- disabled,
29
- }: OptionCardProps) {
30
- return (
31
- <Card
32
- as="label"
33
- padding={3}
34
- radius={2}
35
- border
36
- tone={selected ? 'primary' : 'default'}
37
- style={{
38
- cursor: disabled ? 'not-allowed' : 'pointer',
39
- opacity: disabled ? 0.5 : 1,
40
- }}
41
- >
42
- <Flex gap={3} align="flex-start">
43
- <Box paddingTop={1}>
44
- <Radio
45
- checked={selected}
46
- onChange={() => onSelect(id)}
47
- disabled={disabled}
48
- name="sync-option"
49
- />
50
- </Box>
51
- <Stack space={2} flex={1}>
52
- <Flex align="center" gap={2}>
53
- <Text size={2} weight="semibold">
54
- {title} ({count})
55
- </Text>
56
- </Flex>
57
- <Text size={1} muted>
58
- {description}
59
- </Text>
60
- </Stack>
61
- </Flex>
62
- </Card>
63
- )
64
- }
65
-
66
- function ResyncMetadataDialog(props: ReturnType<typeof useResyncMuxMetadata>) {
67
- const {resyncState} = props
68
-
69
- const videosToUpdate = props.matchedAssets?.filter((m) => m.muxAsset).length || 0
70
- const videosWithEmptyOrPlaceholder =
71
- props.matchedAssets?.filter(
72
- (m) => m.muxAsset && m.muxTitle && isEmptyOrPlaceholderTitle(m.currentTitle, m.muxAsset.id),
73
- ).length || 0
74
-
75
- const hasEmptyTitles = videosWithEmptyOrPlaceholder > 0
76
- const defaultOption: SyncOption = hasEmptyTitles ? 'fillEmpty' : 'syncTitles'
77
- const [selectedOption, setSelectedOption] = useState<SyncOption>(defaultOption)
78
-
79
- const canTriggerResync = resyncState === 'idle' || resyncState === 'error'
80
- const isResyncing = resyncState === 'syncing'
81
- const isDone = resyncState === 'done'
82
- const isLoading = props.muxAssets.loading || props.sanityAssetsLoading
83
-
84
- const handleSync = () => {
85
- switch (selectedOption) {
86
- case 'fillEmpty':
87
- void props.syncOnlyEmpty()
88
- break
89
- case 'syncTitles':
90
- void props.syncAllVideos()
91
- break
92
- case 'fullResync':
93
- void props.syncFullData()
94
- break
95
- default:
96
- break
97
- }
98
- }
99
-
100
- return (
101
- <Dialog
102
- animate
103
- header="Sync with Mux"
104
- zOffset={DIALOGS_Z_INDEX}
105
- id="resync-metadata-dialog"
106
- onClose={props.closeDialog}
107
- onClickOutside={props.closeDialog}
108
- width={1}
109
- position="fixed"
110
- footer={
111
- !isDone && (
112
- <Card padding={3}>
113
- <Flex justify="flex-end" gap={2}>
114
- <Button
115
- fontSize={2}
116
- padding={3}
117
- mode="ghost"
118
- text="Cancel"
119
- onClick={props.closeDialog}
120
- disabled={isResyncing}
121
- />
122
- <Button
123
- icon={SyncIcon}
124
- fontSize={2}
125
- padding={3}
126
- text="Run sync"
127
- tone="primary"
128
- onClick={handleSync}
129
- iconRight={isResyncing && Spinner}
130
- disabled={!canTriggerResync || isLoading}
131
- />
132
- </Flex>
133
- </Card>
134
- )
135
- }
136
- >
137
- <Box padding={4}>
138
- {/* LOADING ASSETS STATE */}
139
- {isLoading && (
140
- <Card tone="primary" marginBottom={4} padding={3} border radius={2}>
141
- <Flex align="center" gap={4}>
142
- <Spinner muted size={4} />
143
- <Stack space={2}>
144
- <Text size={2} weight="semibold">
145
- Loading assets from Mux
146
- </Text>
147
- <Text size={1} muted>
148
- This may take a while.
149
- </Text>
150
- </Stack>
151
- </Flex>
152
- </Card>
153
- )}
154
-
155
- {/* ERROR LOADING MUX */}
156
- {props.muxAssets.error && (
157
- <Card tone="critical" marginBottom={4} padding={3} border radius={2}>
158
- <Flex align="center" gap={2}>
159
- <ErrorOutlineIcon fontSize={36} />
160
- <Stack space={2}>
161
- <Text size={2} weight="semibold">
162
- There was an error getting data from Mux
163
- </Text>
164
- <Text size={1}>Please try again or contact a developer for help.</Text>
165
- </Stack>
166
- </Flex>
167
- </Card>
168
- )}
169
-
170
- {/* SYNCING STATE */}
171
- {resyncState === 'syncing' && (
172
- <Card tone="primary" marginBottom={4} padding={3} border radius={2}>
173
- <Flex align="center" gap={4}>
174
- <Spinner muted size={4} />
175
- <Stack space={2}>
176
- <Text size={2} weight="semibold">
177
- Syncing metadata
178
- </Text>
179
- <Text size={1} muted>
180
- Updating videos from Mux...
181
- </Text>
182
- </Stack>
183
- </Flex>
184
- </Card>
185
- )}
186
-
187
- {/* ERROR SYNCING */}
188
- {resyncState === 'error' && (
189
- <Card tone="critical" marginBottom={4} padding={3} border radius={2}>
190
- <Flex align="center" gap={2}>
191
- <ErrorOutlineIcon fontSize={36} />
192
- <Stack space={2}>
193
- <Text size={2} weight="semibold">
194
- There was an error syncing metadata
195
- </Text>
196
- <Text size={1}>
197
- {props.resyncError
198
- ? `Error: ${props.resyncError}`
199
- : 'Please try again or contact a developer for help.'}
200
- </Text>
201
- </Stack>
202
- </Flex>
203
- </Card>
204
- )}
205
-
206
- {/* SUCCESS STATE */}
207
- {resyncState === 'done' && (
208
- <Stack paddingY={5} space={3} style={{textAlign: 'center'}}>
209
- <Box>
210
- <CheckmarkCircleIcon fontSize={48} />
211
- </Box>
212
- <Heading size={2}>Sync completed</Heading>
213
- <Text size={2} muted>
214
- Videos have been updated from Mux.
215
- </Text>
216
- </Stack>
217
- )}
218
-
219
- {/* OPTIONS */}
220
- {!isDone && !isLoading && !props.muxAssets.error && (
221
- <Stack space={4}>
222
- <Text size={1} muted>
223
- Found {videosToUpdate} video{videosToUpdate === 1 ? '' : 's'} linked to Mux.
224
- </Text>
225
-
226
- <Stack space={3}>
227
- {hasEmptyTitles && (
228
- <OptionCard
229
- id="fillEmpty"
230
- selected={selectedOption === 'fillEmpty'}
231
- onSelect={setSelectedOption}
232
- title="Fill missing titles only"
233
- count={videosWithEmptyOrPlaceholder}
234
- description="Updates only videos without a title or with placeholder titles (e.g., 'Asset #123') using the title from Mux."
235
- disabled={isResyncing}
236
- />
237
- )}
238
-
239
- <OptionCard
240
- id="syncTitles"
241
- selected={selectedOption === 'syncTitles'}
242
- onSelect={setSelectedOption}
243
- title="Sync all titles"
244
- count={videosToUpdate}
245
- description="Replaces the title in Sanity with the title from Mux for all videos."
246
- disabled={isResyncing}
247
- />
248
-
249
- <OptionCard
250
- id="fullResync"
251
- selected={selectedOption === 'fullResync'}
252
- onSelect={setSelectedOption}
253
- title="Full resync"
254
- count={videosToUpdate}
255
- description="Updates all fields from Mux including status, duration, tracks, captions, and renditions."
256
- disabled={isResyncing}
257
- />
258
- </Stack>
259
- </Stack>
260
- )}
261
- </Box>
262
- </Dialog>
263
- )
264
- }
265
-
266
- export default function ResyncMetadata() {
267
- const resyncMetadata = useResyncMuxMetadata()
268
-
269
- if (!resyncMetadata.hasSecrets) {
270
- return
271
- }
272
-
273
- if (resyncMetadata.dialogOpen) {
274
- return <ResyncMetadataDialog {...resyncMetadata} />
275
- }
276
-
277
- return <Button mode="bleed" text="Sync with Mux" onClick={resyncMetadata.openDialog} />
278
- }
@@ -1,39 +0,0 @@
1
- import {useCallback} from 'react'
2
- import {PatchEvent, set, setIfMissing, unset} from 'sanity'
3
-
4
- import type {SetDialogState} from '../hooks/useDialogState'
5
- import type {MuxInputProps, PluginConfig, VideoAssetDocument} from '../util/types'
6
- import VideosBrowser, {type VideosBrowserProps} from './VideosBrowser'
7
-
8
- export interface Props extends Pick<MuxInputProps, 'onChange'> {
9
- asset?: VideoAssetDocument | null | undefined
10
- setDialogState: SetDialogState
11
- config: PluginConfig
12
- }
13
-
14
- export default function SelectAssets({
15
- asset: selectedAsset,
16
- onChange,
17
- setDialogState,
18
- config,
19
- }: Props) {
20
- const handleSelect = useCallback<Required<VideosBrowserProps>['onSelect']>(
21
- (chosenAsset) => {
22
- if (!chosenAsset?._id) {
23
- onChange(PatchEvent.from([unset(['asset'])]))
24
- }
25
- if (chosenAsset._id !== selectedAsset?._id) {
26
- onChange(
27
- PatchEvent.from([
28
- setIfMissing({asset: {}, _type: 'mux.video'}),
29
- set({_type: 'reference', _weak: true, _ref: chosenAsset._id}, ['asset']),
30
- ]),
31
- )
32
- }
33
- setDialogState(false)
34
- },
35
- [onChange, setDialogState, selectedAsset],
36
- )
37
-
38
- return <VideosBrowser onSelect={handleSelect} config={config} />
39
- }
@@ -1,45 +0,0 @@
1
- import {SortIcon} from '@sanity/icons'
2
- import {Button, Menu, MenuButton, MenuItem, type PopoverProps} from '@sanity/ui'
3
- import {useId} from 'react'
4
-
5
- import {ASSET_SORT_OPTIONS, type SortOption} from '../hooks/useAssets'
6
-
7
- const CONTEXT_MENU_POPOVER_PROPS: PopoverProps = {
8
- constrainSize: true,
9
- placement: 'bottom',
10
- portal: true,
11
- width: 0,
12
- }
13
-
14
- /**
15
- * @sanity/ui components adapted from:
16
- * https://github.com/sanity-io/sanity/blob/next/packages/sanity/src/desk/components/pane/PaneContextMenuButton.tsx#L19
17
- */
18
- export function SelectSortOptions(props: {sort: SortOption; setSort: (s: SortOption) => void}) {
19
- const id = useId()
20
-
21
- return (
22
- <MenuButton
23
- button={
24
- <Button text="Sort" icon={SortIcon} mode="bleed" padding={3} style={{cursor: 'pointer'}} />
25
- }
26
- id={id}
27
- menu={
28
- <Menu>
29
- {Object.entries(ASSET_SORT_OPTIONS).map(([type, {label}]) => (
30
- <MenuItem
31
- key={type}
32
- data-as="button"
33
- onClick={() => props.setSort(type as SortOption)}
34
- padding={3}
35
- tone="default"
36
- text={label}
37
- pressed={type === props.sort}
38
- />
39
- ))}
40
- </Menu>
41
- }
42
- popover={CONTEXT_MENU_POPOVER_PROPS}
43
- />
44
- )
45
- }
@@ -1,16 +0,0 @@
1
- import {Box, Spinner} from '@sanity/ui'
2
-
3
- const SpinnerBox: React.FC = () => (
4
- <Box
5
- style={{
6
- display: 'flex',
7
- alignItems: 'center',
8
- justifyContent: 'center',
9
- minHeight: '150px',
10
- }}
11
- >
12
- <Spinner />
13
- </Box>
14
- )
15
-
16
- export default SpinnerBox
@@ -1,24 +0,0 @@
1
- import type {Tool} from 'sanity'
2
-
3
- import type {PluginConfig} from '../util/types'
4
- import ToolIcon from './icons/ToolIcon'
5
- import VideosBrowser from './VideosBrowser'
6
-
7
- const StudioTool: React.FC<PluginConfig> = (config) => {
8
- return <VideosBrowser config={config} />
9
- }
10
-
11
- export const DEFAULT_TOOL_CONFIG = {
12
- icon: ToolIcon,
13
- title: 'Videos',
14
- }
15
-
16
- export default function createStudioTool(config: PluginConfig): Tool {
17
- const toolConfig = typeof config.tool === 'object' ? config.tool : DEFAULT_TOOL_CONFIG
18
- return {
19
- name: 'mux',
20
- icon: toolConfig.icon || DEFAULT_TOOL_CONFIG.icon,
21
- title: toolConfig.title || DEFAULT_TOOL_CONFIG.title,
22
- component: (props: any) => <StudioTool {...config} {...props} />,
23
- }
24
- }
@@ -1,117 +0,0 @@
1
- import {TranslateIcon} from '@sanity/icons'
2
- import {Autocomplete, Box, Card, Checkbox, Flex, Stack, Text} from '@sanity/ui'
3
- import {uuid} from '@sanity/uuid'
4
- import LanguagesList from 'iso-639-1'
5
- import {type Dispatch} from 'react'
6
- import {FormField} from 'sanity'
7
-
8
- import {type PluginConfig, SUPPORTED_MUX_LANGUAGES, type UploadTextTrack} from '../util/types'
9
-
10
- const ALL_LANGUAGE_CODES = LanguagesList.getAllCodes().map((code) => ({
11
- value: code,
12
- label: LanguagesList.getNativeName(code),
13
- }))
14
-
15
- const SUBTITLE_LANGUAGES: Record<
16
- Extract<UploadTextTrack, {language_code: any}>['type'],
17
- {value: string; label: string}[]
18
- > = {
19
- autogenerated: SUPPORTED_MUX_LANGUAGES.map((lang) => ({
20
- value: lang.code,
21
- label: lang.label,
22
- })),
23
- subtitles: ALL_LANGUAGE_CODES,
24
- captions: ALL_LANGUAGE_CODES,
25
- }
26
-
27
- type TrackSubAction =
28
- | {subAction: 'add'; value: Partial<UploadTextTrack>}
29
- | {subAction: 'update'; value: Partial<UploadTextTrack>}
30
- | {subAction: 'delete'}
31
-
32
- export type TrackAction = {action: 'track'; id: string} & TrackSubAction
33
-
34
- export default function TextTracksEditor({
35
- tracks,
36
- dispatch,
37
- defaultLang,
38
- }: {
39
- /**
40
- * Although the schema for tracks is an array, which we'll eventually support to allow uploading
41
- * multiple custom subtitles, for now we only support a single auto-generated track.
42
- */
43
- tracks: (Partial<UploadTextTrack> & {_id: string})[]
44
- dispatch: Dispatch<TrackAction>
45
- defaultLang: PluginConfig['defaultAutogeneratedSubtitleLang']
46
- }) {
47
- const track = tracks[0]
48
- return (
49
- <FormField title="Auto-generated subtitle or caption" path={[]}>
50
- <Stack space={2}>
51
- <Flex align="center">
52
- <Checkbox
53
- id="include-autogenerated-track"
54
- style={{display: 'block'}}
55
- checked={!!track?.language_code}
56
- onChange={() => {
57
- if (track) {
58
- dispatch({action: 'track', id: track._id, subAction: 'delete'})
59
- } else {
60
- dispatch({
61
- action: 'track',
62
- id: uuid(),
63
- subAction: 'add',
64
- value: {
65
- type: 'autogenerated',
66
- name: defaultLang || undefined,
67
- language_code: defaultLang || undefined,
68
- },
69
- })
70
- }
71
- }}
72
- />
73
- <Box flex={1} paddingLeft={3}>
74
- <Text>
75
- <label htmlFor="checkbox">Generate captions</label>
76
- </Text>
77
- </Box>
78
- </Flex>
79
- {track && (
80
- <Autocomplete
81
- id={`text-tract-editor--language`}
82
- value={track.language_code}
83
- onChange={(newValue) =>
84
- dispatch({
85
- action: 'track',
86
- id: track._id,
87
- subAction: 'update',
88
- value: {
89
- language_code: newValue,
90
- name: LanguagesList.getNativeName(newValue),
91
- },
92
- })
93
- }
94
- options={SUBTITLE_LANGUAGES[track.type!]}
95
- icon={TranslateIcon}
96
- placeholder="Select language"
97
- filterOption={(query, option) =>
98
- option.label.toLowerCase().indexOf(query.toLowerCase()) > -1 ||
99
- option.value.toLowerCase().indexOf(query.toLowerCase()) > -1
100
- }
101
- openButton
102
- renderValue={(value) =>
103
- SUBTITLE_LANGUAGES[track.type!].find((l) => l.value === value)?.label || value
104
- }
105
- renderOption={(option) => (
106
- <Card data-as="button" padding={3} radius={2} tone="inherit">
107
- <Text size={2} textOverflow="ellipsis">
108
- {option.label} ({option.value})
109
- </Text>
110
- </Card>
111
- )}
112
- />
113
- )}
114
- </Stack>
115
- </FormField>
116
- )
117
- }