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 {
@@ -71,11 +66,8 @@ export const MessageInputFlat = <
7166 StartRecordingAudioButton = DefaultStartRecordingAudioButton ,
7267 StopAIGenerationButton : StopAIGenerationButtonOverride ,
7368 } = useComponentContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
74- const {
75- acceptedFiles = [ ] ,
76- multipleUploads,
77- quotedMessage,
78- } = useChannelStateContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
69+ const { quotedMessage } =
70+ useChannelStateContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
7971 const { setQuotedMessage } = useChannelActionContext ( 'MessageInputFlat' ) ;
8072 const { channel } = useChatContext < StreamChatGenerics > ( 'MessageInputFlat' ) ;
8173
@@ -96,23 +88,6 @@ export const MessageInputFlat = <
9688 [ attachments ] ,
9789 ) ;
9890
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-
11691 useEffect ( ( ) => {
11792 const handleQuotedMessageUpdate = ( e : Event < StreamChatGenerics > ) => {
11893 if ( e . message ?. id !== quotedMessage ?. id ) return ;
@@ -156,90 +131,76 @@ export const MessageInputFlat = <
156131 ! ! StopAIGenerationButton ;
157132
158133 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 ( ) ) } />
171- ) }
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 >
134+ < WithDragAndDropUpload className = 'str-chat__message-input' component = 'div' >
135+ { recordingEnabled &&
136+ recordingController . permissionState === 'denied' &&
137+ showRecordingPermissionDeniedNotification && (
138+ < RecordingPermissionDeniedNotification
139+ onClose = { closePermissionDeniedNotification }
140+ permissionName = { RecordingPermission . MIC }
141+ />
181142 ) }
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 } />
143+ { findAndEnqueueURLsToEnrich && (
144+ < LinkPreviewList linkPreviews = { Array . from ( linkPreviews . values ( ) ) } />
145+ ) }
146+ { displayQuotedMessage && < QuotedMessagePreviewHeader /> }
147+
148+ < div className = 'str-chat__message-input-inner' >
149+ < AttachmentSelector />
150+ < div className = 'str-chat__message-textarea-container' >
151+ { displayQuotedMessage && < QuotedMessagePreview quotedMessage = { quotedMessage } /> }
152+ { isUploadEnabled &&
153+ ! ! ( numberOfUploads + failedUploadsCount || attachments . length > 0 ) && (
154+ < AttachmentPreviewList />
189155 ) }
190- { isUploadEnabled &&
191- ! ! ( numberOfUploads + failedUploadsCount || attachments . length > 0 ) && (
192- < AttachmentPreviewList />
193- ) }
194156
195- < div className = 'str-chat__message-textarea-with-emoji-picker' >
196- < ChatAutoComplete />
157+ < div className = 'str-chat__message-textarea-with-emoji-picker' >
158+ < ChatAutoComplete />
197159
198- { EmojiPicker && < EmojiPicker /> }
199- </ div >
160+ { EmojiPicker && < EmojiPicker /> }
200161 </ div >
201- { shouldDisplayStopAIGeneration ? (
202- < StopAIGenerationButton onClick = { stopGenerating } />
203- ) : (
204- ! hideSendButton && (
205- < >
206- { cooldownRemaining ? (
207- < CooldownTimer
208- cooldownInterval = { cooldownRemaining }
209- setCooldownRemaining = { setCooldownRemaining }
162+ </ div >
163+ { shouldDisplayStopAIGeneration ? (
164+ < StopAIGenerationButton onClick = { stopGenerating } />
165+ ) : (
166+ ! hideSendButton && (
167+ < >
168+ { cooldownRemaining ? (
169+ < CooldownTimer
170+ cooldownInterval = { cooldownRemaining }
171+ setCooldownRemaining = { setCooldownRemaining }
172+ />
173+ ) : (
174+ < >
175+ < SendButton
176+ disabled = {
177+ ! numberOfUploads &&
178+ ! text . length &&
179+ attachments . length - failedUploadsCount === 0
180+ }
181+ sendMessage = { handleSubmit }
210182 />
211- ) : (
212- < >
213- < SendButton
183+ { recordingEnabled && (
184+ < StartRecordingAudioButton
214185 disabled = {
215- ! numberOfUploads &&
216- ! text . length &&
217- attachments . length - failedUploadsCount === 0
186+ isRecording ||
187+ ( ! asyncMessagesMultiSendEnabled &&
188+ attachments . some (
189+ ( a ) => a . type === RecordingAttachmentType . VOICE_RECORDING ,
190+ ) )
218191 }
219- sendMessage = { handleSubmit }
192+ onClick = { ( ) => {
193+ recordingController . recorder ?. start ( ) ;
194+ setShowRecordingPermissionDeniedNotification ( true ) ;
195+ } }
220196 />
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 >
197+ ) }
198+ </ >
199+ ) }
200+ </ >
201+ )
202+ ) }
242203 </ div >
243- </ >
204+ </ WithDragAndDropUpload >
244205 ) ;
245206} ;
0 commit comments