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

99 use swr (#100)

* 99: made node use SWR

* 99: fixed comments for SWR node

* 99: added error toast to useNodeFormFormik.ts
This commit is contained in:
muerwre 2022-01-02 17:10:21 +07:00 committed by GitHub
parent 832386d39a
commit c2d1c2bfc9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 366 additions and 413 deletions

View file

@ -8,8 +8,9 @@ import classNames from 'classnames';
import { NEW_COMMENT_CLASSNAME } from '~/constants/comment';
type IProps = HTMLAttributes<HTMLDivElement> & {
is_empty?: boolean;
is_loading?: boolean;
nodeId: number;
isEmpty?: boolean;
isLoading?: boolean;
group: ICommentGroup;
isSame?: boolean;
canEdit?: boolean;
@ -20,9 +21,10 @@ type IProps = HTMLAttributes<HTMLDivElement> & {
const Comment: FC<IProps> = memo(
({
group,
is_empty,
nodeId,
isEmpty,
isSame,
is_loading,
isLoading,
className,
canEdit,
onDelete,
@ -34,8 +36,8 @@ const Comment: FC<IProps> = memo(
className={classNames(className, {
[NEW_COMMENT_CLASSNAME]: group.hasNew,
})}
isEmpty={is_empty}
isLoading={is_loading}
isEmpty={isEmpty}
isLoading={isLoading}
user={group.user}
isNew={group.hasNew && !isSame}
{...props}
@ -48,9 +50,10 @@ const Comment: FC<IProps> = memo(
return (
<CommentContent
nodeId={nodeId}
comment={comment}
key={comment.id}
can_edit={!!canEdit}
canEdit={!!canEdit}
onDelete={onDelete}
onShowImageModal={onShowImageModal}
/>

View file

@ -13,106 +13,108 @@ import { PRESETS } from '~/constants/urls';
import { COMMENT_BLOCK_RENDERERS } from '~/constants/comment';
import { CommentMenu } from '../CommentMenu';
import { CommentForm } from '~/components/comment/CommentForm';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { selectNode } from '~/redux/node/selectors';
interface IProps {
nodeId: number;
comment: IComment;
can_edit: boolean;
canEdit: boolean;
onDelete: (id: IComment['id'], isLocked: boolean) => void;
onShowImageModal: (images: IFile[], index: number) => void;
}
const CommentContent: FC<IProps> = memo(({ comment, can_edit, onDelete, onShowImageModal }) => {
const [isEditing, setIsEditing] = useState(false);
const { current } = useShallowSelect(selectNode);
const CommentContent: FC<IProps> = memo(
({ comment, canEdit, nodeId, onDelete, onShowImageModal }) => {
const [isEditing, setIsEditing] = useState(false);
const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]);
const stopEditing = useCallback(() => setIsEditing(false), [setIsEditing]);
const startEditing = useCallback(() => setIsEditing(true), [setIsEditing]);
const stopEditing = useCallback(() => setIsEditing(false), [setIsEditing]);
const groupped = useMemo<Record<keyof typeof UPLOAD_TYPES, IFile[]>>(
() =>
reduce(
(group, file) =>
file.type ? assocPath([file.type], append(file, group[file.type]), group) : group,
{},
comment.files
),
[comment]
);
const groupped = useMemo<Record<keyof typeof UPLOAD_TYPES, IFile[]>>(
() =>
reduce(
(group, file) =>
file.type ? assocPath([file.type], append(file, group[file.type]), group) : 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 menu = useMemo(
() => can_edit && <CommentMenu onDelete={onLockClick} onEdit={startEditing} />,
[can_edit, startEditing, onLockClick]
);
const menu = useMemo(
() => canEdit && <CommentMenu onDelete={onLockClick} onEdit={startEditing} />,
[canEdit, startEditing, onLockClick]
);
const blocks = useMemo(
() =>
!!comment.text.trim()
? formatCommentText(path(['user', 'username'], comment), comment.text)
: [],
[comment]
);
const blocks = useMemo(
() =>
!!comment.text.trim()
? formatCommentText(path(['user', 'username'], comment), comment.text)
: [],
[comment]
);
if (isEditing) {
return <CommentForm nodeId={current.id} comment={comment} onCancelEdit={stopEditing} />;
}
if (isEditing) {
return <CommentForm nodeId={nodeId} comment={comment} onCancelEdit={stopEditing} />;
}
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}>
{blocks.map(
(block, key) =>
COMMENT_BLOCK_RENDERERS[block.type] &&
createElement(COMMENT_BLOCK_RENDERERS[block.type], { block, key })
)}
<Group className={styles.renderers}>
{blocks.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={classNames(styles.images, {
[styles.multiple]: groupped.image.length > 1,
})}
>
{groupped.image.map((file, index) => (
<div key={file.id} onClick={() => onShowImageModal(groupped.image, index)}>
<img src={getURL(file, PRESETS['600'])} alt={file.name} />
</div>
))}
</div>
<div
className={classNames(styles.images, { [styles.multiple]: groupped.image.length > 1 })}
>
{groupped.image.map((file, index) => (
<div key={file.id} onClick={() => onShowImageModal(groupped.image, index)}>
<img src={getURL(file, PRESETS['600'])} alt={file.name} />
<div className={styles.date}>{getPrettyDate(comment.created_at)}</div>
</div>
)}
{groupped.audio && groupped.audio.length > 0 && (
<Fragment>
{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 && (
<Fragment>
{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>
))}
</Fragment>
)}
</div>
);
});
</Fragment>
)}
</div>
);
}
);
export { CommentContent };

View file

@ -10,7 +10,7 @@ import styles from './styles.module.scss';
import { NodeEditorProps } from '~/redux/node/types';
import { useNodeImages } from '~/utils/hooks/node/useNodeImages';
import { useNodeAudios } from '~/utils/hooks/node/useNodeAudios';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
import { useFileUploaderContext } from '~/utils/hooks/useFileUploader';
import { UploadDropzone } from '~/components/upload/UploadDropzone';

View file

@ -1,9 +1,8 @@
import React, { FC, createElement } from 'react';
import styles from './styles.module.scss';
import { INode } from '~/redux/types';
import { NODE_PANEL_COMPONENTS } from '~/redux/node/constants';
import { has } from 'ramda';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
const EditorActionsPanel: FC = () => {
const { values } = useNodeFormContext();

View file

@ -4,7 +4,7 @@ import { Group } from '~/components/containers/Group';
import { InputText } from '~/components/input/InputText';
import { Button } from '~/components/input/Button';
import { Padder } from '~/components/containers/Padder';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
const EditorButtons: FC = () => {
const { values, handleChange, isSubmitting } = useNodeFormContext();
@ -28,6 +28,7 @@ const EditorButtons: FC = () => {
iconRight="check"
color={values.is_promoted ? 'primary' : 'lab'}
disabled={isSubmitting}
type="submit"
/>
</Group>
</Padder>

View file

@ -3,7 +3,7 @@ import { IEditorComponentProps } from '~/redux/node/types';
import { Button } from '~/components/input/Button';
import { Icon } from '~/components/input/Icon';
import styles from './styles.module.scss';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
interface IProps extends IEditorComponentProps {}

View file

@ -5,7 +5,7 @@ import { UPLOAD_TYPES } from '~/redux/uploads/constants';
import { IEditorComponentProps } from '~/redux/node/types';
import { useFileUploaderContext } from '~/utils/hooks/useFileUploader';
import { getFileType } from '~/utils/uploader';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
import { Button } from '~/components/input/Button';
type IProps = IEditorComponentProps & {

View file

@ -12,7 +12,7 @@ import { Icon } from '~/components/input/Icon';
import { PRESETS } from '~/constants/urls';
import { IEditorComponentProps } from '~/redux/node/types';
import { useFileUploader, useFileUploaderContext } from '~/utils/hooks/useFileUploader';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
import { getFileType } from '~/utils/uploader';
type IProps = IEditorComponentProps & {};

View file

@ -4,7 +4,7 @@ import styles from './styles.module.scss';
import { Textarea } from '~/components/input/Textarea';
import { path } from 'ramda';
import { NodeEditorProps } from '~/redux/node/types';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
type IProps = NodeEditorProps & {};

View file

@ -6,7 +6,7 @@ import { InputText } from '~/components/input/InputText';
import classnames from 'classnames';
import { getYoutubeThumb } from '~/utils/dom';
import { NodeEditorProps } from '~/redux/node/types';
import { useNodeFormContext } from '~/utils/hooks/useNodeFormFormik';
import { useNodeFormContext } from '~/utils/hooks/node/useNodeFormFormik';
type IProps = NodeEditorProps & {};

View file

@ -64,7 +64,6 @@ const NodeImageSwiperBlock: FC<IProps> = ({ node }) => {
<div className={styles.single}>
<ImagePreloader
file={images[0]}
onLoad={updateSwiper}
onClick={() => onOpenPhotoSwipe(0)}
className={styles.image}
/>