* fix(app): keep New Workspace on the active project New Workspace preselection was falling back to stale remembered host state when multiple hosts existed. Pass durable active-project context from workspace entry points and centralize initial host selection so stale offline hosts cannot steal the form while startup restore remains last-workspace only. * fix(app): address New Workspace review feedback * fix(app): stabilize New Workspace host selection * fix(app): preserve New Workspace host fallback * test(app): loosen stale-host project assertion * fix(app): prefer reachable new workspace hosts * fix(app): avoid stale offline workspace preselect * fix(app): prefer online project hosts
54 lines
1.5 KiB
TypeScript
54 lines
1.5 KiB
TypeScript
import { useMemo } from "react";
|
|
import { useShallow } from "zustand/shallow";
|
|
import type { DaemonServerInfo } from "@/stores/session-store";
|
|
import { useSessionStore } from "@/stores/session-store";
|
|
|
|
export type HostFeatureName = keyof NonNullable<DaemonServerInfo["features"]>;
|
|
|
|
export interface HostFeatureSessionState {
|
|
sessions: Record<
|
|
string,
|
|
| {
|
|
serverInfo: DaemonServerInfo | null;
|
|
}
|
|
| undefined
|
|
>;
|
|
}
|
|
|
|
export function hostSupportsFeature(
|
|
serverInfo: DaemonServerInfo | null | undefined,
|
|
feature: HostFeatureName,
|
|
): boolean {
|
|
return serverInfo?.features?.[feature] === true;
|
|
}
|
|
|
|
export function selectHostFeature(
|
|
state: HostFeatureSessionState,
|
|
serverId: string,
|
|
feature: HostFeatureName,
|
|
): boolean {
|
|
return hostSupportsFeature(state.sessions[serverId]?.serverInfo, feature);
|
|
}
|
|
|
|
export function useHostFeature(
|
|
serverId: string | null | undefined,
|
|
feature: HostFeatureName,
|
|
): boolean {
|
|
const normalizedServerId = serverId?.trim() ?? "";
|
|
return useSessionStore((state) => selectHostFeature(state, normalizedServerId, feature));
|
|
}
|
|
|
|
export function useHostFeatureMap(
|
|
serverIds: readonly string[],
|
|
feature: HostFeatureName,
|
|
): ReadonlyMap<string, boolean> {
|
|
const flags = useSessionStore(
|
|
useShallow((state) => serverIds.map((serverId) => selectHostFeature(state, serverId, feature))),
|
|
);
|
|
|
|
return useMemo(
|
|
() => new Map(serverIds.map((serverId, index) => [serverId, flags[index] === true] as const)),
|
|
[flags, serverIds],
|
|
);
|
|
}
|