import { useState, useEffect, useRef, Fragment, useCallback } from 'react'; import { Route, Link, Routes, useSearchParams } from 'react-router-dom'; import svg4everybody from 'svg4everybody'; import Icon from './ui/Icon'; import { Discover, Discussions, Blog, Tag, Home } from './ui/Feeds'; import { Friends, Readers } from './ui/Users'; import Settings from './ui/Settings'; import Contacts from './ui/Contacts'; import Chat from './ui/Chat'; import Header from './ui/Header'; import Post from './ui/Post'; import Thread from './ui/Thread'; import Login from './ui/Login'; import { useCookies } from 'react-cookie'; import { me, trends } from './api'; import { useVisitor } from './ui/VisitorContext'; import Avatar from './ui/Avatar'; /** * * @param {import('react').PropsWithChildren<{}> & { * footer: string * }} props props */ export default function App({ footer }) { let contentRef = useRef(null); const [cookie, setCookie] = useCookies(['hash']); const [allTrends, setAllTrends] = useState([]); const [visitor, setVisitor] = useVisitor(); const params = useSearchParams(); useEffect(() => { svg4everybody(); if (params['hash']) { setCookie('hash', params['hash'], { path: '/' }); let retpath = params['retpath'] || `${window.location.protocol}//${window.location.host}${window.location.pathname}`; window.history.replaceState({}, document.title, retpath); } }, [setCookie, footer, params]); let updateStatus = useCallback(() => { // refresh server visitor state (unread counters) me().then(visitor => { setVisitor(visitor); }).catch(console.error); }, [setVisitor]); const [hash, setHash] = useState(cookie.hash); const [eventSource, setEventSource] = /** @param EventSource? */ useState({}); /** * @param {import("./api").SecureUser} visitor */ let auth = useCallback((visitor) => { setVisitor(prevState => { if (visitor.hash != prevState.hash) { setHash(visitor.hash); } return visitor; }); }, [setVisitor]); useEffect(() => { let es; const anonymousUser = { uid: 0 }; if (hash) { me().then(visitor => auth(visitor)) .catch(() => setVisitor(anonymousUser)); if ('EventSource' in window) { const eventParams = new URLSearchParams({ hash: hash }); let url = new URL(`https://juick.com/api/events?${eventParams.toString()}`); console.log(url.toString()); es = new EventSource(url.toString()); es.onopen = () => { console.log('online'); }; es.onerror = () => { es.removeEventListener('read', updateStatus); es.removeEventListener('msg', updateStatus); }; es.addEventListener('read', updateStatus); es.addEventListener('msg', updateStatus); setEventSource(es); } } else { setVisitor(anonymousUser); } return (() => { if (es && es.removeEventListener) { es.removeEventListener('read', updateStatus); es.removeEventListener('msg', updateStatus); } }); }, [auth, hash, setVisitor, updateStatus]); useEffect(() => { const getTrends = async () => { setAllTrends(await trends()); }; getTrends().catch(console.error); }, []); return ( <>
{ }
} /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } /> } />
); }