sanity-plugin-mux-input 3.0.4 → 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 (130) hide show
  1. package/README.md +0 -2
  2. package/dist/index.d.ts +134 -193
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +2893 -4417
  5. package/dist/index.js.map +1 -1
  6. package/package.json +33 -43
  7. package/dist/index.cjs +0 -7270
  8. package/dist/index.cjs.map +0 -1
  9. package/dist/index.d.cts +0 -347
  10. package/sanity.json +0 -8
  11. package/src/_exports/index.ts +0 -73
  12. package/src/actions/assets.ts +0 -152
  13. package/src/actions/secrets.ts +0 -111
  14. package/src/actions/upload.ts +0 -310
  15. package/src/clients/upChunkObservable.ts +0 -54
  16. package/src/components/AddCaptionDialog.tsx +0 -440
  17. package/src/components/CaptionsDialog.tsx +0 -23
  18. package/src/components/ConfigureApi.styled.tsx +0 -19
  19. package/src/components/ConfigureApi.tsx +0 -296
  20. package/src/components/DraggableWatermark.tsx +0 -877
  21. package/src/components/EditCaptionDialog.tsx +0 -510
  22. package/src/components/EditThumbnailDialog.tsx +0 -122
  23. package/src/components/ErrorBoundaryCard.tsx +0 -96
  24. package/src/components/FileInputButton.tsx +0 -54
  25. package/src/components/FileInputMenuItem.styled.tsx +0 -36
  26. package/src/components/FileInputMenuItem.tsx +0 -85
  27. package/src/components/FormField.tsx +0 -38
  28. package/src/components/IconInfo.tsx +0 -22
  29. package/src/components/ImportVideosFromMux.tsx +0 -342
  30. package/src/components/Input.styled.tsx +0 -22
  31. package/src/components/Input.tsx +0 -78
  32. package/src/components/InputBrowser.tsx +0 -41
  33. package/src/components/InputError.tsx +0 -17
  34. package/src/components/MuxLogo.tsx +0 -42
  35. package/src/components/Onboard.tsx +0 -65
  36. package/src/components/PageSelector.tsx +0 -54
  37. package/src/components/Player.styled.tsx +0 -55
  38. package/src/components/Player.tsx +0 -117
  39. package/src/components/PlayerActionsMenu.tsx +0 -190
  40. package/src/components/ResyncMetadata.tsx +0 -280
  41. package/src/components/SelectAsset.tsx +0 -39
  42. package/src/components/SelectSortOptions.tsx +0 -45
  43. package/src/components/SpinnerBox.tsx +0 -16
  44. package/src/components/StudioTool.tsx +0 -24
  45. package/src/components/TextTracksEditor.tsx +0 -117
  46. package/src/components/TextTracksManager.tsx +0 -737
  47. package/src/components/UploadConfiguration.tsx +0 -694
  48. package/src/components/UploadPlaceholder.tsx +0 -88
  49. package/src/components/UploadProgress.tsx +0 -80
  50. package/src/components/Uploader.styled.tsx +0 -66
  51. package/src/components/Uploader.tsx +0 -498
  52. package/src/components/VideoDetails/DeleteDialog.tsx +0 -147
  53. package/src/components/VideoDetails/VideoDetails.tsx +0 -358
  54. package/src/components/VideoDetails/VideoReferences.tsx +0 -63
  55. package/src/components/VideoDetails/useVideoDetails.ts +0 -103
  56. package/src/components/VideoInBrowser.tsx +0 -245
  57. package/src/components/VideoMetadata.tsx +0 -45
  58. package/src/components/VideoPlayer.tsx +0 -235
  59. package/src/components/VideoThumbnail.tsx +0 -138
  60. package/src/components/VideosBrowser.tsx +0 -100
  61. package/src/components/documentPreview/DocumentPreview.tsx +0 -83
  62. package/src/components/documentPreview/DraftStatus.tsx +0 -34
  63. package/src/components/documentPreview/MissingSchemaType.tsx +0 -32
  64. package/src/components/documentPreview/PaneItemPreview.tsx +0 -74
  65. package/src/components/documentPreview/PublishedStatus.tsx +0 -35
  66. package/src/components/documentPreview/TimeAgo.tsx +0 -12
  67. package/src/components/documentPreview/paneItemTypes.ts +0 -7
  68. package/src/components/icons/Audio.tsx +0 -13
  69. package/src/components/icons/Resolution.tsx +0 -12
  70. package/src/components/icons/StopWatch.tsx +0 -20
  71. package/src/components/icons/ToolIcon.tsx +0 -19
  72. package/src/components/uploadConfiguration/PlaybackPolicy.tsx +0 -133
  73. package/src/components/uploadConfiguration/PlaybackPolicyOption.tsx +0 -76
  74. package/src/components/uploadConfiguration/PlaybackPolicyWarning.tsx +0 -29
  75. package/src/components/uploadConfiguration/ResolutionTierSelector.tsx +0 -72
  76. package/src/components/uploadConfiguration/StaticRenditionSelector.tsx +0 -180
  77. package/src/components/withFocusRing/helpers.ts +0 -24
  78. package/src/components/withFocusRing/index.ts +0 -1
  79. package/src/components/withFocusRing/withFocusRing.ts +0 -30
  80. package/src/context/DialogStateContext.tsx +0 -36
  81. package/src/context/DrmPlaybackWarningContext.tsx +0 -93
  82. package/src/hooks/useAccessControl.ts +0 -13
  83. package/src/hooks/useAssetDocumentValues.ts +0 -11
  84. package/src/hooks/useAssets.ts +0 -68
  85. package/src/hooks/useCancelUpload.ts +0 -22
  86. package/src/hooks/useClient.ts +0 -8
  87. package/src/hooks/useDialogState.ts +0 -11
  88. package/src/hooks/useDocReferences.ts +0 -21
  89. package/src/hooks/useFetchFileSize.ts +0 -54
  90. package/src/hooks/useImportMuxAssets.ts +0 -132
  91. package/src/hooks/useInView.ts +0 -42
  92. package/src/hooks/useMediaMetadata.ts +0 -103
  93. package/src/hooks/useMuxAssets.ts +0 -179
  94. package/src/hooks/useMuxPolling.ts +0 -49
  95. package/src/hooks/useResyncAsset.ts +0 -110
  96. package/src/hooks/useResyncMuxMetadata.ts +0 -176
  97. package/src/hooks/useSaveSecrets.ts +0 -78
  98. package/src/hooks/useSecretsDocumentValues.ts +0 -38
  99. package/src/hooks/useSecretsFormState.ts +0 -47
  100. package/src/plugin.tsx +0 -31
  101. package/src/sanity-ui.d.ts +0 -5
  102. package/src/schema.ts +0 -196
  103. package/src/util/addKeysToMuxData.ts +0 -30
  104. package/src/util/areSecretsSignable.ts +0 -5
  105. package/src/util/asserters.ts +0 -36
  106. package/src/util/assetTitlePlaceholder.ts +0 -31
  107. package/src/util/constants.ts +0 -15
  108. package/src/util/convertWatermarkToMux.ts +0 -160
  109. package/src/util/createSearchFilter.ts +0 -76
  110. package/src/util/createUrlParamsObject.ts +0 -29
  111. package/src/util/extractFiles.ts +0 -67
  112. package/src/util/formatBytes.ts +0 -32
  113. package/src/util/formatDriveShareLink.ts +0 -64
  114. package/src/util/formatSeconds.ts +0 -49
  115. package/src/util/generateJwt.ts +0 -57
  116. package/src/util/getAnimatedPosterSrc.ts +0 -26
  117. package/src/util/getPlaybackPolicy.ts +0 -69
  118. package/src/util/getPosterSrc.ts +0 -28
  119. package/src/util/getStoryboardSrc.ts +0 -27
  120. package/src/util/getVideoMetadata.ts +0 -23
  121. package/src/util/getVideoSrc.ts +0 -23
  122. package/src/util/isSigned.ts +0 -20
  123. package/src/util/parsers.ts +0 -5
  124. package/src/util/pluginVersion.ts +0 -1
  125. package/src/util/readSecrets.ts +0 -38
  126. package/src/util/roundPxString.ts +0 -16
  127. package/src/util/textTracks.ts +0 -222
  128. package/src/util/tryWithSuspend.ts +0 -22
  129. package/src/util/types.ts +0 -596
  130. package/v2-incompatible.js +0 -11
