New markdown (#306)
Our current markdown is causing a lot of issues on Android devices, since it wraps everything inside a Text component. On Android, Text doesn't support View as a child. This PR adds react-native-markdown-renderer, that uses View as wrapper and may be better.
This commit is contained in:
parent
061c313e3f
commit
f61a57bb30
|
@ -268,7 +268,6 @@ workflows:
|
|||
- ios-build:
|
||||
requires:
|
||||
- lint-testunit
|
||||
- e2e-test
|
||||
- ios-testflight:
|
||||
requires:
|
||||
- ios-build
|
||||
|
@ -285,4 +284,3 @@ workflows:
|
|||
- android-build:
|
||||
requires:
|
||||
- lint-testunit
|
||||
- e2e-test
|
||||
|
|
|
@ -160,9 +160,9 @@ exports[`render channel 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -332,9 +332,9 @@ exports[`render no icon 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -504,9 +504,9 @@ exports[`render private group 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -744,9 +744,9 @@ exports[`render unread +999 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -1006,9 +1006,9 @@ exports[`render unread 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -1268,9 +1268,9 @@ exports[`renders correctly 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -551,9 +551,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -789,9 +789,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -1023,9 +1023,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -1284,9 +1284,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -1541,9 +1541,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -1798,9 +1798,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -2055,9 +2055,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -2312,9 +2312,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
>
|
||||
|
@ -2569,9 +2569,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -2803,9 +2803,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
@ -3037,9 +3037,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = `
|
|||
<View
|
||||
style={
|
||||
Object {
|
||||
"alignItems": "flex-end",
|
||||
"alignItems": "center",
|
||||
"flex": 1,
|
||||
"flexDirection": "row",
|
||||
"justifyContent": "flex-end",
|
||||
}
|
||||
}
|
||||
/>
|
||||
|
|
|
@ -1,98 +1,13 @@
|
|||
import React from 'react';
|
||||
import { Text, StyleSheet, ViewPropTypes } from 'react-native';
|
||||
import { Text, Platform } from 'react-native';
|
||||
import PropTypes from 'prop-types';
|
||||
import EasyMarkdown from 'react-native-easy-markdown'; // eslint-disable-line
|
||||
import SimpleMarkdown from 'simple-markdown';
|
||||
import { emojify } from 'react-emojione';
|
||||
import { connect } from 'react-redux';
|
||||
import MarkdownRenderer, { PluginContainer } from 'react-native-markdown-renderer';
|
||||
import MarkdownFlowdock from 'markdown-it-flowdock';
|
||||
import styles from './styles';
|
||||
import CustomEmoji from '../EmojiPicker/CustomEmoji';
|
||||
|
||||
const BlockCode = ({ node, state }) => (
|
||||
<Text
|
||||
key={state.key}
|
||||
style={styles.codeStyle}
|
||||
>
|
||||
{node.content}
|
||||
</Text>
|
||||
);
|
||||
const mentionStyle = { color: '#13679a' };
|
||||
|
||||
const defaultRules = {
|
||||
username: {
|
||||
order: -1,
|
||||
match: SimpleMarkdown.inlineRegex(/^@[0-9a-zA-Z-_.]+/),
|
||||
parse: capture => ({ content: capture[0] }),
|
||||
react: (node, output, state) => ({
|
||||
type: 'custom',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: (
|
||||
<Text
|
||||
key={state.key}
|
||||
style={mentionStyle}
|
||||
onPress={() => alert('Username')}
|
||||
>
|
||||
{node.content}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
heading: {
|
||||
order: -2,
|
||||
match: SimpleMarkdown.inlineRegex(/^#[0-9a-zA-Z-_.]+/),
|
||||
parse: capture => ({ content: capture[0] }),
|
||||
react: (node, output, state) => ({
|
||||
type: 'custom',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: (
|
||||
<Text
|
||||
key={state.key}
|
||||
style={mentionStyle}
|
||||
onPress={() => alert('Room')}
|
||||
>
|
||||
{node.content}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
fence: {
|
||||
order: -3,
|
||||
match: SimpleMarkdown.blockRegex(/^ *(`{3,}|~{3,}) *(\S+)? *\n([\s\S]+?)\s*\1 *(?:\n *)+\n/),
|
||||
parse: capture => ({
|
||||
lang: capture[2] || undefined,
|
||||
content: capture[3]
|
||||
}),
|
||||
react: (node, output, state) => ({
|
||||
type: 'custom',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: (
|
||||
<BlockCode key={state.key} node={node} state={state} />
|
||||
)
|
||||
}
|
||||
})
|
||||
},
|
||||
blockCode: {
|
||||
order: -4,
|
||||
match: SimpleMarkdown.blockRegex(/^(```)\s*([\s\S]*?[^`])\s*\1(?!```)/),
|
||||
parse: capture => ({ content: capture[2] }),
|
||||
react: (node, output, state) => ({
|
||||
type: 'custom',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: (
|
||||
<BlockCode key={state.key} node={node} state={state} />
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
const codeStyle = StyleSheet.flatten(styles.codeStyle);
|
||||
import MarkdownEmojiPlugin from './MarkdownEmojiPlugin';
|
||||
|
||||
// Support <http://link|Text>
|
||||
const formatText = text =>
|
||||
|
@ -110,49 +25,64 @@ export default class Markdown extends React.Component {
|
|||
}
|
||||
render() {
|
||||
const {
|
||||
msg, customEmojis = {}, style, markdownStyle, customRules, renderInline
|
||||
msg, customEmojis, style, rules
|
||||
} = this.props;
|
||||
if (!msg) {
|
||||
return null;
|
||||
}
|
||||
let m = formatText(msg);
|
||||
m = emojify(m, { output: 'unicode' });
|
||||
|
||||
const s = StyleSheet.flatten(style);
|
||||
return (
|
||||
<EasyMarkdown
|
||||
style={{ marginBottom: 0, ...s }}
|
||||
markdownStyles={{ code: codeStyle, ...markdownStyle }}
|
||||
<MarkdownRenderer
|
||||
rules={{
|
||||
customEmoji: {
|
||||
order: -5,
|
||||
match: SimpleMarkdown.inlineRegex(/^:([0-9a-zA-Z-_.]+):/),
|
||||
parse: capture => ({ content: capture }),
|
||||
react: (node, output, state) => {
|
||||
const element = {
|
||||
type: 'custom',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: <Text key={state.key}>{node.content[0]}</Text>
|
||||
}
|
||||
};
|
||||
const content = node.content[1];
|
||||
...Platform.OS === 'android' ? {} : {
|
||||
paragraph: (node, children) => (
|
||||
<Text key={node.key} style={styles.paragraph}>
|
||||
{children}
|
||||
</Text>
|
||||
)
|
||||
},
|
||||
mention: node => (
|
||||
<Text key={node.key} onPress={() => alert(`Username @${ node.content }`)} style={styles.mention}>
|
||||
@{node.content}
|
||||
</Text>
|
||||
),
|
||||
hashtag: node => (
|
||||
<Text key={node.key} onPress={() => alert(`Room #${ node.content }`)} style={styles.mention}>
|
||||
#{node.content}
|
||||
</Text>
|
||||
),
|
||||
emoji: (node) => {
|
||||
if (node.children && node.children.length && node.children[0].children && node.children[0].children.length) {
|
||||
const { content } = node.children[0].children[0];
|
||||
const emojiExtension = customEmojis[content];
|
||||
if (emojiExtension) {
|
||||
const emoji = { extension: emojiExtension, content };
|
||||
element.props.children = (
|
||||
<CustomEmoji key={state.key} style={styles.customEmoji} emoji={emoji} />
|
||||
);
|
||||
return <CustomEmoji key={node.key} style={styles.customEmoji} emoji={emoji} />;
|
||||
}
|
||||
return element;
|
||||
return <Text key={node.key}>:{content}:</Text>;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
...defaultRules,
|
||||
...customRules
|
||||
...rules
|
||||
}}
|
||||
renderInline={renderInline}
|
||||
style={{
|
||||
paragraph: styles.paragraph,
|
||||
codeInline: {
|
||||
borderWidth: 1,
|
||||
borderColor: '#CCCCCC',
|
||||
backgroundColor: '#f5f5f5',
|
||||
padding: 2,
|
||||
borderRadius: 4
|
||||
},
|
||||
...style
|
||||
}}
|
||||
plugins={[
|
||||
new PluginContainer(MarkdownFlowdock),
|
||||
new PluginContainer(MarkdownEmojiPlugin)
|
||||
]}
|
||||
>{m}
|
||||
</EasyMarkdown>
|
||||
</MarkdownRenderer>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -160,14 +90,6 @@ export default class Markdown extends React.Component {
|
|||
Markdown.propTypes = {
|
||||
msg: PropTypes.string,
|
||||
customEmojis: PropTypes.object,
|
||||
// eslint-disable-next-line react/no-typos
|
||||
style: ViewPropTypes.style,
|
||||
markdownStyle: PropTypes.object,
|
||||
customRules: PropTypes.object,
|
||||
renderInline: PropTypes.bool
|
||||
};
|
||||
|
||||
BlockCode.propTypes = {
|
||||
node: PropTypes.object,
|
||||
state: PropTypes.object
|
||||
style: PropTypes.any,
|
||||
rules: PropTypes.object
|
||||
};
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
export default function(md) {
|
||||
function tokenize(state, silent) {
|
||||
let token;
|
||||
const start = state.pos;
|
||||
const marker = state.src.charCodeAt(start);
|
||||
|
||||
if (silent) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// :
|
||||
if (marker !== 58) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const scanned = state.scanDelims(state.pos, true);
|
||||
const len = scanned.length;
|
||||
const ch = String.fromCharCode(marker);
|
||||
|
||||
for (let i = 0; i < len; i += 1) {
|
||||
token = state.push('text', '', 0);
|
||||
token.content = ch;
|
||||
|
||||
state.delimiters.push({
|
||||
marker,
|
||||
jump: i,
|
||||
token: state.tokens.length - 1,
|
||||
level: state.level,
|
||||
end: -1,
|
||||
open: scanned.can_open,
|
||||
close: scanned.can_close
|
||||
});
|
||||
}
|
||||
|
||||
state.pos += scanned.length;
|
||||
return true;
|
||||
}
|
||||
|
||||
function postProcess(state) {
|
||||
let startDelim;
|
||||
let endDelim;
|
||||
let token;
|
||||
const { delimiters } = state;
|
||||
const max = delimiters.length;
|
||||
|
||||
for (const i = 0; i < max; i++) { // eslint-disable-line
|
||||
startDelim = delimiters[i];
|
||||
|
||||
// :
|
||||
if (startDelim.marker !== 58) {
|
||||
continue; // eslint-disable-line
|
||||
}
|
||||
|
||||
if (startDelim.end === -1) {
|
||||
continue; // eslint-disable-line
|
||||
}
|
||||
|
||||
endDelim = delimiters[startDelim.end];
|
||||
|
||||
token = state.tokens[startDelim.token];
|
||||
token.type = 'emoji_open';
|
||||
token.tag = 'emoji';
|
||||
token.nesting = 1;
|
||||
token.markup = ':';
|
||||
token.content = '';
|
||||
|
||||
token = state.tokens[endDelim.token];
|
||||
token.type = 'emoji_close';
|
||||
token.tag = 'emoji';
|
||||
token.nesting = -1;
|
||||
token.markup = ':';
|
||||
token.content = '';
|
||||
}
|
||||
}
|
||||
|
||||
md.inline.ruler.before('emphasis', 'emoji', tokenize);
|
||||
md.inline.ruler2.before('emphasis', 'emoji', postProcess);
|
||||
}
|
|
@ -97,5 +97,16 @@ export default StyleSheet.create({
|
|||
},
|
||||
broadcastButtonText: {
|
||||
color: '#1d74f5'
|
||||
},
|
||||
mention: {
|
||||
color: '#13679a'
|
||||
},
|
||||
paragraph: {
|
||||
marginTop: 0,
|
||||
marginBottom: 0,
|
||||
flexWrap: 'wrap',
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-start',
|
||||
justifyContent: 'flex-start'
|
||||
}
|
||||
});
|
||||
|
|
|
@ -4,7 +4,7 @@ import PropTypes from 'prop-types';
|
|||
import { View, Text, StyleSheet, ViewPropTypes } from 'react-native';
|
||||
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
|
||||
import { connect } from 'react-redux';
|
||||
import SimpleMarkdown from 'simple-markdown';
|
||||
// import SimpleMarkdown from 'simple-markdown';
|
||||
|
||||
import Avatar from '../containers/Avatar';
|
||||
import Status from '../containers/status';
|
||||
|
@ -65,10 +65,10 @@ const styles = StyleSheet.create({
|
|||
},
|
||||
row: {
|
||||
// width: '100%',
|
||||
// flex: 1,
|
||||
flex: 1,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'flex-end',
|
||||
justifyContent: 'flex-end'
|
||||
alignItems: 'center'
|
||||
// justifyContent: 'flex-end'
|
||||
},
|
||||
firstRow: {
|
||||
width: '100%',
|
||||
|
@ -98,36 +98,36 @@ const styles = StyleSheet.create({
|
|||
marginTop: 3
|
||||
}
|
||||
});
|
||||
const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } };
|
||||
// const markdownStyle = { block: { marginBottom: 0, flexWrap: 'wrap', flexDirection: 'row' } };
|
||||
|
||||
const parseInline = (parse, content, state) => {
|
||||
const isCurrentlyInline = state.inline || false;
|
||||
state.inline = true;
|
||||
const result = parse(content, state);
|
||||
state.inline = isCurrentlyInline;
|
||||
return result;
|
||||
};
|
||||
const parseCaptureInline = (capture, parse, state) => ({ content: parseInline(parse, capture[1], state) });
|
||||
const customRules = {
|
||||
strong: {
|
||||
order: -4,
|
||||
match: SimpleMarkdown.inlineRegex(/^\*\*([\s\S]+?)\*\*(?!\*)/),
|
||||
parse: parseCaptureInline,
|
||||
react: (node, output, state) => ({
|
||||
type: 'strong',
|
||||
key: state.key,
|
||||
props: {
|
||||
children: output(node.content, state)
|
||||
}
|
||||
})
|
||||
},
|
||||
text: {
|
||||
order: -3,
|
||||
match: SimpleMarkdown.inlineRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),
|
||||
parse: capture => ({ content: capture[0] }),
|
||||
react: node => node.content
|
||||
}
|
||||
};
|
||||
// const parseInline = (parse, content, state) => {
|
||||
// const isCurrentlyInline = state.inline || false;
|
||||
// state.inline = true;
|
||||
// const result = parse(content, state);
|
||||
// state.inline = isCurrentlyInline;
|
||||
// return result;
|
||||
// };
|
||||
// const parseCaptureInline = (capture, parse, state) => ({ content: parseInline(parse, capture[1], state) });
|
||||
// const customRules = {
|
||||
// strong: {
|
||||
// order: -4,
|
||||
// match: SimpleMarkdown.inlineRegex(/^\*\*([\s\S]+?)\*\*(?!\*)/),
|
||||
// parse: parseCaptureInline,
|
||||
// react: (node, output, state) => ({
|
||||
// type: 'strong',
|
||||
// key: state.key,
|
||||
// props: {
|
||||
// children: output(node.content, state)
|
||||
// }
|
||||
// })
|
||||
// },
|
||||
// text: {
|
||||
// order: -3,
|
||||
// match: SimpleMarkdown.inlineRegex(/^[\s\S]+?(?=[^0-9A-Za-z\s\u00c0-\uffff]|\n\n| {2,}\n|\w+:\S|$)/),
|
||||
// parse: capture => ({ content: capture[0] }),
|
||||
// react: node => node.content
|
||||
// }
|
||||
// };
|
||||
|
||||
const renderNumber = (unread, userMentions) => {
|
||||
if (!unread || unread <= 0) {
|
||||
|
@ -283,11 +283,23 @@ export default class RoomItem extends React.Component {
|
|||
<View style={styles.row}>
|
||||
<Markdown
|
||||
msg={this.lastMessage}
|
||||
style={styles.lastMessage}
|
||||
markdownStyle={markdownStyle}
|
||||
customRules={customRules}
|
||||
renderInline
|
||||
numberOfLines={1}
|
||||
style={{
|
||||
view: {
|
||||
flex: 1
|
||||
}
|
||||
}}
|
||||
rules={{
|
||||
mention: node => (
|
||||
<Text key={node.key}>
|
||||
@{node.content}
|
||||
</Text>
|
||||
),
|
||||
hashtag: node => (
|
||||
<Text key={node.key}>
|
||||
#{node.content}
|
||||
</Text>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
{renderNumber(unread, userMentions)}
|
||||
</View>
|
||||
|
|
|
@ -13,7 +13,7 @@ const openMentionedMessagesRoom = function* openMentionedMessagesRoom({ rid, lim
|
|||
newSub = yield RocketChat.subscribe('mentionedMessages', rid, limit);
|
||||
yield put(readyMentionedMessages());
|
||||
if (sub) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe().catch(err => console.warn(err));
|
||||
}
|
||||
sub = newSub;
|
||||
} catch (e) {
|
||||
|
|
|
@ -13,7 +13,7 @@ const openPinnedMessagesRoom = function* openPinnedMessagesRoom({ rid, limit })
|
|||
newSub = yield RocketChat.subscribe('pinnedMessages', rid, limit);
|
||||
yield put(readyPinnedMessages());
|
||||
if (sub) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe().catch(err => console.warn(err));
|
||||
}
|
||||
sub = newSub;
|
||||
} catch (e) {
|
||||
|
|
|
@ -13,7 +13,7 @@ const openRoomFiles = function* openRoomFiles({ rid, limit }) {
|
|||
newSub = yield RocketChat.subscribe('roomFiles', rid, limit);
|
||||
yield put(readyRoomFiles());
|
||||
if (sub) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe().catch(err => console.warn(err));
|
||||
}
|
||||
sub = newSub;
|
||||
} catch (e) {
|
||||
|
|
|
@ -13,7 +13,7 @@ const openSnippetedMessagesRoom = function* openSnippetedMessagesRoom({ rid, lim
|
|||
newSub = yield RocketChat.subscribe('snippetedMessages', rid, limit);
|
||||
yield put(readySnippetedMessages());
|
||||
if (sub) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe().catch(err => console.warn(err));
|
||||
}
|
||||
sub = newSub;
|
||||
} catch (e) {
|
||||
|
|
|
@ -13,7 +13,7 @@ const openStarredMessagesRoom = function* openStarredMessagesRoom({ rid, limit }
|
|||
newSub = yield RocketChat.subscribe('starredMessages', rid, limit);
|
||||
yield put(readyStarredMessages());
|
||||
if (sub) {
|
||||
sub.unsubscribe();
|
||||
sub.unsubscribe().catch(err => console.warn(err));
|
||||
}
|
||||
sub = newSub;
|
||||
} catch (e) {
|
||||
|
|
|
@ -67,7 +67,7 @@ describe('Rooms list screen', () => {
|
|||
await waitFor(element(by.id('rooms-list-view-search'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.id('rooms-list-view-search'))).toBeVisible();
|
||||
await element(by.id('rooms-list-view-search')).replaceText('rocket.cat');
|
||||
await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible().withTimeout(10000);
|
||||
await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible();
|
||||
await element(by.id('rooms-list-view-item-rocket.cat')).tap();
|
||||
await waitFor(element(by.id('room-view'))).toBeVisible().withTimeout(10000);
|
||||
|
@ -77,8 +77,9 @@ describe('Rooms list screen', () => {
|
|||
await element(by.id('header-back')).atIndex(0).tap();
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(2000);
|
||||
await expect(element(by.id('rooms-list-view'))).toBeVisible();
|
||||
await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id('rooms-list-view-item-rocket.cat'))).toBeVisible();
|
||||
await element(by.id('rooms-list-view-search')).replaceText('');
|
||||
await waitFor(element(by.id('rooms-list-view-item-rocket.cat'))).toExist().withTimeout(60000);
|
||||
await expect(element(by.id('rooms-list-view-item-rocket.cat'))).toExist();
|
||||
});
|
||||
|
||||
// Usage - Sidebar
|
||||
|
|
|
@ -90,7 +90,7 @@ describe('Room info screen', () => {
|
|||
});
|
||||
|
||||
it('should have name input', async() => {
|
||||
await expect(element(by.id('room-info-edit-view-name'))).toBeVisible();
|
||||
await expect(element(by.id('room-info-edit-view-name'))).toExist();
|
||||
});
|
||||
|
||||
it('should have description input', async() => {
|
||||
|
|
|
@ -56,6 +56,8 @@ describe('Broadcast room', () => {
|
|||
await element(by.id('login-view-password')).replaceText(data.alternateUserPassword);
|
||||
await element(by.id('login-view-submit')).tap();
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000);
|
||||
await device.reloadReactNative(); // remove after fix logout
|
||||
await waitFor(element(by.id('rooms-list-view'))).toBeVisible().withTimeout(10000);
|
||||
await waitFor(element(by.id(`rooms-list-view-item-broadcast${ data.random }`))).toBeVisible().withTimeout(60000);
|
||||
await expect(element(by.id(`rooms-list-view-item-broadcast${ data.random }`))).toBeVisible();
|
||||
await element(by.id(`rooms-list-view-item-broadcast${ data.random }`)).tap();
|
||||
|
|
|
@ -1229,6 +1229,27 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"@types/markdown-it": {
|
||||
"version": "0.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-0.0.4.tgz",
|
||||
"integrity": "sha512-FWR7QB7EqBRq1s9BMk0ccOSOuRLfVEWYpHQYpFPaXtCoqN6dJx2ttdsdQbUxLLnAlKpYeVjveGGhQ3583TTa7g=="
|
||||
},
|
||||
"@types/react": {
|
||||
"version": "16.3.14",
|
||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-16.3.14.tgz",
|
||||
"integrity": "sha512-wNUGm49fPl7eE2fnYdF0v5vSOrUMdKMQD/4NwtQRnb6mnPwtkhabmuFz37eq90+hhyfz0pWd38jkZHOcaZ6LGw==",
|
||||
"requires": {
|
||||
"csstype": "2.5.2"
|
||||
}
|
||||
},
|
||||
"@types/react-native": {
|
||||
"version": "0.55.15",
|
||||
"resolved": "https://registry.npmjs.org/@types/react-native/-/react-native-0.55.15.tgz",
|
||||
"integrity": "sha512-AEnb2qacurrUL8A1EQknPKzJUXMtliPNRkd+xa4J/joUbsFen3aynVkYi+OPZ2cyomB+FWz+vv9uKCxURkgChQ==",
|
||||
"requires": {
|
||||
"@types/react": "16.3.14"
|
||||
}
|
||||
},
|
||||
"@zamotany/react-proxy": {
|
||||
"version": "3.0.0-alpha.4",
|
||||
"resolved": "https://registry.npmjs.org/@zamotany/react-proxy/-/react-proxy-3.0.0-alpha.4.tgz",
|
||||
|
@ -10746,6 +10767,14 @@
|
|||
"type-check": "0.3.2"
|
||||
}
|
||||
},
|
||||
"linkify-it": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.0.3.tgz",
|
||||
"integrity": "sha1-2UpGSPmxwXnWT6lykSaL22zpQ08=",
|
||||
"requires": {
|
||||
"uc.micro": "1.0.5"
|
||||
}
|
||||
},
|
||||
"load-json-file": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
|
||||
|
@ -11037,6 +11066,23 @@
|
|||
"object-visit": "1.0.1"
|
||||
}
|
||||
},
|
||||
"markdown-it": {
|
||||
"version": "8.4.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.1.tgz",
|
||||
"integrity": "sha512-CzzqSSNkFRUf9vlWvhK1awpJreMRqdCrBvZ8DIoDWTOkESMIF741UPAhuAmbyWmdiFPA6WARNhnu2M6Nrhwa+A==",
|
||||
"requires": {
|
||||
"argparse": "1.0.9",
|
||||
"entities": "1.1.1",
|
||||
"linkify-it": "2.0.3",
|
||||
"mdurl": "1.0.1",
|
||||
"uc.micro": "1.0.5"
|
||||
}
|
||||
},
|
||||
"markdown-it-flowdock": {
|
||||
"version": "0.3.7",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-flowdock/-/markdown-it-flowdock-0.3.7.tgz",
|
||||
"integrity": "sha1-Oj6/V646BKBoTOK2Hbb+lOhZV4E="
|
||||
},
|
||||
"markdown-loader": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/markdown-loader/-/markdown-loader-2.0.2.tgz",
|
||||
|
@ -11076,6 +11122,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"mdurl": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||
},
|
||||
"media-typer": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||
|
@ -14710,19 +14761,6 @@
|
|||
"react-native-drawer-layout": "1.3.2"
|
||||
}
|
||||
},
|
||||
"react-native-easy-markdown": {
|
||||
"version": "git+https://github.com/diegolmello/react-native-easy-markdown.git#1cf9d2bd9683576af0bb09d80ffa286c4dc03f82",
|
||||
"requires": {
|
||||
"simple-markdown": "0.1.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"simple-markdown": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/simple-markdown/-/simple-markdown-0.1.2.tgz",
|
||||
"integrity": "sha1-PBUQ/kC9nqBncXuKUzyc82MltBM="
|
||||
}
|
||||
}
|
||||
},
|
||||
"react-native-fabric": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fabric/-/react-native-fabric-0.5.1.tgz",
|
||||
|
@ -14760,6 +14798,14 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"react-native-fit-image": {
|
||||
"version": "1.5.4",
|
||||
"resolved": "https://registry.npmjs.org/react-native-fit-image/-/react-native-fit-image-1.5.4.tgz",
|
||||
"integrity": "sha512-wNHlGdDWsUU31qlM5SsvZrMH4eXBZt586FQNXFRFuOiXVqdA++6Xait7aiZ+5vxglgqLf+zzSnoICn0NEvDfrw==",
|
||||
"requires": {
|
||||
"prop-types": "15.6.1"
|
||||
}
|
||||
},
|
||||
"react-native-image-picker": {
|
||||
"version": "0.26.10",
|
||||
"resolved": "https://registry.npmjs.org/react-native-image-picker/-/react-native-image-picker-0.26.10.tgz",
|
||||
|
@ -14789,6 +14835,16 @@
|
|||
"react-native-keyboard-tracking-view": {
|
||||
"version": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git#82be12805eb3aa448c1f09f545c334e4776b3148"
|
||||
},
|
||||
"react-native-markdown-renderer": {
|
||||
"version": "git+https://github.com/RocketChat/react-native-markdown-renderer.git#cecc6d0a2c940ac7a1e1e98c624d8b9b4d37ab68",
|
||||
"requires": {
|
||||
"@types/markdown-it": "0.0.4",
|
||||
"@types/react-native": "0.55.15",
|
||||
"markdown-it": "8.4.1",
|
||||
"prop-types": "15.6.1",
|
||||
"react-native-fit-image": "1.5.4"
|
||||
}
|
||||
},
|
||||
"react-native-meteor": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/react-native-meteor/-/react-native-meteor-1.2.0.tgz",
|
||||
|
@ -16320,11 +16376,6 @@
|
|||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
|
||||
"integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
|
||||
},
|
||||
"simple-markdown": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-markdown/-/simple-markdown-0.4.1.tgz",
|
||||
"integrity": "sha512-EkGc+efa/7qv2s9+G6sBBHPfvC6y+mq9mq0zStf8KDgHBlaRbT0U7mbA2WFUrxhUe/IDfSTilgC+G8ctc88n6A=="
|
||||
},
|
||||
"simple-plist": {
|
||||
"version": "0.2.1",
|
||||
"resolved": "https://registry.npmjs.org/simple-plist/-/simple-plist-0.2.1.tgz",
|
||||
|
@ -18119,6 +18170,11 @@
|
|||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz",
|
||||
"integrity": "sha512-uRdSdu1oA1rncCQL7sCj8vSyZkgtL7faaw9Tc9rZ3mGgraQ7+Pdx7w5mnOSF3gw9ZNG6oc+KXfkon3bKuROm0g=="
|
||||
},
|
||||
"uc.micro": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.5.tgz",
|
||||
"integrity": "sha512-JoLI4g5zv5qNyT09f4YAvEZIIV1oOjqnewYg5D38dkQljIzpPT296dbIGvKro3digYI1bkb7W6EP1y4uDlmzLg=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "2.8.29",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
|
||||
|
|
|
@ -34,6 +34,7 @@
|
|||
"ejson": "^2.1.2",
|
||||
"js-base64": "^2.4.5",
|
||||
"lodash": "^4.17.10",
|
||||
"markdown-it-flowdock": "^0.3.7",
|
||||
"moment": "^2.22.1",
|
||||
"prop-types": "^15.6.1",
|
||||
"react": "^16.3.2",
|
||||
|
@ -43,7 +44,6 @@
|
|||
"react-native-action-button": "^2.8.3",
|
||||
"react-native-actionsheet": "^2.4.2",
|
||||
"react-native-audio": "^4.1.3",
|
||||
"react-native-easy-markdown": "git+https://github.com/diegolmello/react-native-easy-markdown.git",
|
||||
"react-native-fabric": "^0.5.1",
|
||||
"react-native-fast-image": "^4.0.14",
|
||||
"react-native-fetch-blob": "^0.10.8",
|
||||
|
@ -51,6 +51,7 @@
|
|||
"react-native-keyboard-aware-scroll-view": "^0.5.0",
|
||||
"react-native-keyboard-input": "git+https://github.com/RocketChat/react-native-keyboard-input.git",
|
||||
"react-native-keyboard-tracking-view": "git+https://github.com/RocketChat/react-native-keyboard-tracking-view.git",
|
||||
"react-native-markdown-renderer": "git+https://github.com/RocketChat/react-native-markdown-renderer.git",
|
||||
"react-native-meteor": "^1.2.0",
|
||||
"react-native-modal": "^6.0.0",
|
||||
"react-native-optimized-flatlist": "^1.0.4",
|
||||
|
@ -75,7 +76,6 @@
|
|||
"redux-immutable-state-invariant": "^2.1.0",
|
||||
"redux-saga": "^0.16.0",
|
||||
"regenerator-runtime": "^0.11.1",
|
||||
"simple-markdown": "^0.4.1",
|
||||
"snyk": "^1.80.1",
|
||||
"strip-ansi": "^4.0.0"
|
||||
},
|
||||
|
|
Loading…
Reference in New Issue