From 066623758679e570507702679a385c55d7c47366 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 14:18:59 +0700 Subject: [PATCH 1/9] added markdown formatter --- .gitignore | 1 + package.json | 4 +- .../comment/CommentTextBlock/index.tsx | 2 +- src/utils/dom.ts | 65 +++++--------- src/utils/formatText.ts | 71 +++++++++++++++ src/utils/reducer.ts | 6 -- yarn.lock | 88 +++---------------- 7 files changed, 111 insertions(+), 126 deletions(-) create mode 100644 src/utils/formatText.ts diff --git a/.gitignore b/.gitignore index a0d7b1b9..1e572c99 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ /npm-debug.log /.idea /dist +/.env diff --git a/package.json b/package.json index ed843287..5865ae95 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,7 @@ "connected-react-router": "^6.5.2", "date-fns": "^2.4.1", "flexbin": "^0.2.0", + "marked": "^2.0.0", "node-sass": "4.14.1", "photoswipe": "^4.1.3", "raleway-cyrillic": "^4.0.2", @@ -61,11 +62,12 @@ ] }, "devDependencies": { + "@craco/craco": "5.8.0", "@types/classnames": "^2.2.7", + "@types/marked": "^1.2.2", "@types/node": "^11.13.22", "@types/ramda": "^0.26.33", "@types/react-redux": "^7.1.11", - "@craco/craco": "5.8.0", "craco-alias": "^2.1.1", "prettier": "^1.18.2" } diff --git a/src/components/comment/CommentTextBlock/index.tsx b/src/components/comment/CommentTextBlock/index.tsx index 930eb96a..2dc3f0fd 100644 --- a/src/components/comment/CommentTextBlock/index.tsx +++ b/src/components/comment/CommentTextBlock/index.tsx @@ -9,7 +9,7 @@ const CommentTextBlock: FC = ({ block }) => {
${block.content}

`, + __html: block.content, }} /> ); diff --git a/src/utils/dom.ts b/src/utils/dom.ts index 383942e2..43b981ea 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -8,6 +8,17 @@ import Axios from 'axios'; import { PRESETS } from '~/constants/urls'; import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/constants/comment'; import format from 'date-fns/format'; +import { pipe } from 'ramda'; +import { + formatDash, + formatExclamations, + formatMarkdown, + formatTextClickableUsernames, + formatTextComments, + formatTextSanitizeTags, + formatTextSanitizeYoutube, + formatTextTodos, +} from '~/utils/formatText'; export const getStyle = (oElm: any, strCssRule: string) => { if (document.defaultView && document.defaultView.getComputedStyle) { @@ -82,50 +93,18 @@ export const getURL = (file: Partial, size?: typeof PRESETS[keyof typeof return file?.url ? getURLFromString(file.url, size) : null; }; -export const formatText = (text: string): string => - !text - ? '' - : text - .replace( - /(https?:\/\/(www\.)?(youtube\.com|youtu\.be)\/(watch)?(\?v=)?[\w\-\&\=]+)/gim, - '\n$1\n' - ) - .replace(/\n{1,}/gim, '\n') - .replace(//g, '>') - .replace( - /~([\wа-яА-Я-]+)/giu, - '~$1' - ) - .replace(/:\/\//gim, ':|--|') - .replace(/(\/\/[^\n]+)/gim, '$1') - .replace(/\/\/\s*(todo|туду):?\s*([^\n]+)/gim, '// $1 $2') - .replace( - /\/\/\s*(done|сделано|сделал|готово|fixed|пофикшено|фиксед):?\s*([^\n]+)/gim, - '// $1 $2' - ) - .replace(/(\*\*[\s\S]*?\*\*)/gim, '$1') - .replace(/(\_\_[\s\S]*?\_\_)/gim, '$1') - .replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '$1') - .replace(/(\/\*[\s\S]*?\*\/)/gim, '$1') - .replace(/([=|-]{5,})/gim, '
') - .replace(/:\|--\|/gim, '://') - .replace( - /(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/gi, - '$1' - ) - .replace(' -- ', ' — ') - .split('\n') - .filter(el => el.trim().length) - .join('\n'); +export const formatText = pipe( + formatTextSanitizeYoutube, + formatTextSanitizeTags, + formatTextClickableUsernames, + formatTextComments, + formatTextTodos, + formatExclamations, + formatDash, + formatMarkdown +); -export const formatTextParagraphs = (text: string): string => - (text && - formatText(text) - .split('\n') - .map(str => `

${str}

`) - .join('\n')) || - null; +export const formatTextParagraphs = (text: string): string => (text && formatText(text)) || null; export const findBlockType = (line: string): ValueOf => { const match = Object.values(COMMENT_BLOCK_DETECTORS).find(detector => line.match(detector.test)); diff --git a/src/utils/formatText.ts b/src/utils/formatText.ts new file mode 100644 index 00000000..d8f4752b --- /dev/null +++ b/src/utils/formatText.ts @@ -0,0 +1,71 @@ +import marked from 'marked'; + +/** + * Cleans youtube urls + */ +export const formatTextSanitizeYoutube = (text: string): string => + text.replace( + /(https?:\/\/(www\.)?(youtube\.com|youtu\.be)\/(watch)?(\?v=)?[\w\-\&\=]+)/gim, + '\n$1\n' + ); + +/** + * Removes HTML tags + */ +export const formatTextSanitizeTags = (text: string): string => + text.replace(//g, '>'); + +/** + * Returns clickable usernames + */ +export const formatTextClickableUsernames = (text: string): string => + text.replace( + /~([\wа-яА-Я-]+)/giu, + '~$1' + ); + +/** + * Makes gray comments + */ +export const formatTextComments = (text: string): string => + text + .replace(/:\/\//gim, ':|--|') + .replace(/(\/\/[^\n]+)/gim, '$1') + .replace(/(\/\*[\s\S]*?\*\/)/gim, '$1') + .replace(/:\|--\|/gim, '://'); + +/** + * Highlights todos + */ +export const formatTextTodos = (text: string): string => + text + .replace(/\/\/\s*(todo|туду):?\s*([^\n]+)/gim, '// $1 $2') + .replace( + /\/\/\s*(done|сделано|сделал|готово|fixed|пофикшено|фиксед):?\s*([^\n]+)/gim, + '// $1 $2' + ); + +/** + * Formats !!exclamation messages with green color + */ +export const formatExclamations = (text: string): string => + text.replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '$1'); + +/** + * Formats links + */ +export const formatLinks = (text: string): string => + text.replace( + /(\b(https?|ftp|file):\/\/([-A-Z0-9+&@#%?=~_|!:,.;]*)([-A-Z0-9+&@#%?\/=~_|!:,.;]*)[-A-Z0-9+&@#\/%=~_|])/gi, + '$1' + ); + +/** + * Replaces -- with dash + */ +export const formatDash = (text: string): string => text.replace(' -- ', ' — '); + +/** + * Formats with markdown + */ +export const formatMarkdown = (text: string): string => marked(text); diff --git a/src/utils/reducer.ts b/src/utils/reducer.ts index 7af01e2d..7348d0aa 100644 --- a/src/utils/reducer.ts +++ b/src/utils/reducer.ts @@ -5,11 +5,5 @@ type Handlers> = { readonly [Type in Types]: (state: State, action: Actions) => State; }; -// export const createReducer = >( -// initialState: State, -// handlers: Handlers, -// ) => (state = initialState, action: Actions) => -// handlers.hasOwnProperty(action.type) ? handlers[action.type as Types](state, action) : state; - export const createReducer = (initialState, handlers) => (state = initialState, action) => handlers.hasOwnProperty(action.type) ? handlers[action.type](state, action) : state; diff --git a/yarn.lock b/yarn.lock index 8f8144de..d8306791 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1102,7 +1102,7 @@ dependencies: regenerator-runtime "^0.13.4" -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.5", "@babel/runtime@^7.2.0", "@babel/runtime@^7.3.1", "@babel/runtime@^7.3.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.12.5" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.12.5.tgz#410e7e487441e1b360c29be715d870d9b985882e" integrity sha512-plcc+hbExy3McchJCEQG3knOsuh3HH+Prx1P6cLIkET/0dLuQDEnrT+s27Axgc9bqfsmNUNHfscgMUdBpC9xfg== @@ -1672,6 +1672,11 @@ resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0" integrity sha512-3c+yGKvVP5Y9TYBEibGNR+kLtijnj7mYrXRg+WpFb2X9xm04g/DXYkfg4hmzJQosc9snFNUPkbYIhu+KAm6jJw== +"@types/marked@^1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@types/marked/-/marked-1.2.2.tgz#1f858a0e690247ecf3b2eef576f98f86e8d960d4" + integrity sha512-wLfw1hnuuDYrFz97IzJja0pdVsC0oedtS4QsKH1/inyW9qkLQbXgMUqEQT0MVtUBx3twjWeInUfjQbhBVLECXw== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" @@ -1719,13 +1724,6 @@ hoist-non-react-statics "^3.3.0" redux "^4.0.0" -"@types/react-transition-group@^4.4.0": - version "4.4.0" - resolved "https://registry.yarnpkg.com/@types/react-transition-group/-/react-transition-group-4.4.0.tgz#882839db465df1320e4753e6e9f70ca7e9b4d46d" - integrity sha512-/QfLHGpu+2fQOqQaXh8MG9q03bFENooTb/it4jr5kKaZlDQfWvjqWZg48AwzPVMBHlRuTRAY7hRHCEOXz5kV6w== - dependencies: - "@types/react" "*" - "@types/react@*": version "16.9.56" resolved "https://registry.yarnpkg.com/@types/react/-/react-16.9.56.tgz#ea25847b53c5bec064933095fc366b1462e2adf0" @@ -2015,11 +2013,6 @@ acorn@^7.1.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== -add-px-to-style@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/add-px-to-style/-/add-px-to-style-1.0.0.tgz#d0c135441fa8014a8137904531096f67f28f263a" - integrity sha1-0ME1RB+oAUqBN5BFMQlvZ/KPJjo= - address@1.1.2, address@^1.0.1: version "1.1.2" resolved "https://registry.yarnpkg.com/address/-/address-1.1.2.tgz#bf1116c9c758c51b7a933d296b72c221ed9428b6" @@ -4044,23 +4037,6 @@ dom-converter@^0.2: dependencies: utila "~0.4" -dom-css@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/dom-css/-/dom-css-2.1.0.tgz#fdbc2d5a015d0a3e1872e11472bbd0e7b9e6a202" - integrity sha1-/bwtWgFdCj4YcuEUcrvQ57nmogI= - dependencies: - add-px-to-style "1.0.0" - prefix-style "2.0.1" - to-camel-case "1.0.0" - -dom-helpers@^5.0.1: - version "5.2.0" - resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.2.0.tgz#57fd054c5f8f34c52a3eeffdb7e7e93cd357d95b" - integrity sha512-Ru5o9+V8CpunKnz5LGgWXkmrH/20cGKwcHwS4m73zIvs54CN9epEmT/HLqFJW3kXpakAFkEdzgy1hzlJe3E4OQ== - dependencies: - "@babel/runtime" "^7.8.7" - csstype "^3.0.2" - dom-serializer@0: version "0.2.2" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51" @@ -7131,6 +7107,11 @@ map-visit@^1.0.0: dependencies: object-visit "^1.0.0" +marked@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/marked/-/marked-2.0.0.tgz#9662bbcb77ebbded0662a7be66ff929a8611cee5" + integrity sha512-NqRSh2+LlN2NInpqTQnS614Y/3NkVMFFU6sJlRFEpxJ/LHuK/qJECH7/fXZjk4VZstPW/Pevjil/VtSONsLc7Q== + md5.js@^1.3.4: version "1.3.5" resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.5.tgz#b5d07b8e3216e3e27cd728d72f70d1e6a342005f" @@ -8929,11 +8910,6 @@ postcss@^7, postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.17, po source-map "^0.6.1" supports-color "^6.1.0" -prefix-style@2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/prefix-style/-/prefix-style-2.0.1.tgz#66bba9a870cfda308a5dc20e85e9120932c95a06" - integrity sha1-ZrupqHDP2jCKXcIOhekSCTLJWgY= - prelude-ls@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" @@ -9017,7 +8993,7 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" -prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -9139,7 +9115,7 @@ querystringify@^2.1.1: resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-2.2.0.tgz#3345941b4153cb9d082d8eee4cda2016a9aef7f6" integrity sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ== -raf@^3.1.0, raf@^3.4.1: +raf@^3.4.1: version "3.4.1" resolved "https://registry.yarnpkg.com/raf/-/raf-3.4.1.tgz#0742e99a4a6552f445d73e3ee0328af0ff1ede39" integrity sha512-Sq4CW4QhwOHE8ucn6J34MqtZCeWFP2aQSmrlroYgqAV1PjStIhJXxYuTgUIfkEk7zTLjmIjLmU5q+fbD1NnOJA== @@ -9375,16 +9351,6 @@ react-sortable-hoc@^1.11: invariant "^2.2.4" prop-types "^15.5.7" -react-transition-group@^4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" - integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== - dependencies: - "@babel/runtime" "^7.5.5" - dom-helpers "^5.0.1" - loose-envify "^1.4.0" - prop-types "^15.6.2" - react@^17.0.1: version "17.0.1" resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127" @@ -10877,23 +10843,11 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= -to-camel-case@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46" - integrity sha1-GlYFSy+daWKYzmamCJcyK29CPkY= - dependencies: - to-space-case "^1.0.0" - to-fast-properties@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e" integrity sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4= -to-no-case@^1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/to-no-case/-/to-no-case-1.0.2.tgz#c722907164ef6b178132c8e69930212d1b4aa16a" - integrity sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo= - to-object-path@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" @@ -10926,13 +10880,6 @@ to-regex@^3.0.1, to-regex@^3.0.2: regex-not "^1.0.2" safe-regex "^1.1.0" -to-space-case@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/to-space-case/-/to-space-case-1.0.0.tgz#b052daafb1b2b29dc770cea0163e5ec0ebc9fc17" - integrity sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc= - dependencies: - to-no-case "^1.0.0" - toidentifier@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/toidentifier/-/toidentifier-1.0.0.tgz#7e1be3470f1e77948bc43d94a3c8f4d7752ba553" @@ -10992,15 +10939,6 @@ tsutils@^3.17.1: dependencies: tslib "^1.8.1" -tt-react-custom-scrollbars@latest: - version "4.2.1-tt2" - resolved "https://registry.yarnpkg.com/tt-react-custom-scrollbars/-/tt-react-custom-scrollbars-4.2.1-tt2.tgz#574b2b38e5f1462c001916e910fc410a302d72de" - integrity sha512-gMEVHHOClNJXM1d/p4PrLdXtCU2JzWRtcZdzUkXgck8sgzkxwFwSDNc3scnTk21sSKG2GSgf7G54sboXwsMVlg== - dependencies: - dom-css "^2.0.0" - prop-types "^15.5.10" - raf "^3.1.0" - tty-browserify@0.0.0: version "0.0.0" resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" From d78660692423ba00e2fc43aa1023fba7719b8730 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 14:36:15 +0700 Subject: [PATCH 2/9] fixed comment text splitting --- .env | 5 ----- src/utils/dom.ts | 12 +++++++----- 2 files changed, 7 insertions(+), 10 deletions(-) delete mode 100644 .env diff --git a/.env b/.env deleted file mode 100644 index bfd29ef4..00000000 --- a/.env +++ /dev/null @@ -1,5 +0,0 @@ -#API_HOST = http://localhost:7777/ -#REMOTE_CURRENT = http://localhost:7777/static/ -REACT_APP_API_HOST = https://pig.staging.vault48.org/ -REACT_APP_REMOTE_CURRENT = https://pig.staging.vault48.org/static/ -EXPOSE = 4000 diff --git a/src/utils/dom.ts b/src/utils/dom.ts index 43b981ea..700015c3 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -94,8 +94,8 @@ export const getURL = (file: Partial, size?: typeof PRESETS[keyof typeof }; export const formatText = pipe( - formatTextSanitizeYoutube, formatTextSanitizeTags, + formatTextSanitizeYoutube, formatTextClickableUsernames, formatTextComments, formatTextTodos, @@ -112,10 +112,12 @@ export const findBlockType = (line: string): ValueOf }; export const splitCommentByBlocks = (text: string): ICommentBlock[] => - text.split('\n').map(line => ({ - type: findBlockType(line), - content: line, - })); + text + .split(/(https?:\/\/(?:www\.)(?:youtube\.com|youtu\.be)\/(?:watch)(?:\?v=)[\w\-\&\=]+)/) + .map(line => ({ + type: findBlockType(line), + content: line, + })); export const formatCommentText = (author: string, text: string): ICommentBlock[] => text ? splitCommentByBlocks(formatText(text)) : null; From 5dbf4245bf2ca87c59da5865e68c78f592334e4e Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 15:16:24 +0700 Subject: [PATCH 3/9] added some markdown stylings --- .../comment/CommentTextBlock/index.tsx | 4 +- src/styles/common/markdown.module.scss | 60 +++++++++++++++++++ src/utils/dom.ts | 14 +++-- src/utils/splitText.ts | 11 ++++ 4 files changed, 82 insertions(+), 7 deletions(-) create mode 100644 src/styles/common/markdown.module.scss create mode 100644 src/utils/splitText.ts diff --git a/src/components/comment/CommentTextBlock/index.tsx b/src/components/comment/CommentTextBlock/index.tsx index 2dc3f0fd..4e8bacc5 100644 --- a/src/components/comment/CommentTextBlock/index.tsx +++ b/src/components/comment/CommentTextBlock/index.tsx @@ -1,13 +1,15 @@ import React, { FC } from 'react'; import { ICommentBlockProps } from '~/constants/comment'; import styles from './styles.module.scss'; +import classNames from 'classnames'; +import markdown from '~/styles/common/markdown.module.scss'; interface IProps extends ICommentBlockProps {} const CommentTextBlock: FC = ({ block }) => { return (
{ if (document.defaultView && document.defaultView.getComputedStyle) { @@ -112,12 +113,13 @@ export const findBlockType = (line: string): ValueOf }; export const splitCommentByBlocks = (text: string): ICommentBlock[] => - text - .split(/(https?:\/\/(?:www\.)(?:youtube\.com|youtu\.be)\/(?:watch)(?:\?v=)[\w\-\&\=]+)/) - .map(line => ({ - type: findBlockType(line), - content: line, - })); + pipe( + splitTextByYoutube, + splitTextOmitEmpty + )([text]).map(line => ({ + type: findBlockType(line), + content: line, + })); export const formatCommentText = (author: string, text: string): ICommentBlock[] => text ? splitCommentByBlocks(formatText(text)) : null; diff --git a/src/utils/splitText.ts b/src/utils/splitText.ts new file mode 100644 index 00000000..5cd7ac8a --- /dev/null +++ b/src/utils/splitText.ts @@ -0,0 +1,11 @@ +import { flatten } from 'ramda'; + +export const splitTextByYoutube = (strings: string[]): string[] => + flatten( + strings.map(str => + str.split(/(https?:\/\/(?:www\.)(?:youtube\.com|youtu\.be)\/(?:watch)(?:\?v=)[\w\-\&\=]+)/) + ) + ); + +export const splitTextOmitEmpty = (strings: string[]): string[] => + strings.filter(el => !!el.trim()); From 1fc04e62a610cc862b7fc065a9d84a6f1efe8f9f Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 15:28:11 +0700 Subject: [PATCH 4/9] fixed comment block separation --- src/components/comment/CommentContent/index.tsx | 10 +++++++++- src/utils/dom.ts | 8 ++++---- src/utils/formatText.ts | 6 +++--- 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/src/components/comment/CommentContent/index.tsx b/src/components/comment/CommentContent/index.tsx index 08e9c49a..87471fb3 100644 --- a/src/components/comment/CommentContent/index.tsx +++ b/src/components/comment/CommentContent/index.tsx @@ -49,6 +49,14 @@ const CommentContent: FC = memo( [can_edit, comment, onEditClick, onLockClick] ); + const blocks = useMemo( + () => + !!comment.text.trim() + ? formatCommentText(path(['user', 'username'], comment), comment.text) + : [], + [comment] + ); + return (
{comment.text && ( @@ -56,7 +64,7 @@ const CommentContent: FC = memo( {menu} - {formatCommentText(path(['user', 'username'], comment), comment.text).map( + {blocks.map( (block, key) => COMMENT_BLOCK_RENDERERS[block.type] && createElement(COMMENT_BLOCK_RENDERERS[block.type], { block, key }) diff --git a/src/utils/dom.ts b/src/utils/dom.ts index 43107208..bc276334 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -10,9 +10,9 @@ import { COMMENT_BLOCK_DETECTORS, COMMENT_BLOCK_TYPES, ICommentBlock } from '~/c import format from 'date-fns/format'; import { pipe } from 'ramda'; import { - formatDash, + formatTextDash, formatExclamations, - formatMarkdown, + formatTextMarkdown, formatTextClickableUsernames, formatTextComments, formatTextSanitizeTags, @@ -101,8 +101,8 @@ export const formatText = pipe( formatTextComments, formatTextTodos, formatExclamations, - formatDash, - formatMarkdown + formatTextDash, + formatTextMarkdown ); export const formatTextParagraphs = (text: string): string => (text && formatText(text)) || null; diff --git a/src/utils/formatText.ts b/src/utils/formatText.ts index d8f4752b..ff8e79d4 100644 --- a/src/utils/formatText.ts +++ b/src/utils/formatText.ts @@ -49,7 +49,7 @@ export const formatTextTodos = (text: string): string => * Formats !!exclamation messages with green color */ export const formatExclamations = (text: string): string => - text.replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '$1'); + text.replace(/(\!\![\s\S]*?(\!\!|\n|$))/gim, '$1$2'); /** * Formats links @@ -63,9 +63,9 @@ export const formatLinks = (text: string): string => /** * Replaces -- with dash */ -export const formatDash = (text: string): string => text.replace(' -- ', ' — '); +export const formatTextDash = (text: string): string => text.replace(' -- ', ' — '); /** * Formats with markdown */ -export const formatMarkdown = (text: string): string => marked(text); +export const formatTextMarkdown = (text: string): string => marked(text); From c383356a4ca30bc4ff8a998217f404f35b2e0f73 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 15:28:31 +0700 Subject: [PATCH 5/9] fixed useMemo for blocks --- src/components/comment/CommentContent/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/comment/CommentContent/index.tsx b/src/components/comment/CommentContent/index.tsx index 87471fb3..a1a48d40 100644 --- a/src/components/comment/CommentContent/index.tsx +++ b/src/components/comment/CommentContent/index.tsx @@ -54,7 +54,7 @@ const CommentContent: FC = memo( !!comment.text.trim() ? formatCommentText(path(['user', 'username'], comment), comment.text) : [], - [comment] + [comment.text] ); return ( From 0c7ed6de99198e983e09414d9fd186841ef8e967 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 15:54:14 +0700 Subject: [PATCH 6/9] fixed image and code appearance --- src/components/comment/CommentTextBlock/index.tsx | 3 ++- src/styles/common/markdown.module.scss | 10 +++++++++- src/utils/dom.ts | 2 +- src/utils/splitText.ts | 4 ++-- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/components/comment/CommentTextBlock/index.tsx b/src/components/comment/CommentTextBlock/index.tsx index 4e8bacc5..09a7e286 100644 --- a/src/components/comment/CommentTextBlock/index.tsx +++ b/src/components/comment/CommentTextBlock/index.tsx @@ -3,6 +3,7 @@ import { ICommentBlockProps } from '~/constants/comment'; import styles from './styles.module.scss'; import classNames from 'classnames'; import markdown from '~/styles/common/markdown.module.scss'; +import { formatText } from '~/utils/dom'; interface IProps extends ICommentBlockProps {} @@ -11,7 +12,7 @@ const CommentTextBlock: FC = ({ block }) => {
); diff --git a/src/styles/common/markdown.module.scss b/src/styles/common/markdown.module.scss index 4ef7b010..e11ba114 100644 --- a/src/styles/common/markdown.module.scss +++ b/src/styles/common/markdown.module.scss @@ -9,8 +9,16 @@ } font-family: monospace; font-size: 13px; - padding: $gap; border-radius: $radius; + width: 100%; + overflow: auto; + padding: $gap; + box-sizing: border-box; + } + + img { + max-width: 100%; + margin-bottom: $gap; } p { diff --git a/src/utils/dom.ts b/src/utils/dom.ts index bc276334..ccbffb75 100644 --- a/src/utils/dom.ts +++ b/src/utils/dom.ts @@ -122,7 +122,7 @@ export const splitCommentByBlocks = (text: string): ICommentBlock[] => })); export const formatCommentText = (author: string, text: string): ICommentBlock[] => - text ? splitCommentByBlocks(formatText(text)) : null; + text ? splitCommentByBlocks(text) : null; export const formatCellText = (text: string): string => formatTextParagraphs(text); diff --git a/src/utils/splitText.ts b/src/utils/splitText.ts index 5cd7ac8a..32366574 100644 --- a/src/utils/splitText.ts +++ b/src/utils/splitText.ts @@ -1,4 +1,4 @@ -import { flatten } from 'ramda'; +import { flatten, isEmpty } from 'ramda'; export const splitTextByYoutube = (strings: string[]): string[] => flatten( @@ -8,4 +8,4 @@ export const splitTextByYoutube = (strings: string[]): string[] => ); export const splitTextOmitEmpty = (strings: string[]): string[] => - strings.filter(el => !!el.trim()); + strings.map(el => el.trim()).filter(el => !isEmpty(el)); From 616398c4fc0d0ca34d9f2f7b42fc311648b741ee Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 16:12:18 +0700 Subject: [PATCH 7/9] added italic text --- src/styles/common/markdown.module.scss | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/styles/common/markdown.module.scss b/src/styles/common/markdown.module.scss index e11ba114..024ab1e4 100644 --- a/src/styles/common/markdown.module.scss +++ b/src/styles/common/markdown.module.scss @@ -5,7 +5,7 @@ background-color: darken($comment_bg, 2%); border: { left: 4px solid $red; - right: 4px solid $red; + right: 4px solid $red; } font-family: monospace; font-size: 13px; @@ -61,6 +61,15 @@ } } + strong { + font-weight: bold; + color: white; + } + + em { + font-style: italic; + } + :global(.grey) { color: #555555; white-space: pre-line; From c98ac8b5977cac5422680989223625a4a3e79ec1 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 16:40:37 +0700 Subject: [PATCH 8/9] added markdown to text node --- .../comment/CommentTextBlock/index.tsx | 6 ++-- src/components/node/NodeTextBlock/index.tsx | 29 ++++++++++++------- src/styles/common/markdown.module.scss | 1 + 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/components/comment/CommentTextBlock/index.tsx b/src/components/comment/CommentTextBlock/index.tsx index 09a7e286..674c7269 100644 --- a/src/components/comment/CommentTextBlock/index.tsx +++ b/src/components/comment/CommentTextBlock/index.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; import { ICommentBlockProps } from '~/constants/comment'; import styles from './styles.module.scss'; import classNames from 'classnames'; @@ -8,11 +8,13 @@ import { formatText } from '~/utils/dom'; interface IProps extends ICommentBlockProps {} const CommentTextBlock: FC = ({ block }) => { + const content = useMemo(() => formatText(block.content), [block.content]); + return (
); diff --git a/src/components/node/NodeTextBlock/index.tsx b/src/components/node/NodeTextBlock/index.tsx index 25f1c2b2..042b1bd7 100644 --- a/src/components/node/NodeTextBlock/index.tsx +++ b/src/components/node/NodeTextBlock/index.tsx @@ -1,19 +1,26 @@ -import React, { FC } from 'react'; -import { INode } from '~/redux/types'; +import React, { FC, useMemo } from 'react'; import { path } from 'ramda'; import { formatTextParagraphs } from '~/utils/dom'; -import styles from './styles.module.scss'; import { INodeComponentProps } from '~/redux/node/constants'; +import classNames from 'classnames'; +import styles from './styles.module.scss'; +import markdown from '~/styles/common/markdown.module.scss'; interface IProps extends INodeComponentProps {} -const NodeTextBlock: FC = ({ node }) => ( -
-); +const NodeTextBlock: FC = ({ node }) => { + const content = useMemo(() => formatTextParagraphs(path(['blocks', 0, 'text'], node)), [ + node.blocks, + ]); + + return ( +
+ ); +}; export { NodeTextBlock }; diff --git a/src/styles/common/markdown.module.scss b/src/styles/common/markdown.module.scss index 024ab1e4..15b3d015 100644 --- a/src/styles/common/markdown.module.scss +++ b/src/styles/common/markdown.module.scss @@ -29,6 +29,7 @@ color: white; font-weight: 800; line-height: 1.2em; + margin-bottom: $gap; } h1 { From 52d5b57245c802d565365009eba0c17cc87e5afc Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Feb 2021 16:49:54 +0700 Subject: [PATCH 9/9] added markdown to flow cells --- src/components/flow/Cell/index.tsx | 13 +++++++++++-- src/components/flow/Cell/styles.module.scss | 1 + src/styles/common/markdown.module.scss | 13 +++++++------ 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/components/flow/Cell/index.tsx b/src/components/flow/Cell/index.tsx index 75523ffa..688d5249 100644 --- a/src/components/flow/Cell/index.tsx +++ b/src/components/flow/Cell/index.tsx @@ -4,6 +4,7 @@ import { formatCellText, getURL } from '~/utils/dom'; import classNames from 'classnames'; import styles from './styles.module.scss'; +import markdown from '~/styles/common/markdown.module.scss'; import { Icon } from '~/components/input/Icon'; import { flowSetCellView } from '~/redux/flow/actions'; import { PRESETS } from '~/constants/urls'; @@ -119,6 +120,8 @@ const Cell: FC = ({ } }, [title]); + const cellText = useMemo(() => formatCellText(text), [text]); + return (
{is_visible && ( @@ -150,7 +153,10 @@ const Cell: FC = ({
{title &&
{title}
} - +
)} @@ -158,7 +164,10 @@ const Cell: FC = ({
{title &&
{title}
} - +
)}
diff --git a/src/components/flow/Cell/styles.module.scss b/src/components/flow/Cell/styles.module.scss index ed6d791b..8a628cc8 100644 --- a/src/components/flow/Cell/styles.module.scss +++ b/src/components/flow/Cell/styles.module.scss @@ -327,6 +327,7 @@ overflow: hidden; box-sizing: border-box; position: relative; + font-size: 6px; &::after { content: ' '; diff --git a/src/styles/common/markdown.module.scss b/src/styles/common/markdown.module.scss index 15b3d015..a4d1cca2 100644 --- a/src/styles/common/markdown.module.scss +++ b/src/styles/common/markdown.module.scss @@ -8,28 +8,29 @@ right: 4px solid $red; } font-family: monospace; - font-size: 13px; + font-size: 0.9em; border-radius: $radius; width: 100%; overflow: auto; padding: $gap; box-sizing: border-box; + margin-bottom: 0.3em; } img { max-width: 100%; - margin-bottom: $gap; + margin-bottom: 0.3em; } p { - margin-bottom: $gap; + margin-bottom: 0.3em; } h5, h4, h3, h2, h1 { color: white; font-weight: 800; line-height: 1.2em; - margin-bottom: $gap; + margin-bottom: 0.3em; } h1 { @@ -55,10 +56,10 @@ ul { list-style: disc; padding-left: 20px; - margin-bottom: $gap; + margin-bottom: 0.3em; li { - margin: 5px 0; + margin: 0.1em 0; } }