diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index 389c0baea..cc81ae7b6 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1254,6 +1254,7 @@ export default function Page() { { inputRef = el diff --git a/packages/app/src/pages/session/composer/session-composer-region.tsx b/packages/app/src/pages/session/composer/session-composer-region.tsx index a882e25dd..93ea3d465 100644 --- a/packages/app/src/pages/session/composer/session-composer-region.tsx +++ b/packages/app/src/pages/session/composer/session-composer-region.tsx @@ -1,4 +1,5 @@ import { Show, createEffect, createMemo, createSignal, onCleanup } from "solid-js" +import { createStore } from "solid-js/store" import { useParams } from "@solidjs/router" import { useSpring } from "@opencode-ai/ui/motion-spring" import { PromptInput } from "@/components/prompt-input" @@ -12,6 +13,7 @@ import { SessionTodoDock } from "@/pages/session/composer/session-todo-dock" export function SessionComposerRegion(props: { state: SessionComposerState + ready: boolean centered: boolean inputRef: (el: HTMLDivElement) => void newSessionWorktree: string @@ -61,7 +63,44 @@ export function SessionComposerRegion(props: { setSessionHandoff(sessionKey(), { prompt: previewPrompt() }) }) - const open = createMemo(() => props.state.dock() && !props.state.closing()) + const [gate, setGate] = createStore({ + ready: false, + }) + let timer: number | undefined + let frame: number | undefined + + const clear = () => { + if (timer !== undefined) { + window.clearTimeout(timer) + timer = undefined + } + if (frame !== undefined) { + cancelAnimationFrame(frame) + frame = undefined + } + } + + createEffect(() => { + sessionKey() + const ready = props.ready + const delay = 140 + + clear() + setGate("ready", false) + if (!ready) return + + frame = requestAnimationFrame(() => { + frame = undefined + timer = window.setTimeout(() => { + setGate("ready", true) + timer = undefined + }, delay) + }) + }) + + onCleanup(clear) + + const open = createMemo(() => gate.ready && props.state.dock() && !props.state.closing()) const config = createMemo(() => open() ? { @@ -76,7 +115,7 @@ export function SessionComposerRegion(props: { const progress = useSpring(() => (open() ? 1 : 0), config) const value = createMemo(() => Math.max(0, Math.min(1, progress()))) const [height, setHeight] = createSignal(320) - const dock = createMemo(() => props.state.dock() || value() > 0.001) + const dock = createMemo(() => (gate.ready && props.state.dock()) || value() > 0.001) const full = createMemo(() => Math.max(78, height())) const [contentRef, setContentRef] = createSignal()