From 031de64acc59953f38e93e88d3b8d0f3c59cfe78 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 11:09:38 +0700 Subject: [PATCH 01/20] #23 using custom blocks at lab nodes --- src/components/containers/Markdown/index.tsx | 11 ++ src/components/lab/LabBottomPanel/index.tsx | 17 +++ .../lab/LabBottomPanel/styles.module.scss | 10 ++ src/components/lab/LabImage/index.tsx | 102 ++++++++++++++++++ .../lab/LabImage/styles.module.scss | 70 ++++++++++++ src/components/lab/LabNode/index.tsx | 19 +--- src/components/lab/LabNode/styles.module.scss | 10 +- src/components/lab/LabNodeTitle/index.tsx | 23 ++++ .../LabNodeTitle}/styles.module.scss | 2 +- src/components/lab/LabPad/index.tsx | 8 ++ src/components/lab/LabPad/styles.module.scss | 5 + src/components/lab/LabText/index.tsx | 28 +++++ src/components/lab/LabText/styles.module.scss | 21 ++++ src/components/node/NodePanelLab/index.tsx | 19 ---- src/containers/lab/LabGrid/styles.module.scss | 2 +- src/redux/node/constants.ts | 12 +++ src/utils/hooks/node/useNodeBlocks.ts | 14 ++- 17 files changed, 330 insertions(+), 43 deletions(-) create mode 100644 src/components/containers/Markdown/index.tsx create mode 100644 src/components/lab/LabBottomPanel/index.tsx create mode 100644 src/components/lab/LabBottomPanel/styles.module.scss create mode 100644 src/components/lab/LabImage/index.tsx create mode 100644 src/components/lab/LabImage/styles.module.scss create mode 100644 src/components/lab/LabNodeTitle/index.tsx rename src/components/{node/NodePanelLab => lab/LabNodeTitle}/styles.module.scss (94%) create mode 100644 src/components/lab/LabPad/index.tsx create mode 100644 src/components/lab/LabPad/styles.module.scss create mode 100644 src/components/lab/LabText/index.tsx create mode 100644 src/components/lab/LabText/styles.module.scss delete mode 100644 src/components/node/NodePanelLab/index.tsx diff --git a/src/components/containers/Markdown/index.tsx b/src/components/containers/Markdown/index.tsx new file mode 100644 index 00000000..3ff0397f --- /dev/null +++ b/src/components/containers/Markdown/index.tsx @@ -0,0 +1,11 @@ +import React, { ButtonHTMLAttributes, DetailedHTMLProps, FC, HTMLAttributes } from 'react'; +import styles from '~/styles/common/markdown.module.scss'; +import classNames from 'classnames'; + +interface IProps extends DetailedHTMLProps, HTMLDivElement> {} + +const Markdown: FC = ({ className, ...props }) => ( +
+); + +export { Markdown }; diff --git a/src/components/lab/LabBottomPanel/index.tsx b/src/components/lab/LabBottomPanel/index.tsx new file mode 100644 index 00000000..16024efd --- /dev/null +++ b/src/components/lab/LabBottomPanel/index.tsx @@ -0,0 +1,17 @@ +import React, { FC } from 'react'; +import { Group } from '~/components/containers/Group'; +import { Icon } from '~/components/input/Icon'; +import { INodeComponentProps } from '~/redux/node/constants'; +import { Filler } from '~/components/containers/Filler'; +import styles from './styles.module.scss'; +import { getPrettyDate } from '~/utils/dom'; + +const LabBottomPanel: FC = ({ node }) => ( + +
{getPrettyDate(node.created_at)}
+ + +
+); + +export { LabBottomPanel }; diff --git a/src/components/lab/LabBottomPanel/styles.module.scss b/src/components/lab/LabBottomPanel/styles.module.scss new file mode 100644 index 00000000..9a2f5871 --- /dev/null +++ b/src/components/lab/LabBottomPanel/styles.module.scss @@ -0,0 +1,10 @@ +@import "~/styles/variables.scss"; + +.wrap { + padding: 0 $gap $gap; +} + +.timestamp { + font: $font_12_regular; + color: darken(white, 40%); +} diff --git a/src/components/lab/LabImage/index.tsx b/src/components/lab/LabImage/index.tsx new file mode 100644 index 00000000..e0383657 --- /dev/null +++ b/src/components/lab/LabImage/index.tsx @@ -0,0 +1,102 @@ +import React, { FC, useCallback, useEffect, useState } from 'react'; +import { INodeComponentProps } from '~/redux/node/constants'; +import SwiperCore, { A11y, Pagination, Navigation, SwiperOptions, Keyboard } from 'swiper'; +import { Swiper, SwiperSlide } from 'swiper/react'; + +import 'swiper/swiper.scss'; +import 'swiper/components/pagination/pagination.scss'; +import 'swiper/components/scrollbar/scrollbar.scss'; +import 'swiper/components/zoom/zoom.scss'; +import 'swiper/components/navigation/navigation.scss'; + +import styles from './styles.module.scss'; +import { useNodeImages } from '~/utils/hooks/node/useNodeImages'; +import { getURL } from '~/utils/dom'; +import { PRESETS, URLS } from '~/constants/urls'; +import SwiperClass from 'swiper/types/swiper-class'; +import { modalShowPhotoswipe } from '~/redux/modal/actions'; +import { useDispatch } from 'react-redux'; +import { useHistory } from 'react-router'; + +SwiperCore.use([Navigation, Pagination, A11y]); + +interface IProps extends INodeComponentProps {} + +const breakpoints: SwiperOptions['breakpoints'] = { + 599: { + spaceBetween: 20, + navigation: true, + }, +}; + +const LabImage: FC = ({ node }) => { + const dispatch = useDispatch(); + const history = useHistory(); + + const [controlledSwiper, setControlledSwiper] = useState(undefined); + + const images = useNodeImages(node); + + const updateSwiper = useCallback(() => { + if (!controlledSwiper) return; + + controlledSwiper.updateSlides(); + controlledSwiper.updateSize(); + controlledSwiper.update(); + }, [controlledSwiper]); + + const resetSwiper = useCallback(() => { + if (!controlledSwiper) return; + controlledSwiper.slideTo(0, 0); + setTimeout(() => controlledSwiper.slideTo(0, 0), 300); + }, [controlledSwiper]); + + useEffect(() => { + updateSwiper(); + resetSwiper(); + }, [images, updateSwiper, resetSwiper]); + + const onClick = useCallback(() => history.push(URLS.NODE_URL(node.id)), [history, node.id]); + + if (!images?.length) { + return null; + } + + return ( +
+ 1 ? 1.1 : 1} + onSwiper={setControlledSwiper} + spaceBetween={10} + grabCursor + autoHeight + breakpoints={breakpoints} + observeSlideChildren + observeParents + resizeObserver + watchOverflow + updateOnImagesReady + onInit={resetSwiper} + keyboard={{ + enabled: true, + onlyInViewport: false, + }} + > + {images.map(file => ( + + {node.title} + + ))} + +
+ ); +}; + +export { LabImage }; diff --git a/src/components/lab/LabImage/styles.module.scss b/src/components/lab/LabImage/styles.module.scss new file mode 100644 index 00000000..06e20d84 --- /dev/null +++ b/src/components/lab/LabImage/styles.module.scss @@ -0,0 +1,70 @@ +@import "~/styles/variables.scss"; + +.wrapper { + border-radius: $radius; + display: flex; + align-items: center; + justify-content: center; + min-width: 0; + + :global(.swiper-container) { + width: 100%; + } + + :global(.swiper-button-next), + :global(.swiper-button-prev) { + color: white; + font-size: 10px; + + &::after { + font-size: 32px; + } + } + +} + +.slide { + text-align: center; + text-transform: uppercase; + font: $font_32_bold; + display: flex; + border-radius: $radius; + align-items: center; + justify-content: center; + width: auto; + max-width: 100%; + opacity: 1; + filter: brightness(50%) saturate(0.5); + transition: opacity 0.5s, filter 0.5s, transform 0.5s; + + &:global(.swiper-slide-active) { + opacity: 1; + filter: brightness(100%); + } + + @include tablet { + padding-bottom: 0; + padding-top: 0; + } +} + +.image { + max-height: calc(100vh - 70px - 70px); + max-width: 100%; + border-radius: $radius; + transition: box-shadow 1s; + box-shadow: transparentize(black, 0.7) 0 3px 5px; + + :global(.swiper-slide-active) & { + box-shadow: transparentize(black, 0.9) 0 10px 5px 4px, + transparentize(black, 0.7) 0 5px 5px, + transparentize(white, 0.95) 0 -1px 2px, + transparentize(white, 0.95) 0 -1px; + } + + @include tablet { + padding-bottom: 0; + max-height: 100vh; + border-radius: 0; + } +} diff --git a/src/components/lab/LabNode/index.tsx b/src/components/lab/LabNode/index.tsx index 5f64c55f..e4207484 100644 --- a/src/components/lab/LabNode/index.tsx +++ b/src/components/lab/LabNode/index.tsx @@ -4,28 +4,17 @@ import { NodePanelInner } from '~/components/node/NodePanelInner'; import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks'; import styles from './styles.module.scss'; import { Card } from '~/components/containers/Card'; -import { NodePanelLab } from '~/components/node/NodePanelLab'; +import { LabNodeTitle } from '~/components/lab/LabNodeTitle'; +import { Grid } from '~/components/containers/Grid'; interface IProps { node: INode; } const LabNode: FC = ({ node }) => { - const { inline, block, head } = useNodeBlocks(node, false); + const { lab } = useNodeBlocks(node, false); - console.log(node.id, { inline, block, head }); - - return ( - -
- -
- - {head} - {block} - {inline} -
- ); + return
{lab}
; }; export { LabNode }; diff --git a/src/components/lab/LabNode/styles.module.scss b/src/components/lab/LabNode/styles.module.scss index 0e8e59ab..cfc41356 100644 --- a/src/components/lab/LabNode/styles.module.scss +++ b/src/components/lab/LabNode/styles.module.scss @@ -1,11 +1,11 @@ @import "~/styles/variables.scss"; .wrap { + box-shadow: transparentize(black, 0.5) 0 0 0 1px, inset transparentize(white, 0.9) 0 1px, lighten(black, 10%) 0 4px; + background-color: $content_bg; + cursor: pointer; + min-width: 0; -} - -.head { - background-color: transparentize(black, 0.9); - border-radius: $radius $radius 0 0; + border-radius: $radius; } diff --git a/src/components/lab/LabNodeTitle/index.tsx b/src/components/lab/LabNodeTitle/index.tsx new file mode 100644 index 00000000..058223c9 --- /dev/null +++ b/src/components/lab/LabNodeTitle/index.tsx @@ -0,0 +1,23 @@ +import React, { FC } from 'react'; +import { INode } from '~/redux/types'; +import styles from './styles.module.scss'; +import { URLS } from '~/constants/urls'; +import { Link } from 'react-router-dom'; + +interface IProps { + node: INode; +} + +const LabNodeTitle: FC = ({ node }) => { + if (!node.title) return null; + + return ( +
+
+ {node.title || '...'} +
+
+ ); +}; + +export { LabNodeTitle }; diff --git a/src/components/node/NodePanelLab/styles.module.scss b/src/components/lab/LabNodeTitle/styles.module.scss similarity index 94% rename from src/components/node/NodePanelLab/styles.module.scss rename to src/components/lab/LabNodeTitle/styles.module.scss index 095dafe5..378f00c7 100644 --- a/src/components/node/NodePanelLab/styles.module.scss +++ b/src/components/lab/LabNodeTitle/styles.module.scss @@ -1,7 +1,7 @@ @import "~/styles/variables.scss"; .wrap { - padding: $gap; + padding: 0 $gap; } .title { diff --git a/src/components/lab/LabPad/index.tsx b/src/components/lab/LabPad/index.tsx new file mode 100644 index 00000000..5432ad99 --- /dev/null +++ b/src/components/lab/LabPad/index.tsx @@ -0,0 +1,8 @@ +import React, { FC } from 'react'; +import styles from './styles.module.scss'; + +interface IProps {} + +const LabPad: FC = () =>
; + +export { LabPad }; diff --git a/src/components/lab/LabPad/styles.module.scss b/src/components/lab/LabPad/styles.module.scss new file mode 100644 index 00000000..7869ed41 --- /dev/null +++ b/src/components/lab/LabPad/styles.module.scss @@ -0,0 +1,5 @@ +@import "~/styles/variables.scss"; + +.pad { + height: $gap; +} diff --git a/src/components/lab/LabText/index.tsx b/src/components/lab/LabText/index.tsx new file mode 100644 index 00000000..ec388b13 --- /dev/null +++ b/src/components/lab/LabText/index.tsx @@ -0,0 +1,28 @@ +import React, { FC, useCallback, useMemo } from 'react'; +import { Markdown } from '~/components/containers/Markdown'; +import { INodeComponentProps } from '~/redux/node/constants'; +import { formatTextParagraphs } from '~/utils/dom'; +import { path } from 'ramda'; +import styles from './styles.module.scss'; +import { useHistory } from 'react-router'; +import { URLS } from '~/constants/urls'; + +const LabText: FC = ({ node }) => { + const content = useMemo(() => formatTextParagraphs(path(['blocks', 0, 'text'], node) || ''), [ + node.blocks, + ]); + + const history = useHistory(); + + const onClick = useCallback(() => history.push(URLS.NODE_URL(node.id)), [node.id]); + + return ( + + ); +}; + +export { LabText }; diff --git a/src/components/lab/LabText/styles.module.scss b/src/components/lab/LabText/styles.module.scss new file mode 100644 index 00000000..c06fe398 --- /dev/null +++ b/src/components/lab/LabText/styles.module.scss @@ -0,0 +1,21 @@ +@import "~/styles/variables.scss"; + +.wrap { + padding: 0 $gap; + + @include tablet { + position: relative; + max-height: 50vh; + overflow: hidden; + + &::after { + content: ' '; + position: absolute; + background: linear-gradient(transparentize($content_bg, 1), $content_bg 80%); + bottom: 0; + left: auto; + width: 100%; + height: 100px; + } + } +} diff --git a/src/components/node/NodePanelLab/index.tsx b/src/components/node/NodePanelLab/index.tsx deleted file mode 100644 index c33714d4..00000000 --- a/src/components/node/NodePanelLab/index.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import React, { FC } from 'react'; -import { INode } from '~/redux/types'; -import styles from './styles.module.scss'; -import { URLS } from '~/constants/urls'; -import { Link } from 'react-router-dom'; - -interface IProps { - node: INode; -} - -const NodePanelLab: FC = ({ node }) => ( -
-
- {node.title || '...'} -
-
-); - -export { NodePanelLab }; diff --git a/src/containers/lab/LabGrid/styles.module.scss b/src/containers/lab/LabGrid/styles.module.scss index 3f42c360..e58bb06d 100644 --- a/src/containers/lab/LabGrid/styles.module.scss +++ b/src/containers/lab/LabGrid/styles.module.scss @@ -4,5 +4,5 @@ display: grid; grid-auto-flow: row; grid-auto-rows: auto; - grid-row-gap: $gap; + grid-row-gap: $gap * 2; } diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts index 8cc79869..59a7050f 100644 --- a/src/redux/node/constants.ts +++ b/src/redux/node/constants.ts @@ -15,6 +15,11 @@ import { IEditorComponentProps, NodeEditorProps } from '~/redux/node/types'; import { EditorFiller } from '~/components/editors/EditorFiller'; import { EditorPublicSwitch } from '~/components/editors/EditorPublicSwitch'; import { NodeImageSwiperBlock } from '~/components/node/NodeImageSwiperBlock'; +import { LabNodeTitle } from '~/components/lab/LabNodeTitle'; +import { LabText } from '~/components/lab/LabText'; +import { LabImage } from '~/components/lab/LabImage'; +import { LabBottomPanel } from '~/components/lab/LabBottomPanel'; +import { LabPad } from '~/components/lab/LabPad'; const prefix = 'NODE.'; export const NODE_ACTIONS = { @@ -83,6 +88,13 @@ export type INodeComponentProps = { export type INodeComponents = Record, FC>; +export const LAB_PREVIEW_LAYOUT: Record[]> = { + [NODE_TYPES.IMAGE]: [LabImage, LabPad, LabNodeTitle, LabBottomPanel], + [NODE_TYPES.VIDEO]: [NodeVideoBlock, LabPad, LabNodeTitle, LabBottomPanel], + [NODE_TYPES.AUDIO]: [LabPad, LabNodeTitle, NodeAudioImageBlock, NodeAudioBlock, LabBottomPanel], + [NODE_TYPES.TEXT]: [LabPad, LabNodeTitle, LabText, LabBottomPanel], +}; + export const NODE_HEADS: INodeComponents = { [NODE_TYPES.IMAGE]: NodeImageSwiperBlock, }; diff --git a/src/utils/hooks/node/useNodeBlocks.ts b/src/utils/hooks/node/useNodeBlocks.ts index 823e522c..df0be6be 100644 --- a/src/utils/hooks/node/useNodeBlocks.ts +++ b/src/utils/hooks/node/useNodeBlocks.ts @@ -3,6 +3,7 @@ import { createElement, FC, useCallback, useMemo } from 'react'; import { isNil, prop } from 'ramda'; import { INodeComponentProps, + LAB_PREVIEW_LAYOUT, NODE_COMPONENTS, NODE_HEADS, NODE_INLINES, @@ -11,11 +12,12 @@ import { // useNodeBlocks returns head, block and inline blocks of node export const useNodeBlocks = (node: INode, isLoading: boolean) => { const createNodeBlock = useCallback( - (block?: FC) => + (block?: FC, key = 0) => !isNil(block) && createElement(block, { node, isLoading, + key, }), [node, isLoading] ); @@ -35,5 +37,13 @@ export const useNodeBlocks = (node: INode, isLoading: boolean) => { [node, createNodeBlock] ); - return { head, block, inline }; + const lab = useMemo( + () => + node?.type && prop(node.type, LAB_PREVIEW_LAYOUT) + ? prop(node.type, LAB_PREVIEW_LAYOUT).map((comp, i) => createNodeBlock(comp, i)) + : undefined, + [node, createNodeBlock] + ); + + return { head, block, inline, lab }; }; From 80967ddfac39cd917adbfd55dbceced302a4d15b Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 11:13:03 +0700 Subject: [PATCH 02/20] #23 fixed lab layout on tablets --- src/components/lab/LabHead/index.tsx | 8 +++++--- src/components/lab/LabHead/styles.module.scss | 13 +++++++++++++ src/containers/lab/LabLayout/styles.module.scss | 5 +++++ 3 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 src/components/lab/LabHead/styles.module.scss diff --git a/src/components/lab/LabHead/index.tsx b/src/components/lab/LabHead/index.tsx index 25fb6cfd..87bfa1ca 100644 --- a/src/components/lab/LabHead/index.tsx +++ b/src/components/lab/LabHead/index.tsx @@ -3,12 +3,14 @@ import { Group } from '~/components/containers/Group'; import { Card } from '~/components/containers/Card'; import { Placeholder } from '~/components/placeholders/Placeholder'; import { Filler } from '~/components/containers/Filler'; +import styles from './styles.module.scss'; +import { Grid } from '~/components/containers/Grid'; interface IProps {} const LabHead: FC = () => ( - - + +
@@ -25,7 +27,7 @@ const LabHead: FC = () => ( - +
); diff --git a/src/components/lab/LabHead/styles.module.scss b/src/components/lab/LabHead/styles.module.scss new file mode 100644 index 00000000..6ba6a4b5 --- /dev/null +++ b/src/components/lab/LabHead/styles.module.scss @@ -0,0 +1,13 @@ +@import "~/styles/variables.scss"; + +.group { + display: flex; + + @include tablet { + flex-wrap: wrap; + } + + & > * { + margin: $gap / 2; + } +} diff --git a/src/containers/lab/LabLayout/styles.module.scss b/src/containers/lab/LabLayout/styles.module.scss index ee69442c..699756e3 100644 --- a/src/containers/lab/LabLayout/styles.module.scss +++ b/src/containers/lab/LabLayout/styles.module.scss @@ -4,6 +4,11 @@ display: grid; grid-template-columns: 3fr 1fr; column-gap: $gap; + + @include tablet { + grid-template-columns: 1fr; + grid-auto-flow: row; + } } .panel { From d5701b2e855e2169c088ac7ece5c16179288ed77 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 11:17:52 +0700 Subject: [PATCH 03/20] #23 fixed lab post background --- src/components/lab/LabImage/index.tsx | 2 -- src/components/lab/LabImage/styles.module.scss | 1 - src/components/lab/LabNode/styles.module.scss | 2 +- src/components/lab/LabNodeTitle/styles.module.scss | 2 +- src/components/lab/LabText/styles.module.scss | 2 +- src/containers/lab/LabLayout/styles.module.scss | 1 + src/styles/_colors.scss | 1 + 7 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/components/lab/LabImage/index.tsx b/src/components/lab/LabImage/index.tsx index e0383657..18d4e5d5 100644 --- a/src/components/lab/LabImage/index.tsx +++ b/src/components/lab/LabImage/index.tsx @@ -30,7 +30,6 @@ const breakpoints: SwiperOptions['breakpoints'] = { }; const LabImage: FC = ({ node }) => { - const dispatch = useDispatch(); const history = useHistory(); const [controlledSwiper, setControlledSwiper] = useState(undefined); @@ -48,7 +47,6 @@ const LabImage: FC = ({ node }) => { const resetSwiper = useCallback(() => { if (!controlledSwiper) return; controlledSwiper.slideTo(0, 0); - setTimeout(() => controlledSwiper.slideTo(0, 0), 300); }, [controlledSwiper]); useEffect(() => { diff --git a/src/components/lab/LabImage/styles.module.scss b/src/components/lab/LabImage/styles.module.scss index 06e20d84..308253be 100644 --- a/src/components/lab/LabImage/styles.module.scss +++ b/src/components/lab/LabImage/styles.module.scss @@ -65,6 +65,5 @@ @include tablet { padding-bottom: 0; max-height: 100vh; - border-radius: 0; } } diff --git a/src/components/lab/LabNode/styles.module.scss b/src/components/lab/LabNode/styles.module.scss index cfc41356..05aed646 100644 --- a/src/components/lab/LabNode/styles.module.scss +++ b/src/components/lab/LabNode/styles.module.scss @@ -2,7 +2,7 @@ .wrap { box-shadow: transparentize(black, 0.5) 0 0 0 1px, inset transparentize(white, 0.9) 0 1px, lighten(black, 10%) 0 4px; - background-color: $content_bg; + background-color: $lab_post_bg; cursor: pointer; min-width: 0; diff --git a/src/components/lab/LabNodeTitle/styles.module.scss b/src/components/lab/LabNodeTitle/styles.module.scss index 378f00c7..008e00f6 100644 --- a/src/components/lab/LabNodeTitle/styles.module.scss +++ b/src/components/lab/LabNodeTitle/styles.module.scss @@ -19,6 +19,6 @@ @include tablet { white-space: nowrap; padding-bottom: 0; - font: $font_16_semibold; + font: $font_20_semibold; } } diff --git a/src/components/lab/LabText/styles.module.scss b/src/components/lab/LabText/styles.module.scss index c06fe398..87c83da4 100644 --- a/src/components/lab/LabText/styles.module.scss +++ b/src/components/lab/LabText/styles.module.scss @@ -11,7 +11,7 @@ &::after { content: ' '; position: absolute; - background: linear-gradient(transparentize($content_bg, 1), $content_bg 80%); + background: linear-gradient(transparentize($lab_post_bg, 1), $lab_post_bg 80%); bottom: 0; left: auto; width: 100%; diff --git a/src/containers/lab/LabLayout/styles.module.scss b/src/containers/lab/LabLayout/styles.module.scss index 699756e3..17f70529 100644 --- a/src/containers/lab/LabLayout/styles.module.scss +++ b/src/containers/lab/LabLayout/styles.module.scss @@ -8,6 +8,7 @@ @include tablet { grid-template-columns: 1fr; grid-auto-flow: row; + padding: 0 $gap / 2; } } diff --git a/src/styles/_colors.scss b/src/styles/_colors.scss index 3a291541..15fb6329 100644 --- a/src/styles/_colors.scss +++ b/src/styles/_colors.scss @@ -36,6 +36,7 @@ $main_text_color: white; $content_bg: darken($main_bg_color, 0%); $content_bg_secondary: darken($content_bg, 2%); +$lab_post_bg: lighten($content_bg, 4%); $cell_bg: lighten($main_bg_color, 0%); $card_bg: lighten($main_bg_color, 0%); From 9745b895f1157eeabae6cc380422d3c7fbb44f5e Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 13:00:28 +0700 Subject: [PATCH 04/20] fixed drone builds --- .drone.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.drone.yml b/.drone.yml index 282a923e..0ddbd29c 100644 --- a/.drone.yml +++ b/.drone.yml @@ -78,7 +78,7 @@ steps: format: markdown message: > {{#success build.status}}🤓{{else}}😨{{/success}} - {{ datetime build.finished "01.02.2006 15:04:05" "UTC" }} [{{repo.name}} / {{commit.branch}}]({{ build.link }}) + [{{repo.name}} / {{commit.branch}}]({{ build.link }}) ``` {{ commit.message }} ``` From 11fd582453fc2b2b4fe008e31b27cf205e87a074 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 15:56:35 +0700 Subject: [PATCH 05/20] #23 lab stats --- src/components/lab/LabBanner/index.tsx | 21 ++++-- .../lab/LabBanner/styles.module.scss | 16 ++++- src/components/lab/LabHero/index.tsx | 53 ++++++++++---- src/components/lab/LabHero/styles.module.scss | 28 +++++++- src/components/lab/LabHeroes/index.tsx | 34 +++++++++ src/components/lab/LabNode/index.tsx | 4 -- src/components/lab/LabTags/index.tsx | 36 ++++++++++ src/components/lab/LabTags/styles.module.scss | 10 +++ src/constants/api.ts | 1 + src/containers/lab/LabLayout/index.tsx | 72 ++----------------- src/containers/lab/LabStats/index.tsx | 60 ++++++++++++++++ .../lab/LabStats/styles.module.scss | 17 +++++ src/redux/lab/actions.ts | 9 +++ src/redux/lab/api.ts | 4 +- src/redux/lab/constants.ts | 3 + src/redux/lab/handlers.ts | 11 ++- src/redux/lab/index.ts | 7 ++ src/redux/lab/sagas.ts | 17 ++++- src/redux/lab/selectors.ts | 3 + src/redux/lab/types.ts | 13 +++- src/styles/_colors.scss | 4 +- src/styles/_global.scss | 4 ++ src/utils/node.ts | 2 +- 23 files changed, 328 insertions(+), 101 deletions(-) create mode 100644 src/components/lab/LabHeroes/index.tsx create mode 100644 src/components/lab/LabTags/index.tsx create mode 100644 src/components/lab/LabTags/styles.module.scss create mode 100644 src/containers/lab/LabStats/index.tsx create mode 100644 src/containers/lab/LabStats/styles.module.scss diff --git a/src/components/lab/LabBanner/index.tsx b/src/components/lab/LabBanner/index.tsx index df8f60ea..856a7844 100644 --- a/src/components/lab/LabBanner/index.tsx +++ b/src/components/lab/LabBanner/index.tsx @@ -9,12 +9,21 @@ interface IProps {} const LabBanner: FC = () => ( - - - - - - +
Лаборатория!
+ + +

+ + Всё, что происходит здесь — всего лишь эксперимент, о котором не узнает никто за + пределами Убежища. + +

+ +

+ Ловим радиоактивных жуков, приручаем утконосов-вампиров, катаемся на младшем научном + сотруднике Егоре Порсифоровиче (у него как раз сейчас линька). +

+
); diff --git a/src/components/lab/LabBanner/styles.module.scss b/src/components/lab/LabBanner/styles.module.scss index f235ed41..c82c7319 100644 --- a/src/components/lab/LabBanner/styles.module.scss +++ b/src/components/lab/LabBanner/styles.module.scss @@ -1,5 +1,19 @@ @import "~/styles/variables.scss"; .wrap { - background: $red_gradient_alt; + background: linear-gradient(darken($dark_blue, 0%), darken($blue, 30%)); +} + +.title { + font: $font_24_bold; + text-transform: uppercase; +} + +.content { + font: $font_14_regular; + line-height: 19px; + + strong { + font-weight: bold; + } } diff --git a/src/components/lab/LabHero/index.tsx b/src/components/lab/LabHero/index.tsx index 1a059815..be4d28d1 100644 --- a/src/components/lab/LabHero/index.tsx +++ b/src/components/lab/LabHero/index.tsx @@ -1,22 +1,51 @@ -import React, { FC } from 'react'; +import React, { FC, useCallback } from 'react'; import { Placeholder } from '~/components/placeholders/Placeholder'; import { Group } from '~/components/containers/Group'; import { Icon } from '~/components/input/Icon'; import styles from './styles.module.scss'; +import { INode } from '~/redux/types'; +import { getPrettyDate } from '~/utils/dom'; +import { URLS } from '~/constants/urls'; +import { Link, useHistory } from 'react-router-dom'; -interface IProps {} +interface IProps { + node?: Partial; + isLoading?: boolean; +} -const LabHero: FC = () => ( - -
- -
+const LabHero: FC = ({ node, isLoading }) => { + const history = useHistory(); + const onClick = useCallback(() => { + history.push(URLS.NODE_URL(node?.id)); + }, [history, node]); - - - + if (!node || isLoading) { + return ( + +
+ +
+ +
+ + +
+
+ ); + } + + return ( + +
+ +
+ +
+
{node.title}
+
{getPrettyDate(node.created_at)}
+
-
-); + ); +}; export { LabHero }; diff --git a/src/components/lab/LabHero/styles.module.scss b/src/components/lab/LabHero/styles.module.scss index b1a7e9cc..bb6f9b8d 100644 --- a/src/components/lab/LabHero/styles.module.scss +++ b/src/components/lab/LabHero/styles.module.scss @@ -1,10 +1,34 @@ @import "~/styles/variables.scss"; .wrap { - margin-bottom: $gap; + min-width: 0; + text-decoration: none; + cursor: pointer; } .star { - fill: #2c2c2c; + fill: darken(white, 76%); + flex: 0 0 32px; +} + +.title { + font: $font_18_semibold; + text-overflow: ellipsis; + line-height: 22px; + word-break: break-all; + color: darken(white, 40%); + + @include clamp(2, 22px) +} + +.description { + font: $font_10_regular; + color: darken(white, 50%); + padding-top: 4px; +} + +.content { + padding: $gap / 2 0; + text-decoration: none; } diff --git a/src/components/lab/LabHeroes/index.tsx b/src/components/lab/LabHeroes/index.tsx new file mode 100644 index 00000000..96a3643c --- /dev/null +++ b/src/components/lab/LabHeroes/index.tsx @@ -0,0 +1,34 @@ +import React, { FC } from 'react'; +import { INode } from '~/redux/types'; +import styles from '~/containers/lab/LabStats/styles.module.scss'; +import { LabHero } from '~/components/lab/LabHero'; +import { Group } from '~/components/containers/Group'; + +interface IProps { + nodes: Partial[]; + isLoading: boolean; +} + +const empty = [...new Array(5)].map((_, i) => i); + +const LabHeroes: FC = ({ nodes, isLoading }) => { + if (isLoading) { + return ( + + {empty.map(i => ( + + ))} + + ); + } + + return ( + + {nodes.slice(0, 7).map(node => ( + + ))} + + ); +}; + +export { LabHeroes }; diff --git a/src/components/lab/LabNode/index.tsx b/src/components/lab/LabNode/index.tsx index e4207484..9b5a212a 100644 --- a/src/components/lab/LabNode/index.tsx +++ b/src/components/lab/LabNode/index.tsx @@ -1,11 +1,7 @@ import React, { FC } from 'react'; import { INode } from '~/redux/types'; -import { NodePanelInner } from '~/components/node/NodePanelInner'; import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks'; import styles from './styles.module.scss'; -import { Card } from '~/components/containers/Card'; -import { LabNodeTitle } from '~/components/lab/LabNodeTitle'; -import { Grid } from '~/components/containers/Grid'; interface IProps { node: INode; diff --git a/src/components/lab/LabTags/index.tsx b/src/components/lab/LabTags/index.tsx new file mode 100644 index 00000000..29a527d6 --- /dev/null +++ b/src/components/lab/LabTags/index.tsx @@ -0,0 +1,36 @@ +import React, { FC } from 'react'; +import styles from './/styles.module.scss'; +import { Placeholder } from '~/components/placeholders/Placeholder'; +import { ITag } from '~/redux/types'; +import { Tag } from '~/components/tags/Tag'; +import { Group } from '~/components/containers/Group'; + +interface IProps { + tags: ITag[]; + isLoading: boolean; +} + +const LabTags: FC = ({ tags, isLoading }) => { + if (isLoading) { + return ( +
+ + + + + + +
+ ); + } + + return ( +
+ {tags.slice(0, 10).map(tag => ( + + ))} +
+ ); +}; + +export { LabTags }; diff --git a/src/components/lab/LabTags/styles.module.scss b/src/components/lab/LabTags/styles.module.scss new file mode 100644 index 00000000..41f211dd --- /dev/null +++ b/src/components/lab/LabTags/styles.module.scss @@ -0,0 +1,10 @@ +@import "~/styles/variables.scss"; + +.tags { + display: flex; + flex-wrap: wrap; + + & > * { + margin: $gap / 2; + } +} diff --git a/src/constants/api.ts b/src/constants/api.ts index c9c4c287..e968e3e8 100644 --- a/src/constants/api.ts +++ b/src/constants/api.ts @@ -52,5 +52,6 @@ export const API = { }, LAB: { NODES: `/lab/`, + STATS: '/lab/stats', }, }; diff --git a/src/containers/lab/LabLayout/index.tsx b/src/containers/lab/LabLayout/index.tsx index df778d28..d27e9136 100644 --- a/src/containers/lab/LabLayout/index.tsx +++ b/src/containers/lab/LabLayout/index.tsx @@ -5,7 +5,7 @@ import { Sticky } from '~/components/containers/Sticky'; import { Container } from '~/containers/main/Container'; import { LabGrid } from '~/containers/lab/LabGrid'; import { useDispatch } from 'react-redux'; -import { labGetList } from '~/redux/lab/actions'; +import { labGetList, labGetStats } from '~/redux/lab/actions'; import { Placeholder } from '~/components/placeholders/Placeholder'; import { Grid } from '~/components/containers/Grid'; import { Group } from '~/components/containers/Group'; @@ -13,6 +13,7 @@ import { LabHero } from '~/components/lab/LabHero'; import { LabBanner } from '~/components/lab/LabBanner'; import { LabHead } from '~/components/lab/LabHead'; import { Filler } from '~/components/containers/Filler'; +import { LabStats } from '~/containers/lab/LabStats'; interface IProps {} @@ -21,6 +22,7 @@ const LabLayout: FC = () => { useEffect(() => { dispatch(labGetList()); + dispatch(labGetStats()); }, [dispatch]); return ( @@ -34,73 +36,7 @@ const LabLayout: FC = () => {
- - - - - - - - - - - -
-
- - - -
- -
- - - - - - -
- -
-
- - - -
- - - -
- -
- -
- -
- -
- -
- - - -
-
- - - - - - -
- - - - - - - - +
diff --git a/src/containers/lab/LabStats/index.tsx b/src/containers/lab/LabStats/index.tsx new file mode 100644 index 00000000..e1dbab77 --- /dev/null +++ b/src/containers/lab/LabStats/index.tsx @@ -0,0 +1,60 @@ +import React, { FC } from 'react'; +import styles from './styles.module.scss'; +import { LabBanner } from '~/components/lab/LabBanner'; +import { Card } from '~/components/containers/Card'; +import { Group } from '~/components/containers/Group'; +import { Placeholder } from '~/components/placeholders/Placeholder'; +import { Filler } from '~/components/containers/Filler'; +import { LabHero } from '~/components/lab/LabHero'; +import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; +import { + selectLabStatsHeroes, + selectLabStatsLoading, + selectLabStatsTags, +} from '~/redux/lab/selectors'; +import { LabTags } from '~/components/lab/LabTags'; +import { LabHeroes } from '~/components/lab/LabHeroes'; + +interface IProps {} + +const LabStats: FC = () => { + const tags = useShallowSelect(selectLabStatsTags); + const heroes = useShallowSelect(selectLabStatsHeroes); + const isLoading = useShallowSelect(selectLabStatsLoading); + + return ( + + + + + + {isLoading ? ( + + ) : ( +
Тэги
+ )} + +
+ +
+ +
+
+
+ + {isLoading ? ( + + ) : ( +
Важные
+ )} + +
+ +
+ + + + ); +}; + +export { LabStats }; diff --git a/src/containers/lab/LabStats/styles.module.scss b/src/containers/lab/LabStats/styles.module.scss new file mode 100644 index 00000000..15742aa5 --- /dev/null +++ b/src/containers/lab/LabStats/styles.module.scss @@ -0,0 +1,17 @@ +@import "~/styles/variables.scss"; + +.title { + font: $font_14_semibold; + color: darken(white, 50%); + text-transform: uppercase; + padding: 0 $gap / 2; + padding-bottom: $gap / 2; +} + +.tags.tags { + margin: 0 -$gap / 2; +} + +.heroes { + margin-top: -$gap; +} diff --git a/src/redux/lab/actions.ts b/src/redux/lab/actions.ts index 1e1ff97a..438a8ad6 100644 --- a/src/redux/lab/actions.ts +++ b/src/redux/lab/actions.ts @@ -10,3 +10,12 @@ export const labSetList = (list: Partial) => ({ type: LAB_ACTIONS.SET_LIST, list, }); + +export const labGetStats = () => ({ + type: LAB_ACTIONS.GET_STATS, +}); + +export const labSetStats = (stats: Partial) => ({ + type: LAB_ACTIONS.SET_STATS, + stats, +}); diff --git a/src/redux/lab/api.ts b/src/redux/lab/api.ts index 5fa97bc0..16bac864 100644 --- a/src/redux/lab/api.ts +++ b/src/redux/lab/api.ts @@ -1,8 +1,10 @@ import { api, cleanResult } from '~/utils/api'; import { API } from '~/constants/api'; -import { GetLabNodesRequest, GetLabNodesResult } from '~/redux/lab/types'; +import { GetLabNodesRequest, GetLabNodesResult, GetLabStatsResult } from '~/redux/lab/types'; export const getLabNodes = ({ after }: GetLabNodesRequest) => api .get(API.LAB.NODES, { params: { after } }) .then(cleanResult); + +export const getLabStats = () => api.get(API.LAB.STATS).then(cleanResult); diff --git a/src/redux/lab/constants.ts b/src/redux/lab/constants.ts index d2e670da..0b7979b8 100644 --- a/src/redux/lab/constants.ts +++ b/src/redux/lab/constants.ts @@ -3,4 +3,7 @@ const prefix = 'LAB.'; export const LAB_ACTIONS = { GET_LIST: `${prefix}GET_LIST`, SET_LIST: `${prefix}SET_LIST`, + + GET_STATS: `${prefix}GET_STATS`, + SET_STATS: `${prefix}SET_STATS`, }; diff --git a/src/redux/lab/handlers.ts b/src/redux/lab/handlers.ts index b09812e2..f23fada1 100644 --- a/src/redux/lab/handlers.ts +++ b/src/redux/lab/handlers.ts @@ -1,5 +1,5 @@ import { LAB_ACTIONS } from '~/redux/lab/constants'; -import { labSetList } from '~/redux/lab/actions'; +import { labSetList, labSetStats } from '~/redux/lab/actions'; import { ILabState } from '~/redux/lab/types'; type LabHandler any> = ( @@ -15,6 +15,15 @@ const setList: LabHandler = (state, { list }) => ({ }, }); +const setStats: LabHandler = (state, { stats }) => ({ + ...state, + stats: { + ...state.stats, + ...stats, + }, +}); + export const LAB_HANDLERS = { [LAB_ACTIONS.SET_LIST]: setList, + [LAB_ACTIONS.SET_STATS]: setStats, }; diff --git a/src/redux/lab/index.ts b/src/redux/lab/index.ts index 56879a52..1a0bc0aa 100644 --- a/src/redux/lab/index.ts +++ b/src/redux/lab/index.ts @@ -1,6 +1,7 @@ import { createReducer } from '~/utils/reducer'; import { LAB_HANDLERS } from '~/redux/lab/handlers'; import { ILabState } from '~/redux/lab/types'; +import { INode, ITag } from '~/redux/types'; const INITIAL_STATE: ILabState = { list: { @@ -9,6 +10,12 @@ const INITIAL_STATE: ILabState = { count: 0, error: '', }, + stats: { + is_loading: false, + heroes: [], + tags: [], + error: undefined, + }, }; export default createReducer(INITIAL_STATE, LAB_HANDLERS); diff --git a/src/redux/lab/sagas.ts b/src/redux/lab/sagas.ts index 5fc48b8b..1a66b3a5 100644 --- a/src/redux/lab/sagas.ts +++ b/src/redux/lab/sagas.ts @@ -1,8 +1,8 @@ import { takeLeading, call, put } from 'redux-saga/effects'; -import { labGetList, labSetList } from '~/redux/lab/actions'; +import { labGetList, labSetList, labSetStats } from '~/redux/lab/actions'; import { LAB_ACTIONS } from '~/redux/lab/constants'; import { Unwrap } from '~/redux/types'; -import { getLabNodes } from '~/redux/lab/api'; +import { getLabNodes, getLabStats } from '~/redux/lab/api'; function* getList({ after = '' }: ReturnType) { try { @@ -16,6 +16,19 @@ function* getList({ after = '' }: ReturnType) { } } +function* getStats() { + try { + yield put(labSetStats({ is_loading: true })); + const { heroes, tags }: Unwrap = yield call(getLabStats); + yield put(labSetStats({ heroes, tags })); + } catch (error) { + yield put(labSetStats({ error: error.message })); + } finally { + yield put(labSetStats({ is_loading: false })); + } +} + export default function* labSaga() { yield takeLeading(LAB_ACTIONS.GET_LIST, getList); + yield takeLeading(LAB_ACTIONS.GET_STATS, getStats); } diff --git a/src/redux/lab/selectors.ts b/src/redux/lab/selectors.ts index 0854ac25..19bdf7e8 100644 --- a/src/redux/lab/selectors.ts +++ b/src/redux/lab/selectors.ts @@ -2,3 +2,6 @@ import { IState } from '~/redux/store'; export const selectLab = (state: IState) => state.lab; export const selectLabListNodes = (state: IState) => state.lab.list.nodes; +export const selectLabStatsHeroes = (state: IState) => state.lab.stats.heroes; +export const selectLabStatsTags = (state: IState) => state.lab.stats.tags; +export const selectLabStatsLoading = (state: IState) => state.lab.stats.is_loading; diff --git a/src/redux/lab/types.ts b/src/redux/lab/types.ts index 7614807b..9a30aebe 100644 --- a/src/redux/lab/types.ts +++ b/src/redux/lab/types.ts @@ -1,4 +1,4 @@ -import { IError, INode } from '~/redux/types'; +import { IError, INode, ITag } from '~/redux/types'; export type ILabState = Readonly<{ list: { @@ -7,6 +7,12 @@ export type ILabState = Readonly<{ count: number; error: IError; }; + stats: { + is_loading: boolean; + heroes: Partial[]; + tags: ITag[]; + error?: string; + }; }>; export type GetLabNodesRequest = { @@ -17,3 +23,8 @@ export type GetLabNodesResult = { nodes: INode[]; count: number; }; + +export type GetLabStatsResult = { + heroes: INode[]; + tags: ITag[]; +}; diff --git a/src/styles/_colors.scss b/src/styles/_colors.scss index 15fb6329..957df9be 100644 --- a/src/styles/_colors.scss +++ b/src/styles/_colors.scss @@ -2,7 +2,7 @@ // $red: #ff3344; $red: #ff3344; $yellow: #ffd60f; -$dark_blue: #3c75ff; +$dark_blue: #592071; $blue: #582cd0; $green: #00d2b9; //$green: #00503c; @@ -16,7 +16,7 @@ $primary: $red; $secondary: $wisegreen; $red_gradient: linear-gradient(165deg, $orange -50%, $red 150%); -$blue_gradient: linear-gradient(170deg, $green, $dark_blue); +$blue_gradient: linear-gradient(170deg, $blue, $dark_blue); $green_gradient: linear-gradient( 170deg, lighten(adjust_hue($wisegreen, 15deg), 10%) 0%, diff --git a/src/styles/_global.scss b/src/styles/_global.scss index 8f755483..f13d045b 100644 --- a/src/styles/_global.scss +++ b/src/styles/_global.scss @@ -27,6 +27,10 @@ body { background-size: 600px 600px; pointer-events: none; } + + * { + min-width: 0; + } } #app { diff --git a/src/utils/node.ts b/src/utils/node.ts index f00d006c..0e2f426e 100644 --- a/src/utils/node.ts +++ b/src/utils/node.ts @@ -16,6 +16,6 @@ export const canLikeNode = (node: Partial, user: Partial): boolean path(['role'], user) && path(['role'], user) !== USER_ROLES.GUEST; export const canStarNode = (node: Partial, user: Partial): boolean => - node.type === NODE_TYPES.IMAGE && + (node.type === NODE_TYPES.IMAGE || node.is_promoted === false) && path(['role'], user) && path(['role'], user) === USER_ROLES.ADMIN; From b761849432a856d604d6569797f8c7479ba715ff Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 16:01:29 +0700 Subject: [PATCH 06/20] #23 fixed lab titles --- src/containers/lab/LabStats/index.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/containers/lab/LabStats/index.tsx b/src/containers/lab/LabStats/index.tsx index e1dbab77..33261b58 100644 --- a/src/containers/lab/LabStats/index.tsx +++ b/src/containers/lab/LabStats/index.tsx @@ -31,7 +31,7 @@ const LabStats: FC = () => { {isLoading ? ( ) : ( -
Тэги
+ tags.length &&
Тэги
)}
@@ -45,7 +45,7 @@ const LabStats: FC = () => { {isLoading ? ( ) : ( -
Важные
+ heroes.length > 0 &&
Важные
)}
From 10729de3755954e5ed9101635236a56e827a9957 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 17:21:35 +0700 Subject: [PATCH 07/20] #23 fixed lab shadows --- src/components/lab/LabBanner/styles.module.scss | 2 ++ src/components/lab/LabHead/index.tsx | 4 ++-- src/components/lab/LabHead/styles.module.scss | 8 ++++++++ src/components/lab/LabNode/styles.module.scss | 3 ++- src/containers/lab/LabStats/index.tsx | 4 ++-- src/containers/lab/LabStats/styles.module.scss | 8 ++++++++ src/redux/node/constants.ts | 12 ++++++++++-- src/styles/variables.scss | 6 ++++++ 8 files changed, 40 insertions(+), 7 deletions(-) diff --git a/src/components/lab/LabBanner/styles.module.scss b/src/components/lab/LabBanner/styles.module.scss index c82c7319..4f4f6174 100644 --- a/src/components/lab/LabBanner/styles.module.scss +++ b/src/components/lab/LabBanner/styles.module.scss @@ -1,6 +1,8 @@ @import "~/styles/variables.scss"; .wrap { + @include lab_shadow; + background: linear-gradient(darken($dark_blue, 0%), darken($blue, 30%)); } diff --git a/src/components/lab/LabHead/index.tsx b/src/components/lab/LabHead/index.tsx index 87bfa1ca..0427b758 100644 --- a/src/components/lab/LabHead/index.tsx +++ b/src/components/lab/LabHead/index.tsx @@ -9,7 +9,7 @@ import { Grid } from '~/components/containers/Grid'; interface IProps {} const LabHead: FC = () => ( - +
@@ -28,7 +28,7 @@ const LabHead: FC = () => (
- +
); export { LabHead }; diff --git a/src/components/lab/LabHead/styles.module.scss b/src/components/lab/LabHead/styles.module.scss index 6ba6a4b5..98f82210 100644 --- a/src/components/lab/LabHead/styles.module.scss +++ b/src/components/lab/LabHead/styles.module.scss @@ -1,5 +1,13 @@ @import "~/styles/variables.scss"; +.wrap { + @include lab_shadow; + + border-radius: $radius; + background-color: $content_bg; + padding: $gap; +} + .group { display: flex; diff --git a/src/components/lab/LabNode/styles.module.scss b/src/components/lab/LabNode/styles.module.scss index 05aed646..14052071 100644 --- a/src/components/lab/LabNode/styles.module.scss +++ b/src/components/lab/LabNode/styles.module.scss @@ -1,7 +1,8 @@ @import "~/styles/variables.scss"; .wrap { - box-shadow: transparentize(black, 0.5) 0 0 0 1px, inset transparentize(white, 0.9) 0 1px, lighten(black, 10%) 0 4px; + @include lab_shadow; + background-color: $lab_post_bg; cursor: pointer; diff --git a/src/containers/lab/LabStats/index.tsx b/src/containers/lab/LabStats/index.tsx index 33261b58..18ba904c 100644 --- a/src/containers/lab/LabStats/index.tsx +++ b/src/containers/lab/LabStats/index.tsx @@ -26,7 +26,7 @@ const LabStats: FC = () => { - +
{isLoading ? ( @@ -52,7 +52,7 @@ const LabStats: FC = () => {
-
+
); }; diff --git a/src/containers/lab/LabStats/styles.module.scss b/src/containers/lab/LabStats/styles.module.scss index 15742aa5..dee75ce6 100644 --- a/src/containers/lab/LabStats/styles.module.scss +++ b/src/containers/lab/LabStats/styles.module.scss @@ -15,3 +15,11 @@ .heroes { margin-top: -$gap; } + +.card { + @include lab_shadow; + + border-radius: $radius; + background-color: $comment_bg; + padding: $gap; +} diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts index 59a7050f..6c8c9c5e 100644 --- a/src/redux/node/constants.ts +++ b/src/redux/node/constants.ts @@ -91,8 +91,16 @@ export type INodeComponents = Record, FC[]> = { [NODE_TYPES.IMAGE]: [LabImage, LabPad, LabNodeTitle, LabBottomPanel], [NODE_TYPES.VIDEO]: [NodeVideoBlock, LabPad, LabNodeTitle, LabBottomPanel], - [NODE_TYPES.AUDIO]: [LabPad, LabNodeTitle, NodeAudioImageBlock, NodeAudioBlock, LabBottomPanel], - [NODE_TYPES.TEXT]: [LabPad, LabNodeTitle, LabText, LabBottomPanel], + [NODE_TYPES.AUDIO]: [ + LabPad, + LabNodeTitle, + LabPad, + NodeAudioImageBlock, + NodeAudioBlock, + LabPad, + LabBottomPanel, + ], + [NODE_TYPES.TEXT]: [LabPad, LabNodeTitle, LabPad, LabText, LabPad, LabBottomPanel], }; export const NODE_HEADS: INodeComponents = { diff --git a/src/styles/variables.scss b/src/styles/variables.scss index a518e5d4..0d1b25cf 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -219,3 +219,9 @@ $sidebar_border: transparentize(white, 0.95); border-radius: $radius; cursor: pointer; } + +@mixin lab_shadow { + box-shadow: transparentize(black, 0.5) 0 0 0 1px, + inset transparentize(white, 0.9) 0 1px, + lighten(black, 10%) 0 4px; +} From 0c07fb5a4548f4ddf8f4197165861eea46a84bc9 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 17:25:56 +0700 Subject: [PATCH 08/20] fixed node cover reset --- src/components/lab/LabHeroes/index.tsx | 2 +- src/utils/hooks/node/useNodeCoverImage.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/lab/LabHeroes/index.tsx b/src/components/lab/LabHeroes/index.tsx index 96a3643c..9c820682 100644 --- a/src/components/lab/LabHeroes/index.tsx +++ b/src/components/lab/LabHeroes/index.tsx @@ -24,7 +24,7 @@ const LabHeroes: FC = ({ nodes, isLoading }) => { return ( - {nodes.slice(0, 7).map(node => ( + {nodes.slice(0, 10).map(node => ( ))} diff --git a/src/utils/hooks/node/useNodeCoverImage.ts b/src/utils/hooks/node/useNodeCoverImage.ts index 5f4e7b39..62e104a9 100644 --- a/src/utils/hooks/node/useNodeCoverImage.ts +++ b/src/utils/hooks/node/useNodeCoverImage.ts @@ -10,7 +10,7 @@ export const useNodeCoverImage = (node: INode) => { dispatch(nodeSetCoverImage(node.cover)); return () => { - nodeSetCoverImage(undefined); + dispatch(nodeSetCoverImage(undefined)); }; }, [dispatch, node.cover, node.id]); }; From 58d5a8ee350a9f3e80e300947ba56c19cc1608a7 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 17:46:47 +0700 Subject: [PATCH 09/20] #23 added lab tabs --- src/components/lab/LabHead/index.tsx | 27 ++++------------ src/components/lab/LabHead/styles.module.scss | 4 ++- src/components/lab/LabHeadItem/index.tsx | 32 +++++++++++++++++++ .../lab/LabHeadItem/styles.module.scss | 26 +++++++++++++++ .../node/NodePanelInner/styles.module.scss | 1 + src/sprites/Sprites.tsx | 16 ++++++++++ 6 files changed, 84 insertions(+), 22 deletions(-) create mode 100644 src/components/lab/LabHeadItem/index.tsx create mode 100644 src/components/lab/LabHeadItem/styles.module.scss diff --git a/src/components/lab/LabHead/index.tsx b/src/components/lab/LabHead/index.tsx index 0427b758..40d1a908 100644 --- a/src/components/lab/LabHead/index.tsx +++ b/src/components/lab/LabHead/index.tsx @@ -1,32 +1,17 @@ import React, { FC } from 'react'; -import { Group } from '~/components/containers/Group'; -import { Card } from '~/components/containers/Card'; -import { Placeholder } from '~/components/placeholders/Placeholder'; -import { Filler } from '~/components/containers/Filler'; import styles from './styles.module.scss'; -import { Grid } from '~/components/containers/Grid'; +import { LabHeadItem } from '~/components/lab/LabHeadItem'; interface IProps {} const LabHead: FC = () => (
- - - - - - - - - - - - - - - - + + Свежие + + Популярные + Важные
); diff --git a/src/components/lab/LabHead/styles.module.scss b/src/components/lab/LabHead/styles.module.scss index 98f82210..0848772f 100644 --- a/src/components/lab/LabHead/styles.module.scss +++ b/src/components/lab/LabHead/styles.module.scss @@ -5,7 +5,7 @@ border-radius: $radius; background-color: $content_bg; - padding: $gap; + padding: $gap / 2; } .group { @@ -13,6 +13,8 @@ @include tablet { flex-wrap: wrap; + align-items: center; + justify-content: center; } & > * { diff --git a/src/components/lab/LabHeadItem/index.tsx b/src/components/lab/LabHeadItem/index.tsx new file mode 100644 index 00000000..b4f51583 --- /dev/null +++ b/src/components/lab/LabHeadItem/index.tsx @@ -0,0 +1,32 @@ +import React, { FC } from 'react'; +import { Group } from '~/components/containers/Group'; +import { Icon } from '~/components/input/Icon'; +import { Placeholder } from '~/components/placeholders/Placeholder'; +import styles from './styles.module.scss'; +import classNames from 'classnames'; + +interface IProps { + icon: string; + isLoading?: boolean; + active?: boolean; +} + +const LabHeadItem: FC = ({ icon, children, isLoading, active }) => { + if (isLoading) { + return ( + + + + + ); + } + + return ( + + + {children} + + ); +}; + +export { LabHeadItem }; diff --git a/src/components/lab/LabHeadItem/styles.module.scss b/src/components/lab/LabHeadItem/styles.module.scss new file mode 100644 index 00000000..1967bb0b --- /dev/null +++ b/src/components/lab/LabHeadItem/styles.module.scss @@ -0,0 +1,26 @@ +@import "~/styles/variables.scss"; + +.item { + flex: 0 0 auto; + padding: $gap / 2; + fill: currentColor; + color: darken(white, 50%); + transition: color 0.25s; + cursor: pointer; + + &:hover { + color: white; + } + + &.active { + color: $blue; + + &:hover { + color: lighten($blue, 4%); + } + } +} + +.text { + font: $font_16_semibold; +} diff --git a/src/components/node/NodePanelInner/styles.module.scss b/src/components/node/NodePanelInner/styles.module.scss index c9b9a94b..e1d3764f 100644 --- a/src/components/node/NodePanelInner/styles.module.scss +++ b/src/components/node/NodePanelInner/styles.module.scss @@ -215,6 +215,7 @@ transition: fill, stroke 0.25s; will-change: transform; position: relative; + flex: 0 0 32px; &:global(.is_liked) { svg { diff --git a/src/sprites/Sprites.tsx b/src/sprites/Sprites.tsx index f822d726..ee678362 100644 --- a/src/sprites/Sprites.tsx +++ b/src/sprites/Sprites.tsx @@ -283,6 +283,22 @@ const Sprites: FC<{}> = () => ( transform="scale(0.011) translate(120, 120)" /> + + + + + + + + + + ); From e44ad8e5c259f1f8c26411a45c4dd3d73584d332 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 17:53:28 +0700 Subject: [PATCH 10/20] #23 added is_loading to lab's head --- src/components/lab/LabHead/index.tsx | 18 +++++++++++++----- src/containers/lab/LabLayout/index.tsx | 5 ++++- src/redux/lab/selectors.ts | 1 + 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/lab/LabHead/index.tsx b/src/components/lab/LabHead/index.tsx index 40d1a908..1f61048f 100644 --- a/src/components/lab/LabHead/index.tsx +++ b/src/components/lab/LabHead/index.tsx @@ -2,16 +2,24 @@ import React, { FC } from 'react'; import styles from './styles.module.scss'; import { LabHeadItem } from '~/components/lab/LabHeadItem'; -interface IProps {} +interface IProps { + isLoading?: boolean; +} -const LabHead: FC = () => ( +const LabHead: FC = ({ isLoading }) => (
- + Свежие - Популярные - Важные + + + Популярные + + + + Важные +
); diff --git a/src/containers/lab/LabLayout/index.tsx b/src/containers/lab/LabLayout/index.tsx index d27e9136..e7ab264b 100644 --- a/src/containers/lab/LabLayout/index.tsx +++ b/src/containers/lab/LabLayout/index.tsx @@ -14,10 +14,13 @@ import { LabBanner } from '~/components/lab/LabBanner'; import { LabHead } from '~/components/lab/LabHead'; import { Filler } from '~/components/containers/Filler'; import { LabStats } from '~/containers/lab/LabStats'; +import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; +import { selectLabList, selectLabListNodes, selectLabStatsLoading } from '~/redux/lab/selectors'; interface IProps {} const LabLayout: FC = () => { + const { is_loading } = useShallowSelect(selectLabList); const dispatch = useDispatch(); useEffect(() => { @@ -30,7 +33,7 @@ const LabLayout: FC = () => {
- + diff --git a/src/redux/lab/selectors.ts b/src/redux/lab/selectors.ts index 19bdf7e8..9c47744c 100644 --- a/src/redux/lab/selectors.ts +++ b/src/redux/lab/selectors.ts @@ -2,6 +2,7 @@ import { IState } from '~/redux/store'; export const selectLab = (state: IState) => state.lab; export const selectLabListNodes = (state: IState) => state.lab.list.nodes; +export const selectLabList = (state: IState) => state.lab.list; export const selectLabStatsHeroes = (state: IState) => state.lab.stats.heroes; export const selectLabStatsTags = (state: IState) => state.lab.stats.tags; export const selectLabStatsLoading = (state: IState) => state.lab.stats.is_loading; From 2b2464b8ddaeaa0eacc46854a04244aa1fdd8c0e Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Mon, 22 Mar 2021 18:00:53 +0700 Subject: [PATCH 11/20] #23 fixed swiper crash --- src/components/node/NodeImageSwiperBlock/index.tsx | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/components/node/NodeImageSwiperBlock/index.tsx b/src/components/node/NodeImageSwiperBlock/index.tsx index 417ae430..d8fa86ed 100644 --- a/src/components/node/NodeImageSwiperBlock/index.tsx +++ b/src/components/node/NodeImageSwiperBlock/index.tsx @@ -45,7 +45,9 @@ const NodeImageSwiperBlock: FC = ({ node }) => { const resetSwiper = useCallback(() => { if (!controlledSwiper) return; controlledSwiper.slideTo(0, 0); - setTimeout(() => controlledSwiper.slideTo(0, 0), 300); + + // TODO: replace with working one + // setTimeout(() => controlledSwiper.slideTo(0, 0), 300); }, [controlledSwiper]); useEffect(() => { @@ -63,7 +65,7 @@ const NodeImageSwiperBlock: FC = ({ node }) => { } return ( -
+
Date: Mon, 22 Mar 2021 18:07:32 +0700 Subject: [PATCH 12/20] #23 fixed lab active tab color --- src/components/lab/LabHeadItem/styles.module.scss | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/components/lab/LabHeadItem/styles.module.scss b/src/components/lab/LabHeadItem/styles.module.scss index 1967bb0b..cb5b360e 100644 --- a/src/components/lab/LabHeadItem/styles.module.scss +++ b/src/components/lab/LabHeadItem/styles.module.scss @@ -14,10 +14,9 @@ &.active { color: $blue; - - &:hover { - color: lighten($blue, 4%); - } + background-color: lighten($content_bg, 6%); + border-radius: $radius; + padding: 0 $gap; } } From deb8c27eca981c441f9b6883269a40acfdb9e1d3 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Tue, 23 Mar 2021 11:23:42 +0700 Subject: [PATCH 13/20] fixed timestamp overflow on comments --- .../comment/CommentTextBlock/styles.module.scss | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/comment/CommentTextBlock/styles.module.scss b/src/components/comment/CommentTextBlock/styles.module.scss index ec47d8fd..f99189e4 100644 --- a/src/components/comment/CommentTextBlock/styles.module.scss +++ b/src/components/comment/CommentTextBlock/styles.module.scss @@ -28,4 +28,12 @@ :global(.green) { color: $wisegreen; } + + & :last-child::after { + display: inline-block; + content: " "; + height: 1em; + width: 120px; + flex: 0 0 120px; + } } From ccec2117270ed6c6a5c88dd480587abe38f73557 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Tue, 23 Mar 2021 11:29:47 +0700 Subject: [PATCH 14/20] fixed header appearance on mobile --- .../comment/CommentTextBlock/styles.module.scss | 2 +- src/components/main/Header/index.tsx | 2 +- src/components/main/Header/styles.module.scss | 11 +++++++++++ src/components/main/Logo/styles.module.scss | 4 ++++ src/styles/_global.scss | 4 ---- 5 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/components/comment/CommentTextBlock/styles.module.scss b/src/components/comment/CommentTextBlock/styles.module.scss index f99189e4..09814017 100644 --- a/src/components/comment/CommentTextBlock/styles.module.scss +++ b/src/components/comment/CommentTextBlock/styles.module.scss @@ -29,7 +29,7 @@ color: $wisegreen; } - & :last-child::after { + & > :last-child::after { display: inline-block; content: " "; height: 1em; diff --git a/src/components/main/Header/index.tsx b/src/components/main/Header/index.tsx index 014e12a1..3f6cd6d9 100644 --- a/src/components/main/Header/index.tsx +++ b/src/components/main/Header/index.tsx @@ -80,7 +80,7 @@ const HeaderUnconnected: FC = memo(
- +
Date: Wed, 24 Mar 2021 14:53:29 +0700 Subject: [PATCH 15/20] #23 adde comment_count and last_seen to lab --- src/components/lab/LabBottomPanel/index.tsx | 1 - src/components/lab/LabNode/index.tsx | 11 +++++++++-- src/containers/lab/LabGrid/index.tsx | 2 +- src/redux/lab/types.ts | 10 ++++++++-- 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/components/lab/LabBottomPanel/index.tsx b/src/components/lab/LabBottomPanel/index.tsx index 16024efd..9e9d6316 100644 --- a/src/components/lab/LabBottomPanel/index.tsx +++ b/src/components/lab/LabBottomPanel/index.tsx @@ -1,6 +1,5 @@ import React, { FC } from 'react'; import { Group } from '~/components/containers/Group'; -import { Icon } from '~/components/input/Icon'; import { INodeComponentProps } from '~/redux/node/constants'; import { Filler } from '~/components/containers/Filler'; import styles from './styles.module.scss'; diff --git a/src/components/lab/LabNode/index.tsx b/src/components/lab/LabNode/index.tsx index 9b5a212a..4d5fe911 100644 --- a/src/components/lab/LabNode/index.tsx +++ b/src/components/lab/LabNode/index.tsx @@ -2,15 +2,22 @@ import React, { FC } from 'react'; import { INode } from '~/redux/types'; import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks'; import styles from './styles.module.scss'; +import { LabBottomPanel } from '~/components/lab/LabBottomPanel'; interface IProps { node: INode; + isLoading?: boolean; } -const LabNode: FC = ({ node }) => { +const LabNode: FC = ({ node, isLoading }) => { const { lab } = useNodeBlocks(node, false); - return
{lab}
; + return ( +
+ {lab} + +
+ ); }; export { LabNode }; diff --git a/src/containers/lab/LabGrid/index.tsx b/src/containers/lab/LabGrid/index.tsx index b6961b5f..5dc8c816 100644 --- a/src/containers/lab/LabGrid/index.tsx +++ b/src/containers/lab/LabGrid/index.tsx @@ -12,7 +12,7 @@ const LabGrid: FC = () => { return (
{nodes.map(node => ( - + ))}
); diff --git a/src/redux/lab/types.ts b/src/redux/lab/types.ts index 9a30aebe..4a188e97 100644 --- a/src/redux/lab/types.ts +++ b/src/redux/lab/types.ts @@ -3,7 +3,7 @@ import { IError, INode, ITag } from '~/redux/types'; export type ILabState = Readonly<{ list: { is_loading: boolean; - nodes: INode[]; + nodes: ILabNode[]; count: number; error: IError; }; @@ -19,8 +19,14 @@ export type GetLabNodesRequest = { after?: string; }; +export interface ILabNode { + node: INode; + last_seen: string | null; + comment_count: number; +} + export type GetLabNodesResult = { - nodes: INode[]; + nodes: ILabNode[]; count: number; }; From e2d1b660cc8caef0d723f39a2440cb9db1e27d99 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Mar 2021 17:11:37 +0700 Subject: [PATCH 16/20] #23 added comment_count and last_seen to lab --- src/components/lab/LabBottomPanel/index.tsx | 25 ++++++++++++++++--- .../lab/LabBottomPanel/styles.module.scss | 17 +++++++++++++ src/components/lab/LabNode/index.tsx | 20 ++++++++++++--- src/containers/lab/LabGrid/index.tsx | 7 +++++- src/redux/node/constants.ts | 16 +++--------- src/sprites/Sprites.tsx | 12 ++++++++- 6 files changed, 77 insertions(+), 20 deletions(-) diff --git a/src/components/lab/LabBottomPanel/index.tsx b/src/components/lab/LabBottomPanel/index.tsx index 9e9d6316..e1789a98 100644 --- a/src/components/lab/LabBottomPanel/index.tsx +++ b/src/components/lab/LabBottomPanel/index.tsx @@ -1,15 +1,34 @@ import React, { FC } from 'react'; import { Group } from '~/components/containers/Group'; -import { INodeComponentProps } from '~/redux/node/constants'; import { Filler } from '~/components/containers/Filler'; import styles from './styles.module.scss'; import { getPrettyDate } from '~/utils/dom'; +import { INode } from '~/redux/types'; +import { Icon } from '~/components/input/Icon'; +import classNames from 'classnames'; +import { Grid } from '~/components/containers/Grid'; -const LabBottomPanel: FC = ({ node }) => ( +type Props = { + node: INode; + isLoading?: boolean; + hasNewComments: boolean; + commentCount: number; +}; + +const LabBottomPanel: FC = ({ node, hasNewComments, commentCount }) => (
{getPrettyDate(node.created_at)}
- + + + + {node.like_count} + + + + + {commentCount} +
); diff --git a/src/components/lab/LabBottomPanel/styles.module.scss b/src/components/lab/LabBottomPanel/styles.module.scss index 9a2f5871..0a4be156 100644 --- a/src/components/lab/LabBottomPanel/styles.module.scss +++ b/src/components/lab/LabBottomPanel/styles.module.scss @@ -8,3 +8,20 @@ font: $font_12_regular; color: darken(white, 40%); } + +.comments.comments { + flex: 0; + font: $font_16_semibold; + color: darken(white, 50%); + fill: currentColor; + stroke: none; + column-gap: $gap / 2 !important; + + &.active { + color: $red; + } +} + +.like { + +} diff --git a/src/components/lab/LabNode/index.tsx b/src/components/lab/LabNode/index.tsx index 4d5fe911..94dc699d 100644 --- a/src/components/lab/LabNode/index.tsx +++ b/src/components/lab/LabNode/index.tsx @@ -1,21 +1,35 @@ -import React, { FC } from 'react'; +import React, { FC, useMemo } from 'react'; import { INode } from '~/redux/types'; import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks'; import styles from './styles.module.scss'; import { LabBottomPanel } from '~/components/lab/LabBottomPanel'; +import { isAfter, parseISO } from 'date-fns'; interface IProps { node: INode; + lastSeen: string | null; isLoading?: boolean; + commentCount: number; } -const LabNode: FC = ({ node, isLoading }) => { +const LabNode: FC = ({ node, isLoading, lastSeen, commentCount }) => { const { lab } = useNodeBlocks(node, false); + const hasNewComments = useMemo( + () => + !!node.commented_at && !!lastSeen && isAfter(parseISO(node.commented_at), parseISO(lastSeen)), + [node.commented_at, lastSeen] + ); + return (
{lab} - +
); }; diff --git a/src/containers/lab/LabGrid/index.tsx b/src/containers/lab/LabGrid/index.tsx index 5dc8c816..a075ea7a 100644 --- a/src/containers/lab/LabGrid/index.tsx +++ b/src/containers/lab/LabGrid/index.tsx @@ -12,7 +12,12 @@ const LabGrid: FC = () => { return (
{nodes.map(node => ( - + ))}
); diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts index 6c8c9c5e..8755a016 100644 --- a/src/redux/node/constants.ts +++ b/src/redux/node/constants.ts @@ -89,18 +89,10 @@ export type INodeComponentProps = { export type INodeComponents = Record, FC>; export const LAB_PREVIEW_LAYOUT: Record[]> = { - [NODE_TYPES.IMAGE]: [LabImage, LabPad, LabNodeTitle, LabBottomPanel], - [NODE_TYPES.VIDEO]: [NodeVideoBlock, LabPad, LabNodeTitle, LabBottomPanel], - [NODE_TYPES.AUDIO]: [ - LabPad, - LabNodeTitle, - LabPad, - NodeAudioImageBlock, - NodeAudioBlock, - LabPad, - LabBottomPanel, - ], - [NODE_TYPES.TEXT]: [LabPad, LabNodeTitle, LabPad, LabText, LabPad, LabBottomPanel], + [NODE_TYPES.IMAGE]: [LabImage, LabPad, LabNodeTitle], + [NODE_TYPES.VIDEO]: [NodeVideoBlock, LabPad, LabNodeTitle], + [NODE_TYPES.AUDIO]: [LabPad, LabNodeTitle, LabPad, NodeAudioImageBlock, NodeAudioBlock, LabPad], + [NODE_TYPES.TEXT]: [LabPad, LabNodeTitle, LabPad, LabText, LabPad], }; export const NODE_HEADS: INodeComponents = { diff --git a/src/sprites/Sprites.tsx b/src/sprites/Sprites.tsx index ee678362..9ace8331 100644 --- a/src/sprites/Sprites.tsx +++ b/src/sprites/Sprites.tsx @@ -1,6 +1,6 @@ import React, { FC } from 'react'; -const Sprites: FC<{}> = () => ( +const Sprites: FC = () => ( = () => ( + + + + + + + + + + From 971e222d6bb5f03ad642d7acbbee30929b49b400 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Mar 2021 17:21:27 +0700 Subject: [PATCH 17/20] #23 fixed lab post appearance --- src/components/lab/LabBottomPanel/index.tsx | 44 ++++++++++++------- .../lab/LabBottomPanel/styles.module.scss | 10 ++--- src/components/lab/LabPad/index.tsx | 12 +++-- 3 files changed, 42 insertions(+), 24 deletions(-) diff --git a/src/components/lab/LabBottomPanel/index.tsx b/src/components/lab/LabBottomPanel/index.tsx index e1789a98..5139686a 100644 --- a/src/components/lab/LabBottomPanel/index.tsx +++ b/src/components/lab/LabBottomPanel/index.tsx @@ -1,4 +1,4 @@ -import React, { FC } from 'react'; +import React, { FC, useCallback } from 'react'; import { Group } from '~/components/containers/Group'; import { Filler } from '~/components/containers/Filler'; import styles from './styles.module.scss'; @@ -7,6 +7,8 @@ import { INode } from '~/redux/types'; import { Icon } from '~/components/input/Icon'; import classNames from 'classnames'; import { Grid } from '~/components/containers/Grid'; +import { useHistory } from 'react-router'; +import { URLS } from '~/constants/urls'; type Props = { node: INode; @@ -15,21 +17,33 @@ type Props = { commentCount: number; }; -const LabBottomPanel: FC = ({ node, hasNewComments, commentCount }) => ( - -
{getPrettyDate(node.created_at)}
- +const LabBottomPanel: FC = ({ node, hasNewComments, commentCount }) => { + const history = useHistory(); + const onClick = useCallback(() => history.push(URLS.NODE_URL(node.id)), [node.id]); - - - {node.like_count} - + return ( + +
{getPrettyDate(node.created_at)}
+ - - - {commentCount} - -
-); + {commentCount > 0 && ( + + + {commentCount} + + )} + + {!!node.like_count && node.like_count > 0 && ( + + + {node.like_count} + + )} + + ); +}; export { LabBottomPanel }; diff --git a/src/components/lab/LabBottomPanel/styles.module.scss b/src/components/lab/LabBottomPanel/styles.module.scss index 0a4be156..09a69c46 100644 --- a/src/components/lab/LabBottomPanel/styles.module.scss +++ b/src/components/lab/LabBottomPanel/styles.module.scss @@ -9,19 +9,17 @@ color: darken(white, 40%); } -.comments.comments { +.comments, .like { flex: 0; - font: $font_16_semibold; + font: $font_14_semibold; color: darken(white, 50%); fill: currentColor; stroke: none; column-gap: $gap / 2 !important; + align-items: center; + justify-content: center; &.active { color: $red; } } - -.like { - -} diff --git a/src/components/lab/LabPad/index.tsx b/src/components/lab/LabPad/index.tsx index 5432ad99..5d853a39 100644 --- a/src/components/lab/LabPad/index.tsx +++ b/src/components/lab/LabPad/index.tsx @@ -1,8 +1,14 @@ -import React, { FC } from 'react'; +import React, { FC, useCallback } from 'react'; import styles from './styles.module.scss'; +import { useHistory } from 'react-router'; +import { URLS } from '~/constants/urls'; +import { INodeComponentProps } from '~/redux/node/constants'; -interface IProps {} +const LabPad: FC = ({ node }) => { + const history = useHistory(); + const onClick = useCallback(() => history.push(URLS.NODE_URL(node.id)), [node.id]); -const LabPad: FC = () =>
; + return
; +}; export { LabPad }; From 462c27ee897e4b4a9f8633e16400c4f9acb38d00 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Mar 2021 17:47:56 +0700 Subject: [PATCH 18/20] #23 added heroic lab icon --- src/components/lab/LabNodeTitle/index.tsx | 15 +++++++++++++-- .../lab/LabNodeTitle/styles.module.scss | 5 +++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/components/lab/LabNodeTitle/index.tsx b/src/components/lab/LabNodeTitle/index.tsx index 058223c9..b44533de 100644 --- a/src/components/lab/LabNodeTitle/index.tsx +++ b/src/components/lab/LabNodeTitle/index.tsx @@ -3,6 +3,9 @@ import { INode } from '~/redux/types'; import styles from './styles.module.scss'; import { URLS } from '~/constants/urls'; import { Link } from 'react-router-dom'; +import { Group } from '~/components/containers/Group'; +import { Icon } from '~/components/input/Icon'; +import Tippy from '@tippy.js/react'; interface IProps { node: INode; @@ -12,11 +15,19 @@ const LabNodeTitle: FC = ({ node }) => { if (!node.title) return null; return ( -
+
{node.title || '...'}
-
+ + {node.is_heroic && ( + +
+ +
+
+ )} + ); }; diff --git a/src/components/lab/LabNodeTitle/styles.module.scss b/src/components/lab/LabNodeTitle/styles.module.scss index 008e00f6..f9ee925c 100644 --- a/src/components/lab/LabNodeTitle/styles.module.scss +++ b/src/components/lab/LabNodeTitle/styles.module.scss @@ -22,3 +22,8 @@ font: $font_20_semibold; } } + +.star { + fill: $yellow; + flex: 0 0 24px; +} From 8a9a9b9104eaae5e7c09c6fbd431043461e4e99b Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Mar 2021 17:48:34 +0700 Subject: [PATCH 19/20] #23 removed lab head --- src/components/lab/LabHead/index.tsx | 32 ++++++++++++++++------------ 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/components/lab/LabHead/index.tsx b/src/components/lab/LabHead/index.tsx index 1f61048f..cce1ff2a 100644 --- a/src/components/lab/LabHead/index.tsx +++ b/src/components/lab/LabHead/index.tsx @@ -6,22 +6,26 @@ interface IProps { isLoading?: boolean; } -const LabHead: FC = ({ isLoading }) => ( -
-
- - Свежие - +const LabHead: FC = ({ isLoading }) => { + return null; - - Популярные - + return ( +
+
+ + Свежие + - - Важные - + + Популярные + + + + Важные + +
-
-); + ); +}; export { LabHead }; From 998a2e305a1b3dfdb17f9f9dce3822ef043bb121 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Wed, 24 Mar 2021 17:56:03 +0700 Subject: [PATCH 20/20] #23 lab doesn't require superpowers now --- .../containers/Authorized/index.tsx | 15 +++++++ .../editors/EditorPublicSwitch/index.tsx | 44 +++++++++---------- src/components/main/Header/index.tsx | 13 +++--- 3 files changed, 42 insertions(+), 30 deletions(-) create mode 100644 src/components/containers/Authorized/index.tsx diff --git a/src/components/containers/Authorized/index.tsx b/src/components/containers/Authorized/index.tsx new file mode 100644 index 00000000..e0b6085b --- /dev/null +++ b/src/components/containers/Authorized/index.tsx @@ -0,0 +1,15 @@ +import React, { FC } from 'react'; +import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; +import { selectUser } from '~/redux/auth/selectors'; + +interface IProps {} + +const Authorized: FC = ({ children }) => { + const user = useShallowSelect(selectUser); + + if (!user.is_user) return null; + + return <>{children}; +}; + +export { Authorized }; diff --git a/src/components/editors/EditorPublicSwitch/index.tsx b/src/components/editors/EditorPublicSwitch/index.tsx index 71c1fef2..627316fb 100644 --- a/src/components/editors/EditorPublicSwitch/index.tsx +++ b/src/components/editors/EditorPublicSwitch/index.tsx @@ -14,29 +14,27 @@ const EditorPublicSwitch: FC = ({ data, setData }) => { ]); return ( - - - + ); }; diff --git a/src/components/main/Header/index.tsx b/src/components/main/Header/index.tsx index 3f6cd6d9..21eb7cea 100644 --- a/src/components/main/Header/index.tsx +++ b/src/components/main/Header/index.tsx @@ -1,15 +1,14 @@ -import React, { FC, useCallback, memo, useState, useEffect, useMemo } from 'react'; +import React, { FC, memo, useCallback, useEffect, useMemo, useState } from 'react'; import { connect } from 'react-redux'; import { push as historyPush } from 'connected-react-router'; import { Link } from 'react-router-dom'; import { Logo } from '~/components/main/Logo'; import { Filler } from '~/components/containers/Filler'; -import { selectUser, selectAuthUpdates } from '~/redux/auth/selectors'; +import { selectAuthUpdates, selectUser } from '~/redux/auth/selectors'; import { Group } from '~/components/containers/Group'; import { DIALOGS } from '~/redux/modal/constants'; -import { pick } from 'ramda'; -import { path } from 'ramda'; +import { path, pick } from 'ramda'; import { UserButton } from '../UserButton'; import { Notifications } from '../Notifications'; import { URLS } from '~/constants/urls'; @@ -21,7 +20,7 @@ import * as MODAL_ACTIONS from '~/redux/modal/actions'; import * as AUTH_ACTIONS from '~/redux/auth/actions'; import { IState } from '~/redux/store'; import isBefore from 'date-fns/isBefore'; -import { Superpower } from '~/components/boris/Superpower'; +import { Authorized } from '~/components/containers/Authorized'; const mapStateToProps = (state: IState) => ({ user: pick(['username', 'is_user', 'photo', 'last_seen_boris'])(selectUser(state)), @@ -90,14 +89,14 @@ const HeaderUnconnected: FC = memo( ФЛОУ - + ЛАБ - +