// Copyright 2019-2021 Signal Messenger, LLC // SPDX-License-Identifier: AGPL-3.0-only import React, { ReactNode } from 'react'; import { MESSAGE_TEXT_CLASS_NAME } from './BaseConversationListItem'; import { AtMentionify } from '../conversation/AtMentionify'; import { MessageBody } from '../conversation/MessageBody'; import { Emojify } from '../conversation/Emojify'; import { AddNewLines } from '../conversation/AddNewLines'; import { SizeClassType } from '../emoji/lib'; import { BodyRangesType, LocalizerType, RenderTextCallbackType, } from '../../types/Util'; const CLASS_NAME = `${MESSAGE_TEXT_CLASS_NAME}__message-search-result-contents`; export type Props = { bodyRanges: BodyRangesType; text: string; i18n: LocalizerType; }; const renderEmoji = ({ text, key, sizeClass, renderNonEmoji, }: { i18n: LocalizerType; text: string; key: number; sizeClass?: SizeClassType; renderNonEmoji: RenderTextCallbackType; }) => ( ); export class MessageBodyHighlight extends React.Component { private readonly renderNewLines: RenderTextCallbackType = ({ text: textWithNewLines, key, }) => { const { bodyRanges } = this.props; return ( ( )} /> ); }; private renderContents(): ReactNode { const { bodyRanges, text, i18n } = this.props; const results: Array = []; const FIND_BEGIN_END = /<>(.+?)<>/g; const processedText = AtMentionify.preprocessMentions(text, bodyRanges); let match = FIND_BEGIN_END.exec(processedText); let last = 0; let count = 1; if (!match) { return ( ); } const sizeClass = ''; while (match) { if (last < match.index) { const beforeText = processedText.slice(last, match.index); count += 1; results.push( renderEmoji({ text: beforeText, sizeClass, key: count, i18n, renderNonEmoji: this.renderNewLines, }) ); } const [, toHighlight] = match; count += 2; results.push( {renderEmoji({ text: toHighlight, sizeClass, key: count, i18n, renderNonEmoji: this.renderNewLines, })} ); last = FIND_BEGIN_END.lastIndex; match = FIND_BEGIN_END.exec(processedText); } if (last < processedText.length) { count += 1; results.push( renderEmoji({ text: processedText.slice(last), sizeClass, key: count, i18n, renderNonEmoji: this.renderNewLines, }) ); } return results; } public render(): ReactNode { return
{this.renderContents()}
; } }