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

made boris with hooks

This commit is contained in:
Fedor Katurov 2021-09-20 12:59:02 +07:00
parent 639c952c2c
commit 20926609b9
9 changed files with 85 additions and 79 deletions

View file

@ -13,7 +13,7 @@ import { IComment, IFile, INode } from '~/redux/types';
interface IProps { interface IProps {
isLoadingComments: boolean; isLoadingComments: boolean;
commentCount: number; commentCount: number;
node: INode; node?: INode;
comments: IComment[]; comments: IComment[];
onDelete: (id: IComment['id'], locked: boolean) => void; onDelete: (id: IComment['id'], locked: boolean) => void;
onLoadMoreComments: () => void; onLoadMoreComments: () => void;
@ -34,7 +34,7 @@ const BorisComments: FC<IProps> = ({
return ( return (
<> <>
<Group className={styles.grid}> <Group className={styles.grid}>
{user.is_user && <NodeCommentForm isBefore nodeId={node.id} />} {user.is_user && <NodeCommentForm isBefore nodeId={node?.id} />}
{isLoadingComments ? ( {isLoadingComments ? (
<NodeNoComments is_loading count={7} /> <NodeNoComments is_loading count={7} />

View file

@ -19,8 +19,8 @@ interface IProps {
commentsOrder: 'ASC' | 'DESC'; commentsOrder: 'ASC' | 'DESC';
comments: IComment[]; comments: IComment[];
commentsCount: number; commentsCount: number;
related?: INodeRelated;
isLoadingComments: boolean; isLoadingComments: boolean;
related: INodeRelated;
onDeleteComment: (id: IComment['id'], locked: boolean) => void; onDeleteComment: (id: IComment['id'], locked: boolean) => void;
onLoadMoreComments: () => void; onLoadMoreComments: () => void;
onShowPhotoswipe: (images: IFile[], index: number) => void; onShowPhotoswipe: (images: IFile[], index: number) => void;

View file

@ -9,7 +9,7 @@ import { Link } from 'react-router-dom';
interface IProps { interface IProps {
isLoading: boolean; isLoading: boolean;
node?: INode; node?: INode;
related: INodeRelated; related?: INodeRelated;
} }
const NodeRelatedBlock: FC<IProps> = ({ isLoading, node, related }) => { const NodeRelatedBlock: FC<IProps> = ({ isLoading, node, related }) => {

View file

@ -27,16 +27,27 @@ import { useHistory, useLocation } from 'react-router';
import { Card } from '~/components/containers/Card'; import { Card } from '~/components/containers/Card';
import { SidebarRouter } from '~/containers/main/SidebarRouter'; import { SidebarRouter } from '~/containers/main/SidebarRouter';
import { BorisContactItem } from '~/components/boris/BorisContactItem'; import { BorisContactItem } from '~/components/boris/BorisContactItem';
import { useNode } from '~/utils/hooks/node/useNode';
import { useNodeComments } from '~/utils/hooks/node/useNodeComments';
type IProps = {}; type IProps = {};
const borisNodeID = 696;
const BorisLayout: FC<IProps> = () => { const BorisLayout: FC<IProps> = () => {
const title = useRandomPhrase('BORIS_TITLE'); const title = useRandomPhrase('BORIS_TITLE');
const dispatch = useDispatch(); const dispatch = useDispatch();
const node = useShallowSelect(selectNode); const { node } = useNode(borisNodeID);
const {
comments,
isLoading: isLoadingComments,
count: commentCount,
onLoadMoreComments,
onShowPhotoswipe,
onDelete,
} = useNodeComments(borisNodeID);
const user = useShallowSelect(selectUser); const user = useShallowSelect(selectUser);
const stats = useShallowSelect(selectBorisStats); const stats = useShallowSelect(selectBorisStats);
const comments = useShallowSelect(selectNodeComments);
const is_tester = useShallowSelect(selectAuthIsTester); const is_tester = useShallowSelect(selectAuthIsTester);
useEffect(() => { useEffect(() => {
@ -54,11 +65,6 @@ const BorisLayout: FC<IProps> = () => {
dispatch(authSetUser({ last_seen_boris: last_comment.created_at })); dispatch(authSetUser({ last_seen_boris: last_comment.created_at }));
}, [user.last_seen_boris, dispatch, comments]); }, [user.last_seen_boris, dispatch, comments]);
useEffect(() => {
if (node.is_loading) return;
dispatch(nodeLoadNode(696, 'DESC'));
}, [dispatch]);
useEffect(() => { useEffect(() => {
dispatch(borisLoadStats()); dispatch(borisLoadStats());
}, [dispatch]); }, [dispatch]);
@ -111,13 +117,13 @@ const BorisLayout: FC<IProps> = () => {
<Route path={`${URLS.BORIS}/ui`} component={BorisUIDemo} /> <Route path={`${URLS.BORIS}/ui`} component={BorisUIDemo} />
<BorisComments <BorisComments
isLoadingComments={node.is_loading_comments} isLoadingComments={isLoadingComments}
commentCount={node.comment_count} commentCount={commentCount}
node={node.current} node={node}
comments={node.comments} comments={comments}
onDelete={console.log} onDelete={onDelete}
onLoadMoreComments={console.log} onLoadMoreComments={onLoadMoreComments}
onShowPhotoswipe={console.log} onShowPhotoswipe={onShowPhotoswipe}
/> />
</Switch> </Switch>
} }

View file

@ -1,90 +1,79 @@
import React, { FC, memo, useCallback } from 'react'; import React, { FC, memo } from 'react';
import { Route, RouteComponentProps } from 'react-router'; import { Route, RouteComponentProps } from 'react-router';
import { selectNode } from '~/redux/node/selectors';
import { Card } from '~/components/containers/Card'; import { Card } from '~/components/containers/Card';
import { NodePanel } from '~/components/node/NodePanel'; import { NodePanel } from '~/components/node/NodePanel';
import { Footer } from '~/components/main/Footer'; import { Footer } from '~/components/main/Footer';
import { SidebarRouter } from '~/containers/main/SidebarRouter'; import { SidebarRouter } from '~/containers/main/SidebarRouter';
import { useShallowSelect } from '~/utils/hooks/useShallowSelect';
import { Container } from '~/containers/main/Container'; import { Container } from '~/containers/main/Container';
import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks'; import { useNodeBlocks } from '~/utils/hooks/node/useNodeBlocks';
import { NodeBottomBlock } from '~/components/node/NodeBottomBlock'; import { NodeBottomBlock } from '~/components/node/NodeBottomBlock';
import { useNodeCoverImage } from '~/utils/hooks/node/useNodeCoverImage'; import { useNodeCoverImage } from '~/utils/hooks/node/useNodeCoverImage';
import { useScrollToTop } from '~/utils/hooks/useScrollToTop'; import { useScrollToTop } from '~/utils/hooks/useScrollToTop';
import { useLoadNode } from '~/utils/hooks/node/useLoadNode';
import { URLS } from '~/constants/urls'; import { URLS } from '~/constants/urls';
import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog'; import { EditorEditDialog } from '~/containers/dialogs/EditorEditDialog';
import { useOnNodeSeen } from '~/utils/hooks/node/useOnNodeSeen'; import { useOnNodeSeen } from '~/utils/hooks/node/useOnNodeSeen';
import styles from './styles.module.scss'; import styles from './styles.module.scss';
import { useNodeFetcher } from '~/utils/hooks/node/useNodeFetcher'; import { useNode } from '~/utils/hooks/node/useNode';
import { useNodeComments } from '~/utils/hooks/node/useNodeComments'; import { useNodeComments } from '~/utils/hooks/node/useNodeComments';
import { IFile } from '~/redux/types'; import { useNodeRelated } from '~/utils/hooks/node/useNodeRelated';
import { modalShowPhotoswipe } from '~/redux/modal/actions';
import { useDispatch } from 'react-redux';
type IProps = RouteComponentProps<{ id: string }> & {}; type IProps = RouteComponentProps<{ id: string }> & {};
const NodeLayout: FC<IProps> = memo( const NodeLayout: FC<IProps> = memo(({ match: { params } }) => {
({ const id = parseInt(params.id, 10);
match: { const { node, isLoading } = useNode(id);
params: { id }, const {
}, comments,
}) => { isLoading: isLoadingComments,
const { node, isLoading } = useNodeFetcher(parseInt(id, 10)); count: commentsCount,
const { onDelete,
comments, onLoadMoreComments,
isLoading: isLoadingComments, onShowPhotoswipe,
count: commentsCount, } = useNodeComments(id);
onDelete,
onLoadMoreComments,
onShowPhotoswipe,
} = useNodeComments(parseInt(id, 10));
const { related } = useShallowSelect(selectNode); const { related } = useNodeRelated(id);
useNodeCoverImage(node); useNodeCoverImage(node);
useScrollToTop([id]); useScrollToTop([id]);
useOnNodeSeen(node); useOnNodeSeen(node);
useLoadNode(id, isLoading);
const { head, block } = useNodeBlocks(node, isLoading); const { head, block } = useNodeBlocks(node, isLoading);
return ( return (
<div className={styles.wrap}> <div className={styles.wrap}>
{head} {head}
<Container> <Container>
<Card className={styles.node} seamless> <Card className={styles.node} seamless>
{block} {block}
<NodePanel node={node} isLoading={isLoading} /> <NodePanel node={node} isLoading={isLoading} />
<NodeBottomBlock <NodeBottomBlock
node={node} node={node}
comments={comments} comments={comments}
isLoading={isLoading} isLoading={isLoading}
isLoadingComments={isLoadingComments} isLoadingComments={isLoadingComments}
commentsCount={commentsCount} commentsCount={commentsCount}
commentsOrder="DESC" commentsOrder="DESC"
related={related} related={related}
onShowPhotoswipe={onShowPhotoswipe} onShowPhotoswipe={onShowPhotoswipe}
onDeleteComment={onDelete} onDeleteComment={onDelete}
onLoadMoreComments={onLoadMoreComments} onLoadMoreComments={onLoadMoreComments}
/> />
<Footer /> <Footer />
</Card> </Card>
</Container> </Container>
<SidebarRouter prefix="/post:id" /> <SidebarRouter prefix="/post:id" />
<Route path={URLS.NODE_EDIT_URL(':id')} render={() => <EditorEditDialog />} /> <Route path={URLS.NODE_EDIT_URL(':id')} render={() => <EditorEditDialog />} />
</div> </div>
); );
} });
);
export { NodeLayout }; export { NodeLayout };

View file

@ -93,8 +93,7 @@ export const apiGetNodeComments = ({
.get<ApiGetNodeCommentsResponse>(API.NODE.COMMENT(id), { params: { take, skip } }) .get<ApiGetNodeCommentsResponse>(API.NODE.COMMENT(id), { params: { take, skip } })
.then(cleanResult); .then(cleanResult);
export const apiGetNodeRelated = ({ id }: ApiGetNodeRelatedRequest) => export const apiGetNodeRelated = url => api.get<ApiGetNodeRelatedResult>(url).then(cleanResult);
api.get<ApiGetNodeRelatedResult>(API.NODE.RELATED(id)).then(cleanResult);
export const apiPostNodeTags = ({ id, tags }: ApiPostNodeTagsRequest) => export const apiPostNodeTags = ({ id, tags }: ApiPostNodeTagsRequest) =>
api api

View file

@ -165,7 +165,7 @@ function* onNodeLoad({ id }: ReturnType<typeof nodeLoadNode>) {
Unwrap<typeof apiGetNodeRelated> Unwrap<typeof apiGetNodeRelated>
] = yield all([ ] = yield all([
call(apiGetNodeComments, { id, take: COMMENTS_DISPLAY, skip: 0 }), call(apiGetNodeComments, { id, take: COMMENTS_DISPLAY, skip: 0 }),
call(apiGetNodeRelated, { id }), call(apiGetNodeRelated, id),
]); ]);
yield put( yield put(

View file

@ -2,7 +2,7 @@ import useSWR from 'swr';
import { INode } from '~/redux/types'; import { INode } from '~/redux/types';
import { apiGetNode } from '~/redux/node/api'; import { apiGetNode } from '~/redux/node/api';
export const useNodeFetcher = (id: INode['id']) => { export const useNode = (id: INode['id']) => {
const { data, error, isValidating } = useSWR(`${id}`, apiGetNode); const { data, error, isValidating } = useSWR(`${id}`, apiGetNode);
const node = data?.node; const node = data?.node;
const isLoading = !data && !isValidating; const isLoading = !data && !isValidating;

View file

@ -0,0 +1,12 @@
import { INode } from '~/redux/types';
import useSWR from 'swr';
import { apiGetNodeRelated } from '~/redux/node/api';
import { API } from '~/constants/api';
export const useNodeRelated = (id?: INode['id']) => {
const { data, error, isValidating } = useSWR(API.NODE.RELATED(id), apiGetNodeRelated);
const isLoading = !data && !isValidating;
const related = data?.related;
return { related, error, isLoading };
};