@@ -29,6 +29,7 @@ import { AgentQuickSelect } from '@/components/agent/AgentQuickSelect'
2929import { VoiceStatusOverlay , type VoiceStatusOverlayState } from './VoiceStatusOverlay'
3030import { detectMentionTrigger , parsePromptToParts , getFilename , filterAgentsByQuery } from '@/lib/promptParser'
3131import { randomId } from '@/lib/utils'
32+ import { showToast } from '@/lib/toast'
3233import { formatModelName , getProviders } from '@/api/providers'
3334import { useQuery } from '@tanstack/react-query'
3435
@@ -812,6 +813,14 @@ export const PromptInput = memo(forwardRef<PromptInputHandle, PromptInputProps>(
812813 } )
813814 }
814815
816+ const addFileAttachment = ( file : File ) => {
817+ if ( ACCEPTED_FILE_TYPES . includes ( file . type ) ) {
818+ addImageAttachment ( file )
819+ } else {
820+ showToast . error ( `Only images and PDFs can be attached (${ file . name } )` )
821+ }
822+ }
823+
815824 const handlePaste = async ( event : React . ClipboardEvent < HTMLTextAreaElement > ) => {
816825 const clipboardData = event . clipboardData
817826 if ( ! clipboardData ) return
@@ -839,7 +848,7 @@ if (isIOS && isSecureContext && navigator.clipboard && navigator.clipboard.read)
839848 try {
840849 const blob = await item . getType ( type )
841850 const file = new File ( [ blob ] , `pasted-${ Date . now ( ) } .${ type . split ( '/' ) [ 1 ] } ` , { type } )
842- addImageAttachment ( file )
851+ addFileAttachment ( file )
843852 } catch ( err ) {
844853 console . error ( 'Failed to read clipboard item type:' , err )
845854 }
@@ -853,30 +862,15 @@ if (isIOS && isSecureContext && navigator.clipboard && navigator.clipboard.read)
853862 }
854863
855864 const items = Array . from ( clipboardData . items )
856-
857- const imageItems = items . filter ( ( item ) => {
858- if ( item . kind !== 'file' ) return false
859-
860- const hasKnownType = ACCEPTED_FILE_TYPES . includes ( item . type )
861- const isLikelyImage = item . type . startsWith ( 'image/' )
862- const hasNoType = ! item . type || item . type === ''
863-
864- return hasKnownType || isLikelyImage || hasNoType
865- } )
866865
867- if ( imageItems . length > 0 ) {
866+ const fileItems = items . filter ( ( item ) => item . kind === 'file' )
867+
868+ if ( fileItems . length > 0 ) {
868869 event . preventDefault ( )
869- for ( const item of imageItems ) {
870+ for ( const item of fileItems ) {
870871 const file = item . getAsFile ( )
871872 if ( file ) {
872- const isValidImageFile =
873- ACCEPTED_FILE_TYPES . includes ( file . type ) ||
874- file . type . startsWith ( 'image/' ) ||
875- file . size > 0
876-
877- if ( isValidImageFile ) {
878- addImageAttachment ( file )
879- }
873+ addFileAttachment ( file )
880874 }
881875 }
882876 }
@@ -904,17 +898,15 @@ if (isIOS && isSecureContext && navigator.clipboard && navigator.clipboard.read)
904898 const files = event . dataTransfer ?. files
905899 if ( files ) {
906900 for ( const file of Array . from ( files ) ) {
907- if ( ACCEPTED_FILE_TYPES . includes ( file . type ) ) {
908- addImageAttachment ( file )
909- }
901+ addFileAttachment ( file )
910902 }
911903 }
912904 }
913905
914906 const handleFileInputChange = ( event : React . ChangeEvent < HTMLInputElement > ) => {
915907 const file = event . currentTarget . files ?. [ 0 ]
916- if ( file && ACCEPTED_FILE_TYPES . includes ( file . type ) ) {
917- addImageAttachment ( file )
908+ if ( file ) {
909+ addFileAttachment ( file )
918910 }
919911 event . currentTarget . value = ''
920912 }
@@ -1368,7 +1360,7 @@ return (
13681360 < input
13691361 ref = { fileInputRef }
13701362 type = "file"
1371- accept = "*/*"
1363+ accept = { ACCEPTED_FILE_TYPES . join ( ',' ) }
13721364 className = "hidden"
13731365 onChange = { handleFileInputChange }
13741366 />
0 commit comments