diff --git a/src/main.ts b/src/main.ts index fb53894..3755bc0 100644 --- a/src/main.ts +++ b/src/main.ts @@ -24,9 +24,8 @@ export default class FolderNotesPlugin extends Plugin { if (!(folder instanceof TFolder)) return; const excludedFolder = this.settings.excludeFolders.find( - (excludedFolder) => (excludedFolder.path === - folder.path?.slice(0, folder?.path.lastIndexOf("/") >= 0 ? folder.path?.lastIndexOf("/") : folder.path.length)) || - (excludedFolder.path === folder?.path.slice(0, folder.path?.lastIndexOf("/")).slice(0, folder.path?.lastIndexOf("/")) + (excludedFolder) => (excludedFolder.path === folder.path) || + (excludedFolder.path === folder.path?.slice(0, folder?.path.lastIndexOf("/") >= 0 ? folder.path?.lastIndexOf("/") : folder.path.length) && excludedFolder.subFolders)); if (excludedFolder?.disableAutoCreate) return; @@ -34,7 +33,7 @@ export default class FolderNotesPlugin extends Plugin { if (!path) return; const file = this.app.vault.getAbstractFileByPath(path); if (file) return; - this.createFolderNote(path, true); + this.createFolderNote(path, true, true); })); @@ -42,6 +41,12 @@ export default class FolderNotesPlugin extends Plugin { if (!this.settings.syncFolderName) return; if (file instanceof TFolder) { const folder = this.app.vault.getAbstractFileByPath(file?.path); + if (!folder) return; + const excludedFolder = this.settings.excludeFolders.find( + (excludedFolder) => (excludedFolder.path === folder.path) || + (excludedFolder.path === folder.path?.slice(0, folder?.path.lastIndexOf("/") >= 0 ? folder.path?.lastIndexOf("/") : folder.path.length) + && excludedFolder.subFolders)); + if (excludedFolder?.disableSync) return; const oldName = oldPath.substring(oldPath.lastIndexOf('/' || '\\')); const newPath = folder?.path + '/' + folder?.name + '.md'; if (folder instanceof TFolder) { @@ -54,7 +59,11 @@ export default class FolderNotesPlugin extends Plugin { } } else if (file instanceof TFile) { const folder = this.app.vault.getAbstractFileByPath(oldPath.substring(0, oldPath.lastIndexOf('/' || '\\'))); - const excludedFolder = this.settings.excludeFolders.find((excludedFolder) => excludedFolder.path === folder?.path); + if (!folder) return; + const excludedFolder = this.settings.excludeFolders.find( + (excludedFolder) => (excludedFolder.path === folder.path) || + (excludedFolder.path === folder.path?.slice(0, folder?.path.lastIndexOf("/") >= 0 ? folder.path?.lastIndexOf("/") : folder.path.length) + && excludedFolder.subFolders)); if (excludedFolder?.disableSync) return; if (file.name !== folder?.name + '.md') return; if (folder instanceof TFolder) { @@ -68,6 +77,7 @@ export default class FolderNotesPlugin extends Plugin { if (rec.type === 'childList') { (rec.target).querySelectorAll('div.nav-folder-title-content') .forEach((element: HTMLElement) => { + if (element.onclick) return; element.onclick = (event: MouseEvent) => this.handleFolderClick(event); }); } @@ -88,22 +98,24 @@ export default class FolderNotesPlugin extends Plugin { return; } - const folder = event.target.parentElement?.getAttribute('data-path'); const excludedFolder = this.settings.excludeFolders.find( - (excludedFolder) => (excludedFolder.path === folder?.slice(0, folder?.lastIndexOf("/") >= 0 ? folder?.lastIndexOf("/") : folder.length)) || - (excludedFolder.path === folder?.slice(0, folder?.lastIndexOf("/")).slice(0, folder?.lastIndexOf("/")) + (excludedFolder) => (excludedFolder.path === folder) || + (excludedFolder.path === folder?.slice(0, folder?.lastIndexOf("/") >= 0 ? folder?.lastIndexOf("/") : folder.length) && excludedFolder.subFolders)); - if (excludedFolder?.enableCollappsing && excludedFolder?.disableFolderNote) { + if (excludedFolder?.disableFolderNote) { event.target.onclick = null; event.target.click(); + event.target.parentElement?.parentElement?.getElementsByClassName('nav-folder-children').item(0)?.querySelectorAll('div.nav-file') + .forEach((element: HTMLElement) => { + if (element.innerText === (event.target as HTMLElement)?.innerText && element.classList.contains('is-folder-note')) { + element.classList.remove('is-folder-note'); + } + }); return; - } else if (excludedFolder?.enableCollappsing) { + } else if (excludedFolder?.enableCollapsing || this.settings.enableCollapsing) { event.target.onclick = null; event.target.click(); - event.target.onclick = (event: MouseEvent) => this.handFolderClickWithCollapse(event); - event.target.click(); - return; } const path = folder + '/' + event.target.innerText + '.md'; @@ -113,13 +125,14 @@ export default class FolderNotesPlugin extends Plugin { event.target.parentElement?.parentElement?.getElementsByClassName('nav-folder-children').item(0)?.querySelectorAll('div.nav-file') .forEach((element: HTMLElement) => { if (element.innerText === (event.target as HTMLElement)?.innerText && !element.classList.contains('is-folder-note')) { + console.log(element) element.classList.add('is-folder-note'); } }); } else if (event.altKey || event.ctrlKey) { if ((this.settings.altKey && event.altKey) || (this.settings.ctrlKey && event.ctrlKey)) { - this.createFolderNote(path); + this.createFolderNote(path, true, true); if (!this.settings.hideFolderNote) return; event.target.parentElement?.parentElement?.getElementsByClassName('nav-folder-children').item(0)?.querySelectorAll('div.nav-file') .forEach((element: HTMLElement) => { @@ -137,58 +150,12 @@ export default class FolderNotesPlugin extends Plugin { } } - handFolderClickWithCollapse(event: MouseEvent) { - console.log(event) - if (!(event.target instanceof HTMLElement)) return; - if (!document.body.classList.contains('folder-notes-plugin')) { - event.target.onclick = null; - event.target.click(); - return; - } - console.log('handFolderClickWithCollapse') - - const folder = event.target.parentElement?.getAttribute('data-path'); - const path = folder + '/' + event.target.innerText + '.md'; - console.log(path) - - - if (this.app.vault.getAbstractFileByPath(path)) { - console.log('openFolderNote') - this.openFolderNote(path); - if (!this.settings.hideFolderNote) return; - event.target.parentElement?.parentElement?.getElementsByClassName('nav-folder-children').item(0)?.querySelectorAll('div.nav-file') - .forEach((element: HTMLElement) => { - if (element.innerText === (event.target as HTMLElement)?.innerText && !element.classList.contains('is-folder-note')) { - element.classList.add('is-folder-note'); - } - }); - - } else if (event.altKey || event.ctrlKey) { - console.log(event.altKey, event.ctrlKey); - if ((this.settings.altKey && event.altKey) || (this.settings.ctrlKey && event.ctrlKey)) { - this.createFolderNote(path); - if (!this.settings.hideFolderNote) return; - event.target.parentElement?.parentElement?.getElementsByClassName('nav-folder-children').item(0)?.querySelectorAll('div.nav-file') - .forEach((element: HTMLElement) => { - if (element.innerText === (event.target as HTMLElement)?.innerText && !element.classList.contains('is-folder-note')) { - element.classList.add('is-folder-note'); - } - }); - } else { - event.target.onclick = null; - event.target.click(); - } - } else { - console.log('click') - event.target.onclick = null; - event.target.click(); - } - } - - async createFolderNote(path: string, useModal?: boolean) { + async createFolderNote(path: string, openFile: boolean, useModal?: boolean) { const leaf = this.app.workspace.getLeaf(false); const file = await this.app.vault.create(path, ''); - await leaf.openFile(file); + if (openFile) { + await leaf.openFile(file); + } applyTemplate(this, this.settings.templatePath); if (!this.settings.autoCreate) return; if (!useModal) return; diff --git a/src/modals/confirmCreation.ts b/src/modals/confirmCreation.ts new file mode 100644 index 0000000..9bc97d0 --- /dev/null +++ b/src/modals/confirmCreation.ts @@ -0,0 +1,42 @@ +import { App, Modal, Setting, TFolder } from 'obsidian'; +import FolderNotesPlugin from '../main'; +export default class ConfirmationModal extends Modal { + plugin: FolderNotesPlugin; + app: App; + folder: TFolder; + constructor(app: App, plugin: FolderNotesPlugin) { + super(app); + this.plugin = plugin; + this.app = app; + } + onOpen() { + const { contentEl } = this; + contentEl.createEl('h2', { text: 'Create folder note for every folder' }); + const setting = new Setting(contentEl) + setting.infoEl.createEl('p', { text: 'Make sure to backup your vault before using this feature.' }).style.color = '#fb464c'; + setting.infoEl.createEl('p', { text: 'This feature will create a folder note for every folder in your vault.' }); + setting.infoEl.createEl('p', { text: 'Every folder that already has a folder note will be ignored' }); + setting.infoEl.parentElement?.classList.add('fn-confirmation-modal') + const button = setting.infoEl.createEl('button', { text: 'Create' }); + button.classList.add('mod-warning', 'fn-confirmation-modal-button'); + button.addEventListener('click', async () => { + this.close(); + this.app.vault.getAllLoadedFiles().forEach(async (file) => { + if (file instanceof TFolder) { + if (this.app.vault.getAbstractFileByPath(file.path + '/' + file.name + '.md')) return; + await this.plugin.createFolderNote(file.path + '/' + file.name + '.md', false); + } + }) + }); + // focus on the button + button.focus(); + const cancelButton = setting.infoEl.createEl('button', { text: 'Cancel' }); + cancelButton.addEventListener('click', async () => { + this.close(); + }); + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} \ No newline at end of file diff --git a/src/modals/exludeFolderSettings.ts b/src/modals/exludeFolderSettings.ts index 39b3287..47df07c 100644 --- a/src/modals/exludeFolderSettings.ts +++ b/src/modals/exludeFolderSettings.ts @@ -74,9 +74,9 @@ export default class ExcludedFolderSettings extends Modal { .setDesc('Choose if the folder should be collapsed when the folder note is opened') .addToggle((toggle) => toggle - .setValue(this.excludedFolder.enableCollappsing) + .setValue(this.excludedFolder.enableCollapsing) .onChange(async (value) => { - this.excludedFolder.enableCollappsing = value; + this.excludedFolder.enableCollapsing = value; await this.plugin.saveSettings(); }) ); diff --git a/src/settings.ts b/src/settings.ts index 396e429..08f2566 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -3,6 +3,7 @@ import FolderNotesPlugin from "./main"; import { FolderSuggest } from "./suggesters/folderSuggester"; import ExcludedFolderSettings from "./modals/exludeFolderSettings"; import { TemplateSuggest } from "./suggesters/templateSuggester"; +import ConfirmationModal from "./modals/confirmCreation"; export interface FolderNotesSettings { syncFolderName: boolean; ctrlKey: boolean; @@ -10,6 +11,7 @@ export interface FolderNotesSettings { hideFolderNote: boolean; templatePath: string; autoCreate: boolean; + enableCollapsing: boolean; excludeFolders: ExcludedFolder[]; } @@ -20,6 +22,7 @@ export const DEFAULT_SETTINGS: FolderNotesSettings = { hideFolderNote: true, templatePath: '', autoCreate: false, + enableCollapsing: false, excludeFolders: [], }; export class SettingsTab extends PluginSettingTab { @@ -36,6 +39,18 @@ export class SettingsTab extends PluginSettingTab { containerEl.createEl('h2', { text: 'Folder notes settings' }); + new Setting(containerEl) + .setName('Disable folder collapsing') + .setDesc('Disable the ability to collapse folders by clicking on the folder name') + .addToggle((toggle) => + toggle + .setValue(!this.plugin.settings.enableCollapsing) + .onChange(async (value) => { + this.plugin.settings.enableCollapsing = !value; + await this.plugin.saveSettings(); + }) + ); + new Setting(containerEl) .setName('Hide folder note') .setDesc('Hide the folder note in the file explorer') @@ -110,6 +125,20 @@ export class SettingsTab extends PluginSettingTab { }); }); + new Setting(containerEl) + .setName('Create folder note for every folder') + .setDesc('Create a folder note for every folder in the vault') + .addButton((cb) => { + cb.setIcon('plus'); + + cb.setTooltip('Create folder notes'); + cb.onClick(async () => { + new ConfirmationModal(this.app, this.plugin).open(); + }); + }); + + + new Setting(containerEl) .setHeading() .setName('Manage excluded folders') @@ -218,7 +247,7 @@ export class ExcludedFolder { disableSync: boolean; disableAutoCreate: boolean; disableFolderNote: boolean; - enableCollappsing: boolean; + enableCollapsing: boolean; position: number; constructor(path: string, position: number) { this.path = path; @@ -226,7 +255,7 @@ export class ExcludedFolder { this.disableSync = true; this.disableAutoCreate = true; this.disableFolderNote = false; - this.enableCollappsing = false; + this.enableCollapsing = false; this.position = position; } } \ No newline at end of file diff --git a/styles.css b/styles.css index 5f703b7..2e82e6b 100644 --- a/styles.css +++ b/styles.css @@ -12,6 +12,7 @@ display: none; } + .nav-folder-collapse-indicator:hover { cursor: pointer; } @@ -37,4 +38,12 @@ .fn-exclude-folder-list-item > *.last-child { margin-right: 0; +} + +.fn-confirmation-modal { + padding-bottom: 0; +} + +.fn-confirmation-modal-button { + margin-right: 0.7rem; } \ No newline at end of file