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,29 +0,0 @@
1
- import {WarningFilledIcon} from '@sanity/icons'
2
- import {Box, Flex, Text} from '@sanity/ui'
3
- import {CSSProperties} from 'react'
4
-
5
- export default function PlaybackPolicyWarning() {
6
- const textStyle: CSSProperties = {
7
- color: '#13141A',
8
- fontWeight: 500,
9
- }
10
-
11
- const boxStyle: CSSProperties = {
12
- outline: '0.01rem solid grey',
13
- backgroundColor: '#979cb0',
14
- borderRadius: '0.5rem',
15
- width: 'max-content',
16
- color: '#13141A',
17
- }
18
-
19
- return (
20
- <Box padding={2} style={boxStyle}>
21
- <Flex align="center" gap={2}>
22
- <WarningFilledIcon />
23
- <Text size={1} style={textStyle}>
24
- Please select at least one Playback Policy
25
- </Text>
26
- </Flex>
27
- </Box>
28
- )
29
- }
@@ -1,72 +0,0 @@
1
- import {Flex, Radio, Text} from '@sanity/ui'
2
- import {ActionDispatch} from 'react'
3
- import {FormField} from 'sanity'
4
-
5
- import {type UploadConfig} from '../../util/types'
6
- import {UploadConfigurationStateAction} from '../UploadConfiguration'
7
-
8
- export const RESOLUTION_TIERS = [
9
- {value: '1080p', label: '1080p'},
10
- {value: '1440p', label: '1440p (2k)'},
11
- {value: '2160p', label: '2160p (4k)'},
12
- ] as const satisfies {value: UploadConfig['max_resolution_tier']; label: string}[]
13
-
14
- export const ResolutionTierSelector = ({
15
- id,
16
- config,
17
- dispatch,
18
- maxSupportedResolution,
19
- }: {
20
- id: string
21
- config: UploadConfig
22
- dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>
23
- maxSupportedResolution: number
24
- }) => {
25
- return (
26
- <FormField
27
- path={[]}
28
- title="Resolution Tier"
29
- description={
30
- <>
31
- The maximum{' '}
32
- <a
33
- href="https://docs.mux.com/api-reference#video/operation/create-direct-upload"
34
- target="_blank"
35
- rel="noopener noreferrer"
36
- >
37
- resolution_tier
38
- </a>{' '}
39
- your asset is encoded, stored, and streamed at.
40
- </>
41
- }
42
- >
43
- <Flex gap={3} wrap={'wrap'}>
44
- {RESOLUTION_TIERS.map(({value, label}, index) => {
45
- const inputId = `${id}--type-${value}`
46
-
47
- if (index > maxSupportedResolution) return null
48
-
49
- return (
50
- <Flex key={value} align="center" gap={2}>
51
- <Radio
52
- checked={config.max_resolution_tier === value}
53
- name="asset-resolutiontier"
54
- onChange={(e) =>
55
- dispatch({
56
- action: 'max_resolution_tier',
57
- value: e.currentTarget.value as UploadConfig['max_resolution_tier'],
58
- })
59
- }
60
- value={value}
61
- id={inputId}
62
- />
63
- <Text as="label" htmlFor={inputId}>
64
- {label}
65
- </Text>
66
- </Flex>
67
- )
68
- })}
69
- </Flex>
70
- </FormField>
71
- )
72
- }
@@ -1,180 +0,0 @@
1
- import {Checkbox, Flex, Label, Radio, Stack, Text} from '@sanity/ui'
2
- import {ActionDispatch, useMemo, useState} from 'react'
3
- import {FormField} from 'sanity'
4
-
5
- import {type StaticRenditionResolution, type UploadConfig} from '../../util/types'
6
- import {UploadConfigurationStateAction} from '../UploadConfiguration'
7
-
8
- const ADVANCED_RESOLUTIONS: {value: StaticRenditionResolution; label: string}[] = [
9
- {value: '270p', label: '270p'},
10
- {value: '360p', label: '360p'},
11
- {value: '480p', label: '480p'},
12
- {value: '540p', label: '540p'},
13
- {value: '720p', label: '720p'},
14
- {value: '1080p', label: '1080p'},
15
- {value: '1440p', label: '1440p'},
16
- {value: '2160p', label: '2160p'},
17
- ]
18
-
19
- export const StaticRenditionSelector = ({
20
- id,
21
- config,
22
- dispatch,
23
- }: {
24
- id: string
25
- config: UploadConfig
26
- dispatch: ActionDispatch<[action: UploadConfigurationStateAction]>
27
- }) => {
28
- // Determine if user is in advanced mode based on selected renditions
29
- const isAdvancedMode = useMemo(() => {
30
- const specificResolutions = config.static_renditions.filter(
31
- (r) => r !== 'highest' && r !== 'audio-only'
32
- )
33
- return specificResolutions.length > 0
34
- }, [config.static_renditions])
35
-
36
- const [renditionMode, setRenditionMode] = useState<'standard' | 'advanced'>(
37
- isAdvancedMode ? 'advanced' : 'standard'
38
- )
39
-
40
- // Helper to toggle a rendition
41
- const toggleRendition = (rendition: StaticRenditionResolution) => {
42
- const current = config.static_renditions
43
- const hasRendition = current.includes(rendition)
44
-
45
- if (hasRendition) {
46
- dispatch({
47
- action: 'static_renditions',
48
- value: current.filter((r) => r !== rendition),
49
- })
50
- } else {
51
- dispatch({
52
- action: 'static_renditions',
53
- value: [...current, rendition],
54
- })
55
- }
56
- }
57
-
58
- // When switching modes, clear renditions that don't apply
59
- const handleModeChange = (mode: 'standard' | 'advanced') => {
60
- setRenditionMode(mode)
61
- if (mode === 'standard') {
62
- // Remove specific resolutions, keep only highest and audio-only
63
- dispatch({
64
- action: 'static_renditions',
65
- value: config.static_renditions.filter((r) => r === 'highest' || r === 'audio-only'),
66
- })
67
- } else {
68
- // Remove highest, keep specific resolutions and audio-only
69
- dispatch({
70
- action: 'static_renditions',
71
- value: config.static_renditions.filter((r) => r !== 'highest'),
72
- })
73
- }
74
- }
75
- return (
76
- <Stack space={3}>
77
- <FormField
78
- path={[]}
79
- title="Static Renditions"
80
- description="Generate downloadable MP4 or M4A files. Note: Mux will not upscale to produce MP4 renditions - renditions that would cause upscaling are skipped."
81
- >
82
- <Stack space={3}>
83
- {/* Mode Selector */}
84
- <Flex gap={3}>
85
- <Flex align="center" gap={2}>
86
- <Radio
87
- checked={renditionMode === 'standard'}
88
- name="rendition-mode"
89
- onChange={() => handleModeChange('standard')}
90
- value="standard"
91
- id={`${id}--mode-standard`}
92
- />
93
- <Text as="label" htmlFor={`${id}--mode-standard`}>
94
- Standard
95
- </Text>
96
- </Flex>
97
- <Flex align="center" gap={2}>
98
- <Radio
99
- checked={renditionMode === 'advanced'}
100
- name="rendition-mode"
101
- onChange={() => handleModeChange('advanced')}
102
- value="advanced"
103
- id={`${id}--mode-advanced`}
104
- />
105
- <Text as="label" htmlFor={`${id}--mode-advanced`}>
106
- Advanced
107
- </Text>
108
- </Flex>
109
- </Flex>
110
-
111
- {/* Standard Mode Options */}
112
- {renditionMode === 'standard' && (
113
- <Stack space={2}>
114
- <Flex align="center" gap={2} padding={[0, 2]}>
115
- <Checkbox
116
- id={`${id}--highest`}
117
- style={{display: 'block'}}
118
- checked={config.static_renditions.includes('highest')}
119
- onChange={() => toggleRendition('highest')}
120
- />
121
- <Text as="label" htmlFor={`${id}--highest`}>
122
- Highest Resolution (up to 4K)
123
- </Text>
124
- </Flex>
125
- <Flex align="center" gap={2} padding={[0, 2]}>
126
- <Checkbox
127
- id={`${id}--audio-only-standard`}
128
- style={{display: 'block'}}
129
- checked={config.static_renditions.includes('audio-only')}
130
- onChange={() => toggleRendition('audio-only')}
131
- />
132
- <Text as="label" htmlFor={`${id}--audio-only-standard`}>
133
- Audio Only (M4A)
134
- </Text>
135
- </Flex>
136
- </Stack>
137
- )}
138
-
139
- {/* Advanced Mode Options */}
140
- {renditionMode === 'advanced' && (
141
- <Stack space={2}>
142
- <Label size={1} muted>
143
- Select specific resolutions:
144
- </Label>
145
- <Flex gap={2} wrap="wrap">
146
- {ADVANCED_RESOLUTIONS.map(({value, label}) => {
147
- const inputId = `${id}--resolution-${value}`
148
- return (
149
- <Flex key={value} align="center" gap={2}>
150
- <Checkbox
151
- id={inputId}
152
- style={{display: 'block'}}
153
- checked={config.static_renditions.includes(value)}
154
- onChange={() => toggleRendition(value)}
155
- />
156
- <Text as="label" htmlFor={inputId} size={1}>
157
- {label}
158
- </Text>
159
- </Flex>
160
- )
161
- })}
162
- </Flex>
163
- <Flex align="center" gap={2} padding={[2, 2, 0, 2]}>
164
- <Checkbox
165
- id={`${id}--audio-only-advanced`}
166
- style={{display: 'block'}}
167
- checked={config.static_renditions.includes('audio-only')}
168
- onChange={() => toggleRendition('audio-only')}
169
- />
170
- <Text as="label" htmlFor={`${id}--audio-only-advanced`}>
171
- Audio Only (M4A)
172
- </Text>
173
- </Flex>
174
- </Stack>
175
- )}
176
- </Stack>
177
- </FormField>
178
- </Stack>
179
- )
180
- }
@@ -1,24 +0,0 @@
1
- // todo: get these utils from @sanity/ui instead
2
- export function focusRingBorderStyle(border: {color: string; width: number}): string {
3
- return `inset 0 0 0 ${border.width}px ${border.color}`
4
- }
5
-
6
- export function focusRingStyle(opts: {
7
- base?: {bg: string}
8
- border?: {color: string; width: number}
9
- focusRing: {offset: number; width: number}
10
- }): string {
11
- const {base, border, focusRing} = opts
12
- const focusRingOutsetWidth = focusRing.offset + focusRing.width
13
- const focusRingInsetWidth = 0 - focusRing.offset
14
- const bgColor = base ? base.bg : 'var(--card-bg-color)'
15
-
16
- return [
17
- focusRingInsetWidth > 0 && `inset 0 0 0 ${focusRingInsetWidth}px var(--card-focus-ring-color)`,
18
- border && focusRingBorderStyle(border),
19
- focusRingInsetWidth < 0 && `0 0 0 ${0 - focusRingInsetWidth}px ${bgColor}`,
20
- focusRingOutsetWidth > 0 && `0 0 0 ${focusRingOutsetWidth}px var(--card-focus-ring-color)`,
21
- ]
22
- .filter(Boolean)
23
- .join(',')
24
- }
@@ -1 +0,0 @@
1
- export * from './withFocusRing'
@@ -1,30 +0,0 @@
1
- import {rem} from '@sanity/ui'
2
- import type {ComponentType} from 'react'
3
- import {css, styled} from 'styled-components'
4
-
5
- import {focusRingBorderStyle, focusRingStyle} from './helpers'
6
-
7
- export function withFocusRing<Props>(component: ComponentType<Props>) {
8
- return styled(component as unknown as any)<Props & {$border?: boolean}>((props) => {
9
- const border = {
10
- width: props.$border ? 1 : 0,
11
- color: 'var(--card-border-color)',
12
- }
13
-
14
- return css`
15
- --card-focus-box-shadow: ${focusRingBorderStyle(border)};
16
-
17
- border-radius: ${rem(props.theme.sanity.radius[1])};
18
- outline: none;
19
- box-shadow: var(--card-focus-box-shadow);
20
-
21
- &:focus {
22
- --card-focus-box-shadow: ${focusRingStyle({
23
- base: props.theme.sanity.color.base,
24
- border,
25
- focusRing: props.theme.sanity.focusRing,
26
- })};
27
- }
28
- `
29
- })
30
- }
@@ -1,36 +0,0 @@
1
- import React, {createContext, useContext} from 'react'
2
-
3
- import {type DialogState, type SetDialogState} from '../hooks/useDialogState'
4
-
5
- type DialogStateContextProps = {
6
- dialogState: DialogState
7
- setDialogState: SetDialogState
8
- }
9
-
10
- const DialogStateContext = createContext<DialogStateContextProps>({
11
- dialogState: false,
12
- setDialogState: () => {
13
- return null
14
- },
15
- })
16
-
17
- interface DialogStateProviderProps extends DialogStateContextProps {
18
- children: React.ReactNode
19
- }
20
-
21
- export const DialogStateProvider = ({
22
- dialogState,
23
- setDialogState,
24
- children,
25
- }: DialogStateProviderProps) => {
26
- return (
27
- <DialogStateContext.Provider value={{dialogState, setDialogState}}>
28
- {children}
29
- </DialogStateContext.Provider>
30
- )
31
- }
32
-
33
- export const useDialogStateContext = () => {
34
- const context = useContext(DialogStateContext)
35
- return context
36
- }
@@ -1,93 +0,0 @@
1
- import {Button, Card, Dialog, Stack, Text} from '@sanity/ui'
2
- import React, {createContext, useContext, useState} from 'react'
3
-
4
- import {PluginConfig} from '../util/types'
5
-
6
- const LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY = 'mux-plugin-has-shown-drm-playback-warning'
7
-
8
- type DrmPlaybackWarningContextContextProps = {
9
- hasShownWarning: boolean
10
- setHasWarnedAboutDrmPlayback: (b: boolean) => void
11
- }
12
-
13
- const DrmPlaybackWarningContext = createContext<DrmPlaybackWarningContextContextProps>({
14
- hasShownWarning: false,
15
- setHasWarnedAboutDrmPlayback: () => {
16
- return null
17
- },
18
- })
19
-
20
- interface DrmPlaybackWarningContextProviderProps {
21
- config?: PluginConfig
22
- children: React.ReactNode
23
- }
24
-
25
- export const DrmPlaybackWarningContextProvider = ({
26
- config,
27
- children,
28
- }: DrmPlaybackWarningContextProviderProps) => {
29
- const warningDisabled = config?.disableDrmPlaybackWarning ?? false
30
- const hasWarned: boolean =
31
- warningDisabled || window.localStorage.getItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY) === 'true'
32
- const [hasWarnedAboutDrmPlayback, setHasWarnedAboutDrmPlayback] = useState(hasWarned)
33
-
34
- const setHasShownWarning = (b: boolean) => {
35
- window.localStorage.setItem(LOCAL_STORAGE_HAS_SHOWN_WARNING_KEY, b.toString())
36
- setHasWarnedAboutDrmPlayback(b)
37
- }
38
- return (
39
- <DrmPlaybackWarningContext.Provider
40
- value={{
41
- hasShownWarning: hasWarnedAboutDrmPlayback,
42
- setHasWarnedAboutDrmPlayback: setHasShownWarning,
43
- }}
44
- >
45
- {children}
46
- </DrmPlaybackWarningContext.Provider>
47
- )
48
- }
49
-
50
- export const useDrmPlaybackWarningContext = () => {
51
- const context = useContext(DrmPlaybackWarningContext)
52
- return context
53
- }
54
-
55
- export const DRMWarningDialog = ({onClose}: {onClose: () => void}) => {
56
- const {setHasWarnedAboutDrmPlayback} = useDrmPlaybackWarningContext()
57
- const _onClose = () => {
58
- setHasWarnedAboutDrmPlayback(true)
59
- onClose()
60
- }
61
- return (
62
- <Dialog
63
- open
64
- id="drm-playback-warn"
65
- onClose={_onClose}
66
- header="DRM Playback Warning"
67
- footer={
68
- <Stack padding={3}>
69
- <Button mode="ghost" tone="primary" onClick={_onClose} text="Ok" />
70
- </Stack>
71
- }
72
- >
73
- <Stack space={3} padding={3}>
74
- <Card padding={[3, 3, 3]} radius={2}>
75
- <Stack space={3}>
76
- <Text size={1} weight="semibold">
77
- DRM-protected playback will generate a license with a small associated cost. The
78
- plugin will attempt to play signed or public playback IDs instead whenever possible.
79
- </Text>
80
- </Stack>
81
- </Card>
82
- <Card padding={[3, 3, 3]} radius={2} tone="suggest">
83
- <Stack space={3}>
84
- <Text size={1} weight="semibold">
85
- This is a one time warning. If it persists, you can disable it from your plugin
86
- configuration.
87
- </Text>
88
- </Stack>
89
- </Card>
90
- </Stack>
91
- </Dialog>
92
- )
93
- }
@@ -1,13 +0,0 @@
1
- import {useCurrentUser} from 'sanity'
2
-
3
- import {PluginConfig} from '../util/types'
4
-
5
- export const useAccessControl = (config: PluginConfig) => {
6
- const user = useCurrentUser()
7
-
8
- const hasConfigAccess =
9
- !config?.allowedRolesForConfiguration?.length ||
10
- user?.roles?.some((role) => config.allowedRolesForConfiguration.includes(role.name))
11
-
12
- return {hasConfigAccess}
13
- }
@@ -1,11 +0,0 @@
1
- import {isReference} from 'sanity'
2
- import {useDocumentValues} from 'sanity'
3
-
4
- import type {Reference, VideoAssetDocument} from '../util/types'
5
-
6
- const path = ['assetId', 'data', 'playbackId', 'status', 'thumbTime', 'filename']
7
- export const useAssetDocumentValues = (asset: Reference | null | undefined) =>
8
- useDocumentValues<VideoAssetDocument | null | undefined>(
9
- isReference(asset) ? asset._ref! : '',
10
- path
11
- )
@@ -1,68 +0,0 @@
1
- import {useMemo, useState} from 'react'
2
- import {collate, createHookFromObservableFactory, DocumentStore, useDocumentStore} from 'sanity'
3
-
4
- import {SANITY_API_VERSION} from '../hooks/useClient'
5
- import {createSearchFilter} from '../util/createSearchFilter'
6
- import type {VideoAssetDocument} from '../util/types'
7
-
8
- export const ASSET_SORT_OPTIONS = {
9
- createdDesc: {groq: '_createdAt desc', label: 'Newest first'},
10
- createdAsc: {groq: '_createdAt asc', label: 'First created (oldest)'},
11
- filenameAsc: {groq: 'filename asc', label: 'By filename (A-Z)'},
12
- filenameDesc: {groq: 'filename desc', label: 'By filename (Z-A)'},
13
- }
14
-
15
- export type SortOption = keyof typeof ASSET_SORT_OPTIONS
16
-
17
- const useAssetDocuments = createHookFromObservableFactory<
18
- VideoAssetDocument[],
19
- {
20
- documentStore: DocumentStore
21
- sort: SortOption
22
- searchQuery: string
23
- }
24
- >(({documentStore, sort, searchQuery}) => {
25
- const search = createSearchFilter(searchQuery)
26
- const filter = [`_type == "mux.videoAsset"`, ...search.filter].filter(Boolean).join(' && ')
27
-
28
- const sortFragment = ASSET_SORT_OPTIONS[sort].groq
29
- return documentStore.listenQuery(
30
- /* groq */ `*[${filter}] | order(${sortFragment})`,
31
- search.params,
32
- {
33
- apiVersion: SANITY_API_VERSION,
34
- }
35
- )
36
- })
37
-
38
- export default function useAssets() {
39
- const documentStore = useDocumentStore()
40
- const [sort, setSort] = useState<SortOption>('createdDesc')
41
- const [searchQuery, setSearchQuery] = useState('')
42
-
43
- const [assetDocuments = [], isLoading] = useAssetDocuments(
44
- useMemo(() => ({documentStore, sort, searchQuery}), [documentStore, sort, searchQuery])
45
- )
46
-
47
- const assets = useMemo(
48
- () =>
49
- // Avoid displaying both drafts & published assets by collating them together and giving preference to drafts
50
- collate<VideoAssetDocument>(assetDocuments).map(
51
- (collated) =>
52
- ({
53
- ...(collated.draft || collated.published || {}),
54
- _id: collated.id,
55
- }) as VideoAssetDocument
56
- ),
57
- [assetDocuments]
58
- )
59
-
60
- return {
61
- assets,
62
- isLoading,
63
- sort,
64
- searchQuery,
65
- setSort,
66
- setSearchQuery,
67
- }
68
- }
@@ -1,22 +0,0 @@
1
- import {useCallback} from 'react'
2
- import {PatchEvent, unset} from 'sanity'
3
-
4
- import {deleteAssetOnMux} from '../actions/assets'
5
- import {useClient} from '../hooks/useClient'
6
- import type {MuxInputProps, VideoAssetDocument} from '../util/types'
7
-
8
- export const useCancelUpload = (asset: VideoAssetDocument, onChange: MuxInputProps['onChange']) => {
9
- const client = useClient()
10
- return useCallback(() => {
11
- if (!asset) {
12
- return
13
- }
14
- onChange(PatchEvent.from(unset()))
15
- if (asset.assetId) {
16
- deleteAssetOnMux(client, asset.assetId)
17
- }
18
- if (asset._id) {
19
- client.delete(asset._id)
20
- }
21
- }, [asset, client, onChange])
22
- }
@@ -1,8 +0,0 @@
1
- // As it's required to specify the API Version this custom hook ensures it's all using the same version
2
- import {useClient as useSanityClient} from 'sanity'
3
-
4
- export const SANITY_API_VERSION = '2024-03-05'
5
-
6
- export function useClient() {
7
- return useSanityClient({apiVersion: SANITY_API_VERSION})
8
- }
@@ -1,11 +0,0 @@
1
- // Handy little state machine to simplify managing which root level dialog to open
2
-
3
- import {useState} from 'react'
4
-
5
- export type DialogState = 'secrets' | 'select-video' | 'edit-thumbnail' | 'edit-captions' | false
6
-
7
- export function useDialogState() {
8
- return useState<DialogState>(false)
9
- }
10
-
11
- export type SetDialogState = ReturnType<typeof useDialogState>[1]
@@ -1,21 +0,0 @@
1
- import {createHookFromObservableFactory, DocumentStore, SanityDocument} from 'sanity'
2
-
3
- import {SANITY_API_VERSION} from './useClient'
4
-
5
- const useDocReferences = createHookFromObservableFactory<
6
- SanityDocument[],
7
- {
8
- documentStore: DocumentStore
9
- id: string
10
- }
11
- >(({documentStore, id}) => {
12
- return documentStore.listenQuery(
13
- /* groq */ '*[references($id)]{_id, _type, _rev, _updatedAt, _createdAt}',
14
- {id},
15
- {
16
- apiVersion: SANITY_API_VERSION,
17
- }
18
- )
19
- })
20
-
21
- export default useDocReferences