Chore: frontend infrastructure upgrade (#16420)

Co-authored-by: NFish <douxc512@gmail.com>
Co-authored-by: zxhlyh <jasonapring2015@outlook.com>
Co-authored-by: twwu <twwu@dify.ai>
Co-authored-by: jZonG <jzongcode@gmail.com>
This commit is contained in:
Joel
2025-03-21 17:41:03 +08:00
committed by GitHub
parent e61415223b
commit 7709d9df20
1435 changed files with 13372 additions and 11612 deletions

View File

@@ -13,24 +13,23 @@ const AudioPreview: FC<AudioPreviewProps> = ({
onCancel,
}) => {
return createPortal(
<div className='fixed inset-0 p-8 flex items-center justify-center bg-black/80 z-[1000]' onClick={e => e.stopPropagation()}>
<div className='fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-8' onClick={e => e.stopPropagation()}>
<div>
<audio controls title={title} autoPlay={false} preload="metadata">
<source
type="audio/mpeg"
src={url}
className='max-w-full max-h-full'
className='max-h-full max-w-full'
/>
</audio>
</div>
<div
className='absolute top-6 right-6 flex items-center justify-center w-8 h-8 bg-white/[0.08] rounded-lg backdrop-blur-[2px] cursor-pointer'
className='absolute right-6 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-white/[0.08] backdrop-blur-[2px]'
onClick={onCancel}
>
<RiCloseLine className='w-4 h-4 text-gray-500'/>
<RiCloseLine className='h-4 w-4 text-gray-500'/>
</div>
</div>
,
</div>,
document.body,
)
}

View File

@@ -29,11 +29,11 @@ const UploadOnlyFromLocal: FC<UploadOnlyFromLocalProps> = ({
{hovering => (
<div
className={`
relative flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer
relative flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg
${hovering && 'bg-gray-100'}
`}
>
<ImagePlus className="w-4 h-4 text-gray-500" />
<ImagePlus className="h-4 w-4 text-gray-500" />
</div>
)}
</Uploader>
@@ -82,20 +82,20 @@ const UploaderButton: FC<UploaderButtonProps> = ({
<button
type="button"
disabled={disabled}
className="relative flex items-center justify-center w-8 h-8 enabled:hover:bg-gray-100 rounded-lg disabled:cursor-not-allowed"
className="relative flex h-8 w-8 items-center justify-center rounded-lg enabled:hover:bg-gray-100 disabled:cursor-not-allowed"
>
<ImagePlus className="w-4 h-4 text-gray-500" />
<ImagePlus className="h-4 w-4 text-gray-500" />
</button>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className="z-50">
<div className="p-2 w-[260px] bg-white rounded-lg border-[0.5px] border-gray-200 shadow-lg">
<div className="w-[260px] rounded-lg border-[0.5px] border-gray-200 bg-white p-2 shadow-lg">
<ImageLinkInput onUpload={handleUpload} disabled={disabled} />
{hasUploadFromLocal && (
<>
<div className="flex items-center mt-2 px-2 text-xs font-medium text-gray-400">
<div className="mr-3 w-[93px] h-[1px] bg-gradient-to-l from-[#F3F4F6]" />
<div className="mt-2 flex items-center px-2 text-xs font-medium text-gray-400">
<div className="mr-3 h-[1px] w-[93px] bg-gradient-to-l from-[#F3F4F6]" />
OR
<div className="ml-3 w-[93px] h-[1px] bg-gradient-to-r from-[#F3F4F6]" />
<div className="ml-3 h-[1px] w-[93px] bg-gradient-to-r from-[#F3F4F6]" />
</div>
<Uploader
onUpload={handleUpload}
@@ -105,11 +105,11 @@ const UploaderButton: FC<UploaderButtonProps> = ({
{hovering => (
<div
className={cn(
'flex items-center justify-center h-8 text-[13px] font-medium text-[#155EEF] rounded-lg cursor-pointer',
'flex h-8 cursor-pointer items-center justify-center rounded-lg text-[13px] font-medium text-[#155EEF]',
hovering && 'bg-primary-50',
)}
>
<Upload03 className="mr-1 w-4 h-4" />
<Upload03 className="mr-1 h-4 w-4" />
{t('common.imageUploader.uploadFromComputer')}
</div>
)}

View File

@@ -33,10 +33,10 @@ const ImageLinkInput: FC<ImageLinkInputProps> = ({
}
return (
<div className='flex items-center pl-1.5 pr-1 h-8 border border-components-panel-border bg-components-panel-bg shadow-xs rounded-lg'>
<div className='flex h-8 items-center rounded-lg border border-components-panel-border bg-components-panel-bg pl-1.5 pr-1 shadow-xs'>
<input
type="text"
className='grow mr-0.5 px-1 h-[18px] text-[13px] text-text-primary bg-transparent outline-none appearance-none'
className='mr-0.5 h-[18px] grow appearance-none bg-transparent px-1 text-[13px] text-text-primary outline-none'
value={imageLink}
onChange={e => setImageLink(e.target.value)}
placeholder={t('common.imageUploader.pasteImageLinkInputPlaceholder') || ''}

View File

@@ -51,23 +51,23 @@ const ImageList: FC<ImageListProps> = ({
{list.map(item => (
<div
key={item._id}
className="group relative mr-1 border-[0.5px] border-black/5 rounded-lg"
className="group relative mr-1 rounded-lg border-[0.5px] border-black/5"
>
{item.type === TransferMethod.local_file && item.progress !== 100 && (
<>
<div
className="absolute inset-0 flex items-center justify-center z-[1] bg-black/30"
className="absolute inset-0 z-[1] flex items-center justify-center bg-black/30"
style={{ left: item.progress > -1 ? `${item.progress}%` : 0 }}
>
{item.progress === -1 && (
<RefreshCcw01
className="w-5 h-5 text-white"
className="h-5 w-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]">
<span className="absolute left-[50%] top-[50%] z-[1] translate-x-[-50%] translate-y-[-50%] text-sm text-white mix-blend-lighten">
{item.progress}%
</span>
)}
@@ -76,27 +76,27 @@ const ImageList: FC<ImageListProps> = ({
{item.type === TransferMethod.remote_url && item.progress !== 100 && (
<div
className={`
absolute inset-0 flex items-center justify-center rounded-lg z-[1] border
absolute inset-0 z-[1] flex items-center justify-center rounded-lg border
${item.progress === -1
? 'bg-[#FEF0C7] border-[#DC6803]'
: 'bg-black/[0.16] border-transparent'
? 'border-[#DC6803] bg-[#FEF0C7]'
: 'border-transparent bg-black/[0.16]'
}
`}
>
{item.progress > -1 && (
<RiLoader2Line className="animate-spin w-5 h-5 text-white" />
<RiLoader2Line className="h-5 w-5 animate-spin text-white" />
)}
{item.progress === -1 && (
<Tooltip
popupContent={t('common.imageUploader.pasteImageLinkInvalid')}
>
<AlertTriangle className="w-4 h-4 text-[#DC6803]" />
<AlertTriangle className="h-4 w-4 text-[#DC6803]" />
</Tooltip>
)}
</div>
)}
<img
className="w-16 h-16 rounded-lg object-cover cursor-pointer border-[0.5px] border-black/5"
className="h-16 w-16 cursor-pointer rounded-lg border-[0.5px] border-black/5 object-cover"
alt={item.file?.name}
onLoad={() => handleImageLinkLoadSuccess(item)}
onError={() => handleImageLinkLoadError(item)}
@@ -118,13 +118,13 @@ const ImageList: FC<ImageListProps> = ({
<button
type="button"
className={cn(
'absolute z-10 -top-[9px] -right-[9px] items-center justify-center w-[18px] h-[18px]',
'hover:bg-state-base-hover rounded-2xl shadow-lg',
'absolute -right-[9px] -top-[9px] z-10 h-[18px] w-[18px] items-center justify-center',
'rounded-2xl shadow-lg hover:bg-state-base-hover',
item.progress === -1 ? 'flex' : 'hidden group-hover:flex',
)}
onClick={() => onRemove && onRemove(item._id)}
>
<RiCloseLine className="w-3 h-3 text-text-tertiary" />
<RiCloseLine className="h-3 w-3 text-text-tertiary" />
</button>
)}
</div>

View File

@@ -7,7 +7,7 @@ import { useHotkeys } from 'react-hotkeys-hook'
import Tooltip from '@/app/components/base/tooltip'
import Toast from '@/app/components/base/toast'
interface ImagePreviewProps {
type ImagePreviewProps = {
url: string
title: string
onCancel: () => void
@@ -61,6 +61,7 @@ const ImagePreview: FC<ImagePreviewProps> = ({
if (url.startsWith('http') || url.startsWith('https')) {
const a = document.createElement('a')
a.href = url
a.target = '_blank'
a.download = title
a.click()
}
@@ -68,6 +69,7 @@ const ImagePreview: FC<ImagePreviewProps> = ({
// Base64 image
const a = document.createElement('a')
a.href = url
a.target = '_blank'
a.download = title
a.click()
}
@@ -103,7 +105,7 @@ const ImagePreview: FC<ImagePreviewProps> = ({
for (let i = 0; i < slice.length; i++)
byteNumbers[i] = slice.charCodeAt(i)
const byteArray = new Uint8Array(byteNumbers)
const byteArray = new Uint8Array(byteNumbers as any)
byteArrays.push(byteArray)
}
@@ -196,11 +198,11 @@ const ImagePreview: FC<ImagePreviewProps> = ({
useHotkeys('esc', onCancel)
useHotkeys('up', zoomIn)
useHotkeys('down', zoomOut)
useHotkeys('left', onPrev || (() => {}))
useHotkeys('right', onNext || (() => {}))
useHotkeys('left', onPrev || (() => { }))
useHotkeys('right', onNext || (() => { }))
return createPortal(
<div className='fixed inset-0 p-8 flex items-center justify-center bg-black/80 z-[1000] image-preview-container'
<div className='image-preview-container fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-8'
onClick={e => e.stopPropagation()}
onWheel={handleWheel}
onMouseDown={handleMouseDown}
@@ -208,54 +210,54 @@ const ImagePreview: FC<ImagePreviewProps> = ({
onMouseUp={handleMouseUp}
style={{ cursor: scale > 1 ? 'move' : 'default' }}
tabIndex={-1}>
{/* eslint-disable-next-line @next/next/no-img-element */}
{ }
<img
ref={imgRef}
alt={title}
src={isBase64(url) ? `data:image/png;base64,${url}` : url}
className='max-w-full max-h-full'
className='max-h-full max-w-full'
style={{
transform: `scale(${scale}) translate(${position.x}px, ${position.y}px)`,
transition: isDragging ? 'none' : 'transform 0.2s ease-in-out',
}}
/>
<Tooltip popupContent={t('common.operation.copyImage')}>
<div className='absolute top-6 right-48 flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer'
<div className='absolute right-48 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg'
onClick={imageCopy}>
{isCopied
? <RiFileCopyLine className='w-4 h-4 text-green-500'/>
: <RiFileCopyLine className='w-4 h-4 text-gray-500'/>}
? <RiFileCopyLine className='h-4 w-4 text-green-500' />
: <RiFileCopyLine className='h-4 w-4 text-gray-500' />}
</div>
</Tooltip>
<Tooltip popupContent={t('common.operation.zoomOut')}>
<div className='absolute top-6 right-40 flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer'
<div className='absolute right-40 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg'
onClick={zoomOut}>
<RiZoomOutLine className='w-4 h-4 text-gray-500'/>
<RiZoomOutLine className='h-4 w-4 text-gray-500' />
</div>
</Tooltip>
<Tooltip popupContent={t('common.operation.zoomIn')}>
<div className='absolute top-6 right-32 flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer'
<div className='absolute right-32 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg'
onClick={zoomIn}>
<RiZoomInLine className='w-4 h-4 text-gray-500'/>
<RiZoomInLine className='h-4 w-4 text-gray-500' />
</div>
</Tooltip>
<Tooltip popupContent={t('common.operation.download')}>
<div className='absolute top-6 right-24 flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer'
<div className='absolute right-24 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg'
onClick={downloadImage}>
<RiDownloadCloud2Line className='w-4 h-4 text-gray-500'/>
<RiDownloadCloud2Line className='h-4 w-4 text-gray-500' />
</div>
</Tooltip>
<Tooltip popupContent={t('common.operation.openInNewTab')}>
<div className='absolute top-6 right-16 flex items-center justify-center w-8 h-8 rounded-lg cursor-pointer'
<div className='absolute right-16 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg'
onClick={openInNewTab}>
<RiAddBoxLine className='w-4 h-4 text-gray-500'/>
<RiAddBoxLine className='h-4 w-4 text-gray-500' />
</div>
</Tooltip>
<Tooltip popupContent={t('common.operation.cancel')}>
<div
className='absolute top-6 right-6 flex items-center justify-center w-8 h-8 bg-white/8 rounded-lg backdrop-blur-[2px] cursor-pointer'
className='absolute right-6 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-white/8 backdrop-blur-[2px]'
onClick={onCancel}>
<RiCloseLine className='w-4 h-4 text-gray-500'/>
<RiCloseLine className='h-4 w-4 text-gray-500' />
</div>
</Tooltip>
</div>,

View File

@@ -50,15 +50,15 @@ const PasteImageLinkButton: FC<PasteImageLinkButtonProps> = ({
>
<PortalToFollowElemTrigger onClick={handleToggle}>
<div className={`
relative flex items-center justify-center px-3 h-8 bg-components-button-tertiary-bg hover:bg-components-button-tertiary-bg-hover text-xs text-text-tertiary rounded-lg
relative flex h-8 items-center justify-center rounded-lg bg-components-button-tertiary-bg px-3 text-xs text-text-tertiary hover:bg-components-button-tertiary-bg-hover
${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
`}>
<Link03 className='mr-2 w-4 h-4' />
<Link03 className='mr-2 h-4 w-4' />
{t('common.imageUploader.pasteImageLink')}
</div>
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-10'>
<div className='p-2 w-[320px] bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-lg shadow-lg'>
<div className='w-[320px] rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg p-2 shadow-lg'>
<ImageLinkInput onUpload={handleUpload} />
</div>
</PortalToFollowElemContent>
@@ -98,11 +98,11 @@ const TextGenerationImageUploader: FC<TextGenerationImageUploaderProps> = ({
{
hovering => (
<div className={`
flex items-center justify-center px-3 h-8 bg-components-button-tertiary-bg
text-xs text-text-tertiary rounded-lg cursor-pointer
flex h-8 cursor-pointer items-center justify-center rounded-lg
bg-components-button-tertiary-bg px-3 text-xs text-text-tertiary
${hovering && 'hover:bg-components-button-tertiary-bg-hover'}
`}>
<ImagePlus className='mr-2 w-4 h-4' />
<ImagePlus className='mr-2 h-4 w-4' />
{t('common.imageUploader.uploadFromComputer')}
</div>
)

View File

@@ -5,7 +5,7 @@ import type { ImageFile } from '@/types/app'
import { ALLOW_FILE_EXTENSIONS } from '@/types/app'
type UploaderProps = {
children: (hovering: boolean) => JSX.Element
children: (hovering: boolean) => React.JSX.Element
onUpload: (imageFile: ImageFile) => void
closePopover?: () => void
limit?: number
@@ -44,7 +44,7 @@ const Uploader: FC<UploaderProps> = ({
>
{children(hovering)}
<input
className='absolute block inset-0 opacity-0 text-[0] w-full disabled:cursor-not-allowed cursor-pointer'
className='absolute inset-0 block w-full cursor-pointer text-[0] opacity-0 disabled:cursor-not-allowed'
onClick={e => ((e.target as HTMLInputElement).value = '')}
type='file'
accept={ALLOW_FILE_EXTENSIONS.map(ext => `.${ext}`).join(',')}

View File

@@ -13,24 +13,23 @@ const VideoPreview: FC<VideoPreviewProps> = ({
onCancel,
}) => {
return createPortal(
<div className='fixed inset-0 p-8 flex items-center justify-center bg-black/80 z-[1000]' onClick={e => e.stopPropagation()}>
<div className='fixed inset-0 z-[1000] flex items-center justify-center bg-black/80 p-8' onClick={e => e.stopPropagation()}>
<div>
<video controls title={title} autoPlay={false} preload="metadata">
<source
type="video/mp4"
src={url}
className='max-w-full max-h-full'
className='max-h-full max-w-full'
/>
</video>
</div>
<div
className='absolute top-6 right-6 flex items-center justify-center w-8 h-8 bg-white/[0.08] rounded-lg backdrop-blur-[2px] cursor-pointer'
className='absolute right-6 top-6 flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg bg-white/[0.08] backdrop-blur-[2px]'
onClick={onCancel}
>
<RiCloseLine className='w-4 h-4 text-gray-500'/>
<RiCloseLine className='h-4 w-4 text-gray-500'/>
</div>
</div>
,
</div>,
document.body,
)
}