diff --git a/src/index.tsx b/src/index.tsx index b98c8553..6b17859b 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -5,14 +5,23 @@ import { PersistGate } from 'redux-persist/integration/react'; import { configureStore } from '~/redux/store'; import App from '~/containers/App'; import '~/styles/main.scss'; +import { SWRConfig } from 'swr'; const { store, persistor } = configureStore(); render( - - - - - , + + + + + + + , document.getElementById('app') ); diff --git a/src/layouts/BorisLayout/index.tsx b/src/layouts/BorisLayout/index.tsx index 4493096d..1bd8b5ff 100644 --- a/src/layouts/BorisLayout/index.tsx +++ b/src/layouts/BorisLayout/index.tsx @@ -1,5 +1,4 @@ import React, { FC, useCallback, useEffect } from 'react'; -import { selectNode, selectNodeComments } from '~/redux/node/selectors'; import { selectAuthIsTester, selectUser } from '~/redux/auth/selectors'; import { useDispatch } from 'react-redux'; import styles from './styles.module.scss'; @@ -11,7 +10,6 @@ import { BorisStats } from '~/components/boris/BorisStats'; 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'; diff --git a/src/redux/messages/api.ts b/src/redux/messages/api.ts index 2e224ab3..d3b263ea 100644 --- a/src/redux/messages/api.ts +++ b/src/redux/messages/api.ts @@ -24,6 +24,6 @@ export const apiSendMessage = ({ username, message }: ApiSendMessageRequest) => export const apiDeleteMessage = ({ username, id, is_locked }: ApiDeleteMessageRequest) => api .delete(API.USER.MESSAGE_DELETE(username, id), { - params: { is_locked }, + params: { isLocked: is_locked }, }) .then(cleanResult); diff --git a/src/redux/node/actions.ts b/src/redux/node/actions.ts index 40540ca6..b70a9678 100644 --- a/src/redux/node/actions.ts +++ b/src/redux/node/actions.ts @@ -118,10 +118,17 @@ export const nodeLock = (id: INode['id'], is_locked: boolean) => ({ is_locked, }); -export const nodeLockComment = (id: IComment['id'], is_locked: boolean) => ({ +export const nodeLockComment = ( + nodeID: INode['id'], + commentID: IComment['id'], + isLocked: boolean, + callback: (e?: string) => void +) => ({ type: NODE_ACTIONS.LOCK_COMMENT, - id, - is_locked, + nodeID, + commentID, + callback, + isLocked, }); export const nodeEditComment = (id: IComment['id']) => ({ diff --git a/src/redux/node/api.ts b/src/redux/node/api.ts index d4b44350..6ba4d8f9 100644 --- a/src/redux/node/api.ts +++ b/src/redux/node/api.ts @@ -108,10 +108,10 @@ export const apiPostNodeHeroic = ({ id }: ApiPostNodeHeroicRequest) => export const apiLockNode = ({ id, is_locked }: ApiLockNodeRequest) => api - .post(API.NODE.POST_LOCK(id), { is_locked }) + .post(API.NODE.POST_LOCK(id), { isLocked: is_locked }) .then(cleanResult); -export const apiLockComment = ({ id, is_locked, current }: ApiLockCommentRequest) => +export const apiLockComment = ({ nodeID, isLocked, commentID }: ApiLockCommentRequest) => api - .post(API.NODE.LOCK_COMMENT(current, id), { is_locked }) + .post(API.NODE.LOCK_COMMENT(nodeID, commentID), { is_locked: isLocked }) .then(cleanResult); diff --git a/src/redux/node/sagas.ts b/src/redux/node/sagas.ts index d5d60a8c..e02ab8ee 100644 --- a/src/redux/node/sagas.ts +++ b/src/redux/node/sagas.ts @@ -312,41 +312,23 @@ function* onLockSaga({ id, is_locked }: ReturnType) { } } -function* onLockCommentSaga({ id, is_locked }: ReturnType) { - const { current, comments }: ReturnType = yield select(selectNode); - +function* onLockCommentSaga({ + commentID, + nodeID, + isLocked, + callback, +}: ReturnType) { try { - yield put( - nodeSetComments( - comments.map(comment => - comment.id === id - ? { ...comment, deleted_at: is_locked ? new Date().toISOString() : undefined } - : comment - ) - ) - ); - - const data: Unwrap = yield call(apiLockComment, { - current: current.id, - id, - is_locked, + yield call(apiLockComment, { + commentID, + nodeID, + isLocked, }); - yield put( - nodeSetComments( - comments.map(comment => - comment.id === id ? { ...comment, deleted_at: data.deleted_at || undefined } : comment - ) - ) - ); - } catch { - yield put( - nodeSetComments( - comments.map(comment => - comment.id === id ? { ...comment, deleted_at: current.deleted_at } : comment - ) - ) - ); + callback(); + } catch (e) { + console.log(e); + callback(e.toString()); } } diff --git a/src/redux/node/types.ts b/src/redux/node/types.ts index c15ab4f7..1951e9ff 100644 --- a/src/redux/node/types.ts +++ b/src/redux/node/types.ts @@ -71,9 +71,9 @@ export type ApiLockNodeResult = { }; export type ApiLockCommentRequest = { - id: IComment['id']; - current: INode['id']; - is_locked: boolean; + commentID: IComment['id']; + nodeID: INode['id']; + isLocked: boolean; }; export type ApiLockcommentResult = { deleted_at: string; diff --git a/src/utils/hooks/node/useNodeComments.ts b/src/utils/hooks/node/useNodeComments.ts index d108ed4f..067967d2 100644 --- a/src/utils/hooks/node/useNodeComments.ts +++ b/src/utils/hooks/node/useNodeComments.ts @@ -22,7 +22,7 @@ export const useNodeComments = (id: INode['id']) => { [id] ); - const { data, error, isValidating, size, setSize } = useSWRInfinite(getKey, fetcher); + const { data, error, isValidating, size, setSize, mutate } = useSWRInfinite(getKey, fetcher); const comments = useMemo( () => (data || []).reduce((acc, { comments }) => [...acc, ...comments], [] as IComment[]), @@ -40,14 +40,37 @@ export const useNodeComments = (id: INode['id']) => { const isLoading = !data && !isValidating; const onDelete = useCallback( - (id: IComment['id'], locked: boolean) => dispatch(nodeLockComment(id, locked)), - [dispatch] + (commentID: IComment['id'], locked: boolean) => { + const callback = (e?: string) => { + if (!e && data) { + console.log({ data, commentID }); + + mutate( + data.map(page => ({ + ...page, + comments: page.comments.map(comment => + comment.id === commentID + ? { + ...comment, + deleted_at: locked ? new Date().toISOString() : undefined, + } + : comment + ), + })), + false + ); + } + }; + + dispatch(nodeLockComment(id, commentID, locked, callback)); + }, + [id, mutate, data] ); const onLoadMoreComments = useCallback(() => setSize(size + 1), [size, setSize]); const onShowPhotoswipe = useCallback( (images: IFile[], index: number) => dispatch(modalShowPhotoswipe(images, index)), - [dispatch] + [] ); return { comments, count, error, isLoading, onDelete, onLoadMoreComments, onShowPhotoswipe };