file uploader

This commit is contained in:
StyleZhang 2024-08-13 15:24:09 +08:00
parent 57f178902f
commit d7c8bced9b
7 changed files with 95 additions and 79 deletions

View File

@ -16,7 +16,8 @@ import type { Theme } from '../../embedded-chatbot/theme/theme-context'
import { useTextAreaHeight } from './hooks' import { useTextAreaHeight } from './hooks'
import Operation from './operation' import Operation from './operation'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
// import { FileListFlexOperation } from '@/app/components/base/file-uploader' import { FileListFlexOperation } from '@/app/components/base/file-uploader'
import { FileContextProvider } from '@/app/components/base/file-uploader/store'
import VoiceInput from '@/app/components/base/voice-input' import VoiceInput from '@/app/components/base/voice-input'
import { useToastContext } from '@/app/components/base/toast' import { useToastContext } from '@/app/components/base/toast'
@ -92,13 +93,14 @@ const ChatInputArea = ({
) )
return ( return (
<FileContextProvider>
<div <div
className={cn( className={cn(
'py-[9px] bg-components-panel-bg-blur border border-components-chat-input-border rounded-xl shadow-md', 'py-[9px] bg-components-panel-bg-blur border border-components-chat-input-border rounded-xl shadow-md',
)} )}
> >
<div className='relative px-[9px] max-h-[158px] overflow-x-hidden overflow-y-auto'> <div className='relative px-[9px] max-h-[158px] overflow-x-hidden overflow-y-auto'>
{/* <FileListFlexOperation /> */} <FileListFlexOperation />
<div <div
ref={wrapperRef} ref={wrapperRef}
className='flex items-center justify-between' className='flex items-center justify-between'
@ -144,6 +146,7 @@ const ChatInputArea = ({
) )
} }
</div> </div>
</FileContextProvider>
) )
} }

View File

@ -8,7 +8,7 @@ type FileListItemProps = {
isFile?: boolean isFile?: boolean
className?: string className?: string
} }
const FileListItem = ({ const FileListFlexItem = ({
isFile, isFile,
className, className,
}: FileListItemProps) => { }: FileListItemProps) => {
@ -48,4 +48,4 @@ const FileListItem = ({
) )
} }
export default memo(FileListItem) export default memo(FileListFlexItem)

View File

@ -3,33 +3,31 @@ import {
memo, memo,
} from 'react' } from 'react'
import { RiCloseLine } from '@remixicon/react' import { RiCloseLine } from '@remixicon/react'
import FileListItem from './file-list-item' import { useStore } from '../store'
import FileListItem from './file-list-flex-item'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
const FileListFlexOperation = forwardRef<HTMLDivElement>((_, ref) => { const FileListFlexOperation = forwardRef<HTMLDivElement>((_, ref) => {
const files = useStore(s => s.files)
return ( return (
<div <div
ref={ref} ref={ref}
className='flex flex-wrap gap-2' className='flex flex-wrap gap-2'
> >
<div className='relative'> {
files.map(file => (
<div
key={file._id}
className='relative'
>
<Button className='absolute -right-1.5 -top-1.5 p-0 w-5 h-5 rounded-full'> <Button className='absolute -right-1.5 -top-1.5 p-0 w-5 h-5 rounded-full'>
<RiCloseLine className='w-4 h-4 text-components-button-secondary-text' /> <RiCloseLine className='w-4 h-4 text-components-button-secondary-text' />
</Button> </Button>
<FileListItem /> <FileListItem />
</div> </div>
<div className='relative'> ))
<Button className='absolute -right-1.5 -top-1.5 p-0 w-5 h-5 rounded-full'> }
<RiCloseLine className='w-4 h-4 text-components-button-secondary-text' />
</Button>
<FileListItem />
</div>
<div className='relative'>
<Button className='absolute -right-1.5 -top-1.5 p-0 w-5 h-5 rounded-full'>
<RiCloseLine className='w-4 h-4 text-components-button-secondary-text' />
</Button>
<FileListItem isFile />
</div>
</div> </div>
) )
}) })

View File

