1
0
Fork 0
mirror of https://github.com/muerwre/vault-frontend.git synced 2025-04-24 20:36:40 +07:00

added months passed to comments

This commit is contained in:
Fedor Katurov 2022-07-15 16:45:59 +07:00
parent e9a1a624fd
commit 3dfd886570
7 changed files with 111 additions and 9 deletions

View file

@ -1,8 +1,10 @@
import React, { FC, HTMLAttributes, memo } from 'react'; import React, { FC, HTMLAttributes, memo } from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { parseISO } from 'date-fns';
import { CommentContent } from '~/components/comment/CommentContent'; import { CommentContent } from '~/components/comment/CommentContent';
import { CommentDistance } from '~/components/comment/CommentDistance';
import { CommentWrapper } from '~/components/containers/CommentWrapper'; import { CommentWrapper } from '~/components/containers/CommentWrapper';
import { NEW_COMMENT_CLASSNAME } from '~/constants/comment'; import { NEW_COMMENT_CLASSNAME } from '~/constants/comment';
import { IComment, ICommentGroup, IFile } from '~/types'; import { IComment, ICommentGroup, IFile } from '~/types';
@ -11,7 +13,6 @@ import { CommendDeleted } from '../../node/CommendDeleted';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
type IProps = HTMLAttributes<HTMLDivElement> & { type IProps = HTMLAttributes<HTMLDivElement> & {
nodeId: number; nodeId: number;
isEmpty?: boolean; isEmpty?: boolean;
@ -50,13 +51,25 @@ const Comment: FC<IProps> = memo(
{...props} {...props}
> >
<div className={styles.wrap}> <div className={styles.wrap}>
{group.comments.map(comment => { {group.comments.map((comment, index) => {
if (comment.deleted_at) { if (comment.deleted_at) {
return <CommendDeleted id={comment.id} onDelete={onDelete} key={comment.id} />; return <CommendDeleted id={comment.id} onDelete={onDelete} key={comment.id} />;
} }
return ( return (
<CommentContent <CommentContent
prefix={
group.distancesInDays[index] > 9 && (
<CommentDistance
firstDate={comment?.created_at ? parseISO(comment.created_at) : undefined}
secondDate={
index > 0 && group.comments[index - 1]?.created_at
? parseISO(group.comments[index - 1].created_at!)
: undefined
}
/>
)
}
saveComment={saveComment} saveComment={saveComment}
nodeId={nodeId} nodeId={nodeId}
comment={comment} comment={comment}

View file

@ -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';
import classNames from 'classnames'; import classNames from 'classnames';
@ -18,6 +27,7 @@ import { CommentMenu } from '../CommentMenu';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
interface IProps { interface IProps {
prefix?: ReactNode;
nodeId: number; nodeId: number;
comment: IComment; comment: IComment;
canEdit: boolean; canEdit: boolean;
@ -27,7 +37,7 @@ interface IProps {
} }
const CommentContent: FC<IProps> = memo( const CommentContent: FC<IProps> = memo(
({ comment, canEdit, nodeId, saveComment, onDelete, onShowImageModal }) => { ({ comment, canEdit, nodeId, saveComment, onDelete, onShowImageModal, prefix }) => {
const [isEditing, setIsEditing] = useState(false); const [isEditing, setIsEditing] = useState(false);
const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]); const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]);
@ -74,8 +84,10 @@ const CommentContent: FC<IProps> = memo(
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
{comment.text && ( {comment.text.trim() && (
<Group className={classnames(styles.block, styles.block_text)}> <Group className={classnames(styles.block, styles.block_text)}>
{!!prefix && <div className={styles.prefix}>{prefix}</div>}
{menu} {menu}
<Group className={styles.renderers}> <Group className={styles.renderers}>

View file

@ -63,7 +63,6 @@
padding-bottom: 10px; padding-bottom: 10px;
box-sizing: border-box; box-sizing: border-box;
flex-direction: column; flex-direction: column;
// padding: $gap 0;
&:first-child { &:first-child {
border-top-right-radius: $radius; border-top-right-radius: $radius;
@ -162,3 +161,11 @@
width: 100%; width: 100%;
margin: 0 !important; margin: 0 !important;
} }
.prefix {
position: absolute;
top: 0;
left: 0;
right: 0;
transform: translate(50%, -50%);
}

View file

@ -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<CommentDistanceProps> = 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 <div className={styles.bar}>прошло {distance}</div>;
});
export { CommentDistance };

View file

@ -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;
}

View file

@ -1,5 +1,3 @@
import { DetailedHTMLProps, InputHTMLAttributes, ReactElement } from 'react';
import { ERRORS } from '~/constants/errors'; import { ERRORS } from '~/constants/errors';
import { IUser } from '~/types/auth'; import { IUser } from '~/types/auth';
@ -126,6 +124,7 @@ export type IMessage = Omit<IComment, 'user' | 'node'> & {
export interface ICommentGroup { export interface ICommentGroup {
user: IUser; user: IUser;
comments: IComment[]; comments: IComment[];
distancesInDays: number[];
ids: IComment['id'][]; ids: IComment['id'][];
hasNew: boolean; hasNew: boolean;
} }

View file

@ -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 { IComment, ICommentGroup } from '~/types';
import { curry, insert, nth, path, remove } from '~/utils/ramda'; import { curry, insert, nth, path, remove } from '~/utils/ramda';
@ -22,6 +22,21 @@ const compareCommentDates = (commentDateValue?: string, lastSeenDateValue?: stri
return isAfter(commentDate, lastSeenDate); 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) => ( export const groupCommentsByUser = (lastSeen?: string) => (
grouppedComments: ICommentGroup[], grouppedComments: ICommentGroup[],
comment: IComment comment: IComment
@ -40,6 +55,7 @@ export const groupCommentsByUser = (lastSeen?: string) => (
{ {
user: comment.user, user: comment.user,
comments: [comment], comments: [comment],
distancesInDays: [0],
ids: [comment.id], ids: [comment.id],
hasNew: compareCommentDates(comment.created_at, lastSeen), hasNew: compareCommentDates(comment.created_at, lastSeen),
}, },
@ -49,6 +65,13 @@ export const groupCommentsByUser = (lastSeen?: string) => (
...grouppedComments.slice(0, grouppedComments.length - 1), ...grouppedComments.slice(0, grouppedComments.length - 1),
{ {
...last, ...last,
distancesInDays: [
...last.distancesInDays,
getCommentDistance(
comment?.created_at,
last.comments[last.comments.length - 1]?.created_at
),
],
comments: [...last.comments, comment], comments: [...last.comments, comment],
ids: [...last.ids, comment.id], ids: [...last.ids, comment.id],
hasNew: last.hasNew || compareCommentDates(comment.created_at, lastSeen), hasNew: last.hasNew || compareCommentDates(comment.created_at, lastSeen),