summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-31 09:23:24 -0600
committerAdam <[email protected]>2025-12-31 09:23:24 -0600
commit2ec6a21cc0018be6677e4cbad6bf48dbf8b37786 (patch)
tree6ad3f27288f660b4bba43772075c5138764f25b3 /packages/ui/src/components
parentebf5ad25c5f5cdf42bcb93199d9913f260ebe767 (diff)
downloadopencode-2ec6a21cc0018be6677e4cbad6bf48dbf8b37786.tar.gz
opencode-2ec6a21cc0018be6677e4cbad6bf48dbf8b37786.zip
feat(desktop): unified diff toggle
Diffstat (limited to 'packages/ui/src/components')
-rw-r--r--packages/ui/src/components/code.tsx4
-rw-r--r--packages/ui/src/components/diff-ssr.tsx2
-rw-r--r--packages/ui/src/components/diff.tsx17
-rw-r--r--packages/ui/src/components/session-review.tsx18
4 files changed, 27 insertions, 14 deletions
diff --git a/packages/ui/src/components/code.tsx b/packages/ui/src/components/code.tsx
index 77696faed..fda08260f 100644
--- a/packages/ui/src/components/code.tsx
+++ b/packages/ui/src/components/code.tsx
@@ -1,7 +1,7 @@
import { type FileContents, File, FileOptions, LineAnnotation } from "@pierre/diffs"
import { ComponentProps, createEffect, createMemo, splitProps } from "solid-js"
import { createDefaultOptions, styleVariables } from "../pierre"
-import { workerPool } from "../pierre/worker"
+import { getWorkerPool } from "../pierre/worker"
export type CodeProps<T = {}> = FileOptions<T> & {
file: FileContents
@@ -21,7 +21,7 @@ export function Code<T>(props: CodeProps<T>) {
...createDefaultOptions<T>("unified"),
...others,
},
- workerPool,
+ getWorkerPool("unified"),
),
)
diff --git a/packages/ui/src/components/diff-ssr.tsx b/packages/ui/src/components/diff-ssr.tsx
index e367a4fbe..56a12c100 100644
--- a/packages/ui/src/components/diff-ssr.tsx
+++ b/packages/ui/src/components/diff-ssr.tsx
@@ -13,7 +13,7 @@ export function Diff<T>(props: SSRDiffProps<T>) {
let container!: HTMLDivElement
let fileDiffRef!: HTMLElement
const [local, others] = splitProps(props, ["before", "after", "class", "classList", "annotations"])
- const workerPool = useWorkerPool()
+ const workerPool = useWorkerPool(props.diffStyle)
let fileDiffInstance: FileDiff<T> | undefined
const cleanupFunctions: Array<() => void> = []
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 75dde0440..ff70cece9 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -1,7 +1,7 @@
import { FileDiff } from "@pierre/diffs"
import { createEffect, createMemo, onCleanup, splitProps } from "solid-js"
import { createDefaultOptions, type DiffProps, styleVariables } from "../pierre"
-import { workerPool } from "../pierre/worker"
+import { getWorkerPool } from "../pierre/worker"
// interface ThreadMetadata {
// threadId: string
@@ -20,26 +20,23 @@ export function Diff<T>(props: DiffProps<T>) {
...createDefaultOptions(props.diffStyle),
...others,
},
- workerPool,
+ getWorkerPool(props.diffStyle),
),
)
- const cleanupFunctions: Array<() => void> = []
-
createEffect(() => {
+ const diff = fileDiff()
container.innerHTML = ""
- fileDiff().render({
+ diff.render({
oldFile: local.before,
newFile: local.after,
lineAnnotations: local.annotations,
containerWrapper: container,
})
- })
- onCleanup(() => {
- // Clean up FileDiff event handlers and dispose SolidJS components
- fileDiff()?.cleanUp()
- cleanupFunctions.forEach((dispose) => dispose())
+ onCleanup(() => {
+ diff.cleanUp()
+ })
})
return <div data-component="diff" style={styleVariables} ref={container} />
diff --git a/packages/ui/src/components/session-review.tsx b/packages/ui/src/components/session-review.tsx
index 9162b5216..9e6c633f4 100644
--- a/packages/ui/src/components/session-review.tsx
+++ b/packages/ui/src/components/session-review.tsx
@@ -1,5 +1,6 @@
import { Accordion } from "./accordion"
import { Button } from "./button"
+import { RadioGroup } from "./radio-group"
import { DiffChanges } from "./diff-changes"
import { FileIcon } from "./file-icon"
import { Icon } from "./icon"
@@ -13,8 +14,12 @@ import { PreloadMultiFileDiffResult } from "@pierre/diffs/ssr"
import { Dynamic } from "solid-js/web"
import { checksum } from "@opencode-ai/util/encode"
+export type SessionReviewDiffStyle = "unified" | "split"
+
export interface SessionReviewProps {
split?: boolean
+ diffStyle?: SessionReviewDiffStyle
+ onDiffStyleChange?: (diffStyle: SessionReviewDiffStyle) => void
class?: string
classList?: Record<string, boolean | undefined>
classes?: { root?: string; header?: string; container?: string }
@@ -28,6 +33,8 @@ export const SessionReview = (props: SessionReviewProps) => {
open: props.diffs.length > 10 ? [] : props.diffs.map((d) => d.file),
})
+ const diffStyle = () => props.diffStyle ?? (props.split ? "split" : "unified")
+
const handleChange = (open: string[]) => {
setStore("open", open)
}
@@ -60,6 +67,15 @@ export const SessionReview = (props: SessionReviewProps) => {
>
<div data-slot="session-review-title">Session changes</div>
<div data-slot="session-review-actions">
+ <Show when={props.onDiffStyleChange}>
+ <RadioGroup
+ options={["unified", "split"] as const}
+ current={diffStyle()}
+ value={(style) => style}
+ label={(style) => (style === "unified" ? "Unified" : "Split")}
+ onSelect={(style) => style && props.onDiffStyleChange?.(style)}
+ />
+ </Show>
<Button size="normal" icon="chevron-grabber-vertical" onClick={handleExpandOrCollapseAll}>
<Switch>
<Match when={store.open.length > 0}>Collapse all</Match>
@@ -102,7 +118,7 @@ export const SessionReview = (props: SessionReviewProps) => {
<Dynamic
component={diffComponent}
preloadedDiff={diff.preloaded}
- diffStyle={props.split ? "split" : "unified"}
+ diffStyle={diffStyle()}
before={{
name: diff.file!,
contents: diff.before!,