@ -2,7 +2,7 @@ import {
forwardRef, forwardRef,
memo, memo,
} from 'react' } from 'react'
import FileListItem from './file-list-item' import FileListFlexItem from './file-list-flex-item'
const FileListFlexPreview = forwardRef<HTMLDivElement>((_, ref) => { const FileListFlexPreview = forwardRef<HTMLDivElement>((_, ref) => {
return ( return (
@ -10,10 +10,10 @@ const FileListFlexPreview = forwardRef<HTMLDivElement>((_, ref) => {
ref={ref} ref={ref}
className='flex flex-wrap gap-2' className='flex flex-wrap gap-2'
> >
<FileListItem /> <FileListFlexItem />
<FileListItem /> <FileListFlexItem />
<FileListItem isFile /> <FileListFlexItem isFile />
<FileListItem isFile /> <FileListFlexItem isFile />
</div> </div>
) )
}) })

View File

@ -1,5 +1,4 @@
import { import {
memo,
useCallback, useCallback,
} from 'react' } from 'react'
import { import {
@ -8,6 +7,10 @@ import {
} from '@remixicon/react' } from '@remixicon/react'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import FileFromLinkOrLocal from '../file-from-link-or-local' import FileFromLinkOrLocal from '../file-from-link-or-local'
import {
FileContextProvider,
useStore,
} from '../store'
import FileInAttachmentItem from './file-in-attachment-item' import FileInAttachmentItem from './file-in-attachment-item'
import Button from '@/app/components/base/button' import Button from '@/app/components/base/button'
import cn from '@/utils/classnames' import cn from '@/utils/classnames'
@ -19,6 +22,7 @@ type Option = {
} }
const FileUploaderInAttachment = () => { const FileUploaderInAttachment = () => {
const { t } = useTranslation() const { t } = useTranslation()
const files = useStore(s => s.files)
const options = [ const options = [
{ {
value: 'local', value: 'local',
@ -68,11 +72,24 @@ const FileUploaderInAttachment = () => {
{options.map(renderOption)} {options.map(renderOption)}
</div> </div>
<div className='mt-1 space-y-1'> <div className='mt-1 space-y-1'>
<FileInAttachmentItem /> {
<FileInAttachmentItem /> files.map(file => (
<FileInAttachmentItem
key={file._id}
/>
))
}
</div> </div>
</div> </div>
) )
} }
export default memo(FileUploaderInAttachment) const FileUploaderInAttachmentWrapper = () => {
return (
<FileContextProvider>
<FileUploaderInAttachment />
</FileContextProvider>
)
}
export default FileUploaderInAttachmentWrapper

View File

@ -1,4 +1,4 @@
export { default as FileUploaderInAttachment } from './file-uploader-in-attachment' export { default as FileUploaderInAttachmentWrapper } from './file-uploader-in-attachment'
export { default as FileUploaderInChatInput } from './file-uploader-in-chat-input' export { default as FileUploaderInChatInput } from './file-uploader-in-chat-input'
export { default as FileTypeIcon } from './file-type-icon' export { default as FileTypeIcon } from './file-type-icon'
export { default as FileListFlexOperation } from './file-list-flex/file-list-flex-operation' export { default as FileListFlexOperation } from './file-list-flex/file-list-flex-operation'

View File

@ -12,8 +12,7 @@ import Textarea from '@/app/components/base/textarea'
import { DEFAULT_VALUE_MAX_LEN } from '@/config' import { DEFAULT_VALUE_MAX_LEN } from '@/config'
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader' import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
import type { VisionFile, VisionSettings } from '@/types/app' import type { VisionFile, VisionSettings } from '@/types/app'
import ChatInputArea from '@/app/components/base/chat/chat/chat-input-area' import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader'
import { FileUploaderInAttachment } from '@/app/components/base/file-uploader'
export type IRunOnceProps = { export type IRunOnceProps = {
siteInfo: SiteInfo siteInfo: SiteInfo
@ -115,8 +114,7 @@ const RunOnce: FC<IRunOnceProps> = ({
</div> </div>
) )
} }
<ChatInputArea /> <FileUploaderInAttachmentWrapper />
<FileUploaderInAttachment />
{promptConfig.prompt_variables.length > 0 && ( {promptConfig.prompt_variables.length > 0 && (
<div className='mt-4 h-[1px] bg-gray-100'></div> <div className='mt-4 h-[1px] bg-gray-100'></div>
)} )}