wip(app): line selection

This commit is contained in:
Adam
2026-01-21 06:17:55 -06:00
parent 0ce0cacb28
commit cb481d9ac8
10 changed files with 685 additions and 158 deletions

View File

@@ -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,9 +414,16 @@ 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)