diff --git a/app/containers/message/Components/Attachments/Reply.tsx b/app/containers/message/Components/Attachments/Reply.tsx index 74d47da3ceb..833f60918ad 100644 --- a/app/containers/message/Components/Attachments/Reply.tsx +++ b/app/containers/message/Components/Attachments/Reply.tsx @@ -17,6 +17,10 @@ import MessageContext from '../../Context'; import Touchable from '../../Touchable'; import messageStyles from '../../styles'; import dayjs from '../../../../lib/dayjs'; +import { CustomIcon } from '../../../CustomIcon'; +import { getFileIcon } from '../../../../lib/methods/getFileIcon'; +import { formatSize } from '../../../../lib/methods/formatSize'; +import { isDocumentFile } from '../../../../lib/methods/isDocumentFile'; const styles = StyleSheet.create({ button: { @@ -30,6 +34,8 @@ const styles = StyleSheet.create({ flex: 1, borderRadius: 4, flexDirection: 'row', + alignItems: 'center', + gap: 8, paddingVertical: 4, paddingLeft: 8 }, @@ -88,6 +94,15 @@ const styles = StyleSheet.create({ flex: 1, fontSize: 16, ...sharedStyles.textMedium + }, + fileIconContainer: { + borderRadius: 4, + padding: 4 + }, + fileSizeText: { + fontSize: 13, + lineHeight: 18, + ...sharedStyles.textRegular } }); @@ -124,6 +139,7 @@ const Description = React.memo( const { user } = useContext(MessageContext); const text = attachment.text || attachment.title; + const { colors } = useTheme(); if (!text) { return null; @@ -134,6 +150,11 @@ const Description = React.memo( // For other attachments (message quotes, embeds), the text may contain actual markdown formatting, // so we use the full Markdown component to preserve styling. const isFileName = attachment.type === 'file' && !attachment.text; + const isDocument = isDocumentFile(attachment); + + if (isFileName && isDocument && attachment.size !== undefined) { + return {formatSize(attachment.size, 2)}; + } if (isFileName) { return ; @@ -151,6 +172,12 @@ const Description = React.memo( if (prevProps.attachment.type !== nextProps.attachment.type) { return false; } + if (prevProps.attachment.format !== nextProps.attachment.format) { + return false; + } + if (prevProps.attachment.size !== nextProps.attachment.size) { + return false; + } return true; } ); @@ -209,7 +236,7 @@ const Reply = React.memo( 'use memo'; const [loading, setLoading] = useState(false); - const { theme } = useTheme(); + const { theme, colors } = useTheme(); const { baseUrl, user, id, e2e, isEncrypted } = useContext(MessageContext); if (!attachment || (isEncrypted && !e2e)) { @@ -236,6 +263,12 @@ const Reply = React.memo( strokeLight = attachment.color; } + // in case we dont have format in payload, we can extract extention from title + const titleParts = attachment.title?.split('.') ?? []; + const attachmentFormat = attachment.format ?? titleParts[titleParts.length - 1]; + + const isDocument = attachment.type === 'file' && isDocumentFile(attachment) && attachment.title; + return ( + {isDocument && ( + + + + )} + <Description attachment={attachment} getCustomEmoji={getCustomEmoji} /> diff --git a/app/containers/message/__snapshots__/Message.test.tsx.snap b/app/containers/message/__snapshots__/Message.test.tsx.snap index eb164c03554..cb7ab51fb7f 100644 --- a/app/containers/message/__snapshots__/Message.test.tsx.snap +++ b/app/containers/message/__snapshots__/Message.test.tsx.snap @@ -1313,9 +1313,11 @@ exports[`Story Snapshots: AttachmentWithTextAndLink should match snapshot 1`] = <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -2053,9 +2055,11 @@ exports[`Story Snapshots: AttachmentWithTextAndLinkLargeFont should match snapsh <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -10356,9 +10360,11 @@ exports[`Story Snapshots: CollapsedAttachments should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -11731,9 +11737,11 @@ exports[`Story Snapshots: CollapsedAttachmentsLargeFont should match snapshot 1` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -13108,9 +13116,11 @@ exports[`Story Snapshots: CollapsibleAttachmentWithText should match snapshot 1` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -14626,9 +14636,11 @@ exports[`Story Snapshots: CollapsibleAttachmentWithTextLargeFont should match sn <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -15562,9 +15574,11 @@ exports[`Story Snapshots: ColoredAttachments should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -15833,9 +15847,11 @@ exports[`Story Snapshots: ColoredAttachments should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -16104,9 +16120,11 @@ exports[`Story Snapshots: ColoredAttachments should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -16765,9 +16783,11 @@ exports[`Story Snapshots: ColoredAttachmentsLargeFont should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -17036,9 +17056,11 @@ exports[`Story Snapshots: ColoredAttachmentsLargeFont should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -17307,9 +17329,11 @@ exports[`Story Snapshots: ColoredAttachmentsLargeFont should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -17968,9 +17992,11 @@ exports[`Story Snapshots: CustomFields should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -18751,9 +18777,11 @@ exports[`Story Snapshots: CustomFields should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -19805,9 +19833,11 @@ exports[`Story Snapshots: CustomFieldsLargeFont should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -20588,9 +20618,11 @@ exports[`Story Snapshots: CustomFieldsLargeFont should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -48204,9 +48236,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -48771,9 +48805,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -49338,9 +49374,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -49905,9 +49943,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -50307,9 +50347,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -50438,9 +50480,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenames should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -50966,9 +51010,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -51533,9 +51579,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -52100,9 +52148,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -52667,9 +52717,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -53069,9 +53121,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -53200,9 +53254,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -53715,9 +53771,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -53858,9 +53916,11 @@ exports[`Story Snapshots: FileAttachmentsWithFilenamesLargeFont should match sna <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -77656,9 +77716,11 @@ exports[`Story Snapshots: MessageWithNestedReplyAndFile should match snapshot 1` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -78220,9 +78282,11 @@ exports[`Story Snapshots: MessageWithNestedReplyAndFile should match snapshot 1` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -81707,9 +81771,11 @@ exports[`Story Snapshots: MessageWithReply should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -82307,9 +82373,11 @@ exports[`Story Snapshots: MessageWithReply should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -82515,9 +82583,11 @@ exports[`Story Snapshots: MessageWithReply should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -83273,9 +83343,11 @@ exports[`Story Snapshots: MessageWithReply should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -84048,9 +84120,11 @@ exports[`Story Snapshots: MessageWithReply should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -84838,9 +84912,11 @@ exports[`Story Snapshots: MessageWithReplyAndFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -85425,9 +85501,11 @@ exports[`Story Snapshots: MessageWithReplyAndFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -86089,9 +86167,11 @@ exports[`Story Snapshots: MessageWithReplyAndFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -86240,9 +86320,11 @@ exports[`Story Snapshots: MessageWithReplyAndFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -86840,9 +86922,11 @@ exports[`Story Snapshots: MessageWithReplyAndFileLargeFont should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -87427,9 +87511,11 @@ exports[`Story Snapshots: MessageWithReplyAndFileLargeFont should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -88091,9 +88177,11 @@ exports[`Story Snapshots: MessageWithReplyAndFileLargeFont should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -88242,9 +88330,11 @@ exports[`Story Snapshots: MessageWithReplyAndFileLargeFont should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -88842,9 +88932,11 @@ exports[`Story Snapshots: MessageWithReplyLargeFont should match snapshot 1`] = <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -89442,9 +89534,11 @@ exports[`Story Snapshots: MessageWithReplyLargeFont should match snapshot 1`] = <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -90145,9 +90239,11 @@ exports[`Story Snapshots: MessageWithReplyLargeFont should match snapshot 1`] = <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -90920,9 +91016,11 @@ exports[`Story Snapshots: MessageWithReplyLargeFont should match snapshot 1`] = <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -124788,9 +124886,11 @@ exports[`Story Snapshots: ThumbnailFromServer should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -125440,9 +125540,11 @@ exports[`Story Snapshots: ThumbnailFromServerLargeFont should match snapshot 1`] <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -127928,9 +128030,11 @@ exports[`Story Snapshots: TwoShortCustomFieldsWithMarkdown should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -128278,9 +128382,11 @@ exports[`Story Snapshots: TwoShortCustomFieldsWithMarkdown should match snapshot <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -129085,9 +129191,11 @@ exports[`Story Snapshots: TwoShortCustomFieldsWithMarkdownLargeFont should match <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -129435,9 +129543,11 @@ exports[`Story Snapshots: TwoShortCustomFieldsWithMarkdownLargeFont should match <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -142308,9 +142418,11 @@ exports[`Story Snapshots: WithFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -142685,9 +142797,11 @@ exports[`Story Snapshots: WithFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -142927,9 +143041,11 @@ exports[`Story Snapshots: WithFile should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -143566,9 +143682,11 @@ exports[`Story Snapshots: WithFileLargeFont should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } @@ -143943,9 +144061,11 @@ exports[`Story Snapshots: WithFileLargeFont should match snapshot 1`] = ` <View style={ { + "alignItems": "center", "borderRadius": 4, "flex": 1, "flexDirection": "row", + "gap": 8, "paddingLeft": 8, "paddingVertical": 4, } diff --git a/app/lib/methods/formatSize.ts b/app/lib/methods/formatSize.ts new file mode 100644 index 00000000000..39b8771d6f4 --- /dev/null +++ b/app/lib/methods/formatSize.ts @@ -0,0 +1,11 @@ +export const formatSize = (bytes: number, decimals = 2): string => { + if (!bytes || bytes === 0) return '0 Bytes'; + + const k = 1024; + const dm = decimals < 0 ? 0 : decimals; + const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; + + const i = Math.floor(Math.log(bytes) / Math.log(k)); + + return `${parseFloat((bytes / Math.pow(k, i)).toFixed(dm))} ${sizes[i]}`; +}; diff --git a/app/lib/methods/getFileIcon.ts b/app/lib/methods/getFileIcon.ts new file mode 100644 index 00000000000..771836b3a2a --- /dev/null +++ b/app/lib/methods/getFileIcon.ts @@ -0,0 +1,25 @@ +import { type TIconsName } from '../../containers/CustomIcon'; + +export const getFileIcon = (format: string): TIconsName => { + const fileFormat = format.toLowerCase(); + + switch (fileFormat) { + case 'pdf': + return 'adobe-reader-monochromatic'; + + // sheets + case 'xls': + case 'xlsx': + case 'csv': + return 'file-sheet'; + + // presentations + case 'pptx': + case 'ppt': + return 'engagement-dashboard'; + + // other documents + default: + return 'file-document'; + } +}; diff --git a/app/lib/methods/isDocumentFile.ts b/app/lib/methods/isDocumentFile.ts new file mode 100644 index 00000000000..d2f6a02ce92 --- /dev/null +++ b/app/lib/methods/isDocumentFile.ts @@ -0,0 +1,18 @@ +import { type IAttachment } from '../../definitions'; + +export const isDocumentFile = (attachment: IAttachment) => { + if (attachment.type === 'file') { + switch (attachment.format?.toLowerCase()) { + case 'pdf': + case 'xlsx': + case 'xls': + case 'csv': + case 'pptx': + case 'ppt': + case 'docx': + case 'doc': + return true; + } + } + return false; +};