Fix removed host routes getting stuck connecting
This commit is contained in:
@@ -84,7 +84,6 @@ import { resolveActiveHost } from "@/utils/active-host";
|
||||
import { toggleDesktopSidebarsWithCheckoutIntent } from "@/utils/desktop-sidebar-toggle";
|
||||
import {
|
||||
buildHostRootRoute,
|
||||
mapPathnameToServer,
|
||||
parseHostAgentRouteFromPathname,
|
||||
parseServerIdFromPathname,
|
||||
parseWorkspaceOpenIntent,
|
||||
@@ -811,7 +810,6 @@ function OpenProjectListener() {
|
||||
}
|
||||
|
||||
function AppWithSidebar({ children }: { children: ReactNode }) {
|
||||
const router = useRouter();
|
||||
const pathname = usePathname();
|
||||
const params = useGlobalSearchParams<{ open?: string | string[] }>();
|
||||
const hosts = useHosts();
|
||||
@@ -820,16 +818,6 @@ function AppWithSidebar({ children }: { children: ReactNode }) {
|
||||
const shouldShowAppChrome =
|
||||
storeReady && activeServerId !== null && hosts.some((host) => host.serverId === activeServerId);
|
||||
|
||||
useEffect(() => {
|
||||
if (!activeServerId || hosts.length === 0) {
|
||||
return;
|
||||
}
|
||||
if (hosts.some((host) => host.serverId === activeServerId)) {
|
||||
return;
|
||||
}
|
||||
router.replace(mapPathnameToServer(pathname, hosts[0].serverId));
|
||||
}, [activeServerId, hosts, pathname, router]);
|
||||
|
||||
// Parse selectedAgentKey directly from pathname
|
||||
// useLocalSearchParams doesn't update when navigating between same-pattern routes
|
||||
const selectedAgentKey = useMemo(() => {
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
import { Redirect, Slot, useLocalSearchParams } from "expo-router";
|
||||
import { HostRouteBootstrapBoundary } from "@/components/host-route-bootstrap-boundary";
|
||||
import { useHosts } from "@/runtime/host-runtime";
|
||||
import { resolveKnownHostRoute } from "@/utils/host-routes";
|
||||
|
||||
export default function HostRouteLayout() {
|
||||
return (
|
||||
<HostRouteBootstrapBoundary>
|
||||
<KnownHostRoute />
|
||||
</HostRouteBootstrapBoundary>
|
||||
);
|
||||
}
|
||||
|
||||
function KnownHostRoute() {
|
||||
const params = useLocalSearchParams<{ serverId?: string | string[] }>();
|
||||
const hosts = useHosts();
|
||||
const routeServerId = typeof params.serverId === "string" ? params.serverId : null;
|
||||
const resolution = resolveKnownHostRoute({ routeServerId, hosts });
|
||||
|
||||
if (resolution.kind === "redirect") {
|
||||
return <Redirect href={resolution.href} />;
|
||||
}
|
||||
|
||||
return <Slot />;
|
||||
}
|
||||
@@ -16,6 +16,7 @@ import {
|
||||
parseHostWorkspaceOpenIntentFromPathname,
|
||||
parseHostWorkspaceRouteFromPathname,
|
||||
parseWorkspaceOpenIntent,
|
||||
resolveKnownHostRoute,
|
||||
} from "./host-routes";
|
||||
|
||||
describe("parseHostAgentRouteFromPathname", () => {
|
||||
@@ -190,3 +191,32 @@ describe("host settings section slugs", () => {
|
||||
expect(normalizeHostSectionSlug("daemon")).toBe("host");
|
||||
});
|
||||
});
|
||||
|
||||
describe("resolveKnownHostRoute", () => {
|
||||
it("renders when the route host is still saved", () => {
|
||||
expect(
|
||||
resolveKnownHostRoute({
|
||||
routeServerId: "srv-current",
|
||||
hosts: [{ serverId: "srv-current" }, { serverId: "srv-next" }],
|
||||
}),
|
||||
).toEqual({ kind: "render" });
|
||||
});
|
||||
|
||||
it("sends removed host routes to the next saved host home", () => {
|
||||
expect(
|
||||
resolveKnownHostRoute({
|
||||
routeServerId: "srv-removed",
|
||||
hosts: [{ serverId: "srv-next" }],
|
||||
}),
|
||||
).toEqual({ kind: "redirect", href: "/h/srv-next/open-project" });
|
||||
});
|
||||
|
||||
it("sends host routes to welcome when no hosts are saved", () => {
|
||||
expect(
|
||||
resolveKnownHostRoute({
|
||||
routeServerId: "srv-removed",
|
||||
hosts: [],
|
||||
}),
|
||||
).toEqual({ kind: "redirect", href: "/welcome" });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -355,6 +355,27 @@ export function buildHostOpenProjectRoute(serverId: string) {
|
||||
return `${base}/open-project` as const;
|
||||
}
|
||||
|
||||
export type KnownHostRouteResolution =
|
||||
| { kind: "render" }
|
||||
| { kind: "redirect"; href: ReturnType<typeof buildHostOpenProjectRoute> | "/welcome" };
|
||||
|
||||
export function resolveKnownHostRoute(input: {
|
||||
routeServerId: string | null | undefined;
|
||||
hosts: readonly { serverId: string }[];
|
||||
}): KnownHostRouteResolution {
|
||||
const routeServerId = trimNonEmpty(input.routeServerId);
|
||||
if (routeServerId && input.hosts.some((host) => host.serverId === routeServerId)) {
|
||||
return { kind: "render" };
|
||||
}
|
||||
|
||||
const fallbackServerId = input.hosts[0]?.serverId;
|
||||
if (fallbackServerId) {
|
||||
return { kind: "redirect", href: buildHostOpenProjectRoute(fallbackServerId) };
|
||||
}
|
||||
|
||||
return { kind: "redirect", href: "/welcome" };
|
||||
}
|
||||
|
||||
export function buildHostNewWorkspaceRoute(
|
||||
serverId: string,
|
||||
sourceDirectory?: string,
|
||||
|
||||
Reference in New Issue
Block a user