Unverified Commit 7ad1a2c1 authored by Diego Mello's avatar Diego Mello Committed by GitHub
Browse files

Merge branch 'develop' into fix.reply-while-editing

parents b97d86ba f3972ef4
import React, { useState } from 'react';
import {
View, Text, TouchableWithoutFeedback, ActivityIndicator, StyleSheet
View, Text, TouchableWithoutFeedback, ActivityIndicator, StyleSheet, SafeAreaView
} from 'react-native';
import FastImage from 'react-native-fast-image';
import PropTypes from 'prop-types';
import Modal from 'react-native-modal';
import ImageViewer from 'react-native-image-zoom-viewer';
import SafeAreaView from 'react-native-safe-area-view';
import { Video } from 'expo-av';
import sharedStyles from '../views/Styles';
......
import React from 'react';
import PropTypes from 'prop-types';
import {
View, PermissionsAndroid, Text
View, SafeAreaView, PermissionsAndroid, Text
} from 'react-native';
import { AudioRecorder, AudioUtils } from 'react-native-audio';
import { BorderlessButton } from 'react-native-gesture-handler';
import SafeAreaView from 'react-native-safe-area-view';
import FileSystem from 'expo-file-system';
import styles from './styles';
......
......@@ -79,7 +79,7 @@ class ReplyPreview extends Component {
<Text style={styles.username}>{message.u.username}</Text>
<Text style={styles.time}>{time}</Text>
</View>
<Markdown msg={message.msg} baseUrl={baseUrl} username={username} getCustomEmoji={getCustomEmoji} numberOfLines={1} useMarkdown={useMarkdown} />
<Markdown msg={message.msg} baseUrl={baseUrl} username={username} getCustomEmoji={getCustomEmoji} numberOfLines={1} useMarkdown={useMarkdown} preview />
</View>
<CustomIcon name='cross' color={COLOR_TEXT_DESCRIPTION} size={20} style={styles.close} onPress={this.close} />
</View>
......
import React from 'react';
import {
View, Text, FlatList, StyleSheet
View, Text, FlatList, StyleSheet, SafeAreaView
} from 'react-native';
import PropTypes from 'prop-types';
import Modal from 'react-native-modal';
import Touchable from 'react-native-platform-touchable';
import SafeAreaView from 'react-native-safe-area-view';
import Emoji from './message/Emoji';
import I18n from '../i18n';
......
......@@ -5,7 +5,7 @@ import { Text } from 'react-native';
import styles from './styles';
const AtMention = React.memo(({
mention, mentions, username, navToRoomInfo
mention, mentions, username, navToRoomInfo, preview, style = []
}) => {
let mentionStyle = styles.mention;
if (mention === 'all' || mention === 'here') {
......@@ -33,8 +33,8 @@ const AtMention = React.memo(({
return (
<Text
style={mentionStyle}
onPress={handlePress}
style={[preview ? styles.text : mentionStyle, ...style]}
onPress={preview ? undefined : handlePress}
>
{`@${ mention }`}
</Text>
......@@ -45,6 +45,8 @@ AtMention.propTypes = {
mention: PropTypes.string,
username: PropTypes.string,
navToRoomInfo: PropTypes.func,
style: PropTypes.array,
preview: PropTypes.bool,
mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
......
......@@ -8,11 +8,11 @@ import CustomEmoji from '../EmojiPicker/CustomEmoji';
import styles from './styles';
const Emoji = React.memo(({
emojiName, literal, isMessageContainsOnlyEmoji, getCustomEmoji, baseUrl
emojiName, literal, isMessageContainsOnlyEmoji, getCustomEmoji, baseUrl, customEmojis, style = []
}) => {
const emojiUnicode = shortnameToUnicode(literal);
const emoji = getCustomEmoji && getCustomEmoji(emojiName);
if (emoji) {
if (emoji && customEmojis) {
return (
<CustomEmoji
baseUrl={baseUrl}
......@@ -21,7 +21,16 @@ const Emoji = React.memo(({
/>
);
}
return <Text style={isMessageContainsOnlyEmoji ? styles.textBig : styles.text}>{emojiUnicode}</Text>;
return (
<Text
style={[
isMessageContainsOnlyEmoji ? styles.textBig : styles.text,
...style
]}
>
{emojiUnicode}
</Text>
);
});
Emoji.propTypes = {
......@@ -29,7 +38,9 @@ Emoji.propTypes = {
literal: PropTypes.string,
isMessageContainsOnlyEmoji: PropTypes.bool,
getCustomEmoji: PropTypes.func,
baseUrl: PropTypes.string
baseUrl: PropTypes.string,
customEmojis: PropTypes.bool,
style: PropTypes.array
};
export default Emoji;
......@@ -5,7 +5,7 @@ import { Text } from 'react-native';
import styles from './styles';
const Hashtag = React.memo(({
hashtag, channels, navToRoomInfo
hashtag, channels, navToRoomInfo, preview, style = []
}) => {
const handlePress = () => {
const index = channels.findIndex(channel => channel.name === hashtag);
......@@ -19,8 +19,8 @@ const Hashtag = React.memo(({
if (channels && channels.length && channels.findIndex(channel => channel.name === hashtag) !== -1) {
return (
<Text
style={styles.mention}
onPress={handlePress}
style={[preview ? styles.text : styles.mention, ...style]}
onPress={preview ? undefined : handlePress}
>
{`#${ hashtag }`}
</Text>
......@@ -32,6 +32,8 @@ const Hashtag = React.memo(({
Hashtag.propTypes = {
hashtag: PropTypes.string,
navToRoomInfo: PropTypes.func,
style: PropTypes.array,
preview: PropTypes.bool,
channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object])
};
......
......@@ -6,7 +6,7 @@ import styles from './styles';
import openLink from '../../utils/openLink';
const Link = React.memo(({
children, link
children, link, preview
}) => {
const handlePress = () => {
if (!link) {
......@@ -20,7 +20,7 @@ const Link = React.memo(({
// if you have a [](https://rocket.chat) render https://rocket.chat
return (
<Text
onPress={handlePress}
onPress={preview ? undefined : handlePress}
style={styles.link}
>
{ childLength !== 0 ? children : link }
......@@ -30,7 +30,8 @@ const Link = React.memo(({
Link.propTypes = {
children: PropTypes.node,
link: PropTypes.string
link: PropTypes.string,
preview: PropTypes.bool
};
export default Link;
......@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
const List = React.memo(({
children, ordered, start, tight
children, ordered, start, tight, numberOfLines = 0
}) => {
let bulletWidth = 15;
......@@ -11,7 +11,13 @@ const List = React.memo(({
bulletWidth = (9 * lastNumber.toString().length) + 7;
}
const _children = React.Children.map(children, (child, index) => React.cloneElement(child, {
let items = React.Children.toArray(children);
if (numberOfLines) {
items = items.slice(0, numberOfLines);
}
const _children = items.map((child, index) => React.cloneElement(child, {
bulletWidth,
ordered,
tight,
......@@ -29,7 +35,8 @@ List.propTypes = {
children: PropTypes.node,
ordered: PropTypes.bool,
start: PropTypes.number,
tight: PropTypes.bool
tight: PropTypes.bool,
numberOfLines: PropTypes.number
};
List.defaultProps = {
......
import React, { PureComponent } from 'react';
import { View, Text, Image } from 'react-native';
import { Text, Image } from 'react-native';
import { Parser, Node } from 'commonmark';
import Renderer from 'commonmark-react-renderer';
import PropTypes from 'prop-types';
......@@ -53,8 +53,6 @@ const emojiCount = (str) => {
return counter;
};
const encodeEmojis = str => toShort(shortnameToUnicode(str));
export default class Markdown extends PureComponent {
static propTypes = {
msg: PropTypes.string,
......@@ -65,21 +63,24 @@ export default class Markdown extends PureComponent {
isEdited: PropTypes.bool,
numberOfLines: PropTypes.number,
useMarkdown: PropTypes.bool,
customEmojis: PropTypes.bool,
channels: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
mentions: PropTypes.oneOfType([PropTypes.array, PropTypes.object]),
navToRoomInfo: PropTypes.func
navToRoomInfo: PropTypes.func,
preview: PropTypes.bool,
style: PropTypes.array
};
constructor(props) {
super(props);
this.parser = this.createParser();
this.renderer = this.createRenderer();
this.renderer = this.createRenderer(props.preview);
}
createParser = () => new Parser();
createRenderer = () => new Renderer({
createRenderer = (preview = false) => new Renderer({
renderers: {
text: this.renderText,
......@@ -112,7 +113,7 @@ export default class Markdown extends PureComponent {
table_row: this.renderTableRow,
table_cell: this.renderTableCell,
editedIndicator: this.renderEditedIndicator
editedIndicator: preview ? () => null : this.renderEditedIndicator
},
renderParagraphsInLists: true
});
......@@ -133,12 +134,17 @@ export default class Markdown extends PureComponent {
};
renderText = ({ context, literal }) => {
const { numberOfLines } = this.props;
const { numberOfLines, preview, style = [] } = this.props;
const defaultStyle = [
this.isMessageContainsOnlyEmoji && !preview ? styles.textBig : {},
...context.map(type => styles[type])
];
return (
<Text
style={[
this.isMessageContainsOnlyEmoji ? styles.textBig : styles.text,
...context.map(type => styles[type])
styles.text,
!preview ? defaultStyle : {},
...style
]}
numberOfLines={numberOfLines}
>
......@@ -147,9 +153,15 @@ export default class Markdown extends PureComponent {
);
}
renderCodeInline = ({ literal }) => <Text style={styles.codeInline}>{literal}</Text>;
renderCodeInline = ({ literal }) => {
const { preview } = this.props;
return <Text style={!preview ? styles.codeInline : {}}>{literal}</Text>;
};
renderCodeBlock = ({ literal }) => <Text style={styles.codeBlock}>{literal}</Text>;
renderCodeBlock = ({ literal }) => {
const { preview } = this.props;
return <Text style={!preview ? styles.codeBlock : {}}>{literal}</Text>;
};
renderBreak = () => {
const { tmid } = this.props;
......@@ -157,56 +169,70 @@ export default class Markdown extends PureComponent {
}
renderParagraph = ({ children }) => {
const { numberOfLines, style } = this.props;
if (!children || children.length === 0) {
return null;
}
return (
<View style={styles.block}>
<Text>
<Text style={style} numberOfLines={numberOfLines}>
{children}
</Text>
</View>
);
};
renderLink = ({ children, href }) => (
<MarkdownLink link={href}>
renderLink = ({ children, href }) => {
const { preview } = this.props;
return (
<MarkdownLink link={href} preview={preview}>
{children}
</MarkdownLink>
);
}
renderHashtag = ({ hashtag }) => {
const { channels, navToRoomInfo } = this.props;
const {
channels, navToRoomInfo, style, preview
} = this.props;
return (
<MarkdownHashtag
hashtag={hashtag}
channels={channels}
navToRoomInfo={navToRoomInfo}
preview={preview}
style={style}
/>
);
}
renderAtMention = ({ mentionName }) => {
const { username, mentions, navToRoomInfo } = this.props;
const {
username, mentions, navToRoomInfo, preview, style
} = this.props;
return (
<MarkdownAtMention
mentions={mentions}
mention={mentionName}
username={username}
navToRoomInfo={navToRoomInfo}
preview={preview}
style={style}
/>
);
}
renderEmoji = ({ emojiName, literal }) => {
const { getCustomEmoji, baseUrl } = this.props;
const {
getCustomEmoji, baseUrl, customEmojis = true, preview, style
} = this.props;
return (
<MarkdownEmoji
emojiName={emojiName}
literal={literal}
isMessageContainsOnlyEmoji={this.isMessageContainsOnlyEmoji}
isMessageContainsOnlyEmoji={this.isMessageContainsOnlyEmoji && !preview}
getCustomEmoji={getCustomEmoji}
baseUrl={baseUrl}
customEmojis={customEmojis}
style={style}
/>
);
}
......@@ -216,9 +242,10 @@ export default class Markdown extends PureComponent {
renderEditedIndicator = () => <Text style={styles.edited}> ({I18n.t('edited')})</Text>;
renderHeading = ({ children, level }) => {
const { numberOfLines } = this.props;
const textStyle = styles[`heading${ level }Text`];
return (
<Text style={textStyle}>
<Text numberOfLines={numberOfLines} style={textStyle}>
{children}
</Text>
);
......@@ -226,15 +253,19 @@ export default class Markdown extends PureComponent {
renderList = ({
children, start, tight, type
}) => (
}) => {
const { numberOfLines } = this.props;
return (
<MarkdownList
ordered={type !== 'bullet'}
start={start}
tight={tight}
numberOfLines={numberOfLines}
>
{children}
</MarkdownList>
);
};
renderListItem = ({
children, context, ...otherProps
......@@ -251,11 +282,17 @@ export default class Markdown extends PureComponent {
);
};
renderBlockQuote = ({ children }) => (
renderBlockQuote = ({ children }) => {
const { preview } = this.props;
if (preview) {
return children;
}
return (
<MarkdownBlockQuote>
{children}
</MarkdownBlockQuote>
);
}
renderTable = ({ children, numColumns }) => (
<MarkdownTable numColumns={numColumns}>
......@@ -269,7 +306,7 @@ export default class Markdown extends PureComponent {
render() {
const {
msg, useMarkdown = true, numberOfLines
msg, useMarkdown = true, numberOfLines, preview = false
} = this.props;
if (!msg) {
......@@ -281,13 +318,18 @@ export default class Markdown extends PureComponent {
// Ex: '[ ](https://open.rocket.chat/group/test?msg=abcdef) Test'
// Return: 'Test'
m = m.replace(/^\[([\s]]*)\]\(([^)]*)\)\s/, '').trim();
m = shortnameToUnicode(m);
if (preview) {
m = m.split('\n').reduce((lines, line) => `${ lines } ${ line }`, '');
}
if (!useMarkdown) {
if (!useMarkdown && !preview) {
return <Text style={styles.text} numberOfLines={numberOfLines}>{m}</Text>;
}
const ast = this.parser.parse(m);
const encodedEmojis = encodeEmojis(m);
const encodedEmojis = toShort(m);
this.isMessageContainsOnlyEmoji = isOnlyEmoji(encodedEmojis) && emojiCount(encodedEmojis) <= 3;
this.editedMessage(ast);
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.