feat: multimodal support (image) (#27793)
Co-authored-by: zxhlyh <jasonapring2015@outlook.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
23
web/app/components/base/file-thumb/image-render.tsx
Normal file
23
web/app/components/base/file-thumb/image-render.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
import React from 'react'
|
||||
|
||||
type ImageRenderProps = {
|
||||
sourceUrl: string
|
||||
name: string
|
||||
}
|
||||
|
||||
const ImageRender = ({
|
||||
sourceUrl,
|
||||
name,
|
||||
}: ImageRenderProps) => {
|
||||
return (
|
||||
<div className='size-full border-[2px] border-effects-image-frame shadow-xs'>
|
||||
<img
|
||||
className='size-full object-cover'
|
||||
src={sourceUrl}
|
||||
alt={name}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(ImageRender)
|
||||
87
web/app/components/base/file-thumb/index.tsx
Normal file
87
web/app/components/base/file-thumb/index.tsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import React, { useCallback } from 'react'
|
||||
import ImageRender from './image-render'
|
||||
import type { VariantProps } from 'class-variance-authority'
|
||||
import { cva } from 'class-variance-authority'
|
||||
import cn from '@/utils/classnames'
|
||||
import { getFileAppearanceType } from '../file-uploader/utils'
|
||||
import { FileTypeIcon } from '../file-uploader'
|
||||
import Tooltip from '../tooltip'
|
||||
|
||||
const FileThumbVariants = cva(
|
||||
'flex items-center justify-center cursor-pointer',
|
||||
{
|
||||
variants: {
|
||||
size: {
|
||||
sm: 'size-6',
|
||||
md: 'size-8',
|
||||
},
|
||||
},
|
||||
defaultVariants: {
|
||||
size: 'sm',
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
export type FileEntity = {
|
||||
name: string
|
||||
size: number
|
||||
extension: string
|
||||
mimeType: string
|
||||
sourceUrl: string
|
||||
}
|
||||
|
||||
type FileThumbProps = {
|
||||
file: FileEntity
|
||||
className?: string
|
||||
onClick?: (file: FileEntity) => void
|
||||
} & VariantProps<typeof FileThumbVariants>
|
||||
|
||||
const FileThumb = ({
|
||||
file,
|
||||
size,
|
||||
className,
|
||||
onClick,
|
||||
}: FileThumbProps) => {
|
||||
const { name, mimeType, sourceUrl } = file
|
||||
const isImage = mimeType.startsWith('image/')
|
||||
|
||||
const handleClick = useCallback((e: React.MouseEvent<HTMLDivElement>) => {
|
||||
e.stopPropagation()
|
||||
e.preventDefault()
|
||||
onClick?.(file)
|
||||
}, [onClick, file])
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
popupContent={name}
|
||||
popupClassName='p-1.5 rounded-lg system-xs-medium text-text-secondary'
|
||||
position='top'
|
||||
>
|
||||
<div
|
||||
className={cn(
|
||||
FileThumbVariants({ size, className }),
|
||||
isImage
|
||||
? 'p-px'
|
||||
: 'rounded-md border-[0.5px] border-components-panel-border bg-components-panel-on-panel-item-bg shadow-xs hover:bg-components-panel-on-panel-item-bg-alt',
|
||||
)}
|
||||
onClick={handleClick}
|
||||
>
|
||||
{
|
||||
isImage ? (
|
||||
<ImageRender
|
||||
sourceUrl={sourceUrl}
|
||||
name={name}
|
||||
/>
|
||||
) : (
|
||||
<FileTypeIcon
|
||||
type={getFileAppearanceType(name, mimeType)}
|
||||
size='sm'
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
||||
|
||||
export default React.memo(FileThumb)
|
||||
@@ -26,10 +26,21 @@ export const getFileUploadErrorMessage = (error: any, defaultMessage: string, t:
|
||||
return defaultMessage
|
||||
}
|
||||
|
||||
type FileUploadResponse = {
|
||||
created_at: number
|
||||
created_by: string
|
||||
extension: string
|
||||
id: string
|
||||
mime_type: string
|
||||
name: string
|
||||
preview_url: string | null
|
||||
size: number
|
||||
source_url: string
|
||||
}
|
||||
type FileUploadParams = {
|
||||
file: File
|
||||
onProgressCallback: (progress: number) => void
|
||||
onSuccessCallback: (res: { id: string }) => void
|
||||
onSuccessCallback: (res: FileUploadResponse) => void
|
||||
onErrorCallback: (error?: any) => void
|
||||
}
|
||||
type FileUpload = (v: FileUploadParams, isPublic?: boolean, url?: string) => void
|
||||
@@ -53,8 +64,8 @@ export const fileUpload: FileUpload = ({
|
||||
data: formData,
|
||||
onprogress: onProgress,
|
||||
}, isPublic, url)
|
||||
.then((res: { id: string }) => {
|
||||
onSuccessCallback(res)
|
||||
.then((res) => {
|
||||
onSuccessCallback(res as FileUploadResponse)
|
||||
})
|
||||
.catch((error) => {
|
||||
onErrorCallback(error)
|
||||
@@ -174,9 +185,9 @@ export const getProcessedFilesFromResponse = (files: FileResponse[]) => {
|
||||
const detectedTypeFromMime = getSupportFileType('', fileItem.mime_type)
|
||||
|
||||
if (detectedTypeFromFileName
|
||||
&& detectedTypeFromMime
|
||||
&& detectedTypeFromFileName === detectedTypeFromMime
|
||||
&& detectedTypeFromFileName !== fileItem.type)
|
||||
&& detectedTypeFromMime
|
||||
&& detectedTypeFromFileName === detectedTypeFromMime
|
||||
&& detectedTypeFromFileName !== fileItem.type)
|
||||
supportFileType = detectedTypeFromFileName
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user