diff --git a/src/components/boris/BorisComments/index.tsx b/src/components/boris/BorisComments/index.tsx index 7b5ebb8e..2925f2b5 100644 --- a/src/components/boris/BorisComments/index.tsx +++ b/src/components/boris/BorisComments/index.tsx @@ -5,46 +5,39 @@ import { NodeCommentForm } from '~/components/node/NodeCommentForm'; import { NodeNoComments } from '~/components/node/NodeNoComments'; import { NodeComments } from '~/views/node/NodeComments'; import { Footer } from '~/components/main/Footer'; -import { IComment, IFile, INode } from '~/redux/types'; -import { IUser } from '~/redux/auth/types'; -import { CommentProvider } from '~/utils/providers/CommentProvider'; +import { CommentProvider, useCommentContext } from '~/utils/providers/CommentProvider'; +import { useUserContext } from '~/utils/providers/UserProvider'; +import { useNodeContext } from '~/utils/providers/NodeProvider'; -interface IProps { - node: INode; - user: IUser; - commentCount: number; - comments: IComment[]; - isLoadingComments: boolean; - onShowImageModal: (images: IFile[], index: number) => void; - onLoadMoreComments: () => void; - onDeleteComment: (id: IComment['id'], isLocked: boolean) => void; -} +interface IProps {} + +const BorisComments: FC = () => { + const user = useUserContext(); + const { + isLoading, + comments, + onLoadMoreComments, + onDeleteComment, + onShowImageModal, + count, + } = useCommentContext(); + const { node } = useNodeContext(); -const BorisComments: FC = ({ - node, - user, - isLoadingComments, - commentCount, - comments, - onLoadMoreComments, - onDeleteComment, - onShowImageModal, -}) => { return ( <> {user.is_user && } - {isLoadingComments ? ( + {isLoading ? ( ) : ( diff --git a/src/containers/main/MainRouter/index.tsx b/src/containers/main/MainRouter/index.tsx index e9d06ab4..4efa5f66 100644 --- a/src/containers/main/MainRouter/index.tsx +++ b/src/containers/main/MainRouter/index.tsx @@ -1,6 +1,5 @@ import React, { FC } from 'react'; import { URLS } from '~/constants/urls'; -import { BorisLayout } from '~/layouts/BorisLayout'; import { ErrorNotFound } from '~/containers/pages/ErrorNotFound'; import { Redirect, Route, Switch, useLocation } from 'react-router'; import { LabLayout } from '~/layouts/LabLayout'; @@ -8,6 +7,7 @@ import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; import { selectAuthUser } from '~/redux/auth/selectors'; import { ProfileLayout } from '~/layouts/ProfileLayout'; import FlowPage from '~/pages'; +import BorisPage from '~/pages/boris'; import NodePage from '~/pages/node/[id]'; interface IProps {} @@ -19,7 +19,7 @@ const MainRouter: FC = () => { return ( - + diff --git a/src/layouts/BorisLayout/index.tsx b/src/layouts/BorisLayout/index.tsx index 12e8e646..11cf7eb9 100644 --- a/src/layouts/BorisLayout/index.tsx +++ b/src/layouts/BorisLayout/index.tsx @@ -1,71 +1,25 @@ -import React, { FC, useCallback, useEffect } from 'react'; -import { selectNode, selectNodeComments } from '~/redux/node/selectors'; -import { selectAuthIsTester } from '~/redux/auth/selectors'; -import { useDispatch } from 'react-redux'; +import React, { FC } from 'react'; import styles from './styles.module.scss'; import { Group } from '~/components/containers/Group'; import boris from '~/sprites/boris_robot.svg'; -import { useRandomPhrase } from '~/constants/phrases'; -import isBefore from 'date-fns/isBefore'; -import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; -import { selectBorisStats } from '~/redux/boris/selectors'; -import { authSetState, authSetUser } from '~/redux/auth/actions'; -import { nodeLoadNode } from '~/redux/node/actions'; -import { borisLoadStats } from '~/redux/boris/actions'; import { Container } from '~/containers/main/Container'; import StickyBox from 'react-sticky-box/dist/esnext'; import { BorisComments } from '~/components/boris/BorisComments'; import { Card } from '~/components/containers/Card'; import { SidebarRouter } from '~/containers/main/SidebarRouter'; import { BorisSidebar } from '~/components/boris/BorisSidebar'; -import { useImageModal } from '~/utils/hooks/useImageModal'; -import { useNodeComments } from '~/utils/hooks/node/useNodeComments'; -import { useUser } from '~/utils/hooks/user/userUser'; +import { useUserContext } from '~/utils/providers/UserProvider'; +import { BorisUsageStats } from '~/redux/boris/reducer'; -type IProps = {}; +type IProps = { + title: string; + setIsBetaTester: (val: boolean) => void; + isTester: boolean; + stats: BorisUsageStats; +}; -const BorisLayout: FC = () => { - const title = useRandomPhrase('BORIS_TITLE'); - const dispatch = useDispatch(); - const node = useShallowSelect(selectNode); - const stats = useShallowSelect(selectBorisStats); - const comments = useShallowSelect(selectNodeComments); - const isTester = useShallowSelect(selectAuthIsTester); - const user = useUser(); - - useEffect(() => { - const last_comment = comments[0]; - - if (!last_comment) return; - - if ( - user.last_seen_boris && - last_comment.created_at && - !isBefore(new Date(user.last_seen_boris), new Date(last_comment.created_at)) - ) - return; - - dispatch(authSetUser({ last_seen_boris: last_comment.created_at })); - }, [user.last_seen_boris, dispatch, comments]); - - useEffect(() => { - if (node.is_loading) return; - dispatch(nodeLoadNode(696, 'DESC')); - }, [dispatch]); - - useEffect(() => { - dispatch(borisLoadStats()); - }, [dispatch]); - - const setBetaTester = useCallback( - (is_tester: boolean) => { - dispatch(authSetState({ is_tester })); - }, - [dispatch] - ); - - const onShowImageModal = useImageModal(); - const { onLoadMoreComments, onDelete: onDeleteComment } = useNodeComments(696); +const BorisLayout: FC = ({ title, setIsBetaTester, isTester, stats }) => { + const user = useUserContext(); return ( @@ -82,16 +36,7 @@ const BorisLayout: FC = () => {
- + @@ -99,7 +44,7 @@ const BorisLayout: FC = () => { diff --git a/src/pages/boris.tsx b/src/pages/boris.tsx new file mode 100644 index 00000000..fe6381f5 --- /dev/null +++ b/src/pages/boris.tsx @@ -0,0 +1,49 @@ +import React, { useEffect, VFC } from 'react'; +import { useDispatch } from 'react-redux'; +import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; +import { selectNode } from '~/redux/node/selectors'; +import { BorisLayout } from '~/layouts/BorisLayout'; +import { nodeLoadNode } from '~/redux/node/actions'; +import { CommentProvider } from '~/utils/providers/CommentProvider'; +import { useImageModal } from '~/utils/hooks/useImageModal'; +import { useNodeComments } from '~/utils/hooks/node/useNodeComments'; +import { useBoris } from '~/utils/hooks/boris/useBoris'; + +const BorisPage: VFC = () => { + const dispatch = useDispatch(); + const node = useShallowSelect(selectNode); + const { + comments, + comment_count: count, + is_loading_comments: isLoadingComments, + } = useShallowSelect(selectNode); + + const onShowImageModal = useImageModal(); + const { onLoadMoreComments, onDelete: onDeleteComment } = useNodeComments(696); + const { title, setIsBetaTester, isTester, stats } = useBoris(comments); + + useEffect(() => { + if (node.is_loading) return; + dispatch(nodeLoadNode(696, 'DESC')); + }, [dispatch]); + + return ( + + + + ); +}; + +export default BorisPage; diff --git a/src/utils/hooks/boris/useBoris.ts b/src/utils/hooks/boris/useBoris.ts new file mode 100644 index 00000000..a29cfd9d --- /dev/null +++ b/src/utils/hooks/boris/useBoris.ts @@ -0,0 +1,48 @@ +import { useDispatch } from 'react-redux'; +import { useCallback, useEffect } from 'react'; +import isBefore from 'date-fns/isBefore'; +import { authSetState, authSetUser } from '~/redux/auth/actions'; +import { borisLoadStats } from '~/redux/boris/actions'; +import { useUser } from '~/utils/hooks/user/userUser'; +import { IComment } from '~/redux/types'; +import { useShallowSelect } from '~/utils/hooks/useShallowSelect'; +import { selectAuthIsTester } from '~/redux/auth/selectors'; +import { selectBorisStats } from '~/redux/boris/selectors'; +import { useRandomPhrase } from '~/constants/phrases'; + +export const useBoris = (comments: IComment[]) => { + const dispatch = useDispatch(); + const user = useUser(); + + useEffect(() => { + const last_comment = comments[0]; + + if (!last_comment) return; + + if ( + user.last_seen_boris && + last_comment.created_at && + !isBefore(new Date(user.last_seen_boris), new Date(last_comment.created_at)) + ) + return; + + dispatch(authSetUser({ last_seen_boris: last_comment.created_at })); + }, [user.last_seen_boris, dispatch, comments]); + + useEffect(() => { + dispatch(borisLoadStats()); + }, [dispatch]); + + const setIsBetaTester = useCallback( + (is_tester: boolean) => { + dispatch(authSetState({ is_tester })); + }, + [dispatch] + ); + + const isTester = useShallowSelect(selectAuthIsTester); + const stats = useShallowSelect(selectBorisStats); + const title = useRandomPhrase('BORIS_TITLE'); + + return { setIsBetaTester, isTester, stats, title }; +};