Add skeleton for file event handling
This commit is contained in:
parent
1420cf104e
commit
8a7cc65e88
6 changed files with 259 additions and 4 deletions
8
plugin/src/events/file-event-handler.ts
Normal file
8
plugin/src/events/file-event-handler.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
import { TAbstractFile } from "obsidian";
|
||||
|
||||
export interface FileEventHandler {
|
||||
onCreate: (path: TAbstractFile) => void;
|
||||
onDelete: (path: TAbstractFile) => void;
|
||||
onRename: (path: TAbstractFile, oldPath: string) => void;
|
||||
onModify: (path: TAbstractFile) => void;
|
||||
}
|
||||
21
plugin/src/events/sync-event-handler.ts
Normal file
21
plugin/src/events/sync-event-handler.ts
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
import { TAbstractFile } from "obsidian";
|
||||
import { FileEventHandler } from "./file-event-handler";
|
||||
import { Logger } from "src/logger";
|
||||
|
||||
export class SyncEventHandler implements FileEventHandler {
|
||||
onCreate(path: TAbstractFile) {
|
||||
Logger.getInstance().info(`File created: ${path}`);
|
||||
}
|
||||
|
||||
onDelete(path: TAbstractFile) {
|
||||
Logger.getInstance().info(`File deleted: ${path}`);
|
||||
}
|
||||
|
||||
onRename(path: TAbstractFile, oldPath: string) {
|
||||
Logger.getInstance().info(`File renamed: ${oldPath} -> ${path}`);
|
||||
}
|
||||
|
||||
onModify(path: TAbstractFile) {
|
||||
Logger.getInstance().info(`File modified: ${path}`);
|
||||
}
|
||||
}
|
||||
68
plugin/src/logger.ts
Normal file
68
plugin/src/logger.ts
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
enum LogLevel {
|
||||
INFO,
|
||||
WARNING,
|
||||
ERROR,
|
||||
}
|
||||
|
||||
class LogLine {
|
||||
constructor(public level: LogLevel, public message: string) {}
|
||||
|
||||
public toString(): string {
|
||||
return `${this.formatLevel()}: ${this.message}`;
|
||||
}
|
||||
|
||||
private formatLevel(): string {
|
||||
switch (this.level) {
|
||||
case LogLevel.INFO:
|
||||
return "INFO";
|
||||
case LogLevel.WARNING:
|
||||
return "WARNING";
|
||||
case LogLevel.ERROR:
|
||||
return "ERROR";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class Logger {
|
||||
private static readonly MAX_MESSAGES = 1000;
|
||||
|
||||
private static instance: Logger;
|
||||
private messages: LogLine[] = [];
|
||||
|
||||
private constructor() {}
|
||||
|
||||
static getInstance(): Logger {
|
||||
if (!Logger.instance) {
|
||||
Logger.instance = new Logger();
|
||||
}
|
||||
return Logger.instance;
|
||||
}
|
||||
|
||||
public info(message: string): void {
|
||||
this.pushMessage(message, LogLevel.INFO);
|
||||
console.log(message);
|
||||
}
|
||||
|
||||
public warn(message: string): void {
|
||||
this.pushMessage(message, LogLevel.WARNING);
|
||||
console.warn(message);
|
||||
}
|
||||
|
||||
public error(message: string): void {
|
||||
this.pushMessage(message, LogLevel.ERROR);
|
||||
console.error(message);
|
||||
}
|
||||
|
||||
public getMessages(): LogLine[] {
|
||||
return this.messages;
|
||||
}
|
||||
|
||||
private pushMessage(message: string, level: LogLevel): void {
|
||||
this.messages.push(new LogLine(level, message));
|
||||
if (this.messages.length > Logger.MAX_MESSAGES) {
|
||||
this.messages.shift();
|
||||
}
|
||||
}
|
||||
}
|
||||
119
plugin/src/plugin.ts
Normal file
119
plugin/src/plugin.ts
Normal file
|
|
@ -0,0 +1,119 @@
|
|||
import {
|
||||
App,
|
||||
Editor,
|
||||
MarkdownView,
|
||||
Modal,
|
||||
Notice,
|
||||
Plugin,
|
||||
PluginSettingTab,
|
||||
Setting,
|
||||
WorkspaceLeaf,
|
||||
} from "obsidian";
|
||||
|
||||
import * as plugin from "../../backend/sync_wasm/pkg/sync_wasm.js";
|
||||
import * as wasmBin from "../../backend/sync_wasm/pkg/sync_wasm_bg.wasm";
|
||||
import { getSystemErrorName } from "util";
|
||||
import { SyncSettingsTab } from "./settings/settings-tab.js";
|
||||
import { SyncView } from "./views/sync-view.js";
|
||||
import {
|
||||
DEFAULT_SETTINGS,
|
||||
SettingsContainer,
|
||||
SyncSettings,
|
||||
} from "./settings/settings.js";
|
||||
import { Logger } from "./logger.js";
|
||||
import { SyncEventHandler } from "./events/sync-event-handler.js";
|
||||
|
||||
export default class SyncPlugin extends Plugin {
|
||||
async onload() {
|
||||
Logger.getInstance().info('Starting plugin "Sample Plugin"');
|
||||
|
||||
await plugin.default(Promise.resolve((wasmBin as any).default));
|
||||
|
||||
const eventHandler = new SyncEventHandler();
|
||||
|
||||
[
|
||||
this.app.vault.on(
|
||||
"create",
|
||||
eventHandler.onCreate.bind(eventHandler)
|
||||
),
|
||||
this.app.vault.on(
|
||||
"modify",
|
||||
eventHandler.onModify.bind(eventHandler)
|
||||
),
|
||||
this.app.vault.on(
|
||||
"delete",
|
||||
eventHandler.onDelete.bind(eventHandler)
|
||||
),
|
||||
this.app.vault.on(
|
||||
"rename",
|
||||
eventHandler.onRename.bind(eventHandler)
|
||||
),
|
||||
].forEach((event) => this.registerEvent(event));
|
||||
|
||||
// This creates an icon in the left ribbon.
|
||||
const ribbonIconEl = this.addRibbonIcon(
|
||||
"dice",
|
||||
"Sample Plugin",
|
||||
(evt: MouseEvent) => {
|
||||
// Called when the user clicks the icon.
|
||||
new Notice("This is a notice!");
|
||||
}
|
||||
);
|
||||
// Perform additional things with the ribbon
|
||||
ribbonIconEl.addClass("my-plugin-ribbon-class");
|
||||
|
||||
// This adds a status bar item to the bottom of the app. Does not work on mobile apps.
|
||||
const statusBarItemEl = this.addStatusBarItem();
|
||||
statusBarItemEl.setText("Status Bar Text");
|
||||
|
||||
// This adds an editor command that can perform some operation on the current editor instance
|
||||
this.addCommand({
|
||||
id: "sample-editor-command",
|
||||
name: "Sample editor command",
|
||||
editorCallback: (editor: Editor, view: MarkdownView) => {
|
||||
console.log(editor.getSelection());
|
||||
editor.replaceSelection("Sample Editor Command");
|
||||
},
|
||||
});
|
||||
|
||||
const settingsContainer = new SettingsContainer(
|
||||
this,
|
||||
await this.loadData()
|
||||
);
|
||||
this.addSettingTab(
|
||||
new SyncSettingsTab(this.app, this, settingsContainer)
|
||||
);
|
||||
|
||||
// When registering intervals, this function will automatically clear the interval when the plugin is disabled.
|
||||
this.registerInterval(
|
||||
window.setInterval(() => console.log("setInterval"), 5 * 60 * 1000)
|
||||
);
|
||||
this.registerView(SyncView.TYPE, (leaf) => new SyncView(leaf));
|
||||
|
||||
this.addRibbonIcon("dice", "Activate view", () => {
|
||||
this.activateView();
|
||||
});
|
||||
}
|
||||
|
||||
onunload() {}
|
||||
|
||||
async activateView() {
|
||||
const { workspace } = this.app;
|
||||
|
||||
let leaf: WorkspaceLeaf | null = null;
|
||||
const leaves = workspace.getLeavesOfType(SyncView.TYPE);
|
||||
|
||||
if (leaves.length > 0) {
|
||||
// A leaf with our view already exists, use that
|
||||
leaf = leaves[0];
|
||||
} else {
|
||||
// Our view could not be found in the workspace, create a new leaf
|
||||
// in the right sidebar for it
|
||||
leaf = workspace.getRightLeaf(false);
|
||||
await leaf?.setViewState({ type: SyncView.TYPE, active: true });
|
||||
}
|
||||
|
||||
// "Reveal" the leaf in case it is in a collapsed sidebar
|
||||
workspace.revealLeaf(leaf!);
|
||||
}
|
||||
}
|
||||
|
|
@ -19,10 +19,7 @@ export class SettingsContainer {
|
|||
|
||||
private onChangeHandlers: Array<(settings: SyncSettings) => void> = [];
|
||||
|
||||
public constructor(
|
||||
private plugin: SyncPlugin,
|
||||
private loadedSettings: any
|
||||
) {
|
||||
public constructor(private plugin: SyncPlugin, loadedSettings: any) {
|
||||
this._settings = Object.assign({}, DEFAULT_SETTINGS, loadedSettings);
|
||||
}
|
||||
|
||||
|
|
|
|||
42
plugin/src/views/sync-view.ts
Normal file
42
plugin/src/views/sync-view.ts
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
import { ItemView, WorkspaceLeaf } from "obsidian";
|
||||
import { Logger } from "src/logger";
|
||||
|
||||
export class SyncView extends ItemView {
|
||||
public static TYPE = "example-view";
|
||||
|
||||
constructor(leaf: WorkspaceLeaf) {
|
||||
super(leaf);
|
||||
}
|
||||
|
||||
getViewType() {
|
||||
return SyncView.TYPE;
|
||||
}
|
||||
|
||||
getDisplayText() {
|
||||
return "Example view";
|
||||
}
|
||||
|
||||
async onOpen() {
|
||||
const container = this.containerEl.children[1];
|
||||
container.empty();
|
||||
container.createEl("h4", { text: "Example view" });
|
||||
|
||||
setInterval(() => this.updateView(), 1000);
|
||||
}
|
||||
|
||||
async updateView() {
|
||||
const container = this.containerEl.children[1];
|
||||
container.empty();
|
||||
|
||||
const messages = Logger.getInstance()
|
||||
.getMessages()
|
||||
.map((message) => message.toString())
|
||||
.join("\n");
|
||||
|
||||
container.createEl("pre", { text: messages });
|
||||
}
|
||||
|
||||
async onClose() {
|
||||
// Nothing to clean up.
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue