Keep composer autocomplete visible after route hops (#1851)
* fix(app): keep composer autocomplete visible after route hops Workspace callers now express only the target workspace. The navigation helper chooses whether to pop to a mounted host route or fall back, and active-workspace tracking ignores stale hidden route params while app-wide routes are foregrounded. * test(app): address workspace navigation review * fix(app): parse decoded legacy workspace routes * fix(app): ignore decoded legacy tab routes * test(app): use canonical offline workspace route
This commit is contained in:
@@ -20,10 +20,6 @@ import { navigateToHostWorkspaceRoute } from "@/navigation/workspace-route-navig
|
||||
|
||||
export type { ActiveWorkspaceSelection } from "@/stores/last-workspace-selection";
|
||||
|
||||
interface NavigateToWorkspaceOptions {
|
||||
currentPathname?: string | null;
|
||||
}
|
||||
|
||||
const lastWorkspaceSelectionStorage: LastWorkspaceSelectionStorage = {
|
||||
read: () => AsyncStorage.getItem(LAST_WORKSPACE_SELECTION_STORAGE_KEY),
|
||||
write: (value) => AsyncStorage.setItem(LAST_WORKSPACE_SELECTION_STORAGE_KEY, value),
|
||||
@@ -33,13 +29,7 @@ const lastWorkspaceSelectionStore = createLastWorkspaceSelectionStore(
|
||||
lastWorkspaceSelectionStorage,
|
||||
);
|
||||
|
||||
function shouldPopToExistingHostRoute(options: NavigateToWorkspaceOptions): boolean {
|
||||
// Only /new needs POP_TO to avoid hidden deck entries; regular workspace switches
|
||||
// should use router navigation so route observers like the sidebar selection update.
|
||||
return options.currentPathname === "/new";
|
||||
}
|
||||
|
||||
function navigateDeps(options: NavigateToWorkspaceOptions): NavigateToWorkspaceDeps {
|
||||
function navigateDeps(): NavigateToWorkspaceDeps {
|
||||
return {
|
||||
getSessionWorkspaces: (serverId) => useSessionStore.getState().sessions[serverId]?.workspaces,
|
||||
getSessionAgents: (serverId) =>
|
||||
@@ -49,9 +39,7 @@ function navigateDeps(options: NavigateToWorkspaceOptions): NavigateToWorkspaceD
|
||||
},
|
||||
rememberLastWorkspace: (selection) => lastWorkspaceSelectionStore.remember(selection),
|
||||
navigateToRoute: (route) => {
|
||||
navigateToHostWorkspaceRoute(route, {
|
||||
popToExistingHostRoute: shouldPopToExistingHostRoute(options),
|
||||
});
|
||||
navigateToHostWorkspaceRoute(route);
|
||||
stripHostWorkspaceRouteEchoSearchFromBrowserUrlAfterCommit();
|
||||
},
|
||||
};
|
||||
@@ -69,17 +57,13 @@ export function getIsLastWorkspaceSelectionHydrated(): boolean {
|
||||
return lastWorkspaceSelectionStore.isHydrated();
|
||||
}
|
||||
|
||||
export function navigateToWorkspace(
|
||||
serverId: string,
|
||||
workspaceId: string,
|
||||
options: NavigateToWorkspaceOptions = {},
|
||||
) {
|
||||
navigateToWorkspacePure(serverId, workspaceId, navigateDeps(options));
|
||||
export function navigateToWorkspace(serverId: string, workspaceId: string) {
|
||||
navigateToWorkspacePure(serverId, workspaceId, navigateDeps());
|
||||
}
|
||||
|
||||
export function navigateToLastWorkspace(): boolean {
|
||||
return navigateToLastWorkspacePure({
|
||||
...navigateDeps({}),
|
||||
...navigateDeps(),
|
||||
getLastWorkspaceSelection: () => lastWorkspaceSelectionStore.getSelection(),
|
||||
});
|
||||
}
|
||||
|
||||
@@ -115,6 +115,18 @@ describe("workspace navigation", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("ignores stale workspace route params while an app-wide route is active", () => {
|
||||
const selection = parseActiveWorkspaceSelection({
|
||||
pathname: "/settings/general",
|
||||
params: {
|
||||
serverId: "server-1",
|
||||
workspaceId: "workspace-a",
|
||||
},
|
||||
});
|
||||
|
||||
expect(selection).toBeNull();
|
||||
});
|
||||
|
||||
it("navigates to the last workspace once a route observation has been remembered", () => {
|
||||
const { deps, navigations } = createLastSelectionDeps(null);
|
||||
|
||||
|
||||
@@ -58,10 +58,16 @@ function parseWorkspaceSelectionFromRouteParams(params: {
|
||||
export function parseActiveWorkspaceSelection(
|
||||
input: RouteSelectionInput,
|
||||
): ActiveWorkspaceSelection | null {
|
||||
return (
|
||||
parseHostWorkspaceRouteFromPathname(input.pathname) ??
|
||||
parseWorkspaceSelectionFromRouteParams(input.params)
|
||||
);
|
||||
const routeSelection = parseHostWorkspaceRouteFromPathname(input.pathname);
|
||||
if (routeSelection) {
|
||||
return routeSelection;
|
||||
}
|
||||
|
||||
if (input.pathname !== "/" && input.pathname !== "") {
|
||||
return null;
|
||||
}
|
||||
|
||||
return parseWorkspaceSelectionFromRouteParams(input.params);
|
||||
}
|
||||
|
||||
export function navigateToWorkspace(
|
||||
|
||||
Reference in New Issue
Block a user