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:
parent
e9a1a624fd
commit
3dfd886570
7 changed files with 111 additions and 9 deletions
|
@ -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<HTMLDivElement> & {
|
||||
nodeId: number;
|
||||
isEmpty?: boolean;
|
||||
|
@ -50,13 +51,25 @@ const Comment: FC<IProps> = memo(
|
|||
{...props}
|
||||
>
|
||||
<div className={styles.wrap}>
|
||||
{group.comments.map(comment => {
|
||||
{group.comments.map((comment, index) => {
|
||||
if (comment.deleted_at) {
|
||||
return <CommendDeleted id={comment.id} onDelete={onDelete} key={comment.id} />;
|
||||
}
|
||||
|
||||
return (
|
||||
<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}
|
||||
nodeId={nodeId}
|
||||
comment={comment}
|
||||
|
|
|
@ -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<IProps> = 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<IProps> = memo(
|
|||
|
||||
return (
|
||||
<div className={styles.wrap}>
|
||||
{comment.text && (
|
||||
{comment.text.trim() && (
|
||||
<Group className={classnames(styles.block, styles.block_text)}>
|
||||
{!!prefix && <div className={styles.prefix}>{prefix}</div>}
|
||||
|
||||
{menu}
|
||||
|
||||
<Group className={styles.renderers}>
|
||||
|
|
|
@ -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%);
|
||||
}
|
||||
|
|
36
src/components/comment/CommentDistance/index.tsx
Normal file
36
src/components/comment/CommentDistance/index.tsx
Normal 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 };
|
12
src/components/comment/CommentDistance/styles.module.scss
Normal file
12
src/components/comment/CommentDistance/styles.module.scss
Normal 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;
|
||||
}
|
|
@ -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<IComment, 'user' | 'node'> & {
|
|||
export interface ICommentGroup {
|
||||
user: IUser;
|
||||
comments: IComment[];
|
||||
distancesInDays: number[];
|
||||
ids: IComment['id'][];
|
||||
hasNew: boolean;
|
||||
}
|
||||
|
|
|
@ -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),
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue