fix: guard pull refresh during unsaved editor edits
This commit is contained in:
@@ -38,6 +38,7 @@ describe('useAppSave', () => {
|
||||
handleSwitchTab: vi.fn(),
|
||||
setToastMessage: vi.fn(),
|
||||
loadModifiedFiles: vi.fn(),
|
||||
trackUnsaved: vi.fn(),
|
||||
clearUnsaved: vi.fn(),
|
||||
unsavedPaths: new Set<string>(),
|
||||
tabs: [] as Array<{ entry: VaultEntry; content: string }>,
|
||||
@@ -56,6 +57,7 @@ describe('useAppSave', () => {
|
||||
deps.unsavedPaths = new Set()
|
||||
deps.tabs = []
|
||||
deps.activeTabPath = null
|
||||
deps.trackUnsaved.mockReset()
|
||||
deps.handleRenameNote.mockResolvedValue(undefined)
|
||||
deps.handleRenameFilename.mockResolvedValue(undefined)
|
||||
deps.initialH1AutoRenameEnabled = true
|
||||
@@ -172,6 +174,20 @@ describe('useAppSave', () => {
|
||||
expect(typeof result.current.handleContentChange).toBe('function')
|
||||
})
|
||||
|
||||
it('marks the edited path as unsaved immediately on content change', () => {
|
||||
const entry = makeEntry('/vault/note.md', 'Note', 'note.md')
|
||||
const { result } = renderSave({
|
||||
tabs: [{ entry, content: '# Note\n\nBefore' }],
|
||||
activeTabPath: entry.path,
|
||||
})
|
||||
|
||||
act(() => {
|
||||
result.current.handleContentChange(entry.path, '# Note\n\nAfter')
|
||||
})
|
||||
|
||||
expect(deps.trackUnsaved).toHaveBeenCalledWith(entry.path)
|
||||
})
|
||||
|
||||
it('bumps modifiedAt in live entry state after saving', async () => {
|
||||
vi.useFakeTimers()
|
||||
vi.setSystemTime(new Date('2026-04-16T14:45:00Z'))
|
||||
|
||||
@@ -414,6 +414,7 @@ interface AppSaveDeps {
|
||||
setToastMessage: (msg: string | null) => void
|
||||
loadModifiedFiles: () => void
|
||||
reloadViews?: () => Promise<void>
|
||||
trackUnsaved?: (path: string) => void
|
||||
clearUnsaved: (path: string) => void
|
||||
unsavedPaths: Set<string>
|
||||
tabs: TabState[]
|
||||
@@ -587,6 +588,7 @@ function useEditorPersistence({
|
||||
setTabs,
|
||||
setToastMessage,
|
||||
loadModifiedFiles,
|
||||
trackUnsaved,
|
||||
clearUnsaved,
|
||||
reloadViews,
|
||||
scheduleUntitledRename,
|
||||
@@ -597,6 +599,7 @@ function useEditorPersistence({
|
||||
setTabs: AppSaveDeps['setTabs']
|
||||
setToastMessage: AppSaveDeps['setToastMessage']
|
||||
loadModifiedFiles: AppSaveDeps['loadModifiedFiles']
|
||||
trackUnsaved?: AppSaveDeps['trackUnsaved']
|
||||
clearUnsaved: AppSaveDeps['clearUnsaved']
|
||||
reloadViews: AppSaveDeps['reloadViews']
|
||||
scheduleUntitledRename: (path: string, content: string) => void
|
||||
@@ -629,8 +632,10 @@ function useEditorPersistence({
|
||||
})
|
||||
|
||||
const handleContentChange = useCallback((path: string, content: string) => {
|
||||
handleContentChangeRaw(resolveCurrentPath(path), content)
|
||||
}, [handleContentChangeRaw, resolveCurrentPath])
|
||||
const resolvedPath = resolveCurrentPath(path)
|
||||
trackUnsaved?.(resolvedPath)
|
||||
handleContentChangeRaw(resolvedPath, content)
|
||||
}, [handleContentChangeRaw, resolveCurrentPath, trackUnsaved])
|
||||
|
||||
const savePendingForPath = useCallback((path: string) => (
|
||||
savePendingForPathRaw(resolveCurrentPath(path))
|
||||
@@ -736,7 +741,7 @@ function useAppSaveHandlers({
|
||||
|
||||
export function useAppSave({
|
||||
updateEntry, setTabs, handleSwitchTab, setToastMessage, loadModifiedFiles, reloadViews,
|
||||
clearUnsaved, unsavedPaths, tabs, activeTabPath, handleRenameNote,
|
||||
trackUnsaved, clearUnsaved, unsavedPaths, tabs, activeTabPath, handleRenameNote,
|
||||
handleRenameFilename: handleRenameFilenameRaw, replaceEntry, resolvedPath,
|
||||
initialH1AutoRenameEnabled,
|
||||
}: AppSaveDeps) {
|
||||
@@ -760,6 +765,7 @@ export function useAppSave({
|
||||
setTabs,
|
||||
setToastMessage,
|
||||
loadModifiedFiles,
|
||||
trackUnsaved,
|
||||
clearUnsaved,
|
||||
reloadViews,
|
||||
scheduleUntitledRename,
|
||||
|
||||
Reference in New Issue
Block a user