From ff8882ce9c32aac0034a6b09b18979eca0d26d1b Mon Sep 17 00:00:00 2001 From: "plebeius.eth" Date: Mon, 29 Apr 2024 12:35:37 +0200 Subject: [PATCH] perf: abstract reply modal logic into hook for post page and board page --- src/hooks/use-reply-modal.ts | 29 +++++++++++++++++++++++++++++ src/views/board/board.tsx | 30 ++++++------------------------ src/views/post-page/post-page.tsx | 13 +++++++++++-- 3 files changed, 46 insertions(+), 26 deletions(-) create mode 100644 src/hooks/use-reply-modal.ts diff --git a/src/hooks/use-reply-modal.ts b/src/hooks/use-reply-modal.ts new file mode 100644 index 00000000..01e3ddc8 --- /dev/null +++ b/src/hooks/use-reply-modal.ts @@ -0,0 +1,29 @@ +import { useState, useCallback } from 'react'; + +const useReplyModal = () => { + const [showReplyModal, setShowReplyModal] = useState(false); + const [activeCid, setActiveCid] = useState(null); + + const openReplyModal = useCallback( + (cid: string) => { + if (activeCid && activeCid !== cid) { + closeModal(); // close modal if a different CID is clicked + setActiveCid(cid); + setShowReplyModal(true); + } else if (!activeCid) { + setActiveCid(cid); + setShowReplyModal(true); + } + }, + [activeCid], + ); + + const closeModal = useCallback(() => { + setActiveCid(null); + setShowReplyModal(false); + }, []); + + return { showReplyModal, activeCid, openReplyModal, closeModal }; +}; + +export default useReplyModal; diff --git a/src/views/board/board.tsx b/src/views/board/board.tsx index 062c34df..b7018cb9 100644 --- a/src/views/board/board.tsx +++ b/src/views/board/board.tsx @@ -1,10 +1,11 @@ -import { useEffect, useMemo, useRef, useState } from 'react'; +import { useEffect, useMemo, useRef } from 'react'; import { useParams } from 'react-router-dom'; import { useFeed, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { Virtuoso, VirtuosoHandle, StateSnapshot } from 'react-virtuoso'; import { useTranslation } from 'react-i18next'; import styles from './board.module.css'; import useFeedStateString from '../../hooks/use-feed-state-string'; +import useReplyModal from '../../hooks/use-reply-modal'; import LoadingEllipsis from '../../components/loading-ellipsis'; import Post from '../../components/post'; import ReplyModal from '../../components/reply-modal'; @@ -23,6 +24,8 @@ const Board = () => { const subplebbit = useSubplebbit({ subplebbitAddress }); const { createdAt, description, rules, shortAddress, state, suggested, title } = subplebbit || {}; + const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal(); + const loadingStateString = useFeedStateString(subplebbitAddresses) || t('loading'); const loadingString =
{state === 'failed' ? state : }
; @@ -53,27 +56,6 @@ const Board = () => { const lastVirtuosoState = lastVirtuosoStates?.[subplebbitAddress + sortType]; - const [showReplyModal, setShowReplyModal] = useState(false); - const [activeCid, setActiveCid] = useState(null); - - const openReplyModal = (cid: string) => { - if (activeCid && activeCid !== cid) { - closeModal(); - setActiveCid(cid); - setShowReplyModal(true); - } else if (!activeCid) { - setActiveCid(cid); - setShowReplyModal(true); - } else { - return; - } - }; - - const closeModal = () => { - setActiveCid(null); - setShowReplyModal(false); - }; - useEffect(() => { document.title = title ? title : shortAddress; }, [title, shortAddress]); @@ -95,9 +77,9 @@ const Board = () => { data={feed} itemContent={(index, post) => { const { deleted, locked, removed } = post || {}; - const isThreadLocked = deleted || locked || removed; + const isThreadClosed = deleted || locked || removed; - return alert(t('thread_closed_alert')) : openReplyModal} />; + return alert(t('thread_closed_alert')) : openReplyModal} />; }} useWindowScroll={true} components={{ Footer }} diff --git a/src/views/post-page/post-page.tsx b/src/views/post-page/post-page.tsx index 9f96b459..3d50d627 100644 --- a/src/views/post-page/post-page.tsx +++ b/src/views/post-page/post-page.tsx @@ -1,13 +1,17 @@ import { useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; import { useComment, useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { useLocation, useParams } from 'react-router-dom'; -import { isDescriptionView, isRulesView } from '../../lib/utils/view-utils'; import styles from './post-page.module.css'; +import { isDescriptionView, isRulesView } from '../../lib/utils/view-utils'; +import useReplyModal from '../../hooks/use-reply-modal'; import Post from '../../components/post'; +import ReplyModal from '../../components/reply-modal'; import SubplebbitDescription from '../../components/subplebbit-description'; import SubplebbitRules from '../../components/subplebbit-rules'; const PostPage = () => { + const { t } = useTranslation(); const params = useParams(); const { commentCid, subplebbitAddress } = params; @@ -18,7 +22,11 @@ const PostPage = () => { const isInDescriptionView = isDescriptionView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params); + const { showReplyModal, activeCid, openReplyModal, closeModal } = useReplyModal(); + const post = useComment({ commentCid }); + const { deleted, locked, removed } = post || {}; + const isThreadClosed = deleted || locked || removed; useEffect(() => { window.scrollTo(0, 0); @@ -26,12 +34,13 @@ const PostPage = () => { return (
+ {showReplyModal && activeCid && } {isInDescriptionView ? ( ) : isInRulesView ? ( ) : ( - + alert(t('thread_closed_alert')) : openReplyModal} /> )}
);