From 32b6c7063a45eb26ade6b006a704f00704f7a36b Mon Sep 17 00:00:00 2001 From: StyleZhang Date: Tue, 10 Sep 2024 14:17:29 +0800 Subject: [PATCH] file uploader --- .../chat/chat/chat-input-area/operation.tsx | 2 +- .../file-from-link-or-local/index.tsx | 14 +++++++- .../file-list-flex-operation.tsx | 35 ++++++++++++------- .../components/base/file-uploader/hooks.ts | 33 +++++++++-------- .../components/base/file-uploader/store.tsx | 6 ++-- .../components/base/file-uploader/types.ts | 6 +++- .../components/base/file-uploader/utils.ts | 6 ++++ 7 files changed, 69 insertions(+), 33 deletions(-) diff --git a/web/app/components/base/chat/chat/chat-input-area/operation.tsx b/web/app/components/base/chat/chat/chat-input-area/operation.tsx index d1524f29ce..c31ef19abe 100644 --- a/web/app/components/base/chat/chat/chat-input-area/operation.tsx +++ b/web/app/components/base/chat/chat/chat-input-area/operation.tsx @@ -38,7 +38,7 @@ const Operation = forwardRef(({ ref={ref} >
- {visionConfig?.enabled && } + { speechToTextConfig?.enabled && ( ) => { + const file = e.target.files?.[0] + + if (!file) + return + + handleLocalFileUpload(file) + } return ( ((e.target as HTMLInputElement).value = '')} type='file' - onChange={() => {}} + onChange={handleChange} /> ) diff --git a/web/app/components/base/file-uploader/file-list-flex/file-list-flex-operation.tsx b/web/app/components/base/file-uploader/file-list-flex/file-list-flex-operation.tsx index 9412a96ac8..583a4ff556 100644 --- a/web/app/components/base/file-uploader/file-list-flex/file-list-flex-operation.tsx +++ b/web/app/components/base/file-uploader/file-list-flex/file-list-flex-operation.tsx @@ -4,12 +4,14 @@ import { } from 'react' import { RiCloseLine } from '@remixicon/react' import { useStore } from '../store' +import { useFile } from '../hooks' import FileListItem from './file-list-flex-item' import Button from '@/app/components/base/button' import ProgressCircle from '@/app/components/base/progress-bar/progress-circle' const FileListFlexOperation = forwardRef((_, ref) => { const files = useStore(s => s.files) + const { handleRemoveFile } = useFile() return (
((_, ref) => { key={file._id} className='relative' > - -
- -
+ { + file._progress !== 100 && ( +
+ +
+ ) + }
)) diff --git a/web/app/components/base/file-uploader/hooks.ts b/web/app/components/base/file-uploader/hooks.ts index 2c02b53640..fdae208e4e 100644 --- a/web/app/components/base/file-uploader/hooks.ts +++ b/web/app/components/base/file-uploader/hooks.ts @@ -6,7 +6,7 @@ import { import produce from 'immer' import { v4 as uuid4 } from 'uuid' import { useTranslation } from 'react-i18next' -import type { TFile } from './types' +import type { FileEntity } from './types' import { useFileStore } from './store' import { fileUpload } from './utils' import { useToastContext } from '@/app/components/base/toast' @@ -15,15 +15,12 @@ type UseFileParams = { isPublicAPI?: boolean url?: string } -export const useFile = ({ - isPublicAPI, - url, -}: UseFileParams) => { +export const useFile = () => { const { t } = useTranslation() const { notify } = useToastContext() const fileStore = useFileStore() - const handleAddOrUpdateFiles = useCallback((newFile: TFile) => { + const handleAddOrUpdateFiles = useCallback((newFile: FileEntity) => { const { files, setFiles, @@ -71,29 +68,37 @@ export const useFile = ({ setFiles([]) }, [fileStore]) - const handleLocalFileUpload = useCallback((file: File) => { + const handleLocalFileUpload = useCallback(( + file: File, + { + isPublicAPI, + url, + }: UseFileParams = { isPublicAPI: false }, + ) => { const reader = new FileReader() + const isImage = file.type.startsWith('image') reader.addEventListener( 'load', () => { - const imageFile = { + const uploadingFile = { _id: uuid4(), file, _url: reader.result as string, _progress: 0, + _base64Url: isImage ? reader.result as string : '', } - handleAddOrUpdateFiles(imageFile) + handleAddOrUpdateFiles(uploadingFile) fileUpload({ - file: imageFile.file, + file: uploadingFile.file, onProgressCallback: (progress) => { - handleAddOrUpdateFiles({ ...imageFile, _progress: progress }) + handleAddOrUpdateFiles({ ...uploadingFile, _progress: progress }) }, onSuccessCallback: (res) => { - handleAddOrUpdateFiles({ ...imageFile, _fileId: res.id, _progress: 100 }) + handleAddOrUpdateFiles({ ...uploadingFile, _fileId: res.id, _progress: 100 }) }, onErrorCallback: () => { notify({ type: 'error', message: t('common.imageUploader.uploadFromComputerUploadError') }) - handleAddOrUpdateFiles({ ...imageFile, _progress: -1 }) + handleAddOrUpdateFiles({ ...uploadingFile, _progress: -1 }) }, }, isPublicAPI, url) }, @@ -107,7 +112,7 @@ export const useFile = ({ false, ) reader.readAsDataURL(file) - }, [notify, t, handleAddOrUpdateFiles, isPublicAPI, url]) + }, [notify, t, handleAddOrUpdateFiles]) const handleClipboardPasteFile = useCallback((e: ClipboardEvent) => { const file = e.clipboardData?.files[0] diff --git a/web/app/components/base/file-uploader/store.tsx b/web/app/components/base/file-uploader/store.tsx index ba0b63bc27..1d58de145e 100644 --- a/web/app/components/base/file-uploader/store.tsx +++ b/web/app/components/base/file-uploader/store.tsx @@ -7,11 +7,11 @@ import { useStore as useZustandStore, } from 'zustand' import { createStore } from 'zustand/vanilla' -import type { TFile } from './types' +import type { FileEntity } from './types' type Shape = { - files: TFile[] - setFiles: (files: TFile[]) => void + files: FileEntity[] + setFiles: (files: FileEntity[]) => void } export const createFileStore = () => { diff --git a/web/app/components/base/file-uploader/types.ts b/web/app/components/base/file-uploader/types.ts index 3298d7e7a4..a28152a4f8 100644 --- a/web/app/components/base/file-uploader/types.ts +++ b/web/app/components/base/file-uploader/types.ts @@ -1,3 +1,5 @@ +import type { TransferMethod } from '@/types/app' + export enum FileTypeEnum { IMAGE = 'IMAGE', VIDEO = 'VIDEO', @@ -13,10 +15,12 @@ export enum FileTypeEnum { OTHER = 'OTHER', } -export type TFile = { +export type FileEntity = { file: File _id: string _fileId?: string _progress?: number _url?: string + _base64Url?: string + _method?: TransferMethod } diff --git a/web/app/components/base/file-uploader/utils.ts b/web/app/components/base/file-uploader/utils.ts index 41715bdc74..66e6668f76 100644 --- a/web/app/components/base/file-uploader/utils.ts +++ b/web/app/components/base/file-uploader/utils.ts @@ -34,3 +34,9 @@ export const fileUpload: FileUpload = ({ onErrorCallback() }) } + +export const isFileType = (type: string) => { + return (file: File) => { + return file.type === type + } +}