From 637bce7ba73c6a0a3d898b9b5e7ad13dc992ee35 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 31 Mar 2021 21:00:36 +0200 Subject: [PATCH 1/5] Fix and improve rendering of markdown elements - Markdown will no be rendered - Render text always below an image - block quotes wont be just indented text --- .../components/CommentInput/CommentInput.tsx | 2 +- .../src/components/Content/BlockQuoteTag.tsx | 21 +++++++++++++++++++ webui/src/components/Content/ImageTag.tsx | 9 +++++--- webui/src/components/Content/index.tsx | 10 +++++---- webui/src/pages/bug/CommentForm.tsx | 8 ------- webui/src/pages/bug/Message.tsx | 3 ++- 6 files changed, 36 insertions(+), 17 deletions(-) create mode 100644 webui/src/components/Content/BlockQuoteTag.tsx diff --git a/webui/src/components/CommentInput/CommentInput.tsx b/webui/src/components/CommentInput/CommentInput.tsx index c574538e886f220675bf839dc91c6ef7ac25c4b8..f12ee8d8f1e35cd88a02c7d49891d1affa15dcd8 100644 --- a/webui/src/components/CommentInput/CommentInput.tsx +++ b/webui/src/components/CommentInput/CommentInput.tsx @@ -5,7 +5,7 @@ import Tabs from '@material-ui/core/Tabs'; import TextField from '@material-ui/core/TextField'; import { makeStyles } from '@material-ui/core/styles'; -import Content from 'src/components/Content'; +import Content from '../Content'; /** * Styles diff --git a/webui/src/components/Content/BlockQuoteTag.tsx b/webui/src/components/Content/BlockQuoteTag.tsx new file mode 100644 index 0000000000000000000000000000000000000000..18c34d8a9c5d1f7e5eba75424833a28612a3ccf3 --- /dev/null +++ b/webui/src/components/Content/BlockQuoteTag.tsx @@ -0,0 +1,21 @@ +import React from 'react'; + +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + tag: { + color: theme.palette.text.secondary, + borderLeftWidth: '0.5ch', + borderLeftStyle: 'solid', + borderLeftColor: theme.palette.text.secondary, + marginLeft: 0, + paddingLeft: '0.5rem', + }, +})); + +const BlockQuoteTag = (props: React.HTMLProps) => { + const classes = useStyles(); + return
; +}; + +export default BlockQuoteTag; diff --git a/webui/src/components/Content/ImageTag.tsx b/webui/src/components/Content/ImageTag.tsx index 70ee1bc03eca2182b87e9fdd186f7f80a7b418bf..29b01da305a5f693d1129720f2db83aad4319cd2 100644 --- a/webui/src/components/Content/ImageTag.tsx +++ b/webui/src/components/Content/ImageTag.tsx @@ -14,9 +14,12 @@ const ImageTag = ({ }: React.ImgHTMLAttributes) => { const classes = useStyles(); return ( - - {alt} - + <> + + {alt} + +
+ ); }; diff --git a/webui/src/components/Content/index.tsx b/webui/src/components/Content/index.tsx index 56e52e1efcfc530815e6cf80987ca3ddb47b82d2..75360bb6bf48d3d2b952f1888096a219df39c33d 100644 --- a/webui/src/components/Content/index.tsx +++ b/webui/src/components/Content/index.tsx @@ -4,23 +4,25 @@ import parse from 'remark-parse'; import remark2react from 'remark-react'; import unified from 'unified'; +import BlockQuoteTag from './BlockQuoteTag'; import ImageTag from './ImageTag'; import PreTag from './PreTag'; type Props = { markdown: string }; const Content: React.FC = ({ markdown }: Props) => { - const processor = unified() + const content = unified() .use(parse) .use(html) .use(remark2react, { remarkReactComponents: { img: ImageTag, pre: PreTag, + blockquote: BlockQuoteTag, }, - }); + }) + .processSync(markdown).result; - const contents: React.ReactNode = processor.processSync(markdown).contents; - return <>{contents}; + return <>{content}; }; export default Content; diff --git a/webui/src/pages/bug/CommentForm.tsx b/webui/src/pages/bug/CommentForm.tsx index e70348a6e883f7ffcb6be3a331322d9f4698250c..a8ce431950fa6bbd002d4512010c61e27a8ee907 100644 --- a/webui/src/pages/bug/CommentForm.tsx +++ b/webui/src/pages/bug/CommentForm.tsx @@ -17,14 +17,6 @@ const useStyles = makeStyles((theme) => ({ container: { padding: theme.spacing(0, 2, 2, 2), }, - textarea: {}, - tabContent: { - margin: theme.spacing(2, 0), - }, - preview: { - borderBottom: `solid 3px ${theme.palette.grey['200']}`, - minHeight: '5rem', - }, actions: { display: 'flex', gap: '1em', diff --git a/webui/src/pages/bug/Message.tsx b/webui/src/pages/bug/Message.tsx index 2f4cbc592ee6f3016426eec371899c3efcd43b99..39b11ccdae7b3ab25dc9f50ccbda9ccef98321a9 100644 --- a/webui/src/pages/bug/Message.tsx +++ b/webui/src/pages/bug/Message.tsx @@ -57,7 +57,8 @@ const useStyles = makeStyles((theme) => ({ }, body: { ...theme.typography.body2, - padding: '0.5rem', + paddingLeft: theme.spacing(1), + paddingRight: theme.spacing(1), }, headerActions: { color: theme.palette.info.contrastText, From 50ef67664dd13ff8abc909be3c0ec0f46a616a15 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 31 Mar 2021 21:17:08 +0200 Subject: [PATCH 2/5] Add emoji rendering support via remark-gemoji --- webui/package-lock.json | 26 +++++++++++++++++++++++--- webui/package.json | 1 + webui/src/components/Content/index.tsx | 2 ++ webui/types/remark-gemoji/index.d.ts | 6 ++++++ 4 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 webui/types/remark-gemoji/index.d.ts diff --git a/webui/package-lock.json b/webui/package-lock.json index 12dea8b969fcabba9ff1466ce1876034f044dd47..b3b2a4907213cc85fa161b95e7ebf5606d1da1b3 100644 --- a/webui/package-lock.json +++ b/webui/package-lock.json @@ -12325,6 +12325,11 @@ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, + "gemoji": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/gemoji/-/gemoji-6.1.0.tgz", + "integrity": "sha512-MOlX3doQ1fsfzxQX8Y+u6bC5Ssc1pBUBIPVyrS69EzKt+5LIZAOm0G5XGVNhwXFgkBF3r+Yk88ONyrFHo8iNFA==" + }, "generic-names": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/generic-names/-/generic-names-2.0.1.tgz", @@ -12572,7 +12577,8 @@ "growly": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", - "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=" + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "optional": true }, "gzip-size": { "version": "5.1.1", @@ -16118,6 +16124,7 @@ "version": "8.0.1", "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-8.0.1.tgz", "integrity": "sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==", + "optional": true, "requires": { "growly": "^1.3.0", "is-wsl": "^2.2.0", @@ -16131,6 +16138,7 @@ "version": "7.3.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.4.tgz", "integrity": "sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==", + "optional": true, "requires": { "lru-cache": "^6.0.0" } @@ -16138,12 +16146,14 @@ "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "optional": true }, "which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "optional": true, "requires": { "isexe": "^2.0.0" } @@ -19227,6 +19237,15 @@ "fbjs": "^1.0.0" } }, + "remark-gemoji": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/remark-gemoji/-/remark-gemoji-6.0.0.tgz", + "integrity": "sha512-LDW2h6QqNzAbAcOjscgfkJW9/8TGBasBe/ji+3mCxHlJdhF2IEXFSmm/3tdEPP1JJDZ4y+Ea+xlFQ4tOIU9WvA==", + "requires": { + "gemoji": "^6.0.0", + "unist-util-visit": "^2.0.0" + } + }, "remark-html": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/remark-html/-/remark-html-12.0.0.tgz", @@ -20219,7 +20238,8 @@ "shellwords": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", - "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==" + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "optional": true }, "side-channel": { "version": "1.0.3", diff --git a/webui/package.json b/webui/package.json index 39696a25918f7fe4b2bd1f8748f1e83097ab9b69..47cdf8d02c56207ea6d87584d9f95f9d7f223156 100644 --- a/webui/package.json +++ b/webui/package.json @@ -22,6 +22,7 @@ "react-router": "^5.2.0", "react-router-dom": "^5.2.0", "react-scripts": "^4.0.0-next.98", + "remark-gemoji": "^6.0.0", "remark-html": "^12.0.0", "remark-parse": "^8.0.3", "remark-react": "^7.0.1", diff --git a/webui/src/components/Content/index.tsx b/webui/src/components/Content/index.tsx index 75360bb6bf48d3d2b952f1888096a219df39c33d..809ae8186a1b2a4fe4c43024d99ed74db10492ae 100644 --- a/webui/src/components/Content/index.tsx +++ b/webui/src/components/Content/index.tsx @@ -1,4 +1,5 @@ import React from 'react'; +import gemoji from 'remark-gemoji'; import html from 'remark-html'; import parse from 'remark-parse'; import remark2react from 'remark-react'; @@ -12,6 +13,7 @@ type Props = { markdown: string }; const Content: React.FC = ({ markdown }: Props) => { const content = unified() .use(parse) + .use(gemoji) .use(html) .use(remark2react, { remarkReactComponents: { diff --git a/webui/types/remark-gemoji/index.d.ts b/webui/types/remark-gemoji/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f15725b2f8ae6c8013f1635cb2855be6785c81ad --- /dev/null +++ b/webui/types/remark-gemoji/index.d.ts @@ -0,0 +1,6 @@ +declare module 'remark-gemoji' { + import { Plugin } from 'unified'; + + const plugin: Plugin; + export default plugin; +} From 23300d1c1a9f99462c08d4e43ca68b1c3fd0cfd2 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 7 Apr 2021 18:51:51 +0200 Subject: [PATCH 3/5] Use custom anchor in markdown The custom anchor will be more readable in dark mode. Also it will supports linking within the SPA. --- webui/src/components/Content/AnchorTag.tsx | 38 ++++++++++++++++++++++ webui/src/components/Content/index.tsx | 2 ++ 2 files changed, 40 insertions(+) create mode 100644 webui/src/components/Content/AnchorTag.tsx diff --git a/webui/src/components/Content/AnchorTag.tsx b/webui/src/components/Content/AnchorTag.tsx new file mode 100644 index 0000000000000000000000000000000000000000..47d5e2fac3433951f3f10cfef9012f92239efd91 --- /dev/null +++ b/webui/src/components/Content/AnchorTag.tsx @@ -0,0 +1,38 @@ +import React from 'react'; +import { Link } from 'react-router-dom'; + +import { makeStyles } from '@material-ui/core/styles'; + +const useStyles = makeStyles((theme) => ({ + tag: { + color: theme.palette.text.secondary, + }, +})); + +const AnchorTag = ({ children, href }: React.HTMLProps) => { + const classes = useStyles(); + const origin = window.location.origin; + const destination = href === undefined ? '' : href; + const isInternalLink = + destination.startsWith('/') || destination.startsWith(origin); + const internalDestination = destination.replace(origin, ''); + const internalLink = ( + + {children} + + ); + const externalLink = ( + + {children} + + ); + + return isInternalLink ? internalLink : externalLink; +}; + +export default AnchorTag; diff --git a/webui/src/components/Content/index.tsx b/webui/src/components/Content/index.tsx index 809ae8186a1b2a4fe4c43024d99ed74db10492ae..e40188093c398842808ab02d7f18f2eb6e9be646 100644 --- a/webui/src/components/Content/index.tsx +++ b/webui/src/components/Content/index.tsx @@ -5,6 +5,7 @@ import parse from 'remark-parse'; import remark2react from 'remark-react'; import unified from 'unified'; +import AnchorTag from './AnchorTag'; import BlockQuoteTag from './BlockQuoteTag'; import ImageTag from './ImageTag'; import PreTag from './PreTag'; @@ -19,6 +20,7 @@ const Content: React.FC = ({ markdown }: Props) => { remarkReactComponents: { img: ImageTag, pre: PreTag, + a: AnchorTag, blockquote: BlockQuoteTag, }, }) From d4ad748e6175a2d00f75c872e60cc83089af9d74 Mon Sep 17 00:00:00 2001 From: Sascha Date: Wed, 7 Apr 2021 19:08:01 +0200 Subject: [PATCH 4/5] Render comment history via markdown --- webui/src/pages/bug/MessageHistoryDialog.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/webui/src/pages/bug/MessageHistoryDialog.tsx b/webui/src/pages/bug/MessageHistoryDialog.tsx index 0ed33642cec6366e438457e2a5184d687b6018e1..da5d0ccff93d7810d7fe4ff806738cbaa6690aed 100644 --- a/webui/src/pages/bug/MessageHistoryDialog.tsx +++ b/webui/src/pages/bug/MessageHistoryDialog.tsx @@ -22,6 +22,8 @@ import { import CloseIcon from '@material-ui/icons/Close'; import ExpandMoreIcon from '@material-ui/icons/ExpandMore'; +import Content from '../../components/Content'; + import { AddCommentFragment } from './MessageCommentFragment.generated'; import { CreateFragment } from './MessageCreateFragment.generated'; import { useMessageHistoryQuery } from './MessageHistory.generated'; @@ -108,6 +110,7 @@ const AccordionSummary = withStyles((theme) => ({ const AccordionDetails = withStyles((theme) => ({ root: { + display: 'block', padding: theme.spacing(2), }, }))(MuiAccordionDetails); @@ -224,7 +227,9 @@ function MessageHistoryDialog({ bugId, commentId, open, onClose }: Props) { > {getSummary(index, edit.date)} - {edit.message} + + + ))} From acfaf6b50f2ecb16add94874c0f8dfc401788d9b Mon Sep 17 00:00:00 2001 From: Sascha Date: Tue, 30 Mar 2021 19:05:27 +0200 Subject: [PATCH 5/5] Fix MessageHistoryDialog console error --- webui/src/pages/bug/MessageHistoryDialog.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/webui/src/pages/bug/MessageHistoryDialog.tsx b/webui/src/pages/bug/MessageHistoryDialog.tsx index da5d0ccff93d7810d7fe4ff806738cbaa6690aed..5879a373aa3e82a800580497b1d223819f001836 100644 --- a/webui/src/pages/bug/MessageHistoryDialog.tsx +++ b/webui/src/pages/bug/MessageHistoryDialog.tsx @@ -217,6 +217,7 @@ function MessageHistoryDialog({ bugId, commentId, open, onClose }: Props) { {history?.map((edit, index) => (