@@ -65,9 +65,6 @@ const styles = StyleSheet.create({
6565 borderTopRightRadius : 16 ,
6666 borderWidth : 1 ,
6767 overflow : 'hidden' ,
68- gap : primitives . spacingXs ,
69- paddingVertical : primitives . spacingXs ,
70- paddingHorizontal : primitives . spacingXs ,
7168 } ,
7269 leftAlignContent : {
7370 justifyContent : 'flex-start' ,
@@ -90,6 +87,9 @@ const styles = StyleSheet.create({
9087 rightAlignItems : {
9188 alignItems : 'flex-end' ,
9289 } ,
90+ textContainer : {
91+ paddingHorizontal : primitives . spacingXs ,
92+ } ,
9393} ) ;
9494
9595export type MessageContentPropsWithContext = Pick <
@@ -141,6 +141,14 @@ export type MessageContentPropsWithContext = Pick<
141141 * If the message is grouped in a single or bottom container
142142 */
143143 messageGroupedSingleOrBottom ?: boolean ;
144+
145+ /**
146+ * If the message has a single file
147+ */
148+ isSingleFile ?: boolean ;
149+ showPaddingTop ?: boolean ;
150+ showPaddingHorizontal ?: boolean ;
151+ showPaddingBottom ?: boolean ;
144152 } ;
145153
146154/**
@@ -175,6 +183,9 @@ const MessageContentWithContext = (props: MessageContentPropsWithContext) => {
175183 setMessageContentWidth,
176184 StreamingMessageView,
177185 threadList,
186+ showPaddingTop,
187+ showPaddingHorizontal,
188+ showPaddingBottom,
178189 } = props ;
179190 const { client } = useChatContext ( ) ;
180191 const { PollContent : PollContentOverride } = useMessagesContext ( ) ;
@@ -341,71 +352,81 @@ const MessageContentWithContext = (props: MessageContentPropsWithContext) => {
341352 ] }
342353 testID = 'message-content-wrapper'
343354 >
344- { messageContentOrder . map ( ( messageContentType , messageContentOrderIndex ) => {
345- switch ( messageContentType ) {
346- case 'quoted_reply' :
347- return (
348- message . quoted_message && (
355+ < View
356+ style = { {
357+ gap : primitives . spacingXs ,
358+ paddingTop : showPaddingTop ? 0 : primitives . spacingXs ,
359+ paddingHorizontal : showPaddingHorizontal ? 0 : primitives . spacingXs ,
360+ paddingBottom : showPaddingBottom ? 0 : primitives . spacingXs ,
361+ } }
362+ >
363+ { messageContentOrder . map ( ( messageContentType , messageContentOrderIndex ) => {
364+ switch ( messageContentType ) {
365+ case 'quoted_reply' :
366+ return (
367+ message . quoted_message && (
368+ < View
369+ key = { `quoted_reply_${ messageContentOrderIndex } ` }
370+ style = { [ styles . replyContainer , replyContainer ] }
371+ >
372+ < Reply styles = { replyStyles } />
373+ </ View >
374+ )
375+ ) ;
376+ case 'attachments' :
377+ return otherAttachments . map ( ( attachment , attachmentIndex ) => (
378+ < Attachment attachment = { attachment } key = { `${ message . id } -${ attachmentIndex } ` } />
379+ ) ) ;
380+ case 'files' :
381+ return (
382+ < FileAttachmentGroup
383+ key = { `file_attachment_group_${ messageContentOrderIndex } ` }
384+ />
385+ ) ;
386+ case 'gallery' :
387+ return (
349388 < View
350- key = { `quoted_reply_ ${ messageContentOrderIndex } ` }
351- style = { [ styles . replyContainer , replyContainer ] }
389+ key = { `gallery_ ${ messageContentOrderIndex } ` }
390+ style = { [ styles . galleryContainer ] }
352391 >
353- < Reply styles = { replyStyles } />
392+ < Gallery />
354393 </ View >
355- )
356- ) ;
357- case 'attachments' :
358- return otherAttachments . map ( ( attachment , attachmentIndex ) => (
359- < Attachment attachment = { attachment } key = { `${ message . id } -${ attachmentIndex } ` } />
360- ) ) ;
361- case 'files' :
362- return (
363- < FileAttachmentGroup key = { `file_attachment_group_${ messageContentOrderIndex } ` } />
364- ) ;
365- case 'gallery' :
366- return (
367- < View
368- key = { `gallery_${ messageContentOrderIndex } ` }
369- style = { [ styles . galleryContainer ] }
370- >
371- < Gallery />
372- </ View >
373- ) ;
374- case 'poll' : {
375- const pollId = message . poll_id ;
376- const poll = pollId && client . polls . fromState ( pollId ) ;
377- return pollId && poll ? (
378- < Poll
379- key = { `poll_${ message . poll_id } ` }
380- message = { message }
381- poll = { poll }
382- PollContent = { PollContentOverride }
383- />
384- ) : null ;
394+ ) ;
395+ case 'poll' : {
396+ const pollId = message . poll_id ;
397+ const poll = pollId && client . polls . fromState ( pollId ) ;
398+ return pollId && poll ? (
399+ < Poll
400+ key = { `poll_${ message . poll_id } ` }
401+ message = { message }
402+ poll = { poll }
403+ PollContent = { PollContentOverride }
404+ />
405+ ) : null ;
406+ }
407+ case 'location' :
408+ return MessageLocation ? (
409+ < MessageLocation
410+ key = { `message_location_${ messageContentOrderIndex } ` }
411+ message = { message }
412+ />
413+ ) : null ;
414+ case 'ai_text' :
415+ return isAIGenerated ? (
416+ < StreamingMessageView
417+ key = { `ai_message_text_container_${ messageContentOrderIndex } ` }
418+ />
419+ ) : null ;
420+ default :
421+ return null ;
385422 }
386- case 'location' :
387- return MessageLocation ? (
388- < MessageLocation
389- key = { `message_location_${ messageContentOrderIndex } ` }
390- message = { message }
391- />
392- ) : null ;
393- case 'ai_text' :
394- return isAIGenerated ? (
395- < StreamingMessageView
396- key = { `ai_message_text_container_${ messageContentOrderIndex } ` }
397- />
398- ) : null ;
399- case 'text' :
400- default :
401- return ( otherAttachments . length && otherAttachments [ 0 ] . actions ) ||
402- isAIGenerated ? null : (
403- < MessageTextContainer
404- key = { `message_text_container_${ messageContentOrderIndex } ` }
405- />
406- ) ;
407- }
408- } ) }
423+ } ) }
424+ </ View >
425+ < View style = { styles . textContainer } >
426+ { ( otherAttachments . length && otherAttachments [ 0 ] . actions ) || isAIGenerated ? null : (
427+ < MessageTextContainer />
428+ ) }
429+ </ View >
409430 </ View >
410431 { isMessageErrorType && < MessageError /> }
411432 </ View >
@@ -591,6 +612,8 @@ export const MessageContent = (props: MessageContentProps) => {
591612 otherAttachments,
592613 preventPress,
593614 threadList,
615+ files,
616+ images,
594617 } = useMessageContext ( ) ;
595618 const {
596619 additionalPressableProps,
@@ -606,6 +629,25 @@ export const MessageContent = (props: MessageContentProps) => {
606629 StreamingMessageView,
607630 } = useMessagesContext ( ) ;
608631 const { t } = useTranslationContext ( ) ;
632+ const isSingleFile = files . length === 1 ;
633+ const messageHasPoll = messageContentOrder . includes ( 'poll' ) ;
634+ const messageHasSingleImage = images . length === 1 ;
635+ const messageHasSingleFile =
636+ messageContentOrder . length === 1 && messageContentOrder [ 0 ] === 'files' && isSingleFile ;
637+ const messageHasOnlyText = messageContentOrder . length === 1 && messageContentOrder [ 0 ] === 'text' ;
638+
639+ const showPaddingTop =
640+ messageHasPoll || messageHasSingleImage || messageHasSingleFile || messageHasOnlyText ;
641+
642+ const showPaddingHorizontal = messageHasPoll || messageHasSingleImage || messageHasSingleFile ;
643+
644+ const showPaddingBottom =
645+ messageHasPoll ||
646+ messageHasSingleImage ||
647+ messageHasSingleFile ||
648+ messageHasOnlyText ||
649+ ( messageContentOrder . length > 1 &&
650+ messageContentOrder [ messageContentOrder . length - 1 ] === 'text' ) ;
609651
610652 return (
611653 < MemoizedMessageContent
@@ -636,6 +678,9 @@ export const MessageContent = (props: MessageContentProps) => {
636678 StreamingMessageView,
637679 t,
638680 threadList,
681+ showPaddingTop,
682+ showPaddingHorizontal,
683+ showPaddingBottom,
639684 } }
640685 { ...props }
641686 />
0 commit comments