From d6cf91b76712edd2217b3c8bc2a72a476ad7d2f7 Mon Sep 17 00:00:00 2001 From: Lost Paul <70213368+LostPaul@users.noreply.github.com> Date: Wed, 4 Jun 2025 14:54:11 +0200 Subject: [PATCH] Fix changing folder names in the path --- src/events/FrontMatterTitle.ts | 39 +++++++++++++++++++--------- src/events/MutationObserver.ts | 20 +++++++------- src/events/handleRename.ts | 4 +-- src/functions/styleFunctions.ts | 2 +- src/main.ts | 29 +++++++++++++-------- src/settings/FileExplorerSettings.ts | 2 +- src/settings/GeneralSettings.ts | 8 +++--- src/settings/PathSettings.ts | 4 +-- 8 files changed, 65 insertions(+), 43 deletions(-) diff --git a/src/events/FrontMatterTitle.ts b/src/events/FrontMatterTitle.ts index a8ae594..966837f 100644 --- a/src/events/FrontMatterTitle.ts +++ b/src/events/FrontMatterTitle.ts @@ -33,7 +33,7 @@ export class FrontMatterTitlePluginHandler { const event: Listener = { name: 'manager:update', cb: (data) => { - this.handleRename(data as any, true); + this.fmptUpdateFileName(data as any, true); }, }; // Keep ref to remove listener @@ -44,7 +44,7 @@ export class FrontMatterTitlePluginHandler { // this.plugin.app.vault.getFiles().forEach((file) => { // this.handleRename({ id: '', result: false, path: file.path }, false); // }); - this.plugin.updateBreadcrumbs(); + this.plugin.updateAllBreadcrumbs(); })(); } deleteEvent() { @@ -52,10 +52,12 @@ export class FrontMatterTitlePluginHandler { this.dispatcher.removeListener(this.eventRef); } } - async handleRename(data: { + async fmptUpdateFileName(data: { id: string; result: boolean; path: string; + pathOnly: boolean; + breadcrumb?: HTMLElement; }, isEvent: boolean) { if ((data as any).data) data = (data as any).data; const file = this.app.vault.getAbstractFileByPath(data.path); @@ -69,12 +71,19 @@ export class FrontMatterTitlePluginHandler { const folderNote = getFolderNote(this.plugin, folder.path); if (!folderNote) { return; } if (folderNote !== file) { return; } + if (!data.pathOnly) { + this.plugin.changeFolderNameInExplorer(folder, newName); + } + + const breadcrumb = data.breadcrumb; + if (breadcrumb) { + this.plugin.changeFolderNameInPath(folder, newName, breadcrumb); + } if (isEvent) { - this.plugin.changeName(folder, newName, true); - } else { - this.plugin.changeName(folder, newName, false); + this.plugin.updateAllBreadcrumbs(); } + if (newName) { folder.newName = newName; this.modifiedFolders.set(folder.path, folder); @@ -85,11 +94,13 @@ export class FrontMatterTitlePluginHandler { } - async handleRenameFolder(data: { + async fmptUpdateFolderName(data: { id: string; result: boolean; path: string; - }, isEvent: boolean) { + pathOnly: boolean; + breadcrumb?: HTMLElement; + }, replacePath: boolean) { if ((data as any).data) data = (data as any).data; const folder = this.app.vault.getAbstractFileByPath(data.path); if (!(folder instanceof TFolder)) { return; } @@ -100,11 +111,15 @@ export class FrontMatterTitlePluginHandler { const newName = resolver?.resolve(folderNote?.path ?? ''); if (!newName) return; - if (isEvent) { - this.plugin.changeName(folder, newName, true); - } else { - this.plugin.changeName(folder, newName, false); + if (!data.pathOnly) { + this.plugin.changeFolderNameInExplorer(folder, newName); } + + const breadcrumb = data.breadcrumb; + if (breadcrumb) { + this.plugin.changeFolderNameInPath(folder, newName, breadcrumb); + } + folder.newName = newName; this.modifiedFolders.set(folder.path, folder); } diff --git a/src/events/MutationObserver.ts b/src/events/MutationObserver.ts index f01589c..5b9b66e 100644 --- a/src/events/MutationObserver.ts +++ b/src/events/MutationObserver.ts @@ -25,7 +25,7 @@ export function registerFileExplorerObserver(plugin: FolderNotesPlugin) { const titleContainer = activeLeaf.querySelector('.view-header-title-container'); if (!(titleContainer instanceof HTMLElement)) return; - updateBreadcrumbs(plugin, titleContainer); + updateFolderNamesInPath(plugin, titleContainer); }) ); } @@ -50,7 +50,7 @@ function initializeBreadcrumbs(plugin: FolderNotesPlugin) { if (!titleContainers.length) return; titleContainers.forEach((container) => { if (!(container instanceof HTMLElement)) return; - scheduleIdle(() => updateBreadcrumbs(plugin, container), { timeout: 1000 }); + scheduleIdle(() => updateFolderNamesInPath(plugin, container), { timeout: 1000 }); }); } @@ -66,7 +66,7 @@ function observeFolderTitleMutations(container: Element, plugin: FolderNotesPlug for (const mutation of mutations) { for (const node of Array.from(mutation.addedNodes)) { if (!(node instanceof HTMLElement)) continue; - processAddedFolderNodes(node, plugin); + processAddedFolders(node, plugin); } } }); @@ -88,7 +88,7 @@ function initializeAllFolderTitles(container: Element, plugin: FolderNotesPlugin } } -function processAddedFolderNodes(node: HTMLElement, plugin: FolderNotesPlugin) { +function processAddedFolders(node: HTMLElement, plugin: FolderNotesPlugin) { const titles: HTMLElement[] = []; if (node.matches('.nav-folder-title-content')) { titles.push(node); @@ -123,7 +123,7 @@ async function setupFolderTitle(folderTitle: HTMLElement, plugin: FolderNotesPlu await applyCSSClassesToFolder(folderPath, plugin); if (plugin.settings.frontMatterTitle.enabled) { - plugin.fmtpHandler?.handleRenameFolder({ id: '', result: false, path: folderPath }, false); + plugin.fmtpHandler?.fmptUpdateFolderName({ id: '', result: false, path: folderPath, pathOnly: false }, false); } folderTitle.addEventListener('auxclick', (event: MouseEvent) => { @@ -160,29 +160,29 @@ async function setupFolderTitle(folderTitle: HTMLElement, plugin: FolderNotesPlu }); } -async function updateBreadcrumbs(plugin: FolderNotesPlugin, titleContainer: HTMLElement) { +async function updateFolderNamesInPath(plugin: FolderNotesPlugin, titleContainer: HTMLElement) { const headers = titleContainer.querySelectorAll('span.view-header-breadcrumb'); let path = ''; headers.forEach(async (breadcrumb: HTMLElement) => { path += breadcrumb.getAttribute('old-name') ?? (breadcrumb as HTMLElement).innerText.trim(); path += '/'; const folderPath = path.slice(0, -1); - if (plugin.settings.frontMatterTitle.enabled) { - plugin.fmtpHandler?.handleRenameFolder({ id: '', result: false, path: folderPath }, false); - } const excludedFolder = getExcludedFolder(plugin, folderPath, true); if (excludedFolder?.disableFolderNote) return; const folderNote = getFolderNote(plugin, folderPath); if (folderNote) breadcrumb.classList.add('has-folder-note'); - breadcrumb?.setAttribute('data-path', path.slice(0, -1)); if (!breadcrumb.onclick) { breadcrumb.addEventListener('click', (e) => { handleViewHeaderClick(e as MouseEvent, plugin); }, { capture: true }); } + + if (plugin.settings.frontMatterTitle.enabled) { + plugin.fmtpHandler?.fmptUpdateFolderName({ id: '', result: false, path: folderPath, pathOnly: true, breadcrumb: breadcrumb }, true); + } }); } diff --git a/src/events/handleRename.ts b/src/events/handleRename.ts index ba9e1b1..e0753df 100644 --- a/src/events/handleRename.ts +++ b/src/events/handleRename.ts @@ -36,7 +36,7 @@ export function handleRename(file: TAbstractFile, oldPath: string, plugin: Folde } } else if (file instanceof TFile) { if (isRename) { - return handleFileRename(file, oldPath, plugin); + return fmptUpdateFileName(file, oldPath, plugin); } else { return handleFileMove(file, oldPath, plugin); } @@ -129,7 +129,7 @@ export async function handleFolderRename(file: TFolder, oldPath: string, plugin: plugin.app.fileManager.renameFile(folderNote, newPath); } -export async function handleFileRename(file: TFile, oldPath: string, plugin: FolderNotesPlugin) { +export async function fmptUpdateFileName(file: TFile, oldPath: string, plugin: FolderNotesPlugin) { const oldFileName = removeExtension(getFileNameFromPathString(oldPath)); const newFileName = file.basename; if (oldFileName === newFileName) { return; } diff --git a/src/functions/styleFunctions.ts b/src/functions/styleFunctions.ts index d5a27f2..f05bf03 100644 --- a/src/functions/styleFunctions.ts +++ b/src/functions/styleFunctions.ts @@ -5,7 +5,7 @@ import { getFolder, getFolderNote } from 'src/functions/folderNoteFunctions'; import { getFileExplorer } from './utils'; import FolderOverviewPlugin from 'src/obsidian-folder-overview/src/main'; -export function loadFileClasses(forceReload = false, plugin: FolderNotesPlugin) { +export function updateAllFileStyles(forceReload = false, plugin: FolderNotesPlugin) { if (plugin.activeFileExplorer === getFileExplorer(plugin) && !forceReload) { return; } plugin.activeFileExplorer = getFileExplorer(plugin); plugin.app.vault.getAllLoadedFiles().forEach(async (file) => { diff --git a/src/main.ts b/src/main.ts index f01c02a..b2292a7 100644 --- a/src/main.ts +++ b/src/main.ts @@ -14,7 +14,7 @@ import { FolderOverview } from './obsidian-folder-overview/src/FolderOverview'; import { TabManager } from './events/TabManager'; import './functions/ListComponent'; import { handleDelete } from './events/handleDelete'; -import { addCSSClassToTitleEL, getEl, loadFileClasses } from './functions/styleFunctions'; +import { addCSSClassToTitleEL, getEl, updateAllFileStyles } from './functions/styleFunctions'; import { getExcludedFolder } from './ExcludeFolders/functions/folderFunctions'; import { FileExplorerView, InternalPlugin } from 'obsidian-typings'; import { getFocusedItem } from './functions/utils'; @@ -275,13 +275,13 @@ export default class FolderNotesPlugin extends Plugin { return true; } - async changeName(folder: TFolder, name: string | null | undefined, replacePath: boolean, waitForCreate = false, count = 0) { - if (!name) name = folder.name; + async changeFolderNameInExplorer(folder: TFolder, newName: string | null | undefined, waitForCreate = false, count = 0) { + if (!newName) newName = folder.name; let fileExplorerItem = getEl(folder.path, this); if (!fileExplorerItem) { if (waitForCreate && count < 5) { await new Promise((r) => setTimeout(r, 500)); - this.changeName(folder, name, replacePath, waitForCreate, count + 1); + this.changeFolderNameInExplorer(folder, newName, waitForCreate, count + 1); return; } return; @@ -290,18 +290,26 @@ export default class FolderNotesPlugin extends Plugin { fileExplorerItem = fileExplorerItem?.querySelector('div.nav-folder-title-content'); if (!fileExplorerItem) { return; } if (this.settings.frontMatterTitle.explorer && this.settings.frontMatterTitle.enabled) { - fileExplorerItem.innerText = name; + fileExplorerItem.innerText = newName; fileExplorerItem.setAttribute('old-name', folder.name); } else { fileExplorerItem.innerText = folder.name; fileExplorerItem.removeAttribute('old-name'); } - if (replacePath) { - this.updateBreadcrumbs(); - } } - updateBreadcrumbs(remove?: boolean) { + async changeFolderNameInPath(folder: TFolder, newName: string | null | undefined, breadcrumb: HTMLElement) { + if (!newName) newName = folder.name; + + breadcrumb.textContent = folder.newName || folder.name; + breadcrumb.setAttribute('old-name', folder.name); + breadcrumb.setAttribute('data-path', folder.path); + } + + /** + * Updates all folder names in the path above the note editor + */ + updateAllBreadcrumbs(remove?: boolean) { if (!this.settings.frontMatterTitle.path && !remove) { return; } const viewHeaderItems = document.querySelectorAll('span.view-header-breadcrumb'); const files = this.app.vault.getAllLoadedFiles().filter((file) => file instanceof TFolder); @@ -330,7 +338,6 @@ export default class FolderNotesPlugin extends Plugin { } onunload() { - console.log('unloading folder notes plugin'); unregisterFileExplorerObserver(); document.body.classList.remove('folder-notes-plugin'); document.body.classList.remove('folder-note-underline'); @@ -369,7 +376,7 @@ export default class FolderNotesPlugin extends Plugin { await this.saveData(this.settings); // cleanup any css if we need too if ((!this.settingsOpened || reloadStyles === true) && reloadStyles !== false) { - loadFileClasses(true, this); + updateAllFileStyles(true, this); } } diff --git a/src/settings/FileExplorerSettings.ts b/src/settings/FileExplorerSettings.ts index b32475a..3cf99ca 100644 --- a/src/settings/FileExplorerSettings.ts +++ b/src/settings/FileExplorerSettings.ts @@ -91,7 +91,7 @@ export async function renderFileExplorer(settingsTab: SettingsTab) { settingsTab.plugin.settings.frontMatterTitle.explorer = value; await settingsTab.plugin.saveSettings(); settingsTab.plugin.app.vault.getFiles().forEach((file) => { - settingsTab.plugin.fmtpHandler?.handleRename({ id: '', result: false, path: file.path }, false); + settingsTab.plugin.fmtpHandler?.fmptUpdateFileName({ id: '', result: false, path: file.path, pathOnly: false }, false); }); }) ); diff --git a/src/settings/GeneralSettings.ts b/src/settings/GeneralSettings.ts index 347b64b..5371df2 100644 --- a/src/settings/GeneralSettings.ts +++ b/src/settings/GeneralSettings.ts @@ -5,7 +5,7 @@ import AddSupportedFileModal from '../modals/AddSupportedFileType'; import { FrontMatterTitlePluginHandler } from '../events/FrontMatterTitle'; import ConfirmationModal from './modals/CreateFnForEveryFolder'; import { TemplateSuggest } from '../suggesters/TemplateSuggester'; -import { loadFileClasses } from '../functions/styleFunctions'; +import { updateAllFileStyles } from '../functions/styleFunctions'; import BackupWarningModal from './modals/BackupWarning'; import RenameFolderNotesModal from './modals/RenameFns'; @@ -186,7 +186,7 @@ export async function renderGeneral(settingsTab: SettingsTab) { settingsTab.plugin.settings.storageLocation = value; await settingsTab.plugin.saveSettings(); settingsTab.display(); - loadFileClasses(undefined, settingsTab.plugin); + updateAllFileStyles(undefined, settingsTab.plugin); }) ) .addButton((button) => @@ -442,10 +442,10 @@ export async function renderGeneral(settingsTab: SettingsTab) { settingsTab.plugin.fmtpHandler = new FrontMatterTitlePluginHandler(settingsTab.plugin); } else { if (settingsTab.plugin.fmtpHandler) { - settingsTab.plugin.updateBreadcrumbs(true); + settingsTab.plugin.updateAllBreadcrumbs(true); } settingsTab.plugin.app.vault.getFiles().forEach((file) => { - settingsTab.plugin.fmtpHandler?.handleRename({ id: '', result: false, path: file.path }, false); + settingsTab.plugin.fmtpHandler?.fmptUpdateFileName({ id: '', result: false, path: file.path, pathOnly: false }, false); }); settingsTab.plugin.fmtpHandler?.deleteEvent(); settingsTab.plugin.fmtpHandler = null; diff --git a/src/settings/PathSettings.ts b/src/settings/PathSettings.ts index 9916ff5..4915082 100644 --- a/src/settings/PathSettings.ts +++ b/src/settings/PathSettings.ts @@ -49,9 +49,9 @@ export async function renderPath(settingsTab: SettingsTab) { settingsTab.plugin.settings.frontMatterTitle.path = value; await settingsTab.plugin.saveSettings(); if (value) { - settingsTab.plugin.updateBreadcrumbs(); + settingsTab.plugin.updateAllBreadcrumbs(); } else { - settingsTab.plugin.updateBreadcrumbs(true); + settingsTab.plugin.updateAllBreadcrumbs(true); } }) );