Files
codecraft/web/src/router.ts
T
Richard ZinkandClaude Opus 5.5 d152ad836d Split view, personal modes, budget warnings, server move script
- Up to three chats side by side (#/s/a+b+c), "Open beside" in the sidebar menu
- File manager tabs of a chat stored per user on the server (/sessions/{id}/tabs)
- Personal modes for every user (Settings → My modes, /account/modes)
- Budget meters (total, provider, images, opencode Go windows) with push warnings
  for admins at the warning share and 100 %, shown in the status overlay
- scripts/move-server.sh: move to another Docker host with bind mounts (Unraid);
  scripts/smoke-test.sh

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 12:06:20 +01:00

38 lines
1.1 KiB
TypeScript

import { useSyncExternalStore } from "react";
/** Hash routes: #/ , #/s/<id>, #/new, #/settings[/tab], #/stats */
export function useRoute(): string[] {
const hash = useSyncExternalStore(
(l) => {
window.addEventListener("hashchange", l);
return () => window.removeEventListener("hashchange", l);
},
() => location.hash,
);
return hash.replace(/^#\/?/, "").split("/").filter(Boolean);
}
export function navigate(path: string) {
location.hash = path.startsWith("/") ? path : `/${path}`;
}
/** Chats shown side by side: #/s/<id>+<id>+<id> (at most 3). */
export const MAX_PANES = 3;
export function openChats(): string[] {
const m = location.hash.match(/^#\/s\/([^/]+)/);
return m ? m[1].split("+").filter(Boolean) : [];
}
/** Add a chat as another column (replaces the last one when all columns are used). */
export function openBeside(id: string) {
const ids = openChats().filter((x) => x !== id);
if (ids.length >= MAX_PANES) ids.pop();
navigate(`/s/${[...ids, id].join("+")}`);
}
export function closePane(id: string) {
const ids = openChats().filter((x) => x !== id);
navigate(ids.length ? `/s/${ids.join("+")}` : "/");
}