Spaces:
Running
Running
BRIDGE Platform Agent
feat(platform): BRIDGE Modules hub with /modules/e and /modules/s routed workspaces
1955a0f Download src/modules/LaunchContext.tsx from sitcod3/BRIDGE_Modul-S_prod: direct link, hf CLI and curl.
- Browser
- Download file 2.45 kB
-
https://huggingface.co/spaces/sitcod3/BRIDGE_Modul-S_prod/resolve/main/src/modules/LaunchContext.tsx
- Command line
-
hf download hf://spaces/sitcod3/BRIDGE_Modul-S_prod/src/modules/LaunchContext.tsx
-
curl -L -o LaunchContext.tsx https://huggingface.co/spaces/sitcod3/BRIDGE_Modul-S_prod/resolve/main/src/modules/LaunchContext.tsx
2.45 kB
| import React, { createContext, useCallback, useContext, useMemo, useState } from "react"; | |
| import { useNavigate } from "react-router-dom"; | |
| import { ModuleId, moduleHref } from "./registry"; | |
| interface LaunchState { | |
| /** Monotonic counter — increments on every explicit launch so the animation re-seeds. */ | |
| seq: number; | |
| /** Module currently being exited (reverse-assembly playing). */ | |
| exiting: ModuleId | null; | |
| } | |
| interface LaunchContextType extends LaunchState { | |
| /** Play exit choreography (if inside a module), then navigate to the target module/hub. */ | |
| startLaunch: (target: ModuleId | "hub") => void; | |
| /** Called by the exiting shell once its reverse-assembly finished. */ | |
| finishExit: () => void; | |
| } | |
| const LaunchContext = createContext<LaunchContextType>({ | |
| seq: 0, | |
| exiting: null, | |
| startLaunch: () => {}, | |
| finishExit: () => {}, | |
| }); | |
| const EXIT_DURATION_MS = 850; | |
| export const LaunchProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { | |
| const [state, setState] = useState<LaunchState>({ seq: 0, exiting: null }); | |
| const navigate = useNavigate(); | |
| const startLaunch = useCallback( | |
| (target: ModuleId | "hub") => { | |
| setState((prev) => { | |
| const navigateAfterExit = () => { | |
| navigate(target === "hub" ? "/" : moduleHref(target)); | |
| }; | |
| // Bumping seq always re-seeds the next enter animation. | |
| const next = { seq: prev.seq + 1, exiting: prev.exiting }; | |
| // Controlled exit: if a module shell is currently mounted, let it play | |
| // its reverse-assembly first, then navigate. | |
| const onHub = window.location.pathname === "/" || !window.location.pathname.startsWith("/modules/"); | |
| if (!onHub) { | |
| next.exiting = (window.location.pathname.startsWith("/modules/s") ? "s" : "e") as ModuleId; | |
| window.setTimeout(navigateAfterExit, EXIT_DURATION_MS); | |
| } else { | |
| // On the hub nothing needs to disassemble — navigate immediately. | |
| window.setTimeout(navigateAfterExit, 0); | |
| } | |
| return next; | |
| }); | |
| }, | |
| [navigate] | |
| ); | |
| const finishExit = useCallback(() => { | |
| setState((prev) => ({ ...prev, exiting: null })); | |
| }, []); | |
| const value = useMemo(() => ({ ...state, startLaunch, finishExit }), [state, startLaunch, finishExit]); | |
| return <LaunchContext.Provider value={value}>{children}</LaunchContext.Provider>; | |
| }; | |
| export const useLaunch = () => useContext(LaunchContext); | |