@@ -14,14 +14,16 @@ import Animated, {
1414
1515import { useSafeAreaInsets } from 'react-native-safe-area-context' ;
1616
17- import { type MessageComposerState , type TextComposerState , type UserResponse } from 'stream-chat' ;
17+ import { type UserResponse } from 'stream-chat' ;
1818
19- import { InputButtons } from './components/InputButtons' ;
20- import { LinkPreviewList } from './components/LinkPreviewList' ;
21- import { OutputButtons } from './components/OutputButtons' ;
2219import { MicPositionProvider } from './contexts/MicPositionContext' ;
20+ import { MessageComposerLeadingView } from './MessageComposerLeadingView' ;
21+ import { MessageComposerTrailingView } from './MessageComposerTrailingView' ;
22+ import { MessageInputHeaderView } from './MessageInputHeaderView' ;
23+ import { MessageInputLeadingView } from './MessageInputLeadingView' ;
24+ import { MessageInputTrailingView } from './MessageInputTrailingView' ;
2325
24- import { useHasLinkPreviews } from './hooks/useLinkPreviews ' ;
26+ import { audioRecorderSelector } from './utils/audioRecorderSelectors ' ;
2527
2628import { ChatContextValue , useChatContext , useOwnCapabilitiesContext } from '../../contexts' ;
2729import {
@@ -36,7 +38,6 @@ import {
3638 MessageComposerAPIContextValue ,
3739 useMessageComposerAPIContext ,
3840} from '../../contexts/messageComposerContext/MessageComposerAPIContext' ;
39- import { useHasAttachments } from '../../contexts/messageInputContext/hooks/useHasAttachments' ;
4041import { useMessageComposer } from '../../contexts/messageInputContext/hooks/useMessageComposer' ;
4142import {
4243 MessageInputContextValue ,
@@ -60,7 +61,6 @@ import { MessageInputHeightState } from '../../state-store/message-input-height-
6061import { primitives } from '../../theme' ;
6162import { AutoCompleteInput } from '../AutoCompleteInput/AutoCompleteInput' ;
6263import { CreatePoll } from '../Poll/CreatePollContent' ;
63- import { GiphyBadge } from '../ui/GiphyBadge' ;
6464import { SafeAreaViewWrapper } from '../UIComponents/SafeAreaViewWrapper' ;
6565
6666const useStyles = ( ) => {
@@ -199,14 +199,6 @@ type MessageInputPropsWithContext = Pick<
199199 recordingStatus ?: string ;
200200 } ;
201201
202- const textComposerStateSelector = ( state : TextComposerState ) => ( {
203- command : state . command ,
204- } ) ;
205-
206- const messageComposerStateStoreSelector = ( state : MessageComposerState ) => ( {
207- quotedMessage : state . quotedMessage ,
208- } ) ;
209-
210202const messageInputHeightStoreSelector = ( state : MessageInputHeightState ) => ( {
211203 height : state . height ,
212204} ) ;
@@ -510,154 +502,6 @@ const MessageInputWithContext = (props: MessageInputPropsWithContext) => {
510502 ) ;
511503} ;
512504
513- /**
514- * PRAGMA: MessageComposerLeadingView
515- * @param state
516- */
517-
518- const idleRecordingStateSelector = ( state : AudioRecorderManagerState ) => ( {
519- isRecordingStateIdle : state . status === 'idle' ,
520- } ) ;
521-
522- export const MessageComposerLeadingView = ( ) => {
523- const {
524- theme : {
525- messageInput : { inputButtonsContainer } ,
526- } ,
527- } = useTheme ( ) ;
528- const styles = useStyles ( ) ;
529-
530- const { audioRecorderManager, messageInputFloating } = useMessageInputContext ( ) ;
531- const { isRecordingStateIdle } = useStateStore (
532- audioRecorderManager . state ,
533- idleRecordingStateSelector ,
534- ) ;
535-
536- return isRecordingStateIdle ? (
537- < Animated . View
538- layout = { LinearTransition . duration ( 200 ) }
539- style = { [
540- styles . inputButtonsContainer ,
541- messageInputFloating ? styles . shadow : null ,
542- inputButtonsContainer ,
543- ] }
544- >
545- < InputButtons />
546- </ Animated . View >
547- ) : null ;
548- } ;
549-
550- /**
551- * PRAGMA: MessageComposerTrailingView
552- * @param state
553- */
554-
555- export const MessageComposerTrailingView = ( ) => {
556- return null ;
557- } ;
558-
559- /**
560- * PRAGMA: MessageInputHeaderView
561- * @param prevProps
562- */
563-
564- export const MessageInputHeaderView = ( ) => {
565- const {
566- theme : {
567- messageInput : { contentContainer } ,
568- } ,
569- } = useTheme ( ) ;
570- const styles = useStyles ( ) ;
571-
572- const messageComposer = useMessageComposer ( ) ;
573- const editing = ! ! messageComposer . editedMessage ;
574- const { clearEditingState } = useMessageComposerAPIContext ( ) ;
575- const { quotedMessage } = useStateStore ( messageComposer . state , messageComposerStateStoreSelector ) ;
576- const hasLinkPreviews = useHasLinkPreviews ( ) ;
577- const { audioRecorderManager, AttachmentUploadPreviewList } = useMessageInputContext ( ) ;
578- const { Reply } = useMessagesContext ( ) ;
579- const { isRecordingStateIdle } = useStateStore (
580- audioRecorderManager . state ,
581- idleRecordingStateSelector ,
582- ) ;
583- const hasAttachments = useHasAttachments ( ) ;
584-
585- return isRecordingStateIdle ? (
586- < Animated . View
587- layout = { LinearTransition . duration ( 200 ) }
588- style = { [
589- styles . contentContainer ,
590- {
591- paddingTop :
592- hasAttachments || quotedMessage || editing || hasLinkPreviews
593- ? primitives . spacingXs
594- : 0 ,
595- } ,
596- contentContainer ,
597- ] }
598- >
599- { editing ? (
600- < Animated . View entering = { FadeIn . duration ( 200 ) } exiting = { FadeOut . duration ( 200 ) } >
601- < Reply
602- mode = 'edit'
603- onDismiss = { clearEditingState }
604- quotedMessage = { messageComposer . editedMessage }
605- />
606- </ Animated . View >
607- ) : null }
608- { quotedMessage ? (
609- < Animated . View entering = { FadeIn . duration ( 200 ) } exiting = { FadeOut . duration ( 200 ) } >
610- < Reply mode = 'reply' />
611- </ Animated . View >
612- ) : null }
613- < AttachmentUploadPreviewList />
614- < LinkPreviewList />
615- </ Animated . View >
616- ) : null ;
617- } ;
618-
619- /**
620- * PRAGMA: MessageInputLeadingView
621- * @param prevProps
622- */
623-
624- export const MessageInputLeadingView = ( ) => {
625- const styles = useStyles ( ) ;
626- const messageComposer = useMessageComposer ( ) ;
627- const { textComposer } = messageComposer ;
628- const { command } = useStateStore ( textComposer . state , textComposerStateSelector ) ;
629-
630- return command ? (
631- < View style = { styles . giphyContainer } >
632- < GiphyBadge />
633- </ View >
634- ) : null ;
635- } ;
636-
637- /**
638- * MessageInputTrailingView
639- * @param prevProps
640- */
641-
642- export const MessageInputTrailingView = ( ) => {
643- const styles = useStyles ( ) ;
644- const {
645- theme : {
646- messageInput : { outputButtonsContainer } ,
647- } ,
648- } = useTheme ( ) ;
649- const { audioRecorderManager } = useMessageInputContext ( ) ;
650- const { micLocked, recordingStatus } = useStateStore (
651- audioRecorderManager . state ,
652- audioRecorderSelector ,
653- ) ;
654- return ( recordingStatus === 'idle' || recordingStatus === 'recording' ) && ! micLocked ? (
655- < View style = { [ styles . outputButtonsContainer , outputButtonsContainer ] } >
656- < OutputButtons />
657- </ View >
658- ) : null ;
659- } ;
660-
661505const areEqual = (
662506 prevProps : MessageInputPropsWithContext ,
663507 nextProps : MessageInputPropsWithContext ,
@@ -800,12 +644,6 @@ const MemoizedMessageInput = React.memo(
800644
801645export type MessageInputProps = Partial < MessageInputPropsWithContext > ;
802646
803- const audioRecorderSelector = ( state : AudioRecorderManagerState ) => ( {
804- micLocked : state . micLocked ,
805- isRecordingStateIdle : state . status === 'idle' ,
806- recordingStatus : state . status ,
807- } ) ;
808-
809647/**
810648 * UI Component for message input
811649 * It's a consumer of
0 commit comments