diff options
| author | Adam <[email protected]> | 2026-01-04 23:28:03 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-05 13:21:30 -0600 |
| commit | d315026abc0a07e88b3bec6b74253e272161659b (patch) | |
| tree | 5f57c5beeb753492e0780654576ca645a44896de | |
| parent | d1191675c68d8995333fc4300b11d09e87d711d2 (diff) | |
| download | opencode-d315026abc0a07e88b3bec6b74253e272161659b.tar.gz opencode-d315026abc0a07e88b3bec6b74253e272161659b.zip | |
fix(app): prompt input shouldn't cover content
| -rw-r--r-- | packages/app/src/components/session/session-new-view.tsx | 5 | ||||
| -rw-r--r-- | packages/app/src/pages/session.tsx | 39 |
2 files changed, 39 insertions, 5 deletions
diff --git a/packages/app/src/components/session/session-new-view.tsx b/packages/app/src/components/session/session-new-view.tsx index 81d719471..68ef0cc1f 100644 --- a/packages/app/src/components/session/session-new-view.tsx +++ b/packages/app/src/components/session/session-new-view.tsx @@ -44,7 +44,10 @@ export function NewSessionView(props: NewSessionViewProps) { } return ( - <div class="size-full flex flex-col pb-45 justify-end items-start gap-4 flex-[1_0_0] self-stretch max-w-200 mx-auto px-6"> + <div + class="size-full flex flex-col pb-45 justify-end items-start gap-4 flex-[1_0_0] self-stretch max-w-200 mx-auto px-6" + style={{ "padding-bottom": "calc(var(--prompt-height, 11.25rem) + 64px)" }} + > <div class="text-20-medium text-text-weaker">New session</div> <div class="flex justify-center items-center gap-3"> <Icon name="folder" size="small" /> diff --git a/packages/app/src/pages/session.tsx b/packages/app/src/pages/session.tsx index be500afd3..3c23ac61e 100644 --- a/packages/app/src/pages/session.tsx +++ b/packages/app/src/pages/session.tsx @@ -1,5 +1,6 @@ import { For, onCleanup, Show, Match, Switch, createMemo, createEffect, on } from "solid-js" import { createMediaQuery } from "@solid-primitives/media" +import { createResizeObserver } from "@solid-primitives/resize-observer" import { Dynamic } from "solid-js/web" import { useLocal } from "@/context/local" import { selectionFromLines, useFile, type SelectedLineRange } from "@/context/file" @@ -248,6 +249,7 @@ export default function Page() { messageId: undefined as string | undefined, mobileTab: "session" as "session" | "review", newSessionWorktree: "main", + promptHeight: 0, }) const newSessionWorktree = createMemo(() => { @@ -289,6 +291,8 @@ export default function Page() { const idle = { type: "idle" as const } let inputRef!: HTMLDivElement + let promptDock: HTMLDivElement | undefined + let scroller: HTMLDivElement | undefined createEffect(() => { if (!params.id) return @@ -668,9 +672,30 @@ export default function Page() { const anchor = (id: string) => `message-${id}` const setScrollRef = (el: HTMLDivElement | undefined) => { + scroller = el autoScroll.scrollRef(el) } + createResizeObserver( + () => promptDock, + ({ height }) => { + const next = Math.ceil(height) + + if (next === store.promptHeight) return + + const el = scroller + const stick = el ? el.scrollHeight - el.clientHeight - el.scrollTop < 10 : false + + setStore("promptHeight", next) + + if (stick && el) { + requestAnimationFrame(() => { + el.scrollTo({ top: el.scrollHeight, behavior: "auto" }) + }) + } + }, + ) + const updateHash = (id: string) => { window.history.replaceState(null, "", `#${anchor(id)}`) } @@ -776,7 +801,10 @@ export default function Page() { "@container relative shrink-0 flex flex-col min-h-0 h-full bg-background-stronger": true, "flex-1 md:flex-none py-6 md:py-3": true, }} - style={{ width: isDesktop() && showTabs() ? `${layout.session.width()}px` : "100%" }} + style={{ + width: isDesktop() && showTabs() ? `${layout.session.width()}px` : "100%", + "--prompt-height": store.promptHeight ? `${store.promptHeight}px` : undefined, + }} > <div class="flex-1 min-h-0 overflow-hidden"> <Switch> @@ -791,7 +819,7 @@ export default function Page() { view={view} diffStyle="unified" classes={{ - root: "pb-32", + root: "pb-[calc(var(--prompt-height,8rem)+32px)]", header: "px-4", container: "px-4", }} @@ -822,7 +850,7 @@ export default function Page() { > <div ref={autoScroll.contentRef} - class="flex flex-col gap-32 items-start justify-start pb-32 md:pb-40 transition-[margin]" + class="flex flex-col gap-32 items-start justify-start pb-[calc(var(--prompt-height,8rem)+64px)] md:pb-[calc(var(--prompt-height,10rem)+64px)] transition-[margin]" classList={{ "mt-0.5": !showTabs(), "mt-0": showTabs(), @@ -894,7 +922,10 @@ export default function Page() { </div> {/* Prompt input */} - <div class="absolute inset-x-0 bottom-0 pt-12 pb-4 md:pb-8 flex flex-col justify-center items-center z-50 px-4 md:px-0 bg-gradient-to-t from-background-stronger via-background-stronger to-transparent pointer-events-none"> + <div + ref={(el) => (promptDock = el)} + class="absolute inset-x-0 bottom-0 pt-12 pb-4 md:pb-8 flex flex-col justify-center items-center z-50 px-4 md:px-0 bg-gradient-to-t from-background-stronger via-background-stronger to-transparent pointer-events-none" + > <div classList={{ "w-full md:px-6 pointer-events-auto": true, |
