Spaces:
Build error
Build error
import type { FC } from 'react' | |
import { | |
Fragment, | |
useEffect, | |
useState, | |
} from 'react' | |
import { useTranslation } from 'react-i18next' | |
import Uploader from './uploader' | |
import ImageLinkInput from './image-link-input' | |
import ImageList from './image-list' | |
import { useImageFiles } from './hooks' | |
import { ImagePlus } from '@/app/components/base/icons/src/vender/line/images' | |
import { Link03 } from '@/app/components/base/icons/src/vender/line/general' | |
import { | |
PortalToFollowElem, | |
PortalToFollowElemContent, | |
PortalToFollowElemTrigger, | |
} from '@/app/components/base/portal-to-follow-elem' | |
import type { ImageFile, VisionSettings } from '@/types/app' | |
import { TransferMethod } from '@/types/app' | |
type PasteImageLinkButtonProps = { | |
onUpload: (imageFile: ImageFile) => void | |
disabled?: boolean | |
} | |
const PasteImageLinkButton: FC<PasteImageLinkButtonProps> = ({ | |
onUpload, | |
disabled, | |
}) => { | |
const { t } = useTranslation() | |
const [open, setOpen] = useState(false) | |
const handleUpload = (imageFile: ImageFile) => { | |
setOpen(false) | |
onUpload(imageFile) | |
} | |
const handleToggle = () => { | |
if (disabled) | |
return | |
setOpen(v => !v) | |
} | |
return ( | |
<PortalToFollowElem | |
open={open} | |
onOpenChange={setOpen} | |
placement='top-start' | |
> | |
<PortalToFollowElemTrigger onClick={handleToggle}> | |
<div className={` | |
relative flex items-center justify-center px-3 h-8 bg-gray-100 hover:bg-gray-200 text-xs text-gray-500 rounded-lg | |
${disabled ? 'cursor-not-allowed' : 'cursor-pointer'} | |
`}> | |
<Link03 className='mr-2 w-4 h-4' /> | |
{t('common.imageUploader.pasteImageLink')} | |
</div> | |
</PortalToFollowElemTrigger> | |
<PortalToFollowElemContent className='z-10'> | |
<div className='p-2 w-[320px] bg-white border-[0.5px] border-gray-200 rounded-lg shadow-lg'> | |
<ImageLinkInput onUpload={handleUpload} /> | |
</div> | |
</PortalToFollowElemContent> | |
</PortalToFollowElem> | |
) | |
} | |
type TextGenerationImageUploaderProps = { | |
settings: VisionSettings | |
onFilesChange: (files: ImageFile[]) => void | |
} | |
const TextGenerationImageUploader: FC<TextGenerationImageUploaderProps> = ({ | |
settings, | |
onFilesChange, | |
}) => { | |
const { t } = useTranslation() | |
const { | |
files, | |
onUpload, | |
onRemove, | |
onImageLinkLoadError, | |
onImageLinkLoadSuccess, | |
onReUpload, | |
} = useImageFiles() | |
useEffect(() => { | |
onFilesChange(files) | |
}, [files]) | |
const localUpload = ( | |
<Uploader | |
onUpload={onUpload} | |
disabled={files.length >= settings.number_limits} | |
limit={+settings.image_file_size_limit!} | |
> | |
{ | |
hovering => ( | |
<div className={` | |
flex items-center justify-center px-3 h-8 bg-gray-100 | |
text-xs text-gray-500 rounded-lg cursor-pointer | |
${hovering && 'bg-gray-200'} | |
`}> | |
<ImagePlus className='mr-2 w-4 h-4' /> | |
{t('common.imageUploader.uploadFromComputer')} | |
</div> | |
) | |
} | |
</Uploader> | |
) | |
const urlUpload = ( | |
<PasteImageLinkButton | |
onUpload={onUpload} | |
disabled={files.length >= settings.number_limits} | |
/> | |
) | |
return ( | |
<div> | |
<div className='mb-1'> | |
<ImageList | |
list={files} | |
onRemove={onRemove} | |
onReUpload={onReUpload} | |
onImageLinkLoadError={onImageLinkLoadError} | |
onImageLinkLoadSuccess={onImageLinkLoadSuccess} | |
/> | |
</div> | |
<div className={`grid gap-1 ${settings.transfer_methods.length === 2 ? 'grid-cols-2' : 'grid-cols-1'}`}> | |
{ | |
settings.transfer_methods.map((method) => { | |
if (method === TransferMethod.local_file) | |
return <Fragment key={TransferMethod.local_file}>{localUpload}</Fragment> | |
if (method === TransferMethod.remote_url) | |
return <Fragment key={TransferMethod.remote_url}>{urlUpload}</Fragment> | |
return null | |
}) | |
} | |
</div> | |
</div> | |
) | |
} | |
export default TextGenerationImageUploader | |