mirror of
https://github.com/decaf-dev/obsidian-vault-explorer.git
synced 2026-07-22 10:10:31 +00:00
feat: add basic handlers for file events
This commit is contained in:
parent
49f77c8e97
commit
f0fd2b0909
4 changed files with 138 additions and 1 deletions
50
src/event/event-manager.ts
Normal file
50
src/event/event-manager.ts
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
import { PluginEvent, EventCallback } from "./types";
|
||||
|
||||
export default class EventManager {
|
||||
private static instance: EventManager;
|
||||
private eventListeners: Record<PluginEvent, EventCallback[]>;
|
||||
|
||||
private constructor() {
|
||||
this.eventListeners = {} as Record<PluginEvent, EventCallback[]>;
|
||||
}
|
||||
|
||||
// Ensures only one instance is created
|
||||
public static getInstance(): EventManager {
|
||||
if (!EventManager.instance) {
|
||||
EventManager.instance = new EventManager();
|
||||
}
|
||||
return EventManager.instance;
|
||||
}
|
||||
|
||||
// Method to add an event listener
|
||||
public on(eventName: PluginEvent, callback: EventCallback): void {
|
||||
if (!this.eventListeners[eventName]) {
|
||||
this.eventListeners[eventName] = [];
|
||||
}
|
||||
this.eventListeners[eventName].push(callback);
|
||||
}
|
||||
|
||||
// Method to remove an event listener
|
||||
public off(
|
||||
eventName: PluginEvent,
|
||||
callbackToRemove: EventCallback
|
||||
): void {
|
||||
if (!this.eventListeners[eventName]) {
|
||||
return;
|
||||
}
|
||||
this.eventListeners[eventName] = this.eventListeners[eventName].filter(
|
||||
(callback) => callback !== callbackToRemove
|
||||
);
|
||||
}
|
||||
|
||||
// Method to trigger all callbacks associated with an event
|
||||
public emit(eventName: PluginEvent, ...data: unknown[]): void {
|
||||
//console.log("[EventManager] emiting event:", eventName);
|
||||
if (!this.eventListeners[eventName]) {
|
||||
return;
|
||||
}
|
||||
this.eventListeners[eventName].forEach((callback) => {
|
||||
callback(...data);
|
||||
});
|
||||
}
|
||||
}
|
||||
3
src/event/types.ts
Normal file
3
src/event/types.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
export type PluginEvent = "rename-file" | "create-file" | "delete-file" | "modify-file";
|
||||
|
||||
export type EventCallback = (...data: unknown[]) => void;
|
||||
34
src/main.ts
34
src/main.ts
|
|
@ -1,4 +1,4 @@
|
|||
import { Plugin, } from 'obsidian';
|
||||
import { Plugin, TFile, } from 'obsidian';
|
||||
|
||||
import VaultExplorerView from './obsidian/vault-explorer-view';
|
||||
import VaultExplorerSettingsTab from './obsidian/vault-explorer-settings-tab';
|
||||
|
|
@ -6,6 +6,7 @@ import VaultExplorerSettingsTab from './obsidian/vault-explorer-settings-tab';
|
|||
import { VaultExplorerPluginSettings } from './types';
|
||||
import { VAULT_EXPLORER_VIEW } from './constants';
|
||||
import _ from 'lodash';
|
||||
import EventManager from './event/event-manager';
|
||||
|
||||
|
||||
const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
|
||||
|
|
@ -53,10 +54,41 @@ export default class VaultExplorerPlugin extends Plugin {
|
|||
}
|
||||
});
|
||||
|
||||
this.registerEvents();
|
||||
|
||||
this.addSettingTab(new VaultExplorerSettingsTab(this.app, this));
|
||||
}
|
||||
|
||||
private registerEvents() {
|
||||
//Callback if the file is renamed or moved
|
||||
//This callback is already debounced by Obsidian
|
||||
this.registerEvent(this.app.vault.on("rename", (file: TFile, oldPath: string) => {
|
||||
if (file.extension !== "md") return;
|
||||
EventManager.getInstance().emit("rename-file", oldPath, file.path);
|
||||
}));
|
||||
|
||||
//Callback if a file is deleted
|
||||
//This callback is already debounced by Obsidian
|
||||
this.registerEvent(this.app.vault.on("delete", (file: TFile) => {
|
||||
if (file.extension !== "md") return;
|
||||
EventManager.getInstance().emit("delete-file", file.path);
|
||||
}));
|
||||
|
||||
//Callback if a file is created
|
||||
//This callback is already debounced by Obsidian
|
||||
this.registerEvent(this.app.vault.on("create", (file: TFile) => {
|
||||
if (file.extension !== "md") return;
|
||||
EventManager.getInstance().emit("create-file", file.path);
|
||||
}));
|
||||
|
||||
//Callback if a file is modified
|
||||
//This callback is already debounced by Obsidian
|
||||
this.registerEvent(this.app.vault.on("modify", (file: TFile) => {
|
||||
if (file.extension !== "md") return;
|
||||
EventManager.getInstance().emit("modify-file", file.path);
|
||||
}));
|
||||
}
|
||||
|
||||
onunload() {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import { useAppMount } from "./app-mount-provider";
|
|||
import Checkbox from "./checkbox";
|
||||
import Flex from "./flex";
|
||||
import Stack from "./stack";
|
||||
import EventManager from "src/event/event-manager";
|
||||
|
||||
export default function ReactView() {
|
||||
const [folderPath, setFolderPath] = React.useState<string>("");
|
||||
|
|
@ -27,6 +28,57 @@ export default function ReactView() {
|
|||
setOnlyCreatedToday(settings.filters.onlyCreatedToday);
|
||||
}, []);
|
||||
|
||||
const [, setRefreshTime] = React.useState(0);
|
||||
|
||||
//TODO optimize
|
||||
React.useEffect(() => {
|
||||
const handleRenameFile = (oldPath: string, newPath: string) => {
|
||||
setRefreshTime(Date.now());
|
||||
};
|
||||
|
||||
EventManager.getInstance().on("rename-file", handleRenameFile);
|
||||
return () => {
|
||||
EventManager.getInstance().off("rename-file", handleRenameFile);
|
||||
};
|
||||
}, []);
|
||||
|
||||
//TODO optimize
|
||||
React.useEffect(() => {
|
||||
const handleCreateFile = (oldPath: string, newPath: string) => {
|
||||
setRefreshTime(Date.now());
|
||||
};
|
||||
|
||||
EventManager.getInstance().on("create-file", handleCreateFile);
|
||||
return () => {
|
||||
EventManager.getInstance().off("create-file", handleCreateFile);
|
||||
};
|
||||
}, []);
|
||||
|
||||
//TODO optimize
|
||||
React.useEffect(() => {
|
||||
const handleDeleteFile = (oldPath: string, newPath: string) => {
|
||||
setRefreshTime(Date.now());
|
||||
};
|
||||
|
||||
EventManager.getInstance().on("delete-file", handleDeleteFile);
|
||||
return () => {
|
||||
EventManager.getInstance().off("delete-file", handleDeleteFile);
|
||||
};
|
||||
}, []);
|
||||
|
||||
//TODO optimize
|
||||
//TODO should we use handle frontmatter change?
|
||||
React.useEffect(() => {
|
||||
const handleModifyFile = (oldPath: string, newPath: string) => {
|
||||
setRefreshTime(Date.now());
|
||||
};
|
||||
|
||||
EventManager.getInstance().on("modify-file", handleModifyFile);
|
||||
return () => {
|
||||
EventManager.getInstance().off("modify-file", handleModifyFile);
|
||||
};
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
onSettingsChange({
|
||||
...settings,
|
||||
|
|
|
|||
Loading…
Reference in a new issue