diff --git a/package.json b/package.json index 4f771da..cdd8d82 100644 --- a/package.json +++ b/package.json @@ -20,5 +20,8 @@ "obsidian": "latest", "tslib": "2.4.0", "typescript": "4.7.4" + }, + "dependencies": { + "@popperjs/core": "^2.11.6" } } diff --git a/src/main.ts b/src/main.ts index 24cd1e3..d427623 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,6 +1,6 @@ import { Plugin, TFile, TFolder, TAbstractFile } from 'obsidian' import { DEFAULT_SETTINGS, FolderNotesSettings, SettingsTab } from './settings' -import FolderNameModal from './folderNameModal'; +import FolderNameModal from './modals/folderName'; export default class FolderNotesPlugin extends Plugin { observer: MutationObserver folders: TFolder[] = [] diff --git a/src/modals/exludeFolderSettings.ts b/src/modals/exludeFolderSettings.ts new file mode 100644 index 0000000..b68a8d2 --- /dev/null +++ b/src/modals/exludeFolderSettings.ts @@ -0,0 +1,34 @@ +import { App, Modal, Setting } from 'obsidian'; +import FolderNotesPlugin from '../main'; +import { ExcludedFolder } from '../settings'; +export default class ExcludedFolderSettings extends Modal { + plugin: FolderNotesPlugin; + app: App; + excludedFolder: ExcludedFolder; + constructor(app: App, plugin: FolderNotesPlugin, excludedFolder: ExcludedFolder) { + super(app); + this.plugin = plugin; + this.app = app; + this.excludedFolder = excludedFolder; + } + onOpen() { + const { contentEl } = this; + contentEl.createEl('h2', { text: 'Exluded folder settings' }); + new Setting(contentEl) + .setName('Include subfolders') + .setDesc('Choose if subfolders of the folder should also be excluded') + .addToggle((toggle) => + toggle + .setValue(this.excludedFolder.subFolders) + .onChange(async (value) => { + this.excludedFolder.subFolders = value; + await this.plugin.saveSettings(); + }) + ); + + } + onClose() { + const { contentEl } = this; + contentEl.empty(); + } +} \ No newline at end of file diff --git a/src/folderNameModal.ts b/src/modals/folderName.ts similarity index 96% rename from src/folderNameModal.ts rename to src/modals/folderName.ts index 2d0337a..0ce65d8 100644 --- a/src/folderNameModal.ts +++ b/src/modals/folderName.ts @@ -1,5 +1,5 @@ import { App, Modal, Setting, TFolder } from 'obsidian'; -import FolderNotesPlugin from './main'; +import FolderNotesPlugin from '../main'; export default class FolderNameModal extends Modal { plugin: FolderNotesPlugin; app: App; diff --git a/src/settings.ts b/src/settings.ts index dc5103e..e84336e 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -1,5 +1,7 @@ import { App, PluginSettingTab, Setting } from "obsidian"; import FolderNotesPlugin from "./main"; +import { FolderSuggest } from "./suggesters/FolderSuggester"; +import ExcludedFolderSettings from "./modals/exludeFolderSettings"; export interface FolderNotesSettings { syncFolderName: boolean; ctrlKey: boolean; @@ -7,16 +9,9 @@ export interface FolderNotesSettings { hideFolderNote: boolean; templatePath: string; autoCreate: boolean; - excludeFolders: string[]; -} -export interface ExcludeFolder { - path: string; - subFolders: boolean; - exludeSync: boolean; - excludeAutoCreate: boolean; - disableFolderNote: boolean; - position: number; + excludeFolders: ExcludedFolder[]; } + export const DEFAULT_SETTINGS: FolderNotesSettings = { syncFolderName: true, ctrlKey: true, @@ -29,6 +24,7 @@ export const DEFAULT_SETTINGS: FolderNotesSettings = { export class SettingsTab extends PluginSettingTab { plugin: FolderNotesPlugin; app: App; + excludeFolders: ExcludedFolder[]; constructor(app: App, plugin: FolderNotesPlugin) { super(app, plugin); } @@ -106,13 +102,108 @@ export class SettingsTab extends PluginSettingTab { cb.setClass('add-exclude-folder'); cb.setTooltip('Add excluded folder'); cb.onClick(() => { + const excludedFolder = new ExcludedFolder('', true, true, true, false, this.plugin.settings.excludeFolders.length); + this.addExcludeFolderListItem(containerEl, excludedFolder); + this.addExcludedFolder(excludedFolder); + this.display(); }) }) + this.plugin.settings.excludeFolders.sort((a, b) => a.position - b.position).forEach((excludedFolder) => { + this.addExcludeFolderListItem(containerEl, excludedFolder); + }) } - addExcludeFolderListItem(excludeFolder: ExcludeFolder) { - const { containerEl } = this; - new Setting(containerEl) + addExcludeFolderListItem(containerEl: HTMLElement, excludedFolder: ExcludedFolder) { + const setting = new Setting(containerEl) + setting.addSearch(cb => { + new FolderSuggest( + cb.inputEl, + this.plugin + ); + cb.setPlaceholder('Folder path'); + cb.setValue(excludedFolder.path); + cb.onChange((value) => { + if (!this.app.vault.getAbstractFileByPath(value)) return; + excludedFolder.path = value; + this.updateExcludedFolder(excludedFolder, excludedFolder); + }) + }) + setting.addButton(cb => { + cb.setIcon('edit'); + cb.setTooltip('Edit folder note'); + cb.onClick(() => { + new ExcludedFolderSettings(this.app, this.plugin, excludedFolder).open(); + }) + }) + + setting.addButton(cb => { + cb.setIcon('up-chevron-glyph'); + cb.setTooltip('Move up'); + cb.onClick(() => { + if (excludedFolder.position === 0) return; + excludedFolder.position = excludedFolder.position - 1; + console.log(excludedFolder.position); + this.updateExcludedFolder(excludedFolder, excludedFolder); + const oldExcludedFolder = this.plugin.settings.excludeFolders.find(folder => folder.position == excludedFolder.position) + if (oldExcludedFolder) { + + oldExcludedFolder.position = oldExcludedFolder.position + 1; + this.updateExcludedFolder(oldExcludedFolder, oldExcludedFolder); + } + this.display(); + }) + }) + setting.addButton(cb => { + cb.setIcon('down-chevron-glyph'); + cb.setTooltip('Move down'); + cb.onClick(() => { + if (excludedFolder.position === this.plugin.settings.excludeFolders.length - 1) return; + excludedFolder.position = excludedFolder.position + 1; + this.updateExcludedFolder(excludedFolder, excludedFolder); + const oldExcludedFolder = this.plugin.settings.excludeFolders.find(folder => folder.position == excludedFolder.position) + if (oldExcludedFolder) { + oldExcludedFolder.position = oldExcludedFolder.position - 1; + this.updateExcludedFolder(oldExcludedFolder, oldExcludedFolder); + } + this.display(); + }) + }) + setting.addButton(cb => { + cb.setIcon('trash-2'); + cb.setTooltip('Delete excluded folder'); + cb.onClick(() => { + this.deleteExcludedFolder(excludedFolder); + setting.clear(); + setting.settingEl.remove(); + }) + }) } - addExcludeFolder(excludeFolder: ExcludeFolder) { + addExcludedFolder(excludedFolder: ExcludedFolder) { + this.plugin.settings.excludeFolders.push(excludedFolder); + this.plugin.saveSettings(); + } + deleteExcludedFolder(excludedFolder: ExcludedFolder) { + this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path); + this.plugin.saveSettings(); + } + updateExcludedFolder(excludedFolder: ExcludedFolder, newExcludeFolder: ExcludedFolder) { + this.plugin.settings.excludeFolders = this.plugin.settings.excludeFolders.filter((folder) => folder.path !== excludedFolder.path); + this.addExcludedFolder(newExcludeFolder); + } + +} +export class ExcludedFolder { + path: string; + subFolders: boolean; + exludeSync: boolean; + excludeAutoCreate: boolean; + disableFolderNote: boolean; + position: number; + constructor(path: string, subFolders: boolean, exludeSync: boolean, excludeAutoCreate: boolean, disableFolderNote: boolean, position: number) { + this.path = path; + this.subFolders = subFolders; + this.exludeSync = exludeSync; + this.excludeAutoCreate = excludeAutoCreate; + this.disableFolderNote = disableFolderNote; + this.position = position; } } \ No newline at end of file diff --git a/src/suggesters/FileSuggester.ts b/src/suggesters/FolderSuggester.ts similarity index 56% rename from src/suggesters/FileSuggester.ts rename to src/suggesters/FolderSuggester.ts index c552642..7660b32 100644 --- a/src/suggesters/FileSuggester.ts +++ b/src/suggesters/FolderSuggester.ts @@ -1,6 +1,6 @@ // Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes and https://github.com/SilentVoid13/Templater -import { TAbstractFile, TFile } from "obsidian"; +import { TAbstractFile, TFolder } from "obsidian"; import { TextInputSuggest } from "./suggest"; import FolderNotesPlugin from "../main"; export enum FileSuggestMode { @@ -8,7 +8,7 @@ export enum FileSuggestMode { ScriptFiles, } -export class FileSuggest extends TextInputSuggest { +export class FolderSuggest extends TextInputSuggest { constructor( public inputEl: HTMLInputElement, private plugin: FolderNotesPlugin @@ -26,28 +26,28 @@ export class FileSuggest extends TextInputSuggest { } } - getSuggestions(input_str: string): TFile[] { - const files: TFile[] = []; + getSuggestions(input_str: string): TFolder[] { + const folders: TFolder[] = []; const lower_input_str = input_str.toLowerCase(); - - this.plugin.app.vault.getFiles().forEach((file: TAbstractFile) => { + this.plugin.app.vault.getAllLoadedFiles().forEach((folder: TAbstractFile) => { if ( - file instanceof TFile && - file.path.toLowerCase().contains(lower_input_str) + folder instanceof TFolder && + folder.path.toLowerCase().contains(lower_input_str) && + !this.plugin.settings.excludeFolders.find(f => f.path === folder.path) ) { - files.push(file); + folders.push(folder); } }); - return files; + return folders; } - renderSuggestion(file: TFile, el: HTMLElement): void { - el.setText(file.path); + renderSuggestion(folder: TFolder, el: HTMLElement): void { + el.setText(folder.path); } - selectSuggestion(file: TFile): void { - this.inputEl.value = file.path; + selectSuggestion(folder: TFolder): void { + this.inputEl.value = folder.path; this.inputEl.trigger("input"); this.close(); }