11import React , { useCallback , useEffect , useMemo , useState } from 'react' ;
22import type { Event } from 'stream-chat' ;
3- import clsx from 'clsx' ;
4- import { useDropzone } from 'react-dropzone' ;
53import {
64 AttachmentSelector as DefaultAttachmentSelector ,
75 SimpleAttachmentSelector ,
@@ -28,17 +26,16 @@ import { RecordingAttachmentType } from '../MediaRecorder/classes';
2826import { useChatContext } from '../../context/ChatContext' ;
2927import { useChannelActionContext } from '../../context/ChannelActionContext' ;
3028import { useChannelStateContext } from '../../context/ChannelStateContext' ;
31- import { useTranslationContext } from '../../context/TranslationContext' ;
3229import { useMessageInputContext } from '../../context/MessageInputContext' ;
3330import { useComponentContext } from '../../context/ComponentContext' ;
3431
3532import type { DefaultStreamChatGenerics } from '../../types/types' ;
3633import { AIStates , useAIState } from '../AIStateIndicator' ;
34+ import { WithDragAndDropUpload } from './WithDragAndDropUpload' ;
3735
3836export const MessageInputFlat = <
3937 StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics ,
4038> ( ) => {
41- const { t } = useTranslationContext ( 'MessageInputFlat' ) ;
4239 const {
4340 asyncMessagesMultiSendEnabled,
4441 attachments,
@@ -48,14 +45,12 @@ export const MessageInputFlat = <
4845 hideSendButton,
4946 isUploadEnabled,
5047 linkPreviews,
51- maxFilesLeft,
5248 message,
5349 numberOfUploads,
5450 parent,
5551 recordingController,
5652 setCooldownRemaining,
5753 text,
58- uploadNewFiles,
5954 } = useMessageInputContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
6055
6156 const {
@@ -72,8 +67,6 @@ export const MessageInputFlat = <
7267 StopAIGenerationButton : StopAIGenerationButtonOverride ,
7368 } = useComponentContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
7469 const {
75- acceptedFiles = [ ] ,
76- multipleUploads,
7770 quotedMessage,
7871 } = useChannelStateContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
7972 const { setQuotedMessage } = useChannelActionContext ( 'MessageInputFlat' ) ;
@@ -96,23 +89,6 @@ export const MessageInputFlat = <
9689 [ attachments ] ,
9790 ) ;
9891
99- const accept = useMemo (
100- ( ) =>
101- acceptedFiles . reduce < Record < string , Array < string > > > ( ( mediaTypeMap , mediaType ) => {
102- mediaTypeMap [ mediaType ] ??= [ ] ;
103- return mediaTypeMap ;
104- } , { } ) ,
105- [ acceptedFiles ] ,
106- ) ;
107-
108- const { getRootProps, isDragActive, isDragReject } = useDropzone ( {
109- accept,
110- disabled : ! isUploadEnabled || maxFilesLeft === 0 ,
111- multiple : multipleUploads ,
112- noClick : true ,
113- onDrop : uploadNewFiles ,
114- } ) ;
115-
11692 useEffect ( ( ) => {
11793 const handleQuotedMessageUpdate = ( e : Event < StreamChatGenerics > ) => {
11894 if ( e . message ?. id !== quotedMessage ?. id ) return ;
@@ -156,90 +132,76 @@ export const MessageInputFlat = <
156132 ! ! StopAIGenerationButton ;
157133
158134 return (
159- < >
160- < div { ...getRootProps ( { className : 'str-chat__message-input' } ) } >
161- { recordingEnabled &&
162- recordingController . permissionState === 'denied' &&
163- showRecordingPermissionDeniedNotification && (
164- < RecordingPermissionDeniedNotification
165- onClose = { closePermissionDeniedNotification }
166- permissionName = { RecordingPermission . MIC }
167- />
168- ) }
169- { findAndEnqueueURLsToEnrich && (
170- < LinkPreviewList linkPreviews = { Array . from ( linkPreviews . values ( ) ) } />
135+ < WithDragAndDropUpload as = 'div' className = 'str-chat__message-input' >
136+ { recordingEnabled &&
137+ recordingController . permissionState === 'denied' &&
138+ showRecordingPermissionDeniedNotification && (
139+ < RecordingPermissionDeniedNotification
140+ onClose = { closePermissionDeniedNotification }
141+ permissionName = { RecordingPermission . MIC }
142+ />
171143 ) }
172- { isDragActive && (
173- < div
174- className = { clsx ( 'str-chat__dropzone-container' , {
175- 'str-chat__dropzone-container--not-accepted' : isDragReject ,
176- } ) }
177- >
178- { ! isDragReject && < p > { t < string > ( 'Drag your files here' ) } </ p > }
179- { isDragReject && < p > { t < string > ( 'Some of the files will not be accepted' ) } </ p > }
180- </ div >
181- ) }
182- { displayQuotedMessage && < QuotedMessagePreviewHeader /> }
183-
184- < div className = 'str-chat__message-input-inner' >
185- < AttachmentSelector />
186- < div className = 'str-chat__message-textarea-container' >
187- { displayQuotedMessage && (
188- < QuotedMessagePreview quotedMessage = { quotedMessage } />
144+ { findAndEnqueueURLsToEnrich && (
145+ < LinkPreviewList linkPreviews = { Array . from ( linkPreviews . values ( ) ) } />
146+ ) }
147+ { displayQuotedMessage && < QuotedMessagePreviewHeader /> }
148+
149+ < div className = 'str-chat__message-input-inner' >
150+ < AttachmentSelector />
151+ < div className = 'str-chat__message-textarea-container' >
152+ { displayQuotedMessage && < QuotedMessagePreview quotedMessage = { quotedMessage } /> }
153+ { isUploadEnabled &&
154+ ! ! ( numberOfUploads + failedUploadsCount || attachments . length > 0 ) && (
155+ < AttachmentPreviewList />
189156 ) }
190- { isUploadEnabled &&
191- ! ! ( numberOfUploads + failedUploadsCount || attachments . length > 0 ) && (
192- < AttachmentPreviewList />
193- ) }
194157
195- < div className = 'str-chat__message-textarea-with-emoji-picker' >
196- < ChatAutoComplete />
158+ < div className = 'str-chat__message-textarea-with-emoji-picker' >
159+ < ChatAutoComplete />
197160
198- { EmojiPicker && < EmojiPicker /> }
199- </ div >
161+ { EmojiPicker && < EmojiPicker /> }
200162 </ div >
201- { shouldDisplayStopAIGeneration ? (
202- < StopAIGenerationButton onClick = { stopGenerating } />
203- ) : (
204- ! hideSendButton && (
205- < >
206- { cooldownRemaining ? (
207- < CooldownTimer
208- cooldownInterval = { cooldownRemaining }
209- setCooldownRemaining = { setCooldownRemaining }
163+ </ div >
164+ { shouldDisplayStopAIGeneration ? (
165+ < StopAIGenerationButton onClick = { stopGenerating } />
166+ ) : (
167+ ! hideSendButton && (
168+ < >
169+ { cooldownRemaining ? (
170+ < CooldownTimer
171+ cooldownInterval = { cooldownRemaining }
172+ setCooldownRemaining = { setCooldownRemaining }
173+ />
174+ ) : (
175+ < >
176+ < SendButton
177+ disabled = {
178+ ! numberOfUploads &&
179+ ! text . length &&
180+ attachments . length - failedUploadsCount === 0
181+ }
182+ sendMessage = { handleSubmit }
210183 />
211- ) : (
212- < >
213- < SendButton
184+ { recordingEnabled && (
185+ < StartRecordingAudioButton
214186 disabled = {
215- ! numberOfUploads &&
216- ! text . length &&
217- attachments . length - failedUploadsCount === 0
187+ isRecording ||
188+ ( ! asyncMessagesMultiSendEnabled &&
189+ attachments . some (
190+ ( a ) => a . type === RecordingAttachmentType . VOICE_RECORDING ,
191+ ) )
218192 }
219- sendMessage = { handleSubmit }
193+ onClick = { ( ) => {
194+ recordingController . recorder ?. start ( ) ;
195+ setShowRecordingPermissionDeniedNotification ( true ) ;
196+ } }
220197 />
221- { recordingEnabled && (
222- < StartRecordingAudioButton
223- disabled = {
224- isRecording ||
225- ( ! asyncMessagesMultiSendEnabled &&
226- attachments . some (
227- ( a ) => a . type === RecordingAttachmentType . VOICE_RECORDING ,
228- ) )
229- }
230- onClick = { ( ) => {
231- recordingController . recorder ?. start ( ) ;
232- setShowRecordingPermissionDeniedNotification ( true ) ;
233- } }
234- />
235- ) }
236- </ >
237- ) }
238- </ >
239- )
240- ) }
241- </ div >
198+ ) }
199+ </ >
200+ ) }
201+ </ >
202+ )
203+ ) }
242204 </ div >
243- </ >
205+ </ WithDragAndDropUpload >
244206 ) ;
245207} ;
0 commit comments