diff --git a/app/components/markdown/index.ts b/app/components/markdown/index.ts index cf0209521..fca59ee53 100644 --- a/app/components/markdown/index.ts +++ b/app/components/markdown/index.ts @@ -5,7 +5,7 @@ import {withDatabase} from '@nozbe/watermelondb/DatabaseProvider'; import withObservables from '@nozbe/with-observables'; import React from 'react'; -import {observeConfigBooleanValue} from '@queries/servers/system'; +import {observeConfigBooleanValue, observeConfigIntValue} from '@queries/servers/system'; import Markdown from './markdown'; @@ -14,11 +14,13 @@ import type {WithDatabaseArgs} from '@typings/database/database'; const enhanced = withObservables([], ({database}: WithDatabaseArgs) => { const enableLatex = observeConfigBooleanValue(database, 'EnableLatex'); const enableInlineLatex = observeConfigBooleanValue(database, 'EnableInlineLatex'); + const maxNodes = observeConfigIntValue(database, 'MaxMarkdownNodes'); return { enableLatex, enableInlineLatex, + maxNodes, }; }); -export default React.memo(withDatabase(enhanced(Markdown))); +export default withDatabase(enhanced(React.memo(Markdown))); diff --git a/app/components/markdown/markdown.tsx b/app/components/markdown/markdown.tsx index 470f2159e..f16237245 100644 --- a/app/components/markdown/markdown.tsx +++ b/app/components/markdown/markdown.tsx @@ -62,6 +62,7 @@ type MarkdownProps = { layoutHeight?: number; layoutWidth?: number; location: string; + maxNodes: number; mentionKeys?: UserMentionKey[]; minimumHashtagLength?: number; onPostPress?: (event: GestureResponderEvent) => void; @@ -69,7 +70,7 @@ type MarkdownProps = { searchPatterns?: SearchPattern[]; textStyles?: MarkdownTextStyles; theme: Theme; - value?: string | number; + value?: string; } const getStyleSheet = makeStyleSheetFromTheme((theme) => { @@ -94,6 +95,9 @@ const getStyleSheet = makeStyleSheetFromTheme((theme) => { color: editedColor, opacity: editedOpacity, }, + maxNodesWarning: { + color: theme.errorTextColor, + }, atMentionOpacity: { opacity: 1, }, @@ -126,7 +130,7 @@ const Markdown = ({ autolinkedUrlSchemes, baseTextStyle, blockStyles, channelId, channelMentions, disableAtChannelMentionHighlight, disableAtMentions, disableBlockQuote, disableChannelLink, disableCodeBlock, disableGallery, disableHashtags, disableHeading, disableTables, - enableInlineLatex, enableLatex, + enableInlineLatex, enableLatex, maxNodes, imagesMetadata, isEdited, isReplyPost, isSearchResult, layoutHeight, layoutWidth, location, mentionKeys, minimumHashtagLength = 3, onPostPress, postId, searchPatterns, textStyles = {}, theme, value = '', baseParagraphStyle, @@ -520,6 +524,19 @@ const Markdown = ({ ); }; + const renderMaxNodesWarning = () => { + const styles = [baseTextStyle, style.maxNodesWarning]; + + return ( + + ); + }; + const createRenderer = () => { const renderers: any = { text: renderText, @@ -534,7 +551,7 @@ const Markdown = ({ channelLink: renderChannelLink, emoji: renderEmoji, hashtag: renderHashtag, - latexinline: renderLatexInline, + latexInline: renderLatexInline, paragraph: renderParagraph, heading: renderHeading, @@ -560,11 +577,13 @@ const Markdown = ({ checkbox: renderCheckbox, editedIndicator: renderEditedIndicator, + maxNodesWarning: renderMaxNodesWarning, }; return new Renderer({ renderers, renderParagraphsInLists: true, + maxNodes, getExtraPropsForNode, allowedTypes: Object.keys(renderers), }); diff --git a/app/components/markdown/markdown_table_row/index.tsx b/app/components/markdown/markdown_table_row/index.tsx index d2086ffee..c34808536 100644 --- a/app/components/markdown/markdown_table_row/index.tsx +++ b/app/components/markdown/markdown_table_row/index.tsx @@ -45,9 +45,11 @@ const MarkdownTableRow = ({isFirstRow, isLastRow, children}: MarkdownTableRowPro // Add an extra prop to the last cell so that it knows not to render a right border since the container // will handle that const renderChildren = React.Children.toArray(children) as ReactElement[]; - renderChildren[renderChildren.length - 1] = React.cloneElement(renderChildren[renderChildren.length - 1], { - isLastCell: true, - }); + if (renderChildren.length > 0) { + renderChildren[renderChildren.length - 1] = React.cloneElement(renderChildren[renderChildren.length - 1], { + isLastCell: true, + }); + } return ( { }, { type: 'at_mention', _mentionName: 'user', - children: [{ - type: 'text', - literal: '@user', - }], }], }], }, @@ -2154,10 +2150,6 @@ describe('Components.Markdown.transform', () => { children: [{ type: 'at_mention', _mentionName: 'words', - children: [{ - type: 'text', - literal: '@words', - }], }], }], }], @@ -2178,10 +2170,6 @@ describe('Components.Markdown.transform', () => { children: [{ type: 'at_mention', _mentionName: 'words', - children: [{ - type: 'text', - literal: '@words', - }], }], }], }], @@ -2579,10 +2567,6 @@ describe('Components.Markdown.transform', () => { children: [{ type: 'at_mention', _mentionName: 'channel.', - children: [{ - type: 'text', - literal: '@channel.', - }], }], }], }], @@ -2601,10 +2585,6 @@ describe('Components.Markdown.transform', () => { }, { type: 'at_mention', _mentionName: 'Gvn.', - children: [{ - type: 'text', - literal: '@Gvn.', - }], }], }], }, diff --git a/assets/base/i18n/en.json b/assets/base/i18n/en.json index 799536bd3..4ff97515b 100644 --- a/assets/base/i18n/en.json +++ b/assets/base/i18n/en.json @@ -404,6 +404,7 @@ "login.signingIn": "Logging In", "login.username": "Username", "markdown.latex.error": "Latex render error", + "markdown.max_nodes.error": "This message is too long to by shown fully on a mobile device. Please view it on desktop or contact an admin to increase this limit.", "mentions.empty.paragraph": "You'll see messages here when someone mentions you or uses terms you're monitoring.", "mentions.empty.title": "No Mentions yet", "mobile.about.appVersion": "App Version: {version} (Build {number})", diff --git a/package-lock.json b/package-lock.json index a3ca6d58e..1c18f5483 100644 --- a/package-lock.json +++ b/package-lock.json @@ -41,8 +41,8 @@ "@stream-io/flat-list-mvcp": "0.10.3", "@tsconfig/react-native": "3.0.2", "base-64": "1.0.0", - "commonmark": "npm:@mattermost/commonmark@0.30.1-0", - "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#2c660491041f7595f6ce5a05f6dc2e30ca769d3a", + "commonmark": "npm:@mattermost/commonmark@0.30.1-1", + "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12", "deep-equal": "2.2.2", "deepmerge": "4.3.1", "emoji-regex": "10.2.1", @@ -9665,9 +9665,9 @@ }, "node_modules/commonmark": { "name": "@mattermost/commonmark", - "version": "0.30.1-0", - "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-0.tgz", - "integrity": "sha512-0+qW22COfd/BA81TQ05nQMfhmnuRAkv/vwCbs3iFVTEj7mTunYRwWUyb5M8K849V2VXdLdrS8htsBtIHDb2H7g==", + "version": "0.30.1-1", + "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-1.tgz", + "integrity": "sha512-zOiOtPA5LjB1WCUVbaMt5KNuNdq/0NLpBOcQlGrKe+ftuJVhiis7pWEqS4agIBlpjhm7ssywwl7p1eurOjcm5A==", "dependencies": { "entities": "~3.0.1", "mdurl": "~1.0.1", @@ -9684,8 +9684,8 @@ }, "node_modules/commonmark-react-renderer": { "version": "4.3.5", - "resolved": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#2c660491041f7595f6ce5a05f6dc2e30ca769d3a", - "integrity": "sha512-D++d6UFNLyu4fAAZg6blRb3rkiG+bFWKJ8fSLOJwzBit3Hm/sPZbx2QQeKfx+IHoMg7cCvHlesAT1+kB/+kBLQ==", + "resolved": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#235bc817bcade503fb81fa51bbbe3c84f958ed12", + "integrity": "sha512-GP3+17loU8tNal91FAlqDcDyUHdhahMPpV/XBm++VAyoyvsGKx3wGQZY/cVKXNx+SV2UANXVf4VFx8GpAkqCBQ==", "license": "MIT", "dependencies": { "lodash.assign": "^4.2.0", @@ -30025,9 +30025,9 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=" }, "commonmark": { - "version": "npm:@mattermost/commonmark@0.30.1-0", - "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-0.tgz", - "integrity": "sha512-0+qW22COfd/BA81TQ05nQMfhmnuRAkv/vwCbs3iFVTEj7mTunYRwWUyb5M8K849V2VXdLdrS8htsBtIHDb2H7g==", + "version": "npm:@mattermost/commonmark@0.30.1-1", + "resolved": "https://registry.npmjs.org/@mattermost/commonmark/-/commonmark-0.30.1-1.tgz", + "integrity": "sha512-zOiOtPA5LjB1WCUVbaMt5KNuNdq/0NLpBOcQlGrKe+ftuJVhiis7pWEqS4agIBlpjhm7ssywwl7p1eurOjcm5A==", "requires": { "entities": "~3.0.1", "mdurl": "~1.0.1", @@ -30044,9 +30044,9 @@ } }, "commonmark-react-renderer": { - "version": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#2c660491041f7595f6ce5a05f6dc2e30ca769d3a", - "integrity": "sha512-D++d6UFNLyu4fAAZg6blRb3rkiG+bFWKJ8fSLOJwzBit3Hm/sPZbx2QQeKfx+IHoMg7cCvHlesAT1+kB/+kBLQ==", - "from": "commonmark-react-renderer@github:mattermost/commonmark-react-renderer#2c660491041f7595f6ce5a05f6dc2e30ca769d3a", + "version": "git+ssh://git@github.com/mattermost/commonmark-react-renderer.git#235bc817bcade503fb81fa51bbbe3c84f958ed12", + "integrity": "sha512-GP3+17loU8tNal91FAlqDcDyUHdhahMPpV/XBm++VAyoyvsGKx3wGQZY/cVKXNx+SV2UANXVf4VFx8GpAkqCBQ==", + "from": "commonmark-react-renderer@github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12", "requires": { "lodash.assign": "^4.2.0", "lodash.isplainobject": "^4.0.6", diff --git a/package.json b/package.json index 6c325d326..314fd0181 100644 --- a/package.json +++ b/package.json @@ -38,8 +38,8 @@ "@stream-io/flat-list-mvcp": "0.10.3", "@tsconfig/react-native": "3.0.2", "base-64": "1.0.0", - "commonmark": "npm:@mattermost/commonmark@0.30.1-0", - "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#2c660491041f7595f6ce5a05f6dc2e30ca769d3a", + "commonmark": "npm:@mattermost/commonmark@0.30.1-1", + "commonmark-react-renderer": "github:mattermost/commonmark-react-renderer#235bc817bcade503fb81fa51bbbe3c84f958ed12", "deep-equal": "2.2.2", "deepmerge": "4.3.1", "emoji-regex": "10.2.1", diff --git a/patches/@types+commonmark-react-renderer+4.3.1.patch b/patches/@types+commonmark-react-renderer+4.3.1.patch index a9c2f8be9..0c5ecb995 100644 --- a/patches/@types+commonmark-react-renderer+4.3.1.patch +++ b/patches/@types+commonmark-react-renderer+4.3.1.patch @@ -1,17 +1,18 @@ diff --git a/node_modules/@types/commonmark-react-renderer/index.d.ts b/node_modules/@types/commonmark-react-renderer/index.d.ts -index 9ee5664..44d9a20 100755 +index 9ee5664..7ada0a0 100755 --- a/node_modules/@types/commonmark-react-renderer/index.d.ts +++ b/node_modules/@types/commonmark-react-renderer/index.d.ts -@@ -88,6 +88,8 @@ declare namespace ReactRenderer { +@@ -88,6 +88,9 @@ declare namespace ReactRenderer { transformLinkUri?: ((uri: string) => string) | null | undefined; transformImageUri?: ((uri: string) => string) | null | undefined; linkTarget?: string | undefined; + renderParagraphsInLists?: boolean; ++ maxNodes?: number; + getExtraPropsForNode?: (node: any) => Record; } interface Renderer { -@@ -113,6 +115,7 @@ interface ReactRenderer { +@@ -113,6 +116,7 @@ interface ReactRenderer { uriTransformer: (uri: string) => string; types: string[]; renderers: ReactRenderer.Renderers; diff --git a/types/api/config.d.ts b/types/api/config.d.ts index 64f719183..7320a732d 100644 --- a/types/api/config.d.ts +++ b/types/api/config.d.ts @@ -143,6 +143,7 @@ interface ClientConfig { LdapPositionAttributeSet: string; LockTeammateNameDisplay: string; MaxFileSize: string; + MaxMarkdownNodes: string; MaxNotificationsPerChannel: string; MaxPostSize: string; MinimumHashtagLength: string;