mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-05-14 11:28:17 +08:00
130 lines
4.9 KiB
TypeScript
130 lines
4.9 KiB
TypeScript
import type { FC } from 'react'
|
|
import { useState } from 'react'
|
|
import { useTranslation } from 'react-i18next'
|
|
import { Loading02, XClose } from '@/app/components/base/icons/src/vender/line/general'
|
|
import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
|
|
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
|
|
import TooltipPlus from '@/app/components/base/tooltip-plus'
|
|
import type { ImageFile } from '@/types/app'
|
|
import { TransferMethod } from '@/types/app'
|
|
import ImagePreview from '@/app/components/base/image-uploader/image-preview'
|
|
|
|
type ImageListProps = {
|
|
list: ImageFile[]
|
|
readonly?: boolean
|
|
onRemove?: (imageFileId: string) => void
|
|
onReUpload?: (imageFileId: string) => void
|
|
onImageLinkLoadSuccess?: (imageFileId: string) => void
|
|
onImageLinkLoadError?: (imageFileId: string) => void
|
|
}
|
|
|
|
const ImageList: FC<ImageListProps> = ({
|
|
list,
|
|
readonly,
|
|
onRemove,
|
|
onReUpload,
|
|
onImageLinkLoadSuccess,
|
|
onImageLinkLoadError,
|
|
}) => {
|
|
const { t } = useTranslation()
|
|
const [imagePreviewUrl, setImagePreviewUrl] = useState('')
|
|
|
|
const handleImageLinkLoadSuccess = (item: ImageFile) => {
|
|
if (item.type === TransferMethod.remote_url && onImageLinkLoadSuccess && item.progress !== -1)
|
|
onImageLinkLoadSuccess(item._id)
|
|
}
|
|
const handleImageLinkLoadError = (item: ImageFile) => {
|
|
if (item.type === TransferMethod.remote_url && onImageLinkLoadError)
|
|
onImageLinkLoadError(item._id)
|
|
}
|
|
|
|
return (
|
|
<div className='flex flex-wrap'>
|
|
{
|
|
list.map(item => (
|
|
<div
|
|
key={item._id}
|
|
className='group relative mr-1 border-[0.5px] border-black/5 rounded-lg'
|
|
>
|
|
{
|
|
item.type === TransferMethod.local_file && item.progress !== 100 && (
|
|
<>
|
|
<div
|
|
className='absolute inset-0 flex items-center justify-center z-[1] bg-black/30'
|
|
style={{ left: item.progress > -1 ? `${item.progress}%` : 0 }}
|
|
>
|
|
{
|
|
item.progress === -1 && (
|
|
<RefreshCcw01 className='w-5 h-5 text-white' onClick={() => onReUpload && onReUpload(item._id)} />
|
|
)
|
|
}
|
|
</div>
|
|
{
|
|
item.progress > -1 && (
|
|
<span className='absolute top-[50%] left-[50%] translate-x-[-50%] translate-y-[-50%] text-sm text-white mix-blend-lighten z-[1]'>{item.progress}%</span>
|
|
)
|
|
}
|
|
</>
|
|
)
|
|
}
|
|
{
|
|
item.type === TransferMethod.remote_url && item.progress !== 100 && (
|
|
<div className={`
|
|
absolute inset-0 flex items-center justify-center rounded-lg z-[1] border
|
|
${item.progress === -1 ? 'bg-[#FEF0C7] border-[#DC6803]' : 'bg-black/[0.16] border-transparent'}
|
|
`}>
|
|
{
|
|
item.progress > -1 && (
|
|
<Loading02 className='animate-spin w-5 h-5 text-white' />
|
|
)
|
|
}
|
|
{
|
|
item.progress === -1 && (
|
|
<TooltipPlus popupContent={t('common.imageUploader.pasteImageLinkInvalid')}>
|
|
<AlertTriangle className='w-4 h-4 text-[#DC6803]' />
|
|
</TooltipPlus>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
<img
|
|
className='w-16 h-16 rounded-lg object-cover cursor-pointer border-[0.5px] border-black/5'
|
|
alt=''
|
|
onLoad={() => handleImageLinkLoadSuccess(item)}
|
|
onError={() => handleImageLinkLoadError(item)}
|
|
src={item.type === TransferMethod.remote_url ? item.url : item.base64Url}
|
|
onClick={() => item.progress === 100 && setImagePreviewUrl((item.type === TransferMethod.remote_url ? item.url : item.base64Url) as string)}
|
|
/>
|
|
{
|
|
!readonly && (
|
|
<div
|
|
className={`
|
|
absolute z-10 -top-[9px] -right-[9px] items-center justify-center w-[18px] h-[18px]
|
|
bg-white hover:bg-gray-50 border-[0.5px] border-black/[0.02] rounded-2xl shadow-lg
|
|
cursor-pointer
|
|
${item.progress === -1 ? 'flex' : 'hidden group-hover:flex'}
|
|
`}
|
|
onClick={() => onRemove && onRemove(item._id)}
|
|
>
|
|
<XClose className='w-3 h-3 text-gray-500' />
|
|
</div>
|
|
)
|
|
}
|
|
</div>
|
|
))
|
|
}
|
|
{
|
|
imagePreviewUrl && (
|
|
<ImagePreview
|
|
url={imagePreviewUrl}
|
|
onCancel={() => setImagePreviewUrl('')}
|
|
/>
|
|
)
|
|
}
|
|
</div>
|
|
)
|
|
}
|
|
|
|
export default ImageList
|