diff --git a/src/app.tsx b/src/app.tsx index 5ac2fb44..14803843 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -1,10 +1,10 @@ import { useEffect, useState } from 'react'; import { Outlet, Route, Routes, useLocation, useNavigate, useParams } from 'react-router-dom'; -import { useAccountComment } from '@plebbit/plebbit-react-hooks'; +import { useAccountComment, useAccountComments } from '@plebbit/plebbit-react-hooks'; import { isAllView, isSubscriptionsView } from './lib/utils/view-utils'; import useIsMobile from './hooks/use-is-mobile'; import useTheme from './hooks/use-theme'; -import { timeFilterNames } from './hooks/use-time-filter'; +import useTimeFilter from './hooks/use-time-filter'; import styles from './app.module.css'; import Board from './views/board'; import Catalog from './views/catalog'; @@ -20,20 +20,37 @@ import PostForm from './components/post-form'; import SubplebbitStats from './components/subplebbit-stats'; import TopBar from './components/topbar'; -const BoardLayout = () => { - const { accountCommentIndex, subplebbitAddress, timeFilterName } = useParams(); - const location = useLocation(); - const isMobile = useIsMobile(); - const isInAllView = isAllView(location.pathname, useParams()); - const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); - const pendingPost = useAccountComment({ commentIndex: accountCommentIndex ? parseInt(accountCommentIndex) : undefined }); +const CheckRouteParams = () => { + const { accountCommentIndex, timeFilterName } = useParams(); + const { timeFilterNames, lastVisitTimeFilterName } = useTimeFilter(); + const { accountComments } = useAccountComments(); - const isValidAccountCommentIndex = !accountCommentIndex || (!isNaN(Number(accountCommentIndex)) && Number(accountCommentIndex) >= 0); + const isValidAccountCommentIndex = + !accountCommentIndex || + (!isNaN(parseInt(accountCommentIndex)) && + parseInt(accountCommentIndex) >= 0 && + accountComments?.length > 0 && + parseInt(accountCommentIndex) < accountComments.length); - if (!isValidAccountCommentIndex || (timeFilterName && !timeFilterNames.includes(timeFilterName))) { + const isDynamicTimeFilter = (filter: string) => /^\d+[dwmy]$/.test(filter); + const isTimeFilterNameValid = + !timeFilterName || timeFilterNames.includes(timeFilterName as any) || timeFilterName === lastVisitTimeFilterName || isDynamicTimeFilter(timeFilterName); + + if (!isValidAccountCommentIndex || !isTimeFilterNameValid) { return ; } + return ; +}; + +const BoardLayout = () => { + const { accountCommentIndex, subplebbitAddress } = useParams(); + const location = useLocation(); + const isMobile = useIsMobile(); + const isInAllView = isAllView(location.pathname); + const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); + const pendingPost = useAccountComment({ commentIndex: accountCommentIndex ? parseInt(accountCommentIndex) : undefined }); + // force rerender of post form when navigating between pages, except when opening settings modal in current view const key = location.pathname.endsWith('/settings') ? `${subplebbitAddress}-${location.pathname.replace(/\/settings$/, '')}` @@ -108,33 +125,34 @@ const App = () => { } /> } /> } /> + }> + }> + } /> + } /> + } /> + } /> - }> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - } /> + } /> + } /> + } /> + } /> - } /> - } /> - } /> - } /> - - } /> - } /> + } /> + } /> + diff --git a/src/components/board-buttons/board-buttons.tsx b/src/components/board-buttons/board-buttons.tsx index 2ae00e4a..7db33822 100644 --- a/src/components/board-buttons/board-buttons.tsx +++ b/src/components/board-buttons/board-buttons.tsx @@ -178,10 +178,8 @@ const ShowOPCommentOption = () => { export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView, isTopbar = false }: BoardButtonsProps) => { const { t } = useTranslation(); - const params = useParams(); const navigate = useNavigate(); - const { timeFilterNames } = useTimeFilter(); - const selectedTimeFilterName = params.timeFilterName; + const { timeFilterName, timeFilterNames } = useTimeFilter(); const changeTimeFilter = (event: React.ChangeEvent) => { const timeFilterName = event.target.value; @@ -199,6 +197,8 @@ export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView const { sortType } = useSortingStore(); + const allTimeFilterNames = timeFilterName && !timeFilterNames.includes(timeFilterName) ? [timeFilterName, ...timeFilterNames.slice(1)] : timeFilterNames.slice(1); + return ( <> {!isTopbar ? ( @@ -208,10 +208,10 @@ export const TimeFilter = ({ isInAllView, isInCatalogView, isInSubscriptionsView ) : ( <> )} - + {allTimeFilterNames.map((name, i) => ( + ))} @@ -223,7 +223,7 @@ export const MobileBoardButtons = () => { const { t } = useTranslation(); const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInCatalogView = isCatalogView(location.pathname, params); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); @@ -317,7 +317,7 @@ export const DesktopBoardButtons = () => { const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); const subplebbitAddress = params?.subplebbitAddress || accountComment?.subplebbitAddress; const isInCatalogView = isCatalogView(location.pathname, params); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInPendingPostPage = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); diff --git a/src/components/board-header/board-header.tsx b/src/components/board-header/board-header.tsx index cf7f0ae9..1bf8227b 100644 --- a/src/components/board-header/board-header.tsx +++ b/src/components/board-header/board-header.tsx @@ -21,7 +21,7 @@ const ImageBanner = () => { const BoardHeader = () => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const accountComment = useAccountComment({ commentIndex: params?.accountCommentIndex as any }); diff --git a/src/components/catalog-row/catalog-row.tsx b/src/components/catalog-row/catalog-row.tsx index 58dc9fed..1f6ee37d 100644 --- a/src/components/catalog-row/catalog-row.tsx +++ b/src/components/catalog-row/catalog-row.tsx @@ -136,7 +136,7 @@ const CatalogPost = ({ post }: { post: Comment }) => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); const postLink = isInAllView && isDescription ? `/p/all/description` : `/p/${subplebbitAddress}/${isDescription ? 'description' : isRules ? 'rules' : `c/${cid}`}`; diff --git a/src/components/post-desktop/post-desktop.tsx b/src/components/post-desktop/post-desktop.tsx index 87c2dd66..8a31968b 100644 --- a/src/components/post-desktop/post-desktop.tsx +++ b/src/components/post-desktop/post-desktop.tsx @@ -61,7 +61,7 @@ const PostInfo = ({ openReplyModal, post, postReplyCount = 0, roles, isHidden }: const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInPostPageView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); diff --git a/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx b/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx index aef8c46d..a9ffcd7e 100644 --- a/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx +++ b/src/components/post-desktop/post-menu-desktop/post-menu-desktop.tsx @@ -147,7 +147,7 @@ const PostMenuDesktop = ({ post }: { post: Comment }) => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInCatalogView = isCatalogView(location.pathname, params); const isInPostPageView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); diff --git a/src/components/post-form/post-form.tsx b/src/components/post-form/post-form.tsx index 9f37ad76..97513fc0 100644 --- a/src/components/post-form/post-form.tsx +++ b/src/components/post-form/post-form.tsx @@ -44,7 +44,7 @@ const PostFormTable = ({ closeForm, postCid }: { closeForm: () => void; postCid: const subjectRef = useRef(null); const location = useLocation(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subscriptions = account?.subscriptions || []; const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); @@ -322,7 +322,7 @@ const PostForm = () => { const isInDescriptionView = isDescriptionView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const post = useComment({ commentCid: useParams().commentCid }); diff --git a/src/components/post-mobile/post-menu-mobile/post-menu-mobile.tsx b/src/components/post-mobile/post-menu-mobile/post-menu-mobile.tsx index 23b0ebba..e1d82fc3 100644 --- a/src/components/post-mobile/post-menu-mobile/post-menu-mobile.tsx +++ b/src/components/post-mobile/post-menu-mobile/post-menu-mobile.tsx @@ -59,7 +59,7 @@ const ViewOnButtons = ({ cid, isDescription, isRules, subplebbitAddress, onClose const { t } = useTranslation(); const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); const getViewOnOtherClientLink = () => { diff --git a/src/components/post-mobile/post-mobile.tsx b/src/components/post-mobile/post-mobile.tsx index b985538e..f2a5e421 100644 --- a/src/components/post-mobile/post-mobile.tsx +++ b/src/components/post-mobile/post-mobile.tsx @@ -36,7 +36,7 @@ const PostInfoAndMedia = ({ openReplyModal, post, postReplyCount = 0, roles }: P const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInPostPageView = isPostPageView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); @@ -349,7 +349,7 @@ const PostMobile = ({ openReplyModal, post, roles, showAllReplies, showReplies = const { isDescription, isRules } = post || {}; // custom properties, not from api const params = useParams(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInPendingPostView = isPendingPostView(location.pathname, params); const isInPostView = isPostPageView(location.pathname, params); const linksCount = useCountLinksInReplies(post); diff --git a/src/components/reply-modal/reply-modal.tsx b/src/components/reply-modal/reply-modal.tsx index 09537f4a..5c9182f4 100644 --- a/src/components/reply-modal/reply-modal.tsx +++ b/src/components/reply-modal/reply-modal.tsx @@ -120,7 +120,7 @@ const ReplyModal = ({ closeModal, showReplyModal, parentCid, postCid, scrollY, s }, [parentCid]); const location = useLocation(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const subplebbit = useSubplebbit({ subplebbitAddress }); const { updatedAt } = subplebbit || {}; diff --git a/src/components/subplebbit-description/subplebbit-description.tsx b/src/components/subplebbit-description/subplebbit-description.tsx index d392f351..3879055a 100644 --- a/src/components/subplebbit-description/subplebbit-description.tsx +++ b/src/components/subplebbit-description/subplebbit-description.tsx @@ -2,7 +2,7 @@ import { Post } from '../../views/post'; import { useTranslation } from 'react-i18next'; import { isAllView } from '../../lib/utils/view-utils'; import { useMultisubMetadata } from '../../hooks/use-default-subplebbits'; -import { useLocation, useParams } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; interface DescriptionPostProps { avatarUrl?: string; @@ -17,7 +17,7 @@ interface DescriptionPostProps { const SubplebbitDescription = ({ avatarUrl, createdAt, description, replyCount, shortAddress, subplebbitAddress, title }: DescriptionPostProps) => { const { t } = useTranslation(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const multisubMetadata = useMultisubMetadata(); const post = { diff --git a/src/components/topbar/topbar.tsx b/src/components/topbar/topbar.tsx index 21996c2b..55aa4f5e 100644 --- a/src/components/topbar/topbar.tsx +++ b/src/components/topbar/topbar.tsx @@ -130,7 +130,7 @@ const TopBarMobile = ({ subplebbitAddress }: { subplebbitAddress: string }) => { const location = useLocation(); const params = useParams(); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInCatalogView = isCatalogView(location.pathname, params); const isInSubscriptionsView = isSubscriptionsView(location.pathname, useParams()); const selectValue = isInAllView ? 'all' : isInSubscriptionsView ? 'subscriptions' : subplebbitAddress; diff --git a/src/hooks/use-catalog-feed-rows.ts b/src/hooks/use-catalog-feed-rows.ts index dbebd0fe..dd3d1f81 100644 --- a/src/hooks/use-catalog-feed-rows.ts +++ b/src/hooks/use-catalog-feed-rows.ts @@ -1,6 +1,6 @@ import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { useParams, useLocation } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; import { useAccountComments, Subplebbit } from '@plebbit/plebbit-react-hooks'; import useInterfaceSettingsStore from '../stores/use-interface-settings-store'; import { getCommentMediaInfo, getHasThumbnail } from '../lib/utils/media-utils'; @@ -15,7 +15,7 @@ const useCatalogFeedRows = (columnCount: number, feed: any, isFeedLoaded: boolea const { hideThreadsWithoutImages } = useInterfaceSettingsStore(); const location = useLocation(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const multisub = useMultisubMetadata(); const { accountComments } = useAccountComments(); diff --git a/src/hooks/use-initial-theme.ts b/src/hooks/use-initial-theme.ts index 2bf46d28..9f041663 100644 --- a/src/hooks/use-initial-theme.ts +++ b/src/hooks/use-initial-theme.ts @@ -17,7 +17,7 @@ const useInitialTheme = (pendingPostSubplebbitAddress?: string) => { const params = useParams(); const isInHomeView = isHomeView(location.pathname); const isInNotFoundView = isNotFoundView(location.pathname, params); - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); const isInPendingPostView = isPendingPostView(location.pathname, params); diff --git a/src/hooks/use-theme.ts b/src/hooks/use-theme.ts index bcff9cb8..6bc6dac4 100644 --- a/src/hooks/use-theme.ts +++ b/src/hooks/use-theme.ts @@ -34,7 +34,7 @@ const useTheme = (): [string, (theme: string) => void] => { const getCurrentTheme = useCallback(() => { const subplebbitAddress = params?.subplebbitAddress || pendingPostSubplebbitAddress; - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); let storedTheme = null; @@ -67,7 +67,7 @@ const useTheme = (): [string, (theme: string) => void] => { const setSubplebbitTheme = useCallback( async (newTheme: string) => { const subplebbitAddress = params?.subplebbitAddress || pendingPostSubplebbitAddress; - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSubscriptionsView = isSubscriptionsView(location.pathname, params); if (isInAllView || isInSubscriptionsView) { diff --git a/src/lib/utils/view-utils.ts b/src/lib/utils/view-utils.ts index 753d56bb..fedeaf7c 100644 --- a/src/lib/utils/view-utils.ts +++ b/src/lib/utils/view-utils.ts @@ -1,5 +1,3 @@ -import { timeFilterNames } from '../../hooks/use-time-filter'; - export type ParamsType = { accountCommentIndex?: string; commentCid?: string; @@ -7,25 +5,8 @@ export type ParamsType = { timeFilterName?: string; }; -export const isAllView = (pathname: string, params: ParamsType): boolean => { - const { timeFilterName } = params; - - if (timeFilterName && !timeFilterNames.includes(timeFilterName)) { - return false; - } - - return ( - pathname === '/p/all' || - pathname === '/p/all/settings' || - pathname === `/p/all/${timeFilterName}` || - pathname === `/p/all/${timeFilterName}/settings` || - pathname === '/p/all/catalog' || - pathname === '/p/all/catalog/settings' || - pathname === `/p/all/catalog/${timeFilterName}` || - pathname === `/p/all/catalog/${timeFilterName}/settings` || - pathname === '/p/all/description' || - pathname === '/p/all/description/settings' - ); +export const isAllView = (pathname: string): boolean => { + return pathname.startsWith('/p/all'); }; export const isBoardView = (pathname: string, params: ParamsType): boolean => { @@ -105,7 +86,7 @@ export const isSubscriptionsView = (pathname: string, params: ParamsType): boole export const isNotFoundView = (pathname: string, params: ParamsType): boolean => { return ( - !isAllView(pathname, params) && + !isAllView(pathname) && !isBoardView(pathname, params) && !isCatalogView(pathname, params) && !isDescriptionView(pathname, params) && diff --git a/src/views/board/board.tsx b/src/views/board/board.tsx index a04d5982..e0a92c07 100644 --- a/src/views/board/board.tsx +++ b/src/views/board/board.tsx @@ -35,7 +35,7 @@ const Board = () => { const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); const { hideThreadsWithoutImages } = useInterfaceSettingsStore(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const defaultSubplebbitAddresses = useDefaultSubplebbitAddresses(); const account = useAccount(); diff --git a/src/views/catalog/catalog.tsx b/src/views/catalog/catalog.tsx index d85e508c..a502f3d0 100644 --- a/src/views/catalog/catalog.tsx +++ b/src/views/catalog/catalog.tsx @@ -33,7 +33,7 @@ const Catalog = () => { const location = useLocation(); const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>(); - const isInAllView = isAllView(location.pathname, useParams()); + const isInAllView = isAllView(location.pathname); const defaultSubplebbits = useDefaultSubplebbits(); const { hideAdultBoards, hideGoreBoards } = useInterfaceSettingsStore(); const { hideThreadsWithoutImages } = useInterfaceSettingsStore(); @@ -153,7 +153,7 @@ const Catalog = () => { ); - const params = useParams(); + const params = useParams<{ sortType?: string; timeFilterName?: string }>(); const currentTimeFilterName = params?.timeFilterName || timeFilterName; const Footer = () => { diff --git a/src/views/post/post.tsx b/src/views/post/post.tsx index 63d3f81e..99cdb810 100644 --- a/src/views/post/post.tsx +++ b/src/views/post/post.tsx @@ -55,7 +55,7 @@ const PostPage = () => { const params = useParams(); const location = useLocation(); const { commentCid, subplebbitAddress } = params; - const isInAllView = isAllView(location.pathname, params); + const isInAllView = isAllView(location.pathname); const isInSettigsView = isSettingsView(location.pathname, params); const isInDescriptionView = isDescriptionView(location.pathname, params); const isInRulesView = isRulesView(location.pathname, params);