sanity-plugin-mux-input 3.0.5 → 4.0.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.
- package/dist/index.js +28 -28
- package/dist/index.js.map +1 -1
- package/package.json +5 -15
- package/dist/index.cjs +0 -5746
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -288
- package/dist/index.d.cts.map +0 -1
- package/sanity.json +0 -8
- package/src/_exports/index.ts +0 -73
- package/src/actions/assets.ts +0 -152
- package/src/actions/secrets.ts +0 -110
- package/src/actions/upload.ts +0 -308
- package/src/clients/upChunkObservable.ts +0 -54
- package/src/components/AddCaptionDialog.tsx +0 -440
- package/src/components/CaptionsDialog.tsx +0 -23
- package/src/components/ConfigureApi.styled.tsx +0 -19
- package/src/components/ConfigureApi.tsx +0 -296
- package/src/components/DraggableWatermark.tsx +0 -885
- package/src/components/EditCaptionDialog.tsx +0 -511
- package/src/components/EditThumbnailDialog.tsx +0 -121
- package/src/components/ErrorBoundaryCard.tsx +0 -97
- package/src/components/FileInputButton.tsx +0 -54
- package/src/components/FileInputMenuItem.styled.tsx +0 -36
- package/src/components/FileInputMenuItem.tsx +0 -85
- package/src/components/FormField.tsx +0 -38
- package/src/components/IconInfo.tsx +0 -22
- package/src/components/ImportVideosFromMux.tsx +0 -339
- package/src/components/Input.styled.tsx +0 -22
- package/src/components/Input.tsx +0 -78
- package/src/components/InputBrowser.tsx +0 -41
- package/src/components/MuxLogo.tsx +0 -42
- package/src/components/Onboard.tsx +0 -65
- package/src/components/PageSelector.tsx +0 -54
- package/src/components/Player.styled.tsx +0 -11
- package/src/components/Player.tsx +0 -117
- package/src/components/PlayerActionsMenu.tsx +0 -191
- package/src/components/ResyncMetadata.tsx +0 -278
- package/src/components/SelectAsset.tsx +0 -39
- package/src/components/SelectSortOptions.tsx +0 -45
- package/src/components/SpinnerBox.tsx +0 -16
- package/src/components/StudioTool.tsx +0 -24
- package/src/components/TextTracksEditor.tsx +0 -117
- package/src/components/TextTracksManager.tsx +0 -738
- package/src/components/UploadConfiguration.tsx +0 -696
- package/src/components/UploadPlaceholder.tsx +0 -88
- package/src/components/UploadProgress.tsx +0 -80
- package/src/components/Uploader.styled.tsx +0 -65
- package/src/components/Uploader.tsx +0 -499
- package/src/components/VideoDetails/DeleteDialog.tsx +0 -148
- package/src/components/VideoDetails/VideoDetails.tsx +0 -358
- package/src/components/VideoDetails/VideoReferences.tsx +0 -63
- package/src/components/VideoDetails/useVideoDetails.ts +0 -103
- package/src/components/VideoInBrowser.tsx +0 -245
- package/src/components/VideoMetadata.tsx +0 -45
- package/src/components/VideoPlayer.tsx +0 -241
- package/src/components/VideoThumbnail.tsx +0 -139
- package/src/components/VideosBrowser.tsx +0 -100
- package/src/components/documentPreview/DocumentPreview.tsx +0 -84
- package/src/components/documentPreview/DraftStatus.tsx +0 -34
- package/src/components/documentPreview/MissingSchemaType.tsx +0 -32
- package/src/components/documentPreview/PaneItemPreview.tsx +0 -67
- package/src/components/documentPreview/PublishedStatus.tsx +0 -35
- package/src/components/documentPreview/TimeAgo.tsx +0 -12
- package/src/components/icons/Audio.tsx +0 -13
- package/src/components/icons/Resolution.tsx +0 -12
- package/src/components/icons/StopWatch.tsx +0 -20
- package/src/components/icons/ToolIcon.tsx +0 -19
- package/src/components/uploadConfiguration/PlaybackPolicy.tsx +0 -133
- package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +0 -76
- package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +0 -29
- package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +0 -72
- package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +0 -180
- package/src/components/withFocusRing/helpers.ts +0 -24
- package/src/components/withFocusRing/index.ts +0 -1
- package/src/components/withFocusRing/withFocusRing.ts +0 -30
- package/src/context/DialogStateContext.tsx +0 -33
- package/src/context/DrmPlaybackWarningContext.tsx +0 -97
- package/src/hooks/useAccessControl.ts +0 -13
- package/src/hooks/useAssetDocumentValues.ts +0 -11
- package/src/hooks/useAssets.ts +0 -73
- package/src/hooks/useCancelUpload.ts +0 -22
- package/src/hooks/useClient.ts +0 -8
- package/src/hooks/useDialogState.ts +0 -11
- package/src/hooks/useDocReferences.ts +0 -21
- package/src/hooks/useFetchFileSize.ts +0 -55
- package/src/hooks/useImportMuxAssets.ts +0 -132
- package/src/hooks/useInView.ts +0 -41
- package/src/hooks/useMediaMetadata.ts +0 -104
- package/src/hooks/useMuxAssets.ts +0 -179
- package/src/hooks/useMuxPolling.ts +0 -52
- package/src/hooks/useResyncAsset.ts +0 -110
- package/src/hooks/useResyncMuxMetadata.ts +0 -169
- package/src/hooks/useSaveSecrets.ts +0 -78
- package/src/hooks/useSecretsDocumentValues.ts +0 -38
- package/src/hooks/useSecretsFormState.ts +0 -47
- package/src/plugin.tsx +0 -31
- package/src/sanity-ui.d.ts +0 -5
- package/src/schema.ts +0 -196
- package/src/util/addKeysToMuxData.ts +0 -30
- package/src/util/asserters.ts +0 -23
- package/src/util/assetTitlePlaceholder.ts +0 -31
- package/src/util/constants.ts +0 -15
- package/src/util/convertWatermarkToMux.ts +0 -160
- package/src/util/createSearchFilter.ts +0 -76
- package/src/util/createUrlParamsObject.ts +0 -29
- package/src/util/extractFiles.ts +0 -67
- package/src/util/formatBytes.ts +0 -31
- package/src/util/formatDriveShareLink.ts +0 -64
- package/src/util/formatSeconds.ts +0 -48
- package/src/util/generateJwt.ts +0 -57
- package/src/util/getAnimatedPosterSrc.ts +0 -26
- package/src/util/getPlaybackPolicy.ts +0 -69
- package/src/util/getPosterSrc.ts +0 -28
- package/src/util/getVideoMetadata.ts +0 -23
- package/src/util/getVideoSrc.ts +0 -23
- package/src/util/parsers.ts +0 -5
- package/src/util/pluginVersion.ts +0 -5
- package/src/util/readSecrets.ts +0 -38
- package/src/util/roundPxString.ts +0 -16
- package/src/util/textTracks.ts +0 -222
- package/src/util/tryWithSuspend.ts +0 -22
- package/src/util/types.ts +0 -566
- package/v2-incompatible.js +0 -11
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CalendarIcon,
|
|
3
|
-
CheckmarkIcon,
|
|
4
|
-
ClockIcon,
|
|
5
|
-
CropIcon,
|
|
6
|
-
EditIcon,
|
|
7
|
-
ErrorOutlineIcon,
|
|
8
|
-
RevertIcon,
|
|
9
|
-
SearchIcon,
|
|
10
|
-
SyncIcon,
|
|
11
|
-
TagIcon,
|
|
12
|
-
TrashIcon,
|
|
13
|
-
} from '@sanity/icons'
|
|
14
|
-
import {
|
|
15
|
-
Button,
|
|
16
|
-
Card,
|
|
17
|
-
Dialog,
|
|
18
|
-
Flex,
|
|
19
|
-
Heading,
|
|
20
|
-
Spinner,
|
|
21
|
-
Stack,
|
|
22
|
-
Tab,
|
|
23
|
-
TabList,
|
|
24
|
-
TabPanel,
|
|
25
|
-
Text,
|
|
26
|
-
TextInput,
|
|
27
|
-
} from '@sanity/ui'
|
|
28
|
-
import React, {useEffect, useState} from 'react'
|
|
29
|
-
|
|
30
|
-
import {DIALOGS_Z_INDEX} from '../../util/constants'
|
|
31
|
-
import type {MuxPlaybackId, MuxTextTrack, PlaybackPolicy} from '../../util/types'
|
|
32
|
-
import FormField from '../FormField'
|
|
33
|
-
import IconInfo from '../IconInfo'
|
|
34
|
-
import {ResolutionIcon} from '../icons/Resolution'
|
|
35
|
-
import {StopWatchIcon} from '../icons/StopWatch'
|
|
36
|
-
import TextTracksManager from '../TextTracksManager'
|
|
37
|
-
import VideoPlayer from '../VideoPlayer'
|
|
38
|
-
import DeleteDialog from './DeleteDialog'
|
|
39
|
-
import useVideoDetails, {type VideoDetailsProps} from './useVideoDetails'
|
|
40
|
-
import VideoReferences from './VideoReferences'
|
|
41
|
-
|
|
42
|
-
const AssetInput: React.FC<{
|
|
43
|
-
label: string
|
|
44
|
-
description?: string
|
|
45
|
-
placeholder?: string
|
|
46
|
-
value: string
|
|
47
|
-
onInput: (e: React.FormEvent<HTMLInputElement>) => void
|
|
48
|
-
disabled?: boolean
|
|
49
|
-
}> = (props) => (
|
|
50
|
-
<FormField title={props.label} description={props.description} inputId={props.label}>
|
|
51
|
-
<TextInput
|
|
52
|
-
id={props.label}
|
|
53
|
-
value={props.value}
|
|
54
|
-
placeholder={props.placeholder}
|
|
55
|
-
onInput={props.onInput}
|
|
56
|
-
disabled={props.disabled}
|
|
57
|
-
/>
|
|
58
|
-
</FormField>
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
const VideoDetails: React.FC<VideoDetailsProps> = (props) => {
|
|
62
|
-
const [tab, setTab] = useState<'details' | 'references'>('details')
|
|
63
|
-
const {
|
|
64
|
-
displayInfo,
|
|
65
|
-
filename,
|
|
66
|
-
modified,
|
|
67
|
-
references,
|
|
68
|
-
referencesLoading,
|
|
69
|
-
setFilename,
|
|
70
|
-
state,
|
|
71
|
-
setState,
|
|
72
|
-
handleClose,
|
|
73
|
-
confirmClose,
|
|
74
|
-
saveChanges,
|
|
75
|
-
handleResync,
|
|
76
|
-
isResyncing,
|
|
77
|
-
} = useVideoDetails(props)
|
|
78
|
-
|
|
79
|
-
const isSaving = state === 'saving'
|
|
80
|
-
|
|
81
|
-
// Avoid layout shifts in large screens' 2-column dialog by setting their `minHeight` to the container's
|
|
82
|
-
const [containerHeight, setContainerHeight] = useState<number | null>(null)
|
|
83
|
-
const contentsRef = React.useRef<HTMLDivElement>(null)
|
|
84
|
-
useEffect(() => {
|
|
85
|
-
if (!contentsRef.current || !('getBoundingClientRect' in contentsRef.current)) return
|
|
86
|
-
|
|
87
|
-
setContainerHeight(contentsRef.current.getBoundingClientRect().height)
|
|
88
|
-
}, [])
|
|
89
|
-
|
|
90
|
-
return (
|
|
91
|
-
<Dialog
|
|
92
|
-
animate
|
|
93
|
-
header={displayInfo.title}
|
|
94
|
-
zOffset={DIALOGS_Z_INDEX}
|
|
95
|
-
id="video-details-dialog"
|
|
96
|
-
onClose={handleClose}
|
|
97
|
-
onClickOutside={handleClose}
|
|
98
|
-
width={2}
|
|
99
|
-
position="fixed"
|
|
100
|
-
footer={
|
|
101
|
-
<Card padding={3}>
|
|
102
|
-
<Flex justify="space-between" align="center">
|
|
103
|
-
<Flex gap={2}>
|
|
104
|
-
<Button
|
|
105
|
-
icon={TrashIcon}
|
|
106
|
-
fontSize={2}
|
|
107
|
-
padding={3}
|
|
108
|
-
mode="bleed"
|
|
109
|
-
text="Delete"
|
|
110
|
-
tone="critical"
|
|
111
|
-
onClick={() => setState('deleting')}
|
|
112
|
-
disabled={isSaving || isResyncing}
|
|
113
|
-
/>
|
|
114
|
-
<Button
|
|
115
|
-
icon={SyncIcon}
|
|
116
|
-
fontSize={2}
|
|
117
|
-
padding={3}
|
|
118
|
-
mode="bleed"
|
|
119
|
-
text="Resync"
|
|
120
|
-
tone="primary"
|
|
121
|
-
onClick={handleResync}
|
|
122
|
-
disabled={isSaving || isResyncing}
|
|
123
|
-
iconRight={isResyncing && Spinner}
|
|
124
|
-
/>
|
|
125
|
-
</Flex>
|
|
126
|
-
{modified && (
|
|
127
|
-
<Button
|
|
128
|
-
icon={CheckmarkIcon}
|
|
129
|
-
fontSize={2}
|
|
130
|
-
padding={3}
|
|
131
|
-
mode="ghost"
|
|
132
|
-
text="Save and close"
|
|
133
|
-
tone="positive"
|
|
134
|
-
onClick={saveChanges}
|
|
135
|
-
iconRight={isSaving && Spinner}
|
|
136
|
-
disabled={isSaving || isResyncing}
|
|
137
|
-
/>
|
|
138
|
-
)}
|
|
139
|
-
</Flex>
|
|
140
|
-
</Card>
|
|
141
|
-
}
|
|
142
|
-
>
|
|
143
|
-
{/* DELETION DIALOG */}
|
|
144
|
-
{state === 'deleting' && (
|
|
145
|
-
<DeleteDialog
|
|
146
|
-
asset={props.asset}
|
|
147
|
-
cancelDelete={() => setState('idle')}
|
|
148
|
-
referencesLoading={referencesLoading}
|
|
149
|
-
references={references}
|
|
150
|
-
succeededDeleting={() => {
|
|
151
|
-
props.closeDialog()
|
|
152
|
-
}}
|
|
153
|
-
/>
|
|
154
|
-
)}
|
|
155
|
-
|
|
156
|
-
{/* CONFIRM CLOSING DIALOG */}
|
|
157
|
-
{state === 'closing' && (
|
|
158
|
-
<Dialog
|
|
159
|
-
animate
|
|
160
|
-
header={'You have unsaved changes'}
|
|
161
|
-
zOffset={DIALOGS_Z_INDEX}
|
|
162
|
-
id="closing-video-details-dialog"
|
|
163
|
-
onClose={() => confirmClose(false)}
|
|
164
|
-
onClickOutside={() => confirmClose(false)}
|
|
165
|
-
width={1}
|
|
166
|
-
position="fixed"
|
|
167
|
-
footer={
|
|
168
|
-
<Card padding={3}>
|
|
169
|
-
<Flex justify="space-between" align="center">
|
|
170
|
-
<Button
|
|
171
|
-
icon={ErrorOutlineIcon}
|
|
172
|
-
fontSize={2}
|
|
173
|
-
padding={3}
|
|
174
|
-
text="Discard changes"
|
|
175
|
-
tone="critical"
|
|
176
|
-
onClick={() => confirmClose(true)}
|
|
177
|
-
/>
|
|
178
|
-
{modified && (
|
|
179
|
-
<Button
|
|
180
|
-
icon={RevertIcon}
|
|
181
|
-
fontSize={2}
|
|
182
|
-
padding={3}
|
|
183
|
-
mode="ghost"
|
|
184
|
-
text="Keep editing"
|
|
185
|
-
tone="primary"
|
|
186
|
-
onClick={() => confirmClose(false)}
|
|
187
|
-
/>
|
|
188
|
-
)}
|
|
189
|
-
</Flex>
|
|
190
|
-
</Card>
|
|
191
|
-
}
|
|
192
|
-
>
|
|
193
|
-
<Card padding={5}>
|
|
194
|
-
<Stack style={{textAlign: 'center'}} space={3}>
|
|
195
|
-
<Heading size={2}>Unsaved changes will be lost</Heading>
|
|
196
|
-
<Text size={2}>Are you sure you want to discard them?</Text>
|
|
197
|
-
</Stack>
|
|
198
|
-
</Card>
|
|
199
|
-
</Dialog>
|
|
200
|
-
)}
|
|
201
|
-
<Card
|
|
202
|
-
padding={4}
|
|
203
|
-
sizing="border"
|
|
204
|
-
style={{
|
|
205
|
-
containerType: 'inline-size',
|
|
206
|
-
}}
|
|
207
|
-
>
|
|
208
|
-
<Flex
|
|
209
|
-
sizing="border"
|
|
210
|
-
gap={4}
|
|
211
|
-
direction={['column', 'column', 'row']}
|
|
212
|
-
align="flex-start"
|
|
213
|
-
ref={contentsRef}
|
|
214
|
-
style={
|
|
215
|
-
typeof containerHeight === 'number'
|
|
216
|
-
? {
|
|
217
|
-
minHeight: containerHeight,
|
|
218
|
-
}
|
|
219
|
-
: undefined
|
|
220
|
-
}
|
|
221
|
-
>
|
|
222
|
-
<Stack space={4} flex={1} sizing="border">
|
|
223
|
-
<VideoPlayer asset={props.asset} autoPlay={props.asset.autoPlay || false} />
|
|
224
|
-
{tab === 'details' && (
|
|
225
|
-
<TextTracksManager
|
|
226
|
-
asset={props.asset}
|
|
227
|
-
iconOnly
|
|
228
|
-
collapseTracks
|
|
229
|
-
tracks={
|
|
230
|
-
displayInfo?.text_tracks ||
|
|
231
|
-
props.asset.data?.tracks?.filter(
|
|
232
|
-
(track): track is MuxTextTrack => track.type === 'text',
|
|
233
|
-
) ||
|
|
234
|
-
[]
|
|
235
|
-
}
|
|
236
|
-
/>
|
|
237
|
-
)}
|
|
238
|
-
</Stack>
|
|
239
|
-
<Stack space={4} flex={1} sizing="border">
|
|
240
|
-
<TabList space={2}>
|
|
241
|
-
<Tab
|
|
242
|
-
aria-controls="details-panel"
|
|
243
|
-
icon={EditIcon}
|
|
244
|
-
id="details-tab"
|
|
245
|
-
label="Details"
|
|
246
|
-
onClick={() => setTab('details')}
|
|
247
|
-
selected={tab === 'details'}
|
|
248
|
-
/>
|
|
249
|
-
<Tab
|
|
250
|
-
aria-controls="references-panel"
|
|
251
|
-
icon={SearchIcon}
|
|
252
|
-
id="references-tab"
|
|
253
|
-
label={`Used by ${references ? `(${references.length})` : ''}`}
|
|
254
|
-
onClick={() => setTab('references')}
|
|
255
|
-
selected={tab === 'references'}
|
|
256
|
-
/>
|
|
257
|
-
</TabList>
|
|
258
|
-
<TabPanel
|
|
259
|
-
aria-labelledby="details-tab"
|
|
260
|
-
id="details-panel"
|
|
261
|
-
hidden={tab !== 'details'}
|
|
262
|
-
style={{wordBreak: 'break-word'}}
|
|
263
|
-
>
|
|
264
|
-
<Stack space={4}>
|
|
265
|
-
<AssetInput
|
|
266
|
-
label="Video title or file name"
|
|
267
|
-
description="Not visible to users. Useful for finding videos later."
|
|
268
|
-
value={filename || ''}
|
|
269
|
-
onInput={(e) => setFilename(e.currentTarget.value)}
|
|
270
|
-
disabled={state !== 'idle'}
|
|
271
|
-
/>
|
|
272
|
-
<Stack space={3}>
|
|
273
|
-
{displayInfo?.duration && (
|
|
274
|
-
<IconInfo
|
|
275
|
-
text={`Duration: ${displayInfo.duration}`}
|
|
276
|
-
icon={ClockIcon}
|
|
277
|
-
size={2}
|
|
278
|
-
/>
|
|
279
|
-
)}
|
|
280
|
-
{displayInfo?.max_stored_resolution && (
|
|
281
|
-
<IconInfo
|
|
282
|
-
text={`Max Resolution: ${displayInfo.max_stored_resolution}`}
|
|
283
|
-
icon={ResolutionIcon}
|
|
284
|
-
size={2}
|
|
285
|
-
/>
|
|
286
|
-
)}
|
|
287
|
-
{displayInfo?.max_stored_frame_rate && (
|
|
288
|
-
<IconInfo
|
|
289
|
-
text={`Frame rate: ${displayInfo.max_stored_frame_rate}`}
|
|
290
|
-
icon={StopWatchIcon}
|
|
291
|
-
size={2}
|
|
292
|
-
/>
|
|
293
|
-
)}
|
|
294
|
-
{displayInfo?.aspect_ratio && (
|
|
295
|
-
<IconInfo
|
|
296
|
-
text={`Aspect Ratio: ${displayInfo.aspect_ratio}`}
|
|
297
|
-
icon={CropIcon}
|
|
298
|
-
size={2}
|
|
299
|
-
/>
|
|
300
|
-
)}
|
|
301
|
-
<IconInfo
|
|
302
|
-
text={`Uploaded on: ${displayInfo.createdAt.toLocaleDateString('en', {
|
|
303
|
-
year: 'numeric',
|
|
304
|
-
month: '2-digit',
|
|
305
|
-
day: '2-digit',
|
|
306
|
-
hour: '2-digit',
|
|
307
|
-
minute: '2-digit',
|
|
308
|
-
hour12: true,
|
|
309
|
-
})}`}
|
|
310
|
-
icon={CalendarIcon}
|
|
311
|
-
size={2}
|
|
312
|
-
/>
|
|
313
|
-
<IconInfo text={`Mux ID: \n${displayInfo.id}`} icon={TagIcon} size={2} />
|
|
314
|
-
<PlaybackIds playback_ids={displayInfo.playback_ids} />
|
|
315
|
-
</Stack>
|
|
316
|
-
</Stack>
|
|
317
|
-
</TabPanel>
|
|
318
|
-
<TabPanel
|
|
319
|
-
aria-labelledby="references-tab"
|
|
320
|
-
id="references-panel"
|
|
321
|
-
hidden={tab !== 'references'}
|
|
322
|
-
>
|
|
323
|
-
<VideoReferences references={references} isLoaded={!referencesLoading} />
|
|
324
|
-
</TabPanel>
|
|
325
|
-
</Stack>
|
|
326
|
-
</Flex>
|
|
327
|
-
</Card>
|
|
328
|
-
</Dialog>
|
|
329
|
-
)
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
const PlaybackIds = ({playback_ids}: {playback_ids?: MuxPlaybackId[]}) => {
|
|
333
|
-
if (playback_ids) {
|
|
334
|
-
return playback_ids.map((entry) => (
|
|
335
|
-
<IconInfo
|
|
336
|
-
key={entry.id}
|
|
337
|
-
text={`Playback ID [${policyToText(entry.policy)}]: ${entry.id}`}
|
|
338
|
-
icon={TagIcon}
|
|
339
|
-
size={2}
|
|
340
|
-
/>
|
|
341
|
-
))
|
|
342
|
-
}
|
|
343
|
-
return <IconInfo text={'No Playback ID'} icon={TagIcon} size={2} />
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const policyToText = (policy: PlaybackPolicy) => {
|
|
347
|
-
switch (policy) {
|
|
348
|
-
case 'drm':
|
|
349
|
-
return 'DRM'
|
|
350
|
-
case 'signed':
|
|
351
|
-
return 'Signed'
|
|
352
|
-
case 'public':
|
|
353
|
-
return 'Public'
|
|
354
|
-
default:
|
|
355
|
-
return policy
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
export default VideoDetails
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import type {SanityDocument} from '@sanity/client'
|
|
2
|
-
import {Box, Card, Text} from '@sanity/ui'
|
|
3
|
-
import {collate, useSchema} from 'sanity'
|
|
4
|
-
import {styled} from 'styled-components'
|
|
5
|
-
|
|
6
|
-
import {DocumentPreview} from '../documentPreview/DocumentPreview'
|
|
7
|
-
import SpinnerBox from '../SpinnerBox'
|
|
8
|
-
|
|
9
|
-
const Container = styled(Box)`
|
|
10
|
-
* {
|
|
11
|
-
color: ${(props: any) => props.theme.sanity.color.base.fg};
|
|
12
|
-
}
|
|
13
|
-
a {
|
|
14
|
-
text-decoration: none;
|
|
15
|
-
}
|
|
16
|
-
h2 {
|
|
17
|
-
font-size: ${(props: any) => props.theme.sanity.fonts.text.sizes[1]};
|
|
18
|
-
}
|
|
19
|
-
`
|
|
20
|
-
|
|
21
|
-
const VideoReferences: React.FC<{
|
|
22
|
-
references?: SanityDocument[]
|
|
23
|
-
isLoaded: boolean
|
|
24
|
-
}> = (props) => {
|
|
25
|
-
const schema = useSchema()
|
|
26
|
-
if (!props.isLoaded) {
|
|
27
|
-
return <SpinnerBox />
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if (!props.references?.length) {
|
|
31
|
-
return (
|
|
32
|
-
<Card border radius={3} padding={3}>
|
|
33
|
-
<Text size={2}>No documents are using this video</Text>
|
|
34
|
-
</Card>
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const documentPairs = collate(props.references || [])
|
|
39
|
-
return (
|
|
40
|
-
<Container>
|
|
41
|
-
{documentPairs?.map((documentPair) => {
|
|
42
|
-
const schemaType = schema.get(documentPair.type)
|
|
43
|
-
|
|
44
|
-
return (
|
|
45
|
-
<Card
|
|
46
|
-
key={documentPair.id}
|
|
47
|
-
marginBottom={2}
|
|
48
|
-
padding={2}
|
|
49
|
-
radius={2}
|
|
50
|
-
shadow={1}
|
|
51
|
-
style={{overflow: 'hidden'}}
|
|
52
|
-
>
|
|
53
|
-
<Box>
|
|
54
|
-
<DocumentPreview documentPair={documentPair} schemaType={schemaType} />
|
|
55
|
-
</Box>
|
|
56
|
-
</Card>
|
|
57
|
-
)
|
|
58
|
-
})}
|
|
59
|
-
</Container>
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export default VideoReferences
|
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
import {useToast} from '@sanity/ui'
|
|
2
|
-
import {useMemo, useState} from 'react'
|
|
3
|
-
import {useDocumentStore} from 'sanity'
|
|
4
|
-
|
|
5
|
-
import {useClient} from '../../hooks/useClient'
|
|
6
|
-
import useDocReferences from '../../hooks/useDocReferences'
|
|
7
|
-
import {useResyncAsset} from '../../hooks/useResyncAsset'
|
|
8
|
-
import getVideoMetadata from '../../util/getVideoMetadata'
|
|
9
|
-
import {type VideoAssetDocument} from '../../util/types'
|
|
10
|
-
|
|
11
|
-
type VideoDetailsState = 'idle' | 'saving' | 'deleting' | 'closing' | 'resyncing'
|
|
12
|
-
|
|
13
|
-
export interface VideoDetailsProps {
|
|
14
|
-
closeDialog: () => void
|
|
15
|
-
asset: VideoAssetDocument & {autoPlay?: boolean}
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export default function useVideoDetails(props: VideoDetailsProps) {
|
|
19
|
-
const documentStore = useDocumentStore()
|
|
20
|
-
const toast = useToast()
|
|
21
|
-
const client = useClient()
|
|
22
|
-
|
|
23
|
-
const [references, referencesLoading] = useDocReferences(
|
|
24
|
-
useMemo(() => ({documentStore, id: props.asset._id}), [documentStore, props.asset._id]),
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
const [originalAsset, setOriginalAsset] = useState(() => props.asset)
|
|
28
|
-
const [filename, setFilename] = useState(props.asset.filename)
|
|
29
|
-
const modified = filename !== originalAsset.filename
|
|
30
|
-
|
|
31
|
-
const displayInfo = getVideoMetadata({...props.asset, filename})
|
|
32
|
-
|
|
33
|
-
const [state, setState] = useState<VideoDetailsState>('idle')
|
|
34
|
-
|
|
35
|
-
const {resyncAsset, isResyncing} = useResyncAsset({showToast: true})
|
|
36
|
-
|
|
37
|
-
async function handleResync() {
|
|
38
|
-
if (state !== 'idle') return
|
|
39
|
-
setState('resyncing')
|
|
40
|
-
await resyncAsset(props.asset)
|
|
41
|
-
setState('idle')
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
function handleClose() {
|
|
45
|
-
if (state !== 'idle') return
|
|
46
|
-
|
|
47
|
-
if (modified) {
|
|
48
|
-
setState('closing')
|
|
49
|
-
return
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
props.closeDialog()
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
function confirmClose(shouldClose: boolean) {
|
|
56
|
-
if (state !== 'closing') return
|
|
57
|
-
|
|
58
|
-
if (shouldClose) props.closeDialog()
|
|
59
|
-
|
|
60
|
-
setState('idle')
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
async function saveChanges() {
|
|
64
|
-
if (state !== 'idle') return
|
|
65
|
-
setState('saving')
|
|
66
|
-
|
|
67
|
-
try {
|
|
68
|
-
await client.patch(props.asset._id).set({filename}).commit()
|
|
69
|
-
setOriginalAsset((prev) => ({...prev, filename}))
|
|
70
|
-
toast.push({
|
|
71
|
-
title: 'Video title updated',
|
|
72
|
-
description: `New title: ${filename}`,
|
|
73
|
-
status: 'success',
|
|
74
|
-
})
|
|
75
|
-
props.closeDialog()
|
|
76
|
-
} catch (error) {
|
|
77
|
-
toast.push({
|
|
78
|
-
title: 'Failed updating file name',
|
|
79
|
-
status: 'error',
|
|
80
|
-
description: typeof error === 'string' ? error : 'Please try again',
|
|
81
|
-
})
|
|
82
|
-
setFilename(originalAsset.filename)
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
setState('idle')
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
return {
|
|
89
|
-
references,
|
|
90
|
-
referencesLoading,
|
|
91
|
-
modified,
|
|
92
|
-
filename,
|
|
93
|
-
setFilename,
|
|
94
|
-
displayInfo,
|
|
95
|
-
state,
|
|
96
|
-
setState,
|
|
97
|
-
handleClose,
|
|
98
|
-
confirmClose,
|
|
99
|
-
saveChanges,
|
|
100
|
-
handleResync,
|
|
101
|
-
isResyncing,
|
|
102
|
-
}
|
|
103
|
-
}
|