From 0db1380d27e6eb6438ba3b88b5fee8d7e611d009 Mon Sep 17 00:00:00 2001 From: Andras Schmelczer Date: Sun, 8 Dec 2024 22:05:05 +0000 Subject: [PATCH] E2E workflow for creating docs --- plugin/src/events/sync-event-handler.ts | 24 +++++--- plugin/src/plugin.ts | 73 +++++++++++-------------- plugin/src/syncer/syncer.ts | 60 ++++++++++++++++++++ 3 files changed, 108 insertions(+), 49 deletions(-) create mode 100644 plugin/src/syncer/syncer.ts diff --git a/plugin/src/events/sync-event-handler.ts b/plugin/src/events/sync-event-handler.ts index 0d1034e..a73d117 100644 --- a/plugin/src/events/sync-event-handler.ts +++ b/plugin/src/events/sync-event-handler.ts @@ -1,21 +1,27 @@ -import { TAbstractFile } from "obsidian"; +import { TAbstractFile, TFile } from "obsidian"; import { FileEventHandler } from "./file-event-handler"; import { Logger } from "src/logger"; +import { Syncer } from "src/syncer/syncer"; export class SyncEventHandler implements FileEventHandler { - onCreate(path: TAbstractFile) { - Logger.getInstance().info(`File created: ${path}`); + constructor(private syncer: Syncer) {} + + async onCreate(file: TAbstractFile) { + if (file instanceof TFile) { + Logger.getInstance().info(`File created: ${file}`); + this.syncer.onCreate(file.path, await file.vault.read(file)); + } } - onDelete(path: TAbstractFile) { - Logger.getInstance().info(`File deleted: ${path}`); + onDelete(file: TAbstractFile) { + Logger.getInstance().info(`File deleted: ${file}`); } - onRename(path: TAbstractFile, oldPath: string) { - Logger.getInstance().info(`File renamed: ${oldPath} -> ${path}`); + onRename(file: TAbstractFile, oldPath: string) { + Logger.getInstance().info(`File renamed: ${oldPath} -> ${file}`); } - onModify(path: TAbstractFile) { - Logger.getInstance().info(`File modified: ${path}`); + onModify(file: TAbstractFile) { + Logger.getInstance().info(`File modified: ${file}`); } } diff --git a/plugin/src/plugin.ts b/plugin/src/plugin.ts index 7484c02..ed55a5a 100644 --- a/plugin/src/plugin.ts +++ b/plugin/src/plugin.ts @@ -10,8 +10,8 @@ import { 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 * as plugin from "../../backend/sync_lib/pkg/sync_lib.js"; +import * as wasmBin from "../../backend/sync_lib/pkg/sync_lib_bg.wasm"; import { getSystemErrorName } from "util"; import { SyncSettingsTab } from "./settings/settings-tab.js"; import { SyncView } from "./views/sync-view.js"; @@ -22,6 +22,7 @@ import { } from "./settings/settings.js"; import { Logger } from "./logger.js"; import { SyncEventHandler } from "./events/sync-event-handler.js"; +import { Syncer } from "./syncer/syncer.js"; export default class SyncPlugin extends Plugin { async onload() { @@ -29,7 +30,26 @@ export default class SyncPlugin extends Plugin { await plugin.default(Promise.resolve((wasmBin as any).default)); - const eventHandler = new SyncEventHandler(); + // 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) + ); + + const syncer = new Syncer(settingsContainer); + const eventHandler = new SyncEventHandler(syncer); [ this.app.vault.on( @@ -50,49 +70,22 @@ export default class SyncPlugin extends Plugin { ), ].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(); - }); + const ribbonIconEl = this.addRibbonIcon( + "dice", + "Sample Plugin", + (evt: MouseEvent) => { + this.activateView(); + + new Notice("This is a notice!"); + } + ); + ribbonIconEl.addClass("my-plugin-ribbon-class"); } onunload() {} diff --git a/plugin/src/syncer/syncer.ts b/plugin/src/syncer/syncer.ts new file mode 100644 index 0000000..22f43a5 --- /dev/null +++ b/plugin/src/syncer/syncer.ts @@ -0,0 +1,60 @@ +import { SettingsContainer, SyncSettings } from "src/settings/settings"; + +import * as plugin from "../../../backend/sync_lib/pkg/sync_lib.js"; + +import createClient, { Client } from "openapi-fetch"; +import type { components, paths } from "./types"; // generated by openapi-typescript +import { Logger } from "src/logger.js"; + +export class Syncer { + private static vault_id = "default"; + private client: Client; + + public constructor(private settings: SettingsContainer) { + this.createClient(settings.getSettings()); + settings.onChange((s) => this.createClient(s)); + } + + private createClient(settings: SyncSettings) { + this.client = createClient({ + baseUrl: settings.remoteUri, + }); + } + + public async onCreate( + relativePath: string, + content: string + ): Promise< + components["schemas"]["DocumentVersionWithoutContent"] | undefined + > { + let response = await this.client.POST("/vaults/{vault_id}/documents", { + params: { + path: { vault_id: Syncer.vault_id }, + header: { + authorization: + "Bearer " + this.settings.getSettings().token, + }, + }, + body: { + contentBase64: plugin.string_to_base64(content), + createdDate: new Date().toISOString(), + isBinary: true, + relativePath, + }, + }); + + Logger.getInstance().info( + "Created document " + JSON.stringify(response.data) + ); + + return response.data; + } + + private uri(path: string) { + let uri = this.settings.getSettings().remoteUri; + if (!uri.endsWith("/")) { + uri += "/"; + } + return uri + path; + } +}