mirror of
https://github.com/bitsocialnet/5chan.git
synced 2026-08-03 07:41:04 +02:00
refactor(routing): migrate to directory-based board routing
This commit is contained in:
@@ -8,6 +8,7 @@ import { shouldShowSnow } from '../../lib/snow';
|
||||
import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-utils';
|
||||
import { isAllView, isSubscriptionsView, isModView } from '../../lib/utils/view-utils';
|
||||
import { useDefaultSubplebbitAddresses } from '../../hooks/use-default-subplebbits';
|
||||
import { useResolvedSubplebbitAddress, useBoardPath } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import { useFeedStateString } from '../../hooks/use-state-string';
|
||||
import useTimeFilter from '../../hooks/use-time-filter';
|
||||
import useInterfaceSettingsStore from '../../stores/use-interface-settings-store';
|
||||
@@ -35,7 +36,8 @@ const createThreadsWithoutImagesFilter = () => ({
|
||||
const Board = () => {
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
||||
const subplebbitAddress = useResolvedSubplebbitAddress();
|
||||
const boardPath = useBoardPath(subplebbitAddress);
|
||||
const { hideThreadsWithoutImages } = useInterfaceSettingsStore();
|
||||
|
||||
const isInAllView = isAllView(location.pathname);
|
||||
@@ -194,7 +196,7 @@ const Board = () => {
|
||||
i18nKey='more_threads_last_week'
|
||||
values={{ currentTimeFilterName, count: feed.length }}
|
||||
components={{
|
||||
1: <Link to={(isInAllView ? '/p/all' : isInSubscriptionsView ? '/p/subscriptions' : isInModView ? '/p/mod' : `/p/${subplebbitAddress}`) + '/1w'} />,
|
||||
1: <Link to={(isInAllView ? '/all' : isInSubscriptionsView ? '/subscriptions' : isInModView ? '/mod' : `/${boardPath}`) + '/1w'} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -204,7 +206,7 @@ const Board = () => {
|
||||
i18nKey='more_threads_last_month'
|
||||
values={{ currentTimeFilterName, count: feed.length }}
|
||||
components={{
|
||||
1: <Link to={(isInAllView ? '/p/all' : isInSubscriptionsView ? '/p/subscriptions' : isInModView ? '/p/mod' : `/p/${subplebbitAddress}`) + '/1m'} />,
|
||||
1: <Link to={(isInAllView ? '/all' : isInSubscriptionsView ? '/subscriptions' : isInModView ? '/mod' : `/${boardPath}`) + '/1m'} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -7,6 +7,7 @@ import { getCommentMediaInfo, getHasThumbnail } from '../../lib/utils/media-util
|
||||
import { isAllView, isSubscriptionsView } from '../../lib/utils/view-utils';
|
||||
import useCatalogFeedRows from '../../hooks/use-catalog-feed-rows';
|
||||
import { useDefaultSubplebbits } from '../../hooks/use-default-subplebbits';
|
||||
import { useResolvedSubplebbitAddress, useBoardPath } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import { useFeedStateString } from '../../hooks/use-state-string';
|
||||
import useTimeFilter from '../../hooks/use-time-filter';
|
||||
import useWindowWidth from '../../hooks/use-window-width';
|
||||
@@ -125,7 +126,8 @@ const createCombinedFilter = (
|
||||
const Catalog = () => {
|
||||
const { t } = useTranslation();
|
||||
const location = useLocation();
|
||||
const { subplebbitAddress } = useParams<{ subplebbitAddress: string }>();
|
||||
const subplebbitAddress = useResolvedSubplebbitAddress();
|
||||
const boardPath = useBoardPath(subplebbitAddress);
|
||||
|
||||
const isInAllView = isAllView(location.pathname);
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
@@ -366,7 +368,7 @@ const Catalog = () => {
|
||||
i18nKey='more_threads_last_week'
|
||||
values={{ currentTimeFilterName, count: feed.length }}
|
||||
components={{
|
||||
1: <Link to={(isInAllView ? '/p/all/catalog' : isInSubscriptionsView ? '/p/subscriptions/catalog' : `/p/${subplebbitAddress}/catalog`) + '/1w'} />,
|
||||
1: <Link to={(isInAllView ? '/all/catalog' : isInSubscriptionsView ? '/subscriptions/catalog' : `/${boardPath}/catalog`) + '/1w'} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
@@ -376,7 +378,7 @@ const Catalog = () => {
|
||||
i18nKey='more_threads_last_month'
|
||||
values={{ currentTimeFilterName, count: feed.length }}
|
||||
components={{
|
||||
1: <Link to={(isInAllView ? '/p/all/catalog' : isInSubscriptionsView ? '/p/subscriptions/catalog' : `/p/${subplebbitAddress}/catalog`) + '/1m'} />,
|
||||
1: <Link to={(isInAllView ? '/all/catalog' : isInSubscriptionsView ? '/subscriptions/catalog' : `/${boardPath}/catalog`) + '/1m'} />,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useDefaultSubplebbitsState, MultisubSubplebbit } from '../../../hooks/use-default-subplebbits';
|
||||
import { useDefaultSubplebbitsState, useDefaultSubplebbits, MultisubSubplebbit } from '../../../hooks/use-default-subplebbits';
|
||||
import { getBoardPath } from '../../../lib/utils/route-utils';
|
||||
import LoadingEllipsis from '../../../components/loading-ellipsis';
|
||||
import useDisclaimerModalStore from '../../../stores/use-disclaimer-modal-store';
|
||||
import useDirectoryModalStore from '../../../stores/use-directory-modal-store';
|
||||
@@ -34,16 +35,19 @@ const BoardsList = ({ multisub }: { multisub: MultisubSubplebbit[] }) => {
|
||||
const { showDisclaimerModal } = useDisclaimerModalStore();
|
||||
const { openDirectoryModal } = useDirectoryModalStore();
|
||||
const { useCatalogLinks, boardFilter } = useBoardsFilterStore();
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
|
||||
const handleLinkClick = (e: React.MouseEvent<HTMLAnchorElement>, address: string) => {
|
||||
e.preventDefault();
|
||||
showDisclaimerModal(address, navigate);
|
||||
const boardPath = getBoardPath(address, defaultSubplebbits);
|
||||
showDisclaimerModal(address, navigate, boardPath);
|
||||
};
|
||||
|
||||
// Helper to generate link URL with optional catalog suffix
|
||||
const getBoardLink = (address: string | null): string => {
|
||||
if (!address) return '#';
|
||||
return `/p/${address}${useCatalogLinks ? '/catalog' : ''}`;
|
||||
const boardPath = getBoardPath(address, defaultSubplebbits);
|
||||
return `/${boardPath}${useCatalogLinks ? '/catalog' : ''}`;
|
||||
};
|
||||
|
||||
// Handler for placeholder board links
|
||||
|
||||
@@ -9,7 +9,8 @@ import { getCommentMediaInfo } from '../../../lib/utils/media-utils';
|
||||
import { CatalogPostMedia } from '../../../components/catalog-row';
|
||||
import LoadingEllipsis from '../../../components/loading-ellipsis';
|
||||
import BoxModal from '../box-modal';
|
||||
import { MultisubSubplebbit } from '../../../hooks/use-default-subplebbits';
|
||||
import { MultisubSubplebbit, useDefaultSubplebbits } from '../../../hooks/use-default-subplebbits';
|
||||
import { getBoardPath } from '../../../lib/utils/route-utils';
|
||||
import { removeMarkdown } from '../../../lib/utils/post-utils';
|
||||
|
||||
interface PopularThreadProps {
|
||||
@@ -27,16 +28,18 @@ export const ContentPreview = ({ content, maxLength = 99 }: { content: string; m
|
||||
const PopularThreadCard = ({ post, multisub }: PopularThreadProps) => {
|
||||
const { cid, content, link, linkHeight, linkWidth, subplebbitAddress, thumbnailUrl, title } = post || {};
|
||||
const commentMediaInfo = getCommentMediaInfo(link, thumbnailUrl, linkWidth, linkHeight);
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
|
||||
// Find the matching MultisubSubplebbit entry and get its title
|
||||
const multisubEntry = multisub.find((ms) => ms?.address === subplebbitAddress);
|
||||
const boardTitle = multisubEntry?.title?.replace(/^\/[^/]+\/\s*-\s*/, '') || '';
|
||||
const boardPath = subplebbitAddress ? getBoardPath(subplebbitAddress, defaultSubplebbits) : '';
|
||||
|
||||
return (
|
||||
<div className={styles.popularThread} key={cid}>
|
||||
<div className={styles.title}>{boardTitle}</div>
|
||||
<div className={styles.mediaContainer}>
|
||||
<Link to={`/p/${subplebbitAddress}/c/${cid}`}>
|
||||
<Link to={`/${boardPath}/thread/${cid}`}>
|
||||
<CatalogPostMedia commentMediaInfo={commentMediaInfo} isOutOfFeed={true} cid={cid} />
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -13,7 +13,10 @@ const NotFoundImage = () => {
|
||||
|
||||
const NotFound = () => {
|
||||
const location = useLocation();
|
||||
const subplebbitAddress = location.pathname.startsWith('/p/') ? location.pathname.split('/')[2] : '';
|
||||
// Extract boardIdentifier from pathname (could be directory code or address)
|
||||
const pathParts = location.pathname.split('/').filter(Boolean);
|
||||
const boardIdentifier = pathParts[0] && pathParts[0] !== 'not-found' && pathParts[0] !== 'faq' ? pathParts[0] : '';
|
||||
const subplebbitAddress = boardIdentifier || '';
|
||||
const subplebbit = useSubplebbitsStore((state) => state.subplebbits[subplebbitAddress]);
|
||||
const { address, shortAddress } = subplebbit || {};
|
||||
|
||||
@@ -32,7 +35,7 @@ const NotFound = () => {
|
||||
<>
|
||||
<br />
|
||||
<div className={styles.backToBoard}>
|
||||
[<Link to={`/p/${subplebbitAddress}`}>Back to p/{shortAddress}</Link>]
|
||||
[<Link to={`/${boardIdentifier || subplebbitAddress}`}>Back to p/{shortAddress}</Link>]
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useNavigate, useParams } from 'react-router-dom';
|
||||
import { useAccountComment, useAccountComments } from '@plebbit/plebbit-react-hooks';
|
||||
import { useDefaultSubplebbits } from '../../hooks/use-default-subplebbits';
|
||||
import { getBoardPath } from '../../lib/utils/route-utils';
|
||||
import { Post } from '../post';
|
||||
|
||||
const PendingPost = () => {
|
||||
@@ -9,6 +11,7 @@ const PendingPost = () => {
|
||||
const commentIndex = accountCommentIndex ? parseInt(accountCommentIndex) : undefined;
|
||||
const post = useAccountComment({ commentIndex });
|
||||
const navigate = useNavigate();
|
||||
const defaultSubplebbits = useDefaultSubplebbits();
|
||||
|
||||
useEffect(() => window.scrollTo(0, 0), []);
|
||||
|
||||
@@ -28,9 +31,10 @@ const PendingPost = () => {
|
||||
|
||||
useEffect(() => {
|
||||
if (post?.cid && post?.subplebbitAddress) {
|
||||
navigate(`/p/${post?.subplebbitAddress}/c/${post?.cid}`, { replace: true });
|
||||
const boardPath = getBoardPath(post.subplebbitAddress, defaultSubplebbits);
|
||||
navigate(`/${boardPath}/thread/${post.cid}`, { replace: true });
|
||||
}
|
||||
}, [post, navigate]);
|
||||
}, [post, navigate, defaultSubplebbits]);
|
||||
|
||||
return <Post post={post} />;
|
||||
};
|
||||
|
||||
@@ -4,6 +4,7 @@ import { Comment, Role, useComment, useEditedComment, useSubplebbit } from '@ple
|
||||
import useSubplebbitsStore from '@plebbit/plebbit-react-hooks/dist/stores/subplebbits';
|
||||
import { useLocation, useParams } from 'react-router-dom';
|
||||
import { isAllView, isDescriptionView, isRulesView } from '../../lib/utils/view-utils';
|
||||
import { useResolvedSubplebbitAddress } from '../../hooks/use-resolved-subplebbit-address';
|
||||
import useIsMobile from '../../hooks/use-is-mobile';
|
||||
import ErrorDisplay from '../../components/error-display/error-display';
|
||||
import PostDesktop from '../../components/post-desktop';
|
||||
@@ -53,7 +54,8 @@ const PostPage = () => {
|
||||
const { t } = useTranslation();
|
||||
const params = useParams();
|
||||
const location = useLocation();
|
||||
const { commentCid, subplebbitAddress } = params;
|
||||
const { commentCid } = params;
|
||||
const subplebbitAddress = useResolvedSubplebbitAddress();
|
||||
const isInAllView = isAllView(location.pathname);
|
||||
const isInDescriptionView = isDescriptionView(location.pathname, params);
|
||||
const isInRulesView = isRulesView(location.pathname, params);
|
||||
@@ -101,7 +103,7 @@ const PostPage = () => {
|
||||
avatarUrl={suggested?.avatarUrl}
|
||||
createdAt={createdAt}
|
||||
description={description}
|
||||
replyCount={location.pathname.startsWith('/p/all/') ? 0 : rules?.length > 0 ? 1 : 0}
|
||||
replyCount={location.pathname.startsWith('/all/') ? 0 : rules?.length > 0 ? 1 : 0}
|
||||
subplebbitAddress={subplebbitAddress}
|
||||
shortAddress={shortAddress}
|
||||
title={title}
|
||||
|
||||
Reference in New Issue
Block a user