import React, { useState, useEffect, useContext } from 'react'; import { Link, useNavigate, useParams } from 'react-router-dom'; import { Container, NavBar, Header, Break, PostForm, PostFormLink, PostFormTable } from './styles/Board.styled'; import { TopBar } from './styles/Thread.styled'; import { Threads } from './styles/Catalog.styled'; import { BoardContext } from '../App'; import { useFeed, useAccountsActions } from '@plebbit/plebbit-react-hooks'; import ImageBanner from './ImageBanner'; import InfiniteScroll from 'react-infinite-scroller'; const Catalog = ({ setBodyStyle }) => { const [defaultSubplebbits, setDefaultSubplebbits] = useState([]); const { selectedTitle, setSelectedTitle, selectedAddress, setSelectedAddress, setSelectedThread, selectedStyle, setSelectedStyle } = useContext(BoardContext); const [showPostFormLink, setShowPostFormLink] = useState(true); const [showPostForm, setShowPostForm] = useState(false); const [name, setName] = useState(''); const [subject, setSubject] = useState(''); const [comment, setComment] = useState(''); const navigate = useNavigate(); const [prevScrollPos, setPrevScrollPos] = useState(0); const [visible, setVisible] = useState(true); const { publishComment } = useAccountsActions(); const { feed, hasMore, loadMore } = useFeed([`${selectedAddress}`], 'new'); const { subplebbitAddress } = useParams(); useEffect(() => { setSelectedAddress(subplebbitAddress); const selectedSubplebbit = defaultSubplebbits.find((subplebbit) => subplebbit.address === subplebbitAddress); if (selectedSubplebbit) { setSelectedTitle(selectedSubplebbit.title); } }, [subplebbitAddress, setSelectedAddress, setSelectedTitle, defaultSubplebbits]); useEffect(() => { let didCancel = false; fetch( "https://raw.githubusercontent.com/plebbit/temporary-default-subplebbits/master/subplebbits.json", { cache: "no-cache" } ) .then((res) => res.json()) .then(res => { if (!didCancel) { setDefaultSubplebbits(res); } }); return () => { didCancel = true; }; }, []); useEffect(() => { const handleScroll = () => { const currentScrollPos = window.pageYOffset; setVisible(prevScrollPos > currentScrollPos || currentScrollPos < 10); setPrevScrollPos(currentScrollPos); }; window.addEventListener('scroll', handleScroll); return () => window.removeEventListener('scroll', handleScroll); }, [prevScrollPos, visible]); const tryLoadMore = async () => { try {loadMore()} catch (e) {await new Promise(resolve => setTimeout(resolve, 1000))} } const onChallengeVerification = (challengeVerification) => { if (challengeVerification.challengeSuccess === true) { console.log('challenge success', {publishedCid: challengeVerification.publication.cid}) } else if (challengeVerification.challengeSuccess === false) { console.error('challenge failed', {reason: challengeVerification.reason, errors: challengeVerification.errors}); alert("Error: You seem to have mistyped the CAPTCHA. Please try again."); } } const onChallenge = async (challenges, comment) => { let challengeAnswers = []; try { challengeAnswers = await getChallengeAnswersFromUser(challenges) } catch (error) { console.log(error); } if (challengeAnswers) { await comment.publishChallengeAnswers(challengeAnswers) } } const onError = (error) => console.error(error) const getChallengeAnswersFromUser = async (challenges) => { return new Promise((resolve, reject) => { const imageString = challenges?.challenges[0].challenge; const imageSource = `data:image/png;base64,${imageString}`; const challengeImg = new Image(); challengeImg.src = imageSource; challengeImg.onload = () => { const inputEl = document.getElementById('t-resp'); const cntEl = document.getElementById('t-cnt'); cntEl.appendChild(challengeImg); inputEl.focus(); const handleKeyDown = (event) => { if (event.key === 'Enter') { const challengeResponse = inputEl.value; inputEl.value = ''; if (cntEl.contains(challengeImg)) { cntEl.removeChild(challengeImg); } document.removeEventListener('keydown', handleKeyDown); resolve(challengeResponse); } }; document.addEventListener('keydown', handleKeyDown); }; challengeImg.onerror = () => { reject(new Error('Could not load challenge image')); }; }); }; const handleVoidClick = () => {} const handleClickTitle = (title, address) => { setSelectedTitle(title); setSelectedAddress(address); }; const handleSelectChange = (event) => { const selected = event.target.value; const selectedTitle = defaultSubplebbits.find((subplebbit) => subplebbit.address === selected).title; setSelectedTitle(selectedTitle); setSelectedAddress(selected); navigate(`/${selected}`); } const handleClickHelp = () => { alert("- The CAPTCHA loads after you click \"Post\" \n- The CAPTCHA is case-sensitive. \n- Make sure to not block any cookies set by plebchan."); }; const handleClickForm = () => { setShowPostFormLink(false); setShowPostForm(true); navigate(`/${selectedAddress}/catalog/post`); }; const handleClickThread = (thread) => { setSelectedThread(thread); } const handlePublishComment = async () => { // Event.preventDefault(); try { const pendingComment = await publishComment({ content: comment, title: subject, subplebbitAddress: selectedAddress, onChallengeVerification, onChallenge, onError, }); console.log(`Comment pending with index: ${pendingComment.index}`); setName(''); setSubject(''); setComment(''); } catch (error) { console.error(error); } }; const handleStyleChange = (event) => { switch (event.target.value) { case "Yotsuba": setBodyStyle({ background: "#ffe url(/assets/fade.png) top repeat-x", color: "maroon", fontFamily: "Arial, Helvetica, sans-serif" }); setSelectedStyle("Yotsuba"); break; case "Yotsuba B": setBodyStyle({ background: "#eef2ff url(/assets/fade-blue.png) top center repeat-x", color: "#000", fontFamily: "Arial, Helvetica, sans-serif" }); setSelectedStyle("Yotsuba B"); break; case "Futaba": setBodyStyle({ background: "#ffe", color: "maroon", fontFamily: "times new roman, serif" }); setSelectedStyle("Futaba"); break; case "Burichan": setBodyStyle({ background: "#eef2ff", color: "#000", fontFamily: "times new roman, serif" }); setSelectedStyle("Burichan"); break; case "Tomorrow": setBodyStyle({ background: "#1d1f21 none", color: "#c5c8c6", fontFamily: "Arial, Helvetica, sans-serif" }); setSelectedStyle("Tomorrow"); break; case "Photon": setBodyStyle({ background: "#eee none", color: "#333", fontFamily: "Arial, Helvetica, sans-serif" }); setSelectedStyle("Photon"); break; default: setBodyStyle({ background: "#ffe url(/assets/fade.png) top repeat-x", color: "maroon", fontFamily: "Arial, Helvetica, sans-serif" }); setSelectedStyle("Yotsuba"); } } return ( <> {defaultSubplebbits.map(subplebbit => ( [ handleClickTitle(subplebbit.title, subplebbit.address)} >{subplebbit.title} ]  ))} [ Settings ] [ handleStyleChange({target: {value: "Yotsuba"}} )}>Home ]
Board  
Settings   handleStyleChange({target: {value: "Yotsuba"}} )}>Home
 
 
<>
<>
{selectedTitle}
p/{selectedAddress}
[ event.target.style.cursor='pointer'}>Start a New Thread ]
event.target.style.cursor='pointer'}>Start a New Thread
Name setName(event.target.value)} /> Subject setSubject(event.target.value)} /> Comment Verification
Embed File

Style:  
[ Return ]
Return

Loading...} > {feed.map(thread => { return (
handleClickThread(thread.cid)}>
R: {thread.replyCount}
{thread.title ? `${thread.title}` : null} {thread.content ? `: ${thread.content}` : null}
)})}
); } export default Catalog;