diff --git a/app/containers/markdown/MessageBody/BigEmoji.js b/app/containers/markdown/MessageBody/BigEmoji.js deleted file mode 100644 index ce671f89c..000000000 --- a/app/containers/markdown/MessageBody/BigEmoji.js +++ /dev/null @@ -1,19 +0,0 @@ -/* eslint-disable react/no-array-index-key */ -import React from 'react'; -import { View } from 'react-native'; -import PropTypes from 'prop-types'; - -import Emoji from './Emoji'; - - -const BigEmoji = ({ value }) => ( - - {value.map((block, index) => )} - -); - -BigEmoji.propTypes = { - value: PropTypes.object -}; - -export default BigEmoji; diff --git a/app/containers/markdown/MessageBody/Plain.js b/app/containers/markdown/MessageBody/Plain.js deleted file mode 100644 index 3cf0e6d4b..000000000 --- a/app/containers/markdown/MessageBody/Plain.js +++ /dev/null @@ -1,15 +0,0 @@ -import React from 'react'; -import { Text } from 'react-native'; -import PropTypes from 'prop-types'; - -const Plain = ({ value }) => ( - - {value} - -); - -Plain.propTypes = { - value: PropTypes.string -}; - -export default Plain; diff --git a/app/containers/markdown/index.tsx b/app/containers/markdown/index.tsx index ff0068a3e..4a8ddbb82 100644 --- a/app/containers/markdown/index.tsx +++ b/app/containers/markdown/index.tsx @@ -4,6 +4,7 @@ import { Node, Parser } from 'commonmark'; import Renderer from 'commonmark-react-renderer'; import removeMarkdown from 'remove-markdown'; import { connect } from 'react-redux'; +import { MarkdownAST } from '@rocket.chat/message-parser'; import shortnameToUnicode from '../../utils/shortnameToUnicode'; import I18n from '../../i18n'; @@ -22,10 +23,16 @@ import mergeTextNodes from './mergeTextNodes'; import styles from './styles'; import { isValidURL } from '../../utils/url'; import { getUserSelector } from '../../selectors/login'; -import MessageBody from './MessageBody'; +import NewMarkdown from './new'; interface IMarkdownProps { msg: string; + md: [ + { + tokens: MarkdownAST; + mentions: object[]; + } + ]; getCustomEmoji: Function; baseUrl: string; username: string; @@ -39,6 +46,9 @@ interface IMarkdownProps { _id: number; }[]; mentions: object[]; + user: { + enableMessageParserEarlyAdoption: boolean; + }; navToRoomInfo: Function; preview: boolean; theme: string; @@ -351,7 +361,7 @@ class Markdown extends PureComponent { } if (user.enableMessageParserEarlyAdoption && md) { - return ; + return ; } let m = formatText(msg); @@ -385,7 +395,7 @@ class Markdown extends PureComponent { } } -const mapStateToProps = state => ({ +const mapStateToProps = (state: any) => ({ user: getUserSelector(state) }); diff --git a/app/containers/markdown/new/BigEmoji.tsx b/app/containers/markdown/new/BigEmoji.tsx new file mode 100644 index 000000000..a29543eb3 --- /dev/null +++ b/app/containers/markdown/new/BigEmoji.tsx @@ -0,0 +1,25 @@ +import React, { FC } from 'react'; +import { StyleSheet, View } from 'react-native'; +import { BigEmoji as BigEmojiProps } from '@rocket.chat/message-parser'; + +import Emoji from './Emoji'; + +interface IBigEmojiProps { + value: BigEmojiProps['value']; +} + +const styles = StyleSheet.create({ + container: { + flexDirection: 'row' + } +}); + +const BigEmoji: FC = ({ value }) => ( + + {value.map(block => ( + + ))} + +); + +export default BigEmoji; diff --git a/app/containers/markdown/MessageBody/Bold.js b/app/containers/markdown/new/Bold.tsx similarity index 61% rename from app/containers/markdown/MessageBody/Bold.js rename to app/containers/markdown/new/Bold.tsx index ed827eff8..840e3ee38 100644 --- a/app/containers/markdown/MessageBody/Bold.js +++ b/app/containers/markdown/new/Bold.tsx @@ -1,28 +1,32 @@ /* eslint-disable react/no-array-index-key */ -import React from 'react'; +import React, { FC } from 'react'; import { StyleSheet, Text } from 'react-native'; -import PropTypes from 'prop-types'; +import { Bold as BoldProps } from '@rocket.chat/message-parser'; import Strike from './Strike'; import Italic from './Italic'; import Plain from './Plain'; +interface IBoldProps { + value: BoldProps['value']; +} + const styles = StyleSheet.create({ text: { fontWeight: 'bold' } }); -const Bold = ({ value }) => ( +const Bold: FC = ({ value }) => ( - {value.map((block, index) => { + {value.map(block => { switch (block.type) { case 'PLAIN_TEXT': return ; case 'STRIKE': - return ; + return ; case 'ITALIC': - return ; + return ; default: return null; } @@ -30,8 +34,4 @@ const Bold = ({ value }) => ( ); -Bold.propTypes = { - value: PropTypes.string -}; - export default Bold; diff --git a/app/containers/markdown/MessageBody/Code.js b/app/containers/markdown/new/Code.js similarity index 94% rename from app/containers/markdown/MessageBody/Code.js rename to app/containers/markdown/new/Code.js index d11532954..02b34ed7c 100644 --- a/app/containers/markdown/MessageBody/Code.js +++ b/app/containers/markdown/new/Code.js @@ -3,15 +3,12 @@ import React from 'react'; import { Text } from 'react-native'; import PropTypes from 'prop-types'; -import CodeLine from './CodeLine'; import styles from '../styles'; - import { themes } from '../../../constants/colors'; import { useTheme } from '../../../theme'; +import CodeLine from './CodeLine'; -const Code = ({ - value, style -}) => { +const Code = ({ value, style }) => { const { theme } = useTheme(); return ( @@ -24,8 +21,7 @@ const Code = ({ borderColor: themes[theme].borderColor }, ...style - ]} - > + ]}> {value.map((block, index) => { switch (block.type) { case 'CODE_LINE': diff --git a/app/containers/markdown/MessageBody/CodeLine.js b/app/containers/markdown/new/CodeLine.js similarity index 65% rename from app/containers/markdown/MessageBody/CodeLine.js rename to app/containers/markdown/new/CodeLine.js index 15c74c6c5..34c6872d3 100644 --- a/app/containers/markdown/MessageBody/CodeLine.js +++ b/app/containers/markdown/new/CodeLine.js @@ -2,9 +2,7 @@ import React from 'react'; import { Text } from 'react-native'; import PropTypes from 'prop-types'; -const CodeLine = ({ value }) => ( - {value.type === 'PLAIN_TEXT' && value.value} -); +const CodeLine = ({ value }) => {value.type === 'PLAIN_TEXT' && value.value}; CodeLine.propTypes = { value: PropTypes.object diff --git a/app/containers/markdown/MessageBody/Emoji.js b/app/containers/markdown/new/Emoji.js similarity index 79% rename from app/containers/markdown/MessageBody/Emoji.js rename to app/containers/markdown/new/Emoji.js index 275b0a9f9..3fcea2a2c 100644 --- a/app/containers/markdown/MessageBody/Emoji.js +++ b/app/containers/markdown/new/Emoji.js @@ -11,15 +11,7 @@ const Emoji = ({ emojiHandle, style, isBigEmoji }) => { const { theme } = useTheme(); const emojiUnicode = shortnameToUnicode(emojiHandle); return ( - - {emojiUnicode} - + {emojiUnicode} ); }; diff --git a/app/containers/markdown/MessageBody/Heading.js b/app/containers/markdown/new/Heading.js similarity index 71% rename from app/containers/markdown/MessageBody/Heading.js rename to app/containers/markdown/new/Heading.js index 82e781ef5..cd578a5e4 100644 --- a/app/containers/markdown/MessageBody/Heading.js +++ b/app/containers/markdown/new/Heading.js @@ -7,18 +7,14 @@ import { useTheme } from '../../../theme'; const Heading = ({ value, level }) => { const { theme } = useTheme(); - const textStyle = styles[`heading${ level }`]; + const textStyle = styles[`heading${level}`]; return ( <> - {value.map((block) => { + {value.map(block => { switch (block.type) { case 'PLAIN_TEXT': - return ( - - {block.value} - - ); + return {block.value}; default: return null; } diff --git a/app/containers/markdown/MessageBody/Inline.js b/app/containers/markdown/new/Inline.js similarity index 89% rename from app/containers/markdown/MessageBody/Inline.js rename to app/containers/markdown/new/Inline.js index d1ab4400a..5fed842fe 100644 --- a/app/containers/markdown/MessageBody/Inline.js +++ b/app/containers/markdown/new/Inline.js @@ -2,6 +2,8 @@ import React from 'react'; import { Text } from 'react-native'; import PropTypes from 'prop-types'; +import Hashtag from '../Hashtag'; + import Link from './Link'; import Plain from './Plain'; import Bold from './Bold'; @@ -10,14 +12,10 @@ import Italic from './Italic'; import Emoji from './Emoji'; import Mention from './Mention'; import InlineCode from './InlineCode'; -import Hashtag from '../Hashtag'; - -const Inline = ({ - value, mentions, channels, navToRoomInfo, style -}) => ( +const Inline = ({ value, mentions, channels, navToRoomInfo, style }) => ( - {value.map((block) => { + {value.map(block => { switch (block.type) { case 'PLAIN_TEXT': return ; @@ -33,7 +31,7 @@ const Inline = ({ case 'MENTION_USER': return ; case 'EMOJI': - return ; + return ; case 'MENTION_CHANNEL': return ; case 'INLINE_CODE': diff --git a/app/containers/markdown/MessageBody/InlineCode.js b/app/containers/markdown/new/InlineCode.js similarity index 72% rename from app/containers/markdown/MessageBody/InlineCode.js rename to app/containers/markdown/new/InlineCode.js index 051c9dc29..a4fdf6101 100644 --- a/app/containers/markdown/MessageBody/InlineCode.js +++ b/app/containers/markdown/new/InlineCode.js @@ -10,17 +10,17 @@ const InlineCode = ({ value, style }) => { const { theme } = useTheme(); return ( - - {((block) => { + + {(block => { switch (block.type) { case 'PLAIN_TEXT': return block.value; diff --git a/app/containers/markdown/MessageBody/Italic.js b/app/containers/markdown/new/Italic.tsx similarity index 75% rename from app/containers/markdown/MessageBody/Italic.js rename to app/containers/markdown/new/Italic.tsx index f4f24dea6..e26525f6e 100644 --- a/app/containers/markdown/MessageBody/Italic.js +++ b/app/containers/markdown/new/Italic.tsx @@ -1,19 +1,23 @@ /* eslint-disable react/no-array-index-key */ -import React from 'react'; +import React, { FC } from 'react'; import { StyleSheet, Text } from 'react-native'; -import PropTypes from 'prop-types'; +import { Italic as ItalicProps } from '@rocket.chat/message-parser'; import Strike from './Strike'; import Bold from './Bold'; import Plain from './Plain'; +interface IItalicProps { + value: ItalicProps['value']; +} + const styles = StyleSheet.create({ text: { fontStyle: 'italic' } }); -const Italic = ({ value }) => ( +const Italic: FC = ({ value }) => ( {value.map((block, index) => { switch (block.type) { @@ -30,8 +34,4 @@ const Italic = ({ value }) => ( ); -Italic.propTypes = { - value: PropTypes.string -}; - export default Italic; diff --git a/app/containers/markdown/MessageBody/Link.js b/app/containers/markdown/new/Link.js similarity index 89% rename from app/containers/markdown/MessageBody/Link.js rename to app/containers/markdown/new/Link.js index 1e83cd9d0..2f5abc043 100644 --- a/app/containers/markdown/MessageBody/Link.js +++ b/app/containers/markdown/new/Link.js @@ -2,9 +2,6 @@ import React from 'react'; import { Text, Clipboard } from 'react-native'; import PropTypes from 'prop-types'; -import Strike from './Strike'; -import Italic from './Italic'; -import Bold from './Bold'; import styles from '../styles'; import I18n from '../../../i18n'; import { LISTENER } from '../../Toast'; @@ -13,6 +10,10 @@ import openLink from '../../../utils/openLink'; import EventEmitter from '../../../utils/events'; import { themes } from '../../../constants/colors'; +import Strike from './Strike'; +import Italic from './Italic'; +import Bold from './Bold'; + const Link = ({ value }) => { const { theme } = useTheme(); const { src, label } = value; @@ -29,12 +30,8 @@ const Link = ({ value }) => { }; return ( - - {((block) => { + + {(block => { switch (block.type) { case 'PLAIN_TEXT': return block.value; diff --git a/app/containers/markdown/MessageBody/Mention.js b/app/containers/markdown/new/Mention.js similarity index 79% rename from app/containers/markdown/MessageBody/Mention.js rename to app/containers/markdown/new/Mention.js index f3bbed12c..2db987d69 100644 --- a/app/containers/markdown/MessageBody/Mention.js +++ b/app/containers/markdown/new/Mention.js @@ -7,9 +7,7 @@ import { events, logEvent } from '../../../utils/log'; import { useTheme } from '../../../theme'; import { themes } from '../../../constants/colors'; -const Mention = ({ - value: mention, mentions, navToRoomInfo, style -}) => { +const Mention = ({ value: mention, mentions, navToRoomInfo, style }) => { const { theme } = useTheme(); let mentionStyle = []; const notMentionedStyle = [styles.text, { color: themes[theme].bodyText }, ...style]; @@ -43,10 +41,14 @@ const Mention = ({ return ( - {mentionedUser ? mentionedUser.name || mention.value : `@{${ mention }}` } + style={[ + styles.mention, + (mention || mentionedUser) && mentionStyle, + !(mention || mentionedUser) && notMentionedStyle, + ...style + ]} + onPress={handlePress}> + {mentionedUser ? mentionedUser.name || mention.value : `@{${mention}}`} ); }; diff --git a/app/containers/markdown/MessageBody/OrderedList.js b/app/containers/markdown/new/OrderedList.js similarity index 100% rename from app/containers/markdown/MessageBody/OrderedList.js rename to app/containers/markdown/new/OrderedList.js diff --git a/app/containers/markdown/MessageBody/Paragraph.js b/app/containers/markdown/new/Paragraph.js similarity index 63% rename from app/containers/markdown/MessageBody/Paragraph.js rename to app/containers/markdown/new/Paragraph.js index 51d0a38f7..dcc9b8fb2 100644 --- a/app/containers/markdown/MessageBody/Paragraph.js +++ b/app/containers/markdown/new/Paragraph.js @@ -3,9 +3,9 @@ import PropTypes from 'prop-types'; import Inline from './Inline'; -const Paragraph = ({ - value, mentions, channels, navToRoomInfo, style -}) => ; +const Paragraph = ({ value, mentions, channels, navToRoomInfo, style }) => ( + +); Paragraph.propTypes = { value: PropTypes.string, diff --git a/app/containers/markdown/new/Plain.tsx b/app/containers/markdown/new/Plain.tsx new file mode 100644 index 000000000..9e3e93804 --- /dev/null +++ b/app/containers/markdown/new/Plain.tsx @@ -0,0 +1,11 @@ +import React, { FC } from 'react'; +import { Text } from 'react-native'; +import { Plain as PlainProps } from '@rocket.chat/message-parser'; + +interface IPlainProps { + value: PlainProps['value']; +} + +const Plain: FC = ({ value }) => {value}; + +export default Plain; diff --git a/app/containers/markdown/MessageBody/Quote.js b/app/containers/markdown/new/Quote.js similarity index 100% rename from app/containers/markdown/MessageBody/Quote.js rename to app/containers/markdown/new/Quote.js diff --git a/app/containers/markdown/MessageBody/Strike.js b/app/containers/markdown/new/Strike.tsx similarity index 56% rename from app/containers/markdown/MessageBody/Strike.js rename to app/containers/markdown/new/Strike.tsx index 0c6984214..75c4880c4 100644 --- a/app/containers/markdown/MessageBody/Strike.js +++ b/app/containers/markdown/new/Strike.tsx @@ -1,28 +1,32 @@ /* eslint-disable react/no-array-index-key */ -import React from 'react'; +import React, { FC } from 'react'; import { StyleSheet, Text } from 'react-native'; -import PropTypes from 'prop-types'; +import { Strike as StrikeProps } from '@rocket.chat/message-parser'; import Bold from './Bold'; import Italic from './Italic'; import Plain from './Plain'; +interface IStrikeProps { + value: StrikeProps['value']; +} + const styles = StyleSheet.create({ text: { textDecorationLine: 'line-through' } }); -const Strike = ({ value }) => ( +const Strike: FC = ({ value }) => ( - {value.map((block, index) => { + {value.map(block => { switch (block.type) { case 'PLAIN_TEXT': - return ; + return ; case 'BOLD': - return ; + return ; case 'ITALIC': - return ; + return ; default: return null; } @@ -30,8 +34,4 @@ const Strike = ({ value }) => ( ); -Strike.propTypes = { - value: PropTypes.string -}; - export default Strike; diff --git a/app/containers/markdown/MessageBody/UnorderedList.js b/app/containers/markdown/new/UnorderedList.js similarity index 100% rename from app/containers/markdown/MessageBody/UnorderedList.js rename to app/containers/markdown/new/UnorderedList.js diff --git a/app/containers/markdown/MessageBody/index.js b/app/containers/markdown/new/index.js similarity index 96% rename from app/containers/markdown/MessageBody/index.js rename to app/containers/markdown/new/index.js index 6950c2429..cb1a3c9a1 100644 --- a/app/containers/markdown/MessageBody/index.js +++ b/app/containers/markdown/new/index.js @@ -13,9 +13,7 @@ import UnorderedList from './UnorderedList'; const isBigEmoji = tokens => tokens.length === 1 && tokens[0].type === 'BIG_EMOJI'; -const Body = ({ - tokens, mentions, channels, navToRoomInfo, style -}) => { +const Body = ({ tokens, mentions, channels, navToRoomInfo, style }) => { if (isBigEmoji(tokens)) { return ; } diff --git a/package.json b/package.json index 1d4a2ac1c..95f32d7ef 100644 --- a/package.json +++ b/package.json @@ -47,6 +47,7 @@ "@react-navigation/drawer": "5.12.5", "@react-navigation/native": "5.9.4", "@react-navigation/stack": "5.14.5", + "@rocket.chat/message-parser": "^0.29.0", "@rocket.chat/react-native-fast-image": "^8.2.0", "@rocket.chat/sdk": "RocketChat/Rocket.Chat.js.SDK#mobile", "@rocket.chat/ui-kit": "0.13.0", diff --git a/yarn.lock b/yarn.lock index ef839c91b..11e49736c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3203,6 +3203,11 @@ dependencies: eslint-plugin-import "^2.17.2" +"@rocket.chat/message-parser@^0.29.0": + version "0.29.0" + resolved "https://registry.yarnpkg.com/@rocket.chat/message-parser/-/message-parser-0.29.0.tgz#9577f354756653e6271b9fe2290fadafcb5d4293" + integrity sha512-2qEPTNSHeWRCFfxCETqz9Asju6bf5dR98+AQUYwNus5911WW4tuehvrfvoqLYrlYqs4w5Qj6q9m2THCXqN27Gw== + "@rocket.chat/react-native-fast-image@^8.2.0": version "8.2.0" resolved "https://registry.yarnpkg.com/@rocket.chat/react-native-fast-image/-/react-native-fast-image-8.2.0.tgz#4f48858f95f40afcb10b39cee9b1239c150d6c51"