mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-20 07:59:10 +08:00
file uploader
This commit is contained in:
parent
57f178902f
commit
d7c8bced9b
@ -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>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
@ -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>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -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>
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
@ -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
|
||||||
|
@ -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'
|
||||||
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user