|
@@ -1,6 +1,7 @@
|
|
|
-import { createEffect, createMemo, Match, on, onCleanup, Switch } from "solid-js"
|
|
|
|
|
|
|
+import { createEffect, createMemo, createSignal, Match, on, onCleanup, Switch } from "solid-js"
|
|
|
import { createStore } from "solid-js/store"
|
|
import { createStore } from "solid-js/store"
|
|
|
import { Dynamic } from "solid-js/web"
|
|
import { Dynamic } from "solid-js/web"
|
|
|
|
|
+import { makeEventListener } from "@solid-primitives/event-listener"
|
|
|
import type { FileSearchHandle } from "@opencode-ai/ui/file"
|
|
import type { FileSearchHandle } from "@opencode-ai/ui/file"
|
|
|
import { useFileComponent } from "@opencode-ai/ui/context/file"
|
|
import { useFileComponent } from "@opencode-ai/ui/context/file"
|
|
|
import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
|
|
import { cloneSelectedLineRange, previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
|
|
@@ -59,7 +60,7 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
|
|
|
let scrollFrame: number | undefined
|
|
let scrollFrame: number | undefined
|
|
|
let restoreFrame: number | undefined
|
|
let restoreFrame: number | undefined
|
|
|
let pending: ScrollPos | undefined
|
|
let pending: ScrollPos | undefined
|
|
|
- let code: HTMLElement[] = []
|
|
|
|
|
|
|
+ const [code, setCode] = createSignal<HTMLElement[]>([])
|
|
|
|
|
|
|
|
const getCode = () => {
|
|
const getCode = () => {
|
|
|
const el = scroll
|
|
const el = scroll
|
|
@@ -106,17 +107,9 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
|
|
|
|
|
|
|
|
const sync = () => {
|
|
const sync = () => {
|
|
|
const next = getCode()
|
|
const next = getCode()
|
|
|
- if (next.length === code.length && next.every((el, i) => el === code[i])) return
|
|
|
|
|
-
|
|
|
|
|
- for (const item of code) {
|
|
|
|
|
- item.removeEventListener("scroll", onCodeScroll)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- code = next
|
|
|
|
|
-
|
|
|
|
|
- for (const item of code) {
|
|
|
|
|
- item.addEventListener("scroll", onCodeScroll)
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ const current = code()
|
|
|
|
|
+ if (next.length === current.length && next.every((el, i) => el === current[i])) return
|
|
|
|
|
+ setCode(next)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const restore = () => {
|
|
const restore = () => {
|
|
@@ -128,14 +121,14 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
|
|
|
|
|
|
|
|
sync()
|
|
sync()
|
|
|
|
|
|
|
|
- if (code.length > 0) {
|
|
|
|
|
- for (const item of code) {
|
|
|
|
|
|
|
+ if (code().length > 0) {
|
|
|
|
|
+ for (const item of code()) {
|
|
|
if (item.scrollLeft !== pos.x) item.scrollLeft = pos.x
|
|
if (item.scrollLeft !== pos.x) item.scrollLeft = pos.x
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
if (el.scrollTop !== pos.y) el.scrollTop = pos.y
|
|
if (el.scrollTop !== pos.y) el.scrollTop = pos.y
|
|
|
- if (code.length > 0) return
|
|
|
|
|
|
|
+ if (code().length > 0) return
|
|
|
if (el.scrollLeft !== pos.x) el.scrollLeft = pos.x
|
|
if (el.scrollLeft !== pos.x) el.scrollLeft = pos.x
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -149,24 +142,24 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const handleScroll = (event: Event & { currentTarget: HTMLDivElement }) => {
|
|
const handleScroll = (event: Event & { currentTarget: HTMLDivElement }) => {
|
|
|
- if (code.length === 0) sync()
|
|
|
|
|
|
|
+ if (code().length === 0) sync()
|
|
|
|
|
|
|
|
save({
|
|
save({
|
|
|
- x: code[0]?.scrollLeft ?? event.currentTarget.scrollLeft,
|
|
|
|
|
|
|
+ x: code()[0]?.scrollLeft ?? event.currentTarget.scrollLeft,
|
|
|
y: event.currentTarget.scrollTop,
|
|
y: event.currentTarget.scrollTop,
|
|
|
})
|
|
})
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ createEffect(() => {
|
|
|
|
|
+ for (const item of code()) makeEventListener(item, "scroll", onCodeScroll)
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
const setViewport = (el: HTMLDivElement) => {
|
|
const setViewport = (el: HTMLDivElement) => {
|
|
|
scroll = el
|
|
scroll = el
|
|
|
restore()
|
|
restore()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
onCleanup(() => {
|
|
onCleanup(() => {
|
|
|
- for (const item of code) {
|
|
|
|
|
- item.removeEventListener("scroll", onCodeScroll)
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
if (scrollFrame !== undefined) cancelAnimationFrame(scrollFrame)
|
|
if (scrollFrame !== undefined) cancelAnimationFrame(scrollFrame)
|
|
|
if (restoreFrame !== undefined) cancelAnimationFrame(restoreFrame)
|
|
if (restoreFrame !== undefined) cancelAnimationFrame(restoreFrame)
|
|
|
})
|
|
})
|
|
@@ -358,8 +351,7 @@ export function FileTabContent(props: { tab: string }) {
|
|
|
find?.focus()
|
|
find?.focus()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- window.addEventListener("keydown", onKeyDown, { capture: true })
|
|
|
|
|
- onCleanup(() => window.removeEventListener("keydown", onKeyDown, { capture: true }))
|
|
|
|
|
|
|
+ makeEventListener(window, "keydown", onKeyDown, { capture: true })
|
|
|
})
|
|
})
|
|
|
|
|
|
|
|
createEffect(
|
|
createEffect(
|