summaryrefslogtreecommitdiffhomepage
path: root/packages/ui/src/components/diff.tsx
diff options
context:
space:
mode:
authorAdam <[email protected]>2026-01-21 06:17:55 -0600
committerAdam <[email protected]>2026-01-22 22:12:12 -0600
commitcb481d9ac861813d4ff091ed33bcac9e882da1a1 (patch)
treec08be4b96815b74ac6dc1e3bab6359cd5dbb27b3 /packages/ui/src/components/diff.tsx
parent0ce0cacb282c47943348a2af21ea00e721bcb9d9 (diff)
downloadopencode-cb481d9ac861813d4ff091ed33bcac9e882da1a1.tar.gz
opencode-cb481d9ac861813d4ff091ed33bcac9e882da1a1.zip
wip(app): line selection
Diffstat (limited to 'packages/ui/src/components/diff.tsx')
-rw-r--r--packages/ui/src/components/diff.tsx42
1 files changed, 42 insertions, 0 deletions
diff --git a/packages/ui/src/components/diff.tsx b/packages/ui/src/components/diff.tsx
index 20dd5c440..825a7e076 100644
--- a/packages/ui/src/components/diff.tsx
+++ b/packages/ui/src/components/diff.tsx
@@ -63,6 +63,7 @@ export function Diff<T>(props: DiffProps<T>) {
"classList",
"annotations",
"selectedLines",
+ "commentedLines",
"onRendered",
])
@@ -82,6 +83,7 @@ export function Diff<T>(props: DiffProps<T>) {
let instance: FileDiff<T> | undefined
const [current, setCurrent] = createSignal<FileDiff<T> | undefined>(undefined)
+ const [rendered, setRendered] = createSignal(0)
const getRoot = () => {
const host = container.querySelector("diffs-container")
@@ -172,6 +174,39 @@ export function Diff<T>(props: DiffProps<T>) {
observer.observe(container, { childList: true, subtree: true })
}
+ const applyCommentedLines = (ranges: SelectedLineRange[]) => {
+ const root = getRoot()
+ if (!root) return
+
+ const existing = Array.from(root.querySelectorAll("[data-comment-selected]"))
+ for (const node of existing) {
+ if (!(node instanceof HTMLElement)) continue
+ node.removeAttribute("data-comment-selected")
+ }
+
+ for (const range of ranges) {
+ const start = Math.max(1, Math.min(range.start, range.end))
+ const end = Math.max(range.start, range.end)
+
+ for (let line = start; line <= end; line++) {
+ const expectedSide =
+ line === end ? (range.endSide ?? range.side) : line === start ? range.side : (range.side ?? range.endSide)
+
+ const nodes = Array.from(root.querySelectorAll(`[data-line="${line}"], [data-alt-line="${line}"]`))
+ for (const node of nodes) {
+ if (!(node instanceof HTMLElement)) continue
+
+ if (expectedSide) {
+ const side = findSide(node)
+ if (side && side !== expectedSide) continue
+ }
+
+ node.setAttribute("data-comment-selected", "")
+ }
+ }
+ }
+ }
+
const setSelectedLines = (range: SelectedLineRange | null) => {
const active = current()
if (!active) return
@@ -379,10 +414,17 @@ export function Diff<T>(props: DiffProps<T>) {
containerWrapper: container,
})
+ setRendered((value) => value + 1)
notifyRendered()
})
createEffect(() => {
+ rendered()
+ const ranges = local.commentedLines ?? []
+ requestAnimationFrame(() => applyCommentedLines(ranges))
+ })
+
+ createEffect(() => {
const selected = local.selectedLines ?? null
setSelectedLines(selected)
})