import React, { useCallback, useEffect, useRef, useState } from 'react'; import { createPortal } from 'react-dom'; import { Helmet } from 'react-helmet-async'; import { Link, useNavigate, useParams } from 'react-router-dom'; import { Tooltip } from 'react-tooltip'; import { useSubplebbit } from '@plebbit/plebbit-react-hooks'; import { debounce } from 'lodash'; import { Container, NavBar, Header, Break, PostMenu, PostForm } from '../styled/views/Board.styled'; import { TopBar, BoardForm, Footer, ReplyFormLink} from '../styled/views/Thread.styled'; import { PostMenuCatalog } from '../styled/views/Catalog.styled'; import ImageBanner from '../ImageBanner'; import AdminListModal from '../modals/AdminListModal'; import OfflineIndicator from '../OfflineIndicator'; import SettingsModal from '../modals/SettingsModal'; import getDate from '../../utils/getDate'; import handleStyleChange from '../../utils/handleStyleChange'; import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson const Rules = () => { const { defaultSubplebbits, isSettingsOpen, setIsSettingsOpen, selectedAddress, setSelectedAddress, selectedStyle, selectedThread, setSelectedThread, setSelectedTitle, } = useGeneralStore(state => state); // temporary hardcode const plebtokenRules = [ "This community is strictly SFW. Any NSFW language or content will be removed.", Only post about the plebbit token ($PLEB). For general cryptocurrency discussion, go to p/business-and-finance.eth., "FUD is allowed unless blatantly meaningless and spammy." ] const navigate = useNavigate(); const threadMenuRefs = useRef({}); const postMenuRef = useRef(null); const postMenuCatalogRef = useRef(null); const [isAdminListOpen, setIsAdminListOpen] = useState(false); const [prevScrollPos, setPrevScrollPos] = useState(0); const [visible, setVisible] = useState(true); const [menuPosition, setMenuPosition] = useState({top: 0, left: 0}); const [openMenuCid, setOpenMenuCid] = useState(null); const { subplebbitAddress, threadCid } = useParams(); const subplebbit = useSubplebbit({subplebbitAddress: selectedAddress}); const handleOptionClick = () => { setOpenMenuCid(null); }; const handleOutsideClick = useCallback((e) => { if (openMenuCid !== null && !postMenuRef.current.contains(e.target) && !postMenuCatalogRef.current.contains(e.target)) { setOpenMenuCid(null); } }, [openMenuCid, postMenuRef, postMenuCatalogRef]); useEffect(() => { if (openMenuCid !== null) { document.addEventListener('click', handleOutsideClick); } else { document.removeEventListener('click', handleOutsideClick); } return () => { document.removeEventListener('click', handleOutsideClick); }; }, [openMenuCid, handleOutsideClick]); useEffect(() => { window.scrollTo(0, 0); }, []); // temporary title from JSON, gets subplebbitAddress and threadCid from URL useEffect(() => { setSelectedAddress(subplebbitAddress); setSelectedThread(threadCid); const selectedSubplebbit = defaultSubplebbits.find((subplebbit) => subplebbit.address === subplebbitAddress); if (selectedSubplebbit) { setSelectedTitle(selectedSubplebbit.title); } }, [subplebbitAddress, setSelectedAddress, setSelectedTitle, defaultSubplebbits, setSelectedThread, threadCid]); // mobile navbar scroll effect useEffect(() => { const debouncedHandleScroll = debounce(() => { const currentScrollPos = window.scrollY; setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 10); setPrevScrollPos(currentScrollPos); }, 50); window.addEventListener('scroll', debouncedHandleScroll); return () => window.removeEventListener('scroll', debouncedHandleScroll); }, [prevScrollPos, visible]); // mobile navbar board select functionality const handleSelectChange = (event) => { const selected = event.target.value; if (selected === 'subscriptions') { navigate(`/p/subscriptions`); return; } else if (selected === 'all') { navigate(`/p/all`); return; } const selectedTitle = defaultSubplebbits.find((subplebbit) => subplebbit.address === selected).title; setSelectedTitle(selectedTitle); setSelectedAddress(selected); navigate(`/p/${selected}`); }; return ( <> {"Board Rules - " + (subplebbit.title || subplebbit.address) + " - plebchan"} setIsAdminListOpen(false)} roles={subplebbit.roles} /> setIsSettingsOpen(false)} /> <> [ All  /  Subscriptions ] [ {defaultSubplebbits.map((subplebbit, index) => ( {index === 0 ? null : "\u00a0"} { setSelectedTitle(subplebbit.title); setSelectedAddress(subplebbit.address); }} >{subplebbit.title ? subplebbit.title : subplebbit.address} {index !== defaultSubplebbits.length - 1 ? " /" : null} ))} ] [ alert( 'To create a board, first you have to run a full node.\nYou can run a full node by simply browsing with the plebbit desktop app. After you download it, open it, wait for it loading, then click on "Home" in the top left, then "Create Community".\n\nAfter you create the community, you can go back to plebchan at any time to see it as a board by pasting its address (begins with p/12D3KooW...) in the search bar, which is in the Home.\n\nNote:\n\n- Your community will be online for as long as you leave the app open, because it functions like a server for the community.\n- The longer you leave the app open, the more data you are seeding to the protocol, which helps performance for everybody.\n - All the data in the plebbit protocol is just text, which is extremely lightweight. All media is generated by links, which is text, embedded by the clients.\n\nDownload the plebbit app here: https://github.com/plebbit/plebbit-react/releases\n\nYou can also use a CLI: https://github.com/plebbit/plebbit-cli\n\nRunning boards in the plebchan app is a planned feature.\n\n' ) }>Create Board ] [ setIsSettingsOpen(true)}>Settings ] [ Home ]
Board     alert( 'To create a board, first you have to run a full node.\nYou can run a full node by simply browsing with the plebbit desktop app. After you download it, open it, wait for it loading, then click on "Home" in the top left, then "Create Community".\n\nAfter you create the community, you can go back to plebchan at any time to see it as a board by pasting its address (begins with p/12D3KooW...) in the search bar, which is in the Home.\n\nNote:\n\n- Your community will be online for as long as you leave the app open, because it functions like a server for the community.\n- The longer you leave the app open, the more data you are seeding to the protocol, which helps performance for everybody.\n - All the data in the plebbit protocol is just text, which is extremely lightweight. All media is generated by links, which is text, embedded by the clients.\n\nDownload the plebbit app here: https://github.com/plebbit/plebbit-react/releases\n\nYou can also use a CLI: https://github.com/plebbit/plebbit-cli\n\nRunning boards in the plebchan app is a planned feature.\n\n' ) }>Create Board
setIsSettingsOpen(true)}>Settings   {handleStyleChange({target: {value: "Yotsuba"}}); window.scrollTo(0, 0);}}>Home
 
 
<>
<>
{subplebbit.title ?? null}
p/{subplebbit.address}
{window.scrollTo(0, 0)}}> Return
{window.scrollTo(0, 0)}}>Catalog
window.scrollTo(0, document.body.scrollHeight)} onMouseOver={(event) => event.target.style.cursor='pointer'}>Bottom
Style:   [ Return ] [ Catalog ] [ window.scrollTo(0, document.body.scrollHeight)} onMouseOver={(event) => event.target.style.cursor='pointer'} onTouchStart={() => window.scrollTo(0, document.body.scrollHeight)}>Bottom ] <>

