diff --git a/src/components/comment/CommentAvatar/index.tsx b/src/components/comment/CommentAvatar/index.tsx new file mode 100644 index 00000000..4477d091 --- /dev/null +++ b/src/components/comment/CommentAvatar/index.tsx @@ -0,0 +1,28 @@ +import React, { FC, useCallback } from 'react'; +import { getURLFromString } from '~/utils/dom'; +import { PRESETS } from '~/constants/urls'; +import styles from './styles.module.scss'; +import classNames from 'classnames'; +import { openUserProfile } from '~/utils/user'; + +interface Props { + url?: string; + username?: string; + size?: number; + className?: string; +} + +const CommentAvatar: FC = ({ url, username, size, className }) => { + const backgroundImage = !!url ? `url('${getURLFromString(url, PRESETS.avatar)}')` : undefined; + const onOpenProfile = useCallback(() => openUserProfile(username), [username]); + + return ( +
+ ); +}; + +export { CommentAvatar }; diff --git a/src/components/comment/CommentAvatar/styles.module.scss b/src/components/comment/CommentAvatar/styles.module.scss new file mode 100644 index 00000000..5ff1bbf9 --- /dev/null +++ b/src/components/comment/CommentAvatar/styles.module.scss @@ -0,0 +1,19 @@ +@import "~/styles/variables"; + +.avatar { + @include outer_shadow; + + width: $comment_height; + height: $comment_height; + background-color: transparentize(black, 0.9); + flex-shrink: 0; + overflow: hidden; + border-radius: $radius; + background-position: center; + background-size: cover; + cursor: pointer; + + img { + object-fit: cover; + } +} diff --git a/src/components/comment/CommentContent/styles.module.scss b/src/components/comment/CommentContent/styles.module.scss index ac9a4bcf..650e7e8f 100644 --- a/src/components/comment/CommentContent/styles.module.scss +++ b/src/components/comment/CommentContent/styles.module.scss @@ -3,6 +3,7 @@ .wrap { position: relative; + @include row_shadow; } .lock, @@ -51,13 +52,10 @@ .edit { top: 28px; - background: blue; } .block { - @include outer_shadow(); min-height: $comment_height; - // box-shadow: inset rgba(255, 255, 255, 0.05) 1px 1px, inset rgba(0, 0, 0, 0.1) -1px -1px; display: flex; align-items: flex-start; justify-content: flex-start; @@ -108,7 +106,7 @@ .date { position: absolute; - bottom: 0; + bottom: 1px; right: 0; font: $font_12_regular; color: transparentize($color: white, $amount: 0.8); diff --git a/src/components/comment/CommentEmbedBlock/styles.module.scss b/src/components/comment/CommentEmbedBlock/styles.module.scss index fe34a541..3c3d3a18 100644 --- a/src/components/comment/CommentEmbedBlock/styles.module.scss +++ b/src/components/comment/CommentEmbedBlock/styles.module.scss @@ -43,7 +43,7 @@ left: 0; width: 100%; height: 100%; - background: transparentize($comment_bg, 0.15) 50% 50%; + background: transparentize($content_bg, 0.15) 50% 50%; background-size: cover; z-index: 15; border-radius: $radius; diff --git a/src/components/comment/CommentForm/styles.module.scss b/src/components/comment/CommentForm/styles.module.scss index fb629c05..57f6e464 100644 --- a/src/components/comment/CommentForm/styles.module.scss +++ b/src/components/comment/CommentForm/styles.module.scss @@ -10,10 +10,9 @@ } .input { - @include outer_shadow(); position: relative; flex: 1; - padding: ($gap / 2) ($gap / 2 + 1px); + padding: 5px; } .buttons { diff --git a/src/components/containers/CommentWrapper/index.tsx b/src/components/containers/CommentWrapper/index.tsx index 959befea..a8c2cb3d 100644 --- a/src/components/containers/CommentWrapper/index.tsx +++ b/src/components/containers/CommentWrapper/index.tsx @@ -2,14 +2,12 @@ import React, { FC, HTMLAttributes } from 'react'; import classNames from 'classnames'; import styles from './styles.module.scss'; -import { Card } from '../Card'; import { IUser } from '~/redux/auth/types'; -import { getURL } from '~/utils/dom'; import { path } from 'ramda'; -import { PRESETS } from '~/constants/urls'; +import { CommentAvatar } from '~/components/comment/CommentAvatar'; +import { Card } from '~/components/containers/Card'; type IProps = HTMLAttributes & { - // photo?: string; user: IUser; is_empty?: boolean; is_loading?: boolean; @@ -26,22 +24,19 @@ const CommentWrapper: FC = ({ user, ...props }) => ( - +
-
window.postMessage({ type: 'username', username: user.username }, '*')} /> +
~{path(['username'], user)}
{children}
- +
); export { CommentWrapper }; diff --git a/src/components/containers/CommentWrapper/styles.module.scss b/src/components/containers/CommentWrapper/styles.module.scss index 6587b197..f457a747 100644 --- a/src/components/containers/CommentWrapper/styles.module.scss +++ b/src/components/containers/CommentWrapper/styles.module.scss @@ -1,12 +1,14 @@ @import "src/styles/variables"; .wrap { + @include outer_shadow; + background: $comment_bg; min-height: $comment_height; display: flex; position: relative; - box-shadow: none; min-width: 0; + border-radius: $radius; &:global(.is_empty) { opacity: 0.5; @@ -54,7 +56,7 @@ } } -.thumb_image { +div.thumb_image { height: $comment_height; background: transparentize(white, 0.97) no-repeat 50% 50%; border-radius: $panel_radius 0 0 $panel_radius; @@ -65,6 +67,7 @@ @include tablet { height: 32px; + width: 32px; flex: 0 0 32px; border-radius: $panel_radius; } diff --git a/src/components/containers/TagField/styles.module.scss b/src/components/containers/TagField/styles.module.scss index 4f090f10..d20ec51b 100644 --- a/src/components/containers/TagField/styles.module.scss +++ b/src/components/containers/TagField/styles.module.scss @@ -7,6 +7,6 @@ flex-wrap: wrap; &> * { - margin: 0 $gap $gap 0; + margin: $gap / 2; } } diff --git a/src/components/node/NodeAuthorBlock/index.tsx b/src/components/node/NodeAuthorBlock/index.tsx new file mode 100644 index 00000000..c04205ba --- /dev/null +++ b/src/components/node/NodeAuthorBlock/index.tsx @@ -0,0 +1,32 @@ +import React, { FC, useCallback } from 'react'; +import { INode } from '~/redux/types'; +import styles from './styles.module.scss'; +import { CommentAvatar } from '~/components/comment/CommentAvatar'; +import { openUserProfile } from '~/utils/user'; + +interface Props { + node?: INode; +} + +const NodeAuthorBlock: FC = ({ node }) => { + if (!node?.user) { + return null; + } + + const { fullname, username, description, photo } = node.user; + + const onOpenProfile = useCallback(() => openUserProfile(username), [username]); + + return ( +
+ + +
+
{fullname || username}
+ {description &&
{description}
} +
+
+ ); +}; + +export { NodeAuthorBlock }; diff --git a/src/components/node/NodeAuthorBlock/styles.module.scss b/src/components/node/NodeAuthorBlock/styles.module.scss new file mode 100644 index 00000000..0d400ed7 --- /dev/null +++ b/src/components/node/NodeAuthorBlock/styles.module.scss @@ -0,0 +1,39 @@ +@import "~/styles/variables.scss"; + +div.block { + @include inner_shadow_active; + + cursor: pointer; + background: $inset_bg; + padding: $gap; + border-radius: $radius; + display: flex; + flex-direction: row; + align-items: center; + justify-content: stretch; +} + +.info { +} + +.username { + font: $font_16_semibold; + line-height: 21px; +} + +.description { + @include clamp(3, 12 * 1.25); + + margin-top: 3px; + font: $font_12_regular; + line-height: 1.25em; + opacity: 0.5; +} + +.avatar { + width: 48px; + height: 48px; + margin-right: 10px; + flex-shrink: 0; + align-self: flex-start; +} diff --git a/src/components/node/NodeBottomBlock/index.tsx b/src/components/node/NodeBottomBlock/index.tsx index 46b93212..4caaef51 100644 --- a/src/components/node/NodeBottomBlock/index.tsx +++ b/src/components/node/NodeBottomBlock/index.tsx @@ -12,6 +12,7 @@ import { NodeTagsBlock } from '~/components/node/NodeTagsBlock'; import { INodeRelated } from '~/redux/node/types'; import StickyBox from 'react-sticky-box/dist/esnext'; import styles from './styles.module.scss'; +import { NodeAuthorBlock } from '~/components/node/NodeAuthorBlock'; interface IProps { node: INode; @@ -60,10 +61,17 @@ const NodeBottomBlock: FC = ({
- - - - +
+
+ +
+
+ +
+
+ +
+
diff --git a/src/components/node/NodeBottomBlock/styles.module.scss b/src/components/node/NodeBottomBlock/styles.module.scss index 15ac42d8..36cc8dc1 100644 --- a/src/components/node/NodeBottomBlock/styles.module.scss +++ b/src/components/node/NodeBottomBlock/styles.module.scss @@ -28,7 +28,6 @@ display: flex; align-items: flex-start; justify-content: flex-start; - padding-left: $gap / 2; min-width: 0; position: relative; z-index: 10; @@ -51,3 +50,7 @@ flex: 1; min-width: 0; } + +.left_item { + padding-bottom: $gap * 2; +} diff --git a/src/components/node/NodeImageSwiperBlock/styles.module.scss b/src/components/node/NodeImageSwiperBlock/styles.module.scss index eb3b14de..df90d7b4 100644 --- a/src/components/node/NodeImageSwiperBlock/styles.module.scss +++ b/src/components/node/NodeImageSwiperBlock/styles.module.scss @@ -11,7 +11,7 @@ left: 50%; bottom: $gap * 2; transform: translate(-50%, 0); - background: darken($comment_bg, 4%); + background: darken($content_bg, 4%); width: auto; padding: 5px 10px; border-radius: 10px; diff --git a/src/components/node/NodePanel/styles.module.scss b/src/components/node/NodePanel/styles.module.scss index 9447eaec..1bc39562 100644 --- a/src/components/node/NodePanel/styles.module.scss +++ b/src/components/node/NodePanel/styles.module.scss @@ -1,7 +1,7 @@ @import "src/styles/variables"; .place { - // height: 72px; + @include row_shadow; position: relative; z-index: 3; margin-top: -$radius; diff --git a/src/components/node/NodePanelInner/styles.module.scss b/src/components/node/NodePanelInner/styles.module.scss index e11bbc87..e12e3742 100644 --- a/src/components/node/NodePanelInner/styles.module.scss +++ b/src/components/node/NodePanelInner/styles.module.scss @@ -38,7 +38,6 @@ justify-content: center; box-sizing: border-box; min-width: 0; - background-color: $content_bg; &:global(.stack) { padding: 0 $gap; @@ -59,12 +58,10 @@ justify-content: stretch; border-radius: $radius $radius 0 0; box-sizing: border-box; - padding: $gap $gap; + padding: $gap; height: 64px; min-width: 0; - @include outer_shadow(); - @include tablet { border-radius: 0; height: auto; diff --git a/src/components/node/NodeRelatedItem/index.tsx b/src/components/node/NodeRelatedItem/index.tsx index c3a6903c..04e974bc 100644 --- a/src/components/node/NodeRelatedItem/index.tsx +++ b/src/components/node/NodeRelatedItem/index.tsx @@ -5,6 +5,7 @@ import { INode } from '~/redux/types'; import { PRESETS, URLS } from '~/constants/urls'; import { RouteComponentProps, withRouter } from 'react-router'; import { getURL, stringToColour } from '~/utils/dom'; +import { CommentAvatar } from '~/components/comment/CommentAvatar'; type IProps = RouteComponentProps & { item: Partial; @@ -59,6 +60,8 @@ const NodeRelatedItemUnconnected: FC = memo(({ item, history }) => { return 'small'; }, [width]); + const image = useMemo(() => getURL({ url: item.thumbnail }, PRESETS.avatar), [item.thumbnail]); + return (
= memo(({ item, history }) => { onClick={onClick} ref={ref} > -
{!item.thumbnail && size === 'small' && ( @@ -85,11 +87,7 @@ const NodeRelatedItemUnconnected: FC = memo(({ item, history }) => {
)} - loader setIsLoaded(true)} - /> + loader setIsLoaded(true)} />
); }); diff --git a/src/components/node/NodeRelatedItem/styles.module.scss b/src/components/node/NodeRelatedItem/styles.module.scss index dfe4e5eb..8bd6b8d2 100644 --- a/src/components/node/NodeRelatedItem/styles.module.scss +++ b/src/components/node/NodeRelatedItem/styles.module.scss @@ -16,13 +16,10 @@ } } -.thumb { +div.thumb { position: absolute; width: 100%; height: 100%; - border-radius: $cell_radius; - background: lighten($content_bg, 2%) 50% 50% no-repeat; - background-size: cover; opacity: 0; transition: opacity 0.5s; will-change: opacity; @@ -33,6 +30,8 @@ } .letters, .title { + @include outer_shadow; + position: absolute; display: flex; align-items: center; diff --git a/src/containers/lab/LabStats/styles.module.scss b/src/containers/lab/LabStats/styles.module.scss index 86a04b08..246ed8b2 100644 --- a/src/containers/lab/LabStats/styles.module.scss +++ b/src/containers/lab/LabStats/styles.module.scss @@ -5,7 +5,6 @@ color: darken(white, 50%); text-transform: uppercase; padding: 0 $gap / 2; - padding-bottom: $gap / 2; } .tags.tags { @@ -20,7 +19,7 @@ @include lab_shadow; border-radius: $radius; - background-color: $comment_bg; + background: $comment_bg; padding: $gap; } diff --git a/src/styles/_colors.scss b/src/styles/_colors.scss index 957df9be..18143ded 100644 --- a/src/styles/_colors.scss +++ b/src/styles/_colors.scss @@ -49,7 +49,9 @@ $text_sign: 22px; $input_bg_color: darken($content_bg, 2%); $button_bg_color: $red_gradient; -$comment_bg: lighten($content_bg, 2%); +$inset_bg: linear-gradient(135deg, darken($content_bg, 2%), $content_bg); +$comment_bg: linear-gradient(135deg, $content_bg, lighten($content_bg, 2%)); + $panel_bg: transparent; $node_bg: darken($content_bg, 2%); $node_image_bg: darken($main_bg_color, 4%); diff --git a/src/styles/variables.scss b/src/styles/variables.scss index f19d0f67..7dcd0247 100644 --- a/src/styles/variables.scss +++ b/src/styles/variables.scss @@ -88,11 +88,38 @@ $login_dialog_padding: $gap $gap 30px $gap; $sidebar_border: transparentize(white, 0.95); @mixin outer_shadow() { - box-shadow: inset transparentize(white, 0.95) 0 1px, transparentize(black, 0.8) -1px -1px; + box-shadow: + inset transparentize(white, 0.95) 1px 1px, + transparentize(black, 0.8) 1px 1px, + transparentize(black, 0.6) 0 1px 5px; +} + +@mixin row_shadow() { + &:not(last-child) { + box-shadow: + transparentize(white, 0.95) 0 1px, + inset transparentize(black, 0.8) 0 -1px; + } + + &:only-child { + box-shadow: none; + } } @mixin inner_shadow() { - box-shadow: inset transparentize(white, 0.95) 0 -1px, inset transparentize(black, 0.5) 0 1px; + box-shadow: + inset transparentize(white, 0.92) -1px -1px, + inset transparentize(black, 0.5) 1px 1px, + inset transparentize(black, 0.7) 0 0 10px; +} + +@mixin inner_shadow_active() { + @include inner_shadow; + transition: background-color 250ms; + + &:hover { + background: transparentize(white, 0.95); + } } @mixin input_shadow() { @@ -232,7 +259,8 @@ $sidebar_border: transparentize(white, 0.95); } @mixin lab_shadow { - box-shadow: transparentize(black, 0.5) 0 0 0 1px, + box-shadow: + transparentize(black, 0.5) 0 0 0 1px, inset transparentize(white, 0.9) 0 1px, - lighten(black, 10%) 0 4px; + lighten(black, 0.1) 0 4px; } diff --git a/src/utils/user.ts b/src/utils/user.ts new file mode 100644 index 00000000..3762927d --- /dev/null +++ b/src/utils/user.ts @@ -0,0 +1,7 @@ +export const openUserProfile = (username?: string) => { + if (!username) { + return; + } + + window.postMessage({ type: 'username', username }, '*'); +};