mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-10-27 11:33:21 +00:00
Refactor optional file synchronisation ownership
This commit is contained in:
1 parent
3b2d5aa5af
commit
826413bf84
67 files changed
+6294
-1856
No files matched your search
@@ -2,14 +2,33 @@ import { ObsidianLiveSyncSettingTab } from "./SettingDialogue/ObsidianLiveSyncSe
|
||||
import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts";
|
||||
// import { PouchDB } from "../../lib/src/pouchdb/pouchdb-browser";
|
||||
import { EVENT_REQUEST_OPEN_SETTINGS, eventHub } from "@/common/events.ts";
|
||||
import type ObsidianLiveSyncPlugin from "@/main.ts";
|
||||
import type { LiveSyncCore } from "@/main.ts";
|
||||
import { openObsidianSettings } from "@/common/obsidianSettings.ts";
|
||||
import type { HiddenFileSyncRepairView } from "@/features/HiddenFileSync/hiddenFileSyncViews.ts";
|
||||
|
||||
export type ModuleObsidianSettingDialogueDependencies = {
|
||||
getHiddenFileSyncRepair(): HiddenFileSyncRepairView | undefined;
|
||||
};
|
||||
|
||||
export class ModuleObsidianSettingDialogue extends AbstractObsidianModule {
|
||||
private readonly dependencies: ModuleObsidianSettingDialogueDependencies;
|
||||
settingTab!: ObsidianLiveSyncSettingTab;
|
||||
|
||||
constructor(
|
||||
plugin: ObsidianLiveSyncPlugin,
|
||||
core: LiveSyncCore,
|
||||
dependencies: Partial<ModuleObsidianSettingDialogueDependencies> = {}
|
||||
) {
|
||||
super(plugin, core);
|
||||
this.dependencies = {
|
||||
getHiddenFileSyncRepair: dependencies.getHiddenFileSyncRepair ?? (() => undefined),
|
||||
};
|
||||
}
|
||||
|
||||
_everyOnloadAfterLoadSettings(): Promise<boolean> {
|
||||
this.settingTab = new ObsidianLiveSyncSettingTab(this.app, this.plugin);
|
||||
const hiddenFileSyncRepair = this.dependencies.getHiddenFileSyncRepair();
|
||||
this.settingTab = new ObsidianLiveSyncSettingTab(this.app, this.plugin, { hiddenFileSyncRepair });
|
||||
this.settingTab.reloadAllSettings(true);
|
||||
this.plugin.addSettingTab(this.settingTab);
|
||||
eventHub.onEvent(EVENT_REQUEST_OPEN_SETTINGS, () => this.openSetting());
|
||||
|
||||
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const settingTabState = vi.hoisted(() => ({
|
||||
callOrder: [] as string[],
|
||||
featureViews: undefined as unknown,
|
||||
reloadAllSettings: vi.fn<(skipUpdate?: boolean) => void>(),
|
||||
}));
|
||||
|
||||
@@ -11,6 +12,10 @@ const eventHubState = vi.hoisted(() => ({
|
||||
|
||||
vi.mock("./SettingDialogue/ObsidianLiveSyncSettingTab.ts", () => ({
|
||||
ObsidianLiveSyncSettingTab: class ObsidianLiveSyncSettingTab {
|
||||
constructor(_app: unknown, _plugin: unknown, featureViews: unknown) {
|
||||
settingTabState.featureViews = featureViews;
|
||||
}
|
||||
|
||||
reloadAllSettings(skipUpdate?: boolean) {
|
||||
settingTabState.callOrder.push(`reload:${String(skipUpdate)}`);
|
||||
settingTabState.reloadAllSettings(skipUpdate);
|
||||
@@ -46,15 +51,20 @@ function createModuleHarness() {
|
||||
},
|
||||
},
|
||||
};
|
||||
const hiddenFileSyncRepair = { scanInternalFiles: vi.fn() };
|
||||
const getHiddenFileSyncRepair = vi.fn(() => hiddenFileSyncRepair);
|
||||
const module = Object.assign(Object.create(ModuleObsidianSettingDialogue.prototype), {
|
||||
plugin,
|
||||
core: { services },
|
||||
dependencies: { getHiddenFileSyncRepair },
|
||||
}) as ModuleObsidianSettingDialogue;
|
||||
|
||||
module.onBindFunction(module.core as never, services as never);
|
||||
|
||||
return {
|
||||
initialisationHandler: () => initialisationHandler,
|
||||
getHiddenFileSyncRepair,
|
||||
hiddenFileSyncRepair,
|
||||
module,
|
||||
plugin,
|
||||
services,
|
||||
@@ -65,6 +75,7 @@ function createModuleHarness() {
|
||||
describe("ModuleObsidianSettingDialogue startup lifecycle", () => {
|
||||
beforeEach(() => {
|
||||
settingTabState.callOrder.length = 0;
|
||||
settingTabState.featureViews = undefined;
|
||||
settingTabState.reloadAllSettings.mockClear();
|
||||
eventHubState.onEvent.mockClear();
|
||||
});
|
||||
@@ -79,7 +90,8 @@ describe("ModuleObsidianSettingDialogue startup lifecycle", () => {
|
||||
});
|
||||
|
||||
it("seeds the setting editor without requesting a render before registration", async () => {
|
||||
const { initialisationHandler, settingsLoadedHandler } = createModuleHarness();
|
||||
const { getHiddenFileSyncRepair, hiddenFileSyncRepair, initialisationHandler, settingsLoadedHandler } =
|
||||
createModuleHarness();
|
||||
const handler = settingsLoadedHandler() ?? initialisationHandler();
|
||||
|
||||
expect(handler).toBeTypeOf("function");
|
||||
@@ -87,5 +99,7 @@ describe("ModuleObsidianSettingDialogue startup lifecycle", () => {
|
||||
|
||||
expect(settingTabState.reloadAllSettings).toHaveBeenCalledWith(true);
|
||||
expect(settingTabState.callOrder).toEqual(["reload:true", "add-setting-tab"]);
|
||||
expect(getHiddenFileSyncRepair).toHaveBeenCalledOnce();
|
||||
expect(settingTabState.featureViews).toEqual({ hiddenFileSyncRepair });
|
||||
});
|
||||
});
|
||||
@@ -14,7 +14,7 @@ import {
|
||||
import { delay, isObjectDifferent, sizeToHumanReadable } from "@vrtmrz/livesync-commonlib/compat/common/utils";
|
||||
import { Logger } from "@vrtmrz/livesync-commonlib/compat/common/logger";
|
||||
import { testCrypt } from "octagonal-wheels/encryption/encryption";
|
||||
import ObsidianLiveSyncPlugin from "@/main.ts";
|
||||
import type ObsidianLiveSyncPlugin from "@/main.ts";
|
||||
import { scheduleTask } from "@/common/utils.ts";
|
||||
import { REMOTE_RESOURCE_KINDS } from "@vrtmrz/livesync-commonlib/replication";
|
||||
import {
|
||||
@@ -78,12 +78,18 @@ import { createExtraMenuSettingSpecGroup, createGeneralSettingSpecGroups } from
|
||||
import { SetupManager } from "@/modules/features/SetupManager.ts";
|
||||
import { isP2PMainRemote } from "@/common/remoteConfiguration.ts";
|
||||
import { withOwnedRemoteResource } from "@/common/ownedRemoteResource.ts";
|
||||
import type { HiddenFileSyncRepairView } from "@/features/HiddenFileSync/hiddenFileSyncViews.ts";
|
||||
|
||||
// For creating a document
|
||||
// const toc = new Set<string>();
|
||||
|
||||
export type SettingTabFeatureViews = {
|
||||
hiddenFileSyncRepair?: HiddenFileSyncRepairView;
|
||||
};
|
||||
|
||||
export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
readonly featureViews: SettingTabFeatureViews;
|
||||
private _lifetimeComponent?: Component;
|
||||
private activePageRefresh?: () => void;
|
||||
get lifetimeComponent(): Component {
|
||||
@@ -323,9 +329,10 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
controlledElementFunc = [] as UpdateFunction[];
|
||||
onSavedHandlers = [] as OnSavedHandler<AllSettingItemKey>[];
|
||||
|
||||
constructor(app: App, plugin: ObsidianLiveSyncPlugin) {
|
||||
constructor(app: App, plugin: ObsidianLiveSyncPlugin, featureViews: SettingTabFeatureViews = {}) {
|
||||
super(app, plugin);
|
||||
this.plugin = plugin;
|
||||
this.featureViews = featureViews;
|
||||
Setting.env = this;
|
||||
eventHub.onEvent(EVENT_REQUEST_RELOAD_SETTING_TAB, () => {
|
||||
this.requestReload();
|
||||
|
||||
@@ -67,8 +67,6 @@ export function paneCustomisationSync(
|
||||
.setButtonText("Open")
|
||||
.setDisabled(false)
|
||||
.onClick(() => {
|
||||
// this.plugin.getAddOn<ConfigSync>(ConfigSync.name)?.showPluginSyncModal();
|
||||
// this.plugin.addOnConfigSync.showPluginSyncModal();
|
||||
eventHub.emitEvent(EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG);
|
||||
});
|
||||
})
|
||||
|
||||
@@ -21,7 +21,6 @@ import {
|
||||
EVENT_REQUEST_RUN_FIX_INCOMPLETE,
|
||||
eventHub,
|
||||
} from "@/common/events.ts";
|
||||
import { HiddenFileSync } from "@/features/HiddenFileSync/CmdHiddenFileSync.ts";
|
||||
import { EVENT_REQUEST_SHOW_HISTORY } from "@/common/obsidianEvents.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
@@ -339,22 +338,22 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
]);
|
||||
};
|
||||
const findHiddenFile = async (path: string) => {
|
||||
const addOn = this.core.getAddOn<HiddenFileSync>(HiddenFileSync.name);
|
||||
if (!addOn) {
|
||||
const repair = this.featureViews.hiddenFileSyncRepair;
|
||||
if (!repair) {
|
||||
return false;
|
||||
}
|
||||
const file = (await addOn.scanInternalFiles()).find((entry) => entry.path === path);
|
||||
const file = (await repair.scanInternalFiles()).find((entry) => entry.path === path);
|
||||
if (!file) {
|
||||
Logger(`Failed to find the file in the internal files: ${path}`, LOG_LEVEL_NOTICE);
|
||||
return false;
|
||||
}
|
||||
return { addOn, file };
|
||||
return { repair, file };
|
||||
};
|
||||
const storeStorageInDatabase = async (path: string): Promise<boolean> => {
|
||||
if (path.startsWith(".")) {
|
||||
const hidden = await findHiddenFile(path);
|
||||
return hidden
|
||||
? Boolean(await hidden.addOn.storeInternalFileToDatabase(hidden.file, true))
|
||||
? Boolean(await hidden.repair.storeInternalFileToDatabase(hidden.file, true))
|
||||
: false;
|
||||
}
|
||||
return Boolean(await this.core.fileHandler.storeFileToDB(path as FilePath, true));
|
||||
@@ -368,7 +367,7 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
const hidden = await findHiddenFile(path);
|
||||
return hidden
|
||||
? Boolean(
|
||||
await hidden.addOn.storeInternalFileToDatabaseWithBaseRevision(
|
||||
await hidden.repair.storeInternalFileToDatabaseWithBaseRevision(
|
||||
hidden.file,
|
||||
revision,
|
||||
createIfDifferent
|
||||
@@ -390,10 +389,10 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
force: boolean
|
||||
): Promise<boolean> => {
|
||||
if (path.startsWith(".")) {
|
||||
const addOn = this.core.getAddOn<HiddenFileSync>(HiddenFileSync.name);
|
||||
return addOn
|
||||
const repair = this.featureViews.hiddenFileSyncRepair;
|
||||
return repair
|
||||
? Boolean(
|
||||
await addOn.extractInternalFileRevisionFromDatabase(
|
||||
await repair.extractInternalFileRevisionFromDatabase(
|
||||
path as FilePath,
|
||||
revision,
|
||||
force
|
||||
|
||||
Reference in new issue
Block a user