✨ feat(vscode): 代码阅读滚进卡片的子块时把外层卡片钉在顶上,同 VS Code 的 Sticky Scroll

This commit is contained in:
cruldra committed 2026-10-08 07:17:26 +08:00
1 parent 5ce2e904f4
commit eb3d1b90cd
17 files changed
+548 -31

No files matched your search

+8 -2
View File
@@ -17,6 +17,7 @@ import { applyFilter, excludedBy, keptWhileEditing } from './filter'
import { FilterBar } from './FilterBar'
import { OverviewRuler } from './OverviewRuler'
import { asksOf, historyOf, PATH_ASK_ANCHOR } from './qa'
import { StickyLines } from './StickyLines'
import { useChangeNav } from './useChangeNav'
import { useDefinitionLinks } from './useDefinitionLinks'
import { useDefinitionPeek } from './useDefinitionPeek'
@@ -27,6 +28,7 @@ import { useRepoLinks } from './useRepoLinks'
import { useReveal } from './useReveal'
import { useRewrite } from './useRewrite'
import { useScrollPosition } from './useScrollPosition'
import { useStickySettings } from './useStickyScroll'
import { collapsedIds } from './viewState'
import { onMessage, postMessage, viewState } from './vscode'
@@ -62,6 +64,8 @@ export function App(): ReactElement | null {
const [diff, setDiff] = useState<DocumentDiff | null>(null)
/** 收到消息时读眼下哪些块在编辑(消息回调只在挂载时注册一次) */
const editing = useRef(view.editing)
/** 块树所在的页面内容:钉住外层卡片时在这里面量 */
const content = useRef<HTMLDivElement>(null)
// 解析失败的文档没有块,不标差异;删掉的块按块筛选同样藏
const changes = useMemo(() => doc && doc.error === undefined
? diffTree(doc.blocks, diff, doc.version, removed => !excludedBy(removed.block, excluded))
@@ -91,9 +95,10 @@ export function App(): ReactElement | null {
useReveal(doc, reveal, collapsed, unshown, covered, show, expand, revealed)
useDefinitionLinks(doc?.version)
const peek = useDefinitionPeek(doc?.version)
const sticky = useStickySettings()
useRepoLinks()
useRepoImages()
const nav = useChangeNav(stops, collapsed, expand)
const nav = useChangeNav(stops, collapsed, expand, sticky)
const occurrencePage = useMemo((): OccurrencePage | undefined => doc
? {
blocks: doc.blocks,
@@ -202,7 +207,7 @@ export function App(): ReactElement | null {
)}
/>
{changes && diff && <OverviewRuler stops={stops} lineCount={diff.lineCount} onPick={nav.goTo} />}
<div className="mx-auto box-content max-w-[880px] px-6 py-5">
<div ref={content} className="mx-auto box-content max-w-[880px] px-6 py-5">
{qa.state.available && (
<div className="mb-4">
<AskThread
@@ -241,6 +246,7 @@ export function App(): ReactElement | null {
? <BlockLevel blocks={doc.blocks} tree={tree} />
: <div className="text-[var(--vscode-descriptionForeground)]">所有块都被筛选隐藏了。</div>}
</div>
{sticky?.enabled && <StickyLines content={content} blocks={doc.blocks} settings={sticky} />}
<DefinitionPeekPopup shown={peek.shown} onJump={peek.jump} />
</DisplayNameContext>
</HighlightContext>