mirror of
https://github.com/anomalyco/opencode.git
synced 2026-05-13 15:44:56 +00:00
Merge pull request #4 from Hona/fix/virtual-timeline-anchor-1778643000
fix(app): anchor virtual timeline to bottom
This commit is contained in:
@@ -29,7 +29,7 @@ import { previewSelectedLines } from "@opencode-ai/ui/pierre/selection-bridge"
|
||||
import { Button } from "@opencode-ai/ui/button"
|
||||
import { showToast } from "@opencode-ai/ui/toast"
|
||||
import { checksum } from "@opencode-ai/core/util/encode"
|
||||
import { useSearchParams } from "@solidjs/router"
|
||||
import { useLocation, useSearchParams } from "@solidjs/router"
|
||||
import { NewSessionView, SessionHeader } from "@/components/session"
|
||||
import { useComments } from "@/context/comments"
|
||||
import { getSessionPrefetch, SESSION_PREFETCH_TTL } from "@/context/global-sync/session-prefetch"
|
||||
@@ -196,6 +196,7 @@ export default function Page() {
|
||||
const comments = useComments()
|
||||
const terminal = useTerminal()
|
||||
const [searchParams, setSearchParams] = useSearchParams<{ prompt?: string }>()
|
||||
const location = useLocation()
|
||||
const { params, sessionKey, tabs, view } = useSessionLayout()
|
||||
|
||||
createEffect(() => {
|
||||
@@ -1719,6 +1720,9 @@ export default function Page() {
|
||||
onUserScroll={markUserScroll}
|
||||
onHistoryScroll={historyLoader.onScrollerScroll}
|
||||
onAutoScrollInteraction={autoScroll.handleInteraction}
|
||||
shouldAnchorBottom={() =>
|
||||
!location.hash && !store.messageId && !ui.pendingMessage && !autoScroll.userScrolled()
|
||||
}
|
||||
centered={centered()}
|
||||
setContentRef={(el) => {
|
||||
content = el
|
||||
|
||||
@@ -107,6 +107,7 @@ function sameKeys(a: readonly string[] | undefined, b: readonly string[] | undef
|
||||
}
|
||||
|
||||
const timelineCacheLimit = 16
|
||||
const timelineFallbackItemSize = 60
|
||||
const timelineCache = new Map<string, { keys: readonly string[]; cache: VirtualizerHandle["cache"] }>()
|
||||
|
||||
function readTimelineCache(id: string, keys: readonly string[]) {
|
||||
@@ -451,6 +452,7 @@ export function MessageTimeline(props: {
|
||||
onUserScroll: () => void
|
||||
onHistoryScroll: () => void
|
||||
onAutoScrollInteraction: (event: MouseEvent) => void
|
||||
shouldAnchorBottom: () => boolean
|
||||
centered: boolean
|
||||
setContentRef: (el: HTMLDivElement) => void
|
||||
historyShift: boolean
|
||||
@@ -713,6 +715,18 @@ export function MessageTimeline(props: {
|
||||
let cacheRowKeys = timelineRowKeys()
|
||||
let virtualizerSessionKey = cacheSessionKey
|
||||
let virtualizerRowKeys = cacheRowKeys
|
||||
let bottomAnchorSessionKey = ""
|
||||
|
||||
const maybeAnchorBottom = () => {
|
||||
const key = sessionKey()
|
||||
if (bottomAnchorSessionKey === key) return
|
||||
if (!virtualizer) return
|
||||
const keys = timelineRowKeys()
|
||||
if (keys.length === 0) return
|
||||
bottomAnchorSessionKey = key
|
||||
if (!props.shouldAnchorBottom()) return
|
||||
virtualizer.scrollToIndex(keys.length - 1, { align: "end" })
|
||||
}
|
||||
|
||||
createEffect(
|
||||
on(
|
||||
@@ -724,6 +738,7 @@ export function MessageTimeline(props: {
|
||||
if (virtualizer) {
|
||||
virtualizerSessionKey = cacheSessionKey
|
||||
virtualizerRowKeys = cacheRowKeys
|
||||
maybeAnchorBottom()
|
||||
}
|
||||
},
|
||||
{ defer: true },
|
||||
@@ -1669,6 +1684,7 @@ export function MessageTimeline(props: {
|
||||
<Virtualizer
|
||||
data={timelineRowKeys()}
|
||||
cache={virtualCache()}
|
||||
itemSize={virtualCache() ? undefined : timelineFallbackItemSize}
|
||||
scrollRef={root()}
|
||||
shift={props.historyShift}
|
||||
keepMounted={keepMounted()}
|
||||
@@ -1681,6 +1697,7 @@ export function MessageTimeline(props: {
|
||||
virtualizer = handle
|
||||
virtualizerSessionKey = cacheSessionKey
|
||||
virtualizerRowKeys = cacheRowKeys
|
||||
maybeAnchorBottom()
|
||||
scheduleContentRoot(root())
|
||||
}}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user