);
};
// Directory rules come straight from the directories JSON (defaults), so a whole category renders at once without a P2P fetch.
const CategoryRulesBox = ({ group, defaults }: { group: CategoryGroup; defaults: DirectoryDefaultsData }) => (
{group.label}
{group.communities.map((community, index) => (
{/* Separator below each entry except the last (matches 4chan's between board rules). */}
{index < group.communities.length - 1 && }
))}
);
// Quick-jump nav (left column) grouped by category; clicking a directory insta-scrolls to its rules via /rules/:code.
const DirectoryNav = ({ groups }: { groups: CategoryGroup[] }) => (
Directories
);
// P2P board rules: fetched live from peers for an arbitrary board address.
const BoardRulesDisplay = ({ communityAddress }: { communityAddress: string }) => {
const { t } = useTranslation();
const communityIdentifier = useCommunityIdentifier(communityAddress);
const community = useCommunity(communityIdentifier ? { community: communityIdentifier } : undefined);
const { rules, state, shortAddress } = community || {};
const stateString = useStateString(community) || t('downloading_board');
const isLoaded = state === 'succeeded';
const displayTitle = `Rules for: ${shortAddress || communityAddress}`;
return (
);
};
// Load any board's own rules live from peers (P2P), separate from the static directory rules below.
// Once a board is loaded the action toggles to "Clear", which drops the result box and empties the input.
const LoadBoardRules = ({ onLoad, onClear, isLoaded }: { onLoad: (address: string) => void; onClear: () => void; isLoaded: boolean }) => {
const { t } = useTranslation();
const [customAddress, setCustomAddress] = useState('');
const handleSubmit = (e: FormEvent) => {
e.preventDefault();
const trimmed = customAddress.trim();
if (trimmed) {
onLoad(trimmed);
}
};
const handleClear = () => {
setCustomAddress('');
onClear();
};
return (
Load rules P2P from any board
);
};
const Rules = () => {
const { boardIdentifier } = useParams();
const directories = useDirectories();
const directoryDefaults = useDirectoryDefaults();
const [loadedAddress, setLoadedAddress] = useState('');
const scrolledForRef = useRef(null);
// Order directories alphabetically by directory code (e.g. /3/, /a/, /aco/...), like 4chan, not by title.
const directoriesWithCode = directories.filter((community) => getDirectoryCode(community)).toSorted((a, b) => getDirectoryCode(a).localeCompare(getDirectoryCode(b)));
const categoryGroups = groupDirectoriesByCategory(directoriesWithCode, directoryDefaults);
const handleLoad = (address: string) => {
setLoadedAddress(getCommunityAddress(address, directories));
};
useEffect(() => {
document.title = 'Rules - 5chan';
}, []);
useEffect(() => {
setLoadedAddress('');
if (!boardIdentifier) {
scrolledForRef.current = null;
window.scrollTo(0, 0);
}
}, [boardIdentifier]);
// Deep-link: /rules/:code insta-scrolls to that directory's rules once the matching section is rendered.
useEffect(() => {
if (!boardIdentifier || scrolledForRef.current === boardIdentifier) {
return;
}
const code = resolveDirectoryCode(boardIdentifier, directories);
const element = code ? document.getElementById(code) : null;
if (element) {
element.scrollIntoView();
scrolledForRef.current = boardIdentifier;
}
}, [boardIdentifier, directories]);
return (
Rules
5chan does not have global rules or moderators. It is a serverless, adminless, static tool for browsing and posting to decentralized imageboards.{' '}
Each directory sets its own rules, listed below and expected of the boards that host it; individual board owners and admins may add their
own.
Please read and respect the rules of whatever board you decide to post to.