[IMPROVE] migrate all markdown container files
This commit is contained in:
parent
1c7ae63ac1
commit
a557d7f5d2
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Text } from 'react-native';
|
import { Text } from 'react-native';
|
||||||
|
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
@ -7,9 +6,19 @@ import { themes } from '../../constants/colors';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { logEvent, events } from '../../utils/log';
|
import { logEvent, events } from '../../utils/log';
|
||||||
|
|
||||||
|
interface IAtMention {
|
||||||
|
mention: string;
|
||||||
|
username: string;
|
||||||
|
navToRoomInfo: Function;
|
||||||
|
style: any;
|
||||||
|
useRealName: boolean;
|
||||||
|
theme: string;
|
||||||
|
mentions: any;
|
||||||
|
}
|
||||||
|
|
||||||
const AtMention = React.memo(({
|
const AtMention = React.memo(({
|
||||||
mention, mentions, username, navToRoomInfo, style = [], useRealName, theme
|
mention, mentions, username, navToRoomInfo, style = [], useRealName, theme
|
||||||
}) => {
|
}: IAtMention) => {
|
||||||
if (mention === 'all' || mention === 'here') {
|
if (mention === 'all' || mention === 'here') {
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
|
@ -36,7 +45,7 @@ const AtMention = React.memo(({
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const user = mentions?.find?.(m => m && m.username === mention);
|
const user = mentions?.find?.((m: any) => m && m.username === mention);
|
||||||
|
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
logEvent(events.ROOM_MENTION_GO_USER_INFO);
|
logEvent(events.ROOM_MENTION_GO_USER_INFO);
|
||||||
|
@ -65,14 +74,4 @@ const AtMention = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
AtMention.propTypes = {
|
|
||||||
mention: PropTypes.string,
|
|
||||||
username: PropTypes.string,
|
|
||||||
navToRoomInfo: PropTypes.func,
|
|
||||||
style: PropTypes.array,
|
|
||||||
useRealName: PropTypes.bool,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
|
|
||||||
};
|
|
||||||
|
|
||||||
export default AtMention;
|
export default AtMention;
|
|
@ -1,12 +1,16 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
|
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
const BlockQuote = React.memo(({ children, theme }) => (
|
interface IBlockQuote {
|
||||||
|
children: JSX.Element;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BlockQuote = React.memo(({ children, theme }: IBlockQuote) => (
|
||||||
<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}>
|
||||||
|
@ -15,9 +19,4 @@ const BlockQuote = React.memo(({ children, theme }) => (
|
||||||
</View>
|
</View>
|
||||||
));
|
));
|
||||||
|
|
||||||
BlockQuote.propTypes = {
|
|
||||||
children: PropTypes.node.isRequired,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default BlockQuote;
|
export default BlockQuote;
|
|
@ -1,4 +1,3 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text } from 'react-native';
|
import { Text } from 'react-native';
|
||||||
|
|
||||||
|
@ -6,9 +5,20 @@ import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
const Hashtag = React.memo(({
|
export type TChannel = {
|
||||||
hashtag, channels, navToRoomInfo, style = [], theme
|
name: string;
|
||||||
}) => {
|
_id: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface IHashtag {
|
||||||
|
hashtag: string;
|
||||||
|
navToRoomInfo: Function;
|
||||||
|
style: [];
|
||||||
|
theme: string;
|
||||||
|
channels: TChannel[];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Hashtag = React.memo(({ hashtag, channels, navToRoomInfo, style = [], theme }: IHashtag) => {
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
const index = channels.findIndex(channel => channel.name === hashtag);
|
const index = channels.findIndex(channel => channel.name === hashtag);
|
||||||
const navParam = {
|
const navParam = {
|
||||||
|
@ -40,12 +50,4 @@ const Hashtag = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Hashtag.propTypes = {
|
|
||||||
hashtag: PropTypes.string,
|
|
||||||
navToRoomInfo: PropTypes.func,
|
|
||||||
style: PropTypes.array,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Hashtag;
|
export default Hashtag;
|
|
@ -1,5 +1,4 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import { Text, Clipboard } from 'react-native';
|
import { Text, Clipboard } from 'react-native';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -9,9 +8,14 @@ import EventEmitter from '../../utils/events';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import openLink from '../../utils/openLink';
|
import openLink from '../../utils/openLink';
|
||||||
|
|
||||||
const Link = React.memo(({
|
interface ILink {
|
||||||
children, link, theme, onLinkPress
|
children: JSX.Element;
|
||||||
}) => {
|
link: string;
|
||||||
|
theme: string;
|
||||||
|
onLinkPress: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Link = React.memo(({ children, link, theme, onLinkPress }: ILink) => {
|
||||||
const handlePress = () => {
|
const handlePress = () => {
|
||||||
if (!link) {
|
if (!link) {
|
||||||
return;
|
return;
|
||||||
|
@ -40,11 +44,4 @@ const Link = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Link.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
link: PropTypes.string,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
onLinkPress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Link;
|
export default Link;
|
|
@ -1,12 +1,18 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
|
||||||
const List = React.memo(({
|
interface IList {
|
||||||
children, ordered, start, tight, numberOfLines = 0
|
children: JSX.Element;
|
||||||
}) => {
|
ordered: boolean;
|
||||||
|
start: number;
|
||||||
|
tight: boolean;
|
||||||
|
numberOfLines: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
const List = React.memo(({ children, ordered, start = 1, tight, numberOfLines = 0 }: IList) => {
|
||||||
let bulletWidth = 15;
|
let bulletWidth = 15;
|
||||||
|
|
||||||
if (ordered) {
|
if (ordered) {
|
||||||
|
// @ts-ignore
|
||||||
const lastNumber = (start + children.length) - 1;
|
const lastNumber = (start + children.length) - 1;
|
||||||
bulletWidth = (9 * lastNumber.toString().length) + 7;
|
bulletWidth = (9 * lastNumber.toString().length) + 7;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +23,7 @@ const List = React.memo(({
|
||||||
items = items.slice(0, numberOfLines);
|
items = items.slice(0, numberOfLines);
|
||||||
}
|
}
|
||||||
|
|
||||||
const _children = items.map((child, index) => React.cloneElement(child, {
|
const _children = items.map((child: any, index: number) => React.cloneElement(child, {
|
||||||
bulletWidth,
|
bulletWidth,
|
||||||
ordered,
|
ordered,
|
||||||
tight,
|
tight,
|
||||||
|
@ -31,16 +37,4 @@ const List = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
List.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
ordered: PropTypes.bool,
|
|
||||||
start: PropTypes.number,
|
|
||||||
tight: PropTypes.bool,
|
|
||||||
numberOfLines: PropTypes.number
|
|
||||||
};
|
|
||||||
|
|
||||||
List.defaultProps = {
|
|
||||||
start: 1
|
|
||||||
};
|
|
||||||
|
|
||||||
export default List;
|
export default List;
|
|
@ -1,10 +1,5 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import { StyleSheet, Text, View } from 'react-native';
|
||||||
import {
|
|
||||||
StyleSheet,
|
|
||||||
Text,
|
|
||||||
View
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
|
@ -22,9 +17,19 @@ const style = StyleSheet.create({
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
interface IListItem {
|
||||||
|
children: JSX.Element;
|
||||||
|
bulletWidth: number;
|
||||||
|
level: number;
|
||||||
|
ordered: boolean;
|
||||||
|
continue: boolean;
|
||||||
|
theme: string;
|
||||||
|
index: number;
|
||||||
|
}
|
||||||
|
|
||||||
const ListItem = React.memo(({
|
const ListItem = React.memo(({
|
||||||
children, level, bulletWidth, continue: _continue, ordered, index, theme
|
children, level, bulletWidth, continue: _continue, ordered, index, theme
|
||||||
}) => {
|
}: IListItem) => {
|
||||||
let bullet;
|
let bullet;
|
||||||
if (_continue) {
|
if (_continue) {
|
||||||
bullet = '';
|
bullet = '';
|
||||||
|
@ -50,14 +55,4 @@ const ListItem = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
ListItem.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
bulletWidth: PropTypes.number,
|
|
||||||
level: PropTypes.number,
|
|
||||||
ordered: PropTypes.bool,
|
|
||||||
continue: PropTypes.bool,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
index: PropTypes.number
|
|
||||||
};
|
|
||||||
|
|
||||||
export default ListItem;
|
export default ListItem;
|
|
@ -1,11 +1,5 @@
|
||||||
import { PropTypes } from 'prop-types';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import {
|
import { ScrollView, TouchableOpacity, View, Text } from 'react-native';
|
||||||
ScrollView,
|
|
||||||
TouchableOpacity,
|
|
||||||
View,
|
|
||||||
Text
|
|
||||||
} from 'react-native';
|
|
||||||
|
|
||||||
import { CELL_WIDTH } from './TableCell';
|
import { CELL_WIDTH } from './TableCell';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
@ -13,20 +7,24 @@ import Navigation from '../../lib/Navigation';
|
||||||
import I18n from '../../i18n';
|
import I18n from '../../i18n';
|
||||||
import { themes } from '../../constants/colors';
|
import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
|
interface ITable {
|
||||||
|
children: JSX.Element;
|
||||||
|
numColumns: number;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
const MAX_HEIGHT = 300;
|
const MAX_HEIGHT = 300;
|
||||||
|
|
||||||
const Table = React.memo(({
|
const Table = React.memo(({ children, numColumns, theme }: ITable) => {
|
||||||
children, numColumns, theme
|
|
||||||
}) => {
|
|
||||||
const getTableWidth = () => numColumns * CELL_WIDTH;
|
const getTableWidth = () => numColumns * CELL_WIDTH;
|
||||||
|
|
||||||
const renderRows = (drawExtraBorders = true) => {
|
const renderRows = (drawExtraBorders: boolean = true) => {
|
||||||
const tableStyle = [styles.table, { borderColor: themes[theme].borderColor }];
|
const tableStyle = [styles.table, { borderColor: themes[theme].borderColor }];
|
||||||
if (drawExtraBorders) {
|
if (drawExtraBorders) {
|
||||||
tableStyle.push(styles.tableExtraBorders);
|
tableStyle.push(styles.tableExtraBorders);
|
||||||
}
|
}
|
||||||
|
|
||||||
const rows = React.Children.toArray(children);
|
const rows: any = React.Children.toArray(children);
|
||||||
rows[rows.length - 1] = React.cloneElement(rows[rows.length - 1], {
|
rows[rows.length - 1] = React.cloneElement(rows[rows.length - 1], {
|
||||||
isLastRow: true
|
isLastRow: true
|
||||||
});
|
});
|
||||||
|
@ -55,10 +53,4 @@ const Table = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Table.propTypes = {
|
|
||||||
children: PropTypes.node.isRequired,
|
|
||||||
numColumns: PropTypes.number.isRequired,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Table;
|
export default Table;
|
|
@ -1,4 +1,3 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Text, View } from 'react-native';
|
import { Text, View } from 'react-native';
|
||||||
|
|
||||||
|
@ -6,11 +5,16 @@ import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
|
interface ITableCell {
|
||||||
|
align: '' | 'left' | 'center' | 'right';
|
||||||
|
children: JSX.Element;
|
||||||
|
isLastCell: boolean;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
export const CELL_WIDTH = 100;
|
export const CELL_WIDTH = 100;
|
||||||
|
|
||||||
const TableCell = React.memo(({
|
const TableCell = React.memo(({ isLastCell, align, children, theme }: ITableCell) => {
|
||||||
isLastCell, align, children, theme
|
|
||||||
}) => {
|
|
||||||
const cellStyle = [styles.cell, { borderColor: themes[theme].borderColor }];
|
const cellStyle = [styles.cell, { borderColor: themes[theme].borderColor }];
|
||||||
if (!isLastCell) {
|
if (!isLastCell) {
|
||||||
cellStyle.push(styles.cellRightBorder);
|
cellStyle.push(styles.cellRightBorder);
|
||||||
|
@ -32,11 +36,4 @@ const TableCell = React.memo(({
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
TableCell.propTypes = {
|
|
||||||
align: PropTypes.oneOf(['', 'left', 'center', 'right']),
|
|
||||||
children: PropTypes.node,
|
|
||||||
isLastCell: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableCell;
|
export default TableCell;
|
|
@ -1,4 +1,3 @@
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { View } from 'react-native';
|
import { View } from 'react-native';
|
||||||
|
|
||||||
|
@ -6,15 +5,19 @@ import { themes } from '../../constants/colors';
|
||||||
|
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
|
|
||||||
const TableRow = React.memo(({
|
interface ITableRow {
|
||||||
isLastRow, children: _children, theme
|
children: JSX.Element;
|
||||||
}) => {
|
isLastRow: boolean;
|
||||||
|
theme: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const TableRow = React.memo(({ isLastRow, children: _children, theme }: ITableRow) => {
|
||||||
const rowStyle = [styles.row, { borderColor: themes[theme].borderColor }];
|
const rowStyle = [styles.row, { borderColor: themes[theme].borderColor }];
|
||||||
if (!isLastRow) {
|
if (!isLastRow) {
|
||||||
rowStyle.push(styles.rowBottomBorder);
|
rowStyle.push(styles.rowBottomBorder);
|
||||||
}
|
}
|
||||||
|
|
||||||
const children = React.Children.toArray(_children);
|
const children: any = React.Children.toArray(_children);
|
||||||
children[children.length - 1] = React.cloneElement(children[children.length - 1], {
|
children[children.length - 1] = React.cloneElement(children[children.length - 1], {
|
||||||
isLastCell: true
|
isLastCell: true
|
||||||
});
|
});
|
||||||
|
@ -22,10 +25,4 @@ const TableRow = React.memo(({
|
||||||
return <View style={rowStyle}>{children}</View>;
|
return <View style={rowStyle}>{children}</View>;
|
||||||
});
|
});
|
||||||
|
|
||||||
TableRow.propTypes = {
|
|
||||||
children: PropTypes.node,
|
|
||||||
isLastRow: PropTypes.bool,
|
|
||||||
theme: PropTypes.string
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TableRow;
|
export default TableRow;
|
|
@ -2,7 +2,6 @@ import React, { PureComponent } from 'react';
|
||||||
import { Text, Image } from 'react-native';
|
import { Text, Image } from 'react-native';
|
||||||
import { Parser, Node } from 'commonmark';
|
import { Parser, Node } from 'commonmark';
|
||||||
import Renderer from 'commonmark-react-renderer';
|
import Renderer from 'commonmark-react-renderer';
|
||||||
import PropTypes from 'prop-types';
|
|
||||||
import removeMarkdown from 'remove-markdown';
|
import removeMarkdown from 'remove-markdown';
|
||||||
|
|
||||||
import shortnameToUnicode from '../../utils/shortnameToUnicode';
|
import shortnameToUnicode from '../../utils/shortnameToUnicode';
|
||||||
|
@ -13,7 +12,7 @@ import MarkdownLink from './Link';
|
||||||
import MarkdownList from './List';
|
import MarkdownList from './List';
|
||||||
import MarkdownListItem from './ListItem';
|
import MarkdownListItem from './ListItem';
|
||||||
import MarkdownAtMention from './AtMention';
|
import MarkdownAtMention from './AtMention';
|
||||||
import MarkdownHashtag from './Hashtag';
|
import MarkdownHashtag, {TChannel} from './Hashtag';
|
||||||
import MarkdownBlockQuote from './BlockQuote';
|
import MarkdownBlockQuote from './BlockQuote';
|
||||||
import MarkdownEmoji from './Emoji';
|
import MarkdownEmoji from './Emoji';
|
||||||
import MarkdownTable from './Table';
|
import MarkdownTable from './Table';
|
||||||
|
@ -24,8 +23,32 @@ import mergeTextNodes from './mergeTextNodes';
|
||||||
import styles from './styles';
|
import styles from './styles';
|
||||||
import { isValidURL } from '../../utils/url';
|
import { isValidURL } from '../../utils/url';
|
||||||
|
|
||||||
|
interface IMarkdownProps {
|
||||||
|
msg: string;
|
||||||
|
getCustomEmoji: Function;
|
||||||
|
baseUrl: string;
|
||||||
|
username: string;
|
||||||
|
tmid: string;
|
||||||
|
isEdited: boolean;
|
||||||
|
numberOfLines: number;
|
||||||
|
customEmojis: boolean;
|
||||||
|
useRealName: boolean;
|
||||||
|
channels: TChannel[];
|
||||||
|
mentions: object[];
|
||||||
|
navToRoomInfo: Function;
|
||||||
|
preview: boolean;
|
||||||
|
theme: string;
|
||||||
|
testID: string;
|
||||||
|
style: any;
|
||||||
|
onLinkPress: Function;
|
||||||
|
}
|
||||||
|
|
||||||
|
type TLiteral = {
|
||||||
|
literal: string;
|
||||||
|
}
|
||||||
|
|
||||||
// Support <http://link|Text>
|
// Support <http://link|Text>
|
||||||
const formatText = text => text.replace(
|
const formatText = (text: string) => text.replace(
|
||||||
new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'),
|
new RegExp('(?:<|<)((?:https|http):\\/\\/[^\\|]+)\\|(.+?)(?=>|>)(?:>|>)', 'gm'),
|
||||||
(match, url, title) => `[${ title }](${ url })`
|
(match, url, title) => `[${ title }](${ url })`
|
||||||
);
|
);
|
||||||
|
@ -36,18 +59,18 @@ const emojiRanges = [
|
||||||
' |\n' // allow spaces and line breaks
|
' |\n' // allow spaces and line breaks
|
||||||
].join('|');
|
].join('|');
|
||||||
|
|
||||||
const removeSpaces = str => str && str.replace(/\s/g, '');
|
const removeSpaces = (str: string) => str && str.replace(/\s/g, '');
|
||||||
|
|
||||||
const removeAllEmoji = str => str.replace(new RegExp(emojiRanges, 'g'), '');
|
const removeAllEmoji = (str: string) => str.replace(new RegExp(emojiRanges, 'g'), '');
|
||||||
|
|
||||||
const isOnlyEmoji = (str) => {
|
const isOnlyEmoji = (str: string) => {
|
||||||
str = removeSpaces(str);
|
str = removeSpaces(str);
|
||||||
return !removeAllEmoji(str).length;
|
return !removeAllEmoji(str).length;
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeOneEmoji = str => str.replace(new RegExp(emojiRanges), '');
|
const removeOneEmoji = (str: string) => str.replace(new RegExp(emojiRanges), '');
|
||||||
|
|
||||||
const emojiCount = (str) => {
|
const emojiCount = (str: string) => {
|
||||||
str = removeSpaces(str);
|
str = removeSpaces(str);
|
||||||
let oldLength = 0;
|
let oldLength = 0;
|
||||||
let counter = 0;
|
let counter = 0;
|
||||||
|
@ -65,28 +88,11 @@ const emojiCount = (str) => {
|
||||||
|
|
||||||
const parser = new Parser();
|
const parser = new Parser();
|
||||||
|
|
||||||
class Markdown extends PureComponent {
|
class Markdown extends PureComponent<IMarkdownProps, any> {
|
||||||
static propTypes = {
|
private renderer: any;
|
||||||
msg: PropTypes.string,
|
private isMessageContainsOnlyEmoji!: boolean;
|
||||||
getCustomEmoji: PropTypes.func,
|
|
||||||
baseUrl: PropTypes.string,
|
|
||||||
username: PropTypes.string,
|
|
||||||
tmid: PropTypes.string,
|
|
||||||
isEdited: PropTypes.bool,
|
|
||||||
numberOfLines: PropTypes.number,
|
|
||||||
customEmojis: PropTypes.bool,
|
|
||||||
useRealName: PropTypes.bool,
|
|
||||||
channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
||||||
mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
|
|
||||||
navToRoomInfo: PropTypes.func,
|
|
||||||
preview: PropTypes.bool,
|
|
||||||
theme: PropTypes.string,
|
|
||||||
testID: PropTypes.string,
|
|
||||||
style: PropTypes.array,
|
|
||||||
onLinkPress: PropTypes.func
|
|
||||||
};
|
|
||||||
|
|
||||||
constructor(props) {
|
constructor(props: IMarkdownProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.renderer = this.createRenderer();
|
this.renderer = this.createRenderer();
|
||||||
}
|
}
|
||||||
|
@ -129,7 +135,7 @@ class Markdown extends PureComponent {
|
||||||
renderParagraphsInLists: true
|
renderParagraphsInLists: true
|
||||||
});
|
});
|
||||||
|
|
||||||
editedMessage = (ast) => {
|
editedMessage = (ast: any) => {
|
||||||
const { isEdited } = this.props;
|
const { isEdited } = this.props;
|
||||||
if (isEdited) {
|
if (isEdited) {
|
||||||
const editIndicatorNode = new Node('edited_indicator');
|
const editIndicatorNode = new Node('edited_indicator');
|
||||||
|
@ -144,7 +150,7 @@ class Markdown extends PureComponent {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
renderText = ({ context, literal }) => {
|
renderText = ({ context, literal }: {context: []; literal: string}) => {
|
||||||
const {
|
const {
|
||||||
numberOfLines, style = []
|
numberOfLines, style = []
|
||||||
} = this.props;
|
} = this.props;
|
||||||
|
@ -163,7 +169,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderCodeInline = ({ literal }) => {
|
renderCodeInline = ({ literal }: TLiteral) => {
|
||||||
const { theme, style = [] } = this.props;
|
const { theme, style = [] } = this.props;
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
|
@ -182,7 +188,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderCodeBlock = ({ literal }) => {
|
renderCodeBlock = ({ literal }: TLiteral) => {
|
||||||
const { theme, style = [] } = this.props;
|
const { theme, style = [] } = this.props;
|
||||||
return (
|
return (
|
||||||
<Text
|
<Text
|
||||||
|
@ -206,7 +212,7 @@ class Markdown extends PureComponent {
|
||||||
return <Text>{tmid ? ' ' : '\n'}</Text>;
|
return <Text>{tmid ? ' ' : '\n'}</Text>;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderParagraph = ({ children }) => {
|
renderParagraph = ({ children }: any) => {
|
||||||
const { numberOfLines, style, theme } = this.props;
|
const { numberOfLines, style, theme } = this.props;
|
||||||
if (!children || children.length === 0) {
|
if (!children || children.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -218,7 +224,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderLink = ({ children, href }) => {
|
renderLink = ({ children, href }: any) => {
|
||||||
const { theme, onLinkPress } = this.props;
|
const { theme, onLinkPress } = this.props;
|
||||||
return (
|
return (
|
||||||
<MarkdownLink
|
<MarkdownLink
|
||||||
|
@ -231,10 +237,8 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHashtag = ({ hashtag }) => {
|
renderHashtag = ({ hashtag }: {hashtag: string}) => {
|
||||||
const {
|
const { channels, navToRoomInfo, style, theme } = this.props;
|
||||||
channels, navToRoomInfo, style, theme
|
|
||||||
} = this.props;
|
|
||||||
return (
|
return (
|
||||||
<MarkdownHashtag
|
<MarkdownHashtag
|
||||||
hashtag={hashtag}
|
hashtag={hashtag}
|
||||||
|
@ -246,10 +250,8 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderAtMention = ({ mentionName }) => {
|
renderAtMention = ({ mentionName }: { mentionName: string }) => {
|
||||||
const {
|
const { username, mentions, navToRoomInfo, useRealName, style, theme } = this.props;
|
||||||
username, mentions, navToRoomInfo, useRealName, style, theme
|
|
||||||
} = this.props;
|
|
||||||
return (
|
return (
|
||||||
<MarkdownAtMention
|
<MarkdownAtMention
|
||||||
mentions={mentions}
|
mentions={mentions}
|
||||||
|
@ -263,10 +265,8 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderEmoji = ({ literal }) => {
|
renderEmoji = ({ literal }: TLiteral) => {
|
||||||
const {
|
const { getCustomEmoji, baseUrl, customEmojis, style, theme } = this.props;
|
||||||
getCustomEmoji, baseUrl, customEmojis, style, theme
|
|
||||||
} = this.props;
|
|
||||||
return (
|
return (
|
||||||
<MarkdownEmoji
|
<MarkdownEmoji
|
||||||
literal={literal}
|
literal={literal}
|
||||||
|
@ -280,7 +280,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderImage = ({ src }) => {
|
renderImage = ({ src }: {src: string}) => {
|
||||||
if (!isValidURL(src)) {
|
if (!isValidURL(src)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -298,7 +298,7 @@ class Markdown extends PureComponent {
|
||||||
return <Text style={[styles.edited, { color: themes[theme].auxiliaryText }]}> ({I18n.t('edited')})</Text>;
|
return <Text style={[styles.edited, { color: themes[theme].auxiliaryText }]}> ({I18n.t('edited')})</Text>;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderHeading = ({ children, level }) => {
|
renderHeading = ({ children, level }: any) => {
|
||||||
const { numberOfLines, theme } = this.props;
|
const { numberOfLines, theme } = this.props;
|
||||||
const textStyle = styles[`heading${ level }Text`];
|
const textStyle = styles[`heading${ level }Text`];
|
||||||
return (
|
return (
|
||||||
|
@ -308,9 +308,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderList = ({
|
renderList = ({ children, start, tight, type }: any) => {
|
||||||
children, start, tight, type
|
|
||||||
}) => {
|
|
||||||
const { numberOfLines } = this.props;
|
const { numberOfLines } = this.props;
|
||||||
return (
|
return (
|
||||||
<MarkdownList
|
<MarkdownList
|
||||||
|
@ -324,11 +322,9 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderListItem = ({
|
renderListItem = ({ children, context, ...otherProps }: any) => {
|
||||||
children, context, ...otherProps
|
|
||||||
}) => {
|
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
const level = context.filter(type => type === 'list').length;
|
const level = context.filter((type: string) => type === 'list').length;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MarkdownListItem
|
<MarkdownListItem
|
||||||
|
@ -341,7 +337,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
renderBlockQuote = ({ children }) => {
|
renderBlockQuote = ({ children }: {children: JSX.Element}) => {
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return (
|
return (
|
||||||
<MarkdownBlockQuote theme={theme}>
|
<MarkdownBlockQuote theme={theme}>
|
||||||
|
@ -350,7 +346,7 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTable = ({ children, numColumns }) => {
|
renderTable = ({ children, numColumns }: { children: JSX.Element; numColumns: number }) => {
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return (
|
return (
|
||||||
<MarkdownTable numColumns={numColumns} theme={theme}>
|
<MarkdownTable numColumns={numColumns} theme={theme}>
|
||||||
|
@ -359,12 +355,12 @@ class Markdown extends PureComponent {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableRow = (args) => {
|
renderTableRow = (args: any) => {
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return <MarkdownTableRow {...args} theme={theme} />;
|
return <MarkdownTableRow {...args} theme={theme} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTableCell = (args) => {
|
renderTableCell = (args: any) => {
|
||||||
const { theme } = this.props;
|
const { theme } = this.props;
|
||||||
return <MarkdownTableCell {...args} theme={theme} />;
|
return <MarkdownTableCell {...args} theme={theme} />;
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
// TODO: should we add this to our commonmark fork instead?
|
// TODO: should we add this to our commonmark fork instead?
|
||||||
// we loop through nodes and try to merge all texts
|
// we loop through nodes and try to merge all texts
|
||||||
export default function mergeTextNodes(ast) {
|
export default function mergeTextNodes(ast: any) {
|
||||||
// https://github.com/commonmark/commonmark.js/blob/master/lib/node.js#L268
|
// https://github.com/commonmark/commonmark.js/blob/master/lib/node.js#L268
|
||||||
const walker = ast.walker();
|
const walker = ast.walker();
|
||||||
let event;
|
let event;
|
|
@ -7,7 +7,7 @@ const codeFontFamily = Platform.select({
|
||||||
android: { fontFamily: 'monospace' }
|
android: { fontFamily: 'monospace' }
|
||||||
});
|
});
|
||||||
|
|
||||||
export default StyleSheet.create({
|
export default StyleSheet.create<any>({
|
||||||
container: {
|
container: {
|
||||||
alignItems: 'flex-start',
|
alignItems: 'flex-start',
|
||||||
flexDirection: 'row'
|
flexDirection: 'row'
|
Loading…
Reference in New Issue