From 359fbc922b13333f2672ff8fd0a5e7fe051779fd Mon Sep 17 00:00:00 2001 From: Logan Yang Date: Wed, 22 Oct 2025 17:09:10 -0700 Subject: [PATCH] Fix new note not discoverable in copilot chat (#1950) --- src/state/vaultDataAtoms.ts | 60 +++++++++++-------------------------- 1 file changed, 17 insertions(+), 43 deletions(-) diff --git a/src/state/vaultDataAtoms.ts b/src/state/vaultDataAtoms.ts index 95d1fc7a..e59a813f 100644 --- a/src/state/vaultDataAtoms.ts +++ b/src/state/vaultDataAtoms.ts @@ -126,8 +126,10 @@ export class VaultDataManager { /** * Handles file rename events + * Note: oldPath parameter is required by Obsidian's event signature but not used + * since we simply refresh all affected data structures */ - private handleFileRename = (file: TAbstractFile): void => { + private handleFileRename = (file: TAbstractFile, _oldPath: string): void => { if (file instanceof TFile) { if (file.extension === "md" || file.extension === "pdf") { this.debouncedRefreshNotes(); @@ -162,7 +164,7 @@ export class VaultDataManager { * Debounced notes refresh - batches rapid file operations using lodash.debounce */ private debouncedRefreshNotes = debounce(() => this.refreshNotes(), VAULT_DEBOUNCE_DELAY, { - leading: false, + leading: true, trailing: true, }); @@ -170,7 +172,7 @@ export class VaultDataManager { * Debounced folders refresh - batches rapid file operations using lodash.debounce */ private debouncedRefreshFolders = debounce(() => this.refreshFolders(), VAULT_DEBOUNCE_DELAY, { - leading: false, + leading: true, trailing: true, }); @@ -181,7 +183,7 @@ export class VaultDataManager { () => this.refreshTagsFrontmatter(), VAULT_DEBOUNCE_DELAY, { - leading: false, + leading: true, trailing: true, } ); @@ -190,7 +192,7 @@ export class VaultDataManager { * Debounced all tags refresh - batches rapid file operations using lodash.debounce */ private debouncedRefreshTagsAll = debounce(() => this.refreshTagsAll(), VAULT_DEBOUNCE_DELAY, { - leading: false, + leading: true, trailing: true, }); @@ -208,11 +210,10 @@ export class VaultDataManager { ); const newFiles = [...markdownFiles, ...pdfFiles]; - // Only update atom if data actually changed (stable reference optimization) - const currentFiles = settingsStore.get(notesAtom); - if (!this.arraysEqual(currentFiles, newFiles)) { - settingsStore.set(notesAtom, newFiles); - } + // Always update atom with new array reference to ensure React components re-render + // Note: Obsidian mutates TFile objects in-place (e.g., on rename), so we need new + // array references to trigger re-renders even when paths are the same + settingsStore.set(notesAtom, newFiles); }; /** @@ -225,11 +226,8 @@ export class VaultDataManager { .getAllLoadedFiles() .filter((file: TAbstractFile): file is TFolder => file instanceof TFolder); - // Only update atom if data actually changed - const currentFolders = settingsStore.get(foldersAtom); - if (!this.arraysEqual(currentFolders, newFolders)) { - settingsStore.set(foldersAtom, newFolders); - } + // Always update atom with new array reference to ensure React components re-render + settingsStore.set(foldersAtom, newFolders); }; /** @@ -250,11 +248,8 @@ export class VaultDataManager { const newTags = Array.from(tagSet).sort(); - // Only update atom if data actually changed - const currentTags = settingsStore.get(tagsFrontmatterAtom); - if (!this.arraysEqual(currentTags, newTags)) { - settingsStore.set(tagsFrontmatterAtom, newTags); - } + // Always update atom with new array reference to ensure React components re-render + settingsStore.set(tagsFrontmatterAtom, newTags); }; /** @@ -275,31 +270,10 @@ export class VaultDataManager { const newTags = Array.from(tagSet).sort(); - // Only update atom if data actually changed - const currentTags = settingsStore.get(tagsAllAtom); - if (!this.arraysEqual(currentTags, newTags)) { - settingsStore.set(tagsAllAtom, newTags); - } + // Always update atom with new array reference to ensure React components re-render + settingsStore.set(tagsAllAtom, newTags); }; - /** - * Helper to compare arrays for equality (stable reference optimization). - * Prevents unnecessary re-renders when data hasn't actually changed. - */ - private arraysEqual(a: T[], b: T[]): boolean { - if (a.length !== b.length) return false; - - // For file/folder arrays, compare by path - if (a.length > 0 && typeof (a[0] as any)?.path === "string") { - const aPaths = new Set((a as any[]).map((item) => item.path)); - const bPaths = (b as any[]).map((item) => item.path); - return bPaths.every((path) => aPaths.has(path)); - } - - // For string arrays (tags), direct comparison - return a.every((val, idx) => val === b[idx]); - } - /** * Cleans up event listeners and debounced functions. * Should be called during plugin unload.