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,97 +0,0 @@
|
|
|
1
|
-
/* eslint-disable no-console */
|
|
2
|
-
import {Button, Card, Flex, Grid, Heading, Inline, Text, useToast} from '@sanity/ui'
|
|
3
|
-
import React, {memo, useCallback, useRef} from 'react'
|
|
4
|
-
import scrollIntoView from 'scroll-into-view-if-needed'
|
|
5
|
-
import {clear} from 'suspend-react'
|
|
6
|
-
import {useErrorBoundary} from 'use-error-boundary'
|
|
7
|
-
|
|
8
|
-
import {name} from '../util/constants'
|
|
9
|
-
import {type MuxInputProps} from '../util/types'
|
|
10
|
-
|
|
11
|
-
export interface Props extends Pick<MuxInputProps, 'schemaType'> {
|
|
12
|
-
children: React.ReactNode
|
|
13
|
-
}
|
|
14
|
-
function ErrorBoundaryCard(props: Props) {
|
|
15
|
-
const {children, schemaType} = props
|
|
16
|
-
const {push: pushToast} = useToast()
|
|
17
|
-
const errorRef = useRef(null)
|
|
18
|
-
const {ErrorBoundary, didCatch, error, reset} = useErrorBoundary({
|
|
19
|
-
// oxlint-disable-next-line no-unstable-nested-components
|
|
20
|
-
onDidCatch: (err, errorInfo) => {
|
|
21
|
-
console.group(err.toString())
|
|
22
|
-
console.groupCollapsed('console.error')
|
|
23
|
-
console.error(err)
|
|
24
|
-
console.groupEnd()
|
|
25
|
-
if (err.stack) {
|
|
26
|
-
console.groupCollapsed('error.stack')
|
|
27
|
-
console.log(err.stack)
|
|
28
|
-
console.groupEnd()
|
|
29
|
-
}
|
|
30
|
-
if (errorInfo?.componentStack) {
|
|
31
|
-
console.groupCollapsed('errorInfo.componentStack')
|
|
32
|
-
console.log(errorInfo.componentStack)
|
|
33
|
-
console.groupEnd()
|
|
34
|
-
}
|
|
35
|
-
console.groupEnd()
|
|
36
|
-
pushToast({
|
|
37
|
-
status: 'error',
|
|
38
|
-
title: 'Plugin crashed',
|
|
39
|
-
description: (
|
|
40
|
-
<Flex align="center">
|
|
41
|
-
<Inline space={1}>
|
|
42
|
-
An error happened while rendering
|
|
43
|
-
<Button
|
|
44
|
-
padding={1}
|
|
45
|
-
fontSize={1}
|
|
46
|
-
style={{transform: 'translateY(1px)'}}
|
|
47
|
-
mode="ghost"
|
|
48
|
-
text={schemaType.title}
|
|
49
|
-
onClick={() => {
|
|
50
|
-
if (errorRef.current) {
|
|
51
|
-
scrollIntoView(errorRef.current, {
|
|
52
|
-
behavior: 'smooth',
|
|
53
|
-
scrollMode: 'if-needed',
|
|
54
|
-
block: 'center',
|
|
55
|
-
})
|
|
56
|
-
}
|
|
57
|
-
}}
|
|
58
|
-
/>
|
|
59
|
-
</Inline>
|
|
60
|
-
</Flex>
|
|
61
|
-
),
|
|
62
|
-
})
|
|
63
|
-
},
|
|
64
|
-
})
|
|
65
|
-
const handleRetry = useCallback(() => {
|
|
66
|
-
// Purge request cache before retrying, otherwise the cached errors will rethrow
|
|
67
|
-
clear([name])
|
|
68
|
-
|
|
69
|
-
reset()
|
|
70
|
-
}, [reset])
|
|
71
|
-
|
|
72
|
-
if (didCatch) {
|
|
73
|
-
return (
|
|
74
|
-
<Card ref={errorRef} paddingX={[2, 3, 4, 4]} height="fill" shadow={1} overflow="auto">
|
|
75
|
-
<Flex justify="flex-start" align="center" height="fill">
|
|
76
|
-
<Grid columns={1} gap={[2, 3, 4, 4]}>
|
|
77
|
-
<Heading as="h1">
|
|
78
|
-
The <code>{name}</code> plugin crashed
|
|
79
|
-
</Heading>
|
|
80
|
-
{error?.message && (
|
|
81
|
-
<Card padding={3} tone="critical" shadow={1} radius={2}>
|
|
82
|
-
<Text>{error.message}</Text>
|
|
83
|
-
</Card>
|
|
84
|
-
)}
|
|
85
|
-
<Inline>
|
|
86
|
-
<Button onClick={handleRetry} text="Retry" />
|
|
87
|
-
</Inline>
|
|
88
|
-
</Grid>
|
|
89
|
-
</Flex>
|
|
90
|
-
</Card>
|
|
91
|
-
)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return <ErrorBoundary>{children}</ErrorBoundary>
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export default memo(ErrorBoundaryCard)
|
|
@@ -1,54 +0,0 @@
|
|
|
1
|
-
import {Button, type ButtonProps} from '@sanity/ui'
|
|
2
|
-
import React, {useCallback, useId, useRef} from 'react'
|
|
3
|
-
import {styled} from 'styled-components'
|
|
4
|
-
|
|
5
|
-
const HiddenInput = styled.input`
|
|
6
|
-
overflow: hidden;
|
|
7
|
-
width: 0.1px;
|
|
8
|
-
height: 0.1px;
|
|
9
|
-
opacity: 0;
|
|
10
|
-
position: absolute;
|
|
11
|
-
z-index: -1;
|
|
12
|
-
`
|
|
13
|
-
|
|
14
|
-
const Label = styled.label`
|
|
15
|
-
position: relative;
|
|
16
|
-
`
|
|
17
|
-
|
|
18
|
-
export interface FileInputButtonProps extends ButtonProps {
|
|
19
|
-
onSelect: (files: FileList) => void
|
|
20
|
-
accept: string
|
|
21
|
-
}
|
|
22
|
-
export const FileInputButton = ({onSelect, accept, ...props}: FileInputButtonProps) => {
|
|
23
|
-
const inputId = `FileSelect${useId()}`
|
|
24
|
-
const inputRef = useRef<HTMLInputElement>(null)
|
|
25
|
-
const handleSelect = useCallback<React.ChangeEventHandler<HTMLInputElement>>(
|
|
26
|
-
(event) => {
|
|
27
|
-
if (onSelect) {
|
|
28
|
-
onSelect(event.target.files!)
|
|
29
|
-
}
|
|
30
|
-
},
|
|
31
|
-
[onSelect],
|
|
32
|
-
)
|
|
33
|
-
const handleButtonClick = useCallback(() => inputRef.current?.click(), [])
|
|
34
|
-
return (
|
|
35
|
-
<Label htmlFor={inputId}>
|
|
36
|
-
<HiddenInput
|
|
37
|
-
accept={accept}
|
|
38
|
-
ref={inputRef}
|
|
39
|
-
tabIndex={0}
|
|
40
|
-
type="file"
|
|
41
|
-
id={inputId}
|
|
42
|
-
onChange={handleSelect}
|
|
43
|
-
value=""
|
|
44
|
-
/>
|
|
45
|
-
<Button
|
|
46
|
-
onClick={handleButtonClick}
|
|
47
|
-
mode="default"
|
|
48
|
-
tone="primary"
|
|
49
|
-
style={{width: '100%'}}
|
|
50
|
-
{...props}
|
|
51
|
-
/>
|
|
52
|
-
</Label>
|
|
53
|
-
)
|
|
54
|
-
}
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
import {MenuItem} from '@sanity/ui'
|
|
2
|
-
import {css, styled} from 'styled-components'
|
|
3
|
-
|
|
4
|
-
import {focusRingStyle} from './withFocusRing/helpers'
|
|
5
|
-
|
|
6
|
-
export const FileButton = styled(MenuItem)(({theme}) => {
|
|
7
|
-
const {focusRing} = theme.sanity
|
|
8
|
-
const base = theme.sanity.color.base
|
|
9
|
-
const border = {width: 1, color: 'var(--card-border-color)'}
|
|
10
|
-
|
|
11
|
-
return css`
|
|
12
|
-
position: relative;
|
|
13
|
-
|
|
14
|
-
&:not([data-disabled='true']) {
|
|
15
|
-
&:focus-within {
|
|
16
|
-
box-shadow: ${focusRingStyle({base, border, focusRing})};
|
|
17
|
-
}
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
& input {
|
|
21
|
-
overflow: hidden;
|
|
22
|
-
top: 0;
|
|
23
|
-
left: 0;
|
|
24
|
-
width: 100%;
|
|
25
|
-
height: 100%;
|
|
26
|
-
position: absolute;
|
|
27
|
-
min-width: 0;
|
|
28
|
-
display: block;
|
|
29
|
-
appearance: none;
|
|
30
|
-
padding: 0;
|
|
31
|
-
margin: 0;
|
|
32
|
-
border: 0;
|
|
33
|
-
opacity: 0;
|
|
34
|
-
}
|
|
35
|
-
`
|
|
36
|
-
})
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import {Box, type ButtonProps, Flex, Text} from '@sanity/ui'
|
|
2
|
-
import {isValidElement, useId, forwardRef, useCallback} from 'react'
|
|
3
|
-
import {isValidElementType} from 'react-is'
|
|
4
|
-
|
|
5
|
-
import {FileButton} from './FileInputMenuItem.styled'
|
|
6
|
-
|
|
7
|
-
export interface FileInputMenuItemProps extends ButtonProps {
|
|
8
|
-
accept?: string
|
|
9
|
-
capture?: 'user' | 'environment'
|
|
10
|
-
multiple?: boolean
|
|
11
|
-
onSelect?: (files: File[]) => void
|
|
12
|
-
disabled?: boolean
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export const FileInputMenuItem = forwardRef(function FileInputMenuItem(
|
|
16
|
-
props: FileInputMenuItemProps &
|
|
17
|
-
Omit<React.HTMLProps<HTMLButtonElement>, 'as' | 'ref' | 'type' | 'value' | 'onSelect'>,
|
|
18
|
-
forwardedRef: React.ForwardedRef<HTMLInputElement>,
|
|
19
|
-
) {
|
|
20
|
-
const {
|
|
21
|
-
icon: Icon,
|
|
22
|
-
id: idProp,
|
|
23
|
-
accept,
|
|
24
|
-
capture,
|
|
25
|
-
fontSize,
|
|
26
|
-
multiple,
|
|
27
|
-
onSelect,
|
|
28
|
-
space = 3,
|
|
29
|
-
textAlign,
|
|
30
|
-
text,
|
|
31
|
-
disabled,
|
|
32
|
-
...rest
|
|
33
|
-
} = props
|
|
34
|
-
const idHook = useId()
|
|
35
|
-
const id = idProp || idHook
|
|
36
|
-
|
|
37
|
-
const handleChange = useCallback(
|
|
38
|
-
(event: React.ChangeEvent<HTMLInputElement>) => {
|
|
39
|
-
if (onSelect && event.target.files) {
|
|
40
|
-
onSelect(Array.from(event.target.files))
|
|
41
|
-
}
|
|
42
|
-
},
|
|
43
|
-
[onSelect],
|
|
44
|
-
)
|
|
45
|
-
|
|
46
|
-
const content = (
|
|
47
|
-
<Flex align="center" justify="flex-start">
|
|
48
|
-
{/* Icon */}
|
|
49
|
-
{Icon && (
|
|
50
|
-
<Box marginRight={text ? space : undefined}>
|
|
51
|
-
<Text size={fontSize}>
|
|
52
|
-
{isValidElement(Icon) && Icon}
|
|
53
|
-
{isValidElementType(Icon) && <Icon />}
|
|
54
|
-
</Text>
|
|
55
|
-
</Box>
|
|
56
|
-
)}
|
|
57
|
-
|
|
58
|
-
{/* Text */}
|
|
59
|
-
{text && (
|
|
60
|
-
<Text align={textAlign} size={fontSize} textOverflow="ellipsis">
|
|
61
|
-
{text}
|
|
62
|
-
</Text>
|
|
63
|
-
)}
|
|
64
|
-
</Flex>
|
|
65
|
-
)
|
|
66
|
-
|
|
67
|
-
return (
|
|
68
|
-
<FileButton {...rest} htmlFor={id} disabled={disabled} ref={forwardedRef}>
|
|
69
|
-
{content}
|
|
70
|
-
|
|
71
|
-
{/* Visibly hidden input */}
|
|
72
|
-
<input
|
|
73
|
-
data-testid="file-button-input"
|
|
74
|
-
accept={accept}
|
|
75
|
-
capture={capture}
|
|
76
|
-
id={id}
|
|
77
|
-
multiple={multiple}
|
|
78
|
-
onChange={handleChange}
|
|
79
|
-
type="file"
|
|
80
|
-
value=""
|
|
81
|
-
disabled={disabled}
|
|
82
|
-
/>
|
|
83
|
-
</FileButton>
|
|
84
|
-
)
|
|
85
|
-
})
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import {Box, Flex, Stack, Text} from '@sanity/ui'
|
|
2
|
-
import React, {memo} from 'react'
|
|
3
|
-
|
|
4
|
-
// @TODO: get rid of this once v3 core is stable
|
|
5
|
-
|
|
6
|
-
export interface Props {
|
|
7
|
-
children: React.ReactNode
|
|
8
|
-
title: React.ReactNode
|
|
9
|
-
description?: React.ReactNode
|
|
10
|
-
inputId: string
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
function FormField(props: Props) {
|
|
14
|
-
const {children, title, description, inputId} = props
|
|
15
|
-
|
|
16
|
-
return (
|
|
17
|
-
<Stack space={1}>
|
|
18
|
-
<Flex align="flex-end">
|
|
19
|
-
<Box flex={1} paddingY={2}>
|
|
20
|
-
<Stack space={2}>
|
|
21
|
-
<Text as="label" htmlFor={inputId} weight="semibold" size={1}>
|
|
22
|
-
{title || <em>Untitled</em>}
|
|
23
|
-
</Text>
|
|
24
|
-
|
|
25
|
-
{description && (
|
|
26
|
-
<Text muted size={1}>
|
|
27
|
-
{description}
|
|
28
|
-
</Text>
|
|
29
|
-
)}
|
|
30
|
-
</Stack>
|
|
31
|
-
</Box>
|
|
32
|
-
</Flex>
|
|
33
|
-
<div>{children}</div>
|
|
34
|
-
</Stack>
|
|
35
|
-
)
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
export default memo(FormField)
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {Flex, Text} from '@sanity/ui'
|
|
2
|
-
|
|
3
|
-
const IconInfo: React.FC<{
|
|
4
|
-
text: string
|
|
5
|
-
icon: React.FC
|
|
6
|
-
size?: number
|
|
7
|
-
muted?: boolean
|
|
8
|
-
}> = (props) => {
|
|
9
|
-
const Icon = props.icon
|
|
10
|
-
return (
|
|
11
|
-
<Flex gap={2} align="center" padding={1}>
|
|
12
|
-
<Text size={(props.size || 1) + 1} muted>
|
|
13
|
-
<Icon />
|
|
14
|
-
</Text>
|
|
15
|
-
<Text size={props.size || 1} muted={props.muted}>
|
|
16
|
-
{props.text}
|
|
17
|
-
</Text>
|
|
18
|
-
</Flex>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export default IconInfo
|
|
@@ -1,339 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
CheckmarkCircleIcon,
|
|
3
|
-
ErrorOutlineIcon,
|
|
4
|
-
InfoOutlineIcon,
|
|
5
|
-
RetrieveIcon,
|
|
6
|
-
RetryIcon,
|
|
7
|
-
} from '@sanity/icons'
|
|
8
|
-
import {
|
|
9
|
-
Box,
|
|
10
|
-
Button,
|
|
11
|
-
Card,
|
|
12
|
-
Checkbox,
|
|
13
|
-
Code,
|
|
14
|
-
Dialog,
|
|
15
|
-
Flex,
|
|
16
|
-
Heading,
|
|
17
|
-
Spinner,
|
|
18
|
-
Stack,
|
|
19
|
-
Text,
|
|
20
|
-
} from '@sanity/ui'
|
|
21
|
-
import {truncateString, useFormattedDuration} from 'sanity'
|
|
22
|
-
import {styled} from 'styled-components'
|
|
23
|
-
|
|
24
|
-
import useImportMuxAssets from '../hooks/useImportMuxAssets'
|
|
25
|
-
import {DIALOGS_Z_INDEX} from '../util/constants'
|
|
26
|
-
import type {MuxAsset} from '../util/types'
|
|
27
|
-
import VideoThumbnail from './VideoThumbnail'
|
|
28
|
-
|
|
29
|
-
const MissingAssetCheckbox = styled(Checkbox)`
|
|
30
|
-
position: static !important;
|
|
31
|
-
|
|
32
|
-
input::after {
|
|
33
|
-
content: '';
|
|
34
|
-
position: absolute;
|
|
35
|
-
inset: 0;
|
|
36
|
-
display: block;
|
|
37
|
-
cursor: pointer;
|
|
38
|
-
z-index: 1000;
|
|
39
|
-
}
|
|
40
|
-
`
|
|
41
|
-
|
|
42
|
-
function MissingAsset({
|
|
43
|
-
asset,
|
|
44
|
-
selectAsset,
|
|
45
|
-
selected,
|
|
46
|
-
}: {
|
|
47
|
-
asset: MuxAsset
|
|
48
|
-
selectAsset: (selected: boolean) => void
|
|
49
|
-
selected: boolean
|
|
50
|
-
}) {
|
|
51
|
-
const duration = useFormattedDuration(asset.duration * 1000)
|
|
52
|
-
|
|
53
|
-
return (
|
|
54
|
-
<Card
|
|
55
|
-
key={asset.id}
|
|
56
|
-
tone={selected ? 'positive' : undefined}
|
|
57
|
-
border
|
|
58
|
-
paddingX={2}
|
|
59
|
-
paddingY={3}
|
|
60
|
-
style={{position: 'relative'}}
|
|
61
|
-
radius={1}
|
|
62
|
-
>
|
|
63
|
-
<Flex align="center" gap={2}>
|
|
64
|
-
<MissingAssetCheckbox
|
|
65
|
-
checked={selected}
|
|
66
|
-
onChange={(e) => {
|
|
67
|
-
selectAsset(e.currentTarget.checked)
|
|
68
|
-
}}
|
|
69
|
-
aria-label={selected ? `Import video ${asset.id}` : `Skip import of video ${asset.id}`}
|
|
70
|
-
/>
|
|
71
|
-
<VideoThumbnail
|
|
72
|
-
asset={{
|
|
73
|
-
assetId: asset.id,
|
|
74
|
-
data: asset,
|
|
75
|
-
filename: asset.id,
|
|
76
|
-
playbackId: asset.playback_ids.find((p) => p.id)?.id,
|
|
77
|
-
}}
|
|
78
|
-
width={150}
|
|
79
|
-
/>
|
|
80
|
-
<Stack space={2}>
|
|
81
|
-
<Flex align="center" gap={1}>
|
|
82
|
-
<Code size={2}>{truncateString(asset.id, 15)}</Code>{' '}
|
|
83
|
-
<Text muted size={2}>
|
|
84
|
-
({duration.formatted})
|
|
85
|
-
</Text>
|
|
86
|
-
</Flex>
|
|
87
|
-
<Text size={1}>
|
|
88
|
-
Uploaded at{' '}
|
|
89
|
-
{new Date(Number(asset.created_at) * 1000).toLocaleDateString('en', {
|
|
90
|
-
year: 'numeric',
|
|
91
|
-
day: '2-digit',
|
|
92
|
-
month: '2-digit',
|
|
93
|
-
})}
|
|
94
|
-
</Text>
|
|
95
|
-
</Stack>
|
|
96
|
-
</Flex>
|
|
97
|
-
</Card>
|
|
98
|
-
)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function ImportVideosDialog(props: ReturnType<typeof useImportMuxAssets>) {
|
|
102
|
-
const {importState} = props
|
|
103
|
-
|
|
104
|
-
const canTriggerImport =
|
|
105
|
-
(importState === 'idle' || importState === 'error') && props.selectedAssets.length > 0
|
|
106
|
-
const isImporting = importState === 'importing'
|
|
107
|
-
const noAssetsToImport =
|
|
108
|
-
props.missingAssets?.length === 0 && !props.muxAssets.loading && !props.assetsInSanityLoading
|
|
109
|
-
|
|
110
|
-
return (
|
|
111
|
-
<Dialog
|
|
112
|
-
animate
|
|
113
|
-
header={'Import videos from Mux'}
|
|
114
|
-
zOffset={DIALOGS_Z_INDEX}
|
|
115
|
-
id="video-details-dialog"
|
|
116
|
-
onClose={props.closeDialog}
|
|
117
|
-
onClickOutside={props.closeDialog}
|
|
118
|
-
width={1}
|
|
119
|
-
position="fixed"
|
|
120
|
-
footer={
|
|
121
|
-
importState !== 'done' &&
|
|
122
|
-
!noAssetsToImport && (
|
|
123
|
-
<Card padding={3}>
|
|
124
|
-
<Flex justify="space-between" align="center">
|
|
125
|
-
<Button
|
|
126
|
-
fontSize={2}
|
|
127
|
-
padding={3}
|
|
128
|
-
mode="ghost"
|
|
129
|
-
text="Cancel"
|
|
130
|
-
tone="critical"
|
|
131
|
-
onClick={props.closeDialog}
|
|
132
|
-
disabled={isImporting}
|
|
133
|
-
/>
|
|
134
|
-
{props.missingAssets && (
|
|
135
|
-
<Button
|
|
136
|
-
icon={RetrieveIcon}
|
|
137
|
-
fontSize={2}
|
|
138
|
-
padding={3}
|
|
139
|
-
mode="ghost"
|
|
140
|
-
text={
|
|
141
|
-
props.selectedAssets?.length > 0
|
|
142
|
-
? `Import ${props.selectedAssets.length} video(s)`
|
|
143
|
-
: 'No video(s) selected'
|
|
144
|
-
}
|
|
145
|
-
tone="positive"
|
|
146
|
-
onClick={props.importAssets}
|
|
147
|
-
iconRight={isImporting && Spinner}
|
|
148
|
-
disabled={!canTriggerImport}
|
|
149
|
-
/>
|
|
150
|
-
)}
|
|
151
|
-
</Flex>
|
|
152
|
-
</Card>
|
|
153
|
-
)
|
|
154
|
-
}
|
|
155
|
-
>
|
|
156
|
-
<Box padding={3}>
|
|
157
|
-
{/* WARNING: SKIPPED ASSETS WITHOUT PLAYBACK */}
|
|
158
|
-
{props.muxAssets.hasSkippedAssetsWithoutPlayback && (
|
|
159
|
-
<Card tone="caution" marginBottom={5} padding={3} border>
|
|
160
|
-
<Flex align="center" gap={2}>
|
|
161
|
-
<InfoOutlineIcon fontSize={36} />
|
|
162
|
-
<Stack space={2}>
|
|
163
|
-
<Text size={2} weight="semibold">
|
|
164
|
-
Some videos were skipped
|
|
165
|
-
</Text>
|
|
166
|
-
<Text size={1}>
|
|
167
|
-
Videos without playback IDs cannot be imported and have been excluded from the
|
|
168
|
-
list.
|
|
169
|
-
</Text>
|
|
170
|
-
</Stack>
|
|
171
|
-
</Flex>
|
|
172
|
-
</Card>
|
|
173
|
-
)}
|
|
174
|
-
|
|
175
|
-
{/* LOADING ASSETS STATE */}
|
|
176
|
-
{(props.muxAssets.loading || props.assetsInSanityLoading) && (
|
|
177
|
-
<Card tone="primary" marginBottom={5} padding={3} border>
|
|
178
|
-
<Flex align="center" gap={4}>
|
|
179
|
-
<Spinner muted size={4} />
|
|
180
|
-
<Stack space={2}>
|
|
181
|
-
<Text size={2} weight="semibold">
|
|
182
|
-
Loading assets from Mux
|
|
183
|
-
</Text>
|
|
184
|
-
<Text size={1}>
|
|
185
|
-
This may take a while.
|
|
186
|
-
{props.missingAssets &&
|
|
187
|
-
props.missingAssets.length > 0 &&
|
|
188
|
-
` There are at least ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} currently not in Sanity...`}
|
|
189
|
-
</Text>
|
|
190
|
-
</Stack>
|
|
191
|
-
</Flex>
|
|
192
|
-
</Card>
|
|
193
|
-
)}
|
|
194
|
-
|
|
195
|
-
{/* ERROR LOADING MUX */}
|
|
196
|
-
{props.muxAssets.error && (
|
|
197
|
-
<Card tone="critical" marginBottom={5} padding={3} border>
|
|
198
|
-
<Flex align="center" gap={2}>
|
|
199
|
-
<ErrorOutlineIcon fontSize={36} />
|
|
200
|
-
<Stack space={2}>
|
|
201
|
-
<Text size={2} weight="semibold">
|
|
202
|
-
There was an error getting all data from Mux
|
|
203
|
-
</Text>
|
|
204
|
-
<Text size={1}>
|
|
205
|
-
{props.missingAssets
|
|
206
|
-
? `But we've found ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} not in Sanity, which you can start importing now.`
|
|
207
|
-
: 'Please try again or contact a developer for help.'}
|
|
208
|
-
</Text>
|
|
209
|
-
</Stack>
|
|
210
|
-
</Flex>
|
|
211
|
-
</Card>
|
|
212
|
-
)}
|
|
213
|
-
|
|
214
|
-
{/* IMPORTING STATE */}
|
|
215
|
-
{importState === 'importing' && (
|
|
216
|
-
<Card tone="primary" marginBottom={5} padding={3} border>
|
|
217
|
-
<Flex align="center" gap={4}>
|
|
218
|
-
<Spinner muted size={4} />
|
|
219
|
-
<Stack space={2}>
|
|
220
|
-
<Text size={2} weight="semibold">
|
|
221
|
-
Importing {props.selectedAssets.length} video
|
|
222
|
-
{props.selectedAssets.length > 1 && 's'} from Mux
|
|
223
|
-
</Text>
|
|
224
|
-
</Stack>
|
|
225
|
-
</Flex>
|
|
226
|
-
</Card>
|
|
227
|
-
)}
|
|
228
|
-
|
|
229
|
-
{/* ERROR IMPORTING */}
|
|
230
|
-
{importState === 'error' && (
|
|
231
|
-
<Card tone="critical" marginBottom={5} padding={3} border>
|
|
232
|
-
<Flex align="center" gap={2}>
|
|
233
|
-
<ErrorOutlineIcon fontSize={36} />
|
|
234
|
-
<Stack space={2}>
|
|
235
|
-
<Text size={2} weight="semibold">
|
|
236
|
-
There was an error importing videos
|
|
237
|
-
</Text>
|
|
238
|
-
<Text size={1}>
|
|
239
|
-
{props.importError
|
|
240
|
-
? `Error: ${props.importError}`
|
|
241
|
-
: 'Please try again or contact a developer for help.'}
|
|
242
|
-
</Text>
|
|
243
|
-
<Box marginTop={1}>
|
|
244
|
-
<Button
|
|
245
|
-
icon={RetryIcon}
|
|
246
|
-
text="Retry"
|
|
247
|
-
tone="primary"
|
|
248
|
-
onClick={props.importAssets}
|
|
249
|
-
/>
|
|
250
|
-
</Box>
|
|
251
|
-
</Stack>
|
|
252
|
-
</Flex>
|
|
253
|
-
</Card>
|
|
254
|
-
)}
|
|
255
|
-
|
|
256
|
-
{/* NO ASSETS TO IMPORT or SUCESS STATE */}
|
|
257
|
-
{(noAssetsToImport || importState === 'done') && (
|
|
258
|
-
<Stack paddingY={5} marginBottom={4} space={3} style={{textAlign: 'center'}}>
|
|
259
|
-
<Box>
|
|
260
|
-
<CheckmarkCircleIcon fontSize={48} />
|
|
261
|
-
</Box>
|
|
262
|
-
<Heading size={2}>
|
|
263
|
-
{importState === 'done'
|
|
264
|
-
? `Videos imported successfully`
|
|
265
|
-
: 'There are no Mux videos to import'}
|
|
266
|
-
</Heading>
|
|
267
|
-
<Text size={2}>
|
|
268
|
-
{importState === 'done'
|
|
269
|
-
? 'You can now use them in your Sanity content.'
|
|
270
|
-
: "They're all in Sanity and ready to be used in your content."}
|
|
271
|
-
</Text>
|
|
272
|
-
</Stack>
|
|
273
|
-
)}
|
|
274
|
-
|
|
275
|
-
{/* MISSING ASSETS SELECTOR */}
|
|
276
|
-
{props.missingAssets &&
|
|
277
|
-
props.missingAssets.length > 0 &&
|
|
278
|
-
(importState === 'idle' || importState === 'error') && (
|
|
279
|
-
<Stack space={4}>
|
|
280
|
-
<Heading size={1}>
|
|
281
|
-
There are {props.missingAssets.length}
|
|
282
|
-
{props.muxAssets.loading && '+'} Mux video{props.missingAssets.length > 1 && 's'}{' '}
|
|
283
|
-
not in Sanity
|
|
284
|
-
</Heading>
|
|
285
|
-
{!props.muxAssets.loading && (
|
|
286
|
-
<Flex align="center" paddingX={2}>
|
|
287
|
-
<Checkbox
|
|
288
|
-
id="import-all"
|
|
289
|
-
style={{display: 'block'}}
|
|
290
|
-
onClick={(e) => {
|
|
291
|
-
const selectAll = e.currentTarget.checked
|
|
292
|
-
if (selectAll) {
|
|
293
|
-
// eslint-disable-next-line no-unused-expressions
|
|
294
|
-
props.missingAssets && props.setSelectedAssets(props.missingAssets)
|
|
295
|
-
} else {
|
|
296
|
-
props.setSelectedAssets([])
|
|
297
|
-
}
|
|
298
|
-
}}
|
|
299
|
-
checked={props.selectedAssets.length === props.missingAssets.length}
|
|
300
|
-
/>
|
|
301
|
-
<Box flex={1} paddingLeft={3} as="label" htmlFor="import-all">
|
|
302
|
-
<Text>Import all</Text>
|
|
303
|
-
</Box>
|
|
304
|
-
</Flex>
|
|
305
|
-
)}
|
|
306
|
-
{props.missingAssets.map((asset) => (
|
|
307
|
-
<MissingAsset
|
|
308
|
-
key={asset.id}
|
|
309
|
-
asset={asset}
|
|
310
|
-
selectAsset={(selected) => {
|
|
311
|
-
if (selected) {
|
|
312
|
-
props.setSelectedAssets([...props.selectedAssets, asset])
|
|
313
|
-
} else {
|
|
314
|
-
props.setSelectedAssets(props.selectedAssets.filter((a) => a.id !== asset.id))
|
|
315
|
-
}
|
|
316
|
-
}}
|
|
317
|
-
selected={props.selectedAssets.some((a) => a.id === asset.id)}
|
|
318
|
-
/>
|
|
319
|
-
))}
|
|
320
|
-
</Stack>
|
|
321
|
-
)}
|
|
322
|
-
</Box>
|
|
323
|
-
</Dialog>
|
|
324
|
-
)
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export default function ImportVideosFromMux() {
|
|
328
|
-
const importAssets = useImportMuxAssets()
|
|
329
|
-
|
|
330
|
-
if (!importAssets.hasSecrets) {
|
|
331
|
-
return
|
|
332
|
-
}
|
|
333
|
-
|
|
334
|
-
if (importAssets.dialogOpen) {
|
|
335
|
-
return <ImportVideosDialog {...importAssets} />
|
|
336
|
-
}
|
|
337
|
-
|
|
338
|
-
return <Button mode="bleed" text="Import from Mux" onClick={importAssets.openDialog} />
|
|
339
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import {Box, Card, Flex, Spinner, Text} from '@sanity/ui'
|
|
2
|
-
|
|
3
|
-
export const InputFallback = () => {
|
|
4
|
-
return (
|
|
5
|
-
<div style={{padding: 1}}>
|
|
6
|
-
<Card
|
|
7
|
-
shadow={1}
|
|
8
|
-
sizing="border"
|
|
9
|
-
style={{aspectRatio: '16/9', width: '100%', borderRadius: '1px'}}
|
|
10
|
-
>
|
|
11
|
-
<Flex align="center" direction="column" height="fill" justify="center">
|
|
12
|
-
<Spinner muted />
|
|
13
|
-
<Box marginTop={3}>
|
|
14
|
-
<Text align="center" muted size={1}>
|
|
15
|
-
Loading…
|
|
16
|
-
</Text>
|
|
17
|
-
</Box>
|
|
18
|
-
</Flex>
|
|
19
|
-
</Card>
|
|
20
|
-
</div>
|
|
21
|
-
)
|
|
22
|
-
}
|