mirror of
https://git.mirrors.martin98.com/https://github.com/langgenius/dify.git
synced 2025-08-19 06:45:57 +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 Operation from './operation'
|
||||
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 { useToastContext } from '@/app/components/base/toast'
|
||||
|
||||
@ -92,58 +93,60 @@ const ChatInputArea = ({
|
||||
)
|
||||
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'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'>
|
||||
{/* <FileListFlexOperation /> */}
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className='flex items-center justify-between'
|
||||
>
|
||||
<div className='flex items-center relative grow w-full'>
|
||||
<div
|
||||
ref={textValueRef}
|
||||
className='absolute w-auto h-auto p-1 leading-6 body-lg-regular pointer-events-none whitespace-pre invisible'
|
||||
>
|
||||
{query}
|
||||
<FileContextProvider>
|
||||
<div
|
||||
className={cn(
|
||||
'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'>
|
||||
<FileListFlexOperation />
|
||||
<div
|
||||
ref={wrapperRef}
|
||||
className='flex items-center justify-between'
|
||||
>
|
||||
<div className='flex items-center relative grow w-full'>
|
||||
<div
|
||||
ref={textValueRef}
|
||||
className='absolute w-auto h-auto p-1 leading-6 body-lg-regular pointer-events-none whitespace-pre invisible'
|
||||
>
|
||||
{query}
|
||||
</div>
|
||||
<Textarea
|
||||
ref={textareaRef}
|
||||
className='p-1 w-full leading-6 body-lg-regular text-text-tertiary outline-none'
|
||||
placeholder='Enter message...'
|
||||
autoSize={{ minRows: 1 }}
|
||||
onResize={handleTextareaResize}
|
||||
value={query}
|
||||
onChange={(e) => {
|
||||
setQuery(e.target.value)
|
||||
handleTextareaResize()
|
||||
}}
|
||||
onKeyUp={handleKeyUp}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
</div>
|
||||
<Textarea
|
||||
ref={textareaRef}
|
||||
className='p-1 w-full leading-6 body-lg-regular text-text-tertiary outline-none'
|
||||
placeholder='Enter message...'
|
||||
autoSize={{ minRows: 1 }}
|
||||
onResize={handleTextareaResize}
|
||||
value={query}
|
||||
onChange={(e) => {
|
||||
setQuery(e.target.value)
|
||||
handleTextareaResize()
|
||||
}}
|
||||
onKeyUp={handleKeyUp}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
{
|
||||
!isMultipleLine && operation
|
||||
}
|
||||
</div>
|
||||
{
|
||||
!isMultipleLine && operation
|
||||
showVoiceInput && (
|
||||
<VoiceInput
|
||||
onCancel={() => setShowVoiceInput(false)}
|
||||
onConverted={text => setQuery(text)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
showVoiceInput && (
|
||||
<VoiceInput
|
||||
onCancel={() => setShowVoiceInput(false)}
|
||||
onConverted={text => setQuery(text)}
|
||||
/>
|
||||
isMultipleLine && (
|
||||
<div className='px-[9px]'>{operation}</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
{
|
||||
isMultipleLine && (
|
||||
<div className='px-[9px]'>{operation}</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</FileContextProvider>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,7 @@ type FileListItemProps = {
|
||||
isFile?: boolean
|
||||
className?: string
|
||||
}
|
||||
const FileListItem = ({
|
||||
const FileListFlexItem = ({
|
||||
isFile,
|
||||
className,
|
||||
}: FileListItemProps) => {
|
||||
@ -48,4 +48,4 @@ const FileListItem = ({
|
||||
)
|
||||
}
|
||||
|
||||
export default memo(FileListItem)
|
||||
export default memo(FileListFlexItem)
|
@ -3,33 +3,31 @@ import {
|
||||
memo,
|
||||
} from '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'
|
||||
|
||||
const FileListFlexOperation = forwardRef<HTMLDivElement>((_, ref) => {
|
||||
const files = useStore(s => s.files)
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className='flex flex-wrap gap-2'
|
||||
>
|
||||
<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 />
|
||||
</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>
|
||||
{
|
||||
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'>
|
||||
<RiCloseLine className='w-4 h-4 text-components-button-secondary-text' />
|
||||
</Button>
|
||||
<FileListItem />
|
||||
</div>
|
||||
))
|
||||
}
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
@ -2,7 +2,7 @@ import {
|
||||
forwardRef,
|
||||
memo,
|
||||
} from 'react'
|
||||
import FileListItem from './file-list-item'
|
||||
import FileListFlexItem from './file-list-flex-item'
|
||||
|
||||
const FileListFlexPreview = forwardRef<HTMLDivElement>((_, ref) => {
|
||||
return (
|
||||
@ -10,10 +10,10 @@ const FileListFlexPreview = forwardRef<HTMLDivElement>((_, ref) => {
|
||||
ref={ref}
|
||||
className='flex flex-wrap gap-2'
|
||||
>
|
||||
<FileListItem />
|
||||
<FileListItem />
|
||||
<FileListItem isFile />
|
||||
<FileListItem isFile />
|
||||
<FileListFlexItem />
|
||||
<FileListFlexItem />
|
||||
<FileListFlexItem isFile />
|
||||
<FileListFlexItem isFile />
|
||||
</div>
|
||||
)
|
||||
})
|
||||
|
@ -1,5 +1,4 @@
|
||||
import {
|
||||
memo,
|
||||
useCallback,
|
||||
} from 'react'
|
||||
import {
|
||||
@ -8,6 +7,10 @@ import {
|
||||
} from '@remixicon/react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import FileFromLinkOrLocal from '../file-from-link-or-local'
|
||||
import {
|
||||
FileContextProvider,
|
||||
useStore,
|
||||
} from '../store'
|
||||
import FileInAttachmentItem from './file-in-attachment-item'
|
||||
import Button from '@/app/components/base/button'
|
||||
import cn from '@/utils/classnames'
|
||||
@ -19,6 +22,7 @@ type Option = {
|
||||
}
|
||||
const FileUploaderInAttachment = () => {
|
||||
const { t } = useTranslation()
|
||||
const files = useStore(s => s.files)
|
||||
const options = [
|
||||
{
|
||||
value: 'local',
|
||||
@ -68,11 +72,24 @@ const FileUploaderInAttachment = () => {
|
||||
{options.map(renderOption)}
|
||||
</div>
|
||||
<div className='mt-1 space-y-1'>
|
||||
<FileInAttachmentItem />
|
||||
<FileInAttachmentItem />
|
||||
{
|
||||
files.map(file => (
|
||||
<FileInAttachmentItem
|
||||
key={file._id}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</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 FileTypeIcon } from './file-type-icon'
|
||||
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 TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
|
||||
import type { VisionFile, VisionSettings } from '@/types/app'
|
||||
import ChatInputArea from '@/app/components/base/chat/chat/chat-input-area'
|
||||
import { FileUploaderInAttachment } from '@/app/components/base/file-uploader'
|
||||
import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader'
|
||||
|
||||
export type IRunOnceProps = {
|
||||
siteInfo: SiteInfo
|
||||
@ -115,8 +114,7 @@ const RunOnce: FC<IRunOnceProps> = ({
|
||||
</div>
|
||||
)
|
||||
}
|
||||
<ChatInputArea />
|
||||
<FileUploaderInAttachment />
|
||||
<FileUploaderInAttachmentWrapper />
|
||||
{promptConfig.prompt_variables.length > 0 && (
|
||||
<div className='mt-4 h-[1px] bg-gray-100'></div>
|
||||
)}
|
||||
|
Loading…
x
Reference in New Issue
Block a user