zxhlyh 1 éve
szülő
commit
cfbfd59b8f

+ 1 - 1
web/app/components/app/configuration/prompt-value-panel/index.tsx

@@ -161,7 +161,7 @@ const PromptValuePanel: FC<IPromptValuePanelProps> = ({
             {
               appType === AppType.completion && visionConfig?.enabled && (
                 <div className="mt-3 xl:flex justify-between">
-                  <div className="mr-1 py-2 shrink-0 w-[120px] text-sm text-gray-900">Image Upload</div>
+                  <div className="mr-1 py-2 shrink-0 w-[120px] text-sm text-gray-900">{t('common.imageUploader.imageUpload')}</div>
                   <div className='grow'>
                     <TextGenerationImageUploader
                       settings={visionConfig}

+ 34 - 5
web/app/components/base/image-uploader/hooks.ts

@@ -1,4 +1,4 @@
-import { useState } from 'react'
+import { useMemo, useRef, useState } from 'react'
 import { useParams } from 'next/navigation'
 import { useTranslation } from 'react-i18next'
 import { imageUpload } from './utils'
@@ -10,38 +10,59 @@ export const useImageFiles = () => {
   const { t } = useTranslation()
   const { notify } = useToastContext()
   const [files, setFiles] = useState<ImageFile[]>([])
+  const filesRef = useRef<ImageFile[]>([])
 
   const handleUpload = (imageFile: ImageFile) => {
-    const newFiles = [...files, imageFile]
-    setFiles(newFiles)
+    const files = filesRef.current
+    const index = files.findIndex(file => file._id === imageFile._id)
+
+    if (index > -1) {
+      const currentFile = files[index]
+      const newFiles = [...files.slice(0, index), { ...currentFile, ...imageFile }, ...files.slice(index + 1)]
+      setFiles(newFiles)
+      filesRef.current = newFiles
+    }
+    else {
+      const newFiles = [...files, imageFile]
+      setFiles(newFiles)
+      filesRef.current = newFiles
+    }
   }
   const handleRemove = (imageFileId: string) => {
+    const files = filesRef.current
     const index = files.findIndex(file => file._id === imageFileId)
 
     if (index > -1) {
-      const newFiles = [...files.slice(0, index), ...files.slice(index + 1)]
+      const currentFile = files[index]
+      const newFiles = [...files.slice(0, index), { ...currentFile, deleted: true }, ...files.slice(index + 1)]
       setFiles(newFiles)
+      filesRef.current = newFiles
     }
   }
   const handleImageLinkLoadError = (imageFileId: string) => {
+    const files = filesRef.current
     const index = files.findIndex(file => file._id === imageFileId)
 
     if (index > -1) {
       const currentFile = files[index]
       const newFiles = [...files.slice(0, index), { ...currentFile, progress: -1 }, ...files.slice(index + 1)]
+      filesRef.current = newFiles
       setFiles(newFiles)
     }
   }
   const handleImageLinkLoadSuccess = (imageFileId: string) => {
+    const files = filesRef.current
     const index = files.findIndex(file => file._id === imageFileId)
 
     if (index > -1) {
       const currentImageFile = files[index]
       const newFiles = [...files.slice(0, index), { ...currentImageFile, progress: 100 }, ...files.slice(index + 1)]
+      filesRef.current = newFiles
       setFiles(newFiles)
     }
   }
   const handleReUpload = (imageFileId: string) => {
+    const files = filesRef.current
     const index = files.findIndex(file => file._id === imageFileId)
 
     if (index > -1) {
@@ -50,15 +71,18 @@ export const useImageFiles = () => {
         file: currentImageFile.file!,
         onProgressCallback: (progress) => {
           const newFiles = [...files.slice(0, index), { ...currentImageFile, progress }, ...files.slice(index + 1)]
+          filesRef.current = newFiles
           setFiles(newFiles)
         },
         onSuccessCallback: (res) => {
           const newFiles = [...files.slice(0, index), { ...currentImageFile, fileId: res.id, progress: 100 }, ...files.slice(index + 1)]
+          filesRef.current = newFiles
           setFiles(newFiles)
         },
         onErrorCallback: () => {
           notify({ type: 'error', message: t('common.imageUploader.uploadFromComputerUploadError') })
           const newFiles = [...files.slice(0, index), { ...currentImageFile, progress: -1 }, ...files.slice(index + 1)]
+          filesRef.current = newFiles
           setFiles(newFiles)
         },
       }, !!params.token)
@@ -67,10 +91,15 @@ export const useImageFiles = () => {
 
   const handleClear = () => {
     setFiles([])
+    filesRef.current = []
   }
 
+  const filteredFiles = useMemo(() => {
+    return files.filter(file => !file.deleted)
+  }, [files])
+
   return {
-    files,
+    files: filteredFiles,
     onUpload: handleUpload,
     onRemove: handleRemove,
     onImageLinkLoadError: handleImageLinkLoadError,

+ 1 - 0
web/app/components/base/image-uploader/uploader.tsx

@@ -88,6 +88,7 @@ const Uploader: FC<UploaderProps> = ({
           absolute block inset-0 opacity-0 text-[0]
           ${disabled ? 'cursor-not-allowed' : 'cursor-pointer'}
         `}
+        onClick={e => (e.target as HTMLInputElement).value = ''}
         type='file'
         accept='.png, .jpg, .jpeg, .webp, .gif'
         onChange={handleChange}

+ 1 - 1
web/app/components/share/text-generation/run-once/index.tsx

@@ -82,7 +82,7 @@ const RunOnce: FC<IRunOnceProps> = ({
           {
             visionConfig?.enabled && (
               <div className="w-full mt-4">
-                <div className="text-gray-900 text-sm font-medium">Image Upload</div>
+                <div className="text-gray-900 text-sm font-medium">{t('common.imageUploader.imageUpload')}</div>
                 <div className='mt-2'>
                   <TextGenerationImageUploader
                     settings={visionConfig}

+ 1 - 0
web/i18n/lang/common.en.ts

@@ -438,6 +438,7 @@ const translation = {
     pasteImageLink: 'Paste image link',
     pasteImageLinkInputPlaceholder: 'Paste image link here',
     pasteImageLinkInvalid: 'Invalid image link',
+    imageUpload: 'Image Upload',
   },
 }
 

+ 1 - 0
web/i18n/lang/common.zh.ts

@@ -438,6 +438,7 @@ const translation = {
     pasteImageLink: '粘贴图片链接',
     pasteImageLinkInputPlaceholder: '将图像链接粘贴到此处',
     pasteImageLinkInvalid: '图片链接无效',
+    imageUpload: '图片上传',
   },
 }
 

+ 1 - 0
web/types/app.ts

@@ -301,6 +301,7 @@ export type ImageFile = {
   progress: number
   url: string
   base64Url?: string
+  deleted?: boolean
 }
 
 export type VisionFile = {