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

feature: added image preview for comments

This commit is contained in:
Fedor Katurov 2020-06-05 17:42:02 +07:00
parent 08f6b518e4
commit 7d3132237d
5 changed files with 80 additions and 63 deletions

View file

@ -7,6 +7,7 @@ import { nodeLockComment, nodeEditComment } from '~/redux/node/actions';
import { INodeState } from '~/redux/node/reducer';
import { CommentForm } from '../CommentForm';
import { CommendDeleted } from '../CommendDeleted';
import * as MODAL_ACTIONS from '~/redux/modal/actions';
type IProps = HTMLAttributes<HTMLDivElement> & {
is_empty?: boolean;
@ -17,6 +18,7 @@ type IProps = HTMLAttributes<HTMLDivElement> & {
can_edit?: boolean;
onDelete: typeof nodeLockComment;
onEdit: typeof nodeEditComment;
modalShowPhotoswipe: typeof MODAL_ACTIONS.modalShowPhotoswipe;
};
const Comment: FC<IProps> = memo(
@ -30,6 +32,7 @@ const Comment: FC<IProps> = memo(
can_edit,
onDelete,
onEdit,
modalShowPhotoswipe,
...props
}) => {
return (
@ -58,6 +61,7 @@ const Comment: FC<IProps> = memo(
can_edit={can_edit}
onDelete={onDelete}
onEdit={onEdit}
modalShowPhotoswipe={modalShowPhotoswipe}
/>
);
})}

View file

