fix: locate note entries after their content mounts
Cross-platform packages / Validate source (push) Canceled after 0s
Cross-platform packages / macos arm64 (push) Canceled after 0s
Cross-platform packages / Authorize desktop packaging (push) Canceled after 0s
Cross-platform packages / linux arm64 (push) Canceled after 0s
Cross-platform packages / windows arm64 (push) Canceled after 0s
Cross-platform packages / linux x64 (push) Canceled after 0s
Cross-platform packages / macos x64 (push) Canceled after 0s
Cross-platform packages / windows x64 (push) Canceled after 0s
Cross-platform packages / Publish GitHub and OSS release (push) Canceled after 0s

Quick Notes could open the full workspace before its selected record was mounted, losing the scroll request. Perform entry navigation after React commits and retain a deterministic regression. Align the manual-compaction fixture with layered model selection and loaded conversation state.

Release note: 从快速笔记打开完整记录时,等待目标内容挂载后再定位,避免偶发只打开页面却未滚动到所选记录。
This commit is contained in:
mesalogo
2026-09-30 19:46:13 +08:00
parent 89fc100d4f
commit 3be55348a2
7 changed files with 41 additions and 12 deletions
+5
View File
@@ -14254,6 +14254,10 @@ describe("App", () => {
const originalScroll = Object.getOwnPropertyDescriptor(HTMLElement.prototype, 'scrollIntoView')
const scrollIntoView = vi.fn()
Object.defineProperty(HTMLElement.prototype, 'scrollIntoView', { configurable: true, value: scrollIntoView })
const animationFrame = vi.spyOn(globalThis, 'requestAnimationFrame').mockImplementation(callback => {
callback(0)
return 0
})
try {
fireEvent.click(within(added).getByRole('button', { name: '在完整工作区打开' }))
await waitFor(() => {
@@ -14261,6 +14265,7 @@ describe("App", () => {
expect(scrollIntoView).toHaveBeenCalledWith({ block: 'center' })
})
} finally {
animationFrame.mockRestore()
if (originalScroll) Object.defineProperty(HTMLElement.prototype, 'scrollIntoView', originalScroll)
else Reflect.deleteProperty(HTMLElement.prototype, 'scrollIntoView')
}
+13 -10
View File
@@ -707,6 +707,18 @@ export function MagicNotesWorkspace({
return () => cancelAnimationFrame(frame)
}, [detail?.id, detailView])
useLayoutEffect(() => {
const entryId = requestedEntryIdRef.current
if (!entryId || detail?.id !== requestedNoteIdRef.current || detailView !== 'notes') return
const frame = requestAnimationFrame(() => {
const entry = document.getElementById(`magic-note-entry-${entryId}`)
if (!entry) return
entry.scrollIntoView({ block: 'center' })
requestedEntryIdRef.current = undefined
})
return () => cancelAnimationFrame(frame)
}, [detail, detailView])
useEffect(() => {
const layout = todoLayoutRef.current
if (!layout) return
@@ -1168,16 +1180,7 @@ export function MagicNotesWorkspace({
if (libraryView === 'notes') overviewFocusRef.current = `magic-note-select-${target.noteId}`
setDetailView('notes')
focusSwitchTarget(target)
void loadDetail(target.noteId, target.entryId).then(() => {
if (!target.entryId || requestedNoteIdRef.current !== target.noteId) {
return
}
requestAnimationFrame(() =>
document
.getElementById(`magic-note-entry-${target.entryId}`)
?.scrollIntoView({ block: 'center' })
)
})
void loadDetail(target.noteId, target.entryId)
},
[
createNote,