generated from obsidianmd/obsidian-sample-plugin
-
-
Notifications
You must be signed in to change notification settings - Fork 16
/
onFileModifyAutomatorManager.ts
84 lines (69 loc) · 3.04 KB
/
onFileModifyAutomatorManager.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import {UniqueQueue} from "../uniqueQueue";
import type {App, TAbstractFile, TFile} from "obsidian";
import {debounce} from "obsidian";
import {UpdatedFileCache} from "../updatedFileCache";
import type {IOnFileModifyAutomator} from "./onFileModifyAutomators/IOnFileModifyAutomator";
import {log} from "../logger/logManager";
import type MetaEdit from "../main";
import {abstractFileToMarkdownTFile} from "../utility";
import type {IAutomatorManager} from "./IAutomatorManager";
import type {OnModifyAutomatorType} from "./onFileModifyAutomators/onModifyAutomatorType";
export class OnFileModifyAutomatorManager implements IAutomatorManager {
private plugin: MetaEdit;
private app: App;
private updateFileQueue: UniqueQueue<TFile> = new UniqueQueue<TFile>();
private updatedFileCache: UpdatedFileCache= new UpdatedFileCache();
private automators: IOnFileModifyAutomator[] = [];
private readonly notifyDelay: number = 5000;
constructor(plugin: MetaEdit) {
this.plugin = plugin;
this.app = plugin.app;
}
startAutomators(): IAutomatorManager {
this.plugin.registerEvent(
this.plugin.app.vault.on("modify", (file) => this.onFileModify(file))
);
return this;
}
attach(automator: IOnFileModifyAutomator): IAutomatorManager {
const isExist = this.automators.some(tAuto => tAuto.type === automator.type);
if (isExist) {
log.logWarning(`a ${automator.type} automator is already attached.`);
return this;
}
this.automators.push(automator);
return this;
}
detach(automatorType: OnModifyAutomatorType): IAutomatorManager {
const automatorIndex = this.automators.findIndex(automator => automator.type === automatorType);
if (automatorIndex === -1) {
log.logMessage(`automator of type '${automatorType}' does not exist.`);
return this;
}
this.automators.splice(automatorIndex, 1);
return this;
}
private async onFileModify(file: TAbstractFile): Promise<void> {
const outfile: TFile = abstractFileToMarkdownTFile(file);
if (!outfile) return;
// Return on Excalidraw files to prevent conflict with its auto-save feature.
const metadata = await this.app.metadataCache.getFileCache(outfile);
const keys = Object.keys(metadata?.frontmatter);
if (keys && keys.some(key => key.toLowerCase().contains("excalidraw"))) {
return;
}
const fileContent: string = await this.app.vault.cachedRead(outfile);
if (!this.updatedFileCache.set(outfile.path, fileContent)) return;
if (this.updateFileQueue.enqueue(outfile)) {
this.notifyAutomators();
}
}
private notifyAutomators = debounce(async () => {
while (!this.updateFileQueue.isEmpty()) {
const file = this.updateFileQueue.dequeue();
for (const automator of this.automators) {
await automator.onFileModify(file);
}
}
}, this.notifyDelay, true);
}