@ -14,87 +14,91 @@ import { PRESETS } from '~/constants/urls';
import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment';
import { nodeLockComment, nodeEditComment } from '~/redux/node/actions';
import { CommentMenu } from '../CommentMenu';
import * as MODAL_ACTIONS from '~/redux/modal/actions';
interface IProps {
comment: IComment;
can_edit: boolean;
onDelete: typeof nodeLockComment;
onEdit: typeof nodeEditComment;
modalShowPhotoswipe: typeof MODAL_ACTIONS.modalShowPhotoswipe;
}
const CommentContent: FC<IProps> = memo(({ comment, can_edit, onDelete, onEdit }) => {
const groupped = useMemo<Record<keyof typeof UPLOAD_TYPES, IFile[]>>(
() =>
reduce(
(group, file) => assocPath([file.type], append(file, group[file.type]), group),
{},
comment.files
),
[comment]
);
const CommentContent: FC<IProps> = memo(
({ comment, can_edit, onDelete, onEdit, modalShowPhotoswipe }) => {
const groupped = useMemo<Record<keyof typeof UPLOAD_TYPES, IFile[]>>(
() =>
reduce(
(group, file) => assocPath([file.type], append(file, group[file.type]), group),
{},
comment.files
),
[comment]
);
const onLockClick = useCallback(() => {
onDelete(comment.id, !comment.deleted_at);
}, [comment, onDelete]);
const onLockClick = useCallback(() => {
onDelete(comment.id, !comment.deleted_at);
}, [comment, onDelete]);
const onEditClick = useCallback(() => {
onEdit(comment.id);
}, [comment, onEdit]);
const onEditClick = useCallback(() => {
onEdit(comment.id);
}, [comment, onEdit]);
const menu = useMemo(
() => can_edit && <CommentMenu onDelete={onLockClick} onEdit={onEditClick} />,
[can_edit, comment, onEditClick, onLockClick]
);
const menu = useMemo(
() => can_edit && <CommentMenu onDelete={onLockClick} onEdit={onEditClick} />,
[can_edit, comment, onEditClick, onLockClick]
);
return (
<div className={styles.wrap}>
{comment.text && (
<Group className={classnames(styles.block, styles.block_text)}>
{menu}
return (
<div className={styles.wrap}>
{comment.text && (
<Group className={classnames(styles.block, styles.block_text)}>
{menu}
<Group className={styles.renderers}>
{formatCommentText(path(['user', 'username'], comment), comment.text).map(
(block, key) =>
COMMENT_BLOCK_RENDERERS[block.type] &&
createElement(COMMENT_BLOCK_RENDERERS[block.type], { block, key })
)}
<Group className={styles.renderers}>
{formatCommentText(path(['user', 'username'], comment), comment.text).map(
(block, key) =>
COMMENT_BLOCK_RENDERERS[block.type] &&
createElement(COMMENT_BLOCK_RENDERERS[block.type], { block, key })
)}
</Group>
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</Group>
)}
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</Group>
)}
{groupped.image && groupped.image.length > 0 && (
<div className={classnames(styles.block, styles.block_image)}>
{menu}
{groupped.image && groupped.image.length > 0 && (
<div className={classnames(styles.block, styles.block_image)}>
{menu}
<div className={styles.images}>
{groupped.image.map((file, index) => (
<div key={file.id} onClick={() => modalShowPhotoswipe(groupped.image, index)}>
<img src={getURL(file, PRESETS['300'])} alt={file.name} />
</div>
))}
</div>
<div className={styles.images}>
{groupped.image.map(file => (
<div key={file.id}>
<img src={getURL(file, PRESETS['300'])} alt={file.name} />
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</div>
)}
{groupped.audio && groupped.audio.length > 0 && (
<>
{groupped.audio.map(file => (
<div className={classnames(styles.block, styles.block_audio)} key={file.id}>
{menu}
<AudioPlayer file={file} />
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</div>
))}
</div>
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</div>
)}
{groupped.audio && groupped.audio.length > 0 && (
<>
{groupped.audio.map(file => (
<div className={classnames(styles.block, styles.block_audio)} key={file.id}>
{menu}
<AudioPlayer file={file} />
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</div>
))}
</>
)}
</div>
);
});
</>
)}
</div>
);
}
);
export { CommentContent };

View file

@ -11,6 +11,7 @@ import { nodeLockComment, nodeEditComment, nodeLoadMoreComments } from '~/redux/
import { INodeState } from '~/redux/node/reducer';
import { COMMENTS_DISPLAY } from '~/redux/node/constants';
import { plural } from '~/utils/dom';
import * as MODAL_ACTIONS from '~/redux/modal/actions';
interface IProps {
comments?: IComment[];
@ -21,6 +22,7 @@ interface IProps {
onEdit: typeof nodeEditComment;
onLoadMore: typeof nodeLoadMoreComments;
order?: 'ASC' | 'DESC';
modalShowPhotoswipe: typeof MODAL_ACTIONS.modalShowPhotoswipe;
}
const NodeComments: FC<IProps> = memo(
@ -33,6 +35,7 @@ const NodeComments: FC<IProps> = memo(
onLoadMore,
comment_count = 0,
order = 'DESC',
modalShowPhotoswipe,
}) => {
const comments_left = useMemo(() => Math.max(0, comment_count - comments.length), [
comments,
@ -73,6 +76,7 @@ const NodeComments: FC<IProps> = memo(
can_edit={canEditComment(group, user)}
onDelete={onDelete}
onEdit={onEdit}
modalShowPhotoswipe={modalShowPhotoswipe}
/>
))}

View file

@ -13,6 +13,7 @@ import { NodeCommentForm } from '~/components/node/NodeCommentForm';
import * as NODE_ACTIONS from '~/redux/node/actions';
import * as AUTH_ACTIONS from '~/redux/auth/actions';
import * as MODAL_ACTIONS from '~/redux/modal/actions';
import isBefore from 'date-fns/isBefore';
import { Card } from '~/components/containers/Card';
import { Footer } from '~/components/main/Footer';
@ -28,6 +29,7 @@ const mapDispatchToProps = {
nodeEditComment: NODE_ACTIONS.nodeEditComment,
nodeLoadMoreComments: NODE_ACTIONS.nodeLoadMoreComments,
authSetUser: AUTH_ACTIONS.authSetUser,
modalShowPhotoswipe: MODAL_ACTIONS.modalShowPhotoswipe,
};
type IProps = ReturnType<typeof mapStateToProps> &
@ -44,6 +46,7 @@ const BorisLayoutUnconnected: FC<IProps> = ({
nodeLockComment,
nodeEditComment,
nodeLoadMoreComments,
modalShowPhotoswipe,
authSetUser,
}) => {
const title = getRandomPhrase('BORIS_TITLE');
@ -90,6 +93,7 @@ const BorisLayoutUnconnected: FC<IProps> = ({
onDelete={nodeLockComment}
onEdit={nodeEditComment}
onLoadMore={nodeLoadMoreComments}
modalShowPhotoswipe={modalShowPhotoswipe}
order="ASC"
/>
)}

View file

@ -177,6 +177,7 @@ const NodeLayoutUnconnected: FC<IProps> = memo(
onDelete={nodeLockComment}
onEdit={nodeEditComment}
onLoadMore={nodeLoadMoreComments}
modalShowPhotoswipe={modalShowPhotoswipe}
order="DESC"
/>
)}