123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143 |
- import type { FC } from 'react'
- import { useState } from 'react'
- import { useTranslation } from 'react-i18next'
- import {
- RiCloseLine,
- RiLoader2Line,
- } from '@remixicon/react'
- import cn from '@/utils/classnames'
- import { RefreshCcw01 } from '@/app/components/base/icons/src/vender/line/arrows'
- import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
- import Tooltip from '@/app/components/base/tooltip'
- 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 && (
- <RiLoader2Line className="animate-spin w-5 h-5 text-white" />
- )}
- {item.progress === -1 && (
- <Tooltip
- popupContent={t('common.imageUploader.pasteImageLinkInvalid')}
- >
- <AlertTriangle className="w-4 h-4 text-[#DC6803]" />
- </Tooltip>
- )}
- </div>
- )}
- <img
- className="w-16 h-16 rounded-lg object-cover cursor-pointer border-[0.5px] border-black/5"
- 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,
- )
- }
- />
- {!readonly && (
- <button
- type="button"
- className={cn(
- '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/2 rounded-2xl shadow-lg',
- item.progress === -1 ? 'flex' : 'hidden group-hover:flex',
- )}
- onClick={() => onRemove && onRemove(item._id)}
- >
- <RiCloseLine className="w-3 h-3 text-gray-500" />
- </button>
- )}
- </div>
- ))}
- {imagePreviewUrl && (
- <ImagePreview
- url={imagePreviewUrl}
- onCancel={() => setImagePreviewUrl('')}
- title=''
- />
- )}
- </div>
- )
- }
- export default ImageList
|