mirror of
				https://github.com/langgenius/dify.git
				synced 2025-10-31 02:42:59 +00: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
 | 
