fix: keep mounted workspace notes during vault switch

This commit is contained in:
lucaronin
2026-05-12 16:11:31 +02:00
parent e82fc964d6
commit dfb363e768
2 changed files with 42 additions and 4 deletions

View File

@@ -61,6 +61,39 @@ describe('useVaultLoader empty cache recovery', () => {
mockIsTauri = true
})
it('keeps mounted workspace entries visible while a newly active empty workspace loads', async () => {
const laputa = { label: 'Laputa', path: '/laputa', alias: 'laputa', available: true, mounted: true }
const refactoring = { label: 'Refactoring', path: '/refactoring', alias: 'refactoring', available: true, mounted: true }
const commandResults = new Map<string, unknown>([
['reload_vault:/laputa', [makeEntry('/laputa/note/hello.md', 'Laputa Hello')]],
['reload_vault:/refactoring', []],
['list_vault:/refactoring', []],
['get_modified_files:', []],
['list_vault_folders:', []],
['list_views:', []],
])
backendInvokeFn.mockImplementation((command: string, args?: Record<string, unknown>) => {
return Promise.resolve(commandResults.get(commandKey(command, args)) ?? null)
})
const { result, rerender } = renderHook(
({ activePath, vaults }) => useVaultLoader(activePath, vaults, activePath, vaults),
{ initialProps: { activePath: '/laputa', vaults: [laputa] } },
)
await waitFor(() => {
expect(result.current.entries.map((entry) => entry.title)).toEqual(['Laputa Hello'])
})
rerender({ activePath: '/refactoring', vaults: [laputa, refactoring] })
expect(result.current.entries.map((entry) => entry.title)).toContain('Laputa Hello')
await waitFor(() => {
expect(result.current.entries.map((entry) => entry.title)).toContain('Laputa Hello')
})
})
it('reloads a background workspace when its cached startup listing is empty in Tauri mode', async () => {
const brian = { label: 'Brian', path: '/brian', alias: 'brian', available: true, mounted: true }
const laputa = { label: 'Laputa', path: '/laputa', alias: 'laputa', available: true, mounted: true }

View File

@@ -307,18 +307,22 @@ function shouldReuseLoadedWorkspaceEntries(
return !!loadOptions.vaults?.length && isWorkspacePathLoaded(path)
}
function resetInitialVaultLoadState(options: InitialVaultLoadEffectOptions, reuseLoadedWorkspaceEntries: boolean) {
function shouldPreserveWorkspaceEntries(loadOptions: InitialVaultLoadSnapshot): boolean {
return !!loadOptions.vaults?.length
}
function resetInitialVaultLoadState(options: InitialVaultLoadEffectOptions, preserveWorkspaceEntries: boolean) {
clearPrefetchCache()
options.setViews([])
resetVaultState({
clearNewPaths: options.clearNewPaths,
clearUnsaved: options.clearUnsaved,
setEntries: reuseLoadedWorkspaceEntries ? () => {} : options.setEntries,
setEntries: preserveWorkspaceEntries ? () => {} : options.setEntries,
setFolders: options.setFolders,
setIsLoading: options.setIsLoading,
setModifiedFiles: options.setModifiedFiles,
setModifiedFilesError: options.setModifiedFilesError,
setViews: reuseLoadedWorkspaceEntries ? () => {} : options.setViews,
setViews: preserveWorkspaceEntries ? () => {} : options.setViews,
})
options.resetReloading()
}
@@ -395,7 +399,8 @@ function useInitialVaultLoad(options: InitialVaultLoadOptions) {
vaultPath, vaults: loadOptions.vaults,
}
const reuseLoadedWorkspaceEntries = shouldReuseLoadedWorkspaceEntries(path, loadOptions, isWorkspacePathLoaded)
resetInitialVaultLoadState(effectOptions, reuseLoadedWorkspaceEntries)
const preserveWorkspaceEntries = reuseLoadedWorkspaceEntries || shouldPreserveWorkspaceEntries(loadOptions)
resetInitialVaultLoadState(effectOptions, preserveWorkspaceEntries)
if (!hasVaultPath({ vaultPath: path })) return