diff --git a/native/chat/inner-text-message.react.js b/native/chat/inner-text-message.react.js --- a/native/chat/inner-text-message.react.js +++ b/native/chat/inner-text-message.react.js @@ -18,6 +18,10 @@ filterCorners, getRoundedContainerStyle, } from './rounded-corners'; +import { + TextMessageMarkdownContext, + useTextMessageMarkdown, +} from './text-message-markdown-context'; /* eslint-disable import/no-named-as-default-member */ const { Node } = Animated; @@ -83,6 +87,7 @@ } const rules = useTextMessageMarkdownRules(darkColor); + const textMessageMarkdown = useTextMessageMarkdown(item.messageInfo); const markdownStyles = React.useMemo(() => { const textStyle = { @@ -95,21 +100,23 @@ }, [darkColor]); const message = ( - - - - - {text} - - - - + + + + + + {text} + + + + + ); // We need to set onLayout in order to allow .measure() to be on the ref diff --git a/native/chat/text-message-markdown-context.js b/native/chat/text-message-markdown-context.js new file mode 100644 --- /dev/null +++ b/native/chat/text-message-markdown-context.js @@ -0,0 +1,45 @@ +// @flow + +import * as React from 'react'; +import * as SimpleMarkdown from 'simple-markdown'; + +import type { SingleASTNode } from 'lib/shared/markdown'; +import { messageKey } from 'lib/shared/message-utils'; +import type { TextMessageInfo } from 'lib/types/messages/text'; + +import { useTextMessageMarkdownRules } from '../chat/message-list-types'; + +export type TextMessageMarkdownContextType = { + +messageKey: string, + +markdownAST: $ReadOnlyArray, +}; + +const TextMessageMarkdownContext: React.Context = React.createContext( + null, +); + +function useTextMessageMarkdown( + messageInfo: TextMessageInfo, +): TextMessageMarkdownContextType { + // useDarkStyle doesn't affect the AST (only the styles), + // so we can safely just set it to false here + const rules = useTextMessageMarkdownRules(false); + const { simpleMarkdownRules, container } = rules; + + const { text } = messageInfo; + const ast = React.useMemo(() => { + const parser = SimpleMarkdown.parserFor(simpleMarkdownRules); + return parser(text, { disableAutoBlockNewlines: true, container }); + }, [simpleMarkdownRules, text, container]); + + const key = messageKey(messageInfo); + return React.useMemo( + () => ({ + messageKey: key, + markdownAST: ast, + }), + [key, ast], + ); +} + +export { TextMessageMarkdownContext, useTextMessageMarkdown }; diff --git a/native/markdown/markdown.react.js b/native/markdown/markdown.react.js --- a/native/markdown/markdown.react.js +++ b/native/markdown/markdown.react.js @@ -8,6 +8,7 @@ import { onlyEmojiRegex } from 'lib/shared/emojis'; +import { TextMessageMarkdownContext } from '../chat/text-message-markdown-context'; import type { TextStyle } from '../types/styles'; import type { MarkdownRules } from './rules.react'; @@ -20,14 +21,18 @@ const { style, children, rules } = props; const { simpleMarkdownRules, emojiOnlyFactor, container } = rules; - const parser = React.useMemo( - () => SimpleMarkdown.parserFor(simpleMarkdownRules), - [simpleMarkdownRules], - ); - const ast = React.useMemo( - () => parser(children, { disableAutoBlockNewlines: true, container }), - [parser, children, container], + const textMessageMarkdownContext = React.useContext( + TextMessageMarkdownContext, ); + const textMessageMarkdownAST = textMessageMarkdownContext?.markdownAST; + + const ast = React.useMemo(() => { + if (textMessageMarkdownAST) { + return textMessageMarkdownAST; + } + const parser = SimpleMarkdown.parserFor(simpleMarkdownRules); + return parser(children, { disableAutoBlockNewlines: true, container }); + }, [textMessageMarkdownAST, simpleMarkdownRules, children, container]); const output = React.useMemo( () => SimpleMarkdown.outputFor(simpleMarkdownRules, 'react'),