From 60f781d20e24ca92f9cd2c5dd9ef41de16fd0767 Mon Sep 17 00:00:00 2001 From: Diego Mello Date: Mon, 18 Jul 2022 16:56:12 -0300 Subject: [PATCH 01/72] Bump version to 4.30.0 (#4378) --- android/app/build.gradle | 2 +- ios/RocketChatRN.xcodeproj/project.pbxproj | 4 ++-- ios/RocketChatRN/Info.plist | 2 +- ios/ShareRocketChatRN/Info.plist | 2 +- package.json | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/android/app/build.gradle b/android/app/build.gradle index 4455d876c..caff3ff8b 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -144,7 +144,7 @@ android { minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion versionCode VERSIONCODE as Integer - versionName "4.29.0" + versionName "4.30.0" vectorDrawables.useSupportLibrary = true if (!isFoss) { manifestPlaceholders = [BugsnagAPIKey: BugsnagAPIKey as String] diff --git a/ios/RocketChatRN.xcodeproj/project.pbxproj b/ios/RocketChatRN.xcodeproj/project.pbxproj index a55210119..087750766 100644 --- a/ios/RocketChatRN.xcodeproj/project.pbxproj +++ b/ios/RocketChatRN.xcodeproj/project.pbxproj @@ -1683,7 +1683,7 @@ INFOPLIST_FILE = NotificationService/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 4.29.0; + MARKETING_VERSION = 4.30.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; @@ -1720,7 +1720,7 @@ INFOPLIST_FILE = NotificationService/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 11.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; - MARKETING_VERSION = 4.29.0; + MARKETING_VERSION = 4.30.0; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = chat.rocket.reactnative.NotificationService; PRODUCT_NAME = "$(TARGET_NAME)"; diff --git a/ios/RocketChatRN/Info.plist b/ios/RocketChatRN/Info.plist index 1fd00c980..74b24292f 100644 --- a/ios/RocketChatRN/Info.plist +++ b/ios/RocketChatRN/Info.plist @@ -26,7 +26,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 4.29.0 + 4.30.0 CFBundleSignature ???? CFBundleURLTypes diff --git a/ios/ShareRocketChatRN/Info.plist b/ios/ShareRocketChatRN/Info.plist index 4001b7e29..ea8840afb 100644 --- a/ios/ShareRocketChatRN/Info.plist +++ b/ios/ShareRocketChatRN/Info.plist @@ -26,7 +26,7 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 4.29.0 + 4.30.0 CFBundleVersion 1 KeychainGroup diff --git a/package.json b/package.json index ef766f4b6..b303c397f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "rocket-chat-reactnative", - "version": "4.29.0", + "version": "4.30.0", "private": true, "scripts": { "start": "react-native start", From 1c1dfe5af1dc7e7cc2846631607619cf9d92b8eb Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Wed, 20 Jul 2022 17:49:51 -0300 Subject: [PATCH 02/72] [FIX] Share Extension shows a server that has no user logged in (#4336) * [FIX] Share Extension shows a server that has no user logged in * set server after login --- app/sagas/login.js | 4 ++-- app/sagas/selectServer.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/sagas/login.js b/app/sagas/login.js index 28843515d..1a9318806 100644 --- a/app/sagas/login.js +++ b/app/sagas/login.js @@ -20,7 +20,7 @@ import { inquiryRequest, inquiryReset } from '../ee/omnichannel/actions/inquiry' import { isOmnichannelStatusAvailable } from '../ee/omnichannel/lib'; import { RootEnum } from '../definitions'; import sdk from '../lib/services/sdk'; -import { TOKEN_KEY } from '../lib/constants'; +import { CURRENT_SERVER, TOKEN_KEY } from '../lib/constants'; import { getCustomEmojis, getEnterpriseModules, @@ -181,9 +181,9 @@ const handleLoginSuccess = function* handleLoginSuccess({ user }) { UserPreferences.setString(`${TOKEN_KEY}-${server}`, user.id); UserPreferences.setString(`${TOKEN_KEY}-${user.id}`, user.token); + UserPreferences.setString(CURRENT_SERVER, server); yield put(setUser(user)); EventEmitter.emit('connected'); - yield put(appStart({ root: RootEnum.ROOT_INSIDE })); const inviteLinkToken = yield select(state => state.inviteLinks.token); if (inviteLinkToken) { diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js index b6669db01..9e65fa7bf 100644 --- a/app/sagas/selectServer.js +++ b/app/sagas/selectServer.js @@ -78,7 +78,6 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch yield put(encryptionStop()); yield put(clearActiveUsers()); const serversDB = database.servers; - UserPreferences.setString(CURRENT_SERVER, server); const userId = UserPreferences.getString(`${TOKEN_KEY}-${server}`); const userCollections = serversDB.get('users'); let user = null; @@ -117,6 +116,7 @@ const handleSelectServer = function* handleSelectServer({ server, version, fetch yield put(setUser(user)); yield connect({ server, logoutOnError: true }); yield put(appStart({ root: RootEnum.ROOT_INSIDE })); + UserPreferences.setString(CURRENT_SERVER, server); // only set server after have a user } else { yield put(clearUser()); yield connect({ server }); From 376c8e8252c8cf1443aa0212845c8453c5f38783 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Wed, 20 Jul 2022 18:02:18 -0300 Subject: [PATCH 03/72] [IMPROVE] Add support to Linebreak and Katex on markdown (#4361) * fix enableMessageParser logic * create LineBreak component * fix code style * add KaTeX support * add Katex and Inline Katex stories * update snapshots * add color prop * update snapshot * update snapshot --- app/containers/markdown/index.tsx | 2 +- app/containers/markdown/new/Code.tsx | 16 +-- app/containers/markdown/new/CodeLine.tsx | 10 +- app/containers/markdown/new/Inline.tsx | 6 +- app/containers/markdown/new/Katex.tsx | 20 +++ app/containers/markdown/new/LineBreak.tsx | 6 + app/containers/markdown/new/index.tsx | 12 +- app/containers/markdown/styles.ts | 8 +- app/externalModules.d.ts | 1 + jest.setup.js | 10 ++ package.json | 1 + storybook/stories/NewMarkdown.js | 39 ++++++ .../stories/__snapshots__/Markdown.storyshot | 2 +- .../__snapshots__/NewMarkdown.storyshot | 6 +- yarn.lock | 129 ++++++++++++++++++ 15 files changed, 248 insertions(+), 20 deletions(-) create mode 100644 app/containers/markdown/new/Katex.tsx create mode 100644 app/containers/markdown/new/LineBreak.tsx diff --git a/app/containers/markdown/index.tsx b/app/containers/markdown/index.tsx index 7b7c3f92b..676cb4b8b 100644 --- a/app/containers/markdown/index.tsx +++ b/app/containers/markdown/index.tsx @@ -138,7 +138,7 @@ class Markdown extends PureComponent { get isNewMarkdown(): boolean { const { md, enableMessageParser } = this.props; - return !!enableMessageParser && !!md; + return (enableMessageParser ?? true) && !!md; } renderText = ({ context, literal }: { context: []; literal: string }) => { diff --git a/app/containers/markdown/new/Code.tsx b/app/containers/markdown/new/Code.tsx index f8303a2b6..9680e0b03 100644 --- a/app/containers/markdown/new/Code.tsx +++ b/app/containers/markdown/new/Code.tsx @@ -1,9 +1,8 @@ import React from 'react'; -import { Text } from 'react-native'; +import { View } from 'react-native'; import { Code as CodeProps } from '@rocket.chat/message-parser'; import styles from '../styles'; -import { themes } from '../../../lib/constants'; import { useTheme } from '../../../theme'; import CodeLine from './CodeLine'; @@ -11,17 +10,16 @@ interface ICodeProps { value: CodeProps['value']; } -const Code = ({ value }: ICodeProps) => { - const { theme } = useTheme(); +const Code = ({ value }: ICodeProps): React.ReactElement => { + const { colors } = useTheme(); return ( - {value.map(block => { @@ -32,7 +30,7 @@ const Code = ({ value }: ICodeProps) => { return null; } })} - + ); }; diff --git a/app/containers/markdown/new/CodeLine.tsx b/app/containers/markdown/new/CodeLine.tsx index 77641447d..7c836c28e 100644 --- a/app/containers/markdown/new/CodeLine.tsx +++ b/app/containers/markdown/new/CodeLine.tsx @@ -1,17 +1,21 @@ +import { CodeLine as CodeLineProps } from '@rocket.chat/message-parser'; import React from 'react'; import { Text } from 'react-native'; -import { CodeLine as CodeLineProps } from '@rocket.chat/message-parser'; + +import { useTheme } from '../../../theme'; +import styles from '../styles'; interface ICodeLineProps { value: CodeLineProps['value']; } -const CodeLine = ({ value }: ICodeLineProps) => { +const CodeLine = ({ value }: ICodeLineProps): React.ReactElement | null => { + const { colors } = useTheme(); if (value.type !== 'PLAIN_TEXT') { return null; } - return {value.value}; + return {value.value}; }; export default CodeLine; diff --git a/app/containers/markdown/new/Inline.tsx b/app/containers/markdown/new/Inline.tsx index c9ad9211b..e1a2f8ffd 100644 --- a/app/containers/markdown/new/Inline.tsx +++ b/app/containers/markdown/new/Inline.tsx @@ -14,12 +14,13 @@ import Emoji from './Emoji'; import InlineCode from './InlineCode'; import Image from './Image'; import MarkdownContext from './MarkdownContext'; +// import { InlineKaTeX, KaTeX } from './Katex'; interface IParagraphProps { value: ParagraphProps['value']; } -const Inline = ({ value }: IParagraphProps) => { +const Inline = ({ value }: IParagraphProps): React.ReactElement | null => { const { useRealName, username, navToRoomInfo, mentions, channels } = useContext(MarkdownContext); return ( @@ -53,6 +54,9 @@ const Inline = ({ value }: IParagraphProps) => { return ; case 'INLINE_CODE': return ; + case 'INLINE_KATEX': + // return ; + return {block.value}; default: return null; } diff --git a/app/containers/markdown/new/Katex.tsx b/app/containers/markdown/new/Katex.tsx new file mode 100644 index 000000000..1ec705cc0 --- /dev/null +++ b/app/containers/markdown/new/Katex.tsx @@ -0,0 +1,20 @@ +import React from 'react'; +import { KaTeX as KaTeXProps } from '@rocket.chat/message-parser'; +// eslint-disable-next-line import/no-unresolved +import MathView, { MathText } from 'react-native-math-view'; + +import { useTheme } from '../../../theme'; + +interface IKaTeXProps { + value: KaTeXProps['value']; +} + +export const KaTeX = ({ value }: IKaTeXProps): React.ReactElement | null => { + const { colors } = useTheme(); + return ; +}; + +export const InlineKaTeX = ({ value }: IKaTeXProps): React.ReactElement | null => { + const { colors } = useTheme(); + return ; +}; diff --git a/app/containers/markdown/new/LineBreak.tsx b/app/containers/markdown/new/LineBreak.tsx new file mode 100644 index 000000000..1d2397f6a --- /dev/null +++ b/app/containers/markdown/new/LineBreak.tsx @@ -0,0 +1,6 @@ +import React from 'react'; +import { View } from 'react-native'; + +export default function LineBreak() { + return ; +} diff --git a/app/containers/markdown/new/index.tsx b/app/containers/markdown/new/index.tsx index f5e7e587c..0e0f8ed9d 100644 --- a/app/containers/markdown/new/index.tsx +++ b/app/containers/markdown/new/index.tsx @@ -12,6 +12,8 @@ import UnorderedList from './UnorderedList'; import { IUserMention, IUserChannel, TOnLinkPress } from '../interfaces'; import TaskList from './TaskList'; import MarkdownContext from './MarkdownContext'; +import LineBreak from './LineBreak'; +import { KaTeX } from './Katex'; interface IBodyProps { tokens?: MarkdownAST; @@ -35,7 +37,7 @@ const Body = ({ getCustomEmoji, baseUrl, onLinkPress -}: IBodyProps) => { +}: IBodyProps): React.ReactElement | null => { if (isEmpty(tokens)) { return null; } @@ -70,6 +72,14 @@ const Body = ({ return ; case 'HEADING': return ; + case 'LINE_BREAK': + return ; + // This prop exists, but not even on the web it is treated, so... + // https://github.com/RocketChat/Rocket.Chat/blob/develop/packages/gazzodown/src/Markup.tsx + // case 'LIST_ITEM': + // return ; + case 'KATEX': + return ; default: return null; } diff --git a/app/containers/markdown/styles.ts b/app/containers/markdown/styles.ts index f26ded1ce..a153cfc0a 100644 --- a/app/containers/markdown/styles.ts +++ b/app/containers/markdown/styles.ts @@ -83,13 +83,15 @@ export default StyleSheet.create({ paddingTop: 2 }, codeBlock: { - fontSize: 16, - ...sharedStyles.textRegular, - ...codeFontFamily, borderWidth: 1, borderRadius: 4, padding: 4 }, + codeBlockText: { + fontSize: 16, + ...sharedStyles.textRegular, + ...codeFontFamily + }, link: { fontSize: 16, ...sharedStyles.textRegular diff --git a/app/externalModules.d.ts b/app/externalModules.d.ts index 535265d73..c825f6bb4 100644 --- a/app/externalModules.d.ts +++ b/app/externalModules.d.ts @@ -11,3 +11,4 @@ declare module 'react-native-mime-types'; declare module 'react-native-restart'; declare module 'react-native-jitsi-meet'; declare module 'rn-root-view'; +declare module 'react-native-math-view'; diff --git a/jest.setup.js b/jest.setup.js index 2c2955e42..0efa7abdd 100644 --- a/jest.setup.js +++ b/jest.setup.js @@ -68,3 +68,13 @@ jest.mock('@gorhom/bottom-sheet', () => { BottomSheetScrollView: react.ScrollView }; }); + +// If you need to manually mock a lib use this mock pattern and set exports. +jest.mock('react-native-math-view', () => { + const react = require('react-native'); + return { + __esModule: true, + default: react.View, // Default export + MathText: react.View // {...} Named export + }; +}); diff --git a/package.json b/package.json index b303c397f..7829f0d86 100644 --- a/package.json +++ b/package.json @@ -97,6 +97,7 @@ "react-native-jitsi-meet": "RocketChat/react-native-jitsi-meet", "react-native-keycommands": "2.0.3", "react-native-localize": "2.1.1", + "react-native-math-view": "^3.9.5", "react-native-mime-types": "2.3.0", "react-native-mmkv-storage": "0.6.12", "react-native-modal": "11.10.0", diff --git a/storybook/stories/NewMarkdown.js b/storybook/stories/NewMarkdown.js index 84fd9ad7e..f7d7384ff 100644 --- a/storybook/stories/NewMarkdown.js +++ b/storybook/stories/NewMarkdown.js @@ -692,3 +692,42 @@ stories.add('Lists', () => ( )); + +const katex = [ + { + type: 'KATEX', + value: ' f(x) = \\int_{-\\infty}^\\infty \\hat f(\\xi)\\,e^{2 \\pi i \\xi x} \\,d\\xi ' + } +]; + +const inlineKatex = [ + { + type: 'PARAGRAPH', + value: [ + { + type: 'INLINE_KATEX', + value: 'This text includes math notations and should be wrapped correctly for $\\alpha$ and $\\beta$ within the view.' + }, + { + type: 'INLINE_KATEX', + value: "The following formula shouldn't be inline:$$x_{1,2} = {-b \\pm \\sqrt{b^2-4ac} \\over 2a}$$" + }, + { + type: 'INLINE_KATEX', + value: 'However the following formula should be inline with the text: \\( a^2 + b^2 = c^2 \\)' + } + ] + } +]; + +stories.add('Katex', () => ( + + + +)); + +stories.add('Inline Katex', () => ( + + + +)); diff --git a/storybook/stories/__snapshots__/Markdown.storyshot b/storybook/stories/__snapshots__/Markdown.storyshot index 33e3f38f8..9aa18b742 100644 --- a/storybook/stories/__snapshots__/Markdown.storyshot +++ b/storybook/stories/__snapshots__/Markdown.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots Markdown Block quote 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"alignItems\\":\\"flex-start\\",\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":\\"100%\\",\\"width\\":2,\\"marginRight\\":5},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"This is block quote\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},null,{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"This is block quote\\"]}]}]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"this is a normal line\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"this is a normal line\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; -exports[`Storyshots Markdown Code 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"This is \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"This is \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"inline code\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Inline \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"Inline \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"code\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" has \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" has \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"back-ticks around\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" it.\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" it.\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"padding\\":4,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"Code block\\\\n\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; +exports[`Storyshots Markdown Code 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"This is \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"This is \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"inline code\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Inline \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"Inline \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"code\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" has \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" has \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2,\\"color\\":\\"#2f343d\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"back-ticks around\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" it.\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" it.\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"borderWidth\\":1,\\"borderRadius\\":4,\\"padding\\":4,\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#f1f2f4\\"}]},\\"children\\":[\\"Code block\\\\n\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; exports[`Storyshots Markdown Emoji 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Unicode: 😃😇👍\\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"Unicode: 😃😇👍\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Shortnames: \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"Shortnames: \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{}]},\\"children\\":[\\"😂\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{}]},\\"children\\":[\\"👍\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Custom emojis: \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"Custom emojis: \\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":20,\\"height\\":20},{}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/react_rocket.png\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" \\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":20,\\"height\\":20},{}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/nyan_rocket.png\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" \\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":20,\\"height\\":20},{}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/marioparty.gif\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},null,{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"😃 \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\"😃 \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{}]},\\"children\\":[\\"👍\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" \\",\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},[{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"marginTop\\":0,\\"marginBottom\\":0,\\"flexWrap\\":\\"wrap\\",\\"flexDirection\\":\\"row\\",\\"alignItems\\":\\"flex-start\\",\\"justifyContent\\":\\"flex-start\\"}]]},\\"children\\":[\\" \\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":30,\\"height\\":30},{}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/marioparty.gif\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; diff --git a/storybook/stories/__snapshots__/NewMarkdown.storyshot b/storybook/stories/__snapshots__/NewMarkdown.storyshot index 4b5e52546..76379e065 100644 --- a/storybook/stories/__snapshots__/NewMarkdown.storyshot +++ b/storybook/stories/__snapshots__/NewMarkdown.storyshot @@ -2,7 +2,7 @@ exports[`Storyshots NewMarkdown Block quote 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"alignItems\\":\\"flex-start\\",\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":\\"100%\\",\\"width\\":2,\\"marginRight\\":5},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Rocket.Chat to the moon\\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Rocket.Chat to the moon\\"]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"alignItems\\":\\"flex-start\\",\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"height\\":\\"100%\\",\\"width\\":2,\\"marginRight\\":5},{\\"backgroundColor\\":\\"#e1e5e8\\"}]},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; -exports[`Storyshots NewMarkdown Code 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"inline code\\"]}]}]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"padding\\":4},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"Multi \\\\nLine \\\\nCode\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; +exports[`Storyshots NewMarkdown Code 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"inline code\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"borderWidth\\":1,\\"borderRadius\\":4,\\"padding\\":4},{\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Multi \\\\nLine \\\\nCode\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; exports[`Storyshots NewMarkdown Emoji 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"💚\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"😂\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":30,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"😁\\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"🚀\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"🤦\\"]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":20,\\"height\\":20}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/nyan_rocket.png\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"overflow\\":\\"hidden\\"},[{\\"width\\":20,\\"height\\":20}]]},\\"children\\":[{\\"type\\":\\"FastImageView\\",\\"props\\":{\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0},\\"source\\":{\\"uri\\":\\"https://open.rocket.chat/emoji-custom/marioparty.gif\\",\\"priority\\":\\"high\\"},\\"resizeMode\\":\\"contain\\"},\\"children\\":null}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; @@ -10,6 +10,10 @@ exports[`Storyshots NewMarkdown Hashtag 1`] = `"{\\"type\\":\\"View\\",\\"props\ exports[`Storyshots NewMarkdown Headers 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"700\\",\\"fontSize\\":24},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"# Header 1\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"700\\",\\"fontSize\\":22},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"## Header 2\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\",\\"fontSize\\":20},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"### Header 3\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\",\\"fontSize\\":18},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"#### Header 4\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"500\\",\\"fontSize\\":16},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"##### Header 5\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"500\\",\\"fontSize\\":14},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"###### Header 6\\"]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; +exports[`Storyshots NewMarkdown Inline Katex 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"This text includes math notations and should be wrapped correctly for $\\\\\\\\alpha$ and $\\\\\\\\beta$ within the view.\\"]},{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"The following formula shouldn't be inline:$$x_{1,2} = {-b \\\\\\\\pm \\\\\\\\sqrt{b^2-4ac} \\\\\\\\over 2a}$$\\"]},{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\"However the following formula should be inline with the text: \\\\\\\\( a^2 + b^2 = c^2 \\\\\\\\)\\"]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; + +exports[`Storyshots NewMarkdown Katex 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"math\\":\\" f(x) = \\\\\\\\int_{-\\\\\\\\infty}^\\\\\\\\infty \\\\\\\\hat f(\\\\\\\\xi)\\\\\\\\,e^{2 \\\\\\\\pi i \\\\\\\\xi x} \\\\\\\\,d\\\\\\\\xi \\",\\"style\\":{\\"color\\":\\"#2f343d\\"}},\\"children\\":null}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; + exports[`Storyshots NewMarkdown Links 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#1d74f5\\"}]},\\"children\\":[\\"https://rocket.chat\\"]}]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#1d74f5\\"}]},\\"children\\":[\\"Markdown link\\"]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; exports[`Storyshots NewMarkdown Lists 1`] = `"{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNCSafeAreaProvider\\",\\"props\\":{\\"style\\":[{\\"flex\\":1},null]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},null]},\\"children\\":[{\\"type\\":\\"RNSScreenContainer\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"RNSScreen\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"activityState\\":2,\\"style\\":{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"collapsable\\":false,\\"style\\":{\\"opacity\\":1}},\\"children\\":null},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"closing\\":false,\\"gestureVelocityImpact\\":0.3,\\"transitionSpec\\":{\\"open\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}},\\"close\\":{\\"animation\\":\\"spring\\",\\"config\\":{\\"stiffness\\":1000,\\"damping\\":500,\\"mass\\":3,\\"overshootClamping\\":true,\\"restDisplacementThreshold\\":10,\\"restSpeedThreshold\\":10}}},\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":[{\\"display\\":\\"flex\\"},{\\"position\\":\\"absolute\\",\\"left\\":0,\\"right\\":0,\\"top\\":0,\\"bottom\\":0}]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"needsOffscreenAlphaCompositing\\":false,\\"style\\":{\\"flex\\":1,\\"transform\\":[{\\"translateX\\":0},{\\"translateX\\":0}]}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":[{\\"flex\\":1,\\"overflow\\":\\"hidden\\"},[{\\"backgroundColor\\":\\"rgb(242, 242, 242)\\"},{\\"backgroundColor\\":\\"#ffffff\\"}]]},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1,\\"flexDirection\\":\\"column-reverse\\"}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flex\\":1}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"marginHorizontal\\":15,\\"backgroundColor\\":\\"#ffffff\\",\\"marginVertical\\":50}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"- \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Plain text \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Plain text \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"💡\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"fontStyle\\":\\"italic\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" italic \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" italic \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"700\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" bold \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" bold \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textDecorationLine\\":\\"line-through\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" strike \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" strike \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"#general\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#1d74f5\\"}]},\\"children\\":[\\" link \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"rocket.cat\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\" inline code\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"- \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"1\\",\\". \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Plain text \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Plain text \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"💡\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"fontStyle\\":\\"italic\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" italic \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" italic \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"700\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" bold \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" bold \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textDecorationLine\\":\\"line-through\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" strike \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" strike \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"#general\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#1d74f5\\"}]},\\"children\\":[\\" link \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"rocket.cat\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\" inline code\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"2\\",\\". \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"- [x] \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Plain text \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Plain text \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"color\\":\\"#2f343d\\"},{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"}]},\\"children\\":[\\"💡\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"fontStyle\\":\\"italic\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" italic \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" italic \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"700\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" bold \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" bold \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"textDecorationLine\\":\\"line-through\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\" strike \\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\" strike \\"]}]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"#general\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#1d74f5\\"}]},\\"children\\":[\\" link \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"600\\"},{\\"color\\":\\"#F3BE08\\"}]},\\"children\\":[\\"rocket.cat\\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"Courier New\\",\\"fontWeight\\":\\"400\\",\\"borderWidth\\":1,\\"borderRadius\\":4,\\"paddingLeft\\":2,\\"paddingTop\\":2},{\\"color\\":\\"#2f343d\\",\\"backgroundColor\\":\\"#f1f2f4\\",\\"borderColor\\":\\"#e1e5e8\\"}]},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{},\\"children\\":[\\" inline code\\"]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"style\\":{\\"flexDirection\\":\\"row\\"}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":[{\\"fontSize\\":16,\\"textAlign\\":\\"left\\",\\"backgroundColor\\":\\"transparent\\",\\"fontFamily\\":\\"System\\",\\"fontWeight\\":\\"400\\"},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"- [ ] \\"]},{\\"type\\":\\"Text\\",\\"props\\":{\\"style\\":{\\"flexShrink\\":1}},\\"children\\":[{\\"type\\":\\"Text\\",\\"props\\":{\\"accessibilityLabel\\":\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\",\\"style\\":[{\\"fontSize\\":16,\\"flexShrink\\":1},{\\"color\\":\\"#2f343d\\"}]},\\"children\\":[\\"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industrys standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries\\"]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{}},\\"children\\":[{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"accessibilityElementsHidden\\":false,\\"importantForAccessibility\\":\\"auto\\",\\"style\\":null},\\"children\\":null}]}]}]}]}]}]}]}]},{\\"type\\":\\"View\\",\\"props\\":{\\"pointerEvents\\":\\"box-none\\",\\"style\\":{\\"zIndex\\":1,\\"height\\":44,\\"position\\":\\"absolute\\",\\"top\\":0,\\"left\\":0,\\"right\\":0}},\\"children\\":null}]}]}]}"`; diff --git a/yarn.lock b/yarn.lock index 484f38cdb..265aaea04 100644 --- a/yarn.lock +++ b/yarn.lock @@ -4654,6 +4654,13 @@ resolved "https://registry.yarnpkg.com/@types/hammerjs/-/hammerjs-2.0.41.tgz#f6ecf57d1b12d2befcce00e928a6a097c22980aa" integrity sha512-ewXv/ceBaJprikMcxCmWU1FKyMAQ2X7a9Gtmzw8fcg2kIePI1crERDM818W+XYrxqdBBOdlf2rm137bU+BltCA== +"@types/hast@^2.0.0": + version "2.3.4" + resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc" + integrity sha512-wLEm0QvaoawEDoTRwzTXp4b4jpwiJDvR5KMnFnVodm3scufTlBOWRD6N1OBf9TZMhjlNsSfcO5V+7AF4+Vy+9g== + dependencies: + "@types/unist" "*" + "@types/history@*": version "4.7.6" resolved "https://registry.yarnpkg.com/@types/history/-/history-4.7.6.tgz#ed8fc802c45b8e8f54419c2d054e55c9ea344356" @@ -4949,6 +4956,11 @@ dependencies: source-map "^0.6.1" +"@types/unist@*": + version "2.0.6" + resolved "https://registry.yarnpkg.com/@types/unist/-/unist-2.0.6.tgz#250a7b16c3b91f672a24552ec64678eeb1d3a08d" + integrity sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ== + "@types/url-parse@^1.4.8": version "1.4.8" resolved "https://registry.yarnpkg.com/@types/url-parse/-/url-parse-1.4.8.tgz#c3825047efbca1295b7f1646f38203d9145130d6" @@ -7370,6 +7382,11 @@ comma-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz#632b80b6117867a158f1080ad498b2fbe7e3f5ea" integrity sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw== +comma-separated-tokens@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/comma-separated-tokens/-/comma-separated-tokens-2.0.2.tgz#d4c25abb679b7751c880be623c1179780fe1dd98" + integrity sha512-G5yTt3KQN4Yn7Yk4ed73hlZ1evrFKXeUW3086p3PRFNp7m2vIjI6Pg+Kgb+oyzhd9F2qdcoj67+y3SdxL5XWsg== + command-exists@^1.2.8: version "1.2.9" resolved "https://registry.yarnpkg.com/command-exists/-/command-exists-1.2.9.tgz#c50725af3808c8ab0260fd60b01fbfa25b954f69" @@ -7405,6 +7422,11 @@ command-line-usage@^6.1.0: table-layout "^1.0.1" typical "^5.2.0" +commander@9.2.0: + version "9.2.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.2.0.tgz#6e21014b2ed90d8b7c9647230d8b7a94a4a419a9" + integrity sha512-e2i4wANQiSXgnrBlIatyHtP1odfUp0BbV5Y5nEGbxtIrStkEOAAzCUirvLBNXHLr7kwLvJl6V+4V3XV9x7Wd9w== + commander@^2.19.0, commander@^2.20.0: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" @@ -7853,6 +7875,11 @@ css-select@^4.2.1: domutils "^2.8.0" nth-check "^2.0.1" +css-selector-parser@^1.0.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.4.1.tgz#03f9cb8a81c3e5ab2c51684557d5aaf6d2569759" + integrity sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g== + css-to-react-native@^2.2.1: version "2.3.2" resolved "https://registry.yarnpkg.com/css-to-react-native/-/css-to-react-native-2.3.2.tgz#e75e2f8f7aa385b4c3611c52b074b70a002f2e7d" @@ -8987,6 +9014,11 @@ eslint@^7.31.0: text-table "^0.2.0" v8-compile-cache "^2.0.3" +esm@^3.2.25: + version "3.2.25" + resolved "https://registry.yarnpkg.com/esm/-/esm-3.2.25.tgz#342c18c29d56157688ba5ce31f8431fbb795cc10" + integrity sha512-U1suiZ2oDVWv4zPO56S0NcR5QriEahGtdN2OR6FiOG4WJvcjBVFB0qI4+eKoWFH483PKGuLuu6V8Z4T5g63UVA== + espree@^7.3.0, espree@^7.3.1: version "7.3.1" resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6" @@ -10338,11 +10370,28 @@ hash.js@^1.0.0, hash.js@^1.0.3: inherits "^2.0.3" minimalistic-assert "^1.0.1" +hast-util-from-selector@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/hast-util-from-selector/-/hast-util-from-selector-2.0.0.tgz#b78142068b26a7996f5e1cfc7069067d5468773b" + integrity sha512-ynzm+z7xEecWF8DvnJ5onpGIsfmXphKRsZUnWCfinKwP+fL1/2mYW1nWOVife61syQpF74j4h/57BT6e5niDwA== + dependencies: + "@types/hast" "^2.0.0" + css-selector-parser "^1.0.0" + hastscript "^7.0.0" + zwitch "^2.0.0" + hast-util-parse-selector@^2.0.0: version "2.2.4" resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-2.2.4.tgz#60c99d0b519e12ab4ed32e58f150ec3f61ed1974" integrity sha512-gW3sxfynIvZApL4L07wryYF4+C9VvH3AUi7LAnVXV4MneGEgwOByXvFo18BgmTWnm7oHAe874jKbIB1YhHSIzA== +hast-util-parse-selector@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/hast-util-parse-selector/-/hast-util-parse-selector-3.1.0.tgz#a519e27e8b61bd5a98fad494ed06131ce68d9c3f" + integrity sha512-AyjlI2pTAZEOeu7GeBPZhROx0RHBnydkQIXlhnFzDi0qfXTmGUWoCYZtomHbrdrheV4VFUlPcfJ6LMF5T6sQzg== + dependencies: + "@types/hast" "^2.0.0" + hastscript@^5.0.0: version "5.1.2" resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-5.1.2.tgz#bde2c2e56d04c62dd24e8c5df288d050a355fb8a" @@ -10353,6 +10402,17 @@ hastscript@^5.0.0: property-information "^5.0.0" space-separated-tokens "^1.0.0" +hastscript@^7.0.0: + version "7.0.2" + resolved "https://registry.yarnpkg.com/hastscript/-/hastscript-7.0.2.tgz#d811fc040817d91923448a28156463b2e40d590a" + integrity sha512-uA8ooUY4ipaBvKcMuPehTAB/YfFLSSzCwFSwT6ltJbocFUKH/GDHLN+tflq7lSRf9H86uOuxOFkh1KgIy3Gg2g== + dependencies: + "@types/hast" "^2.0.0" + comma-separated-tokens "^2.0.0" + hast-util-parse-selector "^3.0.0" + property-information "^6.0.0" + space-separated-tokens "^2.0.0" + he@1.2.0, he@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f" @@ -12764,6 +12824,16 @@ markdown-to-jsx@^6.11.4: prop-types "^15.6.2" unquote "^1.1.0" +mathjax-full@^3.1.4: + version "3.2.2" + resolved "https://registry.yarnpkg.com/mathjax-full/-/mathjax-full-3.2.2.tgz#43f02e55219db393030985d2b6537ceae82f1fa7" + integrity sha512-+LfG9Fik+OuI8SLwsiR02IVdjcnRCy5MufYLi0C3TdMT56L/pjB0alMVGgoWJF8pN9Rc7FESycZB9BMNWIid5w== + dependencies: + esm "^3.2.25" + mhchemparser "^4.1.0" + mj-context-menu "^0.6.1" + speech-rule-engine "^4.0.6" + md5-file@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/md5-file/-/md5-file-3.2.3.tgz#f9bceb941eca2214a4c0727f5e700314e770f06f" @@ -13119,6 +13189,11 @@ metro@0.64.0, metro@^0.64.0: ws "^1.1.5" yargs "^15.3.1" +mhchemparser@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/mhchemparser/-/mhchemparser-4.1.1.tgz#a2142fdab37a02ec8d1b48a445059287790becd5" + integrity sha512-R75CUN6O6e1t8bgailrF1qPq+HhVeFTM3XQ0uzI+mXTybmphy3b6h4NbLOYhemViQ3lUs+6CKRkC3Ws1TlYREA== + microevent.ts@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/microevent.ts/-/microevent.ts-0.1.1.tgz#70b09b83f43df5172d0205a63025bce0f7357fa0" @@ -13322,6 +13397,11 @@ mixin-object@^2.0.1: for-in "^0.1.3" is-extendable "^0.1.1" +mj-context-menu@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/mj-context-menu/-/mj-context-menu-0.6.1.tgz#a043c5282bf7e1cf3821de07b13525ca6f85aa69" + integrity sha512-7NO5s6n10TIV96d4g2uDpG7ZDpIhMh0QNfGdJw/W47JswFcosz457wqz/b5sAKvl12sxINGFCn80NZHKwxQEXA== + mkdirp@^0.5.1, mkdirp@^0.5.3, mkdirp@~0.5.1: version "0.5.5" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def" @@ -14769,6 +14849,11 @@ property-information@^5.0.0: dependencies: xtend "^4.0.0" +property-information@^6.0.0: + version "6.1.1" + resolved "https://registry.yarnpkg.com/property-information/-/property-information-6.1.1.tgz#5ca85510a3019726cb9afed4197b7b8ac5926a22" + integrity sha512-hrzC564QIl0r0vy4l6MvRLhafmUowhO/O3KgVSoXIbbA2Sz4j8HGpJc6T2cubRVwMwpdiG/vKGfhT4IixmKN9w== + proxy-addr@~2.0.5: version "2.0.6" resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-2.0.6.tgz#fdc2336505447d3f2f2c638ed272caf614bbb2bf" @@ -15237,6 +15322,16 @@ react-native-localize@2.1.1: resolved "https://registry.yarnpkg.com/react-native-localize/-/react-native-localize-2.1.1.tgz#da8f8776991d2b748708c408db05152602cefb38" integrity sha512-+uyz2/b0vyLq19fcb7r1qU1gqmzbp3aC6EMTvOVXwfBuiN+aJXR/fDdFOJJ8D7+bLccKeuS2zBDrazh+ZayX/g== +react-native-math-view@^3.9.5: + version "3.9.5" + resolved "https://registry.yarnpkg.com/react-native-math-view/-/react-native-math-view-3.9.5.tgz#59c6fb0bef8eb460bf16bbdf8169e57ceb12eb4c" + integrity sha512-UJxrisNafszfqIW+utoSDylb72SkZ92cKz1IfE5Dm0s+uIaHxOxepF2DdRbktAV8c0FEFllnXfErcGdh8sfIBw== + dependencies: + hast-util-from-selector "^2.0.0" + lodash "^4.17.21" + mathjax-full "^3.1.4" + transformation-matrix "^2.8.0" + react-native-mime-types@2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/react-native-mime-types/-/react-native-mime-types-2.3.0.tgz#1278602c3da94ffb47c6400ef861901c4ebac420" @@ -16784,6 +16879,11 @@ space-separated-tokens@^1.0.0: resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz#85f32c3d10d9682007e917414ddc5c26d1aa6899" integrity sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA== +space-separated-tokens@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/space-separated-tokens/-/space-separated-tokens-2.0.1.tgz#43193cec4fb858a2ce934b7f98b7f2c18107098b" + integrity sha512-ekwEbFp5aqSPKaqeY1PGrlGQxPNaq+Cnx4+bE2D8sciBQrHpbwoBbawqTN2+6jPs9IdWxxiUcN0K2pkczD3zmw== + spdx-correct@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4" @@ -16810,6 +16910,15 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz#3694b5804567a458d3c8045842a6358632f62654" integrity sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q== +speech-rule-engine@^4.0.6: + version "4.0.7" + resolved "https://registry.yarnpkg.com/speech-rule-engine/-/speech-rule-engine-4.0.7.tgz#b655dacbad3dae04acc0f7665e26ef258397dd09" + integrity sha512-sJrL3/wHzNwJRLBdf6CjJWIlxC04iYKkyXvYSVsWVOiC2DSkHmxsqOhEeMsBA9XK+CHuNcsdkbFDnoUfAsmp9g== + dependencies: + commander "9.2.0" + wicked-good-xpath "1.3.0" + xmldom-sre "0.1.31" + split-on-first@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/split-on-first/-/split-on-first-1.1.0.tgz#f610afeee3b12bce1d0c30425e76398b78249a5f" @@ -17672,6 +17781,11 @@ tr46@~0.0.3: resolved "https://registry.yarnpkg.com/tr46/-/tr46-0.0.3.tgz#8184fd347dac9cdc185992f3a6622e14b9d9ab6a" integrity sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o= +transformation-matrix@^2.8.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/transformation-matrix/-/transformation-matrix-2.12.0.tgz#cb826a23aa5d675d18940215ccb7613b8587830f" + integrity sha512-BbzXM7el7rNwIr1s87m8tcffH5qgY+HYROLn3BStRU9Y6vYTL37YZKadfNPEvGbP813iA1h8qflo4pa2TomkyQ== + truncate-utf8-bytes@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz#405923909592d56f78a5818434b0b78489ca5f2b" @@ -18477,6 +18591,11 @@ which@^1.2.9, which@^1.3.1: dependencies: isexe "^2.0.0" +wicked-good-xpath@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/wicked-good-xpath/-/wicked-good-xpath-1.3.0.tgz#81b0e95e8650e49c94b22298fff8686b5553cf6c" + integrity sha512-Gd9+TUn5nXdwj/hFsPVx5cuHHiF5Bwuc30jZ4+ronF1qHK5O7HD0sgmXWSEgwKquT3ClLoKPVbO6qGwVwLzvAw== + wide-align@1.1.3, wide-align@^1.1.0: version "1.1.3" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" @@ -18695,6 +18814,11 @@ xmldoc@^1.1.2: dependencies: sax "^1.2.1" +xmldom-sre@0.1.31: + version "0.1.31" + resolved "https://registry.yarnpkg.com/xmldom-sre/-/xmldom-sre-0.1.31.tgz#10860d5bab2c603144597d04bf2c4980e98067f4" + integrity sha512-f9s+fUkX04BxQf+7mMWAp5zk61pciie+fFLC9hX9UVvCeJQfNHRHXpeo5MPcR0EUf57PYLdt+ZO4f3Ipk2oZUw== + xmldom@~0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.5.0.tgz#193cb96b84aa3486127ea6272c4596354cb4962e" @@ -18819,3 +18943,8 @@ yocto-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + +zwitch@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/zwitch/-/zwitch-2.0.2.tgz#91f8d0e901ffa3d66599756dde7f57b17c95dce1" + integrity sha512-JZxotl7SxAJH0j7dN4pxsTV6ZLXoLdGME+PsjkL/DaBrVryK9kTGq06GfKrwcSOqypP+fdXGoCHE36b99fWVoA== From a965465af306a20a8ba514948952d34907023c78 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Thu, 28 Jul 2022 10:36:40 -0300 Subject: [PATCH 04/72] [FIX] Add support to non ascii url characters on ios devices (#4364) * add support to non ascii url caracters on ios * rename module and add tests * remove last slice --- app/lib/methods/index.ts | 1 + app/lib/methods/serializeAsciiUrl.test.ts | 30 +++++++++++++++++++++++ app/lib/methods/serializeAsciiUrl.ts | 13 ++++++++++ app/views/NewServerView/index.tsx | 4 +-- package.json | 1 + yarn.lock | 7 ++++++ 6 files changed, 54 insertions(+), 2 deletions(-) create mode 100644 app/lib/methods/serializeAsciiUrl.test.ts create mode 100644 app/lib/methods/serializeAsciiUrl.ts diff --git a/app/lib/methods/index.ts b/app/lib/methods/index.ts index 35b8cf512..7df26ec00 100644 --- a/app/lib/methods/index.ts +++ b/app/lib/methods/index.ts @@ -34,3 +34,4 @@ export * from './userPreferencesMethods'; export * from './crashReport'; export * from './parseSettings'; export * from './subscribeRooms'; +export * from './serializeAsciiUrl'; diff --git a/app/lib/methods/serializeAsciiUrl.test.ts b/app/lib/methods/serializeAsciiUrl.test.ts new file mode 100644 index 000000000..dec96a771 --- /dev/null +++ b/app/lib/methods/serializeAsciiUrl.test.ts @@ -0,0 +1,30 @@ +import { serializeAsciiUrl } from '.'; + +const ASCIIUrl = 'https://чат24.рф'; +const NonASCIIUrl = 'open.rocket.chat'; +const ASCIIUrlSerialized = 'https://xn--24-6kc6exa.xn--p1ai'; + +describe('Serialize ASCII url on ios', () => { + jest.mock('react-native', () => ({ Platform: { OS: 'ios' } })); + test('ASCII url', () => { + const result = serializeAsciiUrl(ASCIIUrl); + expect(result).toBe(ASCIIUrlSerialized); + }); + test('Non ASCII url', () => { + const result = serializeAsciiUrl(NonASCIIUrl); + expect(result).toBe(NonASCIIUrl); + }); +}); + +describe('Serialize ASCII url on android', () => { + jest.mock('react-native', () => ({ Platform: { OS: 'android' } })); + // By default android converts ASCII addresses + // test('ASCII url', () => { + // const result = serializeAsciiUrl(ASCIIUrl); + // expect(result).toBe('filename.png'); + // }); + test('Non ASCII url', () => { + const result = serializeAsciiUrl(NonASCIIUrl); + expect(result).toBe(NonASCIIUrl); + }); +}); diff --git a/app/lib/methods/serializeAsciiUrl.ts b/app/lib/methods/serializeAsciiUrl.ts new file mode 100644 index 000000000..c9963049d --- /dev/null +++ b/app/lib/methods/serializeAsciiUrl.ts @@ -0,0 +1,13 @@ +import * as uri from 'uri-js'; + +import { isIOS } from './helpers'; + +export const serializeAsciiUrl = (url: string): string => { + let newUrl = url; + const ascii = /^[ -~\t\n\r]+$/; + if (isIOS && !ascii.test(newUrl)) { + newUrl = uri.serialize(uri.parse(url)); + newUrl = newUrl.charAt(newUrl.length - 1) === '/' ? newUrl.slice(0, -1) : newUrl; + } + return newUrl; +}; diff --git a/app/views/NewServerView/index.tsx b/app/views/NewServerView/index.tsx index f4589039a..f246d7f62 100644 --- a/app/views/NewServerView/index.tsx +++ b/app/views/NewServerView/index.tsx @@ -31,6 +31,7 @@ import { moderateScale, verticalScale } from './scaling'; import SSLPinning from '../../lib/methods/helpers/sslPinning'; import sharedStyles from '../Styles'; import ServerInput from './ServerInput'; +import { serializeAsciiUrl } from '../../lib/methods'; const styles = StyleSheet.create({ onboardingImage: { @@ -257,8 +258,7 @@ class NewServerView extends React.Component uri.replace('file://', ''); diff --git a/package.json b/package.json index 7829f0d86..c3a015060 100644 --- a/package.json +++ b/package.json @@ -133,6 +133,7 @@ "rn-root-view": "1.0.3", "semver": "7.3.5", "ua-parser-js": "^1.0.2", + "uri-js": "^4.4.1", "url-parse": "1.5.10", "use-deep-compare-effect": "1.6.1", "xregexp": "5.0.2" diff --git a/yarn.lock b/yarn.lock index 265aaea04..cb3170660 100644 --- a/yarn.lock +++ b/yarn.lock @@ -18170,6 +18170,13 @@ uri-js@^4.2.2: dependencies: punycode "^2.1.0" +uri-js@^4.4.1: + version "4.4.1" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.4.1.tgz#9b1a52595225859e55f669d928f88c6c57f2a77e" + integrity sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg== + dependencies: + punycode "^2.1.0" + urix@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" From d7f7b1da9f7e973792f916442033a90f5b84bbb6 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Date: Fri, 29 Jul 2022 01:18:42 -0300 Subject: [PATCH 05/72] [FIX] iFrame login takes user to blank screen (#4389) --- app/sagas/selectServer.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/app/sagas/selectServer.js b/app/sagas/selectServer.js index 9e65fa7bf..cc01354c3 100644 --- a/app/sagas/selectServer.js +++ b/app/sagas/selectServer.js @@ -1,4 +1,4 @@ -import { put, takeLatest } from 'redux-saga/effects'; +import { put, takeLatest, select } from 'redux-saga/effects'; import { Alert } from 'react-native'; import { sanitizedRaw } from '@nozbe/watermelondb/RawRecord'; import { Q } from '@nozbe/watermelondb'; @@ -163,7 +163,8 @@ const handleServerRequest = function* handleServerRequest({ server, username, fr yield getLoginSettings({ server }); Navigation.navigate('WorkspaceView'); - if (fromServerHistory) { + const Accounts_iframe_enabled = yield select(state => state.settings.Accounts_iframe_enabled); + if (fromServerHistory && !Accounts_iframe_enabled) { Navigation.navigate('LoginView', { username }); } From 0e378c67b86fa8c693989dadc3e43f2f8a20bdac Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Fri, 29 Jul 2022 14:10:31 -0300 Subject: [PATCH 06/72] Chore: Try Github Actions (#4376) --- .github/workflow-android-experimental.yml | 76 +++++++++++++++++++++++ .github/workflow-ios-experimental.yml | 71 +++++++++++++++++++++ .github/workflow-test-and-lint.yml | 26 ++++++++ 3 files changed, 173 insertions(+) create mode 100644 .github/workflow-android-experimental.yml create mode 100644 .github/workflow-ios-experimental.yml create mode 100644 .github/workflow-test-and-lint.yml diff --git a/.github/workflow-android-experimental.yml b/.github/workflow-android-experimental.yml new file mode 100644 index 000000000..4aaca6e6e --- /dev/null +++ b/.github/workflow-android-experimental.yml @@ -0,0 +1,76 @@ +name: Build Android + +on: + pull_request: + types: ["labeled"] + +jobs: + build-android: + if: contains(github.event.pull_request.labels.*.name, 'android-build') + + name: Build Android + runs-on: ubuntu-latest + environment: develop + defaults: + run: + working-directory: android + + env: + JAVA_OPTS: "-Xms512m -Xmx2g" + GRADLE_OPTS: '-Xmx3g -Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx2g -XX:+HeapDumpOnOutOfMemoryError"' + TERM: dumb + + steps: + - name: Check out Git repository + uses: actions/checkout@v3 + + - name: Decode Keystore + run: echo ${{ secrets.KEYSTORE_BASE_64 }} | base64 -d > ./app/key.keystore + + - uses: c-hive/gha-yarn-cache@v2 + + - name: Install dependencies + run: yarn install --prefer-offline + + - name: Set up JDK 11 + uses: actions/setup-java@v3 + with: + distribution: "zulu" + java-version: 11.0.14 + cache: "gradle" + + - name: Make Gradlew Executable + run: chmod +x ./gradlew + + - name: Set gradle.properties + run: | + echo -e "" > ./gradle.properties + echo -e android.useAndroidX=true >> ./gradle.properties + echo -e android.enableJetifier=true >> ./gradle.properties + echo -e FLIPPER_VERSION=0.51.0 >> ./gradle.properties + echo -e VERSIONCODE=${{ github.run_number }} >> ./gradle.properties + echo -e APPLICATION_ID=chat.rocket.reactnative >> ./gradle.properties + echo -e BugsnagAPIKey=${{ secrets.BUGSNAG_KEY }} >> ./gradle.properties + echo -e KEYSTORE=${{ secrets.KEYSTORE }} >> ./gradle.properties + echo -e KEYSTORE_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }} >> ./gradle.properties + echo -e KEY_ALIAS=${{ secrets.KEY_ALIAS }} >> ./gradle.properties + echo -e KEY_PASSWORD=${{ secrets.KEYSTORE_PASSWORD }} >> ./gradle.properties + + - name: Generate App APK + run: | + ./gradlew bundleExperimentalPlayRelease --no-daemon + + - name: Upload sourcemaps to Bugsnag + run: | + npx bugsnag-source-maps upload-react-native \ + --api-key=${{ secrets.BUGSNAG_KEY }} \ + --app-version-code=${{ github.event.number }} \ + --platform android \ + --source-map=app/build/generated/sourcemaps/react/experimentalPlay/release/app.bundle.map \ + --bundle app/build/generated/assets/react/experimentalPlay/release/app.bundle + + - name: Store Artifacts + uses: actions/upload-artifact@v3 + with: + name: app.bundle-${{ github.event.number }} + path: app/build/generated/assets/react/experimentalPlay/release/app.bundle diff --git a/.github/workflow-ios-experimental.yml b/.github/workflow-ios-experimental.yml new file mode 100644 index 000000000..8cf8c4a71 --- /dev/null +++ b/.github/workflow-ios-experimental.yml @@ -0,0 +1,71 @@ +name: Build iOS + +on: + pull_request: + types: ['labeled'] + +jobs: + build-android: + if: contains(github.event.pull_request.labels.*.name, 'ios-build') + + name: Build iOS + runs-on: macos-latest + environment: develop + defaults: + run: + working-directory: ios + + steps: + - name: Check out Git repository + uses: actions/checkout@v3 + + - uses: c-hive/gha-yarn-cache@v2 + + - name: Install dependencies + run: yarn install --prefer-offline + + - name: Setup Ruby (bundle) + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.6 + bundler-cache: true + - run: bundle install + + - name: Restore Pods cache + uses: actions/cache@v2 + with: + path: | + ios/Pods + ~/Library/Caches/CocoaPods + ~/.cocoapods + key: ${{ runner.os }}-pods-${{ hashFiles('ios/Podfile.lock') }} + restore-keys: | + ${{ runner.os }}-pods- + + - name: Install Pods + run: pod install --repo-update && cd .. + + - name: Set version + run: agvtool new-version -all ${{ github.run_number }} + + - name: Set Keys + run: | + /usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey ${{ secrets.BUGSNAG_KEY }}" ./RocketChatRN/Info.plist + /usr/libexec/PlistBuddy -c "Set :bugsnag:apiKey ${{ secrets.BUGSNAG_KEY }}" ./ShareRocketChatRN/Info.plist + /usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./RocketChatRN/Info.plist + /usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./ShareRocketChatRN/Info.plist + /usr/libexec/PlistBuddy -c "Set IS_OFFICIAL NO" ./NotificationService/Info.plist + + - name: Decode P8 + run: echo ${{ secrets.APP_STORE_CONNECT_API_BASE64 }} | base64 --decode > ./fastlane/app_store_connect_api_key.p8 + + - name: Run fastlane + run: fastlane ios build_experimental + + - name: Store Artifacts + uses: actions/upload-artifact@v3 + with: + name: Rocket.Chat.${{ github.event.number }}.ipa + path: | + Rocket.Chat.ipa + Rocket.Chat.app.dSYM.zip diff --git a/.github/workflow-test-and-lint.yml b/.github/workflow-test-and-lint.yml new file mode 100644 index 000000000..294f67f77 --- /dev/null +++ b/.github/workflow-test-and-lint.yml @@ -0,0 +1,26 @@ +name: Test and Lint + +on: [push] + +jobs: + test-and-lint: + name: Test and lint + runs-on: ubuntu-latest + + steps: + - name: Check out Git repository + uses: actions/checkout@v2 + + - uses: c-hive/gha-yarn-cache@v2 + + - name: Install dependencies + run: yarn install --prefer-offline + + - name: Lint + run: yarn lint + + - name: Test + run: yarn test -w 8 + + - name: Codecov + run: yarn codecov From 5875454a70186c200834e38c95d80afd9ed6d587 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Fri, 29 Jul 2022 14:18:11 -0300 Subject: [PATCH 07/72] [FIX] Github Actions folder (#4400) --- .github/{ => workflows}/workflow-android-experimental.yml | 0 .github/{ => workflows}/workflow-ios-experimental.yml | 0 .github/{ => workflows}/workflow-test-and-lint.yml | 0 3 files changed, 0 insertions(+), 0 deletions(-) rename .github/{ => workflows}/workflow-android-experimental.yml (100%) rename .github/{ => workflows}/workflow-ios-experimental.yml (100%) rename .github/{ => workflows}/workflow-test-and-lint.yml (100%) diff --git a/.github/workflow-android-experimental.yml b/.github/workflows/workflow-android-experimental.yml similarity index 100% rename from .github/workflow-android-experimental.yml rename to .github/workflows/workflow-android-experimental.yml diff --git a/.github/workflow-ios-experimental.yml b/.github/workflows/workflow-ios-experimental.yml similarity index 100% rename from .github/workflow-ios-experimental.yml rename to .github/workflows/workflow-ios-experimental.yml diff --git a/.github/workflow-test-and-lint.yml b/.github/workflows/workflow-test-and-lint.yml similarity index 100% rename from .github/workflow-test-and-lint.yml rename to .github/workflows/workflow-test-and-lint.yml From 41dbbf4d4b88b6152595bcbd91847142ca4cb785 Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Mon, 1 Aug 2022 13:35:05 -0300 Subject: [PATCH 08/72] Chore: Migrate NotificationPreferencesView to hooks (#4327) * add none option * create showErrorAlertWithEMessage function * migrate NotificationPreferencesView to hooks and improves overall * change icon to right * fix navigation options * remove none * fix types * remove memo * cleaning * switching to destructuring * add observe for hideUnreadStatus * fix desktop options * remove unused options Co-authored-by: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> --- app/containers/ActionSheet/Item.tsx | 9 +- app/containers/ActionSheet/Provider.tsx | 2 +- app/containers/ActionSheet/styles.ts | 1 - app/definitions/IRoom.ts | 1 + app/lib/methods/helpers/info.ts | 8 + app/stacks/InsideStack.tsx | 6 +- app/stacks/MasterDetailStack/index.tsx | 6 +- .../NotificationPreferencesView/index.tsx | 436 ++++++++---------- .../NotificationPreferencesView/options.ts | 53 +-- 9 files changed, 208 insertions(+), 314 deletions(-) diff --git a/app/containers/ActionSheet/Item.tsx b/app/containers/ActionSheet/Item.tsx index 2b0b50080..7b48dcefd 100644 --- a/app/containers/ActionSheet/Item.tsx +++ b/app/containers/ActionSheet/Item.tsx @@ -26,11 +26,16 @@ export const Item = React.memo(({ item, hide }: IActionSheetItem) => { style={[styles.item, { backgroundColor: themes[theme].focusedBackground }]} theme={theme} testID={item.testID}> - + {item.icon ? ( + + ) : null} + style={[ + styles.title, + { color: item.danger ? themes[theme].dangerColor : themes[theme].bodyText, marginLeft: item.icon ? 16 : 0 } + ]}> {item.title} diff --git a/app/containers/ActionSheet/Provider.tsx b/app/containers/ActionSheet/Provider.tsx index 945bb9aff..b7caf6416 100644 --- a/app/containers/ActionSheet/Provider.tsx +++ b/app/containers/ActionSheet/Provider.tsx @@ -6,7 +6,7 @@ import ActionSheet from './ActionSheet'; export type TActionSheetOptionsItem = { title: string; - icon: TIconsName; + icon?: TIconsName; danger?: boolean; testID?: string; onPress: () => void; diff --git a/app/containers/ActionSheet/styles.ts b/app/containers/ActionSheet/styles.ts index 3ffb90240..4c099c71b 100644 --- a/app/containers/ActionSheet/styles.ts +++ b/app/containers/ActionSheet/styles.ts @@ -27,7 +27,6 @@ export default StyleSheet.create({ }, title: { fontSize: 16, - marginLeft: 16, ...sharedStyles.textRegular }, handle: { diff --git a/app/definitions/IRoom.ts b/app/definitions/IRoom.ts index 1444d4fef..d49eccf67 100644 --- a/app/definitions/IRoom.ts +++ b/app/definitions/IRoom.ts @@ -237,6 +237,7 @@ export interface IRoomNotifications { desktopNotifications?: TNotifications; mobilePushNotifications?: TNotifications; emailNotifications?: TNotifications; + hideMentionStatus?: boolean; } export type TRoomNotificationsModel = IRoomNotifications & Model; diff --git a/app/lib/methods/helpers/info.ts b/app/lib/methods/helpers/info.ts index 4971f743e..2fc903d04 100644 --- a/app/lib/methods/helpers/info.ts +++ b/app/lib/methods/helpers/info.ts @@ -5,6 +5,14 @@ import I18n from '../../../i18n'; export const showErrorAlert = (message: string, title?: string, onPress = () => {}): void => Alert.alert(title || '', message, [{ text: 'OK', onPress }], { cancelable: true }); +export const showErrorAlertWithEMessage = (e: any): void => { + const messageError = + e.data && e.data.error.includes('[error-too-many-requests]') + ? I18n.t('error-too-many-requests', { seconds: e.data.error.replace(/\D/g, '') }) + : e.data.errorType; + showErrorAlert(messageError); +}; + interface IShowConfirmationAlert { title?: string; message: string; diff --git a/app/stacks/InsideStack.tsx b/app/stacks/InsideStack.tsx index ea17fee27..10889aac8 100644 --- a/app/stacks/InsideStack.tsx +++ b/app/stacks/InsideStack.tsx @@ -111,11 +111,7 @@ const ChatsStackNavigator = () => { - + diff --git a/app/stacks/MasterDetailStack/index.tsx b/app/stacks/MasterDetailStack/index.tsx index bf9a1425e..890e52c5a 100644 --- a/app/stacks/MasterDetailStack/index.tsx +++ b/app/stacks/MasterDetailStack/index.tsx @@ -151,11 +151,7 @@ const ModalStackNavigator = React.memo(({ navigation }: INavigation) => { options={props => DirectoryView.navigationOptions!({ ...props, isMasterDetail: true })} /> - + diff --git a/app/views/NotificationPreferencesView/index.tsx b/app/views/NotificationPreferencesView/index.tsx index aa2931f0f..7029e5a7d 100644 --- a/app/views/NotificationPreferencesView/index.tsx +++ b/app/views/NotificationPreferencesView/index.tsx @@ -1,282 +1,222 @@ -import React from 'react'; -import { StyleSheet, Switch, Text } from 'react-native'; -import { RouteProp } from '@react-navigation/core'; -import { StackNavigationProp } from '@react-navigation/stack'; -import { Observable, Subscription } from 'rxjs'; -import { connect } from 'react-redux'; +import { RouteProp, useNavigation, useRoute } from '@react-navigation/core'; +import React, { useEffect, useState } from 'react'; +import { Switch, Text } from 'react-native'; -import database from '../../lib/database'; -import { SWITCH_TRACK_COLOR, themes } from '../../lib/constants'; -import StatusBar from '../../containers/StatusBar'; +import { TActionSheetOptionsItem, useActionSheet } from '../../containers/ActionSheet'; +import { CustomIcon } from '../../containers/CustomIcon'; import * as List from '../../containers/List'; -import I18n from '../../i18n'; -import { TSupportedThemes, withTheme } from '../../theme'; -import protectedFunction from '../../lib/methods/helpers/protectedFunction'; import SafeAreaView from '../../containers/SafeAreaView'; -import log, { events, logEvent } from '../../lib/methods/helpers/log'; -import sharedStyles from '../Styles'; -import { IOptionsField, OPTIONS } from './options'; -import { ChatsStackParamList } from '../../stacks/types'; -import { IApplicationState, IRoomNotifications, TRoomNotificationsModel } from '../../definitions'; -import { Services } from '../../lib/services'; +import StatusBar from '../../containers/StatusBar'; +import { IRoomNotifications, TRoomNotificationsModel } from '../../definitions'; +import I18n from '../../i18n'; +import { SWITCH_TRACK_COLOR } from '../../lib/constants'; +import { useAppSelector } from '../../lib/hooks'; +import { showErrorAlertWithEMessage } from '../../lib/methods/helpers'; import { compareServerVersion } from '../../lib/methods/helpers/compareServerVersion'; +import log, { events, logEvent } from '../../lib/methods/helpers/log'; +import { Services } from '../../lib/services'; +import { ChatsStackParamList } from '../../stacks/types'; +import { useTheme } from '../../theme'; +import sharedStyles from '../Styles'; +import { OPTIONS } from './options'; -const styles = StyleSheet.create({ - pickerText: { - ...sharedStyles.textRegular, - fontSize: 16 - } -}); +type TOptions = keyof typeof OPTIONS; +type TRoomNotifications = keyof IRoomNotifications; +type TUnionOptionsRoomNotifications = TOptions | TRoomNotifications; -interface INotificationPreferencesViewProps { - navigation: StackNavigationProp; - route: RouteProp; - theme: TSupportedThemes; - serverVersion: string | null; -} - -interface INotificationPreferencesViewState { +interface IBaseParams { + preference: TUnionOptionsRoomNotifications; room: TRoomNotificationsModel; + onChangeValue: (pref: TUnionOptionsRoomNotifications, param: { [key: string]: string }, onError: () => void) => void; } -class NotificationPreferencesView extends React.Component { - static navigationOptions = () => ({ - title: I18n.t('Notification_Preferences') - }); +const RenderListPicker = ({ + preference, + room, + title, + testID, + onChangeValue +}: { + title: string; + testID: string; +} & IBaseParams) => { + const { showActionSheet, hideActionSheet } = useActionSheet(); + const { colors } = useTheme(); - private mounted: boolean; - private rid: string; - private roomObservable?: Observable; - private subscription?: Subscription; + const pref = room[preference] + ? OPTIONS[preference as TOptions].find(option => option.value === room[preference]) + : OPTIONS[preference as TOptions][0]; - constructor(props: INotificationPreferencesViewProps) { - super(props); - this.mounted = false; - this.rid = props.route.params?.rid ?? ''; - const room = props.route.params?.room; - this.state = { - room: room || {} - }; - if (room && room.observe) { - this.roomObservable = room.observe(); - this.subscription = this.roomObservable.subscribe(changes => { - if (this.mounted) { - this.setState({ room: changes }); - } else { - // @ts-ignore - this.state.room = changes; - } - }); - } - } + const [option, setOption] = useState(pref); - componentDidMount() { - this.mounted = true; - } + const options: TActionSheetOptionsItem[] = OPTIONS[preference as TOptions].map(i => ({ + title: I18n.t(i.label, { defaultValue: i.label, second: i.second }), + onPress: () => { + hideActionSheet(); + onChangeValue(preference, { [preference]: i.value.toString() }, () => setOption(option)); + setOption(i); + }, + right: option?.value === i.value ? () => : undefined + })); - componentWillUnmount() { - if (this.subscription && this.subscription.unsubscribe) { - this.subscription.unsubscribe(); - } - } + return ( + showActionSheet({ options })} + right={() => ( + + {option?.label ? I18n.t(option?.label, { defaultValue: option?.label, second: option?.second }) : option?.label} + + )} + /> + ); +}; - saveNotificationSettings = async (key: string, value: string | boolean, params: IRoomNotifications) => { - // @ts-ignore - logEvent(events[`NP_${key.toUpperCase()}`]); - const { room } = this.state; - const db = database.active; +const RenderSwitch = ({ preference, room, onChangeValue }: IBaseParams) => { + const [switchValue, setSwitchValue] = useState(!room[preference]); + return ( + { + onChangeValue(preference, { [preference]: switchValue ? '1' : '0' }, () => setSwitchValue(switchValue)); + setSwitchValue(value); + }} + /> + ); +}; +const NotificationPreferencesView = (): React.ReactElement => { + const route = useRoute>(); + const { rid, room } = route.params; + const navigation = useNavigation(); + const serverVersion = useAppSelector(state => state.server.version); + const [hideUnreadStatus, setHideUnreadStatus] = useState(room.hideUnreadStatus); + + useEffect(() => { + navigation.setOptions({ + title: I18n.t('Notification_Preferences') + }); + }, []); + + useEffect(() => { + const observe = room.observe(); + observe.subscribe(data => { + setHideUnreadStatus(data.hideUnreadStatus); + }); + }, []); + + const saveNotificationSettings = async (key: TUnionOptionsRoomNotifications, params: IRoomNotifications, onError: Function) => { try { - await db.write(async () => { - await room.update( - protectedFunction((r: IRoomNotifications) => { - r[key] = value; - }) - ); - }); - - try { - const result = await Services.saveNotificationSettings(this.rid, params); - if (result.success) { - return; - } - } catch { - // do nothing - } - - await db.write(async () => { - await room.update( - protectedFunction((r: IRoomNotifications) => { - r[key] = room[key]; - }) - ); - }); + // @ts-ignore + logEvent(events[`NP_${key.toUpperCase()}`]); + await Services.saveNotificationSettings(rid, params); } catch (e) { // @ts-ignore logEvent(events[`NP_${key.toUpperCase()}_F`]); log(e); + onError(); + showErrorAlertWithEMessage(e); } }; - onValueChangeSwitch = (key: string, value: string | boolean) => - this.saveNotificationSettings(key, value, { [key]: value ? '1' : '0' }); + return ( + + + + + + } + /> + + + - onValueChangePicker = (key: string, value: string) => this.saveNotificationSettings(key, value, { [key]: value.toString() }); + + + } + /> + + + - pickerSelection = (title: string, key: string) => { - const { room } = this.state; - const { navigation } = this.props; - navigation.navigate('PickerView', { - title, - data: OPTIONS[key], - value: room[key], - onChangeValue: (value: string) => this.onValueChangePicker(key, value) - }); - }; + + + } + /> + + + - renderPickerOption = (key: string) => { - const { room } = this.state; - const { theme } = this.props; - const text = room[key] ? OPTIONS[key].find(option => option.value === room[key]) : (OPTIONS[key][0] as IOptionsField); - return ( - - {text?.label ? I18n.t(text?.label, { defaultValue: text?.label, second: text?.second }) : text?.label} - - ); - }; - - renderSwitch = (key: string) => { - const { room } = this.state; - return ( - this.onValueChangeSwitch(key, !value)} - /> - ); - }; - - render() { - const { serverVersion } = this.props; - const { room } = this.state; - return ( - - - + {hideUnreadStatus && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '4.8.0') ? ( this.renderSwitch('disableNotifications')} + title='Show_badge_for_mentions' + testID='notification-preference-view-badge-for-mentions' + right={() => } /> - + + ) : null} - - - this.renderSwitch('muteGroupMentions')} - /> - - - + + + + + + + + + + + + + + + + + + + + + ); +}; - - - this.renderSwitch('hideUnreadStatus')} - /> - - - - - {room.hideUnreadStatus && compareServerVersion(serverVersion, 'greaterThanOrEqualTo', '4.8.0') ? ( - - - this.renderSwitch('hideMentionStatus')} - /> - - - - ) : null} - - - - this.pickerSelection(title, 'desktopNotifications')} - right={() => this.renderPickerOption('desktopNotifications')} - /> - - - - - - - this.pickerSelection(title, 'mobilePushNotifications')} - right={() => this.renderPickerOption('mobilePushNotifications')} - /> - - - - - - - this.pickerSelection(title, 'audioNotifications')} - right={() => this.renderPickerOption('audioNotifications')} - /> - - this.pickerSelection(title, 'audioNotificationValue')} - right={() => this.renderPickerOption('audioNotificationValue')} - /> - - this.pickerSelection(title, 'desktopNotificationDuration')} - right={() => this.renderPickerOption('desktopNotificationDuration')} - /> - - - - - - this.pickerSelection(title, 'emailNotifications')} - right={() => this.renderPickerOption('emailNotifications')} - /> - - - - - ); - } -} - -const mapStateToProps = (state: IApplicationState) => ({ - serverVersion: state.server.version -}); - -export default connect(mapStateToProps)(withTheme(NotificationPreferencesView)); +export default NotificationPreferencesView; diff --git a/app/views/NotificationPreferencesView/options.ts b/app/views/NotificationPreferencesView/options.ts index a2b3251c6..ee98aebbb 100644 --- a/app/views/NotificationPreferencesView/options.ts +++ b/app/views/NotificationPreferencesView/options.ts @@ -4,11 +4,9 @@ export interface IOptionsField { second?: number; } export interface INotificationOptions { - [desktopNotifications: string]: IOptionsField[]; - audioNotifications: IOptionsField[]; + desktopNotifications: IOptionsField[]; mobilePushNotifications: IOptionsField[]; emailNotifications: IOptionsField[]; - desktopNotificationDuration: IOptionsField[]; audioNotificationValue: IOptionsField[]; } @@ -31,24 +29,6 @@ export const OPTIONS: INotificationOptions = { value: 'nothing' } ], - audioNotifications: [ - { - label: 'Default', - value: 'default' - }, - { - label: 'All_Messages', - value: 'all' - }, - { - label: 'Mentions', - value: 'mentions' - }, - { - label: 'Nothing', - value: 'nothing' - } - ], mobilePushNotifications: [ { label: 'Default', @@ -85,37 +65,6 @@ export const OPTIONS: INotificationOptions = { value: 'nothing' } ], - desktopNotificationDuration: [ - { - label: 'Default', - value: 0 - }, - { - label: 'Seconds', - second: 1, - value: 1 - }, - { - label: 'Seconds', - second: 2, - value: 2 - }, - { - label: 'Seconds', - second: 3, - value: 3 - }, - { - label: 'Seconds', - second: 4, - value: 4 - }, - { - label: 'Seconds', - second: 5, - value: 5 - } - ], audioNotificationValue: [ { label: 'None', From 2c32be6e519ca6f04fe68816b7bc9b4455afa75c Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Mon, 1 Aug 2022 13:42:10 -0300 Subject: [PATCH 09/72] [FIX] Fix display order render on RoomListView (#4392) --- app/views/RoomsListView/index.tsx | 17 ++--------------- 1 file changed, 2 insertions(+), 15 deletions(-) diff --git a/app/views/RoomsListView/index.tsx b/app/views/RoomsListView/index.tsx index 90f22b749..84062f715 100644 --- a/app/views/RoomsListView/index.tsx +++ b/app/views/RoomsListView/index.tsx @@ -530,21 +530,6 @@ class RoomsListView extends React.Component ({ rid: item.rid, alert: item.alert })); - } else { - /** - * Otherwise, we trigger re-render only when chats order changes - * RoomItem handles its own re-render - */ - chatsUpdate = data.map(item => item.rid); - } - const isOmnichannelAgent = user?.roles?.includes('livechat-agent'); if (isOmnichannelAgent) { const omnichannel = chats.filter(s => filterIsOmnichannel(s)); @@ -586,6 +571,8 @@ class RoomsListView extends React.Component item.rid); + this.internalSetState({ chats: tempChats, chatsUpdate, From a4f171a12d0c5a1830ad71551a584df7028db10b Mon Sep 17 00:00:00 2001 From: Danish Ahmed Mirza <77742477+try-catch-stack@users.noreply.github.com> Date: Wed, 3 Aug 2022 22:02:16 +0530 Subject: [PATCH 10/72] [NEW] Redesign reactions list (#4346) --- app/containers/ActionSheet/ActionSheet.tsx | 2 + app/containers/ActionSheet/Provider.tsx | 1 + app/containers/ReactionsList.tsx | 143 ++++++++++++++++++ app/containers/ReactionsModal.tsx | 166 --------------------- app/definitions/index.ts | 1 + app/views/RoomView/index.tsx | 38 ++--- 6 files changed, 167 insertions(+), 184 deletions(-) create mode 100644 app/containers/ReactionsList.tsx delete mode 100644 app/containers/ReactionsModal.tsx diff --git a/app/containers/ActionSheet/ActionSheet.tsx b/app/containers/ActionSheet/ActionSheet.tsx index fb00d5267..e114b8e1c 100644 --- a/app/containers/ActionSheet/ActionSheet.tsx +++ b/app/containers/ActionSheet/ActionSheet.tsx @@ -140,6 +140,8 @@ const ActionSheet = React.memo( style={{ ...styles.container, ...bottomSheet }} backgroundStyle={{ backgroundColor: colors.focusedBackground }} onChange={index => index === -1 && onClose()} + // We need this to allow horizontal swipe gestures inside bottom sheet like in reaction picker + enableContentPanningGesture={data?.enableContentPanningGesture ?? true} {...androidTablet}> diff --git a/app/containers/ActionSheet/Provider.tsx b/app/containers/ActionSheet/Provider.tsx index b7caf6416..4b21726bc 100644 --- a/app/containers/ActionSheet/Provider.tsx +++ b/app/containers/ActionSheet/Provider.tsx @@ -22,6 +22,7 @@ export type TActionSheetOptions = { children?: React.ReactElement | null; snaps?: (string | number)[]; onClose?: () => void; + enableContentPanningGesture?: boolean; }; export interface IActionSheetProvider { showActionSheet: (item: TActionSheetOptions) => void; diff --git a/app/containers/ReactionsList.tsx b/app/containers/ReactionsList.tsx new file mode 100644 index 000000000..10a1b3c80 --- /dev/null +++ b/app/containers/ReactionsList.tsx @@ -0,0 +1,143 @@ +import React from 'react'; +import { StyleSheet, Text, Pressable, View, ScrollView } from 'react-native'; +import ScrollableTabView from 'react-native-scrollable-tab-view'; +import { FlatList } from 'react-native-gesture-handler'; + +import Emoji from './message/Emoji'; +import { useTheme } from '../theme'; +import { TGetCustomEmoji } from '../definitions/IEmoji'; +import { IReaction } from '../definitions'; +import Avatar from './Avatar'; +import sharedStyles from '../views/Styles'; + +const MIN_TAB_WIDTH = 70; + +const styles = StyleSheet.create({ + reactionsListContainer: { height: '100%', width: '100%' }, + tabBarItem: { + paddingHorizontal: 10, + paddingBottom: 10, + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row' + }, + reactionCount: { marginLeft: 5 }, + emojiName: { margin: 10 }, + userItemContainer: { marginHorizontal: 10, marginVertical: 5, flexDirection: 'row' }, + usernameContainer: { marginHorizontal: 10, justifyContent: 'center' }, + usernameText: { fontSize: 17, ...sharedStyles.textMedium }, + standardEmojiStyle: { fontSize: 20, color: '#fff' }, + customEmojiStyle: { width: 25, height: 25 } +}); + +interface IReactionsListBase { + baseUrl: string; + getCustomEmoji: TGetCustomEmoji; +} + +interface IReactionsListProps extends IReactionsListBase { + reactions?: IReaction[]; + width: number; +} + +interface ITabBarItem extends IReactionsListBase { + tab: IReaction; + index: number; + goToPage?: (index: number) => void; +} +interface IReactionsTabBar extends IReactionsListBase { + activeTab?: number; + tabs?: IReaction[]; + goToPage?: (index: number) => void; + width: number; +} + +const TabBarItem = ({ tab, index, goToPage, baseUrl, getCustomEmoji }: ITabBarItem) => { + const { colors } = useTheme(); + return ( + { + goToPage?.(index); + }} + style={({ pressed }: { pressed: boolean }) => ({ + opacity: pressed ? 0.7 : 1 + })}> + + + {tab.usernames.length} + + + ); +}; + +const ReactionsTabBar = ({ tabs, activeTab, goToPage, baseUrl, getCustomEmoji, width }: IReactionsTabBar) => { + const tabWidth = tabs && Math.max(width / tabs.length, MIN_TAB_WIDTH); + const { colors } = useTheme(); + return ( + + + {tabs?.map((tab, index) => { + const isActiveTab = activeTab === index; + return ( + + + + ); + })} + + + ); +}; + +const UsersList = ({ tabLabel }: { tabLabel: IReaction }) => { + const { colors } = useTheme(); + const { emoji, usernames } = tabLabel; + return ( + ( + + {emoji} + + )} + renderItem={({ item }) => ( + + + + {item} + + + )} + keyExtractor={item => item} + /> + ); +}; + +const ReactionsList = ({ reactions, baseUrl, getCustomEmoji, width }: IReactionsListProps): React.ReactElement => { + // sorting reactions in descending order on the basic of number of users reacted + const sortedReactions = reactions?.sort((reaction1, reaction2) => reaction2.usernames.length - reaction1.usernames.length); + + return ( + + }> + {sortedReactions?.map(reaction => ( + + ))} + + + ); +}; + +export default ReactionsList; diff --git a/app/containers/ReactionsModal.tsx b/app/containers/ReactionsModal.tsx deleted file mode 100644 index b74707f04..000000000 --- a/app/containers/ReactionsModal.tsx +++ /dev/null @@ -1,166 +0,0 @@ -import React from 'react'; -import { FlatList, StyleSheet, Text, View } from 'react-native'; -import Modal from 'react-native-modal'; -import Touchable from 'react-native-platform-touchable'; - -import Emoji from './message/Emoji'; -import I18n from '../i18n'; -import { CustomIcon } from './CustomIcon'; -import sharedStyles from '../views/Styles'; -import { themes } from '../lib/constants'; -import { TSupportedThemes, useTheme, withTheme } from '../theme'; -import { TGetCustomEmoji } from '../definitions/IEmoji'; -import { TMessageModel, ILoggedUser } from '../definitions'; -import SafeAreaView from './SafeAreaView'; - -const styles = StyleSheet.create({ - safeArea: { - backgroundColor: 'transparent' - }, - titleContainer: { - alignItems: 'center', - paddingVertical: 10 - }, - title: { - fontSize: 16, - ...sharedStyles.textSemibold, - ...sharedStyles.textAlignCenter - }, - reactCount: { - fontSize: 13, - ...sharedStyles.textRegular - }, - peopleReacted: { - fontSize: 14, - ...sharedStyles.textMedium - }, - peopleItemContainer: { - flex: 1, - flexDirection: 'column', - justifyContent: 'center' - }, - emojiContainer: { - width: 50, - height: 50, - alignItems: 'center', - justifyContent: 'center' - }, - itemContainer: { - height: 50, - flexDirection: 'row' - }, - listContainer: { - flex: 1 - }, - closeButton: { - position: 'absolute', - left: 0, - top: 10 - } -}); -const standardEmojiStyle = { fontSize: 20 }; -const customEmojiStyle = { width: 20, height: 20 }; - -interface ISharedFields { - user?: Pick; - baseUrl: string; - getCustomEmoji: TGetCustomEmoji; -} - -interface IItem extends ISharedFields { - item: { - usernames: string[]; - emoji: string; - }; -} - -interface IModalContent extends ISharedFields { - message?: TMessageModel; - onClose: () => void; - theme: TSupportedThemes; -} - -interface IReactionsModal extends ISharedFields { - message?: TMessageModel; - isVisible: boolean; - onClose(): void; -} - -const Item = React.memo(({ item, user, baseUrl, getCustomEmoji }: IItem) => { - const { theme } = useTheme(); - const count = item.usernames.length; - let usernames = item.usernames - .slice(0, 3) - .map((username: string) => (username === user?.username ? I18n.t('you') : username)) - .join(', '); - if (count > 3) { - usernames = `${usernames} ${I18n.t('and_more')} ${count - 3}`; - } else { - usernames = usernames.replace(/,(?=[^,]*$)/, ` ${I18n.t('and')}`); - } - return ( - - - - - - - {count === 1 ? I18n.t('1_person_reacted') : I18n.t('N_people_reacted', { n: count })} - - {usernames} - - - ); -}); - -const ModalContent = React.memo(({ message, onClose, ...props }: IModalContent) => { - if (message && message.reactions) { - return ( - - - - - {I18n.t('Reactions')} - - - } - keyExtractor={item => item.emoji} - /> - - ); - } - return null; -}); - -const ReactionsModal = React.memo( - ({ isVisible, onClose, ...props }: IReactionsModal) => { - const { theme } = useTheme(); - return ( - - - - ); - }, - (prevProps, nextProps) => prevProps.isVisible === nextProps.isVisible -); - -ReactionsModal.displayName = 'ReactionsModal'; -ModalContent.displayName = 'ReactionsModalContent'; -Item.displayName = 'ReactionsModalItem'; - -export default withTheme(ReactionsModal); diff --git a/app/definitions/index.ts b/app/definitions/index.ts index 4f7d7c3d3..cbe244639 100644 --- a/app/definitions/index.ts +++ b/app/definitions/index.ts @@ -28,6 +28,7 @@ export * from './ICredentials'; export * from './ISearch'; export * from './TUserStatus'; export * from './IProfile'; +export * from './IReaction'; export interface IBaseScreen, S extends string> { navigation: StackNavigationProp; diff --git a/app/views/RoomView/index.tsx b/app/views/RoomView/index.tsx index 0c79ddd41..f12177925 100644 --- a/app/views/RoomView/index.tsx +++ b/app/views/RoomView/index.tsx @@ -3,7 +3,6 @@ import { InteractionManager, Text, View } from 'react-native'; import { connect } from 'react-redux'; import parse from 'url-parse'; import moment from 'moment'; -import * as Haptics from 'expo-haptics'; import { Q } from '@nozbe/watermelondb'; import { dequal } from 'dequal'; import { EdgeInsets, withSafeAreaInsets } from 'react-native-safe-area-context'; @@ -22,7 +21,7 @@ import EventEmitter from '../../lib/methods/helpers/events'; import I18n from '../../i18n'; import RoomHeader from '../../containers/RoomHeader'; import StatusBar from '../../containers/StatusBar'; -import ReactionsModal from '../../containers/ReactionsModal'; +import ReactionsList from '../../containers/ReactionsList'; import { LISTENER } from '../../containers/Toast'; import { getBadgeColor, isBlocked, makeThreadName } from '../../lib/methods/helpers/room'; import { isReadOnly } from '../../lib/methods/helpers/isReadOnly'; @@ -100,6 +99,7 @@ import { hasPermission } from '../../lib/methods/helpers'; import { Services } from '../../lib/services'; +import { withActionSheet, TActionSheetOptions } from '../../containers/ActionSheet'; type TStateAttrsUpdate = keyof IRoomViewState; @@ -170,6 +170,7 @@ interface IRoomViewProps extends IBaseScreen { transferLivechatGuestPermission?: string[]; // TODO: Check if its the correct type viewCannedResponsesPermission?: string[]; // TODO: Check if its the correct type livechatAllowManualOnHold?: boolean; + showActionSheet: (options: TActionSheetOptions) => void; } interface IRoomViewState { @@ -853,12 +854,21 @@ class RoomView extends React.Component { }; onReactionLongPress = (message: TAnyMessageModel) => { - this.setState({ selectedMessage: message, reactionsModalVisible: true }); - Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); - }; - - onCloseReactionsModal = () => { - this.setState({ selectedMessage: undefined, reactionsModalVisible: false }); + this.setState({ selectedMessage: message }); + const { showActionSheet, baseUrl, width } = this.props; + const { selectedMessage } = this.state; + showActionSheet({ + children: ( + + ), + snaps: ['50%'], + enableContentPanningGesture: false + }); }; onEncryptedPress = () => { @@ -1469,7 +1479,7 @@ class RoomView extends React.Component { render() { console.count(`${this.constructor.name}.render calls`); - const { room, reactionsModalVisible, selectedMessage, loading, reacting, showingBlockingLoader } = this.state; + const { room, selectedMessage, loading, reacting, showingBlockingLoader } = this.state; const { user, baseUrl, theme, navigation, Hide_System_Messages, width, height, serverVersion } = this.props; const { rid, t } = room; let sysMes; @@ -1512,14 +1522,6 @@ class RoomView extends React.Component { theme={theme} /> - @@ -1545,4 +1547,4 @@ const mapStateToProps = (state: IApplicationState) => ({ livechatAllowManualOnHold: state.settings.Livechat_allow_manual_on_hold as boolean }); -export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(RoomView)))); +export default connect(mapStateToProps)(withDimensions(withTheme(withSafeAreaInsets(withActionSheet(RoomView))))); From e38aedcbff3db3649b71684286f2e78e0be67b15 Mon Sep 17 00:00:00 2001 From: Reinaldo Neto <47038980+reinaldonetof@users.noreply.github.com> Date: Mon, 8 Aug 2022 15:38:01 -0300 Subject: [PATCH 11/72] [IMPROVE] Add emoji picker to iOS (#4366) * [IMPROVE] Add emoji picker to iOS * clean left and right buttons * fix the redux in emojipicker * fix behavior when emoji keyboard is openning * added isIOS * fix show reactions when emoji is open * minor tweak * add provider * fix baseurl * minor tweak * create closeEmojiAndAction and added to record * fix actionsheet for omnichannel * fix action sheet * fix close emoji when navigate to other screen * added iactionsheetprovider to roomview * clean variables * fix theme * close the emojikeyboard when click on message * apoint package.json to new pr * fix branch * fix package.json --- app/containers/EmojiPicker/EmojiCategory.tsx | 1 + app/containers/EmojiPicker/index.tsx | 7 +- app/containers/MessageBox/EmojiKeyboard.tsx | 37 +++---- app/containers/MessageBox/LeftButtons.ios.tsx | 24 ----- ...eftButtons.android.tsx => LeftButtons.tsx} | 0 app/containers/MessageBox/RecordAudio.tsx | 4 + .../MessageBox/RightButtons.ios.tsx | 17 ---- ...htButtons.android.tsx => RightButtons.tsx} | 3 +- app/containers/MessageBox/constants.ts | 2 + app/containers/MessageBox/index.tsx | 40 ++++---- app/containers/message/index.tsx | 11 ++- app/views/RoomView/ReactionPicker.tsx | 6 +- app/views/RoomView/RightButtons.tsx | 98 ++++++++++--------- app/views/RoomView/index.tsx | 20 ++-- package.json | 2 +- yarn.lock | 6 +- 16 files changed, 129 insertions(+), 149 deletions(-) delete mode 100644 app/containers/MessageBox/LeftButtons.ios.tsx rename app/containers/MessageBox/{LeftButtons.android.tsx => LeftButtons.tsx} (100%) delete mode 100644 app/containers/MessageBox/RightButtons.ios.tsx rename app/containers/MessageBox/{RightButtons.android.tsx => RightButtons.tsx} (83%) diff --git a/app/containers/EmojiPicker/EmojiCategory.tsx b/app/containers/EmojiPicker/EmojiCategory.tsx index a7fb07b11..a1cf1f981 100644 --- a/app/containers/EmojiPicker/EmojiCategory.tsx +++ b/app/containers/EmojiPicker/EmojiCategory.tsx @@ -65,6 +65,7 @@ class EmojiCategory extends React.Component { initialNumToRender={45} removeClippedSubviews {...scrollPersistTaps} + keyboardDismissMode={'none'} /> ); } diff --git a/app/containers/EmojiPicker/index.tsx b/app/containers/EmojiPicker/index.tsx index 4bfa17b6a..558a23bb4 100644 --- a/app/containers/EmojiPicker/index.tsx +++ b/app/containers/EmojiPicker/index.tsx @@ -17,7 +17,7 @@ import protectedFunction from '../../lib/methods/helpers/protectedFunction'; import shortnameToUnicode from '../../lib/methods/helpers/shortnameToUnicode'; import log from '../../lib/methods/helpers/log'; import { themes } from '../../lib/constants'; -import { TSupportedThemes, withTheme } from '../../theme'; +import { TSupportedThemes } from '../../theme'; import { IEmoji, TGetCustomEmoji, IApplicationState, ICustomEmojis, TFrequentlyUsedEmojiModel } from '../../definitions'; interface IEmojiPickerProps { @@ -198,7 +198,8 @@ class EmojiPicker extends Component { } const mapStateToProps = (state: IApplicationState) => ({ - customEmojis: state.customEmojis + customEmojis: state.customEmojis, + baseUrl: state.share.server.server || state.server.server }); -export default connect(mapStateToProps)(withTheme(EmojiPicker)); +export default connect(mapStateToProps)(EmojiPicker); diff --git a/app/containers/MessageBox/EmojiKeyboard.tsx b/app/containers/MessageBox/EmojiKeyboard.tsx index 172b7f4b8..114733eeb 100644 --- a/app/containers/MessageBox/EmojiKeyboard.tsx +++ b/app/containers/MessageBox/EmojiKeyboard.tsx @@ -1,39 +1,28 @@ import React from 'react'; import { View } from 'react-native'; import { KeyboardRegistry } from 'react-native-ui-lib/keyboard'; +import { Provider } from 'react-redux'; -import { store } from '../../lib/store/auxStore'; +import store from '../../lib/store'; import EmojiPicker from '../EmojiPicker'; import styles from './styles'; import { themes } from '../../lib/constants'; -import { TSupportedThemes, withTheme } from '../../theme'; +import { TSupportedThemes } from '../../theme'; -interface IMessageBoxEmojiKeyboard { - theme: TSupportedThemes; -} - -export default class EmojiKeyboard extends React.PureComponent { - private readonly baseUrl: string; - - constructor(props: IMessageBoxEmojiKeyboard) { - super(props); - const state = store.getState(); - this.baseUrl = state.share.server.server || state.server.server; - } - - onEmojiSelected = (emoji: string) => { +const EmojiKeyboard = ({ theme }: { theme: TSupportedThemes }) => { + const onEmojiSelected = (emoji: string) => { KeyboardRegistry.onItemSelected('EmojiKeyboard', { emoji }); }; - render() { - const { theme } = this.props; - return ( + return ( + - + - ); - } -} -KeyboardRegistry.registerKeyboard('EmojiKeyboard', () => withTheme(EmojiKeyboard)); + + ); +}; + +KeyboardRegistry.registerKeyboard('EmojiKeyboard', () => EmojiKeyboard); diff --git a/app/containers/MessageBox/LeftButtons.ios.tsx b/app/containers/MessageBox/LeftButtons.ios.tsx deleted file mode 100644 index 94d253705..000000000 --- a/app/containers/MessageBox/LeftButtons.ios.tsx +++ /dev/null @@ -1,24 +0,0 @@ -import React from 'react'; -import { View } from 'react-native'; - -import { ActionsButton, CancelEditingButton } from './buttons'; -import styles from './styles'; - -interface IMessageBoxLeftButtons { - showMessageBoxActions(): void; - editing: boolean; - editCancel(): void; - isActionsEnabled: boolean; -} - -const LeftButtons = React.memo(({ showMessageBoxActions, editing, editCancel, isActionsEnabled }: IMessageBoxLeftButtons) => { - if (editing) { - return ; - } - if (isActionsEnabled) { - return ; - } - return ; -}); - -export default LeftButtons; diff --git a/app/containers/MessageBox/LeftButtons.android.tsx b/app/containers/MessageBox/LeftButtons.tsx similarity index 100% rename from app/containers/MessageBox/LeftButtons.android.tsx rename to app/containers/MessageBox/LeftButtons.tsx diff --git a/app/containers/MessageBox/RecordAudio.tsx b/app/containers/MessageBox/RecordAudio.tsx index 4b550b62b..1dd5e99ec 100644 --- a/app/containers/MessageBox/RecordAudio.tsx +++ b/app/containers/MessageBox/RecordAudio.tsx @@ -17,6 +17,7 @@ interface IMessageBoxRecordAudioProps { permissionToUpload: boolean; recordingCallback: Function; onFinish: Function; + onStart: Function; } const RECORDING_EXTENSION = '.m4a'; @@ -116,6 +117,9 @@ export default class RecordAudio extends React.PureComponent { + const { onStart } = this.props; + onStart(); + logEvent(events.ROOM_AUDIO_RECORD); if (!this.isRecorderBusy) { this.isRecorderBusy = true; diff --git a/app/containers/MessageBox/RightButtons.ios.tsx b/app/containers/MessageBox/RightButtons.ios.tsx deleted file mode 100644 index f2cf2bca5..000000000 --- a/app/containers/MessageBox/RightButtons.ios.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import React from 'react'; - -import { SendButton } from './buttons'; - -interface IMessageBoxRightButtons { - showSend: boolean; - submit(): void; -} - -const RightButtons = ({ showSend, submit }: IMessageBoxRightButtons) => { - if (showSend) { - return ; - } - return null; -}; - -export default RightButtons; diff --git a/app/containers/MessageBox/RightButtons.android.tsx b/app/containers/MessageBox/RightButtons.tsx similarity index 83% rename from app/containers/MessageBox/RightButtons.android.tsx rename to app/containers/MessageBox/RightButtons.tsx index 4af8d5027..d19109e61 100644 --- a/app/containers/MessageBox/RightButtons.android.tsx +++ b/app/containers/MessageBox/RightButtons.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { View } from 'react-native'; +import { isIOS } from '../../lib/methods/helpers'; import { ActionsButton, SendButton } from './buttons'; import styles from './styles'; @@ -18,7 +19,7 @@ const RightButtons = React.memo(({ showSend, submit, showMessageBoxActions, isAc if (isActionsEnabled) { return ; } - return ; + return !isIOS ? : null; }); export default RightButtons; diff --git a/app/containers/MessageBox/constants.ts b/app/containers/MessageBox/constants.ts index dabaee497..c966c60ce 100644 --- a/app/containers/MessageBox/constants.ts +++ b/app/containers/MessageBox/constants.ts @@ -4,3 +4,5 @@ export const MENTIONS_TRACKING_TYPE_COMMANDS = '/'; export const MENTIONS_TRACKING_TYPE_ROOMS = '#'; export const MENTIONS_TRACKING_TYPE_CANNED = '!'; export const MENTIONS_COUNT_TO_DISPLAY = 4; + +export const TIMEOUT_CLOSE_EMOJI = 300; diff --git a/app/containers/MessageBox/index.tsx b/app/containers/MessageBox/index.tsx index 107edd64d..e42c30905 100644 --- a/app/containers/MessageBox/index.tsx +++ b/app/containers/MessageBox/index.tsx @@ -19,11 +19,7 @@ import RecordAudio from './RecordAudio'; import I18n from '../../i18n'; import ReplyPreview from './ReplyPreview'; import { themes } from '../../lib/constants'; -// @ts-ignore -// eslint-disable-next-line import/extensions,import/no-unresolved import LeftButtons from './LeftButtons'; -// @ts-ignore -// eslint-disable-next-line import/extensions,import/no-unresolved import RightButtons from './RightButtons'; import { canUploadFile } from '../../lib/methods/helpers/media'; import EventEmiter from '../../lib/methods/helpers/events'; @@ -37,12 +33,13 @@ import { MENTIONS_TRACKING_TYPE_COMMANDS, MENTIONS_TRACKING_TYPE_EMOJIS, MENTIONS_TRACKING_TYPE_ROOMS, - MENTIONS_TRACKING_TYPE_USERS + MENTIONS_TRACKING_TYPE_USERS, + TIMEOUT_CLOSE_EMOJI } from './constants'; import CommandsPreview from './CommandsPreview'; import { getUserSelector } from '../../selectors/login'; import Navigation from '../../lib/navigation/appNavigation'; -import { withActionSheet } from '../ActionSheet'; +import { TActionSheetOptionsItem, withActionSheet } from '../ActionSheet'; import { sanitizeLikeString } from '../../lib/database/utils'; import { CustomIcon } from '../CustomIcon'; import { forceJpgExtension } from './forceJpgExtension'; @@ -58,14 +55,12 @@ import { } from '../../definitions'; import { MasterDetailInsideStackParamList } from '../../stacks/MasterDetailStack/types'; import { getPermalinkMessage, search, sendFileMessage } from '../../lib/methods'; -import { hasPermission, debounce, isAndroid, isTablet } from '../../lib/methods/helpers'; +import { hasPermission, debounce, isAndroid, isIOS, isTablet } from '../../lib/methods/helpers'; import { Services } from '../../lib/services'; import { TSupportedThemes } from '../../theme'; import { ChatsStackParamList } from '../../stacks/types'; -if (isAndroid) { - require('./EmojiKeyboard'); -} +require('./EmojiKeyboard'); const imagePickerConfig = { cropping: true, @@ -270,6 +265,7 @@ class MessageBox extends Component { }, 500); }); this.unsubscribeBlur = navigation.addListener('blur', () => { + this.closeEmoji(); this.component?.blur(); }); } @@ -330,6 +326,9 @@ class MessageBox extends Component { if (nextProps.theme !== theme) { return true; } + if (nextState.showEmojiKeyboard !== showEmojiKeyboard) { + return true; + } if (!isFocused()) { return false; } @@ -342,9 +341,6 @@ class MessageBox extends Component { if (nextProps.editing !== editing) { return true; } - if (nextState.showEmojiKeyboard !== showEmojiKeyboard) { - return true; - } if (nextState.trackingType !== trackingType) { return true; } @@ -809,7 +805,7 @@ class MessageBox extends Component { const { permissionToUpload } = this.state; const { showActionSheet, goToCannedResponses } = this.props; - const options = []; + const options: TActionSheetOptionsItem[] = []; if (goToCannedResponses) { options.push({ title: I18n.t('Canned_Responses'), @@ -847,7 +843,8 @@ class MessageBox extends Component { icon: 'discussions', onPress: this.createDiscussion }); - showActionSheet({ options }); + + this.closeEmojiAndAction(showActionSheet, { options }); }; editCancel = () => { @@ -883,6 +880,13 @@ class MessageBox extends Component { this.setState({ showEmojiKeyboard: false }); }; + closeEmojiAndAction = (action?: Function, params?: any) => { + const { showEmojiKeyboard } = this.state; + + this.closeEmoji(); + setTimeout(() => action && action(params), showEmojiKeyboard && isIOS ? TIMEOUT_CLOSE_EMOJI : null); + }; + submit = async () => { const { tshow } = this.state; const { onSubmit, rid: roomId, tmid, showSend, sharing } = this.props; @@ -1089,6 +1093,7 @@ class MessageBox extends Component { recordingCallback={this.recordingCallback} onFinish={this.finishAudioMessage} permissionToUpload={permissionToUpload} + onStart={this.closeEmoji} /> ); @@ -1112,14 +1117,11 @@ class MessageBox extends Component { const textInputAndButtons = !recording ? ( <> (this.component = component)} @@ -1138,7 +1140,6 @@ class MessageBox extends Component { {...isAndroidTablet} /> { renderContent={this.renderContent} kbInputRef={this.component} kbComponent={showEmojiKeyboard ? 'EmojiKeyboard' : null} + kbInitialProps={{ theme }} onKeyboardResigned={this.onKeyboardResigned} onItemSelected={this.onEmojiSelected} trackInteractive diff --git a/app/containers/message/index.tsx b/app/containers/message/index.tsx index 7af7f0899..e123bb34a 100644 --- a/app/containers/message/index.tsx +++ b/app/containers/message/index.tsx @@ -58,6 +58,7 @@ interface IMessageContainerProps { jumpToMessage?: (link: string) => void; onPress?: () => void; theme: TSupportedThemes; + closeEmojiAndAction?: (action?: Function, params?: any) => void; } interface IMessageContainerState { @@ -114,6 +115,14 @@ class MessageContainer extends React.Component { + const { closeEmojiAndAction } = this.props; + + if (closeEmojiAndAction) { + closeEmojiAndAction(this.onPress); + } + }; + onPress = debounce( () => { const { onPress } = this.props; @@ -373,7 +382,7 @@ class MessageContainer extends React.Component { }; render() { - const { width, height, show, baseUrl, reactionClose, isMasterDetail, theme } = this.props; + const { width, height, show, reactionClose, isMasterDetail, theme } = this.props; let widthStyle = width - margin; let heightStyle = Math.min(width, height) - margin * 2; @@ -70,7 +69,7 @@ class ReactionPicker extends React.Component { } ]} testID='reaction-picker'> - + ) : null; @@ -78,7 +77,6 @@ class ReactionPicker extends React.Component { } const mapStateToProps = (state: IApplicationState) => ({ - baseUrl: state.server.server, isMasterDetail: state.app.isMasterDetail }); diff --git a/app/views/RoomView/RightButtons.tsx b/app/views/RoomView/RightButtons.tsx index 6aaabdcc8..308169094 100644 --- a/app/views/RoomView/RightButtons.tsx +++ b/app/views/RoomView/RightButtons.tsx @@ -13,7 +13,7 @@ import { events, logEvent } from '../../lib/methods/helpers/log'; import { isTeamRoom } from '../../lib/methods/helpers/room'; import { IApplicationState, SubscriptionType, TMessageModel, TSubscriptionModel } from '../../definitions'; import { ChatsStackParamList } from '../../stacks/types'; -import { IActionSheetProvider, TActionSheetOptionsItem, withActionSheet } from '../../containers/ActionSheet'; +import { TActionSheetOptionsItem } from '../../containers/ActionSheet'; import i18n from '../../i18n'; import { showConfirmationAlert, showErrorAlert } from '../../lib/methods/helpers'; import { onHoldLivechat, returnLivechat } from '../../lib/services/restApi'; @@ -21,10 +21,10 @@ import { closeLivechat as closeLivechatService } from '../../lib/methods/helpers import { Services } from '../../lib/services'; import { ILivechatDepartment } from '../../definitions/ILivechatDepartment'; -interface IRightButtonsProps extends IActionSheetProvider { +interface IRightButtonsProps { userId?: string; threadsEnabled: boolean; - rid: string; + rid?: string; t: string; tmid?: string; teamId?: string; @@ -34,7 +34,6 @@ interface IRightButtonsProps extends IActionSheetProvider { status?: string; dispatch: Dispatch; encrypted?: boolean; - transferLivechatGuestPermission: boolean; navigation: StackNavigationProp; omnichannelPermissions: { canForwardGuest: boolean; @@ -42,6 +41,7 @@ interface IRightButtonsProps extends IActionSheetProvider { canPlaceLivechatOnHold: boolean; }; livechatRequestComment: boolean; + showActionSheet: Function; departmentId?: string; } @@ -187,34 +187,38 @@ class RightButtonsContainer extends Component { const { rid } = this.props; - showConfirmationAlert({ - message: i18n.t('Would_you_like_to_return_the_inquiry'), - confirmationText: i18n.t('Yes'), - onPress: async () => { - try { - await returnLivechat(rid); - } catch (e: any) { - showErrorAlert(e.reason, i18n.t('Oops')); + if (rid) { + showConfirmationAlert({ + message: i18n.t('Would_you_like_to_return_the_inquiry'), + confirmationText: i18n.t('Yes'), + onPress: async () => { + try { + await returnLivechat(rid); + } catch (e: any) { + showErrorAlert(e.reason, i18n.t('Oops')); + } } - } - }); + }); + } }; placeOnHoldLivechat = () => { const { navigation, rid } = this.props; - showConfirmationAlert({ - title: i18n.t('Are_you_sure_question_mark'), - message: i18n.t('Would_like_to_place_on_hold'), - confirmationText: i18n.t('Yes'), - onPress: async () => { - try { - await onHoldLivechat(rid); - navigation.navigate('RoomsListView'); - } catch (e: any) { - showErrorAlert(e.data?.error, i18n.t('Oops')); + if (rid) { + showConfirmationAlert({ + title: i18n.t('Are_you_sure_question_mark'), + message: i18n.t('Would_like_to_place_on_hold'), + confirmationText: i18n.t('Yes'), + onPress: async () => { + try { + await onHoldLivechat(rid); + navigation.navigate('RoomsListView'); + } catch (e: any) { + showErrorAlert(e.data?.error, i18n.t('Oops')); + } } - } - }); + }); + } }; closeLivechat = async () => { @@ -234,18 +238,20 @@ class RightButtonsContainer extends Component { - if (isMasterDetail) { - navigation.navigate('ModalStackNavigator', { - screen: 'ForwardLivechatView', - params: { rid } - }); - } else { - navigation.navigate('ForwardLivechatView', { rid }); + if (rid) { + if (isMasterDetail) { + navigation.navigate('ModalStackNavigator', { + screen: 'ForwardLivechatView', + params: { rid } + }); + } else { + navigation.navigate('ForwardLivechatView', { rid }); + } } } }); @@ -379,4 +387,4 @@ const mapStateToProps = (state: IApplicationState) => ({ livechatRequestComment: state.settings.Livechat_request_comment_when_closing_conversation as boolean }); -export default connect(mapStateToProps)(withActionSheet(RightButtonsContainer)); +export default connect(mapStateToProps)(RightButtonsContainer); diff --git a/app/views/RoomView/index.tsx b/app/views/RoomView/index.tsx index f12177925..1803974bb 100644 --- a/app/views/RoomView/index.tsx +++ b/app/views/RoomView/index.tsx @@ -99,7 +99,7 @@ import { hasPermission } from '../../lib/methods/helpers'; import { Services } from '../../lib/services'; -import { withActionSheet, TActionSheetOptions } from '../../containers/ActionSheet'; +import { withActionSheet, IActionSheetProvider } from '../../containers/ActionSheet'; type TStateAttrsUpdate = keyof IRoomViewState; @@ -150,7 +150,7 @@ const roomAttrsUpdate = [ 't' ] as TRoomUpdate[]; -interface IRoomViewProps extends IBaseScreen { +interface IRoomViewProps extends IActionSheetProvider, IBaseScreen { user: Pick; appState: string; useRealName?: boolean; @@ -170,7 +170,6 @@ interface IRoomViewProps extends IBaseScreen { transferLivechatGuestPermission?: string[]; // TODO: Check if its the correct type viewCannedResponsesPermission?: string[]; // TODO: Check if its the correct type livechatAllowManualOnHold?: boolean; - showActionSheet: (options: TActionSheetOptions) => void; } interface IRoomViewState { @@ -185,7 +184,7 @@ interface IRoomViewState { fname?: string; prid?: string; joinCodeRequired?: boolean; - status?: boolean; + status?: string; lastMessage?: ILastMessage; sysMes?: boolean; onHold?: boolean; @@ -635,6 +634,7 @@ class RoomView extends React.Component { encrypted={encrypted} navigation={navigation} toggleFollowThread={this.toggleFollowThread} + showActionSheet={this.showActionSheet} departmentId={departmentId} /> ) @@ -785,7 +785,12 @@ class RoomView extends React.Component { }; errorActionsShow = (message: TAnyMessageModel) => { - this.messageErrorActions?.showMessageErrorActions(message); + this.messagebox?.current?.closeEmojiAndAction(this.messageErrorActions?.showMessageErrorActions, message); + }; + + showActionSheet = (options: any) => { + const { showActionSheet } = this.props; + this.messagebox?.current?.closeEmojiAndAction(showActionSheet, options); }; onEditInit = (message: TAnyMessageModel) => { @@ -834,7 +839,7 @@ class RoomView extends React.Component { }; onMessageLongPress = (message: TAnyMessageModel) => { - this.messageActions?.showMessageActions(message); + this.messagebox?.current?.closeEmojiAndAction(this.messageActions?.showMessageActions, message); }; showAttachment = (attachment: IAttachment) => { @@ -857,7 +862,7 @@ class RoomView extends React.Component { this.setState({ selectedMessage: message }); const { showActionSheet, baseUrl, width } = this.props; const { selectedMessage } = this.state; - showActionSheet({ + this.messagebox?.current?.closeEmojiAndAction(showActionSheet, { children: ( { jumpToMessage={this.jumpToMessageByUrl} highlighted={highlightedMessage === item.id} theme={theme} + closeEmojiAndAction={this.messagebox?.current?.closeEmojiAndAction} /> ); } diff --git a/package.json b/package.json index c3a015060..e5e246116 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,7 @@ "react-native-simple-crypto": "RocketChat/react-native-simple-crypto#0.5.0", "react-native-slowlog": "^1.0.2", "react-native-svg": "^12.3.0", - "react-native-ui-lib": "RocketChat/react-native-ui-lib#minor-improvements", + "react-native-ui-lib": "RocketChat/react-native-ui-lib", "react-native-unimodules": "^0.14.8", "react-native-vector-icons": "9.1.0", "react-native-webview": "10.3.2", diff --git a/yarn.lock b/yarn.lock index cb3170660..36a9eeaed 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15491,9 +15491,9 @@ react-native-text-size@4.0.0-rc.1: resolved "https://registry.yarnpkg.com/react-native-text-size/-/react-native-text-size-4.0.0-rc.1.tgz#1e048d345dd6a5a8e1269e0585c1a5948c478da5" integrity sha512-CysqjU2jK6Yc+a+kEI222pUyTY2ywcU2HqbFqf1KHymW6OPTdvBBHqbEJKL0QiLhQaFYDbqicM+h990s9TP00g== -react-native-ui-lib@RocketChat/react-native-ui-lib#minor-improvements: - version "4.2.1" - resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/a80f38aaa947849736ce8643253991cdcb639414" +react-native-ui-lib@RocketChat/react-native-ui-lib: + version "4.2.0" + resolved "https://codeload.github.com/RocketChat/react-native-ui-lib/tar.gz/d20c1bcd09b694fc5133fc2232fd510f5f4ba581" dependencies: babel-plugin-transform-inline-environment-variables "^0.0.2" color "^3.1.0" From 2b08b683d705b869131c1cb60b10707502a9794c Mon Sep 17 00:00:00 2001 From: Gleidson Daniel Silva Date: Mon, 8 Aug 2022 18:02:08 -0300 Subject: [PATCH 12/72] Chore: Upgrade React Native to 0.68.2 (#4316) Co-authored-by: Diego Mello --- .bundle/config | 2 + .circleci/config.yml | 12 +- .gitignore | 1 + .prettierrc.js | 4 +- .ruby-version | 1 + Gemfile | 4 + README.md | 2 +- __mocks__/expo-av.js | 14 - __mocks__/expo-keep-awake.js | 4 - __mocks__/expo-web-browser.js | 3 - __mocks__/react-native-mmkv-storage.js | 17 + __mocks__/rn-user-defaults.js | 4 - android/app/build.gradle | 124 +- android/app/src/debug/AndroidManifest.xml | 2 +- .../reactnative/ReactNativeFlipper.java | 3 +- android/app/src/main/AndroidManifest.xml | 8 +- .../chat/rocket/reactnative/MainActivity.java | 47 +- .../rocket/reactnative/MainApplication.java | 36 +- .../generated/BasePackageList.java | 21 - .../MainApplicationReactNativeHost.java | 116 + .../components/MainComponentsRegistry.java | 36 + ...ApplicationTurboModuleManagerDelegate.java | 48 + android/app/src/main/jni/Android.mk | 49 + .../jni/MainApplicationModuleProvider.cpp | 24 + .../main/jni/MainApplicationModuleProvider.h | 16 + ...nApplicationTurboModuleManagerDelegate.cpp | 45 + ...ainApplicationTurboModuleManagerDelegate.h | 38 + .../src/main/jni/MainComponentsRegistry.cpp | 61 + .../app/src/main/jni/MainComponentsRegistry.h | 32 + android/app/src/main/jni/OnLoad.cpp | 11 + .../res/drawable/rn_edit_text_material.xml | 29 + android/app/src/main/res/values/styles.xml | 2 + android/app/src/play/AndroidManifest.xml | 4 +- android/build.gradle | 56 +- android/gradle.properties | 22 +- .../gradle/wrapper/gradle-wrapper.properties | 2 +- android/gradlew | 269 +- android/settings.gradle | 12 +- app/AppContainer.tsx | 3 +- .../ActionSheet/BottomSheetContent.tsx | 3 +- app/containers/ActionSheet/Item.tsx | 6 +- .../__snapshots__/index.stories.storyshot | 6 +- .../__snapshots__/Button.stories.storyshot | 10 +- app/containers/Button/index.tsx | 3 +- app/containers/EmojiPicker/EmojiCategory.tsx | 3 +- app/containers/EmojiPicker/TabBar.tsx | 3 +- app/containers/EmojiPicker/index.tsx | 3 +- app/containers/FormContainer.tsx | 6 +- app/containers/ImageViewer/ImageViewer.tsx | 8 +- .../InAppNotification/NotifierComponent.tsx | 6 +- app/containers/KeyboardView.tsx | 3 +- app/containers/List/ListContainer.tsx | 3 +- app/containers/List/ListItem.tsx | 6 +- .../LoginServices/ButtonService.tsx | 3 +- .../LoginServices.stories.storyshot | 2 +- app/containers/MessageActions/Header.tsx | 6 +- .../MessageBox/CommandsPreview/Item.tsx | 6 +- app/containers/MessageBox/EmojiKeyboard.tsx | 3 +- .../MessageBox/Mentions/FixedMentionItem.tsx | 3 +- .../MessageBox/Mentions/MentionItem.tsx | 3 +- app/containers/MessageBox/RecordAudio.tsx | 9 +- .../MessageBox/buttons/BaseButton.tsx | 3 +- app/containers/MessageBox/index.tsx | 11 +- app/containers/Passcode/Base/Button.tsx | 3 +- app/containers/RoomHeader/RoomHeader.tsx | 3 +- app/containers/RoomItem/Actions.tsx | 9 +- app/containers/RoomItem/RoomItem.tsx | 6 +- app/containers/RoomItem/Title.tsx | 3 +- app/containers/RoomItem/Touchable.tsx | 3 +- app/containers/RoomItem/UpdatedAt.tsx | 3 +- app/containers/RoomItem/Wrapper.tsx | 6 +- app/containers/SafeAreaView.tsx | 3 +- .../__snapshots__/SearchBox.stories.storyshot | 2 +- app/containers/ServerItem/index.tsx | 3 +- .../__snapshots__/TextInput.stories.storyshot | 2 +- app/containers/TwoFactor/index.tsx | 3 +- app/containers/UIKit/DatePicker.tsx | 3 +- app/containers/UIKit/MultiSelect/Chips.tsx | 3 +- app/containers/UIKit/MultiSelect/Input.tsx | 3 +- app/containers/UIKit/Overflow.tsx | 9 +- app/containers/UnreadBadge/index.tsx | 3 +- app/containers/UserItem.tsx | 3 +- app/containers/markdown/AtMention.tsx | 3 +- app/containers/markdown/Hashtag.tsx | 3 +- app/containers/markdown/Preview.tsx | 3 +- app/containers/markdown/Table.tsx | 3 +- app/containers/markdown/index.tsx | 6 +- app/containers/markdown/new/Code.tsx | 3 +- app/containers/markdown/new/InlineCode.tsx | 3 +- app/containers/markdown/new/index.tsx | 3 +- app/containers/message/Audio.tsx | 12 +- app/containers/message/Broadcast.tsx | 3 +- app/containers/message/CallButton.tsx | 3 +- .../CollapsibleQuote.stories.js | 3 +- .../CollapsibleQuote.test.tsx | 3 +- .../CollapsibleQuote.stories.storyshot | 2 +- .../Components/CollapsibleQuote/index.tsx | 3 +- app/containers/message/Discussion.tsx | 3 +- app/containers/message/Image.tsx | 3 +- app/containers/message/Message.tsx | 3 +- app/containers/message/Reactions.tsx | 6 +- app/containers/message/Reply.tsx | 6 +- app/containers/message/Urls.tsx | 3 +- app/containers/message/User.tsx | 3 +- app/containers/message/Video.tsx | 3 +- app/containers/message/index.tsx | 3 +- app/index.tsx | 64 +- app/lib/methods/helpers/log/index.ts | 2 +- app/lib/methods/helpers/theme.ts | 4 +- app/lib/methods/helpers/touch.tsx | 3 +- app/lib/methods/userPreferences.ts | 16 +- app/share.tsx | 59 +- app/stacks/InsideStack.tsx | 30 +- .../MasterDetailStack/ModalContainer.tsx | 3 +- app/stacks/MasterDetailStack/index.tsx | 12 +- app/stacks/OutsideStack.tsx | 3 +- app/views/AttachmentView.tsx | 4 +- .../Dropdown/index.tsx | 3 +- .../CannedResponseItem.stories.storyshot | 2 +- app/views/CreateChannelView.tsx | 3 +- app/views/CreateDiscussionView/index.tsx | 3 +- app/views/DirectoryView/Options.tsx | 9 +- app/views/DirectoryView/index.tsx | 3 +- app/views/DiscussionsView/Item.tsx | 3 +- .../__snapshots__/Item.stories.storyshot | 4 +- app/views/E2EEnterYourPasswordView.tsx | 10 +- app/views/E2ESaveYourPasswordView.tsx | 3 +- app/views/InviteUsersView/index.tsx | 3 +- app/views/LivechatEditView.tsx | 3 +- app/views/LoginView.tsx | 7 +- app/views/ModalBlockView.tsx | 3 +- app/views/NewMessageView.tsx | 3 +- app/views/NewServerView/ServerInput/index.tsx | 3 +- app/views/NewServerView/index.tsx | 21 +- app/views/ProfileView/index.tsx | 9 +- app/views/ReadReceiptView/index.tsx | 6 +- app/views/RegisterView.tsx | 19 +- app/views/RoomActionsView/index.tsx | 3 +- app/views/RoomInfoEditView/index.tsx | 33 +- app/views/RoomInfoView/index.tsx | 3 +- app/views/RoomView/Banner.tsx | 6 +- app/views/RoomView/JoinCode.tsx | 3 +- app/views/RoomView/List/List.tsx | 7 +- app/views/RoomView/List/index.tsx | 8 +- .../__snapshots__/LoadMore.stories.storyshot | 8 +- app/views/RoomView/ReactionPicker.tsx | 6 +- app/views/RoomView/UploadProgress.tsx | 6 +- app/views/RoomView/index.tsx | 12 +- app/views/RoomsListView/Header/Header.tsx | 3 +- app/views/RoomsListView/ServerDropdown.tsx | 3 +- app/views/ScreenLockedView.tsx | 3 +- app/views/ShareListView/Header/Header.ios.tsx | 3 +- app/views/ShareListView/Header/SearchBox.tsx | 3 +- app/views/ShareListView/index.tsx | 3 +- app/views/ShareView/Preview.tsx | 7 +- app/views/ShareView/Thumbs.tsx | 3 +- app/views/ShareView/index.tsx | 3 +- app/views/SidebarView/SidebarItem.tsx | 3 +- app/views/SidebarView/index.tsx | 6 +- .../ThreadMessagesView/Dropdown/index.tsx | 3 +- app/views/ThreadMessagesView/Item.tsx | 3 +- .../__snapshots__/Item.stories.storyshot | 6 +- e2e/data.js | 2 +- e2e/data/data.cloud.js | 4 +- e2e/data/data.docker.js | 2 +- e2e/tests/assorted/02-broadcast.spec.js | 3 + e2e/tests/assorted/07-changeserver.spec.js | 5 +- e2e/tests/assorted/13-display-pref.spec.js | 4 +- e2e/tests/onboarding/04-createuser.spec.js | 4 +- e2e/tests/room/04-discussion.spec.js | 3 + e2e/tests/room/06-createdmgroup.spec.js | 3 + ios/Podfile | 38 +- ios/Podfile.lock | 1066 ++-- ios/RocketChatRN.xcodeproj/project.pbxproj | 491 +- .../xcschemes/RocketChatRN.xcscheme | 2 +- ios/RocketChatRN/AppDelegate.h | 6 +- ios/RocketChatRN/AppDelegate.m | 125 - ios/RocketChatRN/AppDelegate.mm | 142 + ios/ShareRocketChatRN/ShareRocketChatRN.m | 23 +- jest.setup.js | 12 - metro.config.js | 3 +- package.json | 86 +- ...po-av+9.2.3.patch => expo-av+11.2.3.patch} | 2 +- .../react-native-mmkv-storage+0.6.12.patch | 44 - patches/react-native-mmkv-storage+0.7.6.patch | 114 + patches/react-native-reanimated+2.2.2.patch | 3385 ------------ storybook/stories/Message.js | 3 +- storybook/stories/ServerItem.js | 3 +- storybook/stories/UiKitMessage.js | 3 +- storybook/stories/UiKitModal.js | 3 +- storybook/stories/UnreadBadge.js | 3 +- .../stories/__snapshots__/Avatar.storyshot | 2 +- .../stories/__snapshots__/List.storyshot | 2 +- .../stories/__snapshots__/Markdown.storyshot | 24 +- .../stories/__snapshots__/Message.storyshot | 80 +- .../__snapshots__/NewMarkdown.storyshot | 22 +- storybook/stories/index.js | 2 +- yarn.lock | 4597 +++++++++++------ 198 files changed, 5610 insertions(+), 6634 deletions(-) create mode 100644 .bundle/config create mode 100644 .ruby-version create mode 100644 Gemfile delete mode 100644 __mocks__/expo-av.js delete mode 100644 __mocks__/expo-keep-awake.js delete mode 100644 __mocks__/expo-web-browser.js create mode 100644 __mocks__/react-native-mmkv-storage.js delete mode 100644 __mocks__/rn-user-defaults.js delete mode 100644 android/app/src/main/java/chat/rocket/reactnative/generated/BasePackageList.java create mode 100644 android/app/src/main/java/chat/rocket/reactnative/newarchitecture/MainApplicationReactNativeHost.java create mode 100644 android/app/src/main/java/chat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry.java create mode 100644 android/app/src/main/java/chat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java create mode 100644 android/app/src/main/jni/Android.mk create mode 100644 android/app/src/main/jni/MainApplicationModuleProvider.cpp create mode 100644 android/app/src/main/jni/MainApplicationModuleProvider.h create mode 100644 android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp create mode 100644 android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h create mode 100644 android/app/src/main/jni/MainComponentsRegistry.cpp create mode 100644 android/app/src/main/jni/MainComponentsRegistry.h create mode 100644 android/app/src/main/jni/OnLoad.cpp create mode 100644 android/app/src/main/res/drawable/rn_edit_text_material.xml delete mode 100644 ios/RocketChatRN/AppDelegate.m create mode 100644 ios/RocketChatRN/AppDelegate.mm rename patches/{expo-av+9.2.3.patch => expo-av+11.2.3.patch} (98%) delete mode 100644 patches/react-native-mmkv-storage+0.6.12.patch create mode 100644 patches/react-native-mmkv-storage+0.7.6.patch delete mode 100644 patches/react-native-reanimated+2.2.2.patch diff --git a/.bundle/config b/.bundle/config new file mode 100644 index 000000000..d137d242e --- /dev/null +++ b/.bundle/config @@ -0,0 +1,2 @@ +BUNDLE_PATH: "vendor/bundle" +BUNDLE_FORCE_RUBY_PLATFORM: 1 \ No newline at end of file diff --git a/.circleci/config.yml b/.circleci/config.yml index 1be1e3871..0de081c36 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -80,18 +80,15 @@ commands: steps: - restore_cache: name: Restore pods - # TODO: CircleCI isn't caching Podfile.lock correctly, because checksum changes after install - # key: pods-v1-{{ checksum "ios/Podfile.lock" }} - key: pods-v1-{{ checksum "ios/Podfile" }} + key: pods-v1-{{ checksum "ios/Podfile.lock" }} - run: name: Install pods libs command: | - bundle exec pod install + bundle exec pod install --deployment working_directory: ios - save_cache: name: Save pods specs and pods cache - # key: pods-v1-{{ checksum "ios/Podfile.lock" }} - key: pods-v1-{{ checksum "ios/Podfile" }} + key: pods-v1-{{ checksum "ios/Podfile.lock" }} paths: - ~/.pods - ios/Pods @@ -114,7 +111,8 @@ commands: # echo -e "android.enableAapt2=false" >> ./gradle.properties echo -e "android.useAndroidX=true" >> ./gradle.properties echo -e "android.enableJetifier=true" >> ./gradle.properties - echo -e "FLIPPER_VERSION=0.51.0" >> ./gradle.properties + echo -e "newArchEnabled=false" >> ./gradle.properties + echo -e "FLIPPER_VERSION=0.125.0" >> ./gradle.properties echo -e "VERSIONCODE=$CIRCLE_BUILD_NUM" >> ./gradle.properties if [[ $CIRCLE_JOB == "android-build-official" ]]; then diff --git a/.gitignore b/.gitignore index efb752943..19f2bcab6 100644 --- a/.gitignore +++ b/.gitignore @@ -23,6 +23,7 @@ DerivedData project.xcworkspace *.mobileprovision ios/Pods/ +/vendor/bundle/ # Android/IntelliJ # diff --git a/.prettierrc.js b/.prettierrc.js index 7321592a1..04f6b3a09 100644 --- a/.prettierrc.js +++ b/.prettierrc.js @@ -1,10 +1,10 @@ module.exports = { bracketSpacing: true, - jsxBracketSameLine: true, singleQuote: true, jsxSingleQuote: true, trailingComma: 'none', printWidth: 130, useTabs: true, - arrowParens: 'avoid' + arrowParens: 'avoid', + bracketSameLine: true }; diff --git a/.ruby-version b/.ruby-version new file mode 100644 index 000000000..a4dd9dba4 --- /dev/null +++ b/.ruby-version @@ -0,0 +1 @@ +2.7.4 diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..bbba14aff --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' +# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version +ruby '2.7.4' +gem 'cocoapods', '~> 1.11', '>= 1.11.2' \ No newline at end of file diff --git a/README.md b/README.md index 50e97ea19..0a5f6d766 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ [![CodeFactor](https://www.codefactor.io/repository/github/rocketchat/rocket.chat.reactnative/badge)](https://www.codefactor.io/repository/github/rocketchat/rocket.chat.reactnative) - **Supported server versions:** 0.70.0+ -- **Supported iOS versions**: 11+ +- **Supported iOS versions**: 12+ - **Supported Android versions**: 6.0+ ## Download diff --git a/__mocks__/expo-av.js b/__mocks__/expo-av.js deleted file mode 100644 index e20feac67..000000000 --- a/__mocks__/expo-av.js +++ /dev/null @@ -1,14 +0,0 @@ -export class Sound { - loadAsync = () => {}; - - playAsync = () => {}; - - pauseAsync = () => {}; - - stopAsync = () => {}; - - setOnPlaybackStatusUpdate = () => {}; - - setPositionAsync = () => {}; -} -export const Audio = { Sound }; diff --git a/__mocks__/expo-keep-awake.js b/__mocks__/expo-keep-awake.js deleted file mode 100644 index 4df99a606..000000000 --- a/__mocks__/expo-keep-awake.js +++ /dev/null @@ -1,4 +0,0 @@ -const activateKeepAwake = () => ''; -const deactivateKeepAwake = () => ''; - -export { activateKeepAwake, deactivateKeepAwake }; diff --git a/__mocks__/expo-web-browser.js b/__mocks__/expo-web-browser.js deleted file mode 100644 index 3e5611b84..000000000 --- a/__mocks__/expo-web-browser.js +++ /dev/null @@ -1,3 +0,0 @@ -export default { - openBrowserAsync: () => '' -}; diff --git a/__mocks__/react-native-mmkv-storage.js b/__mocks__/react-native-mmkv-storage.js new file mode 100644 index 000000000..e34fed189 --- /dev/null +++ b/__mocks__/react-native-mmkv-storage.js @@ -0,0 +1,17 @@ +export class MMKVLoader { + constructor() { + console.log('MMKVLoader constructor mock'); + } + + setProcessingMode = jest.fn().mockImplementation(() => ({ + withEncryption: jest.fn().mockImplementation(() => ({ + initialize: jest.fn().mockImplementation(() => {}) + })) + })); +} + +export const ProcessingModes = { + MULTI_PROCESS: '' +}; + +export const create = jest.fn(); diff --git a/__mocks__/rn-user-defaults.js b/__mocks__/rn-user-defaults.js deleted file mode 100644 index 71f26ca30..000000000 --- a/__mocks__/rn-user-defaults.js +++ /dev/null @@ -1,4 +0,0 @@ -export default { - set: () => '', - get: () => '' -}; diff --git a/android/app/build.gradle b/android/app/build.gradle index caff3ff8b..68e818f42 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -93,7 +93,6 @@ project.ext.react = [ ] apply from: "../../node_modules/react-native/react.gradle" -apply from: '../../node_modules/react-native-unimodules/gradle.groovy' /** * Set this to true to create two separate APKs instead of one: @@ -131,13 +130,17 @@ def jscFlavor = 'org.webkit:android-jsc:+' */ def enableHermes = project.ext.react.get("enableHermes", false); -android { - compileSdkVersion rootProject.ext.compileSdkVersion +/** + * Architectures to build native code for. + */ +def reactNativeArchitectures() { + def value = project.getProperties().get("reactNativeArchitectures") + return value ? value.split(",") : ["armeabi-v7a", "x86", "x86_64", "arm64-v8a"] +} - compileOptions { - sourceCompatibility JavaVersion.VERSION_1_8 - targetCompatibility JavaVersion.VERSION_1_8 - } +android { + ndkVersion rootProject.ext.ndkVersion + compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { applicationId APPLICATION_ID @@ -153,6 +156,76 @@ android { resValue "string", "rn_config_reader_custom_package", "chat.rocket.reactnative" testBuildType System.getProperty('testBuildType', 'debug') testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner' + + buildConfigField "boolean", "IS_NEW_ARCHITECTURE_ENABLED", isNewArchitectureEnabled().toString() + if (isNewArchitectureEnabled()) { + // We configure the NDK build only if you decide to opt-in for the New Architecture. + externalNativeBuild { + ndkBuild { + arguments "APP_PLATFORM=android-21", + "APP_STL=c++_shared", + "NDK_TOOLCHAIN_VERSION=clang", + "GENERATED_SRC_DIR=$buildDir/generated/source", + "PROJECT_BUILD_DIR=$buildDir", + "REACT_ANDROID_DIR=$rootDir/../node_modules/react-native/ReactAndroid", + "REACT_ANDROID_BUILD_DIR=$rootDir/../node_modules/react-native/ReactAndroid/build" + cFlags "-Wall", "-Werror", "-fexceptions", "-frtti", "-DWITH_INSPECTOR=1" + cppFlags "-std=c++17" + // Make sure this target name is the same you specify inside the + // src/main/jni/Android.mk file for the `LOCAL_MODULE` variable. + targets "rndiffapp_appmodules" + // Fix for windows limit on number of character in file paths and in command lines + if (Os.isFamily(Os.FAMILY_WINDOWS)) { + arguments "NDK_APP_SHORT_COMMANDS=true" + } + } + } + if (!enableSeparateBuildPerCPUArchitecture) { + ndk { + abiFilters (*reactNativeArchitectures()) + } + } + } + } + + if (isNewArchitectureEnabled()) { + // We configure the NDK build only if you decide to opt-in for the New Architecture. + externalNativeBuild { + ndkBuild { + path "$projectDir/src/main/jni/Android.mk" + } + } + def reactAndroidProjectDir = project(':ReactAndroid').projectDir + def packageReactNdkDebugLibs = tasks.register("packageReactNdkDebugLibs", Copy) { + dependsOn(":ReactAndroid:packageReactNdkDebugLibsForBuck") + from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") + into("$buildDir/react-ndk/exported") + } + def packageReactNdkReleaseLibs = tasks.register("packageReactNdkReleaseLibs", Copy) { + dependsOn(":ReactAndroid:packageReactNdkReleaseLibsForBuck") + from("$reactAndroidProjectDir/src/main/jni/prebuilt/lib") + into("$buildDir/react-ndk/exported") + } + afterEvaluate { + // If you wish to add a custom TurboModule or component locally, + // you should uncomment this line. + // preBuild.dependsOn("generateCodegenArtifactsFromSchema") + preDebugBuild.dependsOn(packageReactNdkDebugLibs) + preReleaseBuild.dependsOn(packageReactNdkReleaseLibs) + // Due to a bug inside AGP, we have to explicitly set a dependency + // between configureNdkBuild* tasks and the preBuild tasks. + // This can be removed once this is solved: https://issuetracker.google.com/issues/207403732 + configureNdkBuildRelease.dependsOn(preReleaseBuild) + configureNdkBuildDebug.dependsOn(preDebugBuild) + reactNativeArchitectures().each { architecture -> + tasks.findByName("configureNdkBuildDebug[${architecture}]")?.configure { + dependsOn("preDebugBuild") + } + tasks.findByName("configureNdkBuildRelease[${architecture}]")?.configure { + dependsOn("preReleaseBuild") + } + } + } } signingConfigs { @@ -170,7 +243,7 @@ android { reset() enable enableSeparateBuildPerCPUArchitecture universalApk false // If true, also generate a universal APK - include "armeabi-v7a", "x86", "arm64-v8a", "x86_64" + include (*reactNativeArchitectures()) } } buildTypes { @@ -181,6 +254,8 @@ android { if (!isFoss) { firebaseCrashlytics { nativeSymbolUploadEnabled true + strippedNativeLibsDir 'build/intermediates/stripped_native_libs/release/out/lib' + unstrippedNativeLibsDir 'build/intermediates/merged_native_libs/release/out/lib' } } } @@ -275,7 +350,6 @@ android { } dependencies { - addUnimodulesDependencies() implementation project(':@react-native-community_viewpager') playImplementation project(':react-native-notifications') playImplementation 'com.google.firebase:firebase-core:16.0.0' @@ -286,14 +360,16 @@ dependencies { exclude group: 'com.facebook.react',module:'react-native-svg' } implementation fileTree(dir: "libs", include: ["*.jar"]) + //noinspection GradleDynamicVersion implementation "com.facebook.react:react-native:+" // From node_modules implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0" debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { - exclude group:'com.facebook.fbjni' + exclude group:'com.facebook.fbjni' } debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' + exclude group:'com.squareup.okhttp3', module:'okhttp' } debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' @@ -307,20 +383,30 @@ dependencies { implementation jscFlavor } - implementation "com.google.code.gson:gson:2.8.5" + implementation "com.google.code.gson:gson:2.8.9" implementation "com.github.bumptech.glide:glide:4.9.0" annotationProcessor "com.github.bumptech.glide:compiler:4.9.0" - implementation "com.tencent:mmkv-static:1.2.1" - implementation 'com.squareup.okhttp3:okhttp:4.9.0' - implementation "com.squareup.okhttp3:okhttp-urlconnection:4.9.0" + implementation "com.tencent:mmkv-static:1.2.10" androidTestImplementation('com.wix:detox:+') { transitive = true } androidTestImplementation 'junit:junit:4.12' } +if (isNewArchitectureEnabled()) { + // If new architecture is enabled, we let you build RN from source + // Otherwise we fallback to a prebuilt .aar bundled in the NPM package. + // This will be applied to all the imported transtitive dependency. + configurations.all { + resolutionStrategy.dependencySubstitution { + substitute(module("com.facebook.react:react-native")) + .using(project(":ReactAndroid")).because("On New Architecture we're building React Native from source") + } + } +} + // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { - from configurations.compile + from configurations.implementation into 'libs' } @@ -328,3 +414,11 @@ apply from: file("../../node_modules/@react-native-community/cli-platform-androi if (!isFoss) { apply plugin: 'com.google.gms.google-services' } + +def isNewArchitectureEnabled() { + // To opt-in for the New Architecture, you can either: + // - Set `newArchEnabled` to true inside the `gradle.properties` file + // - Invoke gradle with `-newArchEnabled=true` + // - Set an environment variable `ORG_GRADLE_PROJECT_newArchEnabled=true` + return project.hasProperty("newArchEnabled") && project.newArchEnabled == "true" +} \ No newline at end of file diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index efbd3e20b..febfaf65f 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -8,7 +8,7 @@ tools:replace="android:name" tools:targetApi="28" android:networkSecurityConfig="@xml/network_security_config"> - + diff --git a/android/app/src/debug/java/chat/rocket/reactnative/ReactNativeFlipper.java b/android/app/src/debug/java/chat/rocket/reactnative/ReactNativeFlipper.java index 6ed1a4798..6d30e2d25 100644 --- a/android/app/src/debug/java/chat/rocket/reactnative/ReactNativeFlipper.java +++ b/android/app/src/debug/java/chat/rocket/reactnative/ReactNativeFlipper.java @@ -18,6 +18,7 @@ import com.facebook.flipper.plugins.network.FlipperOkhttpInterceptor; import com.facebook.flipper.plugins.network.NetworkFlipperPlugin; import com.facebook.flipper.plugins.react.ReactFlipperPlugin; import com.facebook.flipper.plugins.sharedpreferences.SharedPreferencesFlipperPlugin; +import com.facebook.react.ReactInstanceEventListener; import com.facebook.react.ReactInstanceManager; import com.facebook.react.bridge.ReactContext; import com.facebook.react.modules.network.NetworkingModule; @@ -47,7 +48,7 @@ public class ReactNativeFlipper { ReactContext reactContext = reactInstanceManager.getCurrentReactContext(); if (reactContext == null) { reactInstanceManager.addReactInstanceEventListener( - new ReactInstanceManager.ReactInstanceEventListener() { + new ReactInstanceEventListener() { @Override public void onReactContextInitialized(ReactContext reactContext) { reactInstanceManager.removeReactInstanceEventListener(this); diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index b5b6ec2c1..3ced55f71 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -17,7 +17,8 @@ tools:replace="android:allowBackup"> + android:theme="@style/BootTheme" + android:exported="true"> @@ -25,7 +26,7 @@ + android:theme="@style/AppTheme" + android:exported="true"> diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.java b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.java index e67d24c91..fa292ee99 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/MainActivity.java +++ b/android/app/src/main/java/chat/rocket/reactnative/MainActivity.java @@ -1,33 +1,18 @@ package chat.rocket.reactnative; import android.os.Bundle; -import android.content.Context; import android.content.Intent; import android.content.res.Configuration; -import android.content.SharedPreferences; -import com.facebook.react.bridge.Arguments; -import com.facebook.react.bridge.WritableMap; import com.facebook.react.ReactRootView; import com.facebook.react.ReactActivityDelegate; -import com.facebook.react.ReactFragmentActivity; +import com.facebook.react.ReactActivity; + +import expo.modules.ReactActivityDelegateWrapper; import com.zoontek.rnbootsplash.RNBootSplash; -import com.google.gson.Gson; -class ThemePreferences { - String currentTheme; - String darkLevel; -} - -class SortPreferences { - String sortBy; - Boolean groupByType; - Boolean showFavorites; - Boolean showUnread; -} - -public class MainActivity extends ReactFragmentActivity { +public class MainActivity extends ReactActivity { @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,5 +43,27 @@ public class MainActivity extends ReactFragmentActivity { intent.putExtra("newConfig", newConfig); this.sendBroadcast(intent); } -} + /** + * Returns the instance of the {@link ReactActivityDelegate}. There the RootView is created and + * you can specify the rendered you wish to use (Fabric or the older renderer). + */ + @Override + protected ReactActivityDelegate createReactActivityDelegate() { + return new ReactActivityDelegateWrapper(this, new MainActivityDelegate(this, getMainComponentName())); + } + + public static class MainActivityDelegate extends ReactActivityDelegate { + public MainActivityDelegate(ReactActivity activity, String mainComponentName) { + super(activity, mainComponentName); + } + + @Override + protected ReactRootView createRootView() { + ReactRootView reactRootView = new ReactRootView(getContext()); + // If you opted-in for the New Architecture, we enable the Fabric Renderer. + reactRootView.setIsFabric(BuildConfig.IS_NEW_ARCHITECTURE_ENABLED); + return reactRootView; + } + } +} \ No newline at end of file diff --git a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java index c0361e78d..871e6e86d 100644 --- a/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java +++ b/android/app/src/main/java/chat/rocket/reactnative/MainApplication.java @@ -8,24 +8,24 @@ import com.facebook.react.PackageList; import com.facebook.react.ReactApplication; import com.facebook.react.ReactNativeHost; import com.facebook.react.ReactPackage; +import com.facebook.react.config.ReactFeatureFlags; import com.facebook.soloader.SoLoader; import com.reactnativecommunity.viewpager.RNCViewPagerPackage; import com.facebook.react.bridge.JSIModulePackage; import com.swmansion.reanimated.ReanimatedJSIModulePackage; -import org.unimodules.adapters.react.ModuleRegistryAdapter; -import org.unimodules.adapters.react.ReactModuleRegistryProvider; +import android.content.res.Configuration; +import expo.modules.ApplicationLifecycleDispatcher; +import expo.modules.ReactNativeHostWrapper; import java.util.Arrays; import java.util.List; -import chat.rocket.reactnative.generated.BasePackageList; +import chat.rocket.reactnative.newarchitecture.MainApplicationReactNativeHost; import chat.rocket.reactnative.networking.SSLPinningPackage; public class MainApplication extends Application implements ReactApplication { - private final ReactModuleRegistryProvider mModuleRegistryProvider = new ReactModuleRegistryProvider(new BasePackageList().getPackageList(), null); - - private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) { + private final ReactNativeHost mReactNativeHost = new ReactNativeHostWrapper(this, new ReactNativeHost(this) { @Override public boolean getUseDeveloperSupport() { return BuildConfig.DEBUG; @@ -37,10 +37,6 @@ public class MainApplication extends Application implements ReactApplication { List packages = new PackageList(this).getPackages(); packages.add(new RNCViewPagerPackage()); packages.add(new SSLPinningPackage()); - List unimodules = Arrays.asList( - new ModuleRegistryAdapter(mModuleRegistryProvider) - ); - packages.addAll(unimodules); List additionalModules = new AdditionalModules().getAdditionalModules(MainApplication.this); packages.addAll(additionalModules); return packages; @@ -60,16 +56,32 @@ public class MainApplication extends Application implements ReactApplication { protected @Nullable String getBundleAssetName() { return "app.bundle"; } - }; + }); + + private final ReactNativeHost mNewArchitectureNativeHost = + new ReactNativeHostWrapper(this, new MainApplicationReactNativeHost(this)); @Override public ReactNativeHost getReactNativeHost() { - return mReactNativeHost; + if (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) { + return mNewArchitectureNativeHost; + } else { + return mReactNativeHost; + } } @Override public void onCreate() { super.onCreate(); + // If you opted-in for the New Architecture, we enable the TurboModule system + ReactFeatureFlags.useTurboModules = BuildConfig.IS_NEW_ARCHITECTURE_ENABLED; SoLoader.init(this, /* native exopackage */ false); + ApplicationLifecycleDispatcher.onApplicationCreate(this); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + ApplicationLifecycleDispatcher.onConfigurationChanged(this, newConfig); } } diff --git a/android/app/src/main/java/chat/rocket/reactnative/generated/BasePackageList.java b/android/app/src/main/java/chat/rocket/reactnative/generated/BasePackageList.java deleted file mode 100644 index 8143f5969..000000000 --- a/android/app/src/main/java/chat/rocket/reactnative/generated/BasePackageList.java +++ /dev/null @@ -1,21 +0,0 @@ -package chat.rocket.reactnative.generated; - -import java.util.Arrays; -import java.util.List; -import org.unimodules.core.interfaces.Package; - -public class BasePackageList { - public List getPackageList() { - return Arrays.asList( - new expo.modules.av.AVPackage(), - new expo.modules.constants.ConstantsPackage(), - new expo.modules.filesystem.FileSystemPackage(), - new expo.modules.haptics.HapticsPackage(), - new expo.modules.imageloader.ImageLoaderPackage(), - new expo.modules.keepawake.KeepAwakePackage(), - new expo.modules.localauthentication.LocalAuthenticationPackage(), - new expo.modules.videothumbnails.VideoThumbnailsPackage(), - new expo.modules.webbrowser.WebBrowserPackage() - ); - } -} diff --git a/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/MainApplicationReactNativeHost.java b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/MainApplicationReactNativeHost.java new file mode 100644 index 000000000..cf5e9c1ad --- /dev/null +++ b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/MainApplicationReactNativeHost.java @@ -0,0 +1,116 @@ +package chat.rocket.reactnative.newarchitecture; + +import android.app.Application; +import androidx.annotation.NonNull; +import com.facebook.react.PackageList; +import com.facebook.react.ReactInstanceManager; +import com.facebook.react.ReactNativeHost; +import com.facebook.react.ReactPackage; +import com.facebook.react.ReactPackageTurboModuleManagerDelegate; +import com.facebook.react.bridge.JSIModulePackage; +import com.facebook.react.bridge.JSIModuleProvider; +import com.facebook.react.bridge.JSIModuleSpec; +import com.facebook.react.bridge.JSIModuleType; +import com.facebook.react.bridge.JavaScriptContextHolder; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.react.bridge.UIManager; +import com.facebook.react.fabric.ComponentFactory; +import com.facebook.react.fabric.CoreComponentsRegistry; +import com.facebook.react.fabric.EmptyReactNativeConfig; +import com.facebook.react.fabric.FabricJSIModuleProvider; +import com.facebook.react.uimanager.ViewManagerRegistry; +import chat.rocket.reactnative.BuildConfig; +import chat.rocket.reactnative.newarchitecture.components.MainComponentsRegistry; +import chat.rocket.reactnative.newarchitecture.modules.MainApplicationTurboModuleManagerDelegate; +import java.util.ArrayList; +import java.util.List; + +/** + * A {@link ReactNativeHost} that helps you load everything needed for the New Architecture, both + * TurboModule delegates and the Fabric Renderer. + * + *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the + * `newArchEnabled` property). Is ignored otherwise. + */ +public class MainApplicationReactNativeHost extends ReactNativeHost { + public MainApplicationReactNativeHost(Application application) { + super(application); + } + + @Override + public boolean getUseDeveloperSupport() { + return BuildConfig.DEBUG; + } + + @Override + protected List getPackages() { + List packages = new PackageList(this).getPackages(); + // Packages that cannot be autolinked yet can be added manually here, for example: + // packages.add(new MyReactNativePackage()); + // TurboModules must also be loaded here providing a valid TurboReactPackage implementation: + // packages.add(new TurboReactPackage() { ... }); + // If you have custom Fabric Components, their ViewManagers should also be loaded here + // inside a ReactPackage. + return packages; + } + + @Override + protected String getJSMainModuleName() { + return "index"; + } + + @NonNull + @Override + protected ReactPackageTurboModuleManagerDelegate.Builder + getReactPackageTurboModuleManagerDelegateBuilder() { + // Here we provide the ReactPackageTurboModuleManagerDelegate Builder. This is necessary + // for the new architecture and to use TurboModules correctly. + return new MainApplicationTurboModuleManagerDelegate.Builder(); + } + + @Override + protected JSIModulePackage getJSIModulePackage() { + return new JSIModulePackage() { + @Override + public List getJSIModules( + final ReactApplicationContext reactApplicationContext, + final JavaScriptContextHolder jsContext) { + final List specs = new ArrayList<>(); + + // Here we provide a new JSIModuleSpec that will be responsible of providing the + // custom Fabric Components. + specs.add( + new JSIModuleSpec() { + @Override + public JSIModuleType getJSIModuleType() { + return JSIModuleType.UIManager; + } + + @Override + public JSIModuleProvider getJSIModuleProvider() { + final ComponentFactory componentFactory = new ComponentFactory(); + CoreComponentsRegistry.register(componentFactory); + + // Here we register a Components Registry. + // The one that is generated with the template contains no components + // and just provides you the one from React Native core. + MainComponentsRegistry.register(componentFactory); + + final ReactInstanceManager reactInstanceManager = getReactInstanceManager(); + + ViewManagerRegistry viewManagerRegistry = + new ViewManagerRegistry( + reactInstanceManager.getOrCreateViewManagers(reactApplicationContext)); + + return new FabricJSIModuleProvider( + reactApplicationContext, + componentFactory, + new EmptyReactNativeConfig(), + viewManagerRegistry); + } + }); + return specs; + } + }; + } +} \ No newline at end of file diff --git a/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry.java b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry.java new file mode 100644 index 000000000..6519aa669 --- /dev/null +++ b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry.java @@ -0,0 +1,36 @@ +package chat.rocket.reactnative.newarchitecture.components; + +import com.facebook.jni.HybridData; +import com.facebook.proguard.annotations.DoNotStrip; +import com.facebook.react.fabric.ComponentFactory; +import com.facebook.soloader.SoLoader; + +/** + * Class responsible to load the custom Fabric Components. This class has native methods and needs a + * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ + * folder for you). + * + *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the + * `newArchEnabled` property). Is ignored otherwise. + */ +@DoNotStrip +public class MainComponentsRegistry { + static { + SoLoader.loadLibrary("fabricjni"); + } + + @DoNotStrip private final HybridData mHybridData; + + @DoNotStrip + private native HybridData initHybrid(ComponentFactory componentFactory); + + @DoNotStrip + private MainComponentsRegistry(ComponentFactory componentFactory) { + mHybridData = initHybrid(componentFactory); + } + + @DoNotStrip + public static MainComponentsRegistry register(ComponentFactory componentFactory) { + return new MainComponentsRegistry(componentFactory); + } +} \ No newline at end of file diff --git a/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java new file mode 100644 index 000000000..74a5728f2 --- /dev/null +++ b/android/app/src/main/java/chat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate.java @@ -0,0 +1,48 @@ +package chat.rocket.reactnative.newarchitecture.modules; + +import com.facebook.jni.HybridData; +import com.facebook.react.ReactPackage; +import com.facebook.react.ReactPackageTurboModuleManagerDelegate; +import com.facebook.react.bridge.ReactApplicationContext; +import com.facebook.soloader.SoLoader; +import java.util.List; + +/** + * Class responsible to load the TurboModules. This class has native methods and needs a + * corresponding C++ implementation/header file to work correctly (already placed inside the jni/ + * folder for you). + * + *

Please note that this class is used ONLY if you opt-in for the New Architecture (see the + * `newArchEnabled` property). Is ignored otherwise. + */ +public class MainApplicationTurboModuleManagerDelegate + extends ReactPackageTurboModuleManagerDelegate { + + private static volatile boolean sIsSoLibraryLoaded; + + protected MainApplicationTurboModuleManagerDelegate( + ReactApplicationContext reactApplicationContext, List packages) { + super(reactApplicationContext, packages); + } + + protected native HybridData initHybrid(); + + native boolean canCreateTurboModule(String moduleName); + + public static class Builder extends ReactPackageTurboModuleManagerDelegate.Builder { + protected MainApplicationTurboModuleManagerDelegate build( + ReactApplicationContext context, List packages) { + return new MainApplicationTurboModuleManagerDelegate(context, packages); + } + } + + @Override + protected synchronized void maybeLoadOtherSoLibraries() { + if (!sIsSoLibraryLoaded) { + // If you change the name of your application .so file in the Android.mk file, + // make sure you update the name here as well. + SoLoader.loadLibrary("rocketchat_appmodules"); + sIsSoLibraryLoaded = true; + } + } +} \ No newline at end of file diff --git a/android/app/src/main/jni/Android.mk b/android/app/src/main/jni/Android.mk new file mode 100644 index 000000000..db632d8b3 --- /dev/null +++ b/android/app/src/main/jni/Android.mk @@ -0,0 +1,49 @@ +THIS_DIR := $(call my-dir) + +include $(REACT_ANDROID_DIR)/Android-prebuilt.mk + +# If you wish to add a custom TurboModule or Fabric component in your app you +# will have to include the following autogenerated makefile. +# include $(GENERATED_SRC_DIR)/codegen/jni/Android.mk +include $(CLEAR_VARS) + +LOCAL_PATH := $(THIS_DIR) + +# You can customize the name of your application .so file here. +LOCAL_MODULE := rocketchat_appmodules + +LOCAL_C_INCLUDES := $(LOCAL_PATH) +LOCAL_SRC_FILES := $(wildcard $(LOCAL_PATH)/*.cpp) +LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH) + +# If you wish to add a custom TurboModule or Fabric component in your app you +# will have to uncomment those lines to include the generated source +# files from the codegen (placed in $(GENERATED_SRC_DIR)/codegen/jni) +# +# LOCAL_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni +# LOCAL_SRC_FILES += $(wildcard $(GENERATED_SRC_DIR)/codegen/jni/*.cpp) +# LOCAL_EXPORT_C_INCLUDES += $(GENERATED_SRC_DIR)/codegen/jni + +# Here you should add any native library you wish to depend on. +LOCAL_SHARED_LIBRARIES := \ + libfabricjni \ + libfbjni \ + libfolly_futures \ + libfolly_json \ + libglog \ + libjsi \ + libreact_codegen_rncore \ + libreact_debug \ + libreact_nativemodule_core \ + libreact_render_componentregistry \ + libreact_render_core \ + libreact_render_debug \ + libreact_render_graphics \ + librrc_view \ + libruntimeexecutor \ + libturbomodulejsijni \ + libyoga + +LOCAL_CFLAGS := -DLOG_TAG=\"ReactNative\" -fexceptions -frtti -std=c++17 -Wall + +include $(BUILD_SHARED_LIBRARY) \ No newline at end of file diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.cpp b/android/app/src/main/jni/MainApplicationModuleProvider.cpp new file mode 100644 index 000000000..39de093d1 --- /dev/null +++ b/android/app/src/main/jni/MainApplicationModuleProvider.cpp @@ -0,0 +1,24 @@ +#include "MainApplicationModuleProvider.h" + +#include + +namespace facebook { +namespace react { + +std::shared_ptr MainApplicationModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms) { + // Here you can provide your own module provider for TurboModules coming from + // either your application or from external libraries. The approach to follow + // is similar to the following (for a library called `samplelibrary`: + // + // auto module = samplelibrary_ModuleProvider(moduleName, params); + // if (module != nullptr) { + // return module; + // } + // return rncore_ModuleProvider(moduleName, params); + return rncore_ModuleProvider(moduleName, params); +} + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/MainApplicationModuleProvider.h b/android/app/src/main/jni/MainApplicationModuleProvider.h new file mode 100644 index 000000000..2f2fb24a3 --- /dev/null +++ b/android/app/src/main/jni/MainApplicationModuleProvider.h @@ -0,0 +1,16 @@ +#pragma once + +#include +#include + +#include + +namespace facebook { +namespace react { + +std::shared_ptr MainApplicationModuleProvider( + const std::string moduleName, + const JavaTurboModule::InitParams ¶ms); + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp new file mode 100644 index 000000000..f2e4714dc --- /dev/null +++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.cpp @@ -0,0 +1,45 @@ +#include "MainApplicationTurboModuleManagerDelegate.h" +#include "MainApplicationModuleProvider.h" + +namespace facebook { +namespace react { + +jni::local_ref +MainApplicationTurboModuleManagerDelegate::initHybrid( + jni::alias_ref) { + return makeCxxInstance(); +} + +void MainApplicationTurboModuleManagerDelegate::registerNatives() { + registerHybrid({ + makeNativeMethod( + "initHybrid", MainApplicationTurboModuleManagerDelegate::initHybrid), + makeNativeMethod( + "canCreateTurboModule", + MainApplicationTurboModuleManagerDelegate::canCreateTurboModule), + }); +} + +std::shared_ptr +MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string name, + const std::shared_ptr jsInvoker) { + // Not implemented yet: provide pure-C++ NativeModules here. + return nullptr; +} + +std::shared_ptr +MainApplicationTurboModuleManagerDelegate::getTurboModule( + const std::string name, + const JavaTurboModule::InitParams ¶ms) { + return MainApplicationModuleProvider(name, params); +} + +bool MainApplicationTurboModuleManagerDelegate::canCreateTurboModule( + std::string name) { + return getTurboModule(name, nullptr) != nullptr || + getTurboModule(name, {.moduleName = name}) != nullptr; +} + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h new file mode 100644 index 000000000..f2401d08f --- /dev/null +++ b/android/app/src/main/jni/MainApplicationTurboModuleManagerDelegate.h @@ -0,0 +1,38 @@ +#include +#include + +#include +#include + +namespace facebook { +namespace react { + +class MainApplicationTurboModuleManagerDelegate + : public jni::HybridClass< + MainApplicationTurboModuleManagerDelegate, + TurboModuleManagerDelegate> { + public: + // Adapt it to the package you used for your Java class. + static constexpr auto kJavaDescriptor = + "Lchat/rocket/reactnative/newarchitecture/modules/MainApplicationTurboModuleManagerDelegate;"; + + static jni::local_ref initHybrid(jni::alias_ref); + + static void registerNatives(); + + std::shared_ptr getTurboModule( + const std::string name, + const std::shared_ptr jsInvoker) override; + std::shared_ptr getTurboModule( + const std::string name, + const JavaTurboModule::InitParams ¶ms) override; + + /** + * Test-only method. Allows user to verify whether a TurboModule can be + * created by instances of this class. + */ + bool canCreateTurboModule(std::string name); +}; + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/MainComponentsRegistry.cpp b/android/app/src/main/jni/MainComponentsRegistry.cpp new file mode 100644 index 000000000..c5188f4dc --- /dev/null +++ b/android/app/src/main/jni/MainComponentsRegistry.cpp @@ -0,0 +1,61 @@ +#include "MainComponentsRegistry.h" + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +MainComponentsRegistry::MainComponentsRegistry(ComponentFactory *delegate) {} + +std::shared_ptr +MainComponentsRegistry::sharedProviderRegistry() { + auto providerRegistry = CoreComponentsRegistry::sharedProviderRegistry(); + + // Custom Fabric Components go here. You can register custom + // components coming from your App or from 3rd party libraries here. + // + // providerRegistry->add(concreteComponentDescriptorProvider< + // AocViewerComponentDescriptor>()); + return providerRegistry; +} + +jni::local_ref +MainComponentsRegistry::initHybrid( + jni::alias_ref, + ComponentFactory *delegate) { + auto instance = makeCxxInstance(delegate); + + auto buildRegistryFunction = + [](EventDispatcher::Weak const &eventDispatcher, + ContextContainer::Shared const &contextContainer) + -> ComponentDescriptorRegistry::Shared { + auto registry = MainComponentsRegistry::sharedProviderRegistry() + ->createComponentDescriptorRegistry( + {eventDispatcher, contextContainer}); + + auto mutableRegistry = + std::const_pointer_cast(registry); + + mutableRegistry->setFallbackComponentDescriptor( + std::make_shared( + ComponentDescriptorParameters{ + eventDispatcher, contextContainer, nullptr})); + + return registry; + }; + + delegate->buildRegistryFunction = buildRegistryFunction; + return instance; +} + +void MainComponentsRegistry::registerNatives() { + registerHybrid({ + makeNativeMethod("initHybrid", MainComponentsRegistry::initHybrid), + }); +} + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/MainComponentsRegistry.h b/android/app/src/main/jni/MainComponentsRegistry.h new file mode 100644 index 000000000..8e5cd1f1f --- /dev/null +++ b/android/app/src/main/jni/MainComponentsRegistry.h @@ -0,0 +1,32 @@ +#pragma once + +#include +#include +#include +#include + +namespace facebook { +namespace react { + +class MainComponentsRegistry + : public facebook::jni::HybridClass { + public: + // Adapt it to the package you used for your Java class. + constexpr static auto kJavaDescriptor = + "Lchat/rocket/reactnative/newarchitecture/components/MainComponentsRegistry;"; + + static void registerNatives(); + + MainComponentsRegistry(ComponentFactory *delegate); + + private: + static std::shared_ptr + sharedProviderRegistry(); + + static jni::local_ref initHybrid( + jni::alias_ref, + ComponentFactory *delegate); +}; + +} // namespace react +} // namespace facebook \ No newline at end of file diff --git a/android/app/src/main/jni/OnLoad.cpp b/android/app/src/main/jni/OnLoad.cpp new file mode 100644 index 000000000..ae1ef007d --- /dev/null +++ b/android/app/src/main/jni/OnLoad.cpp @@ -0,0 +1,11 @@ +#include +#include "MainApplicationTurboModuleManagerDelegate.h" +#include "MainComponentsRegistry.h" + +JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *) { + return facebook::jni::initialize(vm, [] { + facebook::react::MainApplicationTurboModuleManagerDelegate:: + registerNatives(); + facebook::react::MainComponentsRegistry::registerNatives(); + }); +} \ No newline at end of file diff --git a/android/app/src/main/res/drawable/rn_edit_text_material.xml b/android/app/src/main/res/drawable/rn_edit_text_material.xml new file mode 100644 index 000000000..bb6f578c3 --- /dev/null +++ b/android/app/src/main/res/drawable/rn_edit_text_material.xml @@ -0,0 +1,29 @@ + + + + + + + + + \ No newline at end of file diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index 22d14143e..1fd46175e 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -4,6 +4,8 @@ @color/splashBackground @color/splashBackground false + + @drawable/rn_edit_text_material