diff --git a/src/handlers.ts b/src/handlers.ts index 27a9676..d91cf62 100644 --- a/src/handlers.ts +++ b/src/handlers.ts @@ -28,7 +28,7 @@ export function addCommands(plugin: FileExplorerPlusPlugin) { plugin.settings.pinFilters.active = !plugin.settings.pinFilters.active; plugin.saveSettings(); - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); }, }); @@ -39,7 +39,7 @@ export function addCommands(plugin: FileExplorerPlusPlugin) { plugin.settings.hideFilters.active = !plugin.settings.hideFilters.active; plugin.saveSettings(); - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); }, }); } @@ -47,19 +47,20 @@ export function addCommands(plugin: FileExplorerPlusPlugin) { export function addOnTagChange(plugin: FileExplorerPlusPlugin) { plugin.registerEvent( plugin.app.metadataCache.on("changed", (path, data, cache) => { - const isPinned = plugin.fileExplorer!.fileItems[path.path].info.pinned; - const isHidden = plugin.fileExplorer!.fileItems[path.path].info.hidden; + const isPinned = plugin.getFileExplorer()!.fileItems[path.path].info.pinned; + const isHidden = plugin.getFileExplorer()!.fileItems[path.path].info.hidden; const shouldBePinned = plugin.settings.pinFilters.tags.some((filter) => checkTagFilter(filter, path)); const shouldBeHidden = plugin.settings.hideFilters.tags.some((filter) => checkTagFilter(filter, path)); if (isPinned !== shouldBePinned && !shouldBeHidden) { - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); + return; } if (isHidden !== shouldBeHidden) { - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); } }), ); @@ -153,7 +154,7 @@ export function addCommandsToFileMenu(plugin: FileExplorerPlusPlugin) { plugin.saveSettings(); if (plugin.settings.pinFilters.active) { - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); } }); } else { @@ -163,34 +164,46 @@ export function addCommandsToFileMenu(plugin: FileExplorerPlusPlugin) { plugin.settings.pinFilters.paths.splice(index, 1); plugin.saveSettings(); - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); }); } }) .addItem((item) => { - item.setTitle("Hide File") - .setIcon("eye-off") - .onClick(() => { - const index = plugin.settings.hideFilters.paths.findIndex( - (filter) => filter.patternType === "STRICT" && filter.type === "FILES" && filter.pattern === path.path, - ); - if (index === -1) { - plugin.settings.hideFilters.paths.push({ - name: "", - active: true, - type: "FILES", - pattern: path.path, - patternType: "STRICT", - }); - } else { - plugin.settings.hideFilters.paths[index].active = true; - } - - plugin.saveSettings(); - if (plugin.settings.hideFilters.active) { - plugin.fileExplorer!.requestSort(); - } - }); + const index = plugin.settings.hideFilters.paths.findIndex( + (filter) => filter.patternType === "STRICT" && filter.type === "FILES" && filter.pattern === path.path, + ); + + if (index === -1 || !plugin.settings.hideFilters.paths[index].active) { + item.setTitle("Hide File") + .setIcon("eye-off") + .onClick(() => { + if (index === -1) { + plugin.settings.hideFilters.paths.push({ + name: "", + active: true, + type: "FILES", + pattern: path.path, + patternType: "STRICT", + }); + } else { + plugin.settings.hideFilters.paths[index].active = true; + } + + plugin.saveSettings(); + if (plugin.settings.hideFilters.active) { + plugin.getFileExplorer()?.requestSort(); + } + }); + } else { + item.setTitle("Unhide File") + .setIcon("eye") + .onClick(() => { + plugin.settings.hideFilters.paths.splice(index, 1); + + plugin.saveSettings(); + plugin.getFileExplorer()?.requestSort(); + }); + } }); } else { menu.addSeparator() @@ -217,7 +230,7 @@ export function addCommandsToFileMenu(plugin: FileExplorerPlusPlugin) { plugin.saveSettings(); if (plugin.settings.pinFilters.active) { - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); } }); } else { @@ -227,35 +240,46 @@ export function addCommandsToFileMenu(plugin: FileExplorerPlusPlugin) { plugin.settings.pinFilters.paths.splice(index, 1); plugin.saveSettings(); - plugin.fileExplorer!.requestSort(); + plugin.getFileExplorer()?.requestSort(); }); } }) .addItem((item) => { - item.setTitle("Hide Folder") - .setIcon("eye-off") - .onClick(() => { - const index = plugin.settings.hideFilters.paths.findIndex( - (filter) => - filter.patternType === "STRICT" && filter.type === "DIRECTORIES" && filter.pattern === path.path, - ); - if (index === -1) { - plugin.settings.hideFilters.paths.push({ - name: "", - active: true, - type: "DIRECTORIES", - pattern: path.path, - patternType: "STRICT", - }); - } else { - plugin.settings.hideFilters.paths[index].active = true; - } - - plugin.saveSettings(); - if (plugin.settings.hideFilters.active) { - plugin.fileExplorer!.requestSort(); - } - }); + const index = plugin.settings.hideFilters.paths.findIndex( + (filter) => filter.patternType === "STRICT" && filter.type === "DIRECTORIES" && filter.pattern === path.path, + ); + + if (index === -1 || !plugin.settings.hideFilters.paths[index].active) { + item.setTitle("Hide Folder") + .setIcon("eye-off") + .onClick(() => { + if (index === -1) { + plugin.settings.hideFilters.paths.push({ + name: "", + active: true, + type: "DIRECTORIES", + pattern: path.path, + patternType: "STRICT", + }); + } else { + plugin.settings.hideFilters.paths[index].active = true; + } + + plugin.saveSettings(); + if (plugin.settings.hideFilters.active) { + plugin.getFileExplorer()?.requestSort(); + } + }); + } else { + item.setTitle("Unhide Folder") + .setIcon("eye") + .onClick(() => { + plugin.settings.hideFilters.paths.splice(index, 1); + + plugin.saveSettings(); + plugin.getFileExplorer()?.requestSort(); + }); + } }); } }), diff --git a/src/main.ts b/src/main.ts index 4240b13..faa5b00 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,4 @@ -import { Plugin, TAbstractFile, TFolder, Vault, FileExplorerView, PathVirtualElement } from "obsidian"; +import { Plugin, TAbstractFile, FileExplorerView, WorkspaceLeaf, PathVirtualElement } from "obsidian"; import { around } from "monkey-around"; import FileExplorerPlusSettingTab, { FileExplorerPlusPluginSettings, UNSEEN_FILES_DEFAULT_SETTINGS } from "./settings"; @@ -7,7 +7,6 @@ import { checkPathFilter, checkTagFilter, changeVirtualElementPin } from "./util export default class FileExplorerPlusPlugin extends Plugin { settings: FileExplorerPlusPluginSettings; - fileExplorer?: FileExplorerView | null; async onload() { await this.loadSettings(); @@ -21,42 +20,46 @@ export default class FileExplorerPlusPlugin extends Plugin { this.addSettingTab(new FileExplorerPlusSettingTab(this.app, this)); this.app.workspace.onLayoutReady(() => { - this.patchFileExplorerFolder(); - this.fileExplorer!.requestSort(); + this.patchFileExplorer(); + this.getFileExplorer()?.requestSort(); + + console.log(this.app.workspace.getLeavesOfType("file-explorer")?.first()); }); + + this.app.workspace.on("layout-change", () => { + if (!this.getFileExplorer()?.fileExplorerPlusPatched) { + this.patchFileExplorer(); + this.getFileExplorer()?.requestSort(); + } + }); + } + + getFileExplorerContainer(): WorkspaceLeaf | undefined { + return this.app.workspace.getLeavesOfType("file-explorer")?.first(); } getFileExplorer(): FileExplorerView | undefined { - return this.app.workspace.getLeavesOfType("file-explorer")?.first()?.view as FileExplorerView; + const fileExplorerContainer = this.getFileExplorerContainer(); + return fileExplorerContainer?.view as FileExplorerView; } - patchFileExplorerFolder() { - this.fileExplorer = this.getFileExplorer(); + patchFileExplorer() { + const fileExplorer = this.getFileExplorer(); - if (!this.fileExplorer) { + if (!fileExplorer) { throw Error("Could not find file explorer"); } const plugin = this; const leaf = this.app.workspace.getLeaf(true); - //@ts-expect-error - const tmpFolder = new TFolder(Vault, ""); - const Folder = this.fileExplorer!.createFolderDom(tmpFolder).constructor; - this.register( - around(Folder.prototype, { - sort(old: any) { + around(Object.getPrototypeOf(fileExplorer), { + getSortedFolderItems(old: any) { return function (...args: any[]) { - old.call(this, ...args); + let sortedChildren: PathVirtualElement[] = old.call(this, ...args); - if (!this.hiddenVChildren) { - this.hiddenVChildren = []; - } - - // after old.call vChildren is repopulated, but hiddenVChildren is kept - let virtualElements: PathVirtualElement[] = this.vChildren.children; - let paths = virtualElements.map((el) => el.file); + let paths = sortedChildren.map((el) => el.file); if (plugin.settings.hideFilters.active) { const pathsToHide = plugin.getPathsToHide(paths); @@ -69,26 +72,19 @@ export default class FileExplorerPlusPlugin extends Plugin { {} as { [key: string]: boolean }, ); - const hiddenVChildren = []; - const visibleVChildren = []; - - for (const vEl of virtualElements) { + sortedChildren = sortedChildren.filter((vEl) => { if (pathsToHideLookUp[vEl.file.path]) { vEl.info.hidden = true; - hiddenVChildren.push(vEl); + return false; } else { vEl.info.hidden = false; - visibleVChildren.push(vEl); + return true; } - } - - this.hiddenVChildren = hiddenVChildren; - this.vChildren.setChildren(visibleVChildren); + }); } // only get visible vChildren - virtualElements = this.vChildren.children; - paths = virtualElements.map((el) => el.file); + paths = sortedChildren.map((el) => el.file); if (plugin.settings.pinFilters.active) { const pathsToPin = plugin.getPathsToPin(paths); @@ -101,40 +97,54 @@ export default class FileExplorerPlusPlugin extends Plugin { {} as { [key: string]: boolean }, ); - const pinnedVirtualElements = []; - const notPinnedVirtualElements = []; - - for (let vEl of virtualElements) { + const pinnedVirtualElements = sortedChildren.filter((vEl) => { if (pathsToPinLookUp[vEl.file.path]) { vEl = changeVirtualElementPin(vEl, true); vEl.info.pinned = true; - pinnedVirtualElements.push(vEl); + return true; } else { vEl = changeVirtualElementPin(vEl, false); vEl.info.pinned = false; - notPinnedVirtualElements.push(vEl); + return false; + } + }); + const notPinnedVirtualElements = sortedChildren.filter((vEl) => { + if (pathsToPinLookUp[vEl.file.path]) { + return false; + } else { + return true; } - } + }); - virtualElements = pinnedVirtualElements.concat(notPinnedVirtualElements); + sortedChildren = pinnedVirtualElements.concat(notPinnedVirtualElements); } else { - virtualElements = virtualElements.map((vEl) => changeVirtualElementPin(vEl, false)); + sortedChildren = sortedChildren.map((vEl) => changeVirtualElementPin(vEl, false)); } - this.vChildren.setChildren(virtualElements); + return sortedChildren; }; }, }), ); + leaf.detach(); + + fileExplorer.fileExplorerPlusPatched = true; } onunload() { - for (const path in this.fileExplorer!.fileItems) { - this.fileExplorer!.fileItems[path] = changeVirtualElementPin(this.fileExplorer!.fileItems[path], false); + const fileExplorer = this.getFileExplorer(); + + if (!fileExplorer) { + return; + } + + for (const path in fileExplorer!.fileItems) { + fileExplorer!.fileItems[path] = changeVirtualElementPin(fileExplorer!.fileItems[path], false); } - this.fileExplorer!.requestSort(); + fileExplorer.requestSort(); + fileExplorer.fileExplorerPlusPatched = false; } async loadSettings() { diff --git a/src/settings.ts b/src/settings.ts index 42d3987..4e2c0cf 100644 --- a/src/settings.ts +++ b/src/settings.ts @@ -131,7 +131,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); @@ -159,7 +159,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); @@ -214,7 +214,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.tags[index].pattern = newPattern; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -229,7 +229,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.tags[index].patternType = newPatternType as Filter["patternType"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addToggle((toggle) => { @@ -240,7 +240,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.tags[index].active = isActive; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addExtraButton((button) => { @@ -260,7 +260,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); this.display(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); }); @@ -309,7 +309,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.paths[index].pattern = newPattern; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -324,7 +324,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.paths[index].type = newType as PathFilter["type"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -339,7 +339,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.paths[index].patternType = newPatternType as Filter["patternType"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addToggle((toggle) => { @@ -350,7 +350,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.pinFilters.paths[index].active = isActive; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addExtraButton((button) => { @@ -370,7 +370,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); this.display(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); }); @@ -413,7 +413,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.tags[index].pattern = newPattern; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -428,7 +428,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.tags[index].patternType = newPatternType as Filter["patternType"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addToggle((toggle) => { @@ -439,7 +439,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.tags[index].active = isActive; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addExtraButton((button) => { @@ -459,7 +459,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); this.display(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); }); @@ -508,7 +508,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.paths[index].pattern = newPattern; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -523,7 +523,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.paths[index].type = newType as PathFilter["type"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addDropdown((dropdown) => { @@ -538,7 +538,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.paths[index].patternType = newPatternType as Filter["patternType"]; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addToggle((toggle) => { @@ -549,7 +549,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.settings.hideFilters.paths[index].active = isActive; this.plugin.saveSettings(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }) .addExtraButton((button) => { @@ -569,7 +569,7 @@ export default class FileExplorerPlusSettingTab extends PluginSettingTab { this.plugin.saveSettings(); this.display(); - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); }); }); }); diff --git a/src/types.d.ts b/src/types.d.ts index 974ef81..b198271 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -37,6 +37,7 @@ declare module "obsidian" { export interface FileExplorerView extends View { createFolderDom(folder: TFolder): FileExplorerFolder; requestSort(): void; + fileExplorerPlusPatched?: boolean; fileItems: { [key: string]: PathVirtualElement; diff --git a/src/ui/modals.ts b/src/ui/modals.ts index 21bf550..e0d41a1 100644 --- a/src/ui/modals.ts +++ b/src/ui/modals.ts @@ -68,7 +68,7 @@ export class InputFilterNameModal extends FuzzySuggestModal { }); } - this.plugin.fileExplorer!.requestSort(); + this.plugin.getFileExplorer()?.requestSort(); } }