diff --git a/packages/app/src/pages/session/composer/session-permission-dock.tsx b/packages/app/src/pages/session/composer/session-permission-dock.tsx index 06ff4f4aa71..4de823985ff 100644 --- a/packages/app/src/pages/session/composer/session-permission-dock.tsx +++ b/packages/app/src/pages/session/composer/session-permission-dock.tsx @@ -1,4 +1,4 @@ -import { For, Show } from "solid-js" +import { For, Show, onCleanup, onMount } from "solid-js" import type { PermissionRequest } from "@opencode-ai/sdk/v2" import { Button } from "@opencode-ai/ui/button" import { DockPrompt } from "@opencode-ai/ui/dock-prompt" @@ -11,6 +11,56 @@ export function SessionPermissionDock(props: { onDecide: (response: "once" | "always" | "reject") => void }) { const language = useLanguage() + let root: HTMLDivElement | undefined + + const measure = () => { + if (!root) return + + const scroller = document.querySelector(".scroll-view__viewport") + const head = scroller instanceof HTMLElement ? scroller.firstElementChild : undefined + const top = + head instanceof HTMLElement && head.classList.contains("sticky") ? head.getBoundingClientRect().bottom : 0 + if (!top) { + root.style.removeProperty("--permission-prompt-max-height") + return + } + + const dock = root.closest('[data-component="session-prompt-dock"]') + if (!(dock instanceof HTMLElement)) return + + const dockBottom = dock.getBoundingClientRect().bottom + const below = Math.max(0, dockBottom - root.getBoundingClientRect().bottom) + const gap = 8 + const max = Math.max(240, Math.floor(dockBottom - top - gap - below)) + root.style.setProperty("--permission-prompt-max-height", `${max}px`) + } + + onMount(() => { + let raf: number | undefined + const update = () => { + if (raf !== undefined) cancelAnimationFrame(raf) + raf = requestAnimationFrame(() => { + raf = undefined + measure() + }) + } + + update() + window.addEventListener("resize", update) + + const dock = root?.closest('[data-component="session-prompt-dock"]') + const scroller = document.querySelector(".scroll-view__viewport") + const observer = new ResizeObserver(update) + if (dock instanceof HTMLElement) observer.observe(dock) + if (scroller instanceof HTMLElement) observer.observe(scroller) + + onCleanup(() => { + window.removeEventListener("resize", update) + observer.disconnect() + if (raf !== undefined) cancelAnimationFrame(raf) + root?.style.removeProperty("--permission-prompt-max-height") + }) + }) const toolDescription = () => { const key = `settings.permissions.tool.${props.request.permission}.description` @@ -22,6 +72,7 @@ export function SessionPermissionDock(props: { return ( (root = el)} header={
diff --git a/packages/ui/src/components/message-part.css b/packages/ui/src/components/message-part.css index 58227f62597..513529f7f18 100644 --- a/packages/ui/src/components/message-part.css +++ b/packages/ui/src/components/message-part.css @@ -669,7 +669,7 @@ flex-direction: column; gap: 0; min-height: 0; - max-height: 100dvh; + max-height: var(--permission-prompt-max-height, 100dvh); [data-slot="permission-body"] { display: flex; @@ -720,6 +720,8 @@ gap: 4px; flex: 1; min-height: 0; + overflow-y: auto; + padding-right: 8px; } [data-slot="permission-hint"] {