From 3dfd8865704d0272aaca907ac512d82045dd5325 Mon Sep 17 00:00:00 2001 From: Fedor Katurov Date: Fri, 15 Jul 2022 16:45:59 +0700 Subject: [PATCH] added months passed to comments --- src/components/comment/Comment/index.tsx | 17 +++++++-- .../comment/CommentContent/index.tsx | 18 ++++++++-- .../comment/CommentContent/styles.module.scss | 9 ++++- .../comment/CommentDistance/index.tsx | 36 +++++++++++++++++++ .../CommentDistance/styles.module.scss | 12 +++++++ src/types/index.ts | 3 +- src/utils/fn.ts | 25 ++++++++++++- 7 files changed, 111 insertions(+), 9 deletions(-) create mode 100644 src/components/comment/CommentDistance/index.tsx create mode 100644 src/components/comment/CommentDistance/styles.module.scss diff --git a/src/components/comment/Comment/index.tsx b/src/components/comment/Comment/index.tsx index ebb14097..0dd9c1ac 100644 --- a/src/components/comment/Comment/index.tsx +++ b/src/components/comment/Comment/index.tsx @@ -1,8 +1,10 @@ import React, { FC, HTMLAttributes, memo } from 'react'; import classNames from 'classnames'; +import { parseISO } from 'date-fns'; import { CommentContent } from '~/components/comment/CommentContent'; +import { CommentDistance } from '~/components/comment/CommentDistance'; import { CommentWrapper } from '~/components/containers/CommentWrapper'; import { NEW_COMMENT_CLASSNAME } from '~/constants/comment'; import { IComment, ICommentGroup, IFile } from '~/types'; @@ -11,7 +13,6 @@ import { CommendDeleted } from '../../node/CommendDeleted'; import styles from './styles.module.scss'; - type IProps = HTMLAttributes & { nodeId: number; isEmpty?: boolean; @@ -50,13 +51,25 @@ const Comment: FC = memo( {...props} >
- {group.comments.map(comment => { + {group.comments.map((comment, index) => { if (comment.deleted_at) { return ; } return ( 9 && ( + 0 && group.comments[index - 1]?.created_at + ? parseISO(group.comments[index - 1].created_at!) + : undefined + } + /> + ) + } saveComment={saveComment} nodeId={nodeId} comment={comment} diff --git a/src/components/comment/CommentContent/index.tsx b/src/components/comment/CommentContent/index.tsx index dbaec5e5..a3bd4a22 100644 --- a/src/components/comment/CommentContent/index.tsx +++ b/src/components/comment/CommentContent/index.tsx @@ -1,4 +1,13 @@ -import React, { createElement, FC, Fragment, memo, useCallback, useMemo, useState } from 'react'; +import React, { + createElement, + FC, + Fragment, + memo, + ReactNode, + useCallback, + useMemo, + useState, +} from 'react'; import classnames from 'classnames'; import classNames from 'classnames'; @@ -18,6 +27,7 @@ import { CommentMenu } from '../CommentMenu'; import styles from './styles.module.scss'; interface IProps { + prefix?: ReactNode; nodeId: number; comment: IComment; canEdit: boolean; @@ -27,7 +37,7 @@ interface IProps { } const CommentContent: FC = memo( - ({ comment, canEdit, nodeId, saveComment, onDelete, onShowImageModal }) => { + ({ comment, canEdit, nodeId, saveComment, onDelete, onShowImageModal, prefix }) => { const [isEditing, setIsEditing] = useState(false); const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]); @@ -74,8 +84,10 @@ const CommentContent: FC = memo( return (
- {comment.text && ( + {comment.text.trim() && ( + {!!prefix &&
{prefix}
} + {menu} diff --git a/src/components/comment/CommentContent/styles.module.scss b/src/components/comment/CommentContent/styles.module.scss index b307d8e3..d9723ace 100644 --- a/src/components/comment/CommentContent/styles.module.scss +++ b/src/components/comment/CommentContent/styles.module.scss @@ -63,7 +63,6 @@ padding-bottom: 10px; box-sizing: border-box; flex-direction: column; - // padding: $gap 0; &:first-child { border-top-right-radius: $radius; @@ -162,3 +161,11 @@ width: 100%; margin: 0 !important; } + +.prefix { + position: absolute; + top: 0; + left: 0; + right: 0; + transform: translate(50%, -50%); +} diff --git a/src/components/comment/CommentDistance/index.tsx b/src/components/comment/CommentDistance/index.tsx new file mode 100644 index 00000000..d532edcd --- /dev/null +++ b/src/components/comment/CommentDistance/index.tsx @@ -0,0 +1,36 @@ +import React, { FC, memo, useMemo } from 'react'; + +import { differenceInDays, formatDistance } from 'date-fns'; +import ru from 'date-fns/locale/ru'; + +import styles from './styles.module.scss'; + +interface CommentDistanceProps { + firstDate?: Date; + secondDate?: Date; +} + +const CommentDistance: FC = memo(({ firstDate, secondDate }) => { + const distance = useMemo(() => { + if (!firstDate || !secondDate) { + return undefined; + } + + if (differenceInDays(secondDate, firstDate) < 30) { + return undefined; + } + + return formatDistance(secondDate, firstDate, { + locale: ru, + addSuffix: false, + }); + }, []); + + if (!distance) { + return null; + } + + return
прошло {distance}
; +}); + +export { CommentDistance }; diff --git a/src/components/comment/CommentDistance/styles.module.scss b/src/components/comment/CommentDistance/styles.module.scss new file mode 100644 index 00000000..fc566447 --- /dev/null +++ b/src/components/comment/CommentDistance/styles.module.scss @@ -0,0 +1,12 @@ +@import "src/styles/variables"; + +.bar { + @include inner_shadow; + + font: $font_12_regular; + color: darken(white, 50%); + background: $content_bg; + display: inline-flex; + padding: 1px 10px 3px; + border-radius: 12px; +} diff --git a/src/types/index.ts b/src/types/index.ts index dca30260..eb057215 100644 --- a/src/types/index.ts +++ b/src/types/index.ts @@ -1,5 +1,3 @@ -import { DetailedHTMLProps, InputHTMLAttributes, ReactElement } from 'react'; - import { ERRORS } from '~/constants/errors'; import { IUser } from '~/types/auth'; @@ -126,6 +124,7 @@ export type IMessage = Omit & { export interface ICommentGroup { user: IUser; comments: IComment[]; + distancesInDays: number[]; ids: IComment['id'][]; hasNew: boolean; } diff --git a/src/utils/fn.ts b/src/utils/fn.ts index 7a96f1a3..53b461be 100644 --- a/src/utils/fn.ts +++ b/src/utils/fn.ts @@ -1,4 +1,4 @@ -import { isAfter, isValid, parseISO } from 'date-fns'; +import { differenceInDays, isAfter, isValid, parseISO } from 'date-fns'; import { IComment, ICommentGroup } from '~/types'; import { curry, insert, nth, path, remove } from '~/utils/ramda'; @@ -22,6 +22,21 @@ const compareCommentDates = (commentDateValue?: string, lastSeenDateValue?: stri return isAfter(commentDate, lastSeenDate); }; +const getCommentDistance = (firstDate?: string, secondDate?: string) => { + try { + if (!firstDate || !secondDate) { + return 0; + } + + const first = parseISO(firstDate); + const second = parseISO(secondDate); + + return differenceInDays(second, first); + } catch (e) { + return 0; + } +}; + export const groupCommentsByUser = (lastSeen?: string) => ( grouppedComments: ICommentGroup[], comment: IComment @@ -40,6 +55,7 @@ export const groupCommentsByUser = (lastSeen?: string) => ( { user: comment.user, comments: [comment], + distancesInDays: [0], ids: [comment.id], hasNew: compareCommentDates(comment.created_at, lastSeen), }, @@ -49,6 +65,13 @@ export const groupCommentsByUser = (lastSeen?: string) => ( ...grouppedComments.slice(0, grouppedComments.length - 1), { ...last, + distancesInDays: [ + ...last.distancesInDays, + getCommentDistance( + comment?.created_at, + last.comments[last.comments.length - 1]?.created_at + ), + ], comments: [...last.comments, comment], ids: [...last.ids, comment.id], hasNew: last.hasNew || compareCommentDates(comment.created_at, lastSeen),