mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-07-04 03:45:20 +00:00
Add Obsidian setting definition renderer
This commit is contained in:
@@ -110,6 +110,7 @@ type SettingDefinition<TSettings, TKey extends keyof TSettings | string> = {
|
||||
validate?: (value: unknown, context: SettingEvaluationContext<TSettings>) => SettingValidationResult;
|
||||
coerce?: (value: unknown, context: SettingEvaluationContext<TSettings>) => unknown;
|
||||
affects?: SettingEffect[];
|
||||
commit?: SettingCommitPolicy<TKey>;
|
||||
render?: "auto" | "custom";
|
||||
};
|
||||
```
|
||||
@@ -127,8 +128,15 @@ consumers. `label` and `description` remain compatibility aliases while existing
|
||||
code still expects resolved strings.
|
||||
|
||||
`internal` should mark settings that are not currently editable from the UI.
|
||||
Obsolete settings are internal by default. Persisted settings without UI metadata
|
||||
are also internal until explicitly classified otherwise.
|
||||
Obsolete settings are internal by default. Missing UI metadata alone should not
|
||||
make a setting internal; `kind`, `render`, and explicit `internal` metadata
|
||||
should decide whether the automatic renderer can safely handle it.
|
||||
|
||||
`commit` should describe when a value is persisted, not how a button is rendered.
|
||||
Immediate settings can save on change. Explicit settings are held in the editing
|
||||
buffer until an apply action commits the configured group. This keeps apply
|
||||
buttons out of the repository while still making grouped save behaviour
|
||||
testable.
|
||||
|
||||
## Storage Domains
|
||||
|
||||
@@ -273,6 +281,9 @@ adapter or custom workflow.
|
||||
|
||||
- Replace `isNeedRebuildLocal()` and `isNeedRebuildRemote()` with
|
||||
repository-driven effect calculation.
|
||||
- Model explicit commit groups for settings that must be applied together, for
|
||||
example configuration encryption passphrase settings, setting sync file, and
|
||||
database suffix changes.
|
||||
- Add capability metadata for CouchDB diagnostics, repair, Hidden File Sync, and
|
||||
Obsidian-only plug-in operations.
|
||||
- Use this to improve warnings for database-scoped CouchDB users and
|
||||
|
||||
+1
-1
Submodule src/lib updated: 72a2f684d1...c7c5fe21be
@@ -8,7 +8,13 @@ import {
|
||||
type ValueComponent,
|
||||
} from "@/deps.ts";
|
||||
import { unique } from "octagonal-wheels/collection";
|
||||
import { LEVEL_ADVANCED, LEVEL_POWER_USER, statusDisplay, type ConfigurationItem } from "@lib/common/types.ts";
|
||||
import {
|
||||
LEVEL_ADVANCED,
|
||||
LEVEL_POWER_USER,
|
||||
statusDisplay,
|
||||
type ConfigurationItem,
|
||||
type SettingDefinition,
|
||||
} from "@lib/common/types.ts";
|
||||
import { type ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import {
|
||||
type AllSettingItemKey,
|
||||
@@ -18,9 +24,21 @@ import {
|
||||
type AllNumericItemKey,
|
||||
type AllBooleanItemKey,
|
||||
} from "./settingConstants.ts";
|
||||
import { $msg } from "@lib/common/i18n.ts";
|
||||
import { $msg, $t } from "@lib/common/i18n.ts";
|
||||
import { wrapMemo, type AutoWireOption, type OnUpdateResult } from "./SettingPane.ts";
|
||||
|
||||
function configurationFromDefinition(definition: SettingDefinition<AllSettingItemKey>): ConfigurationItem {
|
||||
return {
|
||||
name: $t(definition.labelKey),
|
||||
desc: definition.descriptionKey ? $t(definition.descriptionKey) : undefined,
|
||||
placeHolder: definition.placeholder,
|
||||
status: definition.status,
|
||||
obsolete: definition.obsolete,
|
||||
level: definition.level,
|
||||
isHidden: definition.secret,
|
||||
};
|
||||
}
|
||||
|
||||
export class LiveSyncSetting extends Setting {
|
||||
autoWiredComponent?: TextComponent | ToggleComponent | DropdownComponent | ButtonComponent | TextAreaComponent;
|
||||
applyButtonComponent?: ButtonComponent;
|
||||
@@ -56,7 +74,7 @@ export class LiveSyncSetting extends Setting {
|
||||
return this;
|
||||
}
|
||||
autoWireSetting(key: AllSettingItemKey, opt?: AutoWireOption) {
|
||||
const conf = getConfig(key);
|
||||
const conf = opt?.settingDefinition ? configurationFromDefinition(opt.settingDefinition) : getConfig(key);
|
||||
if (!conf) {
|
||||
// throw new Error($msg("liveSyncSetting.errorNoSuchSettingItem", { key }));
|
||||
return;
|
||||
|
||||
@@ -0,0 +1,76 @@
|
||||
import {
|
||||
getExplicitSettingCommitGroup,
|
||||
getSettingDefinition,
|
||||
type AllBooleanItemKey,
|
||||
type AllNumericItemKey,
|
||||
type AllSettingItemKey,
|
||||
type AllStringItemKey,
|
||||
} from "./settingConstants.ts";
|
||||
import type { LiveSyncSetting } from "./LiveSyncSetting.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { AutoWireOption } from "./SettingPane.ts";
|
||||
|
||||
export type ObsidianSettingRenderOption<TOption extends string = string> = AutoWireOption & {
|
||||
options?: Record<TOption, string>;
|
||||
clampMin?: number;
|
||||
clampMax?: number;
|
||||
acceptZero?: boolean;
|
||||
renderInternal?: boolean;
|
||||
};
|
||||
|
||||
export function addObsidianApplyButton(setting: LiveSyncSetting, group: string, text?: string): LiveSyncSetting {
|
||||
const commitGroup = getExplicitSettingCommitGroup(group);
|
||||
if (!commitGroup) {
|
||||
throw new Error(`No explicit setting commit group found for '${group}'`);
|
||||
}
|
||||
return setting.addApplyButton(commitGroup.applyKeys, text);
|
||||
}
|
||||
|
||||
export function renderObsidianApplyButton(containerEl: HTMLElement, group: string, text?: string): LiveSyncSetting {
|
||||
return addObsidianApplyButton(new Setting(containerEl), group, text);
|
||||
}
|
||||
|
||||
export function renderObsidianSetting<TOption extends string = string>(
|
||||
containerEl: HTMLElement,
|
||||
key: AllSettingItemKey,
|
||||
opt: ObsidianSettingRenderOption<TOption> = {}
|
||||
): LiveSyncSetting {
|
||||
const definition = getSettingDefinition(key);
|
||||
if (!definition) {
|
||||
throw new Error(`No setting definition found for '${key}'`);
|
||||
}
|
||||
if (definition.internal && !opt.renderInternal) {
|
||||
throw new Error(`Setting '${key}' is internal and cannot be rendered automatically`);
|
||||
}
|
||||
if (definition.render === "custom" || definition.kind === "custom") {
|
||||
throw new Error(`Setting '${key}' requires a custom renderer`);
|
||||
}
|
||||
|
||||
const isExplicitCommit = definition.commit?.mode === "explicit";
|
||||
const holdValue = opt.holdValue ?? isExplicitCommit;
|
||||
const setting = new Setting(containerEl);
|
||||
const wireOption = {
|
||||
...opt,
|
||||
holdValue,
|
||||
settingDefinition: definition,
|
||||
};
|
||||
|
||||
if (opt.options) {
|
||||
return setting.autoWireDropDown(key as AllStringItemKey, { ...wireOption, options: opt.options });
|
||||
}
|
||||
|
||||
switch (definition.kind) {
|
||||
case "boolean":
|
||||
return setting.autoWireToggle(key as AllBooleanItemKey, wireOption);
|
||||
case "number":
|
||||
return setting.autoWireNumeric(key as AllNumericItemKey, wireOption);
|
||||
case "password":
|
||||
return setting.autoWireText(key as AllStringItemKey, { ...wireOption, isPassword: true });
|
||||
case "textarea":
|
||||
return setting.autoWireTextArea(key as AllStringItemKey, wireOption);
|
||||
case "select":
|
||||
throw new Error(`Setting '${key}' requires select options`);
|
||||
case "text":
|
||||
return setting.autoWireText(key as AllStringItemKey, wireOption);
|
||||
}
|
||||
}
|
||||
@@ -1,41 +1,37 @@
|
||||
import { ChunkAlgorithmNames } from "@lib/common/types.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
|
||||
export function paneAdvanced(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
void addPanel(paneEl, "Memory cache").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireNumeric("hashCacheMaxCount", { clampMin: 10 });
|
||||
// new Setting(paneEl).autoWireNumeric("hashCacheMaxAmount", { clampMin: 1 });
|
||||
renderObsidianSetting(paneEl, "hashCacheMaxCount", { clampMin: 10 });
|
||||
// renderObsidianSetting(paneEl, "hashCacheMaxAmount", { clampMin: 1 });
|
||||
});
|
||||
void addPanel(paneEl, "Local Database Tweak").then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
|
||||
const items = ChunkAlgorithmNames;
|
||||
new Setting(paneEl).autoWireDropDown("chunkSplitterVersion", {
|
||||
renderObsidianSetting(paneEl, "chunkSplitterVersion", {
|
||||
options: items,
|
||||
});
|
||||
new Setting(paneEl).autoWireNumeric("customChunkSize", { clampMin: 0, acceptZero: true });
|
||||
renderObsidianSetting(paneEl, "customChunkSize", { clampMin: 0, acceptZero: true });
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Transfer Tweak").then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.setClass("wizardHidden")
|
||||
.autoWireToggle("readChunksOnline", { onUpdate: this.onlyOnCouchDB });
|
||||
new Setting(paneEl)
|
||||
.setClass("wizardHidden")
|
||||
.autoWireToggle("useOnlyLocalChunk", { onUpdate: this.onlyOnCouchDB });
|
||||
renderObsidianSetting(paneEl, "readChunksOnline", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "useOnlyLocalChunk", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("concurrencyOfReadChunksOnline", {
|
||||
renderObsidianSetting(paneEl, "concurrencyOfReadChunksOnline", {
|
||||
clampMin: 10,
|
||||
onUpdate: this.onlyOnCouchDB,
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("minimumIntervalOfReadChunksOnline", {
|
||||
renderObsidianSetting(paneEl, "minimumIntervalOfReadChunksOnline", {
|
||||
clampMin: 10,
|
||||
onUpdate: this.onlyOnCouchDB,
|
||||
});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("autoAcceptCompatibleTweak");
|
||||
}).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "autoAcceptCompatibleTweak").setClass("wizardHidden");
|
||||
// new Setting(paneEl)
|
||||
// .setClass("wizardHidden")
|
||||
// .autoWireToggle("sendChunksBulk", { onUpdate: onlyOnCouchDB })
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG, eventHub } from "@/common/events.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { enableOnly, visibleOnly } from "./SettingPane.ts";
|
||||
export function paneCustomisationSync(
|
||||
@@ -35,27 +36,27 @@ export function paneCustomisationSync(
|
||||
visibleOnly(() => this.isConfiguredAs("usePluginSync", true))
|
||||
);
|
||||
|
||||
new Setting(paneEl).autoWireText("deviceAndVaultName", {
|
||||
renderObsidianSetting(paneEl, "deviceAndVaultName", {
|
||||
placeHolder: "desktop",
|
||||
onUpdate: enableOnlyOnPluginSyncIsNotEnabled,
|
||||
});
|
||||
|
||||
new Setting(paneEl).autoWireToggle("usePluginSyncV2");
|
||||
renderObsidianSetting(paneEl, "usePluginSyncV2");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("usePluginSync", {
|
||||
renderObsidianSetting(paneEl, "usePluginSync", {
|
||||
onUpdate: enableOnly(() => !this.isConfiguredAs("deviceAndVaultName", "")),
|
||||
});
|
||||
|
||||
new Setting(paneEl).autoWireToggle("autoSweepPlugins", {
|
||||
renderObsidianSetting(paneEl, "autoSweepPlugins", {
|
||||
onUpdate: visibleOnlyOnPluginSyncEnabled,
|
||||
});
|
||||
|
||||
new Setting(paneEl).autoWireToggle("autoSweepPluginsPeriodic", {
|
||||
renderObsidianSetting(paneEl, "autoSweepPluginsPeriodic", {
|
||||
onUpdate: visibleOnly(
|
||||
() => this.isConfiguredAs("usePluginSync", true) && this.isConfiguredAs("autoSweepPlugins", true)
|
||||
),
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("notifyPluginOrSettingUpdated", {
|
||||
renderObsidianSetting(paneEl, "notifyPluginOrSettingUpdated", {
|
||||
onUpdate: visibleOnlyOnPluginSyncEnabled,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { $msg, $t } from "@lib/common/i18n.ts";
|
||||
import { SUPPORTED_I18N_LANGS, type I18N_LANGS } from "@lib/common/rosetta.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
@@ -16,20 +17,20 @@ export function paneGeneral(
|
||||
// ["", $msg("obsidianLiveSyncSettingTab.defaultLanguage")],
|
||||
...SUPPORTED_I18N_LANGS.map((e) => [e, $t(`lang-${e}`)]),
|
||||
]) as Record<I18N_LANGS, string>;
|
||||
new Setting(paneEl).autoWireDropDown("displayLanguage", {
|
||||
renderObsidianSetting(paneEl, "displayLanguage", {
|
||||
options: languages,
|
||||
});
|
||||
this.addOnSaved("displayLanguage", () => this.display());
|
||||
new Setting(paneEl).autoWireToggle("showStatusOnEditor");
|
||||
renderObsidianSetting(paneEl, "showStatusOnEditor");
|
||||
this.addOnSaved("showStatusOnEditor", () => {
|
||||
eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR);
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("showOnlyIconsOnEditor", {
|
||||
renderObsidianSetting(paneEl, "showOnlyIconsOnEditor", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("showStatusOnEditor", true)),
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("showStatusOnStatusbar");
|
||||
new Setting(paneEl).autoWireToggle("hideFileWarningNotice");
|
||||
new Setting(paneEl).autoWireDropDown("networkWarningStyle", {
|
||||
renderObsidianSetting(paneEl, "showStatusOnStatusbar");
|
||||
renderObsidianSetting(paneEl, "hideFileWarningNotice");
|
||||
renderObsidianSetting(paneEl, "networkWarningStyle", {
|
||||
options: {
|
||||
[NetworkWarningStyles.BANNER]: "Show full banner",
|
||||
[NetworkWarningStyles.ICON]: "Show icon only",
|
||||
@@ -43,9 +44,9 @@ export function paneGeneral(
|
||||
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleLogging")).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("lessInformationInLog");
|
||||
renderObsidianSetting(paneEl, "lessInformationInLog");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("showVerboseLog", {
|
||||
renderObsidianSetting(paneEl, "showVerboseLog", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("lessInformationInLog", false)),
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ import { ICHeader, ICXHeader, PSCHeader } from "@/common/types.ts";
|
||||
import { HiddenFileSync } from "@/features/HiddenFileSync/CmdHiddenFileSync.ts";
|
||||
import { EVENT_REQUEST_SHOW_HISTORY } from "@/common/obsidianEvents.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { isNotFoundError } from "@lib/common/utils.doc.ts";
|
||||
export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
@@ -87,14 +88,14 @@ export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement,
|
||||
eventHub.emitEvent(EVENT_REQUEST_CHECK_REMOTE_SIZE);
|
||||
})
|
||||
);
|
||||
new Setting(paneEl).autoWireToggle("writeLogToTheFile");
|
||||
renderObsidianSetting(paneEl, "writeLogToTheFile");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Scram Switches").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("suspendFileWatching");
|
||||
renderObsidianSetting(paneEl, "suspendFileWatching");
|
||||
this.addOnSaved("suspendFileWatching", () => this.services.appLifecycle.askRestart());
|
||||
|
||||
new Setting(paneEl).autoWireToggle("suspendParseReplicationResult");
|
||||
renderObsidianSetting(paneEl, "suspendParseReplicationResult");
|
||||
this.addOnSaved("suspendParseReplicationResult", () => this.services.appLifecycle.askRestart());
|
||||
});
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import {
|
||||
} from "@lib/common/types.ts";
|
||||
import { Logger } from "@lib/common/logger.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { addObsidianApplyButton, renderObsidianApplyButton, renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
@@ -16,17 +17,17 @@ import { migrateDatabases } from "./settingUtils.ts";
|
||||
|
||||
export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
void addPanel(paneEl, "Compatibility (Metadata)").then((paneEl) => {
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("deleteMetadataOfDeletedFiles");
|
||||
renderObsidianSetting(paneEl, "deleteMetadataOfDeletedFiles").setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("automaticallyDeleteMetadataOfDeletedFiles", {
|
||||
renderObsidianSetting(paneEl, "automaticallyDeleteMetadataOfDeletedFiles", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("deleteMetadataOfDeletedFiles", true)),
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Conflict Behaviour)").then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("disableMarkdownAutoMerge");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("writeDocumentsIfConflicted");
|
||||
renderObsidianSetting(paneEl, "disableMarkdownAutoMerge").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "writeDocumentsIfConflicted").setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Database structure)").then((paneEl) => {
|
||||
@@ -113,18 +114,18 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
});
|
||||
}
|
||||
}
|
||||
new Setting(paneEl).autoWireToggle("handleFilenameCaseSensitive", { holdValue: true }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "handleFilenameCaseSensitive", { holdValue: true }).setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Compatibility (Internal API Usage)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("watchInternalFileChanges", { invert: true });
|
||||
renderObsidianSetting(paneEl, "watchInternalFileChanges", { invert: true });
|
||||
});
|
||||
void addPanel(paneEl, "Compatibility (Remote Database)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireDropDown("E2EEAlgorithm", {
|
||||
renderObsidianSetting(paneEl, "E2EEAlgorithm", {
|
||||
options: E2EEAlgorithmNames,
|
||||
});
|
||||
});
|
||||
new Setting(paneEl).autoWireToggle("useDynamicIterationCount", {
|
||||
renderObsidianSetting(paneEl, "useDynamicIterationCount", {
|
||||
holdValue: true,
|
||||
onUpdate: visibleOnly(
|
||||
() =>
|
||||
@@ -134,16 +135,15 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Edge case addressing (Database)").then((paneEl) => {
|
||||
new Setting(paneEl)
|
||||
.autoWireText("additionalSuffixOfDatabaseName", { holdValue: true })
|
||||
.addApplyButton(["additionalSuffixOfDatabaseName"]);
|
||||
renderObsidianSetting(paneEl, "additionalSuffixOfDatabaseName");
|
||||
renderObsidianApplyButton(paneEl, "database-suffix");
|
||||
|
||||
this.addOnSaved("additionalSuffixOfDatabaseName", async (key) => {
|
||||
Logger("Suffix has been changed. Reopening database...", LOG_LEVEL_NOTICE);
|
||||
await this.services.databaseEvents.initialiseDatabase();
|
||||
});
|
||||
|
||||
new Setting(paneEl).autoWireDropDown("hashAlg", {
|
||||
renderObsidianSetting(paneEl, "hashAlg", {
|
||||
options: {
|
||||
"": "Old Algorithm",
|
||||
xxhash32: "xxhash32 (Fast but less collision resistance)",
|
||||
@@ -157,15 +157,15 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
});
|
||||
});
|
||||
void addPanel(paneEl, "Edge case addressing (Behaviour)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("doNotSuspendOnFetching");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("doNotDeleteFolder");
|
||||
new Setting(paneEl).autoWireToggle("processSizeMismatchedFiles");
|
||||
renderObsidianSetting(paneEl, "doNotSuspendOnFetching");
|
||||
renderObsidianSetting(paneEl, "doNotDeleteFolder").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "processSizeMismatchedFiles");
|
||||
});
|
||||
|
||||
void addPanel(paneEl, "Edge case addressing (Processing)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableWorkerForGeneratingChunks");
|
||||
renderObsidianSetting(paneEl, "disableWorkerForGeneratingChunks");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("processSmallFilesInUIThread", {
|
||||
renderObsidianSetting(paneEl, "processSmallFilesInUIThread", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("disableWorkerForGeneratingChunks", false)),
|
||||
});
|
||||
});
|
||||
@@ -173,11 +173,11 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
// new Setting(paneEl).autoWireToggle("useRequestAPI");
|
||||
// });
|
||||
void addPanel(paneEl, "Compatibility (Trouble addressed)").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("disableCheckingConfigMismatch");
|
||||
renderObsidianSetting(paneEl, "disableCheckingConfigMismatch");
|
||||
});
|
||||
void addPanel(paneEl, "Remediation").then((paneEl) => {
|
||||
let dateEl: HTMLSpanElement;
|
||||
new Setting(paneEl)
|
||||
const remediationSetting = new Setting(paneEl)
|
||||
.addText((text) => {
|
||||
const updateDateText = () => {
|
||||
if (this.editingSettings.maxMTimeForReflectEvents == 0) {
|
||||
@@ -212,8 +212,8 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
updateDateText();
|
||||
return text;
|
||||
})
|
||||
.setAuto("maxMTimeForReflectEvents")
|
||||
.addApplyButton(["maxMTimeForReflectEvents"]);
|
||||
.setAuto("maxMTimeForReflectEvents");
|
||||
addObsidianApplyButton(remediationSetting, "remediation-reflect-events");
|
||||
|
||||
this.addOnSaved("maxMTimeForReflectEvents", async (key) => {
|
||||
const buttons = ["Restart Now", "Later"] as const;
|
||||
@@ -240,6 +240,6 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
// .setClass("wizardHidden");
|
||||
// new Setting(paneEl).autoWireNumeric("maxAgeInEden", { onUpdate: onlyUsingEden }).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("enableCompression").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "enableCompression").setClass("wizardHidden");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { type ConfigPassphraseStore } from "@lib/common/types.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { renderObsidianApplyButton, renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
|
||||
@@ -21,14 +21,14 @@ export function panePowerUsers(
|
||||
this.onlyOnCouchDB
|
||||
).addClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl)
|
||||
.setClass("wizardHidden")
|
||||
.autoWireNumeric("batch_size", { clampMin: 2, onUpdate: this.onlyOnCouchDB });
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batches_limit", {
|
||||
renderObsidianSetting(paneEl, "batch_size", { clampMin: 2, onUpdate: this.onlyOnCouchDB }).setClass(
|
||||
"wizardHidden"
|
||||
);
|
||||
renderObsidianSetting(paneEl, "batches_limit", {
|
||||
clampMin: 2,
|
||||
onUpdate: this.onlyOnCouchDB,
|
||||
});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("useTimeouts", { onUpdate: this.onlyOnCouchDB });
|
||||
}).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "useTimeouts", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
|
||||
});
|
||||
void addPanel(paneEl, "Configuration Encryption").then((paneEl) => {
|
||||
const passphrase_options: Record<ConfigPassphraseStore, string> = {
|
||||
@@ -37,23 +37,18 @@ export function panePowerUsers(
|
||||
ASK_AT_LAUNCH: "Ask an passphrase at every launch",
|
||||
};
|
||||
|
||||
new Setting(paneEl)
|
||||
.setName("Encrypting sensitive configuration items")
|
||||
.autoWireDropDown("configPassphraseStore", {
|
||||
options: passphrase_options,
|
||||
holdValue: true,
|
||||
})
|
||||
.setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "configPassphraseStore", {
|
||||
options: passphrase_options,
|
||||
}).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl)
|
||||
.autoWireText("configPassphrase", { isPassword: true, holdValue: true })
|
||||
renderObsidianSetting(paneEl, "configPassphrase")
|
||||
.setClass("wizardHidden")
|
||||
.addOnUpdate(() => ({
|
||||
disabled: !this.isConfiguredAs("configPassphraseStore", "LOCALSTORAGE"),
|
||||
}));
|
||||
new Setting(paneEl).addApplyButton(["configPassphrase", "configPassphraseStore"]).setClass("wizardHidden");
|
||||
renderObsidianApplyButton(paneEl, "configuration-encryption").setClass("wizardHidden");
|
||||
});
|
||||
void addPanel(paneEl, "Developer").then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("enableDebugTools").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "enableDebugTools").setClass("wizardHidden");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ import {
|
||||
import { Menu, type ButtonComponent } from "@/deps.ts";
|
||||
import { $msg } from "@lib/common/i18n.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
// import { visibleOnly } from "./SettingPane.ts";
|
||||
@@ -674,7 +675,7 @@ export function paneRemoteConfig(
|
||||
|
||||
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleNotification"), () => {}).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
new Setting(paneEl).autoWireNumeric("notifyThresholdOfRemoteStorageSize", {}).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "notifyThresholdOfRemoteStorageSize", {}).setClass("wizardHidden");
|
||||
});
|
||||
|
||||
// new Setting(paneEl).setClass("wizardOnly").addButton((button) =>
|
||||
|
||||
@@ -4,6 +4,7 @@ import MultipleRegExpControl from "./MultipleRegExpControl.svelte";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { mount } from "svelte";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
|
||||
@@ -46,12 +47,12 @@ export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLEleme
|
||||
},
|
||||
},
|
||||
});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("syncMaxSizeInMB", { clampMin: 0 });
|
||||
renderObsidianSetting(paneEl, "syncMaxSizeInMB", { clampMin: 0 }).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("useIgnoreFiles");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireTextArea("ignoreFiles", {
|
||||
renderObsidianSetting(paneEl, "useIgnoreFiles").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "ignoreFiles", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("useIgnoreFiles", true)),
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
});
|
||||
void addPanel(paneEl, "Hidden Files", undefined, undefined, LEVEL_ADVANCED).then((paneEl) => {
|
||||
const targetPatternSetting = new Setting(paneEl)
|
||||
|
||||
@@ -15,6 +15,7 @@ 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";
|
||||
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
export function paneSetup(
|
||||
this: ObsidianLiveSyncSettingTab,
|
||||
paneEl: HTMLElement,
|
||||
@@ -107,10 +108,9 @@ export function paneSetup(
|
||||
});
|
||||
|
||||
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleExtraFeatures")).then((paneEl) => {
|
||||
new Setting(paneEl).autoWireToggle("useAdvancedMode");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("usePowerUserMode");
|
||||
new Setting(paneEl).autoWireToggle("useEdgeCaseMode");
|
||||
renderObsidianSetting(paneEl, "useAdvancedMode");
|
||||
renderObsidianSetting(paneEl, "usePowerUserMode");
|
||||
renderObsidianSetting(paneEl, "useEdgeCaseMode");
|
||||
|
||||
this.addOnSaved("useAdvancedMode", () => this.display());
|
||||
this.addOnSaved("usePowerUserMode", () => this.display());
|
||||
|
||||
@@ -2,6 +2,7 @@ import { type ObsidianLiveSyncSettings, LOG_LEVEL_NOTICE, REMOTE_COUCHDB, LEVEL_
|
||||
import { Logger } from "@lib/common/logger.ts";
|
||||
import { $msg } from "@lib/common/i18n.ts";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import { renderObsidianApplyButton, renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
|
||||
import { EVENT_REQUEST_COPY_SETUP_URI, eventHub } from "@/common/events.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
@@ -31,18 +32,16 @@ export function paneSyncSettings(
|
||||
DISABLE: $msg("obsidianLiveSyncSettingTab.optionDisableAllAutomatic"),
|
||||
};
|
||||
|
||||
new Setting(paneEl)
|
||||
.autoWireDropDown("preset", {
|
||||
options: options,
|
||||
holdValue: true,
|
||||
})
|
||||
.addButton((button) => {
|
||||
button.setButtonText($msg("obsidianLiveSyncSettingTab.btnApply"));
|
||||
button.onClick(async () => {
|
||||
// await this.saveSettings(["preset"]);
|
||||
await this.saveAllDirtySettings();
|
||||
});
|
||||
renderObsidianSetting(paneEl, "preset", {
|
||||
options: options,
|
||||
holdValue: true,
|
||||
}).addButton((button) => {
|
||||
button.setButtonText($msg("obsidianLiveSyncSettingTab.btnApply"));
|
||||
button.onClick(async () => {
|
||||
// await this.saveSettings(["preset"]);
|
||||
await this.saveAllDirtySettings();
|
||||
});
|
||||
});
|
||||
|
||||
this.addOnSaved("preset", async (currentPreset) => {
|
||||
if (currentPreset == "") {
|
||||
@@ -136,7 +135,7 @@ export function paneSyncSettings(
|
||||
const onlyOnNonLiveSync = visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC"));
|
||||
const onlyOnPeriodic = visibleOnly(() => this.isConfiguredAs("syncMode", "PERIODIC"));
|
||||
|
||||
const optionsSyncMode =
|
||||
const optionsSyncMode: Record<string, string> =
|
||||
this.editingSettings.remoteType == REMOTE_COUCHDB
|
||||
? {
|
||||
ONEVENTS: $msg("obsidianLiveSyncSettingTab.optionOnEvents"),
|
||||
@@ -148,12 +147,9 @@ export function paneSyncSettings(
|
||||
PERIODIC: $msg("obsidianLiveSyncSettingTab.optionPeriodicAndEvents"),
|
||||
};
|
||||
|
||||
new Setting(paneEl)
|
||||
.autoWireDropDown("syncMode", {
|
||||
//@ts-ignore
|
||||
options: optionsSyncMode,
|
||||
})
|
||||
.setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncMode", {
|
||||
options: optionsSyncMode,
|
||||
}).setClass("wizardHidden");
|
||||
this.addOnSaved("syncMode", async (value) => {
|
||||
this.editingSettings.liveSync = false;
|
||||
this.editingSettings.periodicReplication = false;
|
||||
@@ -167,32 +163,28 @@ export function paneSyncSettings(
|
||||
await this.services.control.applySettings();
|
||||
});
|
||||
|
||||
new Setting(paneEl)
|
||||
.autoWireNumeric("periodicReplicationInterval", {
|
||||
clampMax: 5000,
|
||||
onUpdate: onlyOnPeriodic,
|
||||
})
|
||||
.setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "periodicReplicationInterval", {
|
||||
clampMax: 5000,
|
||||
onUpdate: onlyOnPeriodic,
|
||||
}).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).autoWireNumeric("syncMinimumInterval", {
|
||||
renderObsidianSetting(paneEl, "syncMinimumInterval", {
|
||||
onUpdate: onlyOnNonLiveSync,
|
||||
});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnSave", { onUpdate: onlyOnNonLiveSync });
|
||||
new Setting(paneEl)
|
||||
.setClass("wizardHidden")
|
||||
.autoWireToggle("syncOnEditorSave", { onUpdate: onlyOnNonLiveSync });
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnFileOpen", { onUpdate: onlyOnNonLiveSync });
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnStart", { onUpdate: onlyOnNonLiveSync });
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncAfterMerge", { onUpdate: onlyOnNonLiveSync });
|
||||
renderObsidianSetting(paneEl, "syncOnSave", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncOnEditorSave", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncOnFileOpen", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncOnStart", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncAfterMerge", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
|
||||
// Desktop app only, and only for the sync modes that keep a background replication channel
|
||||
// (LiveSync and Periodic). Ignored on mobile, where suspending preserves battery. The
|
||||
// visibility predicate mirrors the runtime guard in ModuleObsidianEvents.
|
||||
if (!this.services.API.isMobile()) {
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("keepReplicationActiveInBackground", {
|
||||
renderObsidianSetting(paneEl, "keepReplicationActiveInBackground", {
|
||||
onUpdate: visibleOnly(
|
||||
() => this.isConfiguredAs("syncMode", "LIVESYNC") || this.isConfiguredAs("syncMode", "PERIODIC")
|
||||
),
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
}
|
||||
});
|
||||
|
||||
@@ -203,15 +195,15 @@ export function paneSyncSettings(
|
||||
visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC"))
|
||||
).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("batchSave");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batchSaveMinimumDelay", {
|
||||
renderObsidianSetting(paneEl, "batchSave").setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "batchSaveMinimumDelay", {
|
||||
acceptZero: true,
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)),
|
||||
});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batchSaveMaximumDelay", {
|
||||
}).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "batchSaveMaximumDelay", {
|
||||
acceptZero: true,
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)),
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(
|
||||
@@ -222,9 +214,9 @@ export function paneSyncSettings(
|
||||
LEVEL_ADVANCED
|
||||
).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("trashInsteadDelete");
|
||||
renderObsidianSetting(paneEl, "trashInsteadDelete").setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("doNotDeleteFolder");
|
||||
renderObsidianSetting(paneEl, "doNotDeleteFolder").setClass("wizardHidden");
|
||||
});
|
||||
void addPanel(
|
||||
paneEl,
|
||||
@@ -235,11 +227,11 @@ export function paneSyncSettings(
|
||||
).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("resolveConflictsByNewerFile");
|
||||
renderObsidianSetting(paneEl, "resolveConflictsByNewerFile").setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("checkConflictOnlyOnOpen");
|
||||
renderObsidianSetting(paneEl, "checkConflictOnlyOnOpen").setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("showMergeDialogOnlyOnActive");
|
||||
renderObsidianSetting(paneEl, "showMergeDialogOnlyOnActive").setClass("wizardHidden");
|
||||
});
|
||||
|
||||
void addPanel(
|
||||
@@ -250,11 +242,12 @@ export function paneSyncSettings(
|
||||
LEVEL_ADVANCED
|
||||
).then((paneEl) => {
|
||||
paneEl.addClass("wizardHidden");
|
||||
new Setting(paneEl).autoWireText("settingSyncFile", { holdValue: true }).addApplyButton(["settingSyncFile"]);
|
||||
renderObsidianSetting(paneEl, "settingSyncFile");
|
||||
renderObsidianApplyButton(paneEl, "setting-sync-file");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("writeCredentialsForSettingSync");
|
||||
renderObsidianSetting(paneEl, "writeCredentialsForSettingSync");
|
||||
|
||||
new Setting(paneEl).autoWireToggle("notifyAllSettingSyncFile");
|
||||
renderObsidianSetting(paneEl, "notifyAllSettingSyncFile");
|
||||
});
|
||||
|
||||
void addPanel(
|
||||
@@ -313,14 +306,14 @@ export function paneSyncSettings(
|
||||
});
|
||||
}
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("suppressNotifyHiddenFilesChange", {});
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncInternalFilesBeforeReplication", {
|
||||
renderObsidianSetting(paneEl, "suppressNotifyHiddenFilesChange", {}).setClass("wizardHidden");
|
||||
renderObsidianSetting(paneEl, "syncInternalFilesBeforeReplication", {
|
||||
onUpdate: visibleOnly(() => this.isConfiguredAs("watchInternalFileChanges", true)),
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
|
||||
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("syncInternalFilesInterval", {
|
||||
renderObsidianSetting(paneEl, "syncInternalFilesInterval", {
|
||||
clampMin: 10,
|
||||
acceptZero: true,
|
||||
});
|
||||
}).setClass("wizardHidden");
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
import { $msg } from "@lib/common/i18n";
|
||||
import { LEVEL_ADVANCED, LEVEL_EDGE_CASE, LEVEL_POWER_USER, type ConfigLevel } from "@lib/common/types";
|
||||
import {
|
||||
LEVEL_ADVANCED,
|
||||
LEVEL_EDGE_CASE,
|
||||
LEVEL_POWER_USER,
|
||||
type ConfigLevel,
|
||||
type SettingDefinition,
|
||||
} from "@lib/common/types";
|
||||
import type { AllSettingItemKey, AllSettings } from "./settingConstants";
|
||||
|
||||
export const combineOnUpdate = (func1: OnUpdateFunc, func2: OnUpdateFunc): OnUpdateFunc => {
|
||||
@@ -77,6 +83,7 @@ export type AutoWireOption = {
|
||||
invert?: boolean;
|
||||
onUpdate?: OnUpdateFunc;
|
||||
obsolete?: boolean;
|
||||
settingDefinition?: SettingDefinition<AllSettingItemKey>;
|
||||
};
|
||||
|
||||
export function findAttrFromParent(el: HTMLElement, attr: string): string {
|
||||
|
||||
Reference in New Issue
Block a user