diff options
| author | Dax <[email protected]> | 2026-04-07 19:48:23 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-07 19:48:23 -0400 |
| commit | b7fab49b64275b83bcec8200d7492fc5d15ffe06 (patch) | |
| tree | d9dadf65ca69eb4b8fe75654eb15666ee2b23774 /packages/app/src/pages | |
| parent | 463318486f94fa20e8d864d77708a347fa8423e3 (diff) | |
| download | opencode-b7fab49b64275b83bcec8200d7492fc5d15ffe06.tar.gz opencode-b7fab49b64275b83bcec8200d7492fc5d15ffe06.zip | |
refactor(snapshot): store unified patches in file diffs (#21244)
Co-authored-by: Adam <[email protected]>
Diffstat (limited to 'packages/app/src/pages')
| -rw-r--r-- | packages/app/src/pages/session.tsx | 82 | ||||
| -rw-r--r-- | packages/app/src/pages/session/review-tab.tsx | 6 | ||||
| -rw-r--r-- | packages/app/src/pages/session/session-side-panel.tsx | 4 |
3 files changed, 40 insertions, 52 deletions
diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 0c6764726..cf50fbe90 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1,4 +1,4 @@ -import type { FileDiff, Project, UserMessage } from "@opencode-ai/sdk/v2" +import type { Project, UserMessage, VcsFileDiff } from "@opencode-ai/sdk/v2" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useMutation } from "@tanstack/solid-query" import { @@ -68,7 +68,7 @@ type FollowupItem = FollowupDraft & { id: string } type FollowupEdit = Pick<FollowupItem, "id" | "prompt" | "context"> const emptyFollowups: FollowupItem[] = [] -type ChangeMode = "git" | "branch" | "session" | "turn" +type ChangeMode = "git" | "branch" | "turn" type VcsMode = "git" | "branch" type SessionHistoryWindowInput = { @@ -463,13 +463,6 @@ export default function Page() { if (!id) return false return sync.session.history.loading(id) }) - const diffsReady = createMemo(() => { - const id = params.id - if (!id) return true - if (!hasSessionReview()) return true - return sync.data.session_diff[id] !== undefined - }) - const userMessages = createMemo( () => messages().filter((m) => m.role === "user") as UserMessage[], emptyUserMessages, @@ -527,10 +520,19 @@ export default function Page() { deferRender: false, }) - const [vcs, setVcs] = createStore({ + const [vcs, setVcs] = createStore<{ + diff: { + git: VcsFileDiff[] + branch: VcsFileDiff[] + } + ready: { + git: boolean + branch: boolean + } + }>({ diff: { - git: [] as FileDiff[], - branch: [] as FileDiff[], + git: [] as VcsFileDiff[], + branch: [] as VcsFileDiff[], }, ready: { git: false, @@ -648,6 +650,7 @@ export default function Page() { }, desktopReviewOpen()) const turnDiffs = createMemo(() => lastUserMessage()?.summary?.diffs ?? []) + const nogit = createMemo(() => !!sync.project && sync.project.vcs !== "git") const changesOptions = createMemo<ChangeMode[]>(() => { const list: ChangeMode[] = [] if (sync.project?.vcs === "git") list.push("git") @@ -659,7 +662,7 @@ export default function Page() { ) { list.push("branch") } - list.push("session", "turn") + list.push("turn") return list }) const vcsMode = createMemo<VcsMode | undefined>(() => { @@ -668,20 +671,17 @@ export default function Page() { const reviewDiffs = createMemo(() => { if (store.changes === "git") return vcs.diff.git if (store.changes === "branch") return vcs.diff.branch - if (store.changes === "session") return diffs() return turnDiffs() }) const reviewCount = createMemo(() => { if (store.changes === "git") return vcs.diff.git.length if (store.changes === "branch") return vcs.diff.branch.length - if (store.changes === "session") return sessionCount() return turnDiffs().length }) const hasReview = createMemo(() => reviewCount() > 0) const reviewReady = createMemo(() => { if (store.changes === "git") return vcs.ready.git if (store.changes === "branch") return vcs.ready.branch - if (store.changes === "session") return !hasSessionReview() || diffsReady() return true }) @@ -749,13 +749,6 @@ export default function Page() { scrollToMessage(msgs[targetIndex], "auto") } - const sessionEmptyKey = createMemo(() => { - const project = sync.project - if (project && !project.vcs) return "session.review.noVcs" - if (sync.data.config.snapshot === false) return "session.review.noSnapshot" - return "session.review.empty" - }) - function upsert(next: Project) { const list = globalSync.data.project sync.set("project", next.id) @@ -1156,7 +1149,6 @@ export default function Page() { const label = (option: ChangeMode) => { if (option === "git") return language.t("ui.sessionReview.title.git") if (option === "branch") return language.t("ui.sessionReview.title.branch") - if (option === "session") return language.t("ui.sessionReview.title") return language.t("ui.sessionReview.title.lastTurn") } @@ -1179,11 +1171,26 @@ export default function Page() { </div> ) + const createGit = (input: { emptyClass: string }) => ( + <div class={input.emptyClass}> + <div class="flex flex-col gap-3"> + <div class="text-14-medium text-text-strong">{language.t("session.review.noVcs.createGit.title")}</div> + <div class="text-14-regular text-text-base max-w-md" style={{ "line-height": "var(--line-height-normal)" }}> + {language.t("session.review.noVcs.createGit.description")} + </div> + </div> + <Button size="large" disabled={gitMutation.isPending} onClick={initGit}> + {gitMutation.isPending + ? language.t("session.review.noVcs.createGit.actionLoading") + : language.t("session.review.noVcs.createGit.action")} + </Button> + </div> + ) + const reviewEmptyText = createMemo(() => { if (store.changes === "git") return language.t("session.review.noUncommittedChanges") if (store.changes === "branch") return language.t("session.review.noBranchChanges") - if (store.changes === "turn") return language.t("session.review.noChanges") - return language.t(sessionEmptyKey()) + return language.t("session.review.noChanges") }) const reviewEmpty = (input: { loadingClass: string; emptyClass: string }) => { @@ -1193,31 +1200,10 @@ export default function Page() { } if (store.changes === "turn") { + if (nogit()) return createGit(input) return empty(reviewEmptyText()) } - if (hasSessionReview() && !diffsReady()) { - return <div class={input.loadingClass}>{language.t("session.review.loadingChanges")}</div> - } - - if (sessionEmptyKey() === "session.review.noVcs") { - return ( - <div class={input.emptyClass}> - <div class="flex flex-col gap-3"> - <div class="text-14-medium text-text-strong">{language.t("session.review.noVcs.createGit.title")}</div> - <div class="text-14-regular text-text-base max-w-md" style={{ "line-height": "var(--line-height-normal)" }}> - {language.t("session.review.noVcs.createGit.description")} - </div> - </div> - <Button size="large" disabled={gitMutation.isPending} onClick={initGit}> - {gitMutation.isPending - ? language.t("session.review.noVcs.createGit.actionLoading") - : language.t("session.review.noVcs.createGit.action")} - </Button> - </div> - ) - } - return ( <div class={input.emptyClass}> <div class="text-14-regular text-text-weak max-w-56">{reviewEmptyText()}</div> diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx index b68128645..71dfe375e 100644 --- a/packages/app/src/pages/session/review-tab.tsx +++ b/packages/app/src/pages/session/review-tab.tsx @@ -1,6 +1,6 @@ import { createEffect, createSignal, onCleanup, type JSX } from "solid-js" import { makeEventListener } from "@solid-primitives/event-listener" -import type { FileDiff } from "@opencode-ai/sdk/v2" +import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" import { SessionReview } from "@opencode-ai/ui/session-review" import type { SessionReviewCommentActions, @@ -14,10 +14,12 @@ import type { LineComment } from "@/context/comments" export type DiffStyle = "unified" | "split" +type ReviewDiff = SnapshotFileDiff | VcsFileDiff + export interface SessionReviewTabProps { title?: JSX.Element empty?: JSX.Element - diffs: () => FileDiff[] + diffs: () => ReviewDiff[] view: () => ReturnType<ReturnType<typeof useLayout>["view"]> diffStyle: DiffStyle onDiffStyleChange?: (style: DiffStyle) => void diff --git a/packages/app/src/pages/session/session-side-panel.tsx b/packages/app/src/pages/session/session-side-panel.tsx index 86f932ea2..cddbea84d 100644 --- a/packages/app/src/pages/session/session-side-panel.tsx +++ b/packages/app/src/pages/session/session-side-panel.tsx @@ -8,7 +8,7 @@ import { ResizeHandle } from "@opencode-ai/ui/resize-handle" import { Mark } from "@opencode-ai/ui/logo" import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, closestCenter } from "@thisbeyond/solid-dnd" import type { DragEvent } from "@thisbeyond/solid-dnd" -import type { FileDiff } from "@opencode-ai/sdk/v2" +import type { SnapshotFileDiff, VcsFileDiff } from "@opencode-ai/sdk/v2" import { ConstrainDragYAxis, getDraggableId } from "@/utils/solid-dnd" import { useDialog } from "@opencode-ai/ui/context/dialog" @@ -27,7 +27,7 @@ import { useSessionLayout } from "@/pages/session/session-layout" export function SessionSidePanel(props: { canReview: () => boolean - diffs: () => FileDiff[] + diffs: () => (SnapshotFileDiff | VcsFileDiff)[] diffsReady: () => boolean empty: () => string hasReview: () => boolean |
