mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-07-06 12:55:21 +00:00
@@ -61,21 +61,21 @@ export abstract class AbstractModule<
|
||||
return this.testDone(false);
|
||||
}
|
||||
|
||||
async _test(key: string, process: () => Promise<any>) {
|
||||
this._log(`Testing ${key}`, LOG_LEVEL_VERBOSE);
|
||||
try {
|
||||
const ret = await process();
|
||||
if (ret !== true) {
|
||||
this.addTestResult(key, false, ret.toString());
|
||||
return this.testFail(`${key} failed: ${ret}`);
|
||||
}
|
||||
this.addTestResult(key, true, "");
|
||||
} catch (ex: any) {
|
||||
this.addTestResult(key, false, "Failed by Exception", ex.toString());
|
||||
return this.testFail(`${key} failed: ${ex}`);
|
||||
}
|
||||
return this.testDone();
|
||||
}
|
||||
// async _test(key: string, process: () => Promise<any>) {
|
||||
// this._log(`Testing ${key}`, LOG_LEVEL_VERBOSE);
|
||||
// try {
|
||||
// const ret = await process();
|
||||
// if (ret !== true) {
|
||||
// this.addTestResult(key, false, ret.toString());
|
||||
// return this.testFail(`${key} failed: ${ret}`);
|
||||
// }
|
||||
// this.addTestResult(key, true, "");
|
||||
// } catch (ex: any) {
|
||||
// this.addTestResult(key, false, "Failed by Exception", ex.toString());
|
||||
// return this.testFail(`${key} failed: ${ex}`);
|
||||
// }
|
||||
// return this.testDone();
|
||||
// }
|
||||
|
||||
isMainReady() {
|
||||
return this.services.appLifecycle.isReady();
|
||||
|
||||
@@ -1,13 +1,6 @@
|
||||
import { type Prettify } from "@lib/common/types";
|
||||
import type { LiveSyncCore } from "@/main";
|
||||
import type ObsidianLiveSyncPlugin from "@/main";
|
||||
import { AbstractModule } from "./AbstractModule.ts";
|
||||
import type { ChainableExecuteFunction, OverridableFunctionsKeys } from "./ModuleTypes";
|
||||
|
||||
export type IObsidianModuleBase = OverridableFunctionsKeys<ObsidianLiveSyncPlugin>;
|
||||
export type IObsidianModule = Prettify<Partial<IObsidianModuleBase>>;
|
||||
export type ModuleKeys = keyof IObsidianModule;
|
||||
export type ChainableModuleProps = ChainableExecuteFunction<ObsidianLiveSyncPlugin>;
|
||||
|
||||
export abstract class AbstractObsidianModule extends AbstractModule {
|
||||
get app() {
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
import type { Prettify } from "@lib/common/types";
|
||||
import type { LiveSyncCore } from "@/main";
|
||||
|
||||
export type OverridableFunctionsKeys<T> = {
|
||||
[K in keyof T as K extends `$${string}` ? K : never]: T[K];
|
||||
};
|
||||
|
||||
export type ChainableExecuteFunction<T> = {
|
||||
[K in keyof T as K extends `$${string}`
|
||||
? T[K] extends (...args: any) => ChainableFunctionResult
|
||||
? K
|
||||
: never
|
||||
: never]: T[K];
|
||||
};
|
||||
|
||||
export type ICoreModuleBase = OverridableFunctionsKeys<LiveSyncCore>;
|
||||
export type ICoreModule = Prettify<Partial<ICoreModuleBase>>;
|
||||
export type CoreModuleKeys = keyof ICoreModule;
|
||||
|
||||
export type ChainableFunctionResult =
|
||||
| Promise<boolean | undefined | string>
|
||||
| Promise<boolean | undefined>
|
||||
| Promise<boolean>
|
||||
| Promise<void>;
|
||||
export type ChainableFunctionResultOrAll = Promise<boolean | undefined | string | void>;
|
||||
|
||||
type AllExecuteFunction<T> = {
|
||||
[K in keyof T as K extends `$all${string}`
|
||||
? T[K] extends (...args: any[]) => ChainableFunctionResultOrAll
|
||||
? K
|
||||
: never
|
||||
: never]: T[K];
|
||||
};
|
||||
type EveryExecuteFunction<T> = {
|
||||
[K in keyof T as K extends `$every${string}`
|
||||
? T[K] extends (...args: any[]) => ChainableFunctionResult
|
||||
? K
|
||||
: never
|
||||
: never]: T[K];
|
||||
};
|
||||
type AnyExecuteFunction<T> = {
|
||||
[K in keyof T as K extends `$any${string}`
|
||||
? T[K] extends (...args: any[]) => ChainableFunctionResult
|
||||
? K
|
||||
: never
|
||||
: never]: T[K];
|
||||
};
|
||||
type InjectableFunction<T> = {
|
||||
[K in keyof T as K extends `$$${string}` ? (T[K] extends (...args: any[]) => any ? K : never) : never]: T[K];
|
||||
};
|
||||
export type AllExecuteProps = AllExecuteFunction<LiveSyncCore>;
|
||||
export type EveryExecuteProps = EveryExecuteFunction<LiveSyncCore>;
|
||||
export type AnyExecuteProps = AnyExecuteFunction<LiveSyncCore>;
|
||||
|
||||
export type AllInjectableProps = InjectableFunction<LiveSyncCore>;
|
||||
@@ -21,7 +21,7 @@ import { MARK_LOG_NETWORK_ERROR } from "@lib/services/lib/logUtils";
|
||||
|
||||
function isOnlineAndCanReplicate(
|
||||
errorManager: UnresolvedErrorManager,
|
||||
host: NecessaryServices<"API", any>,
|
||||
host: NecessaryServices<"API", never>,
|
||||
showMessage: boolean
|
||||
): Promise<boolean> {
|
||||
const errorMessage = "Network is offline";
|
||||
@@ -34,7 +34,7 @@ function isOnlineAndCanReplicate(
|
||||
}
|
||||
async function canReplicateWithPBKDF2(
|
||||
errorManager: UnresolvedErrorManager,
|
||||
host: NecessaryServices<"replicator" | "setting", any>,
|
||||
host: NecessaryServices<"replicator" | "setting", never>,
|
||||
showMessage: boolean
|
||||
): Promise<boolean> {
|
||||
const currentSettings = host.services.setting.currentSettings();
|
||||
|
||||
@@ -22,6 +22,7 @@ import { Semaphore } from "octagonal-wheels/concurrency/semaphore_v2";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
import type { ReactiveSource } from "octagonal-wheels/dataobject/reactive_v2";
|
||||
import type { LiveSyncBaseCore } from "@/LiveSyncBaseCore";
|
||||
import { isNotFoundError } from "@lib/common/utils.doc";
|
||||
|
||||
const KV_KEY_REPLICATION_RESULT_PROCESSOR_SNAPSHOT = "replicationResultProcessorSnapshot";
|
||||
type ReplicateResultProcessorState = {
|
||||
@@ -39,7 +40,7 @@ export class ReplicateResultProcessor {
|
||||
private log(message: string, level: LOG_LEVEL = LOG_LEVEL_INFO) {
|
||||
Logger(`[ReplicateResultProcessor] ${message}`, level);
|
||||
}
|
||||
private logError(e: any) {
|
||||
private logError(e: unknown) {
|
||||
Logger(e, LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
private replicator: ModuleReplicator;
|
||||
@@ -466,8 +467,8 @@ export class ReplicateResultProcessor {
|
||||
return false; // This means that the document already processed (While no conflict existed).
|
||||
}
|
||||
return true; // This mostly should not happen, but we have to process it just in case.
|
||||
} catch (e: any) {
|
||||
if ("status" in e && e.status == 404) {
|
||||
} catch (e) {
|
||||
if (isNotFoundError(e)) {
|
||||
// getRaw failed due to not existing, it may not be happened normally especially on replication.
|
||||
// If the process caused by some other reason, we **probably** have to process it.
|
||||
// Note that this is not a common case.
|
||||
|
||||
@@ -18,7 +18,7 @@ import type { InjectableServiceHub } from "@lib/services/InjectableServices.ts";
|
||||
import type { LiveSyncCore } from "@/main.ts";
|
||||
import { REMOTE_P2P } from "@lib/common/models/setting.const.ts";
|
||||
|
||||
function valueToString(value: any) {
|
||||
function valueToString(value: string | number | boolean | object | undefined): string {
|
||||
if (typeof value === "boolean") {
|
||||
return value ? "true" : "false";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ButtonComponent } from "@/deps.ts";
|
||||
import { App, FuzzySuggestModal, MarkdownRenderer, Modal, Plugin, Setting } from "@/deps.ts";
|
||||
import { App, FuzzySuggestModal, MarkdownRenderer, Modal, Plugin, Setting, Component } from "@/deps.ts";
|
||||
import { EVENT_PLUGIN_UNLOADED, eventHub } from "@/common/events.ts";
|
||||
import { compatGlobal, type CompatIntervalHandle } from "@lib/common/coreEnvFunctions.ts";
|
||||
|
||||
@@ -148,6 +148,7 @@ export class MessageBox<T extends readonly string[]> extends AutoClosableModal {
|
||||
wideButton: boolean;
|
||||
|
||||
onSubmit: (result: string | false) => void;
|
||||
component: Component = new Component();
|
||||
|
||||
constructor(
|
||||
plugin: Plugin,
|
||||
@@ -189,6 +190,7 @@ export class MessageBox<T extends readonly string[]> extends AutoClosableModal {
|
||||
}
|
||||
|
||||
override onOpen() {
|
||||
this.component.load();
|
||||
const { contentEl } = this;
|
||||
this.titleEl.setText(this.title);
|
||||
const div = contentEl.createDiv();
|
||||
@@ -196,7 +198,7 @@ export class MessageBox<T extends readonly string[]> extends AutoClosableModal {
|
||||
userSelect: "text",
|
||||
webkitUserSelect: "text",
|
||||
});
|
||||
void MarkdownRenderer.render(this.plugin.app, this.contentMd, div, "/", this.plugin);
|
||||
void MarkdownRenderer.render(this.plugin.app, this.contentMd, div, "/", this.component);
|
||||
const buttonSetting = new Setting(contentEl);
|
||||
const labelWrapper = contentEl.createDiv();
|
||||
labelWrapper.addClass("sls-dialogue-note-wrapper");
|
||||
@@ -254,6 +256,7 @@ export class MessageBox<T extends readonly string[]> extends AutoClosableModal {
|
||||
|
||||
override onClose() {
|
||||
super.onClose();
|
||||
this.component.unload();
|
||||
const { contentEl } = this;
|
||||
contentEl.empty();
|
||||
if (this.timer) {
|
||||
|
||||
@@ -80,7 +80,7 @@ export class ObsHttpHandler extends FetchHttpHandler {
|
||||
contentType = transformedHeaders["content-type"];
|
||||
}
|
||||
|
||||
let transformedBody: any = body;
|
||||
let transformedBody = body;
|
||||
if (ArrayBuffer.isView(body)) {
|
||||
transformedBody = new Uint8Array(body.buffer).buffer;
|
||||
}
|
||||
|
||||
@@ -36,10 +36,11 @@ export class ModuleObsidianEvents extends AbstractObsidianModule {
|
||||
this.services.appLifecycle.performRestart();
|
||||
}
|
||||
|
||||
initialCallback: any;
|
||||
initialCallback: (() => void) | undefined = undefined;
|
||||
|
||||
swapSaveCommand() {
|
||||
this._log("Modifying callback of the save command", LOG_LEVEL_VERBOSE);
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- Editor Tweaking
|
||||
const saveCommandDefinition = (this.app as any).commands?.commands?.["editor:save-file"];
|
||||
const save = saveCommandDefinition?.callback;
|
||||
if (typeof save === "function") {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import { delay, fireAndForget } from "octagonal-wheels/promises";
|
||||
import { delay } from "octagonal-wheels/promises";
|
||||
import { __onMissingTranslation } from "@lib/common/i18n";
|
||||
import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts";
|
||||
import { LOG_LEVEL_VERBOSE } from "octagonal-wheels/common/logger";
|
||||
import { eventHub } from "@/common/events";
|
||||
import { enableTestFunction } from "./devUtil/testUtils.ts";
|
||||
// import { enableTestFunction } from "./devUtil/testUtils.ts";
|
||||
import { TestPaneView, VIEW_TYPE_TEST } from "./devUtil/TestPaneView.ts";
|
||||
import { writable } from "svelte/store";
|
||||
import type { FilePathWithPrefix } from "@lib/common/types.ts";
|
||||
import type { LiveSyncCore } from "@/main.ts";
|
||||
import type { WorkspaceLeaf } from "@/deps.ts";
|
||||
export class ModuleDev extends AbstractObsidianModule {
|
||||
_everyOnloadStart(): Promise<boolean> {
|
||||
__onMissingTranslation(() => {});
|
||||
@@ -37,57 +37,7 @@ export class ModuleDev extends AbstractObsidianModule {
|
||||
|
||||
private _everyOnloadAfterLoadSettings(): Promise<boolean> {
|
||||
if (!this.settings.enableDebugTools) return Promise.resolve(true);
|
||||
this.onMissingTranslation = this.onMissingTranslation.bind(this);
|
||||
__onMissingTranslation((key) => {
|
||||
void this.onMissingTranslation(key);
|
||||
});
|
||||
type STUB = {
|
||||
toc: Set<string>;
|
||||
stub: { [key: string]: { [key: string]: Map<string, Record<string, string>> } };
|
||||
};
|
||||
eventHub.onEvent("document-stub-created", (detail: STUB) => {
|
||||
fireAndForget(async () => {
|
||||
const stub = detail.stub;
|
||||
const toc = detail.toc;
|
||||
|
||||
const stubDocX = Object.entries(stub)
|
||||
.map(([key, value]) => {
|
||||
return [
|
||||
`## ${key}`,
|
||||
Object.entries(value)
|
||||
.map(([key2, value2]) => {
|
||||
return [
|
||||
`### ${key2}`,
|
||||
[...value2.entries()].map(([key3, value3]) => {
|
||||
// return `#### ${key3}` + "\n" + JSON.stringify(value3);
|
||||
const isObsolete = value3["is_obsolete"] ? " (obsolete)" : "";
|
||||
const desc = value3["desc"] ?? "";
|
||||
const key = value3["key"] ? "Setting key: " + value3["key"] + "\n" : "";
|
||||
return `#### ${key3}${isObsolete}\n${key}${desc}\n`;
|
||||
}),
|
||||
].flat();
|
||||
})
|
||||
.flat(),
|
||||
].flat();
|
||||
})
|
||||
.flat();
|
||||
const stubDocMD =
|
||||
`
|
||||
| Icon | Description |
|
||||
| :---: | ----------------------------------------------------------------- |
|
||||
` +
|
||||
[...toc.values()].map((e) => `${e}`).join("\n") +
|
||||
"\n\n" +
|
||||
stubDocX.join("\n");
|
||||
await this.core.storageAccess.writeHiddenFileAuto(
|
||||
this.app.vault.configDir + "/ls-debug/stub-doc.md",
|
||||
stubDocMD
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
enableTestFunction(this.plugin);
|
||||
this.registerView(VIEW_TYPE_TEST, (leaf) => new TestPaneView(leaf, this.plugin, this));
|
||||
this.registerView(VIEW_TYPE_TEST, (leaf: WorkspaceLeaf) => new TestPaneView(leaf, this.plugin, this));
|
||||
this.addCommand({
|
||||
id: "view-test",
|
||||
name: "Open Test dialogue",
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
import { fireAndForget } from "@lib/common/utils.ts";
|
||||
import { serialized } from "octagonal-wheels/concurrency/lock";
|
||||
import type ObsidianLiveSyncPlugin from "@/main.ts";
|
||||
|
||||
let plugin: ObsidianLiveSyncPlugin;
|
||||
export function enableTestFunction(plugin_: ObsidianLiveSyncPlugin) {
|
||||
plugin = plugin_;
|
||||
}
|
||||
export function addDebugFileLog(message: any, stackLog = false) {
|
||||
fireAndForget(
|
||||
serialized("debug-log", async () => {
|
||||
const now = new Date();
|
||||
const filename = `debug-log`;
|
||||
const time = now.toISOString().split("T")[0];
|
||||
const outFile = `${filename}${time}.jsonl`;
|
||||
// const messageContent = typeof message == "string" ? message : message instanceof Error ? `${message.name}:${message.message}` : JSON.stringify(message, null, 2);
|
||||
const timestamp = now.toLocaleString();
|
||||
const timestampEpoch = now;
|
||||
let out = { timestamp: timestamp, epoch: timestampEpoch } as Record<string, any>;
|
||||
if (message instanceof Error) {
|
||||
// debugger;
|
||||
// console.dir(message.stack);
|
||||
out = { ...out, message };
|
||||
} else if (stackLog) {
|
||||
if (stackLog) {
|
||||
const stackE = new Error();
|
||||
const stack = stackE.stack;
|
||||
out = { ...out, stack };
|
||||
}
|
||||
}
|
||||
if (typeof message == "object") {
|
||||
out = { ...out, ...message };
|
||||
} else {
|
||||
out = {
|
||||
result: message,
|
||||
};
|
||||
}
|
||||
// const out = "--" + timestamp + "--\n" + messageContent + " " + (stack || "");
|
||||
// const out
|
||||
try {
|
||||
await plugin.core.storageAccess.appendHiddenFile(
|
||||
plugin.core.services.API.getSystemConfigDir() + "/ls-debug/" + outFile,
|
||||
JSON.stringify(out) + "\n"
|
||||
);
|
||||
} catch {
|
||||
//NO OP
|
||||
}
|
||||
})
|
||||
);
|
||||
}
|
||||
@@ -99,9 +99,11 @@ export class DocumentHistoryModal extends Modal {
|
||||
if (!file && id) {
|
||||
this.file = this.services.path.id2path(id);
|
||||
}
|
||||
// eslint-disable-next-line obsidianmd/no-unsupported-api -- loadLocalStorage is supported in Obsidian 1.7.2+
|
||||
if (this.app.loadLocalStorage("ols-history-highlightdiff") == "1") {
|
||||
this.showDiff = true;
|
||||
}
|
||||
// eslint-disable-next-line obsidianmd/no-unsupported-api -- loadLocalStorage is supported in Obsidian 1.7.2+
|
||||
if (this.app.loadLocalStorage("ols-history-diffonly") == "1") {
|
||||
this.diffOnly = true;
|
||||
}
|
||||
@@ -139,7 +141,7 @@ export class DocumentHistoryModal extends Modal {
|
||||
this.range.value = `${this.revs_info.length - 1 - rIndex}`;
|
||||
}
|
||||
}
|
||||
const index = this.revs_info.length - 1 - (this.range.value as any) / 1;
|
||||
const index = this.revs_info.length - 1 - (Number(this.range.value) || 0);
|
||||
const rev = this.revs_info[index];
|
||||
await this.showExactRev(rev.rev);
|
||||
}
|
||||
@@ -251,7 +253,7 @@ export class DocumentHistoryModal extends Modal {
|
||||
}
|
||||
let rendered = false;
|
||||
if (this.showDiff) {
|
||||
const prevRevIdx = this.revs_info.length - 1 - ((this.range.value as any) / 1 - 1);
|
||||
const prevRevIdx = this.revs_info.length - 1 - ((Number(this.range.value) || 0) - 1);
|
||||
if (prevRevIdx >= 0 && prevRevIdx < this.revs_info.length) {
|
||||
const oldRev = this.revs_info[prevRevIdx].rev;
|
||||
const w2 = await db.getDBEntry(this.file, { rev: oldRev }, false, false, true);
|
||||
@@ -550,8 +552,9 @@ export class DocumentHistoryModal extends Modal {
|
||||
if (this.showDiff) {
|
||||
checkbox.checked = true;
|
||||
}
|
||||
checkbox.addEventListener("input", (evt: any) => {
|
||||
checkbox.addEventListener("input", (evt: Event) => {
|
||||
this.showDiff = checkbox.checked;
|
||||
// eslint-disable-next-line obsidianmd/no-unsupported-api -- saveLocalStorage is supported in Obsidian 1.7.2+
|
||||
this.app.saveLocalStorage("ols-history-highlightdiff", this.showDiff == true ? "1" : null);
|
||||
this.updateDiffNavVisibility();
|
||||
void scheduleOnceIfDuplicated("loadRevs", () => this.loadRevs());
|
||||
@@ -565,8 +568,9 @@ export class DocumentHistoryModal extends Modal {
|
||||
if (this.diffOnly) {
|
||||
checkbox.checked = true;
|
||||
}
|
||||
checkbox.addEventListener("input", (evt: any) => {
|
||||
checkbox.addEventListener("input", (evt: Event) => {
|
||||
this.diffOnly = checkbox.checked;
|
||||
// eslint-disable-next-line obsidianmd/no-unsupported-api -- saveLocalStorage is supported in Obsidian 1.7.2+
|
||||
this.app.saveLocalStorage("ols-history-diffonly", this.diffOnly == true ? "1" : null);
|
||||
void scheduleOnceIfDuplicated("loadRevs", () => this.loadRevs());
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { AbstractObsidianModule } from "@/modules/AbstractObsidianModule.ts";
|
||||
import { VIEW_TYPE_GLOBAL_HISTORY, GlobalHistoryView } from "./GlobalHistory/GlobalHistoryView.ts";
|
||||
import type { WorkspaceLeaf } from "@/deps.ts";
|
||||
|
||||
export class ModuleObsidianGlobalHistory extends AbstractObsidianModule {
|
||||
_everyOnloadStart(): Promise<boolean> {
|
||||
@@ -11,7 +12,7 @@ export class ModuleObsidianGlobalHistory extends AbstractObsidianModule {
|
||||
},
|
||||
});
|
||||
|
||||
this.registerView(VIEW_TYPE_GLOBAL_HISTORY, (leaf) => new GlobalHistoryView(leaf, this.plugin));
|
||||
this.registerView(VIEW_TYPE_GLOBAL_HISTORY, (leaf: WorkspaceLeaf) => new GlobalHistoryView(leaf, this.plugin));
|
||||
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
|
||||
@@ -48,7 +48,7 @@ import { generateReport } from "@/common/reportTool.ts";
|
||||
|
||||
// DI the log again.
|
||||
const recentLogEntries = reactiveSource<LogEntry[]>([]);
|
||||
const globalLogFunction = (message: any, level?: number, key?: string) => {
|
||||
const globalLogFunction = (message: unknown, level?: number, key?: string) => {
|
||||
const messageX =
|
||||
message instanceof Error
|
||||
? new LiveSyncError("[Error Logged]: " + message.message, { cause: message })
|
||||
@@ -501,7 +501,7 @@ ${stringifyYaml(info)}
|
||||
})
|
||||
);
|
||||
}
|
||||
__addLog(message: any, level: LOG_LEVEL = LOG_LEVEL_INFO, key = ""): void {
|
||||
__addLog(message: unknown, level: LOG_LEVEL = LOG_LEVEL_INFO, key = ""): void {
|
||||
if (level == LOG_LEVEL_DEBUG && !showDebugLog) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,7 @@ import {
|
||||
} from "@/deps.ts";
|
||||
import { unique } from "octagonal-wheels/collection";
|
||||
import { LEVEL_ADVANCED, LEVEL_POWER_USER, statusDisplay, type ConfigurationItem } from "@lib/common/types.ts";
|
||||
import { createStub, type ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import { type ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import {
|
||||
type AllSettingItemKey,
|
||||
getConfig,
|
||||
@@ -19,7 +19,7 @@ import {
|
||||
type AllBooleanItemKey,
|
||||
} from "./settingConstants.ts";
|
||||
import { $msg } from "@lib/common/i18n.ts";
|
||||
import { findAttrFromParent, wrapMemo, type AutoWireOption, type OnUpdateResult } from "./SettingPane.ts";
|
||||
import { wrapMemo, type AutoWireOption, type OnUpdateResult } from "./SettingPane.ts";
|
||||
|
||||
export class LiveSyncSetting extends Setting {
|
||||
autoWiredComponent?: TextComponent | ToggleComponent | DropdownComponent | ButtonComponent | TextAreaComponent;
|
||||
@@ -35,37 +35,19 @@ export class LiveSyncSetting extends Setting {
|
||||
hasPassword: boolean = false;
|
||||
|
||||
invalidateValue?: () => void;
|
||||
setValue?: (value: any) => void;
|
||||
setValue?: (value: unknown) => void;
|
||||
constructor(containerEl: HTMLElement) {
|
||||
super(containerEl);
|
||||
LiveSyncSetting.env.settingComponents.push(this);
|
||||
}
|
||||
|
||||
_createDocStub(key: string, value: string | DocumentFragment) {
|
||||
DEV: {
|
||||
const paneName = findAttrFromParent(this.settingEl, "data-pane");
|
||||
const panelName = findAttrFromParent(this.settingEl, "data-panel");
|
||||
const itemName =
|
||||
typeof this.nameBuf == "string" ? this.nameBuf : (this.nameBuf.textContent?.toString() ?? "");
|
||||
const strValue = typeof value == "string" ? value : (value.textContent?.toString() ?? "");
|
||||
|
||||
createStub(itemName, key, strValue, panelName, paneName);
|
||||
}
|
||||
}
|
||||
|
||||
override setDesc(desc: string | DocumentFragment): this {
|
||||
this.descBuf = desc;
|
||||
DEV: {
|
||||
this._createDocStub("desc", desc);
|
||||
}
|
||||
super.setDesc(desc);
|
||||
return this;
|
||||
}
|
||||
override setName(name: string | DocumentFragment): this {
|
||||
this.nameBuf = name;
|
||||
DEV: {
|
||||
this._createDocStub("name", name);
|
||||
}
|
||||
super.setName(name);
|
||||
return this;
|
||||
}
|
||||
@@ -84,11 +66,6 @@ export class LiveSyncSetting extends Setting {
|
||||
if (conf.desc) {
|
||||
this.setDesc(conf.desc);
|
||||
}
|
||||
DEV: {
|
||||
this._createDocStub("key", key);
|
||||
if (conf.obsolete) this._createDocStub("is_obsolete", "true");
|
||||
if (conf.level) this._createDocStub("level", conf.level);
|
||||
}
|
||||
|
||||
this.holdValue = opt?.holdValue || this.holdValue;
|
||||
this.selfKey = key;
|
||||
@@ -102,7 +79,7 @@ export class LiveSyncSetting extends Setting {
|
||||
}
|
||||
return conf;
|
||||
}
|
||||
autoWireComponent(component: ValueComponent<any>, conf?: ConfigurationItem, opt?: AutoWireOption) {
|
||||
autoWireComponent<T>(component: ValueComponent<T>, conf?: ConfigurationItem, opt?: AutoWireOption) {
|
||||
this.placeHolderBuf = conf?.placeHolder || opt?.placeHolder || "";
|
||||
if (conf?.level == LEVEL_ADVANCED) {
|
||||
this.settingEl.toggleClass("sls-setting-advanced", true);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { App, PluginSettingTab } from "@/deps.ts";
|
||||
import { App, Component, PluginSettingTab } from "@/deps.ts";
|
||||
import {
|
||||
type ObsidianLiveSyncSettings,
|
||||
type RemoteDBSettings,
|
||||
@@ -40,12 +40,13 @@ import { JournalSyncMinio } from "@lib/replication/journal/objectstore/JournalSy
|
||||
import { paneChangeLog } from "./PaneChangeLog.ts";
|
||||
import {
|
||||
enableOnly,
|
||||
findAttrFromParent,
|
||||
getLevelStr,
|
||||
// findAttrFromParent,
|
||||
// getLevelStr,
|
||||
setLevelClass,
|
||||
setStyle,
|
||||
visibleOnly,
|
||||
type OnSavedHandler,
|
||||
type OnSavedHandlerFunc,
|
||||
type OnUpdateFunc,
|
||||
type OnUpdateResult,
|
||||
type PageFunctions,
|
||||
@@ -65,28 +66,14 @@ import { paneMaintenance } from "./PaneMaintenance.ts";
|
||||
import { compatGlobal } from "@lib/common/coreEnvFunctions.ts";
|
||||
|
||||
// For creating a document
|
||||
const toc = new Set<string>();
|
||||
const stubs = {} as {
|
||||
[key: string]: { [key: string]: Map<string, Record<string, string>> };
|
||||
};
|
||||
export function createStub(name: string, key: string, value: string, panel: string, pane: string) {
|
||||
DEV: {
|
||||
if (!(pane in stubs)) {
|
||||
stubs[pane] = {};
|
||||
}
|
||||
if (!(panel in stubs[pane])) {
|
||||
stubs[pane][panel] = new Map<string, Record<string, string>>();
|
||||
}
|
||||
const old = stubs[pane][panel].get(name) ?? {};
|
||||
stubs[pane][panel].set(name, { ...old, [key]: value });
|
||||
scheduleTask("update-stub", 100, () => {
|
||||
eventHub.emitEvent("document-stub-created", { toc: toc, stub: stubs });
|
||||
});
|
||||
}
|
||||
}
|
||||
// const toc = new Set<string>();
|
||||
|
||||
export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
plugin: ObsidianLiveSyncPlugin;
|
||||
private _lifetimeComponent: Component = new Component();
|
||||
get lifetimeComponent(): Component {
|
||||
return this._lifetimeComponent;
|
||||
}
|
||||
get core() {
|
||||
return this.plugin.core;
|
||||
}
|
||||
@@ -181,7 +168,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
// if (runOnSaved) {
|
||||
const handlers = this.onSavedHandlers
|
||||
.filter((e) => appliedKeys.indexOf(e.key) !== -1)
|
||||
.map((e) => Promise.resolve(e.handler(this.editingSettings[e.key as AllSettingItemKey])));
|
||||
.map((e) => Promise.resolve(e.handler(this.editingSettings[e.key])));
|
||||
await Promise.all(handlers);
|
||||
// }
|
||||
keys.forEach((e) => this.refreshSetting(e));
|
||||
@@ -287,7 +274,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
// UI Element Wrapper -->
|
||||
settingComponents = [] as Setting[];
|
||||
controlledElementFunc = [] as UpdateFunction[];
|
||||
onSavedHandlers = [] as OnSavedHandler<any>[];
|
||||
onSavedHandlers = [] as OnSavedHandler<AllSettingItemKey>[];
|
||||
|
||||
inWizard: boolean = false;
|
||||
|
||||
@@ -370,8 +357,9 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
return Promise.resolve(elm);
|
||||
}
|
||||
|
||||
addOnSaved<T extends AllSettingItemKey>(key: T, func: (value: AllSettings[T]) => Promise<void> | void) {
|
||||
this.onSavedHandlers.push({ key, handler: func });
|
||||
addOnSaved<T extends AllSettingItemKey>(key: T, func: OnSavedHandlerFunc<T>) {
|
||||
const newHandler = { key, handler: func } as OnSavedHandler<AllSettingItemKey>;
|
||||
this.onSavedHandlers.push(newHandler);
|
||||
}
|
||||
resetEditingSettings() {
|
||||
this._editingSettings = undefined;
|
||||
@@ -379,6 +367,8 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
}
|
||||
|
||||
override hide() {
|
||||
super.hide();
|
||||
this._lifetimeComponent.unload();
|
||||
this.isShown = false;
|
||||
}
|
||||
isShown: boolean = false;
|
||||
@@ -663,8 +653,10 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
}
|
||||
}
|
||||
|
||||
display(): void {
|
||||
override display(): void {
|
||||
const changeDisplay = this.changeDisplay.bind(this);
|
||||
// Make sure lifetime component is loaded for markdown rendering in panes.
|
||||
this._lifetimeComponent.load();
|
||||
const { containerEl } = this;
|
||||
this.settingComponents.length = 0;
|
||||
this.controlledElementFunc.length = 0;
|
||||
@@ -718,7 +710,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
visibleOnly(() => this.isNeedRebuildLocal() || this.isNeedRebuildRemote())
|
||||
);
|
||||
|
||||
let paneNo = 0;
|
||||
// let paneNo = 0;
|
||||
const addPane = (
|
||||
parentEl: HTMLElement,
|
||||
title: string,
|
||||
@@ -728,20 +720,9 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
level?: ConfigLevel
|
||||
) => {
|
||||
const el = this.createEl(parentEl, "div", { text: "" });
|
||||
DEV: {
|
||||
const mdTitle = `${paneNo++}. ${title}${getLevelStr(level ?? "")}`;
|
||||
el.setAttribute("data-pane", mdTitle);
|
||||
toc.add(
|
||||
`| ${icon} | [${mdTitle}](#${mdTitle
|
||||
.toLowerCase()
|
||||
.replace(/ /g, "-")
|
||||
.replace(/[^\w\s-]/g, "")}) | `
|
||||
);
|
||||
}
|
||||
|
||||
setLevelClass(el, level);
|
||||
// TODO: Refactor to use Obsidian's recommended way to create heading.
|
||||
// eslint-disable-next-line obsidianmd/settings-tab/no-manual-html-headings
|
||||
el.createEl("h3", { text: title, cls: "sls-setting-pane-title" });
|
||||
new Setting(el).setName(title).setHeading().setClass("sls-setting-pane-title");
|
||||
if (this.menuEl) {
|
||||
this.menuEl.createEl(
|
||||
"label",
|
||||
@@ -772,7 +753,7 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
// });
|
||||
return p;
|
||||
};
|
||||
const panelNoMap = {} as { [key: string]: number };
|
||||
// const panelNoMap = {} as { [key: string]: number };
|
||||
const addPanel = (
|
||||
parentEl: HTMLElement,
|
||||
title: string,
|
||||
@@ -781,15 +762,6 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
level?: ConfigLevel
|
||||
) => {
|
||||
const el = this.createEl(parentEl, "div", { text: "" }, callback, func);
|
||||
DEV: {
|
||||
const paneNo = findAttrFromParent(parentEl, "data-pane");
|
||||
if (!(paneNo in panelNoMap)) {
|
||||
panelNoMap[paneNo] = 0;
|
||||
}
|
||||
panelNoMap[paneNo] += 1;
|
||||
const panelNo = panelNoMap[paneNo];
|
||||
el.setAttribute("data-panel", `${panelNo}. ${title}${getLevelStr(level ?? "")}`);
|
||||
}
|
||||
setLevelClass(el, level);
|
||||
this.createEl(el, "h4", { text: title, cls: "sls-setting-panel-title" });
|
||||
const p = Promise.resolve(el);
|
||||
@@ -823,6 +795,9 @@ export class ObsidianLiveSyncSettingTab extends PluginSettingTab {
|
||||
return callback;
|
||||
};
|
||||
|
||||
// Add panes
|
||||
|
||||
// TODO: Refactor to new API style.
|
||||
void addPane(containerEl, $msg("obsidianLiveSyncSettingTab.panelChangeLog"), "💬", 100, false).then(
|
||||
bindPane(paneChangeLog)
|
||||
);
|
||||
|
||||
@@ -20,7 +20,6 @@ export function paneChangeLog(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElem
|
||||
undefined,
|
||||
visibleOnly(() => !this.isConfiguredAs("versionUpFlash", ""))
|
||||
);
|
||||
|
||||
this.createEl(
|
||||
cx,
|
||||
"div",
|
||||
@@ -58,6 +57,6 @@ export function paneChangeLog(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElem
|
||||
});
|
||||
}
|
||||
fireAndForget(() =>
|
||||
MarkdownRenderer.render(this.plugin.app, updateInformation, informationDivEl, "/", this.plugin)
|
||||
MarkdownRenderer.render(this.plugin.app, updateInformation, informationDivEl, "/", this.lifetimeComponent)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
type LoadedEntry,
|
||||
type MetaEntry,
|
||||
type FilePath,
|
||||
type EntryDoc,
|
||||
} from "@lib/common/types.ts";
|
||||
import { createBlob, getFileRegExp, isDocContentSame, readAsBlob } from "@lib/common/utils.ts";
|
||||
import { Logger } from "@lib/common/logger.ts";
|
||||
@@ -441,8 +442,8 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
const newData = entriesToDelete.rows.map((e) => ({
|
||||
...e.doc,
|
||||
_deleted: true,
|
||||
}));
|
||||
const r = await this.core.localDatabase.bulkDocsRaw(newData as any[]);
|
||||
})) as EntryDoc[];
|
||||
const r = await this.core.localDatabase.bulkDocsRaw(newData);
|
||||
// Do not care about the result.
|
||||
Logger(
|
||||
`${r.length} items have been removed, to confirm how many items are left, please perform it again.`,
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
type ObsidianLiveSyncSettings,
|
||||
LOG_LEVEL_VERBOSE,
|
||||
} from "@lib/common/types.ts";
|
||||
import { Menu } from "@/deps.ts";
|
||||
import { Menu, type ButtonComponent } from "@/deps.ts";
|
||||
import { $msg } from "@lib/common/i18n.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
@@ -37,9 +37,9 @@ import { syncActivatedRemoteSettings } from "./remoteConfigBuffer.ts";
|
||||
|
||||
function getSettingsFromEditingSettings(editingSettings: AllSettings): ObsidianLiveSyncSettings {
|
||||
const workObj = { ...editingSettings } as ObsidianLiveSyncSettings;
|
||||
const keys = Object.keys(OnDialogSettingsDefault);
|
||||
const keys = Object.keys(OnDialogSettingsDefault) as (keyof ObsidianLiveSyncSettings)[];
|
||||
for (const k of keys) {
|
||||
delete (workObj as any)[k];
|
||||
delete workObj[k];
|
||||
}
|
||||
return workObj;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ function serializeRemoteConfiguration(settings: ObsidianLiveSyncSettings): strin
|
||||
return ConnectionStringParser.serialize({ type: "couchdb", settings });
|
||||
}
|
||||
|
||||
function setEmojiButton(button: any, emoji: string, tooltip: string) {
|
||||
function setEmojiButton(button: ButtonComponent, emoji: string, tooltip: string) {
|
||||
button.setButtonText(emoji);
|
||||
button.setTooltip(tooltip, { delay: 10, placement: "top" });
|
||||
// button.buttonEl.addClass("clickable-icon");
|
||||
|
||||
@@ -14,6 +14,7 @@ import { visibleOnly } from "./SettingPane.ts";
|
||||
import { DEFAULT_SETTINGS } from "@lib/common/types.ts";
|
||||
import { request } from "@/deps.ts";
|
||||
import { SetupManager, UserMode } from "@/modules/features/SetupManager.ts";
|
||||
import { LiveSyncError } from "@lib/common/LSError.ts";
|
||||
export function paneSetup(
|
||||
this: ObsidianLiveSyncSettingTab,
|
||||
paneEl: HTMLElement,
|
||||
@@ -145,8 +146,9 @@ export function paneSetup(
|
||||
let remoteTroubleShootMDSrc = "";
|
||||
try {
|
||||
remoteTroubleShootMDSrc = await request(`${rawRepoURI}${basePath}/${filename}`);
|
||||
} catch (ex: any) {
|
||||
remoteTroubleShootMDSrc = `${$msg("obsidianLiveSyncSettingTab.logErrorOccurred")}\n${ex.toString()}`;
|
||||
} catch (ex) {
|
||||
const err = LiveSyncError.fromError(ex);
|
||||
remoteTroubleShootMDSrc = `${$msg("obsidianLiveSyncSettingTab.logErrorOccurred")}\n${err.toString()}`;
|
||||
}
|
||||
const remoteTroubleShootMD = remoteTroubleShootMDSrc.replace(
|
||||
/\((.*?(.png)|(.jpg))\)/g,
|
||||
@@ -158,7 +160,7 @@ export function paneSetup(
|
||||
`<a class='sls-troubleshoot-anchor'></a> [${$msg("obsidianLiveSyncSettingTab.linkTipsAndTroubleshooting")}](${topPath}) [${$msg("obsidianLiveSyncSettingTab.linkPageTop")}](${filename})\n\n${remoteTroubleShootMD}`,
|
||||
troubleShootEl,
|
||||
`${rawRepoURI}`,
|
||||
this.plugin
|
||||
this.lifetimeComponent
|
||||
);
|
||||
// Menu
|
||||
troubleShootEl.querySelector<HTMLAnchorElement>(".sls-troubleshoot-anchor")?.parentElement?.setCssStyles({
|
||||
|
||||
@@ -5,7 +5,7 @@ import { type Writable, writable, get } from "svelte/store";
|
||||
* Props passed to Svelte panels, containing a writable port
|
||||
* to communicate with the panel
|
||||
*/
|
||||
export type SveltePanelProps<T = any> = {
|
||||
export type SveltePanelProps<T = unknown> = {
|
||||
port: Writable<T | undefined>;
|
||||
};
|
||||
|
||||
@@ -13,7 +13,7 @@ export type SveltePanelProps<T = any> = {
|
||||
* A class to manage a Svelte panel within Obsidian
|
||||
* Especially useful for settings panels
|
||||
*/
|
||||
export class SveltePanel<T = any> {
|
||||
export class SveltePanel<T = unknown> {
|
||||
private _mountedComponent: ReturnType<typeof mount>;
|
||||
private _componentValue = writable<T | undefined>(undefined);
|
||||
/**
|
||||
|
||||
@@ -8,6 +8,7 @@ import {
|
||||
} from "@lib/common/utils";
|
||||
import { getConfig, type AllSettingItemKey } from "./settingConstants";
|
||||
import { LOG_LEVEL_NOTICE, Logger } from "octagonal-wheels/common/logger";
|
||||
import { isNotFoundError } from "@lib/common/utils.doc";
|
||||
|
||||
/**
|
||||
* Generates a summary of P2P configuration settings
|
||||
@@ -90,10 +91,10 @@ export function getSummaryFromPartialSettings(setting: Partial<ObsidianLiveSyncS
|
||||
export async function copyMigrationDocs(docName: string, dbFrom: PouchDB.Database, dbTo: PouchDB.Database) {
|
||||
try {
|
||||
const doc = await dbFrom.get(docName);
|
||||
delete (doc as any)._rev;
|
||||
delete (doc as { _rev?: string })._rev;
|
||||
await dbTo.put(doc);
|
||||
} catch (e) {
|
||||
if ((e as any).status === 404) {
|
||||
if (isNotFoundError(e)) {
|
||||
return;
|
||||
}
|
||||
throw e;
|
||||
|
||||
@@ -6,6 +6,7 @@ import { fireAndForget, parseHeaderValues } from "@lib/common/utils";
|
||||
import { isCloudantURI } from "@lib/pouchdb/utils_couchdb";
|
||||
import { generateCredentialObject } from "@lib/replication/httplib";
|
||||
import { compatGlobal } from "@lib/common/coreEnvFunctions.ts";
|
||||
import { isUnauthorizedError } from "@lib/common/utils.doc";
|
||||
|
||||
export const checkConfig = async (
|
||||
checkResultDiv: HTMLDivElement | undefined,
|
||||
@@ -260,8 +261,8 @@ export const checkConfig = async (
|
||||
addResult($msg("obsidianLiveSyncSettingTab.msgDone"), ["ob-btn-config-head"]);
|
||||
addResult($msg("obsidianLiveSyncSettingTab.msgConnectionProxyNote"), ["ob-btn-config-info"]);
|
||||
Logger($msg("obsidianLiveSyncSettingTab.logCheckingConfigDone"), LOG_LEVEL_INFO);
|
||||
} catch (ex: any) {
|
||||
if (ex?.status == 401) {
|
||||
} catch (ex) {
|
||||
if (isUnauthorizedError(ex)) {
|
||||
isSuccessful = false;
|
||||
addResult($msg("obsidianLiveSyncSettingTab.errAccessForbidden"));
|
||||
addResult($msg("obsidianLiveSyncSettingTab.errCannotContinueTest"));
|
||||
|
||||
@@ -22,17 +22,17 @@
|
||||
detectedIssues.push({ message: `Error during testAndFixSettings: ${e}`, result: "error", classes: [] });
|
||||
}
|
||||
}
|
||||
function isErrorResult(result: ConfigCheckResult): result is ResultError | ResultErrorMessage {
|
||||
function isErrorResult(result: ConfigCheckResult): result is ResultError<unknown> | ResultErrorMessage {
|
||||
return "result" in result && result.result === "error";
|
||||
}
|
||||
function isFixableError(result: ConfigCheckResult): result is ResultError {
|
||||
function isFixableError(result: ConfigCheckResult): result is ResultError<unknown> {
|
||||
return isErrorResult(result) && "fix" in result && typeof result.fix === "function";
|
||||
}
|
||||
function isSuccessResult(result: ConfigCheckResult): result is { message: string; result: "ok"; value?: any } {
|
||||
return "result" in result && result.result === "ok";
|
||||
}
|
||||
let processing = $state(false);
|
||||
async function fixIssue(issue: ResultError) {
|
||||
async function fixIssue(issue: ResultError<unknown>) {
|
||||
try {
|
||||
processing = true;
|
||||
await issue.fix();
|
||||
|
||||
@@ -6,12 +6,17 @@ import { parseHeaderValues } from "@lib/common/utils";
|
||||
import { isCloudantURI } from "@lib/pouchdb/utils_couchdb";
|
||||
import { generateCredentialObject } from "@lib/replication/httplib";
|
||||
import { compatGlobal } from "@lib/common/coreEnvFunctions.ts";
|
||||
import { isUnauthorizedError } from "@lib/common/utils.doc";
|
||||
|
||||
export type ResultMessage = { message: string; classes: string[] };
|
||||
export type ResultErrorMessage = { message: string; result: "error"; classes: string[] };
|
||||
export type ResultOk = { message: string; result: "ok"; value?: any };
|
||||
export type ResultError = { message: string; result: "error"; value: any; fixMessage: string; fix(): Promise<void> };
|
||||
export type ConfigCheckResult = ResultOk | ResultError | ResultMessage | ResultErrorMessage;
|
||||
export type ResultOk<T> = { message: string; result: "ok"; value?: T };
|
||||
export type ResultError<T> = { message: string; result: "error"; value: T; fixMessage: string; fix(): Promise<void> };
|
||||
export type ConfigCheckResult<T = unknown, U = unknown> =
|
||||
| ResultOk<T>
|
||||
| ResultError<U>
|
||||
| ResultMessage
|
||||
| ResultErrorMessage;
|
||||
/**
|
||||
* Compares two version strings to determine if the baseVersion is greater than or equal to the version.
|
||||
* @param baseVersion a.b.c format
|
||||
@@ -37,7 +42,11 @@ function isGreaterThanOrEqual(baseVersion: string, version: string) {
|
||||
* @param value setting value to update
|
||||
* @returns true if the update was successful, false otherwise
|
||||
*/
|
||||
async function updateRemoteSetting(setting: ObsidianLiveSyncSettings, key: string, value: any) {
|
||||
async function updateRemoteSetting(
|
||||
setting: ObsidianLiveSyncSettings,
|
||||
key: string,
|
||||
value: string
|
||||
): Promise<true | string> {
|
||||
const customHeaders = parseHeaderValues(setting.couchDB_CustomHeaders);
|
||||
const credential = generateCredentialObject(setting);
|
||||
const res = await requestToCouchDBWithCredentials(
|
||||
@@ -62,24 +71,29 @@ async function updateRemoteSetting(setting: ObsidianLiveSyncSettings, key: strin
|
||||
* @returns Array of ConfigCheckResult
|
||||
*/
|
||||
export const checkConfig = async (editingSettings: ObsidianLiveSyncSettings) => {
|
||||
const result = [] as ConfigCheckResult[];
|
||||
const result = [] as ConfigCheckResult<unknown, unknown>[];
|
||||
const addMessage = (msg: string, classes: string[] = []) => {
|
||||
result.push({ message: msg, classes });
|
||||
};
|
||||
const addSuccess = (msg: string, value?: any) => {
|
||||
const addSuccess = <T>(msg: string, value?: T) => {
|
||||
result.push({ message: msg, result: "ok", value });
|
||||
};
|
||||
const _addError = (message: string, fixMessage: string, fix: () => Promise<void>, value?: any) => {
|
||||
const _addError = <T>(message: string, fixMessage: string, fix: () => Promise<void>, value?: T) => {
|
||||
result.push({ message, result: "error", fixMessage, fix, value });
|
||||
};
|
||||
const addErrorMessage = (msg: string, classes: string[] = []) => {
|
||||
result.push({ message: msg, result: "error", classes });
|
||||
};
|
||||
|
||||
const addError = (message: string, fixMessage: string, key: string, expected: any) => {
|
||||
_addError(message, fixMessage, async () => {
|
||||
await updateRemoteSetting(editingSettings, key, expected);
|
||||
});
|
||||
const addError = (message: string, fixMessage: string, key: string, expected: string) => {
|
||||
_addError(
|
||||
message,
|
||||
fixMessage,
|
||||
async () => {
|
||||
await updateRemoteSetting(editingSettings, key, expected);
|
||||
},
|
||||
expected
|
||||
);
|
||||
};
|
||||
|
||||
addMessage($msg("obsidianLiveSyncSettingTab.logCheckingDbConfig"));
|
||||
@@ -281,8 +295,8 @@ export const checkConfig = async (editingSettings: ObsidianLiveSyncSettings) =>
|
||||
addMessage($msg("obsidianLiveSyncSettingTab.msgDone"), ["ob-btn-config-head"]);
|
||||
addMessage($msg("obsidianLiveSyncSettingTab.msgConnectionProxyNote"), ["ob-btn-config-info"]);
|
||||
addMessage($msg("obsidianLiveSyncSettingTab.logCheckingConfigDone"));
|
||||
} catch (ex: any) {
|
||||
if (ex?.status == 401) {
|
||||
} catch (ex) {
|
||||
if (isUnauthorizedError(ex)) {
|
||||
addErrorMessage($msg("obsidianLiveSyncSettingTab.errAccessForbidden"));
|
||||
addErrorMessage($msg("obsidianLiveSyncSettingTab.errCannotContinueTest"));
|
||||
addMessage($msg("obsidianLiveSyncSettingTab.logCheckingConfigDone"));
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { InjectableAPIService } from "@lib/services/implements/injectable/InjectableAPIService";
|
||||
import type { ObsidianServiceContext } from "@lib/services/implements/obsidian/ObsidianServiceContext";
|
||||
import { Platform, type Command, type ViewCreator } from "obsidian";
|
||||
import { Platform, type Command, type ViewCreator } from "@/deps.ts";
|
||||
import { ObsHttpHandler } from "@/modules/essentialObsidian/APILib/ObsHttpHandler";
|
||||
import { ObsidianConfirm } from "./ObsidianConfirm";
|
||||
import type { Confirm } from "@lib/interfaces/Confirm";
|
||||
@@ -122,14 +122,15 @@ export class ObsidianAPIService extends InjectableAPIService<ObsidianServiceCont
|
||||
return this.context.plugin.addCommand(command) as TCommand;
|
||||
}
|
||||
|
||||
registerWindow(type: string, factory: ViewCreator): void {
|
||||
return this.context.plugin.registerView(type, factory);
|
||||
registerWindow<T>(type: string, factory: (leaf: T) => unknown): void {
|
||||
return this.context.plugin.registerView(type, factory as ViewCreator);
|
||||
}
|
||||
addRibbonIcon(icon: string, title: string, callback: (evt: MouseEvent) => any): HTMLElement {
|
||||
|
||||
addRibbonIcon(icon: string, title: string, callback: (evt: MouseEvent) => unknown): HTMLElement {
|
||||
return this.context.plugin.addRibbonIcon(icon, title, callback);
|
||||
}
|
||||
|
||||
registerProtocolHandler(action: string, handler: (params: Record<string, string>) => any): void {
|
||||
registerProtocolHandler(action: string, handler: (params: Record<string, string>) => unknown): void {
|
||||
return this.context.plugin.registerObsidianProtocolHandler(action, handler);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user