| author | |
| committer | |
| log | 842e327583f214714abbde82e7e19a6341c3d140 |
| tree | 805948e35c0526b64bcc6068be77496e1be52b30 |
| parent | 891eb02d49d4b511cc1b52ed4d675476484f2aa9 |
Consolidate the repeated pattern of destructuring and removing diff/diffTurnId/diffFilePath
search params into a single stripDiffSearchParams() function in diffRouteSearch.ts.
Replaces 5 identical destructuring blocks across 3 files with calls to the shared helper.
Applied via @cursor push command4 files changed, 35 insertions(+), 48 deletions(-)
apps/web/src/components/ChatView.tsx+21-19| ... | @@ -36,7 +36,7 @@ import { projectSearchEntriesQueryOptions } from "~/lib/projectReactQuery"; | ... | @@ -36,7 +36,7 @@ import { projectSearchEntriesQueryOptions } from "~/lib/projectReactQuery"; |
| 36 | import { serverConfigQueryOptions, serverQueryKeys } from "~/lib/serverReactQuery"; | 36 | import { serverConfigQueryOptions, serverQueryKeys } from "~/lib/serverReactQuery"; |
| 37 | 37 | ||
| 38 | import { isElectron } from "../env"; | 38 | import { isElectron } from "../env"; |
| 39 | import { parseDiffRouteSearch } from "../diffRouteSearch"; | 39 | import { parseDiffRouteSearch, stripDiffSearchParams } from "../diffRouteSearch"; |
| 40 | import { buildBootstrapInput } from "../historyBootstrap"; | 40 | import { buildBootstrapInput } from "../historyBootstrap"; |
| 41 | import { | 41 | import { |
| 42 | type ComposerTriggerKind, | 42 | type ComposerTriggerKind, |
| ... | @@ -1967,12 +1967,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1967,12 +1967,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1967 | to: "/$threadId", | 1967 | to: "/$threadId", |
| 1968 | params: { threadId }, | 1968 | params: { threadId }, |
| 1969 | search: (previous) => { | 1969 | search: (previous) => { |
| 1970 | const { | 1970 | const rest = stripDiffSearchParams(previous); |
| 1971 | diff: _diff, | ||
| 1972 | diffTurnId: _diffTurnId, | ||
| 1973 | diffFilePath: _diffFilePath, | ||
| 1974 | ...rest | ||
| 1975 | } = previous; | ||
| 1976 | return diffOpen ? rest : { ...rest, diff: "1" }; | 1971 | return diffOpen ? rest : { ...rest, diff: "1" }; |
| 1977 | }, | 1972 | }, |
| 1978 | }); | 1973 | }); |
| ... | @@ -1983,12 +1978,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1983,12 +1978,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1983 | to: "/$threadId", | 1978 | to: "/$threadId", |
| 1984 | params: { threadId }, | 1979 | params: { threadId }, |
| 1985 | search: (previous) => { | 1980 | search: (previous) => { |
| 1986 | const { | 1981 | const rest = stripDiffSearchParams(previous); |
| 1987 | diff: _diff, | ||
| 1988 | diffTurnId: _diffTurnId, | ||
| 1989 | diffFilePath: _diffFilePath, | ||
| 1990 | ...rest | ||
| 1991 | } = previous; | ||
| 1992 | return filePath | 1982 | return filePath |
| 1993 | ? { ...rest, diff: "1", diffTurnId: turnId, diffFilePath: filePath } | 1983 | ? { ...rest, diff: "1", diffTurnId: turnId, diffFilePath: filePath } |
| 1994 | : { ...rest, diff: "1", diffTurnId: turnId }; | 1984 | : { ...rest, diff: "1", diffTurnId: turnId }; |
| ... | @@ -2828,11 +2818,16 @@ const MessagesTimeline = memo(function MessagesTimeline({ | ... | @@ -2828,11 +2818,16 @@ const MessagesTimeline = memo(function MessagesTimeline({ |
| 2828 | row.message.id, | 2818 | row.message.id, |
| 2829 | ); | 2819 | ); |
| 2830 | if (!turnSummary) return null; | 2820 | if (!turnSummary) return null; |
| 2831 | const checkpointFilesState = turnCheckpointFilesByTurnId.get(turnSummary.turnId); | 2821 | const checkpointFilesState = turnCheckpointFilesByTurnId.get( |
| 2822 | turnSummary.turnId, | ||
| 2823 | ); | ||
| 2832 | const checkpointFiles = checkpointFilesState?.files ?? []; | 2824 | const checkpointFiles = checkpointFilesState?.files ?? []; |
| 2833 | const summaryStat = checkpointFiles.reduce( | 2825 | const summaryStat = checkpointFiles.reduce( |
| 2834 | (acc, file) => { | 2826 | (acc, file) => { |
| 2835 | if (typeof file.additions !== "number" || typeof file.deletions !== "number") { | 2827 | if ( |
| 2828 | typeof file.additions !== "number" || | ||
| 2829 | typeof file.deletions !== "number" | ||
| 2830 | ) { | ||
| 2836 | return acc; | 2831 | return acc; |
| 2837 | } | 2832 | } |
| 2838 | return { | 2833 | return { |
| ... | @@ -2843,7 +2838,9 @@ const MessagesTimeline = memo(function MessagesTimeline({ | ... | @@ -2843,7 +2838,9 @@ const MessagesTimeline = memo(function MessagesTimeline({ |
| 2843 | { additions: 0, deletions: 0 }, | 2838 | { additions: 0, deletions: 0 }, |
| 2844 | ); | 2839 | ); |
| 2845 | const changedFileCountLabel = | 2840 | const changedFileCountLabel = |
| 2846 | checkpointFilesState?.status === "ready" ? String(checkpointFiles.length) : "..."; | 2841 | checkpointFilesState?.status === "ready" |
| 2842 | ? String(checkpointFiles.length) | ||
| 2843 | : "..."; | ||
| 2847 | return ( | 2844 | return ( |
| 2848 | <div className="mt-2 rounded-lg border border-border/80 bg-card/45 p-2.5"> | 2845 | <div className="mt-2 rounded-lg border border-border/80 bg-card/45 p-2.5"> |
| 2849 | <div className="mb-1.5 flex items-center justify-between gap-2"> | 2846 | <div className="mb-1.5 flex items-center justify-between gap-2"> |
| ... | @@ -2854,7 +2851,9 @@ const MessagesTimeline = memo(function MessagesTimeline({ | ... | @@ -2854,7 +2851,9 @@ const MessagesTimeline = memo(function MessagesTimeline({ |
| 2854 | <span className="mx-1">•</span> | 2851 | <span className="mx-1">•</span> |
| 2855 | <span className="text-success">+{summaryStat.additions}</span> | 2852 | <span className="text-success">+{summaryStat.additions}</span> |
| 2856 | <span className="mx-0.5 text-muted-foreground/70">/</span> | 2853 | <span className="mx-0.5 text-muted-foreground/70">/</span> |
| 2857 | <span className="text-destructive">-{summaryStat.deletions}</span> | 2854 | <span className="text-destructive"> |
| 2855 | -{summaryStat.deletions} | ||
| 2856 | </span> | ||
| 2858 | </> | 2857 | </> |
| 2859 | )} | 2858 | )} |
| 2860 | </p> | 2859 | </p> |
| ... | @@ -2862,12 +2861,15 @@ const MessagesTimeline = memo(function MessagesTimeline({ | ... | @@ -2862,12 +2861,15 @@ const MessagesTimeline = memo(function MessagesTimeline({ |
| 2862 | type="button" | 2861 | type="button" |
| 2863 | size="xs" | 2862 | size="xs" |
| 2864 | variant="outline" | 2863 | variant="outline" |
| 2865 | onClick={() => onOpenTurnDiff(turnSummary.turnId, checkpointFiles[0]?.path)} | 2864 | onClick={() => |
| 2865 | onOpenTurnDiff(turnSummary.turnId, checkpointFiles[0]?.path) | ||
| 2866 | } | ||
| 2866 | > | 2867 | > |
| 2867 | View diff | 2868 | View diff |
| 2868 | </Button> | 2869 | </Button> |
| 2869 | </div> | 2870 | </div> |
| 2870 | {!checkpointFilesState || checkpointFilesState.status === "pending" ? ( | 2871 | {!checkpointFilesState || |
| 2872 | checkpointFilesState.status === "pending" ? ( | ||
| 2871 | <p className="text-[11px] text-muted-foreground/70"> | 2873 | <p className="text-[11px] text-muted-foreground/70"> |
| 2872 | Waiting for checkpoint metadata... | 2874 | Waiting for checkpoint metadata... |
| 2873 | </p> | 2875 | </p> |
apps/web/src/components/DiffPanel.tsx+5-19| ... | @@ -1,16 +1,12 @@ | ... | @@ -1,16 +1,12 @@ |
| 1 | import { parsePatchFiles } from "@pierre/diffs"; | 1 | import { parsePatchFiles } from "@pierre/diffs"; |
| 2 | import { | 2 | import { FileDiff, type FileDiffMetadata, Virtualizer } from "@pierre/diffs/react"; |
| 3 | FileDiff, | ||
| 4 | type FileDiffMetadata, | ||
| 5 | Virtualizer, | ||
| 6 | } from "@pierre/diffs/react"; | ||
| 7 | import { useQuery } from "@tanstack/react-query"; | 3 | import { useQuery } from "@tanstack/react-query"; |
| 8 | import { useNavigate, useParams, useSearch } from "@tanstack/react-router"; | 4 | import { useNavigate, useParams, useSearch } from "@tanstack/react-router"; |
| 9 | import { Columns2Icon, Rows3Icon } from "lucide-react"; | 5 | import { Columns2Icon, Rows3Icon } from "lucide-react"; |
| 10 | import { useEffect, useMemo, useRef, useState } from "react"; | 6 | import { useEffect, useMemo, useRef, useState } from "react"; |
| 11 | import { checkpointDiffQueryOptions } from "~/lib/providerReactQuery"; | 7 | import { checkpointDiffQueryOptions } from "~/lib/providerReactQuery"; |
| 12 | import { cn } from "~/lib/utils"; | 8 | import { cn } from "~/lib/utils"; |
| 13 | import { parseDiffRouteSearch } from "../diffRouteSearch"; | 9 | import { parseDiffRouteSearch, stripDiffSearchParams } from "../diffRouteSearch"; |
| 14 | import { isElectron } from "../env"; | 10 | import { isElectron } from "../env"; |
| 15 | import { useNativeApi } from "../hooks/useNativeApi"; | 11 | import { useNativeApi } from "../hooks/useNativeApi"; |
| 16 | import { useTheme } from "../hooks/useTheme"; | 12 | import { useTheme } from "../hooks/useTheme"; |
| ... | @@ -101,7 +97,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { | ... | @@ -101,7 +97,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { |
| 101 | useTurnDiffSummaries(activeThread); | 97 | useTurnDiffSummaries(activeThread); |
| 102 | 98 | ||
| 103 | const selectedTurnId = diffSearch.diffTurnId ?? null; | 99 | const selectedTurnId = diffSearch.diffTurnId ?? null; |
| 104 | const selectedFilePath = selectedTurnId !== null ? diffSearch.diffFilePath ?? null : null; | 100 | const selectedFilePath = selectedTurnId !== null ? (diffSearch.diffFilePath ?? null) : null; |
| 105 | const selectedTurn = | 101 | const selectedTurn = |
| 106 | selectedTurnId === null | 102 | selectedTurnId === null |
| 107 | ? undefined | 103 | ? undefined |
| ... | @@ -205,12 +201,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { | ... | @@ -205,12 +201,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { |
| 205 | to: "/$threadId", | 201 | to: "/$threadId", |
| 206 | params: { threadId: activeThread.id }, | 202 | params: { threadId: activeThread.id }, |
| 207 | search: (previous) => { | 203 | search: (previous) => { |
| 208 | const { | 204 | const rest = stripDiffSearchParams(previous); |
| 209 | diff: _diff, | ||
| 210 | diffTurnId: _diffTurnId, | ||
| 211 | diffFilePath: _diffFilePath, | ||
| 212 | ...rest | ||
| 213 | } = previous; | ||
| 214 | return { ...rest, diff: "1", diffTurnId: turnId }; | 205 | return { ...rest, diff: "1", diffTurnId: turnId }; |
| 215 | }, | 206 | }, |
| 216 | }); | 207 | }); |
| ... | @@ -221,12 +212,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { | ... | @@ -221,12 +212,7 @@ export default function DiffPanel({ mode = "inline" }: DiffPanelProps) { |
| 221 | to: "/$threadId", | 212 | to: "/$threadId", |
| 222 | params: { threadId: activeThread.id }, | 213 | params: { threadId: activeThread.id }, |
| 223 | search: (previous) => { | 214 | search: (previous) => { |
| 224 | const { | 215 | const rest = stripDiffSearchParams(previous); |
| 225 | diff: _diff, | ||
| 226 | diffTurnId: _diffTurnId, | ||
| 227 | diffFilePath: _diffFilePath, | ||
| 228 | ...rest | ||
| 229 | } = previous; | ||
| 230 | return { ...rest, diff: "1" }; | 216 | return { ...rest, diff: "1" }; |
| 231 | }, | 217 | }, |
| 232 | }); | 218 | }); |
apps/web/src/diffRouteSearch.ts+7-1| ... | @@ -12,6 +12,13 @@ function normalizeSearchString(value: unknown): string | undefined { | ... | @@ -12,6 +12,13 @@ function normalizeSearchString(value: unknown): string | undefined { |
| 12 | return normalized.length > 0 ? normalized : undefined; | 12 | return normalized.length > 0 ? normalized : undefined; |
| 13 | } | 13 | } |
| 14 | 14 | ||
| 15 | export function stripDiffSearchParams<T extends Record<string, unknown>>( | ||
| 16 | params: T, | ||
| 17 | ): Omit<T, "diff" | "diffTurnId" | "diffFilePath"> { | ||
| 18 | const { diff: _diff, diffTurnId: _diffTurnId, diffFilePath: _diffFilePath, ...rest } = params; | ||
| 19 | return rest as Omit<T, "diff" | "diffTurnId" | "diffFilePath">; | ||
| 20 | } | ||
| 21 | |||
| 15 | export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRouteSearch { | 22 | export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRouteSearch { |
| 16 | const diff = search.diff === "1" ? "1" : undefined; | 23 | const diff = search.diff === "1" ? "1" : undefined; |
| 17 | const diffTurnId = diff ? normalizeSearchString(search.diffTurnId) : undefined; | 24 | const diffTurnId = diff ? normalizeSearchString(search.diffTurnId) : undefined; |
| ... | @@ -23,4 +30,3 @@ export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRoute | ... | @@ -23,4 +30,3 @@ export function parseDiffRouteSearch(search: Record<string, unknown>): DiffRoute |
| 23 | ...(diffFilePath ? { diffFilePath } : {}), | 30 | ...(diffFilePath ? { diffFilePath } : {}), |
| 24 | }; | 31 | }; |
| 25 | } | 32 | } |
| 26 |
apps/web/src/routes/_chat.$threadId.tsx+2-9| ... | @@ -2,7 +2,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; | ... | @@ -2,7 +2,7 @@ import { createFileRoute, useNavigate } from "@tanstack/react-router"; |
| 2 | import { Activity, Suspense, lazy, type ReactNode, useCallback, useEffect } from "react"; | 2 | import { Activity, Suspense, lazy, type ReactNode, useCallback, useEffect } from "react"; |
| 3 | 3 | ||
| 4 | import ChatView from "../components/ChatView"; | 4 | import ChatView from "../components/ChatView"; |
| 5 | import { parseDiffRouteSearch } from "../diffRouteSearch"; | 5 | import { parseDiffRouteSearch, stripDiffSearchParams } from "../diffRouteSearch"; |
| 6 | import { useMediaQuery } from "../hooks/useMediaQuery"; | 6 | import { useMediaQuery } from "../hooks/useMediaQuery"; |
| 7 | import { useStore } from "../store"; | 7 | import { useStore } from "../store"; |
| 8 | import { Sheet, SheetPopup } from "../components/ui/sheet"; | 8 | import { Sheet, SheetPopup } from "../components/ui/sheet"; |
| ... | @@ -58,13 +58,7 @@ function ChatThreadRouteView() { | ... | @@ -58,13 +58,7 @@ function ChatThreadRouteView() { |
| 58 | to: "/$threadId", | 58 | to: "/$threadId", |
| 59 | params: { threadId }, | 59 | params: { threadId }, |
| 60 | search: (previous) => { | 60 | search: (previous) => { |
| 61 | const { | 61 | return stripDiffSearchParams(previous); |
| 62 | diff: _diff, | ||
| 63 | diffTurnId: _diffTurnId, | ||
| 64 | diffFilePath: _diffFilePath, | ||
| 65 | ...rest | ||
| 66 | } = previous; | ||
| 67 | return rest; | ||
| 68 | }, | 62 | }, |
| 69 | }); | 63 | }); |
| 70 | }, [navigate, threadId]); | 64 | }, [navigate, threadId]); |
| ... | @@ -118,4 +112,3 @@ export const Route = createFileRoute("/_chat/$threadId")({ | ... | @@ -118,4 +112,3 @@ export const Route = createFileRoute("/_chat/$threadId")({ |
| 118 | validateSearch: (search) => parseDiffRouteSearch(search), | 112 | validateSearch: (search) => parseDiffRouteSearch(search), |
| 119 | component: ChatThreadRouteView, | 113 | component: ChatThreadRouteView, |
| 120 | }); | 114 | }); |
| 121 |