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 Post from '../Post'; import CreateBoardModal from '../modals/CreateBoardModal'; import AdminListModal from '../modals/AdminListModal'; import OfflineIndicator from '../OfflineIndicator'; import SettingsModal from '../modals/SettingsModal'; import getDate from '../../utils/getDate'; import handleImageClick from '../../utils/handleImageClick'; import handleStyleChange from '../../utils/handleStyleChange'; import useGeneralStore from '../../hooks/stores/useGeneralStore'; import packageJson from '../../../package.json' const {version} = packageJson const Description = () => { const { defaultSubplebbits, isSettingsOpen, setIsSettingsOpen, selectedAddress, setSelectedAddress, selectedStyle, selectedThread, setSelectedThread, setSelectedTitle, } = useGeneralStore(state => state); 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 [isCreateBoardOpen, setIsCreateBoardOpen] = useState(false); 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 Description - " + (subplebbit.title || subplebbit.address) + " - plebchan"} setIsCreateBoardOpen(false)} /> setIsAdminListOpen(false)} roles={subplebbit.roles} /> setIsSettingsOpen(false)} /> <> [ window.scrollTo(0, 0)}>All  /  window.scrollTo(0, 0)}>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} ))} ] [ { window.electron && window.electron.isElectron ? ( setIsCreateBoardOpen(true) ) : ( alert( 'You can create a board with the desktop version of plebchan, which you can download from here: https://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, you can also run a board (called "subplebbit") using plebbit-cli: https://github.com/plebbit/plebbit-cli\n\n' ) ) } }>Create Board ] [ setIsSettingsOpen(true)}>Settings ] [ Home ]
Board     alert( 'You can create a board with the desktop version of plebchan, which you can download from here: https://github.com/plebbit/plebchan/releases/latest\n\nIf you are comfortable with the command line, you can also run a board (called "subplebbit") using plebbit-cli: https://github.com/plebbit/plebbit-cli\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 ] <>

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

{setIsAdminListOpen(!isAdminListOpen)}} >## Board Admins   Sticky   Closed
Welcome to {subplebbit.title || subplebbit.address}  
{getDate(subplebbit.createdAt)}  
{subplebbit.suggested?.avatarUrl ? (
board avatar
image
) : null}
{}} className="button-mobile">View Thread
); } export default Description;