Skip to content

Commit

Permalink
fix: explicitly list allowed image types for upload
Browse files Browse the repository at this point in the history
  • Loading branch information
rexxars committed Nov 14, 2024
1 parent 0997caa commit cb49883
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -108,10 +108,8 @@ function BaseImageInputComponent(props: BaseImageInputProps): JSX.Element {
}, [path])

const clearUploadStatus = useCallback(() => {
if (value?._upload) {
onChange(unset(['_upload']))
}
}, [onChange, value?._upload])
onChange(unset(['_upload']))
}, [onChange])
const cancelUpload = useCallback(() => {
if (uploadSubscription.current) {
uploadSubscription.current.unsubscribe()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {type Observable} from 'rxjs'
import {MenuItem} from '../../../../../ui-components'
import {useTranslation} from '../../../../i18n'
import {ActionsMenu} from '../common/ActionsMenu'
import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../constants'
import {ImageActionsMenu, ImageActionsMenuWaitPlaceholder} from './ImageActionsMenu'
import {type BaseImageInputProps} from './types'

Expand Down Expand Up @@ -54,7 +55,10 @@ function ImageInputAssetMenuComponent(
} = props
const {t} = useTranslation()

const accept = useMemo(() => get(schemaType, 'options.accept', 'image/*'), [schemaType])
const accept = useMemo(
() => get(schemaType, 'options.accept', SUPPORTED_IMAGE_UPLOAD_TYPES.join(',')),
[schemaType],
)
const asset = value?.asset

const showAdvancedEditButton = value && asset && isImageToolEnabled
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {get} from 'lodash'
import {memo, useMemo} from 'react'

import {WithReferencedAsset} from '../../../utils/WithReferencedAsset'
import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../constants'
import {type BaseImageInputProps} from './types'

function ImageInputAssetSourceComponent(
Expand All @@ -20,7 +21,10 @@ function ImageInputAssetSourceComponent(
selectedAssetSource,
value,
} = props
const accept = useMemo(() => get(schemaType, 'options.accept', 'image/*'), [schemaType])
const accept = useMemo(
() => get(schemaType, 'options.accept', SUPPORTED_IMAGE_UPLOAD_TYPES.join(',')),
[schemaType],
)

if (!selectedAssetSource) {
return null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {get} from 'lodash'
import {memo, useMemo} from 'react'

import {UploadPlaceholder} from '../common/UploadPlaceholder'
import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../constants'
import {type BaseImageInputProps, type FileInfo} from './types'

function ImageInputUploadPlaceholderComponent(props: {
Expand All @@ -28,7 +29,10 @@ function ImageInputUploadPlaceholderComponent(props: {
() => hoveringFiles.filter((file) => resolveUploader(schemaType, file)),
[hoveringFiles, resolveUploader, schemaType],
)
const accept = useMemo(() => get(schemaType, 'options.accept', 'image/*'), [schemaType])
const accept = useMemo(
() => get(schemaType, 'options.accept', SUPPORTED_IMAGE_UPLOAD_TYPES.join(',')),
[schemaType],
)

const rejectedFilesCount = hoveringFiles.length - acceptedFiles.length

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import {Card, Container, Flex} from '@sanity/ui'

import {Button} from '../../../../../ui-components'
import {UploadPlaceholder} from '../common/UploadPlaceholder'
import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../constants'

export default function UploadPlaceholderStory() {
return (
<Flex align="center" height="fill" justify="center" padding={3}>
<Container width={1}>
<Card>
<UploadPlaceholder
accept="image/*"
accept={SUPPORTED_IMAGE_UPLOAD_TYPES.join(',')}
acceptedFiles={[{name: 'foo.jpg', type: 'image/jpeg'}]}
browse={<Button text="Browse btn" mode="ghost" />}
directUploads
Expand Down
16 changes: 16 additions & 0 deletions packages/sanity/src/core/form/inputs/files/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,19 @@
* the upload will be marked as stale/interrupted.
*/
export const STALE_UPLOAD_MS = 1000 * 60 * 2

/**
* The mime types of image formats we support uploading
*
* @internal
*/
export const SUPPORTED_IMAGE_UPLOAD_TYPES = [
'image/bmp',
'image/gif',
'image/jpeg',
'image/png',
'image/svg',
'image/tiff',
'image/webp',
'.psd', // Many different mime types for PSD files, so we just use the extension
]
Original file line number Diff line number Diff line change
Expand Up @@ -73,10 +73,13 @@ export const uploadImageAsset = (
client: SanityClient,
file: File | Blob,
options?: UploadOptions,
) => uploadAsset(client, 'image', file, options)
): Observable<UploadEvent> => uploadAsset(client, 'image', file, options)

export const uploadFileAsset = (client: SanityClient, file: File | Blob, options?: UploadOptions) =>
uploadAsset(client, 'file', file, options)
export const uploadFileAsset = (
client: SanityClient,
file: File | Blob,
options?: UploadOptions,
): Observable<UploadEvent> => uploadAsset(client, 'file', file, options)

/**
*
Expand Down Expand Up @@ -123,11 +126,17 @@ function observeAssetDoc(documentPreviewStore: DocumentPreviewStore, id: string)
)
}

export function observeImageAsset(documentPreviewStore: DocumentPreviewStore, id: string) {
export function observeImageAsset(
documentPreviewStore: DocumentPreviewStore,
id: string,
): Observable<ImageAsset> {
return observeAssetDoc(documentPreviewStore, id) as Observable<ImageAsset>
}

export function observeFileAsset(documentPreviewStore: DocumentPreviewStore, id: string) {
export function observeFileAsset(
documentPreviewStore: DocumentPreviewStore,
id: string,
): Observable<FileAsset> {
return observeAssetDoc(documentPreviewStore, id) as Observable<FileAsset>
}

Expand Down
5 changes: 2 additions & 3 deletions packages/sanity/src/core/form/studio/uploads/uploadImage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,11 @@ export function uploadImage(
options?: UploadOptions,
): Observable<UploadProgressEvent> {
const upload$ = uploadImageAsset(client, file, options).pipe(
filter((event: any) => event.stage !== 'download'),
filter((event) => !('stage' in event) || event.stage !== 'download'),
map((event) => ({
...event,
progress: 2 + (event.percent / 100) * 98,
progress: event.type === 'complete' ? 100 : 2 + (event.percent / 100) * 98,
})),

map((event) => {
if (event.type === 'complete') {
return createUploadEvent([
Expand Down
3 changes: 2 additions & 1 deletion packages/sanity/src/core/form/studio/uploads/uploaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import {type SanityClient} from '@sanity/client'
import {type SchemaType} from '@sanity/types'
import {map} from 'rxjs/operators'

import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../../inputs/files/constants'
import {set} from '../../patch'
import {type Uploader, type UploaderDef, type UploadOptions} from './types'
import {uploadFile} from './uploadFile'
import {uploadImage} from './uploadImage'

const UPLOAD_IMAGE: UploaderDef = {
type: 'image',
accepts: 'image/*',
accepts: SUPPORTED_IMAGE_UPLOAD_TYPES.join(','),
upload: (client: SanityClient, file: File, type?: SchemaType, options?: UploadOptions) =>
uploadImage(client, file, options),
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {styled} from 'styled-components'

import {Button, MenuButton, MenuItem} from '../../../../../../../../../../ui-components'
import {type Source} from '../../../../../../../../../config'
import {SUPPORTED_IMAGE_UPLOAD_TYPES} from '../../../../../../../../../form/inputs/files/constants'
import {FileSource, ImageSource} from '../../../../../../../../../form/studio/assetSource'
import {useClient} from '../../../../../../../../../hooks'
import {useTranslation} from '../../../../../../../../../i18n'
Expand Down Expand Up @@ -102,13 +103,15 @@ export function SearchFilterAssetInput(type?: AssetType) {

const AssetSourceComponent = selectedAssetSource?.component

const fontSize = fullscreen ? 2 : 1

const buttonText = t(value ? 'search.filter-asset-change' : 'search.filter-asset-select', {
context: type,
})

const accept = get(type, 'options.accept', type === 'image' ? 'image/*' : '')
const accept = get(
type,
'options.accept',
type === 'image' ? SUPPORTED_IMAGE_UPLOAD_TYPES.join(',') : '',
)

return (
<ContainerBox>
Expand Down

0 comments on commit cb49883

Please sign in to comment.