diff --git a/src/components/comment/Comment/index.tsx b/src/components/comment/Comment/index.tsx index 6ee92c31..622103e8 100644 --- a/src/components/comment/Comment/index.tsx +++ b/src/components/comment/Comment/index.tsx @@ -31,10 +31,10 @@ const Comment: FC = memo( return (
diff --git a/src/components/comment/CommentAvatar/index.tsx b/src/components/comment/CommentAvatar/index.tsx index 4477d091..b027469b 100644 --- a/src/components/comment/CommentAvatar/index.tsx +++ b/src/components/comment/CommentAvatar/index.tsx @@ -1,27 +1,59 @@ -import React, { FC, useCallback } from 'react'; -import { getURLFromString } from '~/utils/dom'; -import { PRESETS } from '~/constants/urls'; +import React, { FC, useCallback, useState } from 'react'; +import { IUser } from '~/redux/auth/types'; +import { Avatar } from '~/components/common/Avatar'; +import { path } from 'ramda'; +import { Manager, Popper, Reference } from 'react-popper'; import styles from './styles.module.scss'; -import classNames from 'classnames'; -import { openUserProfile } from '~/utils/user'; +import { useRandomPhrase } from '~/constants/phrases'; interface Props { - url?: string; - username?: string; - size?: number; + user: IUser; + withDetails: boolean; className?: string; } -const CommentAvatar: FC = ({ url, username, size, className }) => { - const backgroundImage = !!url ? `url('${getURLFromString(url, PRESETS.avatar)}')` : undefined; - const onOpenProfile = useCallback(() => openUserProfile(username), [username]); +const modifiers = [ + { + name: 'offset', + options: { + offset: [0, 10], + }, + }, +]; + +const CommentAvatar: FC = ({ user, withDetails, className }) => { + const [hovered, setHovered] = useState(false); + const randomPhrase = useRandomPhrase('USER_DESCRIPTION'); + + const onMouseOver = useCallback(() => setHovered(true), [setHovered]); + const onMouseOut = useCallback(() => setHovered(false), [setHovered]); return ( -
+ + + {({ ref }) => ( + + )} + + + {hovered && withDetails && ( + + {({ style, ref }) => ( +
+

{user.fullname || user.username}

+
{user.description || randomPhrase}
+
+ )} +
+ )} +
); }; diff --git a/src/components/comment/CommentAvatar/styles.module.scss b/src/components/comment/CommentAvatar/styles.module.scss index 5ff1bbf9..324189ae 100644 --- a/src/components/comment/CommentAvatar/styles.module.scss +++ b/src/components/comment/CommentAvatar/styles.module.scss @@ -1,19 +1,33 @@ -@import "~/styles/variables"; +@import "~/styles/variables.scss"; -.avatar { +@keyframes appear { + 0% { opacity: 0 } + 100% { opacity: 1 } +} + +.popper { @include outer_shadow; - width: $comment_height; - height: $comment_height; - background-color: transparentize(black, 0.9); - flex-shrink: 0; - overflow: hidden; + background-color: darken($content_bg, 4%); + padding: $gap; + box-sizing:border-box; + z-index: 4; + touch-action: none; + pointer-events: none; border-radius: $radius; - background-position: center; - background-size: cover; - cursor: pointer; - - img { - object-fit: cover; - } + animation: appear forwards 250ms; +} + +.username { + font: $font_18_semibold; + line-height: 1.25em; +} + +.description { + @include clamp(2, 12px); + + font: $font_12_regular; + opacity: 0.5; + margin-top: 3px; + line-height: 1.25em; } diff --git a/src/components/common/Avatar/index.tsx b/src/components/common/Avatar/index.tsx new file mode 100644 index 00000000..538ccc3a --- /dev/null +++ b/src/components/common/Avatar/index.tsx @@ -0,0 +1,31 @@ +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'; +import { DivProps } from '~/utils/types'; + +interface Props extends DivProps { + url?: string; + username?: string; + size?: number; + innerRef?: React.Ref; +} + +const Avatar: FC = ({ url, username, size, className, innerRef, ...rest }) => { + const backgroundImage = !!url ? `url('${getURLFromString(url, PRESETS.avatar)}')` : undefined; + const onOpenProfile = useCallback(() => openUserProfile(username), [username]); + + return ( +
+ ); +}; + +export { Avatar }; diff --git a/src/components/common/Avatar/styles.module.scss b/src/components/common/Avatar/styles.module.scss new file mode 100644 index 00000000..5ff1bbf9 --- /dev/null +++ b/src/components/common/Avatar/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/containers/CommentWrapper/index.tsx b/src/components/containers/CommentWrapper/index.tsx index a8c2cb3d..2f80e466 100644 --- a/src/components/containers/CommentWrapper/index.tsx +++ b/src/components/containers/CommentWrapper/index.tsx @@ -1,37 +1,40 @@ -import React, { FC, HTMLAttributes } from 'react'; +import React, { FC } from 'react'; import classNames from 'classnames'; import styles from './styles.module.scss'; import { IUser } from '~/redux/auth/types'; import { path } from 'ramda'; import { CommentAvatar } from '~/components/comment/CommentAvatar'; -import { Card } from '~/components/containers/Card'; +import { DivProps } from '~/utils/types'; -type IProps = HTMLAttributes & { +type IProps = DivProps & { user: IUser; - is_empty?: boolean; - is_loading?: boolean; - is_same?: boolean; + isEmpty?: boolean; + isLoading?: boolean; + isSame?: boolean; + isForm?: boolean; }; const CommentWrapper: FC = ({ - // photo, - children, - is_empty, - is_loading, - className, - is_same, user, + className, + isEmpty, + isLoading, + isSame, + isForm, + children, ...props }) => ( -
+
- - +
~{path(['username'], user)}
diff --git a/src/components/node/NodeAuthorBlock/index.tsx b/src/components/node/NodeAuthorBlock/index.tsx index c4b97dc6..9e05d03e 100644 --- a/src/components/node/NodeAuthorBlock/index.tsx +++ b/src/components/node/NodeAuthorBlock/index.tsx @@ -1,7 +1,7 @@ import React, { FC, useCallback } from 'react'; import { INode } from '~/redux/types'; import styles from './styles.module.scss'; -import { CommentAvatar } from '~/components/comment/CommentAvatar'; +import { Avatar } from '~/components/common/Avatar'; import { openUserProfile } from '~/utils/user'; import { useRandomPhrase } from '~/constants/phrases'; @@ -24,7 +24,7 @@ const NodeAuthorBlock: FC = ({ node }) => { return (
- +
{fullname || username}
diff --git a/src/components/node/NodeCommentForm/index.tsx b/src/components/node/NodeCommentForm/index.tsx index b60df5f4..2635346c 100644 --- a/src/components/node/NodeCommentForm/index.tsx +++ b/src/components/node/NodeCommentForm/index.tsx @@ -16,7 +16,7 @@ type IProps = ReturnType & { const NodeCommentFormUnconnected: FC = ({ user, isBefore, nodeId }) => { return ( - + ); diff --git a/src/components/node/NodeRelatedItem/index.tsx b/src/components/node/NodeRelatedItem/index.tsx index 04e974bc..18d3b5f1 100644 --- a/src/components/node/NodeRelatedItem/index.tsx +++ b/src/components/node/NodeRelatedItem/index.tsx @@ -5,7 +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'; +import { Avatar } from '~/components/common/Avatar'; type IProps = RouteComponentProps & { item: Partial; @@ -69,7 +69,7 @@ const NodeRelatedItemUnconnected: FC = memo(({ item, history }) => { onClick={onClick} ref={ref} > - , + HTMLDivElement +>;