Skip to content

Commit 052e4ed

Browse files
authored
Merge pull request #1 from trey-wallis/add-basic-event-handlers
feat: add basic handlers for file events
2 parents 49f77c8 + f0fd2b0 commit 052e4ed

File tree

4 files changed

+138
-1
lines changed

4 files changed

+138
-1
lines changed

src/event/event-manager.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { PluginEvent, EventCallback } from "./types";
2+
3+
export default class EventManager {
4+
private static instance: EventManager;
5+
private eventListeners: Record<PluginEvent, EventCallback[]>;
6+
7+
private constructor() {
8+
this.eventListeners = {} as Record<PluginEvent, EventCallback[]>;
9+
}
10+
11+
// Ensures only one instance is created
12+
public static getInstance(): EventManager {
13+
if (!EventManager.instance) {
14+
EventManager.instance = new EventManager();
15+
}
16+
return EventManager.instance;
17+
}
18+
19+
// Method to add an event listener
20+
public on(eventName: PluginEvent, callback: EventCallback): void {
21+
if (!this.eventListeners[eventName]) {
22+
this.eventListeners[eventName] = [];
23+
}
24+
this.eventListeners[eventName].push(callback);
25+
}
26+
27+
// Method to remove an event listener
28+
public off(
29+
eventName: PluginEvent,
30+
callbackToRemove: EventCallback
31+
): void {
32+
if (!this.eventListeners[eventName]) {
33+
return;
34+
}
35+
this.eventListeners[eventName] = this.eventListeners[eventName].filter(
36+
(callback) => callback !== callbackToRemove
37+
);
38+
}
39+
40+
// Method to trigger all callbacks associated with an event
41+
public emit(eventName: PluginEvent, ...data: unknown[]): void {
42+
//console.log("[EventManager] emiting event:", eventName);
43+
if (!this.eventListeners[eventName]) {
44+
return;
45+
}
46+
this.eventListeners[eventName].forEach((callback) => {
47+
callback(...data);
48+
});
49+
}
50+
}

src/event/types.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export type PluginEvent = "rename-file" | "create-file" | "delete-file" | "modify-file";
2+
3+
export type EventCallback = (...data: unknown[]) => void;

src/main.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import { Plugin, } from 'obsidian';
1+
import { Plugin, TFile, } from 'obsidian';
22

33
import VaultExplorerView from './obsidian/vault-explorer-view';
44
import VaultExplorerSettingsTab from './obsidian/vault-explorer-settings-tab';
55

66
import { VaultExplorerPluginSettings } from './types';
77
import { VAULT_EXPLORER_VIEW } from './constants';
88
import _ from 'lodash';
9+
import EventManager from './event/event-manager';
910

1011

1112
const DEFAULT_SETTINGS: VaultExplorerPluginSettings = {
@@ -53,10 +54,41 @@ export default class VaultExplorerPlugin extends Plugin {
5354
}
5455
});
5556

57+
this.registerEvents();
5658

5759
this.addSettingTab(new VaultExplorerSettingsTab(this.app, this));
5860
}
5961

62+
private registerEvents() {
63+
//Callback if the file is renamed or moved
64+
//This callback is already debounced by Obsidian
65+
this.registerEvent(this.app.vault.on("rename", (file: TFile, oldPath: string) => {
66+
if (file.extension !== "md") return;
67+
EventManager.getInstance().emit("rename-file", oldPath, file.path);
68+
}));
69+
70+
//Callback if a file is deleted
71+
//This callback is already debounced by Obsidian
72+
this.registerEvent(this.app.vault.on("delete", (file: TFile) => {
73+
if (file.extension !== "md") return;
74+
EventManager.getInstance().emit("delete-file", file.path);
75+
}));
76+
77+
//Callback if a file is created
78+
//This callback is already debounced by Obsidian
79+
this.registerEvent(this.app.vault.on("create", (file: TFile) => {
80+
if (file.extension !== "md") return;
81+
EventManager.getInstance().emit("create-file", file.path);
82+
}));
83+
84+
//Callback if a file is modified
85+
//This callback is already debounced by Obsidian
86+
this.registerEvent(this.app.vault.on("modify", (file: TFile) => {
87+
if (file.extension !== "md") return;
88+
EventManager.getInstance().emit("modify-file", file.path);
89+
}));
90+
}
91+
6092
onunload() {
6193

6294
}

src/react/index.tsx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { useAppMount } from "./app-mount-provider";
88
import Checkbox from "./checkbox";
99
import Flex from "./flex";
1010
import Stack from "./stack";
11+
import EventManager from "src/event/event-manager";
1112

1213
export default function ReactView() {
1314
const [folderPath, setFolderPath] = React.useState<string>("");
@@ -27,6 +28,57 @@ export default function ReactView() {
2728
setOnlyCreatedToday(settings.filters.onlyCreatedToday);
2829
}, []);
2930

31+
const [, setRefreshTime] = React.useState(0);
32+
33+
//TODO optimize
34+
React.useEffect(() => {
35+
const handleRenameFile = (oldPath: string, newPath: string) => {
36+
setRefreshTime(Date.now());
37+
};
38+
39+
EventManager.getInstance().on("rename-file", handleRenameFile);
40+
return () => {
41+
EventManager.getInstance().off("rename-file", handleRenameFile);
42+
};
43+
}, []);
44+
45+
//TODO optimize
46+
React.useEffect(() => {
47+
const handleCreateFile = (oldPath: string, newPath: string) => {
48+
setRefreshTime(Date.now());
49+
};
50+
51+
EventManager.getInstance().on("create-file", handleCreateFile);
52+
return () => {
53+
EventManager.getInstance().off("create-file", handleCreateFile);
54+
};
55+
}, []);
56+
57+
//TODO optimize
58+
React.useEffect(() => {
59+
const handleDeleteFile = (oldPath: string, newPath: string) => {
60+
setRefreshTime(Date.now());
61+
};
62+
63+
EventManager.getInstance().on("delete-file", handleDeleteFile);
64+
return () => {
65+
EventManager.getInstance().off("delete-file", handleDeleteFile);
66+
};
67+
}, []);
68+
69+
//TODO optimize
70+
//TODO should we use handle frontmatter change?
71+
React.useEffect(() => {
72+
const handleModifyFile = (oldPath: string, newPath: string) => {
73+
setRefreshTime(Date.now());
74+
};
75+
76+
EventManager.getInstance().on("modify-file", handleModifyFile);
77+
return () => {
78+
EventManager.getInstance().off("modify-file", handleModifyFile);
79+
};
80+
}, []);
81+
3082
React.useEffect(() => {
3183
onSettingsChange({
3284
...settings,

0 commit comments

Comments
 (0)