import { useEffect, useState, useRef } from "react"; import { useNavigate, useLocation } from "react-router-dom"; import { connectionBase } from './Global'; import { SetSnackType } from './Snack'; const getSessionId = async () => { const response = await fetch(connectionBase + `/api/context`, { method: 'POST', headers: { 'Content-Type': 'application/json', }, }); if (!response.ok) { throw Error("Server is temporarily down."); } const newSession = (await response.json()).id; console.log(`Session created: ${newSession}`); return newSession; }; interface SessionWrapperProps { setSnack: SetSnackType; children: React.ReactNode; } const SessionWrapper = ({ setSnack, children }: SessionWrapperProps) => { const navigate = useNavigate(); const location = useLocation(); const [sessionId, setSessionId] = useState(undefined); const fetchingRef = useRef(false); useEffect(() => { const ensureSessionId = async () => { const parts = location.pathname.split("/").filter(Boolean); const pattern = /^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-4[0-9a-fA-F]{3}-[89ab][0-9a-fA-F]{3}-[0-9a-fA-F]{12}$/i; const hasSession = parts.length !== 0 && pattern.test(parts[parts.length - 1]); if (!hasSession) { let activeSession = sessionId; if (!activeSession) { activeSession = await getSessionId(); setSessionId(activeSession); } const newPath = [...parts, activeSession].join("/"); navigate(`/${newPath}`, { replace: true }); } }; if (!fetchingRef.current) { fetchingRef.current = true; ensureSessionId().catch((e) => { console.error(e); setSnack("Backstory is temporarily unavailable.", "error"); }); } }, [location.pathname, navigate, setSnack, sessionId]); return <>{children}; }; export { SessionWrapper };