summaryrefslogtreecommitdiffhomepage
path: root/packages/app/src/pages/session
diff options
context:
space:
mode:
Diffstat (limited to 'packages/app/src/pages/session')
-rw-r--r--packages/app/src/pages/session/composer/session-composer-state.ts4
-rw-r--r--packages/app/src/pages/session/file-tabs.tsx40
-rw-r--r--packages/app/src/pages/session/helpers.ts12
-rw-r--r--packages/app/src/pages/session/review-tab.tsx20
-rw-r--r--packages/app/src/pages/session/terminal-panel.tsx9
5 files changed, 32 insertions, 53 deletions
diff --git a/packages/app/src/pages/session/composer/session-composer-state.ts b/packages/app/src/pages/session/composer/session-composer-state.ts
index 0884f4cc6..eab210868 100644
--- a/packages/app/src/pages/session/composer/session-composer-state.ts
+++ b/packages/app/src/pages/session/composer/session-composer-state.ts
@@ -1,5 +1,6 @@
import { createEffect, createMemo, on, onCleanup, onMount } from "solid-js"
import { createStore } from "solid-js/store"
+import { makeEventListener } from "@solid-primitives/event-listener"
import type { PermissionRequest, QuestionRequest, Todo } from "@opencode-ai/sdk/v2"
import { useParams } from "@solidjs/router"
import { showToast } from "@opencode-ai/ui/toast"
@@ -86,8 +87,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
pull()
}
- window.addEventListener(composerEvent, onEvent)
- onCleanup(() => window.removeEventListener(composerEvent, onEvent))
+ makeEventListener(window, composerEvent, onEvent)
})
const todos = createMemo((): Todo[] => {
diff --git a/packages/app/src/pages/session/file-tabs.tsx b/packages/app/src/pages/session/file-tabs.tsx
index 9430b7025..cb7617523 100644
--- a/packages/app/src/pages/session/file-tabs.tsx
+++ b/packages/app/src/pages/session/file-tabs.tsx
@@ -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 { Dynamic } from "solid-js/web"
+import { makeEventListener } from "@solid-primitives/event-listener"
import type { FileSearchHandle } from "@opencode-ai/ui/file"
import { useFileComponent } from "@opencode-ai/ui/context/file"
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 restoreFrame: number | undefined
let pending: ScrollPos | undefined
- let code: HTMLElement[] = []
+ const [code, setCode] = createSignal<HTMLElement[]>([])
const getCode = () => {
const el = scroll
@@ -106,17 +107,9 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
const sync = () => {
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 = () => {
@@ -128,14 +121,14 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
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 (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
}
@@ -149,24 +142,24 @@ function createScrollSync(input: { tab: () => string; view: ReturnType<typeof us
}
const handleScroll = (event: Event & { currentTarget: HTMLDivElement }) => {
- if (code.length === 0) sync()
+ if (code().length === 0) sync()
save({
- x: code[0]?.scrollLeft ?? event.currentTarget.scrollLeft,
+ x: code()[0]?.scrollLeft ?? event.currentTarget.scrollLeft,
y: event.currentTarget.scrollTop,
})
}
+ createEffect(() => {
+ for (const item of code()) makeEventListener(item, "scroll", onCodeScroll)
+ })
+
const setViewport = (el: HTMLDivElement) => {
scroll = el
restore()
}
onCleanup(() => {
- for (const item of code) {
- item.removeEventListener("scroll", onCodeScroll)
- }
-
if (scrollFrame !== undefined) cancelAnimationFrame(scrollFrame)
if (restoreFrame !== undefined) cancelAnimationFrame(restoreFrame)
})
@@ -358,8 +351,7 @@ export function FileTabContent(props: { tab: string }) {
find?.focus()
}
- window.addEventListener("keydown", onKeyDown, { capture: true })
- onCleanup(() => window.removeEventListener("keydown", onKeyDown, { capture: true }))
+ makeEventListener(window, "keydown", onKeyDown, { capture: true })
})
createEffect(
diff --git a/packages/app/src/pages/session/helpers.ts b/packages/app/src/pages/session/helpers.ts
index 7e2c1ccf7..f3215f685 100644
--- a/packages/app/src/pages/session/helpers.ts
+++ b/packages/app/src/pages/session/helpers.ts
@@ -1,5 +1,6 @@
import { batch, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
import { createStore } from "solid-js/store"
+import { makeEventListener } from "@solid-primitives/event-listener"
import { same } from "@/utils/same"
const emptyTabs: string[] = []
@@ -171,14 +172,9 @@ export const createSizing = () => {
}
onMount(() => {
- window.addEventListener("pointerup", stop)
- window.addEventListener("pointercancel", stop)
- window.addEventListener("blur", stop)
- onCleanup(() => {
- window.removeEventListener("pointerup", stop)
- window.removeEventListener("pointercancel", stop)
- window.removeEventListener("blur", stop)
- })
+ makeEventListener(window, "pointerup", stop)
+ makeEventListener(window, "pointercancel", stop)
+ makeEventListener(window, "blur", stop)
})
onCleanup(() => {
diff --git a/packages/app/src/pages/session/review-tab.tsx b/packages/app/src/pages/session/review-tab.tsx
index 76b65a221..b68128645 100644
--- a/packages/app/src/pages/session/review-tab.tsx
+++ b/packages/app/src/pages/session/review-tab.tsx
@@ -1,4 +1,5 @@
-import { createEffect, onCleanup, type JSX } from "solid-js"
+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 { SessionReview } from "@opencode-ai/ui/session-review"
import type {
@@ -123,13 +124,6 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
onCleanup(() => {
if (restoreFrame !== undefined) cancelAnimationFrame(restoreFrame)
- if (scroll) {
- scroll.removeEventListener("wheel", handleInteraction, { capture: true })
- scroll.removeEventListener("mousewheel", handleInteraction, { capture: true })
- scroll.removeEventListener("pointerdown", handleInteraction, { capture: true })
- scroll.removeEventListener("touchstart", handleInteraction, { capture: true })
- scroll.removeEventListener("keydown", handleInteraction, { capture: true })
- }
})
return (
@@ -138,11 +132,11 @@ export function SessionReviewTab(props: SessionReviewTabProps) {
empty={props.empty}
scrollRef={(el) => {
scroll = el
- el.addEventListener("wheel", handleInteraction, { passive: true, capture: true })
- el.addEventListener("mousewheel", handleInteraction, { passive: true, capture: true })
- el.addEventListener("pointerdown", handleInteraction, { passive: true, capture: true })
- el.addEventListener("touchstart", handleInteraction, { passive: true, capture: true })
- el.addEventListener("keydown", handleInteraction, { passive: true, capture: true })
+ makeEventListener(el, "wheel", handleInteraction, { passive: true, capture: true })
+ makeEventListener(el, "mousewheel", handleInteraction, { passive: true, capture: true })
+ makeEventListener(el, "pointerdown", handleInteraction, { passive: true, capture: true })
+ makeEventListener(el, "touchstart", handleInteraction, { passive: true, capture: true })
+ makeEventListener(el, "keydown", handleInteraction, { capture: true })
props.onScrollRef?.(el)
queueRestore()
}}
diff --git a/packages/app/src/pages/session/terminal-panel.tsx b/packages/app/src/pages/session/terminal-panel.tsx
index c663d7d67..1161d565a 100644
--- a/packages/app/src/pages/session/terminal-panel.tsx
+++ b/packages/app/src/pages/session/terminal-panel.tsx
@@ -1,5 +1,6 @@
import { For, Show, createEffect, createMemo, on, onCleanup, onMount } from "solid-js"
import { createStore } from "solid-js/store"
+import { makeEventListener } from "@solid-primitives/event-listener"
import { Tabs } from "@opencode-ai/ui/tabs"
import { ResizeHandle } from "@opencode-ai/ui/resize-handle"
import { IconButton } from "@opencode-ai/ui/icon-button"
@@ -50,12 +51,8 @@ export function TerminalPanel() {
const port = window.visualViewport
sync()
- window.addEventListener("resize", sync)
- port?.addEventListener("resize", sync)
- onCleanup(() => {
- window.removeEventListener("resize", sync)
- port?.removeEventListener("resize", sync)
- })
+ makeEventListener(window, "resize", sync)
+ if (port) makeEventListener(port, "resize", sync)
})
createEffect(() => {