import { type ObsidianLiveSyncSettings, LOG_LEVEL_NOTICE } from "../../lib/src/common/types.ts"; import { configURIBase } from "../../common/types.ts"; // import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser.js"; import { fireAndForget } from "../../lib/src/common/utils.ts"; import { EVENT_REQUEST_COPY_SETUP_URI, EVENT_REQUEST_OPEN_P2P_SETTINGS, EVENT_REQUEST_OPEN_SETUP_URI, EVENT_REQUEST_SHOW_SETUP_QR, eventHub, } from "../../common/events.ts"; import { $msg } from "../../lib/src/common/i18n.ts"; // import { performDoctorConsultation, RebuildOptions } from "@/lib/src/common/configForDoc.ts"; import type { LiveSyncCore } from "../../main.ts"; import { encodeQR, encodeSettingsToQRCodeData, encodeSettingsToSetupURI, OutputFormat, } from "../../lib/src/API/processSetting.ts"; import { SetupManager, UserMode } from "./SetupManager.ts"; import { AbstractModule } from "../AbstractModule.ts"; export class ModuleSetupObsidian extends AbstractModule { private _setupManager!: SetupManager; private _everyOnload(): Promise { this._setupManager = this.core.getModule(SetupManager); this.registerObsidianProtocolHandler("setuplivesync", async (conf: any) => { if (conf.settings) { await this._setupManager.onUseSetupURI( UserMode.Unknown, `${configURIBase}${encodeURIComponent(conf.settings)}` ); } else if (conf.settingsQR) { await this._setupManager.decodeQR(conf.settingsQR); } }); this.addCommand({ id: "livesync-setting-qr", name: "Show settings as a QR code", callback: () => fireAndForget(this.encodeQR()), }); this.addCommand({ id: "livesync-copysetupuri", name: "Copy settings as a new setup URI", callback: () => fireAndForget(this.command_copySetupURI()), }); this.addCommand({ id: "livesync-copysetupuri-short", name: "Copy settings as a new setup URI (With customization sync)", callback: () => fireAndForget(this.command_copySetupURIWithSync()), }); this.addCommand({ id: "livesync-copysetupurifull", name: "Copy settings as a new setup URI (Full)", callback: () => fireAndForget(this.command_copySetupURIFull()), }); this.addCommand({ id: "livesync-opensetupuri", name: "Use the copied setup URI (Formerly Open setup URI)", callback: () => fireAndForget(this.command_openSetupURI()), }); eventHub.onEvent(EVENT_REQUEST_OPEN_SETUP_URI, () => fireAndForget(() => this.command_openSetupURI())); eventHub.onEvent(EVENT_REQUEST_COPY_SETUP_URI, () => fireAndForget(() => this.command_copySetupURI())); eventHub.onEvent(EVENT_REQUEST_SHOW_SETUP_QR, () => fireAndForget(() => this.encodeQR())); eventHub.onEvent(EVENT_REQUEST_OPEN_P2P_SETTINGS, () => fireAndForget(() => { return this._setupManager.onP2PManualSetup(UserMode.Update, this.settings, false); }) ); return Promise.resolve(true); } async encodeQR() { const settingString = encodeSettingsToQRCodeData(this.settings); const codeSVG = encodeQR(settingString, OutputFormat.SVG); if (codeSVG == "") { return ""; } const msg = $msg("Setup.QRCode", { qr_image: codeSVG }); await this.core.confirm.confirmWithMessage("Settings QR Code", msg, ["OK"], "OK"); return await Promise.resolve(codeSVG); } async askEncryptingPassphrase(): Promise { const encryptingPassphrase = await this.core.confirm.askString( "Encrypt your settings", "The passphrase to encrypt the setup URI", "", true ); return encryptingPassphrase; } async command_copySetupURI(stripExtra = true) { const encryptingPassphrase = await this.askEncryptingPassphrase(); if (encryptingPassphrase === false) return; const encryptedURI = await encodeSettingsToSetupURI( this.settings, encryptingPassphrase, [...((stripExtra ? ["pluginSyncExtendedSetting"] : []) as (keyof ObsidianLiveSyncSettings)[])], true ); if (await this.services.UI.promptCopyToClipboard("Setup URI", encryptedURI)) { this._log("Setup URI copied to clipboard", LOG_LEVEL_NOTICE); } // await navigator.clipboard.writeText(encryptedURI); } async command_copySetupURIFull() { const encryptingPassphrase = await this.askEncryptingPassphrase(); if (encryptingPassphrase === false) return; const encryptedURI = await encodeSettingsToSetupURI(this.settings, encryptingPassphrase, [], false); await navigator.clipboard.writeText(encryptedURI); this._log("Setup URI copied to clipboard", LOG_LEVEL_NOTICE); } async command_copySetupURIWithSync() { await this.command_copySetupURI(false); } async command_openSetupURI() { await this._setupManager.onUseSetupURI(UserMode.Unknown); } // TODO: Where to implement these? // async askSyncWithRemoteConfig(tryingSettings: ObsidianLiveSyncSettings): Promise { // const buttons = { // fetch: $msg("Setup.FetchRemoteConf.Buttons.Fetch"), // no: $msg("Setup.FetchRemoteConf.Buttons.Skip"), // } as const; // const fetchRemoteConf = await this.core.confirm.askSelectStringDialogue( // $msg("Setup.FetchRemoteConf.Message"), // Object.values(buttons), // { defaultAction: buttons.fetch, timeout: 0, title: $msg("Setup.FetchRemoteConf.Title") } // ); // if (fetchRemoteConf == buttons.no) { // return tryingSettings; // } // const newSettings = JSON.parse(JSON.stringify(tryingSettings)) as ObsidianLiveSyncSettings; // const remoteConfig = await this.services.tweakValue.fetchRemotePreferred(newSettings); // if (remoteConfig) { // this._log("Remote configuration found.", LOG_LEVEL_NOTICE); // const resultSettings = { // ...DEFAULT_SETTINGS, // ...tryingSettings, // ...remoteConfig, // } satisfies ObsidianLiveSyncSettings; // return resultSettings; // } else { // this._log("Remote configuration not applied.", LOG_LEVEL_NOTICE); // return { // ...DEFAULT_SETTINGS, // ...tryingSettings, // } satisfies ObsidianLiveSyncSettings; // } // } // async askPerformDoctor( // tryingSettings: ObsidianLiveSyncSettings // ): Promise<{ settings: ObsidianLiveSyncSettings; shouldRebuild: boolean; isModified: boolean }> { // const buttons = { // yes: $msg("Setup.Doctor.Buttons.Yes"), // no: $msg("Setup.Doctor.Buttons.No"), // } as const; // const performDoctor = await this.core.confirm.askSelectStringDialogue( // $msg("Setup.Doctor.Message"), // Object.values(buttons), // { defaultAction: buttons.yes, timeout: 0, title: $msg("Setup.Doctor.Title") } // ); // if (performDoctor == buttons.no) { // return { settings: tryingSettings, shouldRebuild: false, isModified: false }; // } // const newSettings = JSON.parse(JSON.stringify(tryingSettings)) as ObsidianLiveSyncSettings; // const { settings, shouldRebuild, isModified } = await performDoctorConsultation(this.core, newSettings, { // localRebuild: RebuildOptions.AutomaticAcceptable, // Because we are in the setup wizard, we can skip the confirmation. // remoteRebuild: RebuildOptions.SkipEvenIfRequired, // activateReason: "New settings from URI", // }); // if (isModified) { // this._log("Doctor has fixed some issues!", LOG_LEVEL_NOTICE); // return { // settings, // shouldRebuild, // isModified, // }; // } else { // this._log("Doctor detected no issues!", LOG_LEVEL_NOTICE); // return { settings: tryingSettings, shouldRebuild: false, isModified: false }; // } // } onBindFunction(core: LiveSyncCore, services: typeof core.services): void { services.appLifecycle.onLoaded.addHandler(this._everyOnload.bind(this)); } }