import React, { useCallback, useEffect, useRef, useState } from 'react'; import Feed from './components/feed'; import StreamMetadata from './components/feed/StreamMetadata'; import useStream from './contexts/Stream/useStream'; import useMobileBreakpoint from './contexts/MobileBreakpoint/useMobileBreakpoint'; import { useParams, useNavigate } from 'react-router-dom'; import './App.css'; const feedJSON = `${process.env.PUBLIC_URL}/feed.json`; const App = () => { const { isMobileView } = useMobileBreakpoint(); const { activeStream, setStreams } = useStream(); const [metadataVisible, setMetadataVisible] = useState(true); const metadataRef = useRef(); const params = useParams(); const navigate = useNavigate(); useEffect(() => { const fetchStreams = async () => { try { const response = await fetch(feedJSON); if (response.ok) { const { streams } = await response.json(); const paramsStreamId = parseInt(params.id); const streamIds = streams.map((s) => s.id); const initialStreamId = streamIds.includes(paramsStreamId) ? paramsStreamId : 0; setStreams(streams, initialStreamId); } else throw new Error(response.statusText); } catch (e) { console.error(e); } }; fetchStreams(); }, [setStreams]); // eslint-disable-line react-hooks/exhaustive-deps // Update the page URL for the active stream useEffect(() => { if (!activeStream) return; const activeStreamId = activeStream.data.id; if (activeStreamId !== params.id) { navigate(`/${activeStreamId}`, { replace: true }); } }, [activeStream, params.id, navigate]); useEffect(() => toggleMetadata(!isMobileView, false), [isMobileView]); // eslint-disable-line react-hooks/exhaustive-deps const toggleMetadata = useCallback( (show = !metadataVisible, transition = true) => { if (metadataRef.current) { const { scrollHeight: contentHeight, style } = metadataRef.current; style.transition = transition ? 'height 0.2s ease-out' : ''; if (show) { // Show metadata style.height = isMobileView ? `${contentHeight}px` : '100%'; metadataRef.current.addEventListener( 'transitionend', () => (style.height = null), { once: true } ); } else { // Hide metadata if (transition) { requestAnimationFrame(() => { style.height = `${contentHeight}px`; requestAnimationFrame(() => (style.height = '0')); }); } else style.height = '0'; } setMetadataVisible(show); } }, [metadataVisible, isMobileView] ); return (
); }; export default App;