diff options
| author | Brendan Allan <[email protected]> | 2026-04-02 17:40:03 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-04-02 09:40:03 +0000 |
| commit | 69d047ae7dd84d4c4de41e09b1ecee88e3fdc3d3 (patch) | |
| tree | 832dc97a20d9e1ee0ac4fba7b9daa689691a18c3 /packages/app/src/pages/session | |
| parent | 327f62526a7f60c1c67ae017d1b105466bb730e9 (diff) | |
| download | opencode-69d047ae7dd84d4c4de41e09b1ecee88e3fdc3d3.tar.gz opencode-69d047ae7dd84d4c4de41e09b1ecee88e3fdc3d3.zip | |
cleanup event listeners with solid-primitives/event-listener (#20619)
Diffstat (limited to 'packages/app/src/pages/session')
| -rw-r--r-- | packages/app/src/pages/session/composer/session-composer-state.ts | 4 | ||||
| -rw-r--r-- | packages/app/src/pages/session/file-tabs.tsx | 40 | ||||
| -rw-r--r-- | packages/app/src/pages/session/helpers.ts | 12 | ||||
| -rw-r--r-- | packages/app/src/pages/session/review-tab.tsx | 20 | ||||
| -rw-r--r-- | packages/app/src/pages/session/terminal-panel.tsx | 9 |
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(() => { |
