mirror of
https://github.com/simstudioai/sim.git
synced 2026-09-24 15:45:35 +08:00
feat(files): allow image uploads in workspace files (#4419)
* feat(files): allow image uploads in workspace files * fix(files): include images in workspace type filter * fix(files): match all image mime types in image filter
This commit is contained in:
@@ -43,6 +43,7 @@ import {
|
||||
SUPPORTED_AUDIO_EXTENSIONS,
|
||||
SUPPORTED_CODE_EXTENSIONS,
|
||||
SUPPORTED_DOCUMENT_EXTENSIONS,
|
||||
SUPPORTED_IMAGE_EXTENSIONS,
|
||||
SUPPORTED_VIDEO_EXTENSIONS,
|
||||
} from '@/lib/uploads/utils/validation'
|
||||
import type {
|
||||
@@ -89,6 +90,7 @@ const SUPPORTED_EXTENSIONS = [
|
||||
...SUPPORTED_CODE_EXTENSIONS,
|
||||
...SUPPORTED_AUDIO_EXTENSIONS,
|
||||
...SUPPORTED_VIDEO_EXTENSIONS,
|
||||
...SUPPORTED_IMAGE_EXTENSIONS,
|
||||
] as const
|
||||
|
||||
const ACCEPT_ATTR = SUPPORTED_EXTENSIONS.map((ext) => `.${ext}`).join(',')
|
||||
@@ -125,6 +127,7 @@ function formatFileType(mimeType: string | null, filename: string): string {
|
||||
|
||||
if (mimeType?.startsWith('audio/')) return 'Audio'
|
||||
if (mimeType?.startsWith('video/')) return 'Video'
|
||||
if (mimeType?.startsWith('image/')) return 'Image'
|
||||
|
||||
const ext = getFileExtension(filename)
|
||||
if (ext) return ext.toUpperCase()
|
||||
@@ -246,6 +249,7 @@ export function Files() {
|
||||
if (typeFilter.includes('document') && isSupportedExtension(ext)) return true
|
||||
if (typeFilter.includes('audio') && isAudioFileType(f.type)) return true
|
||||
if (typeFilter.includes('video') && isVideoFileType(f.type)) return true
|
||||
if (typeFilter.includes('image') && f.type?.startsWith('image/')) return true
|
||||
return false
|
||||
})
|
||||
}
|
||||
@@ -926,9 +930,14 @@ export function Files() {
|
||||
typeFilter.length === 0
|
||||
? 'All'
|
||||
: typeFilter.length === 1
|
||||
? (({ document: 'Documents', audio: 'Audio', video: 'Video' } as Record<string, string>)[
|
||||
typeFilter[0]
|
||||
] ?? typeFilter[0])
|
||||
? ((
|
||||
{
|
||||
document: 'Documents',
|
||||
image: 'Images',
|
||||
audio: 'Audio',
|
||||
video: 'Video',
|
||||
} as Record<string, string>
|
||||
)[typeFilter[0]] ?? typeFilter[0])
|
||||
: `${typeFilter.length} selected`
|
||||
|
||||
const sizeDisplayLabel =
|
||||
@@ -954,6 +963,7 @@ export function Files() {
|
||||
<Combobox
|
||||
options={[
|
||||
{ value: 'document', label: 'Documents' },
|
||||
{ value: 'image', label: 'Images' },
|
||||
{ value: 'audio', label: 'Audio' },
|
||||
{ value: 'video', label: 'Video' },
|
||||
]}
|
||||
@@ -1036,6 +1046,7 @@ export function Files() {
|
||||
if (typeFilter.length > 0) {
|
||||
const typeLabels: Record<string, string> = {
|
||||
document: 'Documents',
|
||||
image: 'Images',
|
||||
audio: 'Audio',
|
||||
video: 'Video',
|
||||
}
|
||||
|
||||
@@ -95,13 +95,31 @@ export const SUPPORTED_AUDIO_EXTENSIONS = [
|
||||
|
||||
export const SUPPORTED_VIDEO_EXTENSIONS = ['mp4', 'mov', 'avi', 'mkv', 'webm'] as const
|
||||
|
||||
export const SUPPORTED_IMAGE_EXTENSIONS = [
|
||||
'png',
|
||||
'jpg',
|
||||
'jpeg',
|
||||
'gif',
|
||||
'webp',
|
||||
'svg',
|
||||
'bmp',
|
||||
'tif',
|
||||
'tiff',
|
||||
'heic',
|
||||
'heif',
|
||||
'avif',
|
||||
'ico',
|
||||
] as const
|
||||
|
||||
export type SupportedDocumentExtension = (typeof SUPPORTED_DOCUMENT_EXTENSIONS)[number]
|
||||
export type SupportedAudioExtension = (typeof SUPPORTED_AUDIO_EXTENSIONS)[number]
|
||||
export type SupportedVideoExtension = (typeof SUPPORTED_VIDEO_EXTENSIONS)[number]
|
||||
export type SupportedImageExtension = (typeof SUPPORTED_IMAGE_EXTENSIONS)[number]
|
||||
export type SupportedMediaExtension =
|
||||
| SupportedDocumentExtension
|
||||
| SupportedAudioExtension
|
||||
| SupportedVideoExtension
|
||||
| SupportedImageExtension
|
||||
|
||||
export const SUPPORTED_MIME_TYPES: Record<SupportedDocumentExtension, string[]> = {
|
||||
pdf: ['application/pdf', 'application/x-pdf'],
|
||||
@@ -180,14 +198,19 @@ const SUPPORTED_IMAGE_MIME_TYPES = [
|
||||
'image/gif',
|
||||
'image/webp',
|
||||
'image/svg+xml',
|
||||
'image/bmp',
|
||||
'image/tiff',
|
||||
'image/heic',
|
||||
'image/heif',
|
||||
'image/avif',
|
||||
'image/x-icon',
|
||||
'image/vnd.microsoft.icon',
|
||||
]
|
||||
|
||||
const SUPPORTED_IMAGE_EXTENSIONS = ['.jpg', '.jpeg', '.png', '.gif', '.webp', '.svg']
|
||||
|
||||
export const CHAT_ACCEPT_ATTRIBUTE = [
|
||||
ACCEPT_ATTRIBUTE,
|
||||
...SUPPORTED_IMAGE_MIME_TYPES,
|
||||
...SUPPORTED_IMAGE_EXTENSIONS,
|
||||
...SUPPORTED_IMAGE_EXTENSIONS.map((ext) => `.${ext}`),
|
||||
].join(',')
|
||||
|
||||
export interface FileValidationError {
|
||||
|
||||
Reference in New Issue
Block a user