Rules   {setIsAdminListOpen(!isAdminListOpen)}} >## Board Admins   {getDate(subplebbit.createdAt)}   Sticky   Closed   [ {}} style={{textDecoration: "none"}} className="reply-link">Reply ] { threadMenuRefs.current["rules"] = el; }} className='post-menu-button' rotated={openMenuCid === "rules"} onClick={(event) => { event.stopPropagation(); const rect = threadMenuRefs.current["rules"].getBoundingClientRect(); setMenuPosition({top: rect.top + window.scrollY, left: rect.left}); setOpenMenuCid(prevCid => (prevCid === "rules" ? null : "rules")); }} > ▶ {createPortal( {postMenuCatalogRef.current = el}} onClick={(event) => event.stopPropagation()} style={{position: "absolute", top: menuPosition.top + 7, left: menuPosition.left}}>
  • handleOptionClick("rules")}>Hide thread
  • {/* {isModerator ? ( <> change rules ) : null} */}
, document.body )}
{subplebbit.address === "plebtoken.eth" ? ( plebtokenRules.map((rule, index) => ( {index + 1}. {rule}
)) ) : ( subplebbit.rules?.map((rule, index) => ( {index + 1}. {rule}
)) )}

{setIsAdminListOpen(!isAdminListOpen)}} >## Board Admins   Sticky   Closed
Rules  
{getDate(subplebbit.createdAt)}  
{subplebbit.address === "plebtoken.eth" ? ( plebtokenRules.map((rule, index) => ( {index + 1}. {rule}
)) ) : ( subplebbit.rules?.map((rule, index) => ( {index + 1}. {rule}
)) )}
{}} className="button-mobile">View Thread
); } export default Rules;