// Copyright 2018-2020 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; import { getSizeClass, SizeClassType } from '../emoji/lib'; import { AtMentionify } from './AtMentionify'; import { Emojify } from './Emojify'; import { AddNewLines } from './AddNewLines'; import { Linkify } from './Linkify'; import { BodyRangesType, LocalizerType, RenderTextCallbackType, } from '../../types/Util'; type OpenConversationActionType = ( conversationId: string, messageId?: string ) => void; export type Props = { direction?: 'incoming' | 'outgoing'; text: string; textPending?: boolean; /** If set, all emoji will be the same size. Otherwise, just one emoji will be large. */ disableJumbomoji?: boolean; /** If set, links will be left alone instead of turned into clickable `` tags. */ disableLinks?: boolean; i18n: LocalizerType; bodyRanges?: BodyRangesType; openConversation?: OpenConversationActionType; }; const renderEmoji = ({ text, key, sizeClass, renderNonEmoji, }: { i18n: LocalizerType; text: string; key: number; sizeClass?: SizeClassType; renderNonEmoji: RenderTextCallbackType; }) => ( ); /** * This component makes it very easy to use all three of our message formatting * components: `Emojify`, `Linkify`, and `AddNewLines`. Because each of them is fully * configurable with their `renderXXX` props, this component will assemble all three of * them for you. */ export class MessageBody extends React.Component { private readonly renderNewLines: RenderTextCallbackType = ({ text: textWithNewLines, key, }) => { const { bodyRanges, direction, openConversation } = this.props; return ( ( )} /> ); }; public addDownloading(jsx: JSX.Element): JSX.Element { const { i18n, textPending } = this.props; return ( {jsx} {textPending ? ( {' '} {i18n('downloading')} ) : null} ); } public render(): JSX.Element { const { bodyRanges, text, textPending, disableJumbomoji, disableLinks, i18n, } = this.props; const sizeClass = disableJumbomoji ? undefined : getSizeClass(text); const textWithPending = AtMentionify.preprocessMentions( textPending ? `${text}...` : text, bodyRanges ); if (disableLinks) { return this.addDownloading( renderEmoji({ i18n, text: textWithPending, sizeClass, key: 0, renderNonEmoji: this.renderNewLines, }) ); } return this.addDownloading( { return renderEmoji({ i18n, text: nonLinkText, sizeClass, key, renderNonEmoji: this.renderNewLines, }); }} /> ); } }