From e1659137bd072c4ac8264e6922a63a1dc8403bc8 Mon Sep 17 00:00:00 2001 From: Alejandro Daniel Noel Date: Tue, 11 Jun 2024 20:51:40 +0200 Subject: [PATCH] Implement feedback from PR - making use of built-ins --- src/indexer.ts | 6 +- .../{suggesters => }/FolderSuggester.ts | 18 +- src/settings/Settings.ts | 14 +- src/settings/suggesters/suggest.ts | 202 ------------------ 4 files changed, 20 insertions(+), 220 deletions(-) rename src/settings/{suggesters => }/FolderSuggester.ts (60%) delete mode 100644 src/settings/suggesters/suggest.ts diff --git a/src/indexer.ts b/src/indexer.ts index f3aeb2f..5fa0cef 100644 --- a/src/indexer.ts +++ b/src/indexer.ts @@ -175,7 +175,7 @@ class Node { const child = this.children.find(child => child.tagComponent() === nextComponent); return child ? child.findChildNode(tagPath) : undefined; } - console.log("ERROR: did not find node at path \"" + tagPath + "\""); + console.error("Did not find node at path \"" + tagPath + "\""); return undefined; } @@ -204,7 +204,7 @@ class Node { const newNode = new Node(nextTagPath, this.settings, this.app); const success = newNode.addNoteWithPath(tagPath, note, hasPriority, isIndex); if (!success) { - console.log("ERROR: could not add path for note: ", tagPath + "|" + nextTagPath, this); + console.error("Could not add path for note: ", tagPath + "|" + nextTagPath, this); } this.children.push(newNode); return success; @@ -343,7 +343,7 @@ export class IndexUpdater { fileTags = fileTags.split(',').map(tag => tag.trim()); } if (!fileTags || !Array.isArray(fileTags)) { - console.log("File tags are not an array: ", fileTags); + console.error("File tags are not an array: ", fileTags); return; } const hasPriorityTag = fileTags.includes(this.settings.priority_tag); diff --git a/src/settings/suggesters/FolderSuggester.ts b/src/settings/FolderSuggester.ts similarity index 60% rename from src/settings/suggesters/FolderSuggester.ts rename to src/settings/FolderSuggester.ts index 83d9d38..c5cb540 100644 --- a/src/settings/suggesters/FolderSuggester.ts +++ b/src/settings/FolderSuggester.ts @@ -1,11 +1,12 @@ -// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes +// @ts-ignore +import { App, TAbstractFile, TFolder, TFile, AbstractInputSuggest } from "obsidian"; -import { TAbstractFile, TFolder } from "obsidian"; -import { TextInputSuggest } from "./suggest"; +export class FolderSuggest extends AbstractInputSuggest { + textInputEl: HTMLInputElement; -export class FolderSuggest extends TextInputSuggest { getSuggestions(inputStr: string): TFolder[] { - const abstractFiles = app.vault.getAllLoadedFiles(); + // @ts-ignore + const abstractFiles = this.app.vault.getAllLoadedFiles(); const folders: TFolder[] = []; const lowerCaseInputStr = inputStr.toLowerCase(); @@ -26,8 +27,9 @@ export class FolderSuggest extends TextInputSuggest { } selectSuggestion(file: TFolder): void { - this.inputEl.value = file.path; - this.inputEl.trigger("input"); + this.textInputEl.value = file.path; + this.textInputEl.trigger("input"); + // @ts-ignore this.close(); } -} \ No newline at end of file +} diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 96955c4..51d3bf1 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -1,7 +1,6 @@ -import { App, Notice, PluginSettingTab, Setting, TFile } from 'obsidian'; +import { App, Notice, PluginSettingTab, Setting, parseYaml } from 'obsidian'; import IndexNotesPlugin from "main"; -import { FolderSuggest } from "./suggesters/FolderSuggester"; -import YAML from 'yaml' +import { FolderSuggest } from "./FolderSuggester"; export interface IndexNotesSettings { update_interval_seconds: number; @@ -33,7 +32,6 @@ export class IndexNotesSettingTab extends PluginSettingTab { display(): void { this.containerEl.empty(); - this.containerEl.createEl('h2', { text: 'Settings for Index Notes plugin' }); this.add_index_tag_setting(); this.add_meta_index_tag_setting(); this.add_priority_tag_setting(); @@ -127,18 +125,20 @@ export class IndexNotesSettingTab extends PluginSettingTab { } add_exclude_folders_setting() { - this.containerEl.createEl("h2", { text: "Excluded folders from indexing" }); + new Setting(this.containerEl).setName("Add excluded folder").setHeading(); this.plugin.settings.exclude_folders.forEach((template, index) => { const s = new Setting(this.containerEl) .addSearch((cb) => { - new FolderSuggest(cb.inputEl); + // @ts-ignore + new FolderSuggest(this.plugin.app, cb.inputEl); cb.setPlaceholder("Example: folder1/template_file") .setValue(template) .onChange((new_template) => { try { if (new_template && this.plugin.settings.exclude_folders.includes(new_template)) { new Notice("Folder is already excluded"); + cb.setValue(""); } else { this.plugin.settings.exclude_folders[index] = new_template; this.plugin.saveSettings(); @@ -191,7 +191,7 @@ export class IndexNotesSettingTab extends PluginSettingTab { cb.setValue(this.plugin.settings.metadata_template) .onChange(async (value) => { try { - YAML.parse(value.replace(/{{/g, '"{{').replace(/}}/g, '}}"')); + parseYaml(value.replace(/{{/g, '"{{').replace(/}}/g, '}}"')); cb.inputEl.removeClass("index-notes-metadata-template-error"); this.plugin.settings.metadata_template = value; await this.plugin.saveSettings(); diff --git a/src/settings/suggesters/suggest.ts b/src/settings/suggesters/suggest.ts deleted file mode 100644 index 430505b..0000000 --- a/src/settings/suggesters/suggest.ts +++ /dev/null @@ -1,202 +0,0 @@ -// Adapted from Templater plugin https://github.com/SilentVoid13/Templater -// Credits go to Liam's Periodic Notes Plugin: https://github.com/liamcain/obsidian-periodic-notes - -import { ISuggestOwner, Scope } from "obsidian"; -import { createPopper, Instance as PopperInstance } from "@popperjs/core"; - -const wrapAround = (value: number, size: number): number => { - return ((value % size) + size) % size; -}; - -class Suggest { - private owner: ISuggestOwner; - private values: T[]; - private suggestions: HTMLDivElement[]; - private selectedItem: number; - private containerEl: HTMLElement; - - constructor( - owner: ISuggestOwner, - containerEl: HTMLElement, - scope: Scope - ) { - this.owner = owner; - this.containerEl = containerEl; - - containerEl.on( - "click", - ".suggestion-item", - this.onSuggestionClick.bind(this) - ); - containerEl.on( - "mousemove", - ".suggestion-item", - this.onSuggestionMouseover.bind(this) - ); - - scope.register([], "ArrowUp", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem - 1, true); - return false; - } - }); - - scope.register([], "ArrowDown", (event) => { - if (!event.isComposing) { - this.setSelectedItem(this.selectedItem + 1, true); - return false; - } - }); - - scope.register([], "Enter", (event) => { - if (!event.isComposing) { - this.useSelectedItem(event); - return false; - } - }); - } - - onSuggestionClick(event: MouseEvent, el: HTMLDivElement): void { - event.preventDefault(); - - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - this.useSelectedItem(event); - } - - onSuggestionMouseover(_event: MouseEvent, el: HTMLDivElement): void { - const item = this.suggestions.indexOf(el); - this.setSelectedItem(item, false); - } - - setSuggestions(values: T[]) { - this.containerEl.empty(); - const suggestionEls: HTMLDivElement[] = []; - - values.forEach((value) => { - const suggestionEl = this.containerEl.createDiv("suggestion-item"); - this.owner.renderSuggestion(value, suggestionEl); - suggestionEls.push(suggestionEl); - }); - - this.values = values; - this.suggestions = suggestionEls; - this.setSelectedItem(0, false); - } - - useSelectedItem(event: MouseEvent | KeyboardEvent) { - const currentValue = this.values[this.selectedItem]; - if (currentValue) { - this.owner.selectSuggestion(currentValue, event); - } - } - - setSelectedItem(selectedIndex: number, scrollIntoView: boolean) { - const normalizedIndex = wrapAround( - selectedIndex, - this.suggestions.length - ); - const prevSelectedSuggestion = this.suggestions[this.selectedItem]; - const selectedSuggestion = this.suggestions[normalizedIndex]; - - prevSelectedSuggestion?.removeClass("is-selected"); - selectedSuggestion?.addClass("is-selected"); - - this.selectedItem = normalizedIndex; - - if (scrollIntoView) { - selectedSuggestion.scrollIntoView(false); - } - } -} - -export abstract class TextInputSuggest implements ISuggestOwner { - protected inputEl: HTMLInputElement | HTMLTextAreaElement; - - private popper: PopperInstance; - private scope: Scope; - private suggestEl: HTMLElement; - private suggest: Suggest; - - constructor(inputEl: HTMLInputElement | HTMLTextAreaElement) { - this.inputEl = inputEl; - this.scope = new Scope(); - - this.suggestEl = createDiv("suggestion-container"); - const suggestion = this.suggestEl.createDiv("suggestion"); - this.suggest = new Suggest(this, suggestion, this.scope); - - this.scope.register([], "Escape", this.close.bind(this)); - - this.inputEl.addEventListener("input", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("focus", this.onInputChanged.bind(this)); - this.inputEl.addEventListener("blur", this.close.bind(this)); - this.suggestEl.on( - "mousedown", - ".suggestion-container", - (event: MouseEvent) => { - event.preventDefault(); - } - ); - } - - onInputChanged(): void { - const inputStr = this.inputEl.value; - const suggestions = this.getSuggestions(inputStr); - - if (!suggestions) { - this.close(); - return; - } - - if (suggestions.length > 0) { - this.suggest.setSuggestions(suggestions); - this.open(app.dom.appContainerEl, this.inputEl); - app - } else { - this.close(); - } - } - - open(container: HTMLElement, inputEl: HTMLElement): void { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - app.keymap.pushScope(this.scope); - - container.appendChild(this.suggestEl); - this.popper = createPopper(inputEl, this.suggestEl, { - placement: "bottom-start", - modifiers: [ - { - name: "sameWidth", - enabled: true, - fn: ({ state, instance }) => { - // Note: positioning needs to be calculated twice - - // first pass - positioning it according to the width of the popper - // second pass - position it with the width bound to the reference element - // we need to early exit to avoid an infinite loop - const targetWidth = `${state.rects.reference.width}px`; - if (state.styles.popper.width === targetWidth) { - return; - } - state.styles.popper.width = targetWidth; - instance.update(); - }, - phase: "beforeWrite", - requires: ["computeStyles"], - }, - ], - }); - } - - close(): void { - app.keymap.popScope(this.scope); - - this.suggest.setSuggestions([]); - if (this.popper) this.popper.destroy(); - this.suggestEl.detach(); - } - - abstract getSuggestions(inputStr: string): T[]; - abstract renderSuggestion(item: T, el: HTMLElement): void; - abstract selectSuggestion(item: T): void; -} \ No newline at end of file