From 6a6985c39bb749533d4ce31d6087b3460cbf5f7d Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Sun, 29 Nov 2020 10:51:04 +0700 Subject: [PATCH 01/59] added react fast reload --- craco.config.js | 28 +++++++------ package.json | 6 +-- src/components/input/InputText/index.tsx | 8 ++-- src/containers/dialogs/EditorDialog/index.tsx | 40 +++++++++++-------- 4 files changed, 45 insertions(+), 37 deletions(-) diff --git a/craco.config.js b/craco.config.js index 06864f66..a7ca11e9 100644 --- a/craco.config.js +++ b/craco.config.js @@ -1,4 +1,5 @@ const CracoAlias = require('craco-alias'); +const fastRefreshCracoPlugin = require('craco-fast-refresh'); module.exports = { webpack: { @@ -14,27 +15,28 @@ module.exports = { mode: 'file', }, jest: { - setupTestFrameworkScriptFile: "/src/setupTests.js", + setupTestFrameworkScriptFile: '/src/setupTests.js', configure: { moduleNameMapper: { - "^~/(.*)$": "/src/$1", - "^.+\\.scss$": "identity-obj-proxy" + '^~/(.*)$': '/src/$1', + '^.+\\.scss$': 'identity-obj-proxy', }, - snapshotSerializers: ["enzyme-to-json/serializer"], - moduleFileExtensions: ["js", "json", "ts", "tsx", "jsx", "node"], + snapshotSerializers: ['enzyme-to-json/serializer'], + moduleFileExtensions: ['js', 'json', 'ts', 'tsx', 'jsx', 'node'], verbose: true, - roots: ["/src"], + roots: ['/src'], transform: { - "^.+\\.tsx?$": "ts-jest", - "^.+\\.ts?$": "babel-jest", - "^.+\\.js?$": "ts-jest", - "^.+\\.jsx?$": "babel-jest" + '^.+\\.tsx?$': 'ts-jest', + '^.+\\.ts?$': 'babel-jest', + '^.+\\.js?$': 'ts-jest', + '^.+\\.jsx?$': 'babel-jest', }, - preset: "ts-jest/presets/js-with-ts", - testEnvironment: "node" - } + preset: 'ts-jest/presets/js-with-ts', + testEnvironment: 'node', + }, }, plugins: [ + { plugin: fastRefreshCracoPlugin }, { plugin: CracoAlias, options: { diff --git a/package.json b/package.json index ed843287..579992cc 100644 --- a/package.json +++ b/package.json @@ -44,8 +44,7 @@ }, "eslintConfig": { "extends": [ - "react-app", - "react-app/jest" + "react-app" ] }, "browserslist": { @@ -61,12 +60,13 @@ ] }, "devDependencies": { + "@craco/craco": "5.8.0", "@types/classnames": "^2.2.7", "@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", + "craco-fast-refresh": "^1.0.2", "prettier": "^1.18.2" } } diff --git a/src/components/input/InputText/index.tsx b/src/components/input/InputText/index.tsx index 4c57faaa..f8d457b8 100644 --- a/src/components/input/InputText/index.tsx +++ b/src/components/input/InputText/index.tsx @@ -1,9 +1,9 @@ -import React, { FC, ChangeEvent, useCallback, useState, useEffect, LegacyRef } from 'react'; +import React, {ChangeEvent, FC, useCallback, useEffect, useState} from 'react'; import classNames from 'classnames'; import styles from '~/styles/common/inputs.module.scss'; -import { Icon } from '~/components/input/Icon'; -import { IInputTextProps } from '~/redux/types'; -import { LoaderCircle } from '~/components/input/LoaderCircle'; +import {Icon} from '~/components/input/Icon'; +import {IInputTextProps} from '~/redux/types'; +import {LoaderCircle} from '~/components/input/LoaderCircle'; const InputText: FC = ({ wrapperClassName, diff --git a/src/containers/dialogs/EditorDialog/index.tsx b/src/containers/dialogs/EditorDialog/index.tsx index 02e7933d..e2468f28 100644 --- a/src/containers/dialogs/EditorDialog/index.tsx +++ b/src/containers/dialogs/EditorDialog/index.tsx @@ -1,21 +1,21 @@ -import React, { createElement, FC, FormEvent, useCallback, useEffect, useState } from 'react'; -import { connect } from 'react-redux'; -import { IDialogProps } from '~/redux/modal/constants'; -import { useCloseOnEscape } from '~/utils/hooks'; -import { Group } from '~/components/containers/Group'; -import { InputText } from '~/components/input/InputText'; -import { Button } from '~/components/input/Button'; -import { Padder } from '~/components/containers/Padder'; +import React, {createElement, FC, FormEvent, useCallback, useEffect, useState} from 'react'; +import {connect} from 'react-redux'; +import {IDialogProps} from '~/redux/modal/constants'; +import {useCloseOnEscape} from '~/utils/hooks'; +import {Group} from '~/components/containers/Group'; +import {InputText} from '~/components/input/InputText'; +import {Button} from '~/components/input/Button'; +import {Padder} from '~/components/containers/Padder'; import styles from './styles.module.scss'; -import { selectNode } from '~/redux/node/selectors'; -import { EditorPanel } from '~/components/editors/EditorPanel'; +import {selectNode} from '~/redux/node/selectors'; +import {EditorPanel} from '~/components/editors/EditorPanel'; import * as NODE_ACTIONS from '~/redux/node/actions'; -import { selectUploads } from '~/redux/uploads/selectors'; -import { ERROR_LITERAL } from '~/constants/errors'; -import { EMPTY_NODE, NODE_EDITORS } from '~/redux/node/constants'; -import { BetterScrollDialog } from '../BetterScrollDialog'; -import { CoverBackdrop } from '~/components/containers/CoverBackdrop'; -import { IEditorComponentProps } from '~/redux/node/types'; +import {selectUploads} from '~/redux/uploads/selectors'; +import {ERROR_LITERAL} from '~/constants/errors'; +import {EMPTY_NODE, NODE_EDITORS} from '~/redux/node/constants'; +import {BetterScrollDialog} from '../BetterScrollDialog'; +import {CoverBackdrop} from '~/components/containers/CoverBackdrop'; +import {IEditorComponentProps} from '~/redux/node/types'; const mapStateToProps = state => { const { editor, errors } = selectNode(state); @@ -78,7 +78,13 @@ const EditorDialogUnconnected: FC = ({ - + ); }; diff --git a/src/components/comment/CommentFormFormatButtons/styles.module.scss b/src/components/comment/CommentFormFormatButtons/styles.module.scss index 55e5b2ee..738e46e6 100644 --- a/src/components/comment/CommentFormFormatButtons/styles.module.scss +++ b/src/components/comment/CommentFormFormatButtons/styles.module.scss @@ -4,5 +4,4 @@ display: flex; flex-wrap: wrap; height: 32px; - overflow: hidden; } diff --git a/src/components/input/Button/index.tsx b/src/components/input/Button/index.tsx index 7b9d8a8c..b480ef8d 100644 --- a/src/components/input/Button/index.tsx +++ b/src/components/input/Button/index.tsx @@ -1,8 +1,16 @@ import classnames from 'classnames'; -import React, { ButtonHTMLAttributes, DetailedHTMLProps, FC, createElement, memo } from 'react'; +import React, { + ButtonHTMLAttributes, + DetailedHTMLProps, + FC, + createElement, + memo, + useRef, +} from 'react'; import styles from './styles.module.scss'; import { Icon } from '~/components/input/Icon'; import { IIcon } from '~/redux/types'; +import { usePopper } from 'react-popper'; type IButtonProps = DetailedHTMLProps< ButtonHTMLAttributes, @@ -19,6 +27,7 @@ type IButtonProps = DetailedHTMLProps< is_loading?: boolean; stretchy?: boolean; iconOnly?: boolean; + label?: string; }; const Button: FC = memo( @@ -37,9 +46,24 @@ const Button: FC = memo( stretchy, disabled, iconOnly, + label, + ref, ...props - }) => - createElement( + }) => { + const tooltip = useRef(); + const pop = usePopper(tooltip?.current?.parentElement, tooltip.current, { + placement: 'top', + modifiers: [ + { + name: 'offset', + options: { + offset: [0, 5], + }, + }, + ], + }); + + return createElement( seamless || non_submitting ? 'div' : 'button', { className: classnames(styles.button, className, styles[size], styles[color], { @@ -58,8 +82,19 @@ const Button: FC = memo( iconLeft && , title ? {title} : children || null, iconRight && , + !!label && ( + + {label} + + ), ] - ) + ); + } ); export { Button }; diff --git a/src/components/input/Button/styles.module.scss b/src/components/input/Button/styles.module.scss index a2fd301e..c3ee1e0c 100644 --- a/src/components/input/Button/styles.module.scss +++ b/src/components/input/Button/styles.module.scss @@ -10,6 +10,7 @@ } .button { + position: relative; height: $input_height; border: none; box-sizing: border-box; @@ -235,3 +236,21 @@ width: 20px; height: 20px; } + +.tooltip { + padding: 5px 10px; + background-color: darken($content_bg, 4%); + z-index: 2; + border-radius: $input_radius; + text-transform: none; + opacity: 0; + pointer-events: none; + touch-action: none; + transition: opacity 0.1s; + border: 1px solid transparentize(white, 0.9); + + .button:hover & { + opacity: 1; + font: $font_14_semibold; + } +} From 2d034f2fbb937cb84187f83f1bd9c12c501245f3 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Fri, 26 Feb 2021 15:53:43 +0700 Subject: [PATCH 28/59] fixed key warnings --- src/components/input/Button/index.tsx | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/components/input/Button/index.tsx b/src/components/input/Button/index.tsx index b480ef8d..d34c4b0a 100644 --- a/src/components/input/Button/index.tsx +++ b/src/components/input/Button/index.tsx @@ -83,12 +83,7 @@ const Button: FC = memo( title ? {title} : children || null, iconRight && , !!label && ( - + {label} ), From d42a98957deae723978c51102a4c344be3bc8d60 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Fri, 26 Feb 2021 15:58:52 +0700 Subject: [PATCH 29/59] hiding buttons on mobile --- src/components/comment/CommentForm/styles.module.scss | 1 + .../comment/CommentFormFormatButtons/styles.module.scss | 4 ++++ 2 files changed, 5 insertions(+) diff --git a/src/components/comment/CommentForm/styles.module.scss b/src/components/comment/CommentForm/styles.module.scss index dd978bde..c2a58a5c 100644 --- a/src/components/comment/CommentForm/styles.module.scss +++ b/src/components/comment/CommentForm/styles.module.scss @@ -26,6 +26,7 @@ background: transparentize(black, 0.8); padding: $gap / 2; border-radius: 0 0 $radius $radius; + flex-wrap: wrap; } .uploads { diff --git a/src/components/comment/CommentFormFormatButtons/styles.module.scss b/src/components/comment/CommentFormFormatButtons/styles.module.scss index 738e46e6..5360b104 100644 --- a/src/components/comment/CommentFormFormatButtons/styles.module.scss +++ b/src/components/comment/CommentFormFormatButtons/styles.module.scss @@ -4,4 +4,8 @@ display: flex; flex-wrap: wrap; height: 32px; + + @media(max-width: 480px) { + display: none; + } } From 8ae2dc02f0d84e9f75b3b50e51808aab6abd45d0 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Fri, 26 Feb 2021 16:47:38 +0700 Subject: [PATCH 30/59] #34 added LocalCommentForm --- package.json | 5 +- src/components/comment/CommentForm/index.tsx | 99 ++++++++++--------- .../comment/LocalCommentForm/index.tsx | 25 +++++ .../LocalCommentFormTextarea/index.tsx | 36 +++++++ src/utils/hooks/useCommentFormFormik.ts | 35 +++++++ yarn.lock | 75 +++++++++++++- 6 files changed, 226 insertions(+), 49 deletions(-) create mode 100644 src/components/comment/LocalCommentForm/index.tsx create mode 100644 src/components/comment/LocalCommentFormTextarea/index.tsx create mode 100644 src/utils/hooks/useCommentFormFormik.ts diff --git a/package.json b/package.json index 7d948d3e..9faa2025 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", + "formik": "^2.2.6", "insane": "^2.6.2", "marked": "^2.0.0", "node-sass": "4.14.1", @@ -36,7 +37,8 @@ "throttle-debounce": "^2.1.0", "typescript": "^4.0.5", "uuid4": "^1.1.4", - "web-vitals": "^0.2.4" + "web-vitals": "^0.2.4", + "yup": "^0.32.9" }, "scripts": { "start": "craco start", @@ -68,6 +70,7 @@ "@types/node": "^11.13.22", "@types/ramda": "^0.26.33", "@types/react-redux": "^7.1.11", + "@types/yup": "^0.29.11", "craco-alias": "^2.1.1", "craco-fast-refresh": "^1.0.2", "prettier": "^1.18.2" diff --git a/src/components/comment/CommentForm/index.tsx b/src/components/comment/CommentForm/index.tsx index 22613f08..559b7cea 100644 --- a/src/components/comment/CommentForm/index.tsx +++ b/src/components/comment/CommentForm/index.tsx @@ -30,6 +30,7 @@ import { CommentFormAttaches } from '~/components/comment/CommentFormAttaches'; import { CommentFormAttachButtons } from '~/components/comment/CommentFormAttachButtons'; import { CommentFormDropzone } from '~/components/comment/CommentFormDropzone'; import { CommentFormFormatButtons } from '~/components/comment/CommentFormFormatButtons'; +import { LocalCommentForm } from '~/components/comment/LocalCommentForm'; const mapStateToProps = (state: IState) => ({ node: selectNode(state), @@ -180,61 +181,65 @@ const CommentFormUnconnected: FC = memo( ); return ( - -
-
-