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.
Files changed (123) hide show
  1. package/dist/index.js +28 -28
  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,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
- }