| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | import type { FC } from 'react' | 
					
						
							|  |  |  | import { useState } from 'react' | 
					
						
							|  |  |  | import { useTranslation } from 'react-i18next' | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  | import { | 
					
						
							| 
									
										
										
										
											2024-06-20 11:05:08 +08:00
										 |  |  |   RiCloseLine, | 
					
						
							|  |  |  |   RiLoader2Line, | 
					
						
							|  |  |  | } from '@remixicon/react' | 
					
						
							| 
									
										
										
										
											2024-07-09 15:05:40 +08:00
										 |  |  | import cn from '@/utils/classnames' | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows' | 
					
						
							|  |  |  | import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback' | 
					
						
							| 
									
										
										
										
											2024-08-26 13:00:02 +08:00
										 |  |  | import Tooltip from '@/app/components/base/tooltip' | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  | 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) => { | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |     if ( | 
					
						
							|  |  |  |       item.type === TransferMethod.remote_url | 
					
						
							|  |  |  |       && onImageLinkLoadSuccess | 
					
						
							|  |  |  |       && item.progress !== -1 | 
					
						
							|  |  |  |     ) | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |       onImageLinkLoadSuccess(item._id) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  |   const handleImageLinkLoadError = (item: ImageFile) => { | 
					
						
							|  |  |  |     if (item.type === TransferMethod.remote_url && onImageLinkLoadError) | 
					
						
							|  |  |  |       onImageLinkLoadError(item._id) | 
					
						
							|  |  |  |   } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   return ( | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |     <div className="flex flex-wrap"> | 
					
						
							|  |  |  |       {list.map(item => ( | 
					
						
							|  |  |  |         <div | 
					
						
							|  |  |  |           key={item._id} | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |           className="group relative mr-1 rounded-lg border-[0.5px] border-black/5" | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |         > | 
					
						
							|  |  |  |           {item.type === TransferMethod.local_file && item.progress !== 100 && ( | 
					
						
							|  |  |  |             <> | 
					
						
							|  |  |  |               <div | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 className="absolute inset-0 z-[1] flex items-center justify-center bg-black/30" | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                 style={{ left: item.progress > -1 ? `${item.progress}%` : 0 }} | 
					
						
							|  |  |  |               > | 
					
						
							|  |  |  |                 {item.progress === -1 && ( | 
					
						
							|  |  |  |                   <RefreshCcw01 | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                     className="h-5 w-5 text-white" | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                     onClick={() => onReUpload && onReUpload(item._id)} | 
					
						
							|  |  |  |                   /> | 
					
						
							|  |  |  |                 )} | 
					
						
							|  |  |  |               </div> | 
					
						
							|  |  |  |               {item.progress > -1 && ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <span className="absolute left-[50%] top-[50%] z-[1] translate-x-[-50%] translate-y-[-50%] text-sm text-white mix-blend-lighten"> | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                   {item.progress}% | 
					
						
							|  |  |  |                 </span> | 
					
						
							|  |  |  |               )} | 
					
						
							|  |  |  |             </> | 
					
						
							|  |  |  |           )} | 
					
						
							|  |  |  |           {item.type === TransferMethod.remote_url && item.progress !== 100 && ( | 
					
						
							|  |  |  |             <div | 
					
						
							|  |  |  |               className={`
 | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   absolute inset-0 z-[1] flex items-center justify-center rounded-lg border | 
					
						
							| 
									
										
										
										
											2024-06-05 00:13:29 +08:00
										 |  |  |                   ${item.progress === -1 | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               ? 'border-[#DC6803] bg-[#FEF0C7]' | 
					
						
							|  |  |  |               : 'border-transparent bg-black/[0.16]' | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |             } | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                 `}
 | 
					
						
							|  |  |  |             > | 
					
						
							|  |  |  |               {item.progress > -1 && ( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 <RiLoader2Line className="h-5 w-5 animate-spin text-white" /> | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |               )} | 
					
						
							|  |  |  |               {item.progress === -1 && ( | 
					
						
							| 
									
										
										
										
											2024-08-26 13:00:02 +08:00
										 |  |  |                 <Tooltip | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                   popupContent={t('common.imageUploader.pasteImageLinkInvalid')} | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |                 > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                   <AlertTriangle className="h-4 w-4 text-[#DC6803]" /> | 
					
						
							| 
									
										
										
										
											2024-08-26 13:00:02 +08:00
										 |  |  |                 </Tooltip> | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |               )} | 
					
						
							|  |  |  |             </div> | 
					
						
							|  |  |  |           )} | 
					
						
							|  |  |  |           <img | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |             className="h-16 w-16 cursor-pointer rounded-lg border-[0.5px] border-black/5 object-cover" | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |             alt={item.file?.name} | 
					
						
							|  |  |  |             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, | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |               ) | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |           /> | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |           {!readonly && ( | 
					
						
							|  |  |  |             <button | 
					
						
							|  |  |  |               type="button" | 
					
						
							|  |  |  |               className={cn( | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |                 'absolute -right-[9px] -top-[9px] z-10 h-[18px] w-[18px] items-center justify-center', | 
					
						
							|  |  |  |                 'rounded-2xl shadow-lg hover:bg-state-base-hover', | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |                 item.progress === -1 ? 'flex' : 'hidden group-hover:flex', | 
					
						
							|  |  |  |               )} | 
					
						
							|  |  |  |               onClick={() => onRemove && onRemove(item._id)} | 
					
						
							|  |  |  |             > | 
					
						
							| 
									
										
										
										
											2025-03-21 17:41:03 +08:00
										 |  |  |               <RiCloseLine className="h-3 w-3 text-text-tertiary" /> | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |             </button> | 
					
						
							|  |  |  |           )} | 
					
						
							|  |  |  |         </div> | 
					
						
							|  |  |  |       ))} | 
					
						
							|  |  |  |       {imagePreviewUrl && ( | 
					
						
							|  |  |  |         <ImagePreview | 
					
						
							|  |  |  |           url={imagePreviewUrl} | 
					
						
							|  |  |  |           onCancel={() => setImagePreviewUrl('')} | 
					
						
							| 
									
										
										
										
											2024-11-01 15:45:27 +08:00
										 |  |  |           title='' | 
					
						
							| 
									
										
										
										
											2024-03-10 13:11:41 +08:00
										 |  |  |         /> | 
					
						
							|  |  |  |       )} | 
					
						
							| 
									
										
										
										
											2023-11-13 22:32:39 +08:00
										 |  |  |     </div> | 
					
						
							|  |  |  |   ) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | export default ImageList |