diff --git a/src/components/comment/Comment/index.tsx b/src/components/comment/Comment/index.tsx index 50d9cd82..4f2ee99b 100644 --- a/src/components/comment/Comment/index.tsx +++ b/src/components/comment/Comment/index.tsx @@ -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} /> diff --git a/src/components/comment/CommentContent/index.tsx b/src/components/comment/CommentContent/index.tsx index bc280fbc..e8b79667 100644 --- a/src/components/comment/CommentContent/index.tsx +++ b/src/components/comment/CommentContent/index.tsx @@ -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 }; diff --git a/src/containers/node/NodeComments/index.tsx b/src/containers/node/NodeComments/index.tsx index 4cedbe28..0d129c4a 100644 --- a/src/containers/node/NodeComments/index.tsx +++ b/src/containers/node/NodeComments/index.tsx @@ -9,6 +9,7 @@ import { useGrouppedComments } from '~/utils/hooks/node/useGrouppedComments'; import { useCommentContext } from '~/utils/context/CommentContextProvider'; import { Comment } from '~/components/comment/Comment'; import { useUserContext } from '~/utils/context/UserContextProvider'; +import { useNodeContext } from '~/utils/context/NodeContextProvider'; interface IProps { order: 'ASC' | 'DESC'; @@ -16,6 +17,8 @@ interface IProps { const NodeComments: FC<IProps> = memo(({ order }) => { const user = useUserContext(); + const { node } = useNodeContext(); + const { comments, count, @@ -41,12 +44,17 @@ const NodeComments: FC<IProps> = memo(({ order }) => { [left, onLoadMoreComments] ); + if (!node?.id) { + return null; + } + return ( <div className={styles.wrap}> {order === 'DESC' && more} {groupped.map(group => ( <Comment + nodeId={node.id!} key={group.ids.join()} group={group} canEdit={canEditComment(group, user)} diff --git a/src/redux/node/actions.ts b/src/redux/node/actions.ts index c7d93f21..a8c95483 100644 --- a/src/redux/node/actions.ts +++ b/src/redux/node/actions.ts @@ -47,7 +47,7 @@ export const nodePostLocalComment = ( nodeId, comment, callback, - type: NODE_ACTIONS.POST_COMMENT, + type: NODE_ACTIONS.POST_LOCAL_COMMENT, }); export const nodeSetSendingComment = (is_sending_comment: boolean) => ({ @@ -60,34 +60,6 @@ export const nodeSetComments = (comments: IComment[]) => ({ type: NODE_ACTIONS.SET_COMMENTS, }); -export const nodeUpdateTags = (id: INode['id'], tags: string[]) => ({ - type: NODE_ACTIONS.UPDATE_TAGS, - id, - tags, -}); - -export const nodeDeleteTag = (id: INode['id'], tagId: ITag['ID']) => ({ - type: NODE_ACTIONS.DELETE_TAG, - id: id!, - tagId, -}); - -export const nodeSetTags = (tags: ITag[]) => ({ - type: NODE_ACTIONS.SET_TAGS, - tags, -}); - -export const nodeCreate = (node_type: INode['type'], isLab?: boolean) => ({ - type: NODE_ACTIONS.CREATE, - node_type, - isLab, -}); - -export const nodeEdit = (id: INode['id']) => ({ - type: NODE_ACTIONS.EDIT, - id, -}); - export const nodeLike = (id: INode['id']) => ({ type: NODE_ACTIONS.LIKE, id, @@ -104,17 +76,13 @@ export const nodeLock = (id: INode['id'], is_locked: boolean) => ({ is_locked, }); -export const nodeLockComment = (id: IComment['id'], is_locked: boolean) => ({ +export const nodeLockComment = (id: number, is_locked: boolean, nodeId: number) => ({ type: NODE_ACTIONS.LOCK_COMMENT, + nodeId, id, is_locked, }); -export const nodeEditComment = (id: IComment['id']) => ({ - type: NODE_ACTIONS.EDIT_COMMENT, - id, -}); - export const nodeSetEditor = (editor: INode) => ({ type: NODE_ACTIONS.SET_EDITOR, editor, diff --git a/src/redux/node/constants.ts b/src/redux/node/constants.ts index 5fdd5868..314d7ad1 100644 --- a/src/redux/node/constants.ts +++ b/src/redux/node/constants.ts @@ -29,13 +29,11 @@ export const NODE_ACTIONS = { GOTO_NODE: `${prefix}GOTO_NODE`, SET: `${prefix}SET`, - EDIT: `${prefix}EDIT`, LIKE: `${prefix}LIKE`, STAR: `${prefix}STAR`, LOCK: `${prefix}LOCK`, LOCK_COMMENT: `${prefix}LOCK_COMMENT`, EDIT_COMMENT: `${prefix}EDIT_COMMENT`, - CREATE: `${prefix}CREATE`, LOAD_MORE_COMMENTS: `${prefix}LOAD_MORE_COMMENTS`, SET_SAVE_ERRORS: `${prefix}SET_SAVE_ERRORS`, @@ -45,13 +43,10 @@ export const NODE_ACTIONS = { SET_CURRENT: `${prefix}SET_CURRENT`, SET_EDITOR: `${prefix}SET_EDITOR`, - POST_COMMENT: `${prefix}POST_LOCAL_COMMENT`, + POST_LOCAL_COMMENT: `${prefix}POST_LOCAL_COMMENT`, SET_COMMENTS: `${prefix}SET_COMMENTS`, SET_RELATED: `${prefix}SET_RELATED`, - UPDATE_TAGS: `${prefix}UPDATE_TAGS`, - DELETE_TAG: `${prefix}DELETE_TAG`, - SET_TAGS: `${prefix}SET_TAGS`, SET_COVER_IMAGE: `${prefix}SET_COVER_IMAGE`, }; diff --git a/src/redux/node/handlers.ts b/src/redux/node/handlers.ts index 2bdd2da3..87b6d9dd 100644 --- a/src/redux/node/handlers.ts +++ b/src/redux/node/handlers.ts @@ -10,7 +10,6 @@ import { nodeSetLoadingComments, nodeSetSaveErrors, nodeSetSendingComment, - nodeSetTags, } from './actions'; import { INodeState } from './reducer'; @@ -41,9 +40,6 @@ const setSendingComment = ( const setComments = (state: INodeState, { comments }: ReturnType<typeof nodeSetComments>) => assocPath(['comments'], comments, state); -const setTags = (state: INodeState, { tags }: ReturnType<typeof nodeSetTags>) => - assocPath(['current', 'tags'], tags, state); - const setEditor = (state: INodeState, { editor }: ReturnType<typeof nodeSetEditor>) => assocPath(['editor'], editor, state); @@ -60,7 +56,6 @@ export const NODE_HANDLERS = { [NODE_ACTIONS.SET_CURRENT]: setCurrent, [NODE_ACTIONS.SET_SENDING_COMMENT]: setSendingComment, [NODE_ACTIONS.SET_COMMENTS]: setComments, - [NODE_ACTIONS.SET_TAGS]: setTags, [NODE_ACTIONS.SET_EDITOR]: setEditor, [NODE_ACTIONS.SET_COVER_IMAGE]: setCoverImage, }; diff --git a/src/redux/node/sagas.ts b/src/redux/node/sagas.ts index 7cc8cae2..df713aa0 100644 --- a/src/redux/node/sagas.ts +++ b/src/redux/node/sagas.ts @@ -1,11 +1,7 @@ import { call, put, select, takeLatest, takeLeading } from 'redux-saga/effects'; -import { push } from 'connected-react-router'; import { COMMENTS_DISPLAY, EMPTY_NODE, NODE_ACTIONS, NODE_EDITOR_DATA } from './constants'; import { - nodeCreate, - nodeDeleteTag, - nodeEdit, nodeGotoNode, nodeLike, nodeLoadNode, @@ -15,15 +11,9 @@ import { nodeSet, nodeSetComments, nodeSetCurrent, - nodeSetEditor, - nodeSetLoading, nodeSetLoadingComments, - nodeSetTags, - nodeUpdateTags, } from './actions'; import { - apiDeleteNodeTag, - apiGetNode, apiGetNodeComments, apiLockComment, apiLockNode, @@ -44,6 +34,7 @@ import { has } from 'ramda'; import { selectLabListNodes } from '~/redux/lab/selectors'; import { labSetList } from '~/redux/lab/actions'; import { apiPostNode } from '~/redux/node/api'; +import { showErrorToast } from '~/utils/errors/showToast'; export function* updateNodeEverywhere(node) { const { @@ -127,22 +118,9 @@ function* nodeGetComments(id: INode['id']) { } function* onNodeLoad({ id }: ReturnType<typeof nodeLoadNode>) { - // Get node body - try { - yield put(nodeSetLoading(true)); - yield put(nodeSetLoadingComments(true)); - - const { node, last_seen }: Unwrap<typeof apiGetNode> = yield call(apiGetNode, { id }); - - yield put(nodeSet({ current: node, lastSeenCurrent: last_seen })); - yield put(nodeSetLoading(false)); - } catch (error) { - yield put(push(URLS.ERRORS.NOT_FOUND)); - yield put(nodeSetLoading(false)); - } - // Comments try { + yield put(nodeSetLoadingComments(true)); yield call(nodeGetComments, id); yield put( @@ -160,82 +138,24 @@ function* onPostComment({ nodeId, comment, callback }: ReturnType<typeof nodePos id: nodeId, }); - const { current }: ReturnType<typeof selectNode> = yield select(selectNode); + const { comments }: ReturnType<typeof selectNode> = yield select(selectNode); - if (current?.id === nodeId) { - const { comments }: ReturnType<typeof selectNode> = yield select(selectNode); - - if (!comment.id) { - yield put(nodeSetComments([data.comment, ...comments])); - } else { - yield put( - nodeSet({ - comments: comments.map(item => (item.id === comment.id ? data.comment : item)), - }) - ); - } - - callback(); + if (!comment.id) { + yield put(nodeSetComments([data.comment, ...comments])); + } else { + yield put( + nodeSet({ + comments: comments.map(item => (item.id === comment.id ? data.comment : item)), + }) + ); } + + callback(); } catch (error) { return callback(error.message); } } -function* onUpdateTags({ id, tags }: ReturnType<typeof nodeUpdateTags>) { - try { - const { node }: Unwrap<typeof apiPostNodeTags> = yield call(apiPostNodeTags, { id, tags }); - const { current }: ReturnType<typeof selectNode> = yield select(selectNode); - if (!node || !node.id || node.id !== current.id) return; - yield put(nodeSetTags(node.tags)); - } catch {} -} - -function* onDeleteTag({ id, tagId }: ReturnType<typeof nodeDeleteTag>) { - try { - const { tags }: Unwrap<typeof apiDeleteNodeTag> = yield call(apiDeleteNodeTag, { id, tagId }); - yield put(nodeSetTags(tags)); - } catch {} -} - -function* onCreateSaga({ node_type: type, isLab }: ReturnType<typeof nodeCreate>) { - if (!type || !has(type, NODE_EDITOR_DIALOGS)) return; - - yield put( - nodeSetEditor({ - ...EMPTY_NODE, - ...(NODE_EDITOR_DATA[type] || {}), - type, - is_promoted: !isLab, - }) - ); - - yield put(modalShowDialog(NODE_EDITOR_DIALOGS[type])); -} - -function* onEditSaga({ id }: ReturnType<typeof nodeEdit>) { - try { - if (!id) { - return; - } - - yield put(modalShowDialog(DIALOGS.LOADING)); - - const { node }: Unwrap<typeof apiGetNode> = yield call(apiGetNode, { id }); - - if (!node.type || !has(node.type, NODE_EDITOR_DIALOGS)) return; - - if (!NODE_EDITOR_DIALOGS[node?.type]) { - throw new Error('Unknown node type'); - } - - yield put(nodeSetEditor(node)); - yield put(modalShowDialog(NODE_EDITOR_DIALOGS[node.type])); - } catch (error) { - yield put(modalSetShown(false)); - } -} - function* onLikeSaga({ id }: ReturnType<typeof nodeLike>) { const { current }: ReturnType<typeof selectNode> = yield select(selectNode); @@ -293,22 +213,12 @@ function* onLockSaga({ id, is_locked }: ReturnType<typeof nodeLock>) { } } -function* onLockCommentSaga({ id, is_locked }: ReturnType<typeof nodeLockComment>) { - const { current, comments }: ReturnType<typeof selectNode> = yield select(selectNode); +function* onLockCommentSaga({ nodeId, id, is_locked }: ReturnType<typeof nodeLockComment>) { + const { comments }: ReturnType<typeof selectNode> = yield select(selectNode); try { - yield put( - nodeSetComments( - comments.map(comment => - comment.id === id - ? { ...comment, deleted_at: is_locked ? new Date().toISOString() : undefined } - : comment - ) - ) - ); - const data: Unwrap<typeof apiLockComment> = yield call(apiLockComment, { - current: current.id, + current: nodeId, id, is_locked, }); @@ -320,25 +230,15 @@ function* onLockCommentSaga({ id, is_locked }: ReturnType<typeof nodeLockComment ) ) ); - } catch { - yield put( - nodeSetComments( - comments.map(comment => - comment.id === id ? { ...comment, deleted_at: current.deleted_at } : comment - ) - ) - ); + } catch (e) { + showErrorToast(e); } } export default function* nodeSaga() { yield takeLatest(NODE_ACTIONS.GOTO_NODE, onNodeGoto); yield takeLatest(NODE_ACTIONS.LOAD_NODE, onNodeLoad); - yield takeLatest(NODE_ACTIONS.POST_COMMENT, onPostComment); - yield takeLatest(NODE_ACTIONS.UPDATE_TAGS, onUpdateTags); - yield takeLatest(NODE_ACTIONS.DELETE_TAG, onDeleteTag); - yield takeLatest(NODE_ACTIONS.CREATE, onCreateSaga); - yield takeLatest(NODE_ACTIONS.EDIT, onEditSaga); + yield takeLatest(NODE_ACTIONS.POST_LOCAL_COMMENT, onPostComment); yield takeLatest(NODE_ACTIONS.LIKE, onLikeSaga); yield takeLatest(NODE_ACTIONS.STAR, onStarSaga); yield takeLatest(NODE_ACTIONS.LOCK, onLockSaga); diff --git a/src/utils/errors/showToast.ts b/src/utils/errors/showToast.ts new file mode 100644 index 00000000..ce357a56 --- /dev/null +++ b/src/utils/errors/showToast.ts @@ -0,0 +1,9 @@ +export const showErrorToast = (error: unknown) => { + if (!(error instanceof Error)) { + console.warn('catched strange exception', error); + return; + } + + // TODO: show toast or something + console.warn(error.message); +}; diff --git a/src/utils/hooks/node/useFullNode.ts b/src/utils/hooks/node/useFullNode.ts index 2f5e91dd..8ace61f7 100644 --- a/src/utils/hooks/node/useFullNode.ts +++ b/src/utils/hooks/node/useFullNode.ts @@ -13,7 +13,7 @@ export const useFullNode = (id: string) => { lastSeenCurrent, } = useShallowSelect(selectNode); - // useLoadNode(id); + useLoadNode(id); // useOnNodeSeen(node); return { node, comments, commentsCount, lastSeenCurrent, isLoading, isLoadingComments }; diff --git a/src/utils/hooks/node/useLoadNode.ts b/src/utils/hooks/node/useLoadNode.ts index 03eee3d0..8fc2f6c8 100644 --- a/src/utils/hooks/node/useLoadNode.ts +++ b/src/utils/hooks/node/useLoadNode.ts @@ -1,7 +1,6 @@ import { useEffect } from 'react'; -import { nodeGotoNode, nodeSetCurrent } from '~/redux/node/actions'; +import { nodeGotoNode } from '~/redux/node/actions'; import { useDispatch } from 'react-redux'; -import { EMPTY_NODE } from '~/redux/node/constants'; // useLoadNode loads node on id change export const useLoadNode = (id: any) => { @@ -9,9 +8,5 @@ export const useLoadNode = (id: any) => { useEffect(() => { dispatch(nodeGotoNode(parseInt(id, 10), undefined)); - - return () => { - dispatch(nodeSetCurrent(EMPTY_NODE)); - }; }, [dispatch, id]); }; diff --git a/src/utils/hooks/node/useNodeActions.ts b/src/utils/hooks/node/useNodeActions.ts index 389ed94a..04be1d72 100644 --- a/src/utils/hooks/node/useNodeActions.ts +++ b/src/utils/hooks/node/useNodeActions.ts @@ -1,12 +1,21 @@ import { INode } from '~/redux/types'; import { useCallback } from 'react'; import { useDispatch } from 'react-redux'; -import { nodeEdit, nodeLike, nodeLock, nodeStar } from '~/redux/node/actions'; +import { nodeLike, nodeLock, nodeStar } from '~/redux/node/actions'; +import { modalShowDialog } from '~/redux/modal/actions'; +import { NODE_EDITOR_DIALOGS } from '~/constants/dialogs'; export const useNodeActions = (node: INode) => { const dispatch = useDispatch(); - const onEdit = useCallback(() => dispatch(nodeEdit(node.id)), [dispatch, node]); + const onEdit = useCallback(() => { + if (!node.type) { + return; + } + + dispatch(modalShowDialog(NODE_EDITOR_DIALOGS[node.type])); + }, [dispatch, node]); + const onLike = useCallback(() => dispatch(nodeLike(node.id)), [dispatch, node]); const onStar = useCallback(() => dispatch(nodeStar(node.id)), [dispatch, node]); const onLock = useCallback(() => dispatch(nodeLock(node.id, !node.deleted_at)), [dispatch, node]); diff --git a/src/utils/hooks/node/useNodeComments.ts b/src/utils/hooks/node/useNodeComments.ts index 97511475..5b477e62 100644 --- a/src/utils/hooks/node/useNodeComments.ts +++ b/src/utils/hooks/node/useNodeComments.ts @@ -1,16 +1,16 @@ import { useCallback } from 'react'; import { nodeLoadMoreComments, nodeLockComment } from '~/redux/node/actions'; -import { IComment, INode } from '~/redux/types'; +import { IComment } from '~/redux/types'; import { useDispatch } from 'react-redux'; -export const useNodeComments = (id: INode['id']) => { +export const useNodeComments = (nodeId: number) => { const dispatch = useDispatch(); const onLoadMoreComments = useCallback(() => dispatch(nodeLoadMoreComments()), [dispatch]); const onDelete = useCallback( - (id: IComment['id'], locked: boolean) => dispatch(nodeLockComment(id, locked)), - [dispatch] + (id: IComment['id'], locked: boolean) => dispatch(nodeLockComment(id, locked, nodeId)), + [dispatch, nodeId] ); return { onLoadMoreComments, onDelete }; diff --git a/src/utils/hooks/node/useNodeTags.ts b/src/utils/hooks/node/useNodeTags.ts index 00cfe620..ff175f15 100644 --- a/src/utils/hooks/node/useNodeTags.ts +++ b/src/utils/hooks/node/useNodeTags.ts @@ -1,7 +1,5 @@ -import { useDispatch } from 'react-redux'; import { useHistory } from 'react-router'; import { useCallback } from 'react'; -import { nodeDeleteTag, nodeUpdateTags } from '~/redux/node/actions'; import { ITag } from '~/redux/types'; import { URLS } from '~/constants/urls'; import { useGetNode } from '~/utils/hooks/data/useGetNode'; @@ -9,7 +7,6 @@ import { apiDeleteNodeTag, apiPostNodeTags } from '~/redux/node/api'; export const useNodeTags = (id: number) => { const { update } = useGetNode(id); - const dispatch = useDispatch(); const history = useHistory(); const onChange = useCallback(