diff --git a/.circleci/config.yml b/.circleci/config.yml index 750a4726..9b97ca20 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -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 diff --git a/__tests__/__snapshots__/RoomItem.js.snap b/__tests__/__snapshots__/RoomItem.js.snap index 079beb68..a8963e9b 100644 --- a/__tests__/__snapshots__/RoomItem.js.snap +++ b/__tests__/__snapshots__/RoomItem.js.snap @@ -160,9 +160,9 @@ exports[`render channel 1`] = ` @@ -332,9 +332,9 @@ exports[`render no icon 1`] = ` @@ -504,9 +504,9 @@ exports[`render private group 1`] = ` @@ -744,9 +744,9 @@ exports[`render unread +999 1`] = ` @@ -1006,9 +1006,9 @@ exports[`render unread 1`] = ` @@ -1268,9 +1268,9 @@ exports[`renders correctly 1`] = ` diff --git a/__tests__/__snapshots__/Storyshots.test.js.snap b/__tests__/__snapshots__/Storyshots.test.js.snap index 1751229c..8088a0a5 100644 --- a/__tests__/__snapshots__/Storyshots.test.js.snap +++ b/__tests__/__snapshots__/Storyshots.test.js.snap @@ -551,9 +551,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -789,9 +789,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1023,9 +1023,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1284,9 +1284,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1541,9 +1541,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -1798,9 +1798,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -2055,9 +2055,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -2312,9 +2312,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -2569,9 +2569,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -2803,9 +2803,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` @@ -3037,9 +3037,9 @@ exports[`Storyshots Channel Cell Direct Messages 1`] = ` diff --git a/app/containers/message/Markdown.js b/app/containers/message/Markdown.js index 1dc11b8f..019ddf0a 100644 --- a/app/containers/message/Markdown.js +++ b/app/containers/message/Markdown.js @@ -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 }) => ( - - {node.content} - -); -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: ( - alert('Username')} - > - {node.content} - - ) - } - }) - }, - 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: ( - alert('Room')} - > - {node.content} - - ) - } - }) - }, - 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: { - 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: ( - - ) - } - }) - } -}; - -const codeStyle = StyleSheet.flatten(styles.codeStyle); +import MarkdownEmojiPlugin from './MarkdownEmojiPlugin'; // Support 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 ( - ({ content: capture }), - react: (node, output, state) => { - const element = { - type: 'custom', - key: state.key, - props: { - children: {node.content[0]} - } - }; - const content = node.content[1]; + ...Platform.OS === 'android' ? {} : { + paragraph: (node, children) => ( + + {children} + + ) + }, + mention: node => ( + alert(`Username @${ node.content }`)} style={styles.mention}> + @{node.content} + + ), + hashtag: node => ( + alert(`Room #${ node.content }`)} style={styles.mention}> + #{node.content} + + ), + 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 = ( - - ); + return ; } - return element; + return :{content}:; } + 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} - + ); } } @@ -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 }; diff --git a/app/containers/message/MarkdownEmojiPlugin.js b/app/containers/message/MarkdownEmojiPlugin.js new file mode 100644 index 00000000..17e46c63 --- /dev/null +++ b/app/containers/message/MarkdownEmojiPlugin.js @@ -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); +} diff --git a/app/containers/message/styles.js b/app/containers/message/styles.js index 8421b09e..71ae6719 100644 --- a/app/containers/message/styles.js +++ b/app/containers/message/styles.js @@ -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' } }); diff --git a/app/presentation/RoomItem.js b/app/presentation/RoomItem.js index 719d6d7a..f2401d69 100644 --- a/app/presentation/RoomItem.js +++ b/app/presentation/RoomItem.js @@ -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 { ( + + @{node.content} + + ), + hashtag: node => ( + + #{node.content} + + ) + }} /> {renderNumber(unread, userMentions)} diff --git a/app/sagas/mentionedMessages.js b/app/sagas/mentionedMessages.js index b7e45dc6..6543a15c 100644 --- a/app/sagas/mentionedMessages.js +++ b/app/sagas/mentionedMessages.js @@ -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) { diff --git a/app/sagas/pinnedMessages.js b/app/sagas/pinnedMessages.js index eb945abe..b14007f8 100644 --- a/app/sagas/pinnedMessages.js +++ b/app/sagas/pinnedMessages.js @@ -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) { diff --git a/app/sagas/roomFiles.js b/app/sagas/roomFiles.js index a75b13df..e258b6c6 100644 --- a/app/sagas/roomFiles.js +++ b/app/sagas/roomFiles.js @@ -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) { diff --git a/app/sagas/snippetedMessages.js b/app/sagas/snippetedMessages.js index 6301afd6..de7831e8 100644 --- a/app/sagas/snippetedMessages.js +++ b/app/sagas/snippetedMessages.js @@ -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) { diff --git a/app/sagas/starredMessages.js b/app/sagas/starredMessages.js index af9f5ffe..dcba2895 100644 --- a/app/sagas/starredMessages.js +++ b/app/sagas/starredMessages.js @@ -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) { diff --git a/e2e/05-roomslist.spec.js b/e2e/05-roomslist.spec.js index f73526e5..62485b84 100644 --- a/e2e/05-roomslist.spec.js +++ b/e2e/05-roomslist.spec.js @@ -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 diff --git a/e2e/09-roominfo.spec.js b/e2e/09-roominfo.spec.js index 0eeda19e..06037a7d 100644 --- a/e2e/09-roominfo.spec.js +++ b/e2e/09-roominfo.spec.js @@ -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() => { diff --git a/e2e/11-broadcast.spec.js b/e2e/11-broadcast.spec.js index 5ae9344e..988eb68a 100644 --- a/e2e/11-broadcast.spec.js +++ b/e2e/11-broadcast.spec.js @@ -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(); diff --git a/package-lock.json b/package-lock.json index c7cadaf4..62ea43ee 100644 --- a/package-lock.json +++ b/package-lock.json @@ -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", diff --git a/package.json b/package.json index 5b2488d7..60b02618 100644 --- a/package.json +++ b/package.json @@ -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" },