Fix SPA with routes and no context

This commit is contained in:
James Ketr 2025-05-05 13:27:41 -07:00
parent 170abae7c0
commit 406d1c1dc1
2 changed files with 62 additions and 36 deletions

View File

@ -39,6 +39,7 @@ import '@fontsource/roboto/700.css';
import MuiMarkdown from 'mui-markdown'; import MuiMarkdown from 'mui-markdown';
const getConnectionBase = (loc: any): string => { const getConnectionBase = (loc: any): string => {
console.log(`getConnectionBase(${loc})`)
if (!loc.host.match(/.*battle-linux.*/)) { if (!loc.host.match(/.*battle-linux.*/)) {
return loc.protocol + "//" + loc.host; return loc.protocol + "//" + loc.host;
} else { } else {
@ -46,6 +47,8 @@ const getConnectionBase = (loc: any): string => {
} }
} }
const connectionBase = getConnectionBase(window.location);
interface TabProps { interface TabProps {
label?: string, label?: string,
path: string, path: string,
@ -57,9 +60,13 @@ interface TabProps {
} }
}; };
const isValidUUIDv4 = (str: string): 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;
return pattern.test(str);
}
const App = () => { const App = () => {
const [sessionId, setSessionId] = useState<string | undefined>(undefined); const [sessionId, setSessionId] = useState<string | undefined>(undefined);
const [connectionBase,] = useState<string>(getConnectionBase(window.location))
const [menuOpen, setMenuOpen] = useState(false); const [menuOpen, setMenuOpen] = useState(false);
const [isMenuClosing, setIsMenuClosing] = useState(false); const [isMenuClosing, setIsMenuClosing] = useState(false);
const [activeTab, setActiveTab] = useState<number>(0); const [activeTab, setActiveTab] = useState<number>(0);
@ -272,13 +279,10 @@ const App = () => {
</Scrollable> </Scrollable>
) )
}]; }];
}, [about, connectionBase, sessionId, setSnack, isMobile]); }, [about, sessionId, setSnack, isMobile]);
useEffect(() => { const fetchSession = useCallback((async (pathParts?: string[]) => {
const url = new URL(window.location.href);
const pathParts = url.pathname.split('/').filter(Boolean); // [path, sessionId]
const fetchSession = async () => {
try { try {
const response = await fetch(connectionBase + `/api/context`, { const response = await fetch(connectionBase + `/api/context`, {
method: 'POST', method: 'POST',
@ -290,33 +294,56 @@ const App = () => {
if (!response.ok) { if (!response.ok) {
throw Error("Server is temporarily down."); throw Error("Server is temporarily down.");
} }
const data = await response.json(); const new_session = (await response.json()).id;
console.log(`Session created: ${data.id}`); console.log(`Session created: ${new_session}`);
setSessionId(data.id);
const newPath = `/${data.id}`; if (pathParts === undefined) {
setSessionId(new_session);
const newPath = `/${new_session}`;
window.history.replaceState({}, '', newPath); window.history.replaceState({}, '', newPath);
} else {
const currentPath = pathParts.length < 2 ? '' : pathParts[0];
let tabIndex = tabs.findIndex((tab) => tab.path === currentPath);
if (-1 === tabIndex) {
console.log(`Invalid path "${currentPath}" -- redirecting to default`);
window.history.replaceState({}, '', `/${new_session}`);
setActiveTab(0);
} else {
window.history.replaceState({}, '', `/${pathParts.join('/')}/${new_session}`);
setActiveTab(tabIndex);
}
setSessionId(new_session);
}
} catch (error: any) { } catch (error: any) {
console.error(error); console.error(error);
setSnack("Server is temporarily down", "error"); setSnack("Server is temporarily down", "error");
} }
}; }), [setSnack, tabs]);
useEffect(() => {
const url = new URL(window.location.href);
const pathParts = url.pathname.split('/').filter(Boolean); // [path, sessionId]
console.log(tabs);
if (pathParts.length < 1) { if (pathParts.length < 1) {
console.log("No session id or path -- creating new session"); console.log("No session id or path -- creating new session");
fetchSession(); fetchSession();
} else { } else {
const currentPath = pathParts.length < 2 ? '' : pathParts[0]; const currentPath = pathParts.length < 2 ? '' : pathParts[0];
const session = pathParts.length < 2 ? pathParts[0] : pathParts[1]; const path_session = pathParts.length < 2 ? pathParts[0] : pathParts[1];
if (!isValidUUIDv4(path_session)) {
console.log(`Invalid session id ${path_session}-- creating new session`);
fetchSession(pathParts);
} else {
let tabIndex = tabs.findIndex((tab) => tab.path === currentPath); let tabIndex = tabs.findIndex((tab) => tab.path === currentPath);
if (-1 === tabIndex) { if (-1 === tabIndex) {
console.log(`Invalid path "${currentPath}" -- redirecting to default`); console.log(`Invalid path "${currentPath}" -- redirecting to default`);
tabIndex = 0; tabIndex = 0;
} }
setSessionId(session); setSessionId(path_session);
setActiveTab(tabIndex); setActiveTab(tabIndex);
} }
}, [setSessionId, connectionBase, setSnack, tabs]); }
}, [setSessionId, setSnack, tabs, fetchSession]);
const handleMenuClose = () => { const handleMenuClose = () => {
setIsMenuClosing(true); setIsMenuClosing(true);

View File

@ -20,7 +20,6 @@ const ChatQuery = (props : ChatQueryInterface) => {
if (typeof (tunables) === "string") { if (typeof (tunables) === "string") {
tunables = JSON.parse(tunables); tunables = JSON.parse(tunables);
} }
console.log(tunables);
if (submitQuery === undefined) { if (submitQuery === undefined) {
return (<Box>{prompt}</Box>); return (<Box>{prompt}</Box>);