@@ -1,96 +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
- onDidCatch: (err, errorInfo) => {
20
- console.group(err.toString())
21
- console.groupCollapsed('console.error')
22
- console.error(err)
23
- console.groupEnd()
24
- if (err.stack) {
25
- console.groupCollapsed('error.stack')
26
- console.log(err.stack)
27
- console.groupEnd()
28
- }
29
- if (errorInfo?.componentStack) {
30
- console.groupCollapsed('errorInfo.componentStack')
31
- console.log(errorInfo.componentStack)
32
- console.groupEnd()
33
- }
34
- console.groupEnd()
35
- pushToast({
36
- status: 'error',
37
- title: 'Plugin crashed',
38
- description: (
39
- <Flex align="center">
40
- <Inline space={1}>
41
- An error happened while rendering
42
- <Button
43
- padding={1}
44
- fontSize={1}
45
- style={{transform: 'translateY(1px)'}}
46
- mode="ghost"
47
- text={schemaType.title}
48
- onClick={() => {
49
- if (errorRef.current) {
50
- scrollIntoView(errorRef.current, {
51
- behavior: 'smooth',
52
- scrollMode: 'if-needed',
53
- block: 'center',
54
- })
55
- }
56
- }}
57
- />
58
- </Inline>
59
- </Flex>
60
- ),
61
- })
62
- },
63
- })
64
- const handleRetry = useCallback(() => {
65
- // Purge request cache before retrying, otherwise the cached errors will rethrow
66
- clear([name])
67
-
68
- reset()
69
- }, [reset])
70
-
71
- if (didCatch) {
72
- return (
73
- <Card ref={errorRef} paddingX={[2, 3, 4, 4]} height="fill" shadow={1} overflow="auto">
74
- <Flex justify="flex-start" align="center" height="fill">
75
- <Grid columns={1} gap={[2, 3, 4, 4]}>
76
- <Heading as="h1">
77
- The <code>{name}</code> plugin crashed
78
- </Heading>
79
- {error?.message && (
80
- <Card padding={3} tone="critical" shadow={1} radius={2}>
81
- <Text>{error.message}</Text>
82
- </Card>
83
- )}
84
- <Inline>
85
- <Button onClick={handleRetry} text="Retry" />
86
- </Inline>
87
- </Grid>
88
- </Flex>
89
- </Card>
90
- )
91
- }
92
-
93
- return <ErrorBoundary>{children}</ErrorBoundary>
94
- }
95
-
96
- 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, ButtonProps, Flex, Text} from '@sanity/ui'
2
- import React, {createElement, isValidElement, useId} 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 = React.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,
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 = React.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) && createElement(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,342 +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
- // eslint-disable-next-line complexity
102
- function ImportVideosDialog(props: ReturnType<typeof useImportMuxAssets>) {
103
- const {importState} = props
104
-
105
- const canTriggerImport =
106
- (importState === 'idle' || importState === 'error') && props.selectedAssets.length > 0
107
- const isImporting = importState === 'importing'
108
- const noAssetsToImport =
109
- props.missingAssets?.length === 0 && !props.muxAssets.loading && !props.assetsInSanityLoading
110
-
111
- return (
112
- <Dialog
113
- animate
114
- header={'Import videos from Mux'}
115
- zOffset={DIALOGS_Z_INDEX}
116
- id="video-details-dialog"
117
- onClose={props.closeDialog}
118
- onClickOutside={props.closeDialog}
119
- width={1}
120
- position="fixed"
121
- footer={
122
- importState !== 'done' &&
123
- !noAssetsToImport && (
124
- <Card padding={3}>
125
- <Flex justify="space-between" align="center">
126
- <Button
127
- fontSize={2}
128
- padding={3}
129
- mode="ghost"
130
- text="Cancel"
131
- tone="critical"
132
- onClick={props.closeDialog}
133
- disabled={isImporting}
134
- />
135
- {props.missingAssets && (
136
- <Button
137
- icon={RetrieveIcon}
138
- fontSize={2}
139
- padding={3}
140
- mode="ghost"
141
- text={
142
- props.selectedAssets?.length > 0
143
- ? `Import ${props.selectedAssets.length} video(s)`
144
- : 'No video(s) selected'
145
- }
146
- tone="positive"
147
- onClick={props.importAssets}
148
- iconRight={isImporting && Spinner}
149
- disabled={!canTriggerImport}
150
- />
151
- )}
152
- </Flex>
153
- </Card>
154
- )
155
- }
156
- >
157
- <Box padding={3}>
158
- {/* WARNING: SKIPPED ASSETS WITHOUT PLAYBACK */}
159
- {props.muxAssets.hasSkippedAssetsWithoutPlayback && (
160
- <Card tone="caution" marginBottom={5} padding={3} border>
161
- <Flex align="center" gap={2}>
162
- <InfoOutlineIcon fontSize={36} />
163
- <Stack space={2}>
164
- <Text size={2} weight="semibold">
165
- Some videos were skipped
166
- </Text>
167
- <Text size={1}>
168
- Videos without playback IDs cannot be imported and have been excluded from the
169
- list.
170
- </Text>
171
- </Stack>
172
- </Flex>
173
- </Card>
174
- )}
175
-
176
- {/* LOADING ASSETS STATE */}
177
- {(props.muxAssets.loading || props.assetsInSanityLoading) && (
178
- <Card tone="primary" marginBottom={5} padding={3} border>
179
- <Flex align="center" gap={4}>
180
- <Spinner muted size={4} />
181
- <Stack space={2}>
182
- <Text size={2} weight="semibold">
183
- Loading assets from Mux
184
- </Text>
185
- <Text size={1}>
186
- This may take a while.
187
- {props.missingAssets &&
188
- props.missingAssets.length > 0 &&
189
- ` There are at least ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} currently not in Sanity...`}
190
- </Text>
191
- </Stack>
192
- </Flex>
193
- </Card>
194
- )}
195
-
196
- {/* ERROR LOADING MUX */}
197
- {props.muxAssets.error && (
198
- <Card tone="critical" marginBottom={5} padding={3} border>
199
- <Flex align="center" gap={2}>
200
- <ErrorOutlineIcon fontSize={36} />
201
- <Stack space={2}>
202
- <Text size={2} weight="semibold">
203
- There was an error getting all data from Mux
204
- </Text>
205
- <Text size={1}>
206
- {props.missingAssets
207
- ? `But we've found ${props.missingAssets.length} video${props.missingAssets.length > 1 ? 's' : ''} not in Sanity, which you can start importing now.`
208
- : 'Please try again or contact a developer for help.'}
209
- </Text>
210
- </Stack>
211
- </Flex>
212
- </Card>
213
- )}
214
-
215
- {/* IMPORTING STATE */}
216
- {importState === 'importing' && (
217
- <Card tone="primary" marginBottom={5} padding={3} border>
218
- <Flex align="center" gap={4}>
219
- <Spinner muted size={4} />
220
- <Stack space={2}>
221
- <Text size={2} weight="semibold">
222
- Importing {props.selectedAssets.length} video
223
- {props.selectedAssets.length > 1 && 's'} from Mux
224
- </Text>
225
- </Stack>
226
- </Flex>
227
- </Card>
228
- )}
229
-
230
- {/* ERROR IMPORTING */}
231
- {importState === 'error' && (
232
- <Card tone="critical" marginBottom={5} padding={3} border>
233
- <Flex align="center" gap={2}>
234
- <ErrorOutlineIcon fontSize={36} />
235
- <Stack space={2}>
236
- <Text size={2} weight="semibold">
237
- There was an error importing videos
238
- </Text>
239
- <Text size={1}>
240
- {props.importError
241
- ? `Error: ${props.importError}`
242
- : 'Please try again or contact a developer for help.'}
243
- </Text>
244
- <Box marginTop={1}>
245
- <Button
246
- icon={RetryIcon}
247
- text="Retry"
248
- tone="primary"
249
- onClick={props.importAssets}
250
- />
251
- </Box>
252
- </Stack>
253
- </Flex>
254
- </Card>
255
- )}
256
-
257
- {/* NO ASSETS TO IMPORT or SUCESS STATE */}
258
- {(noAssetsToImport || importState === 'done') && (
259
- <Stack paddingY={5} marginBottom={4} space={3} style={{textAlign: 'center'}}>
260
- <Box>
261
- <CheckmarkCircleIcon fontSize={48} />
262
- </Box>
263
- <Heading size={2}>
264
- {importState === 'done'
265
- ? `Videos imported successfully`
266
- : 'There are no Mux videos to import'}
267
- </Heading>
268
- <Text size={2}>
269
- {importState === 'done'
270
- ? 'You can now use them in your Sanity content.'
271
- : "They're all in Sanity and ready to be used in your content."}
272
- </Text>
273
- </Stack>
274
- )}
275
-
276
- {/* MISSING ASSETS SELECTOR */}
277
- {props.missingAssets &&
278
- props.missingAssets.length > 0 &&
279
- (importState === 'idle' || importState === 'error') && (
280
- <Stack space={4}>
281
- <Heading size={1}>
282
- There are {props.missingAssets.length}
283
- {props.muxAssets.loading && '+'} Mux video{props.missingAssets.length > 1 && 's'}{' '}
284
- not in Sanity
285
- </Heading>
286
- {!props.muxAssets.loading && (
287
- <Flex align="center" paddingX={2}>
288
- <Checkbox
289
- id="import-all"
290
- style={{display: 'block'}}
291
- onClick={(e) => {
292
- const selectAll = e.currentTarget.checked
293
- if (selectAll) {
294
- // eslint-disable-next-line no-unused-expressions
295
- props.missingAssets && props.setSelectedAssets(props.missingAssets)
296
- } else {
297
- props.setSelectedAssets([])
298
- }
299
- }}
300
- checked={props.selectedAssets.length === props.missingAssets.length}
301
- />
302
- <Box flex={1} paddingLeft={3} as="label" htmlFor="import-all">
303
- <Text>Import all</Text>
304
- </Box>
305
- </Flex>
306
- )}
307
- {props.missingAssets.map((asset) => (
308
- <MissingAsset
309
- key={asset.id}
310
- asset={asset}
311
- selectAsset={(selected) => {
312
- if (selected) {
313
- props.setSelectedAssets([...props.selectedAssets, asset])
314
- } else {
315
- props.setSelectedAssets(props.selectedAssets.filter((a) => a.id !== asset.id))
316
- }
317
- }}
318
- selected={props.selectedAssets.some((a) => a.id === asset.id)}
319
- />
320
- ))}
321
- </Stack>
322
- )}
323
- </Box>
324
- </Dialog>
325
- )
326
- }
327
-
328
- export default function ImportVideosFromMux() {
329
- const importAssets = useImportMuxAssets()
330
-
331
- if (!importAssets.hasSecrets) {
332
- return
333
- }
334
-
335
- if (importAssets.dialogOpen) {
336
- // eslint-disable-next-line consistent-return
337
- return <ImportVideosDialog {...importAssets} />
338
- }
339
-
340
- // eslint-disable-next-line consistent-return
341
- return <Button mode="bleed" text="Import from Mux" onClick={importAssets.openDialog} />
342
- }
@@ -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
- }