Migrate components to TypeScript and fix styling

This commit is contained in:
Gerzon Z 2021-09-22 19:09:26 -04:00
parent 20d2db9aa3
commit 5edbfe65b6
28 changed files with 326 additions and 295 deletions

View File

@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { StyleProp, Text, TextStyle } from 'react-native';
import { themes } from '../../constants/colors'; import { themes } from '../../constants/colors';
import { useTheme } from '../../theme'; import { useTheme } from '../../theme';
@ -8,8 +8,7 @@ import styles from './styles';
interface IHashtag { interface IHashtag {
hashtag: string; hashtag: string;
navToRoomInfo: Function; navToRoomInfo: Function;
style: []; style: StyleProp<TextStyle>;
theme: string;
channels: { channels: {
name: string; name: string;
_id: number; _id: number;

View File

@ -25,14 +25,18 @@ import { isValidURL } from '../../utils/url';
import { getUserSelector } from '../../selectors/login'; import { getUserSelector } from '../../selectors/login';
import NewMarkdown from './new'; import NewMarkdown from './new';
interface IUser {
_id: string;
username: string;
name: string;
}
type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
interface IMarkdownProps { interface IMarkdownProps {
msg: string; msg: string;
md: [ md: MarkdownAST;
{ mentions: UserMention[];
tokens: MarkdownAST;
mentions: object[];
}
];
getCustomEmoji: Function; getCustomEmoji: Function;
baseUrl: string; baseUrl: string;
username: string; username: string;
@ -45,7 +49,6 @@ interface IMarkdownProps {
name: string; name: string;
_id: number; _id: number;
}[]; }[];
mentions: object[];
user: { user: {
enableMessageParserEarlyAdoption: boolean; enableMessageParserEarlyAdoption: boolean;
}; };

View File

@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { StyleSheet, View } from 'react-native'; import { StyleSheet, View } from 'react-native';
import { BigEmoji as BigEmojiProps } from '@rocket.chat/message-parser'; import { BigEmoji as BigEmojiProps } from '@rocket.chat/message-parser';
@ -14,10 +14,10 @@ const styles = StyleSheet.create({
} }
}); });
const BigEmoji: FC<IBigEmojiProps> = ({ value }) => ( const BigEmoji: React.FC<IBigEmojiProps> = ({ value }) => (
<View style={styles.container}> <View style={styles.container}>
{value.map(block => ( {value.map(block => (
<Emoji emojiHandle={`:${block.value.value}:`} isBigEmoji /> <Emoji value={block.value} isBigEmoji />
))} ))}
</View> </View>
); );

View File

@ -1,8 +1,8 @@
/* eslint-disable react/no-array-index-key */ import React from 'react';
import React, { FC } from 'react';
import { StyleSheet, Text } from 'react-native'; import { StyleSheet, Text } from 'react-native';
import { Bold as BoldProps } from '@rocket.chat/message-parser'; import { Bold as BoldProps } from '@rocket.chat/message-parser';
import sharedStyles from '../../../views/Styles';
import Strike from './Strike'; import Strike from './Strike';
import Italic from './Italic'; import Italic from './Italic';
import Plain from './Plain'; import Plain from './Plain';
@ -13,11 +13,11 @@ interface IBoldProps {
const styles = StyleSheet.create({ const styles = StyleSheet.create({
text: { text: {
fontWeight: 'bold' ...sharedStyles.textBold
} }
}); });
const Bold: FC<IBoldProps> = ({ value }) => ( const Bold: React.FC<IBoldProps> = ({ value }) => (
<Text style={styles.text}> <Text style={styles.text}>
{value.map(block => { {value.map(block => {
switch (block.type) { switch (block.type) {

View File

@ -1,14 +1,18 @@
/* eslint-disable react/no-array-index-key */
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { StyleProp, Text, TextStyle } from 'react-native';
import PropTypes from 'prop-types'; import { Code as CodeProps } from '@rocket.chat/message-parser';
import styles from '../styles'; import styles from '../styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme'; import { useTheme } from '../../../theme';
import CodeLine from './CodeLine'; import CodeLine from './CodeLine';
const Code = ({ value, style }) => { interface ICodeProps {
value: CodeProps['value'];
style: StyleProp<TextStyle>[];
}
const Code: React.FC<ICodeProps> = ({ value, style }) => {
const { theme } = useTheme(); const { theme } = useTheme();
return ( return (
@ -22,10 +26,10 @@ const Code = ({ value, style }) => {
}, },
...style ...style
]}> ]}>
{value.map((block, index) => { {value.map(block => {
switch (block.type) { switch (block.type) {
case 'CODE_LINE': case 'CODE_LINE':
return <CodeLine key={index} value={block.value} />; return <CodeLine value={block.value} />;
default: default:
return null; return null;
} }
@ -34,9 +38,4 @@ const Code = ({ value, style }) => {
); );
}; };
Code.propTypes = {
value: PropTypes.array,
style: PropTypes.object
};
export default Code; export default Code;

View File

@ -1,11 +0,0 @@
import React from 'react';
import { Text } from 'react-native';
import PropTypes from 'prop-types';
const CodeLine = ({ value }) => <Text>{value.type === 'PLAIN_TEXT' && value.value}</Text>;
CodeLine.propTypes = {
value: PropTypes.object
};
export default CodeLine;

View File

@ -0,0 +1,11 @@
import React from 'react';
import { Text } from 'react-native';
import { CodeLine as CodeLineProps } from '@rocket.chat/message-parser';
interface ICodeLineProps {
value: CodeLineProps['value'];
}
const CodeLine: React.FC<ICodeLineProps> = ({ value }) => <Text>{value.type === 'PLAIN_TEXT' && value.value}</Text>;
export default CodeLine;

View File

@ -1,24 +0,0 @@
import React from 'react';
import { Text } from 'react-native';
import PropTypes from 'prop-types';
import shortnameToUnicode from '../../../utils/shortnameToUnicode';
import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
import styles from '../styles';
const Emoji = ({ emojiHandle, style, isBigEmoji }) => {
const { theme } = useTheme();
const emojiUnicode = shortnameToUnicode(emojiHandle);
return (
<Text style={[{ color: themes[theme].bodyText }, isBigEmoji ? styles.textBig : styles.text, style]}>{emojiUnicode}</Text>
);
};
Emoji.propTypes = {
emojiHandle: PropTypes.string,
style: PropTypes.object,
isBigEmoji: PropTypes.bool
};
export default Emoji;

View File

@ -0,0 +1,24 @@
import React from 'react';
import { StyleProp, Text, TextStyle } from 'react-native';
import { Emoji as EmojiProps } from '@rocket.chat/message-parser';
import shortnameToUnicode from '../../../utils/shortnameToUnicode';
import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme';
import styles from '../styles';
interface IEmojiProps {
value: EmojiProps['value'];
style?: StyleProp<TextStyle>;
isBigEmoji?: boolean;
}
const Emoji: React.FC<IEmojiProps> = ({ value, style, isBigEmoji }) => {
const { theme } = useTheme();
const emojiUnicode = shortnameToUnicode(`:${value.value}:`);
return (
<Text style={[{ color: themes[theme!].bodyText }, isBigEmoji ? styles.textBig : styles.text, style]}>{emojiUnicode}</Text>
);
};
export default Emoji;

View File

@ -1,11 +1,17 @@
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import PropTypes from 'prop-types'; import { Heading as HeadingProps } from '@rocket.chat/message-parser';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import styles from '../styles'; import styles from '../styles';
import { useTheme } from '../../../theme'; import { useTheme } from '../../../theme';
const Heading = ({ value, level }) => { interface IHeadingProps {
value: HeadingProps['value'];
level: HeadingProps['level'];
}
const Heading: React.FC<IHeadingProps> = ({ value, level }) => {
const { theme } = useTheme(); const { theme } = useTheme();
const textStyle = styles[`heading${level}`]; const textStyle = styles[`heading${level}`];
@ -23,9 +29,4 @@ const Heading = ({ value, level }) => {
); );
}; };
Heading.propTypes = {
value: PropTypes.string,
level: PropTypes.number
};
export default Heading; export default Heading;

View File

@ -1,9 +1,8 @@
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { StyleProp, Text, ViewStyle } from 'react-native';
import PropTypes from 'prop-types'; import { Paragraph as ParagraphProps } from '@rocket.chat/message-parser';
import Hashtag from '../Hashtag'; import Hashtag from '../Hashtag';
import Link from './Link'; import Link from './Link';
import Plain from './Plain'; import Plain from './Plain';
import Bold from './Bold'; import Bold from './Bold';
@ -13,7 +12,26 @@ import Emoji from './Emoji';
import Mention from './Mention'; import Mention from './Mention';
import InlineCode from './InlineCode'; import InlineCode from './InlineCode';
const Inline = ({ value, mentions, channels, navToRoomInfo, style }) => ( interface IUser {
_id: string;
username: string;
name: string;
}
type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
interface IParagraphProps {
value: ParagraphProps['value'];
mentions: UserMention[];
channels: {
name: string;
_id: number;
}[];
navToRoomInfo: Function;
style: StyleProp<ViewStyle>[];
}
const Inline: React.FC<IParagraphProps> = ({ value, mentions, channels, navToRoomInfo, style }) => (
<Text> <Text>
{value.map(block => { {value.map(block => {
switch (block.type) { switch (block.type) {
@ -26,12 +44,11 @@ const Inline = ({ value, mentions, channels, navToRoomInfo, style }) => (
case 'ITALIC': case 'ITALIC':
return <Italic value={block.value} />; return <Italic value={block.value} />;
case 'LINK': case 'LINK':
// eslint-disable-next-line jsx-a11y/anchor-is-valid
return <Link value={block.value} />; return <Link value={block.value} />;
case 'MENTION_USER': case 'MENTION_USER':
return <Mention value={block.value} navToRoomInfo={navToRoomInfo} mentions={mentions} style={style} />; return <Mention value={block.value} navToRoomInfo={navToRoomInfo} mentions={mentions} style={style} />;
case 'EMOJI': case 'EMOJI':
return <Emoji emojiHandle={`:${block.value.value}:`} />; return <Emoji value={block.value} />;
case 'MENTION_CHANNEL': case 'MENTION_CHANNEL':
return <Hashtag hashtag={block.value.value} navToRoomInfo={navToRoomInfo} channels={channels} style={style} />; return <Hashtag hashtag={block.value.value} navToRoomInfo={navToRoomInfo} channels={channels} style={style} />;
case 'INLINE_CODE': case 'INLINE_CODE':
@ -43,12 +60,4 @@ const Inline = ({ value, mentions, channels, navToRoomInfo, style }) => (
</Text> </Text>
); );
Inline.propTypes = {
value: PropTypes.object,
mentions: PropTypes.array,
channels: PropTypes.array,
navToRoomInfo: PropTypes.func,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
export default Inline; export default Inline;

View File

@ -1,12 +1,17 @@
import React from 'react'; import React from 'react';
import { Text } from 'react-native'; import { StyleProp, Text, TextStyle } from 'react-native';
import PropTypes from 'prop-types'; import { InlineCode as InlineCodeProps } from '@rocket.chat/message-parser';
import styles from '../styles'; import styles from '../styles';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme'; import { useTheme } from '../../../theme';
const InlineCode = ({ value, style }) => { interface IInlineCodeProps {
value: InlineCodeProps['value'];
style: StyleProp<TextStyle>[];
}
const InlineCode: React.FC<IInlineCodeProps> = ({ value, style }) => {
const { theme } = useTheme(); const { theme } = useTheme();
return ( return (
@ -32,9 +37,4 @@ const InlineCode = ({ value, style }) => {
); );
}; };
InlineCode.propTypes = {
value: PropTypes.object,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
export default InlineCode; export default InlineCode;

View File

@ -1,5 +1,4 @@
/* eslint-disable react/no-array-index-key */ import React from 'react';
import React, { FC } from 'react';
import { StyleSheet, Text } from 'react-native'; import { StyleSheet, Text } from 'react-native';
import { Italic as ItalicProps } from '@rocket.chat/message-parser'; import { Italic as ItalicProps } from '@rocket.chat/message-parser';
@ -17,16 +16,16 @@ const styles = StyleSheet.create({
} }
}); });
const Italic: FC<IItalicProps> = ({ value }) => ( const Italic: React.FC<IItalicProps> = ({ value }) => (
<Text style={styles.text}> <Text style={styles.text}>
{value.map((block, index) => { {value.map(block => {
switch (block.type) { switch (block.type) {
case 'PLAIN_TEXT': case 'PLAIN_TEXT':
return <Plain key={index} value={block.value} />; return <Plain value={block.value} />;
case 'STRIKE': case 'STRIKE':
return <Strike key={index} value={block.value} />; return <Strike value={block.value} />;
case 'BOLD': case 'BOLD':
return <Bold key={index} value={block.value} />; return <Bold value={block.value} />;
default: default:
return null; return null;
} }

View File

@ -1,6 +1,6 @@
import React from 'react'; import React from 'react';
import { Text, Clipboard } from 'react-native'; import { Text, Clipboard } from 'react-native';
import PropTypes from 'prop-types'; import { Link as LinkProps } from '@rocket.chat/message-parser';
import styles from '../styles'; import styles from '../styles';
import I18n from '../../../i18n'; import I18n from '../../../i18n';
@ -9,12 +9,15 @@ import { useTheme } from '../../../theme';
import openLink from '../../../utils/openLink'; import openLink from '../../../utils/openLink';
import EventEmitter from '../../../utils/events'; import EventEmitter from '../../../utils/events';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import Strike from './Strike'; import Strike from './Strike';
import Italic from './Italic'; import Italic from './Italic';
import Bold from './Bold'; import Bold from './Bold';
const Link = ({ value }) => { interface ILinkProps {
value: LinkProps['value'];
}
const Link: React.FC<ILinkProps> = ({ value }) => {
const { theme } = useTheme(); const { theme } = useTheme();
const { src, label } = value; const { src, label } = value;
const handlePress = () => { const handlePress = () => {
@ -49,11 +52,4 @@ const Link = ({ value }) => {
); );
}; };
Link.propTypes = {
value: {
src: PropTypes.string,
label: PropTypes.string
}
};
export default Link; export default Link;

View File

@ -1,63 +0,0 @@
import React from 'react';
import { Text } from 'react-native';
import PropTypes from 'prop-types';
import styles from '../styles';
import { events, logEvent } from '../../../utils/log';
import { useTheme } from '../../../theme';
import { themes } from '../../../constants/colors';
const Mention = ({ value: mention, mentions, navToRoomInfo, style }) => {
const { theme } = useTheme();
let mentionStyle = [];
const notMentionedStyle = [styles.text, { color: themes[theme].bodyText }, ...style];
const mentionedUser = mentions.find(mentioned => mentioned.username === mention.value);
if (mention === 'all' || mention === 'here') {
mentionStyle = [
{
color: themes[theme].mentionGroupColor
},
...style
];
} else if (mention === mentionedUser) {
mentionStyle = {
color: themes[theme].mentionMeColor
};
} else {
mentionStyle = {
color: themes[theme].mentionOtherColor
};
}
const handlePress = () => {
logEvent(events.ROOM_MENTION_GO_USER_INFO);
const navParam = {
t: 'd',
rid: mentionedUser && mentionedUser._id
};
navToRoomInfo(navParam);
};
return (
<Text
style={[
styles.mention,
(mention || mentionedUser) && mentionStyle,
!(mention || mentionedUser) && notMentionedStyle,
...style
]}
onPress={handlePress}>
{mentionedUser ? mentionedUser.name || mention.value : `@{${mention}}`}
</Text>
);
};
Mention.propTypes = {
value: PropTypes.string,
mentions: PropTypes.array,
navToRoomInfo: PropTypes.func,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
export default Mention;

View File

@ -0,0 +1,66 @@
import React from 'react';
import { StyleProp, Text, TextStyle, ViewStyle } from 'react-native';
import { UserMention as UserMentionProps } from '@rocket.chat/message-parser';
import styles from '../styles';
import { events, logEvent } from '../../../utils/log';
import { useTheme } from '../../../theme';
import { themes } from '../../../constants/colors';
interface IUser {
_id: string;
username: string;
name: string;
}
type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
interface IMentionProps {
value: UserMentionProps['value'];
mentions: UserMention[];
navToRoomInfo: Function;
style: StyleProp<ViewStyle>[];
}
const Mention: React.FC<IMentionProps> = ({ value: { value: mention }, mentions, navToRoomInfo, style }) => {
const { theme } = useTheme();
let mentionStyle: StyleProp<TextStyle>;
const notMentionedStyle = [styles.text, { color: themes[theme].bodyText }, ...style];
const mentioned = mentions.find(mentioned => mentioned.username === mention);
if (mention === 'all' || mention === 'here') {
mentionStyle = [
{
color: themes[theme].mentionGroupColor
},
...style
];
} else if (mentioned) {
mentionStyle = {
color: themes[theme].mentionMeColor
};
} else {
mentionStyle = {
color: themes[theme].mentionOtherColor
};
}
const handlePress = () => {
logEvent(events.ROOM_MENTION_GO_USER_INFO);
const navParam = {
t: 'd',
rid: mentioned && mentioned._id
};
navToRoomInfo(navParam);
};
return (
<Text
style={[styles.mention, (mention || mentioned) && mentionStyle, !(mention || mentioned) && notMentionedStyle, ...style]}
onPress={handlePress}>
{mentioned ? mentioned.name || mention : `@{${mention}}`}
</Text>
);
};
export default Mention;

View File

@ -1,23 +1,23 @@
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
import React from 'react'; import React from 'react';
import { View, Text } from 'react-native'; import { View, Text } from 'react-native';
import PropTypes from 'prop-types'; import { OrderedList as OrderedListProps } from '@rocket.chat/message-parser';
import Inline from './Inline'; import Inline from './Inline';
const OrderedList = React.memo(({ value }) => ( interface IOrderedListProps {
value: OrderedListProps['value'];
}
const OrderedList: React.FC<IOrderedListProps> = React.memo(({ value }) => (
<> <>
{value.map((item, index) => ( {value.map((item, index) => (
<View style={{ flexDirection: 'row' }}> <View style={{ flexDirection: 'row' }}>
<Text>{index + 1}. </Text> <Text>{index + 1}. </Text>
<Inline key={index} value={item.value} /> <Inline value={item.value} />
</View> </View>
))} ))}
</> </>
)); ));
OrderedList.propTypes = {
value: PropTypes.array
};
export default OrderedList; export default OrderedList;

View File

@ -1,18 +0,0 @@
import React from 'react';
import PropTypes from 'prop-types';
import Inline from './Inline';
const Paragraph = ({ value, mentions, channels, navToRoomInfo, style }) => (
<Inline value={value} mentions={mentions} channels={channels} navToRoomInfo={navToRoomInfo} style={style} />
);
Paragraph.propTypes = {
value: PropTypes.string,
mentions: PropTypes.array,
channels: PropTypes.array,
navToRoomInfo: PropTypes.func,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
export default Paragraph;

View File

@ -0,0 +1,30 @@
import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { Paragraph as ParagraphProps } from '@rocket.chat/message-parser';
import Inline from './Inline';
interface IUser {
_id: string;
username: string;
name: string;
}
type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
interface IParagraphProps {
value: ParagraphProps['value'];
mentions: UserMention[];
channels: {
name: string;
_id: number;
}[];
navToRoomInfo: Function;
style: StyleProp<ViewStyle>;
}
const Paragraph: React.FC<IParagraphProps> = ({ value, mentions, channels, navToRoomInfo, style }) => (
<Inline value={value} mentions={mentions} channels={channels} navToRoomInfo={navToRoomInfo} style={style} />
);
export default Paragraph;

View File

@ -1,4 +1,4 @@
import React, { FC } from 'react'; import React from 'react';
import { Text } from 'react-native'; import { Text } from 'react-native';
import { Plain as PlainProps } from '@rocket.chat/message-parser'; import { Plain as PlainProps } from '@rocket.chat/message-parser';
@ -6,6 +6,6 @@ interface IPlainProps {
value: PlainProps['value']; value: PlainProps['value'];
} }
const Plain: FC<IPlainProps> = ({ value }) => <Text accessibilityLabel={value}>{value}</Text>; const Plain: React.FC<IPlainProps> = ({ value }) => <Text accessibilityLabel={value}>{value}</Text>;
export default Plain; export default Plain;

View File

@ -1,21 +1,26 @@
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
import React from 'react'; import React from 'react';
import { View } from 'react-native'; import { View } from 'react-native';
import PropTypes from 'prop-types'; import { Quote as QuoteProps } from '@rocket.chat/message-parser';
import { themes } from '../../../constants/colors'; import { themes } from '../../../constants/colors';
import { useTheme } from '../../../theme'; import { useTheme } from '../../../theme';
import styles from '../styles'; import styles from '../styles';
import Paragraph from './Paragraph'; import Paragraph from './Paragraph';
const Quote = ({ value }) => { interface IQuoteProps {
value: QuoteProps['value'];
}
const Quote: React.FC<IQuoteProps> = ({ value }) => {
const { theme } = useTheme(); const { theme } = useTheme();
return ( return (
<> <>
<View style={styles.container}> <View style={styles.container}>
<View style={[styles.quote, { backgroundColor: themes[theme].borderColor }]} /> <View style={[styles.quote, { backgroundColor: themes[theme].borderColor }]} />
<View style={styles.childContainer}> <View style={styles.childContainer}>
{value.map((item, index) => ( {value.map(item => (
<Paragraph key={index} value={item.value} mentions={[]} /> <Paragraph value={item.value} mentions={[]} />
))} ))}
</View> </View>
</View> </View>
@ -23,8 +28,4 @@ const Quote = ({ value }) => {
); );
}; };
Quote.propTypes = {
value: PropTypes.string
};
export default Quote; export default Quote;

View File

@ -1,5 +1,5 @@
/* eslint-disable react/no-array-index-key */ /* eslint-disable react/no-array-index-key */
import React, { FC } from 'react'; import React from 'react';
import { StyleSheet, Text } from 'react-native'; import { StyleSheet, Text } from 'react-native';
import { Strike as StrikeProps } from '@rocket.chat/message-parser'; import { Strike as StrikeProps } from '@rocket.chat/message-parser';
@ -17,7 +17,7 @@ const styles = StyleSheet.create({
} }
}); });
const Strike: FC<IStrikeProps> = ({ value }) => ( const Strike: React.FC<IStrikeProps> = ({ value }) => (
<Text style={styles.text}> <Text style={styles.text}>
{value.map(block => { {value.map(block => {
switch (block.type) { switch (block.type) {

View File

@ -1,18 +0,0 @@
/* eslint-disable react/no-array-index-key */
import React from 'react';
import PropTypes from 'prop-types';
import Inline from './Inline';
const UnorderedList = React.memo(({ value }) => (
<>
{value.map((item, index) => (
<Inline key={index} value={item.value} />
))}
</>
));
UnorderedList.propTypes = {
value: PropTypes.array
};
export default UnorderedList;

View File

@ -0,0 +1,18 @@
import React from 'react';
import { UnorderedList as UnorderedListProps } from '@rocket.chat/message-parser';
import Inline from './Inline';
interface IUnorderedListProps {
value: UnorderedListProps['value'];
}
const UnorderedList: React.FC<IUnorderedListProps> = ({ value }) => (
<>
{value.map(item => (
<Inline value={item.value} />
))}
</>
);
export default UnorderedList;

View File

@ -1,67 +0,0 @@
/* eslint-disable react/no-array-index-key */
import React from 'react';
import PropTypes from 'prop-types';
import Quote from './Quote';
import Paragraph from './Paragraph';
import Heading from './Heading';
import Code from './Code';
import Link from './Link';
import BigEmoji from './BigEmoji';
import OrderedList from './OrderedList';
import UnorderedList from './UnorderedList';
const isBigEmoji = tokens => tokens.length === 1 && tokens[0].type === 'BIG_EMOJI';
const Body = ({ tokens, mentions, channels, navToRoomInfo, style }) => {
if (isBigEmoji(tokens)) {
return <BigEmoji value={tokens[0].value} />;
}
return (
<>
{tokens.map((block, index) => {
switch (block.type) {
case 'UNORDERED_LIST':
return <UnorderedList key={index} value={block.value} />;
case 'ORDERED_LIST':
return <OrderedList key={index} value={block.value} />;
case 'TASK':
return <OrderedList key={index} value={block.value} />;
case 'QUOTE':
return <Quote key={index} value={block.value} />;
case 'PARAGRAPH':
return (
<Paragraph
key={index}
value={block.value}
navToRoomInfo={navToRoomInfo}
channels={channels}
mentions={mentions}
style={style}
/>
);
case 'CODE':
return <Code key={index} value={block.value} style={style} />;
case 'LINK':
// eslint-disable-next-line jsx-a11y/anchor-is-valid
return <Link key={index} value={block.value} />;
case 'HEADING':
return <Heading key={index} value={block.value} level={block.level} />;
default:
return null;
}
})}
</>
);
};
Body.propTypes = {
tokens: PropTypes.array,
mentions: PropTypes.array,
channels: PropTypes.array,
navToRoomInfo: PropTypes.func,
style: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
export default Body;

View File

@ -0,0 +1,72 @@
import React from 'react';
import { StyleProp, ViewStyle } from 'react-native';
import { MarkdownAST, BigEmoji as BigEmojiProps } from '@rocket.chat/message-parser';
import Quote from './Quote';
import Paragraph from './Paragraph';
import Heading from './Heading';
import Code from './Code';
import BigEmoji from './BigEmoji';
import OrderedList from './OrderedList';
import UnorderedList from './UnorderedList';
interface IUser {
_id: string;
username: string;
name: string;
}
type UserMention = Pick<IUser, '_id' | 'username' | 'name'>;
interface IBodyProps {
tokens: MarkdownAST;
mentions: UserMention[];
channels: {
name: string;
_id: number;
}[];
navToRoomInfo: Function;
style: StyleProp<ViewStyle>[];
}
const isBigEmoji = (tokens: MarkdownAST): tokens is [BigEmojiProps] => tokens.length === 1 && tokens[0].type === 'BIG_EMOJI';
const Body: React.FC<IBodyProps> = ({ tokens, mentions, channels, navToRoomInfo, style }) => {
if (isBigEmoji(tokens)) {
return <BigEmoji value={tokens[0].value} />;
}
return (
<>
{tokens.map(block => {
switch (block.type) {
case 'UNORDERED_LIST':
return <UnorderedList value={block.value} />;
case 'ORDERED_LIST':
return <OrderedList value={block.value} />;
case 'TASKS':
return <OrderedList value={block.value} />;
case 'QUOTE':
return <Quote value={block.value} />;
case 'PARAGRAPH':
return (
<Paragraph
value={block.value}
navToRoomInfo={navToRoomInfo}
channels={channels}
mentions={mentions}
style={style}
/>
);
case 'CODE':
return <Code value={block.value} style={style} />;
case 'HEADING':
return <Heading value={block.value} level={block.level} />;
default:
return null;
}
})}
</>
);
};
export default Body;

View File

@ -103,6 +103,9 @@ const Content = React.memo(
if (prevProps.isIgnored !== nextProps.isIgnored) { if (prevProps.isIgnored !== nextProps.isIgnored) {
return false; return false;
} }
if (!dequal(prevProps.md, nextProps.md)) {
return false;
}
if (!dequal(prevProps.mentions, nextProps.mentions)) { if (!dequal(prevProps.mentions, nextProps.mentions)) {
return false; return false;
} }

View File

@ -772,5 +772,6 @@
"Converting_Team_To_Channel": "Converting Team to Channel", "Converting_Team_To_Channel": "Converting Team to Channel",
"Select_Team_Channels_To_Delete": "Select the Teams Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.", "Select_Team_Channels_To_Delete": "Select the Teams Channels you would like to delete, the ones you do not select will be moved to the Workspace. \n\nNotice that public Channels will be public and visible to everyone.",
"You_are_converting_the_team": "You are converting this Team to a Channel", "You_are_converting_the_team": "You are converting this Team to a Channel",
"creating_discussion": "creating discussion" "creating_discussion": "creating discussion",
"Enable_Message_Parser": "Enable Message Parser"
} }