mirror of
https://github.com/anomalyco/opencode.git
synced 2026-04-30 21:49:53 +00:00
cleanup event listeners with solid-primitives/event-listener (#20619)
This commit is contained in:
parent
327f62526a
commit
69d047ae7d
22 changed files with 102 additions and 176 deletions
|
|
@ -1,6 +1,7 @@
|
|||
import { useIsRouting, useLocation } from "@solidjs/router"
|
||||
import { batch, createEffect, onCleanup, onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { Tooltip } from "@opencode-ai/ui/tooltip"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
||||
|
|
@ -349,13 +350,12 @@ export function DebugBar() {
|
|||
|
||||
syncHeap()
|
||||
start()
|
||||
document.addEventListener("visibilitychange", vis)
|
||||
makeEventListener(document, "visibilitychange", vis)
|
||||
|
||||
onCleanup(() => {
|
||||
if (one !== 0) cancelAnimationFrame(one)
|
||||
if (two !== 0) cancelAnimationFrame(two)
|
||||
stop()
|
||||
document.removeEventListener("visibilitychange", vis)
|
||||
for (const ob of obs) ob.disconnect()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import { onCleanup, onMount } from "solid-js"
|
||||
import { onMount } from "solid-js"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { usePrompt, type ContentPart, type ImageAttachmentPart } from "@/context/prompt"
|
||||
import { useLanguage } from "@/context/language"
|
||||
|
|
@ -181,15 +182,9 @@ export function createPromptAttachments(input: PromptAttachmentsInput) {
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("dragover", handleGlobalDragOver)
|
||||
document.addEventListener("dragleave", handleGlobalDragLeave)
|
||||
document.addEventListener("drop", handleGlobalDrop)
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
document.removeEventListener("dragover", handleGlobalDragOver)
|
||||
document.removeEventListener("dragleave", handleGlobalDragLeave)
|
||||
document.removeEventListener("drop", handleGlobalDrop)
|
||||
makeEventListener(document, "dragover", handleGlobalDragOver)
|
||||
makeEventListener(document, "dragleave", handleGlobalDragLeave)
|
||||
makeEventListener(document, "drop", handleGlobalDrop)
|
||||
})
|
||||
|
||||
return {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
import { Component, For, Show, createMemo, onCleanup, onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { Button } from "@opencode-ai/ui/button"
|
||||
import { Icon } from "@opencode-ai/ui/icon"
|
||||
import { IconButton } from "@opencode-ai/ui/icon-button"
|
||||
|
|
@ -250,8 +251,7 @@ function useKeyCapture(input: {
|
|||
input.stop()
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", handle, true)
|
||||
onCleanup(() => document.removeEventListener("keydown", handle, true))
|
||||
makeEventListener(document, "keydown", handle, { capture: true })
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ import { createSimpleContext } from "@opencode-ai/ui/context"
|
|||
import { useDialog } from "@opencode-ai/ui/context/dialog"
|
||||
import { type Accessor, createEffect, createMemo, onCleanup, onMount } from "solid-js"
|
||||
import { createStore } from "solid-js/store"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { useLanguage } from "@/context/language"
|
||||
import { useSettings } from "@/context/settings"
|
||||
import { dict as en } from "@/i18n/en"
|
||||
|
|
@ -378,11 +379,7 @@ export const { use: useCommand, provider: CommandProvider } = createSimpleContex
|
|||
}
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleKeyDown)
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
document.removeEventListener("keydown", handleKeyDown)
|
||||
makeEventListener(document, "keydown", handleKeyDown)
|
||||
})
|
||||
|
||||
function register(cb: () => CommandOption[]): void
|
||||
|
|
|
|||
|
|
@ -1,7 +1,8 @@
|
|||
import type { Event } from "@opencode-ai/sdk/v2/client"
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { createGlobalEmitter } from "@solid-primitives/event-bus"
|
||||
import { batch, onCleanup } from "solid-js"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { batch, onCleanup, onMount } from "solid-js"
|
||||
import z from "zod"
|
||||
import { createSdkForServer } from "@/utils/server"
|
||||
import { useLanguage } from "./language"
|
||||
|
|
@ -206,21 +207,16 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
|
|||
clearHeartbeat()
|
||||
}
|
||||
|
||||
const onVisibility = () => {
|
||||
if (typeof document === "undefined") return
|
||||
if (document.visibilityState !== "visible") return
|
||||
if (!started) return
|
||||
if (Date.now() - lastEventAt < HEARTBEAT_TIMEOUT_MS) return
|
||||
attempt?.abort()
|
||||
}
|
||||
if (typeof document !== "undefined") {
|
||||
document.addEventListener("visibilitychange", onVisibility)
|
||||
}
|
||||
onMount(() => {
|
||||
makeEventListener(document, "visibilitychange", () => {
|
||||
if (document.visibilityState !== "visible") return
|
||||
if (!started) return
|
||||
if (Date.now() - lastEventAt < HEARTBEAT_TIMEOUT_MS) return
|
||||
attempt?.abort()
|
||||
})
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
if (typeof document !== "undefined") {
|
||||
document.removeEventListener("visibilitychange", onVisibility)
|
||||
}
|
||||
stop()
|
||||
abort.abort()
|
||||
flush()
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { createStore, produce } from "solid-js/store"
|
||||
import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
|
||||
import { createSimpleContext } from "@opencode-ai/ui/context"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { useGlobalSync } from "./global-sync"
|
||||
import { useGlobalSDK } from "./global-sdk"
|
||||
import { useServer } from "./server"
|
||||
|
|
@ -366,12 +367,10 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
|
|||
flush()
|
||||
}
|
||||
|
||||
window.addEventListener("pagehide", flush)
|
||||
document.addEventListener("visibilitychange", handleVisibility)
|
||||
makeEventListener(window, "pagehide", flush)
|
||||
makeEventListener(document, "visibilitychange", handleVisibility)
|
||||
|
||||
onCleanup(() => {
|
||||
window.removeEventListener("pagehide", flush)
|
||||
document.removeEventListener("visibilitychange", handleVisibility)
|
||||
scroll.dispose()
|
||||
})
|
||||
})
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@ import {
|
|||
untrack,
|
||||
type Accessor,
|
||||
} from "solid-js"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { useNavigate, useParams } from "@solidjs/router"
|
||||
import { useLayout, LocalProject } from "@/context/layout"
|
||||
import { useGlobalSync } from "@/context/global-sync"
|
||||
|
|
@ -215,18 +216,11 @@ export default function Layout(props: ParentProps) {
|
|||
if (document.visibilityState !== "hidden") return
|
||||
reset()
|
||||
}
|
||||
window.addEventListener("pointerup", stop)
|
||||
window.addEventListener("pointercancel", stop)
|
||||
window.addEventListener("blur", stop)
|
||||
window.addEventListener("blur", blur)
|
||||
document.addEventListener("visibilitychange", hide)
|
||||
onCleanup(() => {
|
||||
window.removeEventListener("pointerup", stop)
|
||||
window.removeEventListener("pointercancel", stop)
|
||||
window.removeEventListener("blur", stop)
|
||||
window.removeEventListener("blur", blur)
|
||||
document.removeEventListener("visibilitychange", hide)
|
||||
})
|
||||
makeEventListener(window, "pointerup", stop)
|
||||
makeEventListener(window, "pointercancel", stop)
|
||||
makeEventListener(window, "blur", stop)
|
||||
makeEventListener(window, "blur", blur)
|
||||
makeEventListener(document, "visibilitychange", hide)
|
||||
})
|
||||
|
||||
const sidebarHovering = createMemo(() => !layout.sidebar.opened() && state.hoverProject !== undefined)
|
||||
|
|
@ -1394,8 +1388,7 @@ export default function Layout(props: ParentProps) {
|
|||
}
|
||||
|
||||
handleDeepLinks(drainPendingDeepLinks(window))
|
||||
window.addEventListener(deepLinkEvent, handler as EventListener)
|
||||
onCleanup(() => window.removeEventListener(deepLinkEvent, handler as EventListener))
|
||||
makeEventListener(window, deepLinkEvent, handler as EventListener)
|
||||
})
|
||||
|
||||
async function renameProject(project: LocalProject, next: string) {
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ import {
|
|||
onMount,
|
||||
untrack,
|
||||
} from "solid-js"
|
||||
import { makeEventListener } from "@solid-primitives/event-listener"
|
||||
import { createMediaQuery } from "@solid-primitives/media"
|
||||
import { createResizeObserver } from "@solid-primitives/resize-observer"
|
||||
import { useLocal } from "@/context/local"
|
||||
|
|
@ -1687,11 +1688,10 @@ export default function Page() {
|
|||
)
|
||||
|
||||
onMount(() => {
|
||||
document.addEventListener("keydown", handleKeyDown)
|
||||
makeEventListener(document, "keydown", handleKeyDown)
|
||||
})
|
||||
|
||||
onCleanup(() => {
|
||||
document.removeEventListener("keydown", handleKeyDown)
|
||||
if (reviewFrame !== undefined) cancelAnimationFrame(reviewFrame)
|
||||
if (refreshFrame !== undefined) cancelAnimationFrame(refreshFrame)
|
||||
if (refreshTimer !== undefined) window.clearTimeout(refreshTimer)
|
||||
|
|
|
|||
|
|
@ -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[] => {
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
}}
|
||||
|
|
|
|||
|
|
@ -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(() => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue