import React, { useEffect } from 'react'; import { Route, Routes, useLocation } from 'react-router-dom'; import { Helmet } from 'react-helmet-async'; import { useAccount, useBufferedFeeds } from '@plebbit/plebbit-react-hooks'; import 'react-tooltip/dist/react-tooltip.css'; import 'react-toastify/dist/ReactToastify.css'; import useGeneralStore from './hooks/stores/useGeneralStore'; import { GlobalStyle } from './components/styled/GlobalStyle.styled'; import { Toast } from './components/styled/Toast.styled'; import Board from './components/views/Board'; import Catalog from './components/views/Catalog'; import Home from './components/views/Home'; import NotFound from './components/views/NotFound'; import Pending from './components/views/Pending'; import Subscriptions from './components/views/Subscriptions'; import SubscriptionsCatalog from './components/views/SubscriptionsCatalog'; import Thread from './components/views/Thread'; import CaptchaModal from './components/CaptchaModal'; import { importAll } from './components/ImageBanner'; import preloadImages from './utils/preloadImages'; export default function App() { const { bodyStyle, setBodyStyle, defaultSubplebbits, setDefaultSubplebbits, isCaptchaOpen, setIsCaptchaOpen, setIsSettingsOpen, selectedStyle, setSelectedStyle, setShowPostForm, setShowPostFormLink, } = useGeneralStore(state => state); const location = useLocation(); const isHomeRoute = location.pathname === "/"; const account = useAccount(); // preload default subs and subscriptions useBufferedFeeds({ feedsOptions: [ {subplebbitAddresses: defaultSubplebbits.map( (subplebbit) => subplebbit.address ), sortType: 'new'}, {subplebbitAddresses: account?.subscriptions, sortType: 'new'} ] }); // preload banners useEffect(() => { const loadImages = async () => { const images = await importAll(require.context('../public/assets', true, /\.(png|jpe?g|svg)$/)); const imageUrls = images.map((image) => image.default); preloadImages(imageUrls); }; loadImages(); }, []); // automatic dark mode without interefering with user's selected style useEffect(() => { if (isHomeRoute) return; const darkModeMediaQuery = window.matchMedia('(prefers-color-scheme: dark)'); const isDarkMode = darkModeMediaQuery.matches; if (isDarkMode && !isHomeRoute) { setSelectedStyle('Tomorrow'); setBodyStyle({ background: '#1d1f21 none', color: '#c5c8c6', fontFamily: 'Arial, Helvetica, sans-serif' }); localStorage.setItem('selectedStyle', 'Tomorrow'); } const darkModeListener = (e) => { if (e.matches && !isHomeRoute) { setSelectedStyle('Tomorrow'); setBodyStyle({ background: '#1d1f21 none', color: '#c5c8c6', fontFamily: 'Arial, Helvetica, sans-serif' }); localStorage.setItem('selectedStyle', 'Tomorrow'); } }; darkModeMediaQuery.addEventListener('change', darkModeListener); return () => { darkModeMediaQuery.removeEventListener('change', darkModeListener); }; }, [isHomeRoute, setBodyStyle, setSelectedStyle]); // fetch default subplebbits 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; }; }, [setDefaultSubplebbits]); // handle nested routes useEffect(() => { const path = location.pathname; if (path.endsWith('/post')) { setShowPostFormLink(false); setShowPostForm(true); } else { setShowPostFormLink(true); setShowPostForm(false); } if (path.endsWith('/settings')) { setIsSettingsOpen(true); } else { setIsSettingsOpen(false); } }, [location.pathname, setIsSettingsOpen, setShowPostForm, setShowPostFormLink]); return (
} /> }> } /> } /> }> } /> } /> }> } /> } /> }> } /> }> } /> }> } /> } /> setIsCaptchaOpen(false)} />
)}