mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-04-08 18:08:42 +00:00
Refactor: Migrate the outdated, unstable platform abstraction layer to Services
This commit is contained in:
@@ -9,7 +9,6 @@ import {
|
||||
} from "../../lib/src/common/types.ts";
|
||||
import { generatePatchObj, isObjectDifferent } from "../../lib/src/common/utils.ts";
|
||||
import { AbstractObsidianModule } from "../AbstractObsidianModule.ts";
|
||||
import { SvelteDialogManager } from "./SetupWizard/ObsidianSvelteDialog.ts";
|
||||
import Intro from "./SetupWizard/dialogs/Intro.svelte";
|
||||
import SelectMethodNewUser from "./SetupWizard/dialogs/SelectMethodNewUser.svelte";
|
||||
import SelectMethodExisting from "./SetupWizard/dialogs/SelectMethodExisting.svelte";
|
||||
@@ -52,10 +51,13 @@ export const enum UserMode {
|
||||
* Setup Manager to handle onboarding and configuration setup
|
||||
*/
|
||||
export class SetupManager extends AbstractObsidianModule {
|
||||
/**
|
||||
* Dialog manager for handling Svelte dialogs
|
||||
*/
|
||||
private dialogManager: SvelteDialogManager = new SvelteDialogManager(this.plugin);
|
||||
// /**
|
||||
// * Dialog manager for handling Svelte dialogs
|
||||
// */
|
||||
// private dialogManager: SvelteDialogManager = new SvelteDialogManager(this.plugin);
|
||||
get dialogManager() {
|
||||
return this.services.UI.dialogManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the onboarding process
|
||||
|
||||
@@ -1,141 +0,0 @@
|
||||
import { eventHub, EVENT_PLUGIN_UNLOADED } from "@/common/events";
|
||||
import { Modal } from "@/deps";
|
||||
import type ObsidianLiveSyncPlugin from "@/main";
|
||||
import { mount, unmount } from "svelte";
|
||||
import DialogHost from "@lib/UI/DialogHost.svelte";
|
||||
import { fireAndForget, promiseWithResolvers, type PromiseWithResolvers } from "octagonal-wheels/promises";
|
||||
import { LOG_LEVEL_NOTICE, Logger } from "octagonal-wheels/common/logger";
|
||||
import {
|
||||
type DialogControlBase,
|
||||
type DialogSvelteComponentBaseProps,
|
||||
type ComponentHasResult,
|
||||
setupDialogContext,
|
||||
getDialogContext,
|
||||
type SvelteDialogManagerBase,
|
||||
} from "@/lib/src/UI/svelteDialog.ts";
|
||||
|
||||
export type DialogSvelteComponentProps = DialogSvelteComponentBaseProps & {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
services: ObsidianLiveSyncPlugin["services"];
|
||||
};
|
||||
|
||||
export type DialogControls<T = any, U = any> = DialogControlBase<T, U> & {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
services: ObsidianLiveSyncPlugin["services"];
|
||||
};
|
||||
|
||||
export type DialogMessageProps = Record<string, any>;
|
||||
// type DialogSvelteComponent<T extends DialogSvelteComponentProps = DialogSvelteComponentProps> = Component<SvelteComponent<T>,any>;
|
||||
|
||||
export class SvelteDialog<T, U> extends Modal {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
mountedComponent?: ReturnType<typeof mount>;
|
||||
component: ComponentHasResult<T, U>;
|
||||
result?: T;
|
||||
initialData?: U;
|
||||
title: string = "Obsidian LiveSync - Setup Wizard";
|
||||
constructor(plugin: ObsidianLiveSyncPlugin, component: ComponentHasResult<T, U>, initialData?: U) {
|
||||
super(plugin.app);
|
||||
this.plugin = plugin;
|
||||
this.component = component;
|
||||
this.initialData = initialData;
|
||||
}
|
||||
resolveResult() {
|
||||
this.resultPromiseWithResolvers?.resolve(this.result);
|
||||
this.resultPromiseWithResolvers = undefined;
|
||||
}
|
||||
resultPromiseWithResolvers?: PromiseWithResolvers<T | undefined>;
|
||||
onOpen() {
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
||||
const dialog = this;
|
||||
|
||||
if (this.resultPromiseWithResolvers) {
|
||||
this.resultPromiseWithResolvers.reject("Dialog opened again");
|
||||
}
|
||||
const pr = promiseWithResolvers<any>();
|
||||
eventHub.once(EVENT_PLUGIN_UNLOADED, () => {
|
||||
if (this.resultPromiseWithResolvers === pr) {
|
||||
pr.reject("Plugin unloaded");
|
||||
this.close();
|
||||
}
|
||||
});
|
||||
this.resultPromiseWithResolvers = pr;
|
||||
this.mountedComponent = mount(DialogHost, {
|
||||
target: contentEl,
|
||||
props: {
|
||||
onSetupContext: (props: DialogSvelteComponentBaseProps) => {
|
||||
setupDialogContext({
|
||||
...props,
|
||||
plugin: this.plugin,
|
||||
services: this.plugin.services,
|
||||
});
|
||||
},
|
||||
setTitle: (title: string) => {
|
||||
dialog.setTitle(title);
|
||||
},
|
||||
closeDialog: () => {
|
||||
dialog.close();
|
||||
},
|
||||
setResult: (result: T) => {
|
||||
this.result = result;
|
||||
},
|
||||
getInitialData: () => this.initialData,
|
||||
mountComponent: this.component,
|
||||
},
|
||||
});
|
||||
}
|
||||
waitForClose(): Promise<T | undefined> {
|
||||
if (!this.resultPromiseWithResolvers) {
|
||||
throw new Error("Dialog not opened yet");
|
||||
}
|
||||
return this.resultPromiseWithResolvers.promise;
|
||||
}
|
||||
onClose() {
|
||||
this.resolveResult();
|
||||
fireAndForget(async () => {
|
||||
if (this.mountedComponent) {
|
||||
await unmount(this.mountedComponent);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export async function openSvelteDialog<T, U>(
|
||||
plugin: ObsidianLiveSyncPlugin,
|
||||
component: ComponentHasResult<T, U>,
|
||||
initialData?: U
|
||||
): Promise<T | undefined> {
|
||||
const dialog = new SvelteDialog<T, U>(plugin, component, initialData);
|
||||
dialog.open();
|
||||
|
||||
return await dialog.waitForClose();
|
||||
}
|
||||
|
||||
export class SvelteDialogManager implements SvelteDialogManagerBase {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
constructor(plugin: ObsidianLiveSyncPlugin) {
|
||||
this.plugin = plugin;
|
||||
}
|
||||
async open<T, U>(component: ComponentHasResult<T, U>, initialData?: U): Promise<T | undefined> {
|
||||
return await openSvelteDialog<T, U>(this.plugin, component, initialData);
|
||||
}
|
||||
async openWithExplicitCancel<T, U>(component: ComponentHasResult<T, U>, initialData?: U): Promise<T> {
|
||||
for (let i = 0; i < 10; i++) {
|
||||
const ret = await openSvelteDialog<T, U>(this.plugin, component, initialData);
|
||||
if (ret !== undefined) {
|
||||
return ret;
|
||||
}
|
||||
if (this.plugin.services.appLifecycle.hasUnloaded()) {
|
||||
throw new Error("Operation cancelled due to app shutdown.");
|
||||
}
|
||||
Logger("Please select 'Cancel' explicitly to cancel this operation.", LOG_LEVEL_NOTICE);
|
||||
}
|
||||
throw new Error("Operation Forcibly cancelled by user.");
|
||||
}
|
||||
}
|
||||
|
||||
export function getObsidianDialogContext<T = any>(): DialogControls<T> {
|
||||
return getDialogContext<T>() as DialogControls<T>;
|
||||
}
|
||||
@@ -16,8 +16,7 @@
|
||||
} from "../../../../lib/src/common/types";
|
||||
|
||||
import { onMount } from "svelte";
|
||||
import type { GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { getObsidianDialogContext } from "../ObsidianSvelteDialog";
|
||||
import { getDialogContext, type GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { copyTo, pickBucketSyncSettings } from "../../../../lib/src/common/utils";
|
||||
|
||||
const default_setting = pickBucketSyncSettings(DEFAULT_SETTINGS);
|
||||
@@ -39,7 +38,7 @@
|
||||
}
|
||||
});
|
||||
let error = $state("");
|
||||
const context = getObsidianDialogContext();
|
||||
const context = getDialogContext();
|
||||
const isEndpointSecure = $derived.by(() => {
|
||||
return syncSetting.endpoint.trim().toLowerCase().startsWith("https://");
|
||||
});
|
||||
|
||||
@@ -17,9 +17,8 @@
|
||||
} from "../../../../lib/src/common/types";
|
||||
import { isCloudantURI } from "../../../../lib/src/pouchdb/utils_couchdb";
|
||||
|
||||
import { getObsidianDialogContext } from "../ObsidianSvelteDialog";
|
||||
import { onMount } from "svelte";
|
||||
import type { GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { getDialogContext, type GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { copyTo, pickCouchDBSyncSettings } from "../../../../lib/src/common/utils";
|
||||
import PanelCouchDBCheck from "./PanelCouchDBCheck.svelte";
|
||||
|
||||
@@ -40,7 +39,7 @@
|
||||
});
|
||||
|
||||
let error = $state("");
|
||||
const context = getObsidianDialogContext();
|
||||
const context = getDialogContext();
|
||||
|
||||
function generateSetting() {
|
||||
const connSetting: CouchDBConnection = {
|
||||
|
||||
@@ -22,16 +22,15 @@
|
||||
import { TrysteroReplicator } from "../../../../lib/src/replication/trystero/TrysteroReplicator";
|
||||
import type { ReplicatorHostEnv } from "../../../../lib/src/replication/trystero/types";
|
||||
import { copyTo, pickP2PSyncSettings, type SimpleStore } from "../../../../lib/src/common/utils";
|
||||
import { getObsidianDialogContext } from "../ObsidianSvelteDialog";
|
||||
import { onMount } from "svelte";
|
||||
import type { GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { getDialogContext, type GuestDialogProps } from "../../../../lib/src/UI/svelteDialog";
|
||||
import { SETTING_KEY_P2P_DEVICE_NAME } from "../../../../lib/src/common/types";
|
||||
import ExtraItems from "../../../../lib/src/UI/components/ExtraItems.svelte";
|
||||
|
||||
const default_setting = pickP2PSyncSettings(DEFAULT_SETTINGS);
|
||||
let syncSetting = $state<P2PConnectionInfo>({ ...default_setting });
|
||||
|
||||
const context = getObsidianDialogContext();
|
||||
const context = getDialogContext();
|
||||
let error = $state("");
|
||||
const TYPE_CANCELLED = "cancelled";
|
||||
type SettingInfo = P2PConnectionInfo;
|
||||
@@ -104,7 +103,7 @@
|
||||
processReplicatedDocs: async (docs: any[]) => {
|
||||
return;
|
||||
},
|
||||
confirm: context.plugin.confirm,
|
||||
confirm: context.services.confirm,
|
||||
db: dummyPouch,
|
||||
simpleStore: store,
|
||||
deviceName: syncSetting.P2P_DevicePeerName || "unnamed-device",
|
||||
|
||||
Reference in New Issue
Block a user