feat(rules): add URL params for direct links to board rules

Support /rules/:boardIdentifier (e.g. /rules/pol, /rules/somedomain.eth).
Selection updates URL; rules page always uses yotsuba theme.
This commit is contained in:
plebeius
2026-02-20 16:12:52 +08:00
parent cb0ab3a698
commit 64c89533f0
3 changed files with 22 additions and 5 deletions
+1 -1
View File
@@ -194,7 +194,7 @@ const App = () => (
<Route element={<GlobalLayout />}> <Route element={<GlobalLayout />}>
<Route path='/' element={<Home />} /> <Route path='/' element={<Home />} />
<Route path='/faq' element={<FAQ />} /> <Route path='/faq' element={<FAQ />} />
<Route path='/rules' element={<Rules />} /> <Route path='/rules/:boardIdentifier?' element={<Rules />} />
<Route element={<BoardLayout />}> <Route element={<BoardLayout />}>
<Route path='/all/:timeFilterName?' element={null} /> <Route path='/all/:timeFilterName?' element={null} />
<Route path='/all/:timeFilterName?/settings' element={null} /> <Route path='/all/:timeFilterName?/settings' element={null} />
+5
View File
@@ -55,6 +55,11 @@ const useTheme = (): [string, (theme: string) => void] => {
return 'yotsuba'; return 'yotsuba';
} }
// Always use yotsuba for rules page (boardIdentifier in URL is for loading rules, not theming)
if (location.pathname.startsWith('/rules')) {
return 'yotsuba';
}
// If special theme is enabled, use tomorrow // If special theme is enabled, use tomorrow
if (isEnabled) { if (isEnabled) {
return 'tomorrow'; return 'tomorrow';
+16 -4
View File
@@ -1,7 +1,9 @@
import { useEffect, useState, FormEvent } from 'react'; import { useEffect, useState, FormEvent } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { useSubplebbit } from '@plebbit/plebbit-react-hooks';
import { Footer, HomeLogo } from '../home'; import { Footer, HomeLogo } from '../home';
import { useDirectories, DirectoryCommunity } from '../../hooks/use-directories'; import { useDirectories, DirectoryCommunity } from '../../hooks/use-directories';
import { getSubplebbitAddress, getBoardPath } from '../../lib/utils/route-utils';
import Markdown from '../../components/markdown'; import Markdown from '../../components/markdown';
import styles from './rules.module.css'; import styles from './rules.module.css';
@@ -110,8 +112,9 @@ const BoardSelector = ({
const handleCustomSubmit = (e: FormEvent) => { const handleCustomSubmit = (e: FormEvent) => {
e.preventDefault(); e.preventDefault();
if (customAddress.trim()) { const trimmed = customAddress.trim();
onSelect(customAddress.trim()); if (trimmed) {
onSelect(trimmed);
} }
}; };
@@ -133,6 +136,7 @@ const BoardSelector = ({
</option> </option>
); );
})} })}
{selectedAddress && !directories.some((sub) => sub.address === selectedAddress) && <option value={selectedAddress}>{selectedAddress}</option>}
</select> </select>
<span className={styles.orSeparator}>or</span> <span className={styles.orSeparator}>or</span>
<form onSubmit={handleCustomSubmit} className={styles.customAddressForm}> <form onSubmit={handleCustomSubmit} className={styles.customAddressForm}>
@@ -154,8 +158,16 @@ const BoardSelector = ({
}; };
const Rules = () => { const Rules = () => {
const { boardIdentifier } = useParams();
const navigate = useNavigate();
const directories = useDirectories(); const directories = useDirectories();
const [selectedAddress, setSelectedAddress] = useState('');
const selectedAddress = boardIdentifier ? getSubplebbitAddress(boardIdentifier, directories) : '';
const handleBoardSelect = (address: string) => {
const path = getBoardPath(address, directories);
navigate(`/rules/${path}`, { replace: true });
};
useEffect(() => { useEffect(() => {
window.scrollTo(0, 0); window.scrollTo(0, 0);
@@ -178,7 +190,7 @@ const Rules = () => {
Please read and respect the rules of whatever board you decide to post to. Please read and respect the rules of whatever board you decide to post to.
</div> </div>
</div> </div>
<BoardSelector directories={directories} selectedAddress={selectedAddress} onSelect={setSelectedAddress} /> <BoardSelector directories={directories} selectedAddress={selectedAddress} onSelect={handleBoardSelect} />
{selectedAddress && <BoardRulesDisplay subplebbitAddress={selectedAddress} directories={directories} />} {selectedAddress && <BoardRulesDisplay subplebbitAddress={selectedAddress} directories={directories} />}
<Footer /> <Footer />
</div> </div>