Skip to content

Commit fb03415

Browse files
perf(web): the remove-cloned-project hook compiles without manual memoization
Co-Authored-By: Claude Opus 5.5 <[email protected]>
1 parent 70d60e0 commit fb03415

2 files changed

Lines changed: 38 additions & 41 deletions

File tree

‎apps/web/reactCompiledFiles.ts‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,4 +96,5 @@ export const REACT_COMPILED_FILES = [
9696
"apps/web/src/components/pullRequest/PullRequestDetailPanel.tsx",
9797
"apps/web/src/components/ThreadTerminalDrawer.tsx",
9898
"apps/web/src/components/settings/SettingsPanels.tsx",
99+
"apps/web/src/hooks/useRemoveClonedProject.ts",
99100
] as const;
Lines changed: 37 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { useRouter } from "@tanstack/react-router";
22
import { squashAtomCommandFailure } from "@t3tools/client-runtime/state/runtime";
33
import type { ScopedProjectRef } from "@t3tools/contracts";
4-
import { useCallback } from "react";
54

65
import { useComposerDraftStore } from "../composerDraftStore";
76
import { resolveThreadRouteTarget } from "../threadRoutes";
@@ -15,44 +14,41 @@ export function useRemoveClonedProject() {
1514
const router = useRouter();
1615
const deleteProject = useAtomCommand(projectEnvironment.delete, { reportFailure: false });
1716

18-
return useCallback(
19-
async (projectRef: ScopedProjectRef) => {
20-
const draftStore = useComposerDraftStore.getState();
21-
const result = await deleteProject({
22-
environmentId: projectRef.environmentId,
23-
// Not forced: a project whose clone never landed has no threads, and
24-
// if one appeared in the meantime the server refuses rather than
25-
// silently deleting it.
26-
input: { projectId: projectRef.projectId },
27-
});
28-
if (result._tag === "Failure") {
29-
const error = squashAtomCommandFailure(result);
30-
toastManager.add(
31-
stackedThreadToast({
32-
type: "error",
33-
title: "Failed to remove project",
34-
description: error instanceof Error ? error.message : "An error occurred.",
35-
}),
36-
);
37-
return false;
38-
}
39-
await waitForProjectRemoval(projectRef);
40-
// Read the route after the await: the user may have moved on while the
41-
// delete was in flight, and only a draft of this project needs to go.
42-
const routeParams = router.state.matches[router.state.matches.length - 1]?.params ?? {};
43-
const routeTarget = resolveThreadRouteTarget(routeParams);
44-
const viewingDraft =
45-
routeTarget?.kind === "draft" ? draftStore.getDraftSession(routeTarget.draftId) : null;
46-
const viewingThisProject =
47-
viewingDraft?.environmentId === projectRef.environmentId &&
48-
viewingDraft.projectId === projectRef.projectId;
49-
releaseProjectDraftUploads(projectRef);
50-
const projectDraft = draftStore.getDraftThreadByProjectRef(projectRef);
51-
if (projectDraft) draftStore.clearDraftThread(projectDraft.draftId);
52-
draftStore.clearProjectDraftThreadId(projectRef);
53-
if (viewingThisProject) void router.navigate({ to: "/", replace: true });
54-
return true;
55-
},
56-
[deleteProject, router],
57-
);
17+
return async (projectRef: ScopedProjectRef) => {
18+
const draftStore = useComposerDraftStore.getState();
19+
const result = await deleteProject({
20+
environmentId: projectRef.environmentId,
21+
// Not forced: a project whose clone never landed has no threads, and
22+
// if one appeared in the meantime the server refuses rather than
23+
// silently deleting it.
24+
input: { projectId: projectRef.projectId },
25+
});
26+
if (result._tag === "Failure") {
27+
const error = squashAtomCommandFailure(result);
28+
toastManager.add(
29+
stackedThreadToast({
30+
type: "error",
31+
title: "Failed to remove project",
32+
description: error instanceof Error ? error.message : "An error occurred.",
33+
}),
34+
);
35+
return false;
36+
}
37+
await waitForProjectRemoval(projectRef);
38+
// Read the route after the await: the user may have moved on while the
39+
// delete was in flight, and only a draft of this project needs to go.
40+
const routeParams = router.state.matches[router.state.matches.length - 1]?.params ?? {};
41+
const routeTarget = resolveThreadRouteTarget(routeParams);
42+
const viewingDraft =
43+
routeTarget?.kind === "draft" ? draftStore.getDraftSession(routeTarget.draftId) : null;
44+
const viewingThisProject =
45+
viewingDraft?.environmentId === projectRef.environmentId &&
46+
viewingDraft.projectId === projectRef.projectId;
47+
releaseProjectDraftUploads(projectRef);
48+
const projectDraft = draftStore.getDraftThreadByProjectRef(projectRef);
49+
if (projectDraft) draftStore.clearDraftThread(projectDraft.draftId);
50+
draftStore.clearProjectDraftThreadId(projectRef);
51+
if (viewingThisProject) void router.navigate({ to: "/", replace: true });
52+
return true;
53+
};
5854
}

0 commit comments

Comments
 (0)