Add Obsidian setting definition renderer

This commit is contained in:
vorotamoroz committed 2026-07-03 11:24:19 +00:00
1 parent c9ff34842f
commit 2090d42631
15 files changed
+243 -142

No files matched your search

@@ -110,6 +110,7 @@ type SettingDefinition<TSettings, TKey extends keyof TSettings | string> = {
validate?: (value: unknown, context: SettingEvaluationContext<TSettings>) => SettingValidationResult; validate?: (value: unknown, context: SettingEvaluationContext<TSettings>) => SettingValidationResult;
coerce?: (value: unknown, context: SettingEvaluationContext<TSettings>) => unknown; coerce?: (value: unknown, context: SettingEvaluationContext<TSettings>) => unknown;
affects?: SettingEffect[]; affects?: SettingEffect[];
commit?: SettingCommitPolicy<TKey>;
render?: "auto" | "custom"; render?: "auto" | "custom";
}; };
``` ```
@@ -127,8 +128,15 @@ consumers. `label` and `description` remain compatibility aliases while existing
code still expects resolved strings. code still expects resolved strings.
`internal` should mark settings that are not currently editable from the UI. `internal` should mark settings that are not currently editable from the UI.
Obsolete settings are internal by default. Persisted settings without UI metadata Obsolete settings are internal by default. Missing UI metadata alone should not
are also internal until explicitly classified otherwise. 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 ## Storage Domains
@@ -273,6 +281,9 @@ adapter or custom workflow.
- Replace `isNeedRebuildLocal()` and `isNeedRebuildRemote()` with - Replace `isNeedRebuildLocal()` and `isNeedRebuildRemote()` with
repository-driven effect calculation. 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 - Add capability metadata for CouchDB diagnostics, repair, Hidden File Sync, and
Obsidian-only plug-in operations. Obsidian-only plug-in operations.
- Use this to improve warnings for database-scoped CouchDB users and - 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, type ValueComponent,
} from "@/deps.ts"; } from "@/deps.ts";
import { unique } from "octagonal-wheels/collection"; 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 ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import { import {
type AllSettingItemKey, type AllSettingItemKey,
@@ -18,9 +24,21 @@ import {
type AllNumericItemKey, type AllNumericItemKey,
type AllBooleanItemKey, type AllBooleanItemKey,
} from "./settingConstants.ts"; } 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"; 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 { export class LiveSyncSetting extends Setting {
autoWiredComponent?: TextComponent | ToggleComponent | DropdownComponent | ButtonComponent | TextAreaComponent; autoWiredComponent?: TextComponent | ToggleComponent | DropdownComponent | ButtonComponent | TextAreaComponent;
applyButtonComponent?: ButtonComponent; applyButtonComponent?: ButtonComponent;
@@ -56,7 +74,7 @@ export class LiveSyncSetting extends Setting {
return this; return this;
} }
autoWireSetting(key: AllSettingItemKey, opt?: AutoWireOption) { autoWireSetting(key: AllSettingItemKey, opt?: AutoWireOption) {
const conf = getConfig(key); const conf = opt?.settingDefinition ? configurationFromDefinition(opt.settingDefinition) : getConfig(key);
if (!conf) { if (!conf) {
// throw new Error($msg("liveSyncSetting.errorNoSuchSettingItem", { key })); // throw new Error($msg("liveSyncSetting.errorNoSuchSettingItem", { key }));
return; 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 { 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 { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
export function paneAdvanced(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void { export function paneAdvanced(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
void addPanel(paneEl, "Memory cache").then((paneEl) => { void addPanel(paneEl, "Memory cache").then((paneEl) => {
new Setting(paneEl).autoWireNumeric("hashCacheMaxCount", { clampMin: 10 }); renderObsidianSetting(paneEl, "hashCacheMaxCount", { clampMin: 10 });
// new Setting(paneEl).autoWireNumeric("hashCacheMaxAmount", { clampMin: 1 }); // renderObsidianSetting(paneEl, "hashCacheMaxAmount", { clampMin: 1 });
}); });
void addPanel(paneEl, "Local Database Tweak").then((paneEl) => { void addPanel(paneEl, "Local Database Tweak").then((paneEl) => {
paneEl.addClass("wizardHidden"); paneEl.addClass("wizardHidden");
const items = ChunkAlgorithmNames; const items = ChunkAlgorithmNames;
new Setting(paneEl).autoWireDropDown("chunkSplitterVersion", { renderObsidianSetting(paneEl, "chunkSplitterVersion", {
options: items, 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) => { void addPanel(paneEl, "Transfer Tweak").then((paneEl) => {
new Setting(paneEl) renderObsidianSetting(paneEl, "readChunksOnline", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
.setClass("wizardHidden") renderObsidianSetting(paneEl, "useOnlyLocalChunk", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
.autoWireToggle("readChunksOnline", { onUpdate: this.onlyOnCouchDB });
new Setting(paneEl)
.setClass("wizardHidden")
.autoWireToggle("useOnlyLocalChunk", { onUpdate: this.onlyOnCouchDB });
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("concurrencyOfReadChunksOnline", { renderObsidianSetting(paneEl, "concurrencyOfReadChunksOnline", {
clampMin: 10, clampMin: 10,
onUpdate: this.onlyOnCouchDB, onUpdate: this.onlyOnCouchDB,
}); }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("minimumIntervalOfReadChunksOnline", { renderObsidianSetting(paneEl, "minimumIntervalOfReadChunksOnline", {
clampMin: 10, clampMin: 10,
onUpdate: this.onlyOnCouchDB, onUpdate: this.onlyOnCouchDB,
}); }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("autoAcceptCompatibleTweak"); renderObsidianSetting(paneEl, "autoAcceptCompatibleTweak").setClass("wizardHidden");
// new Setting(paneEl) // new Setting(paneEl)
// .setClass("wizardHidden") // .setClass("wizardHidden")
// .autoWireToggle("sendChunksBulk", { onUpdate: onlyOnCouchDB }) // .autoWireToggle("sendChunksBulk", { onUpdate: onlyOnCouchDB })
@@ -1,6 +1,7 @@
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
import { EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG, eventHub } from "@/common/events.ts"; import { EVENT_REQUEST_OPEN_PLUGIN_SYNC_DIALOG, eventHub } from "@/common/events.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
import { enableOnly, visibleOnly } from "./SettingPane.ts"; import { enableOnly, visibleOnly } from "./SettingPane.ts";
export function paneCustomisationSync( export function paneCustomisationSync(
@@ -35,27 +36,27 @@ export function paneCustomisationSync(
visibleOnly(() => this.isConfiguredAs("usePluginSync", true)) visibleOnly(() => this.isConfiguredAs("usePluginSync", true))
); );
new Setting(paneEl).autoWireText("deviceAndVaultName", { renderObsidianSetting(paneEl, "deviceAndVaultName", {
placeHolder: "desktop", placeHolder: "desktop",
onUpdate: enableOnlyOnPluginSyncIsNotEnabled, onUpdate: enableOnlyOnPluginSyncIsNotEnabled,
}); });
new Setting(paneEl).autoWireToggle("usePluginSyncV2"); renderObsidianSetting(paneEl, "usePluginSyncV2");
new Setting(paneEl).autoWireToggle("usePluginSync", { renderObsidianSetting(paneEl, "usePluginSync", {
onUpdate: enableOnly(() => !this.isConfiguredAs("deviceAndVaultName", "")), onUpdate: enableOnly(() => !this.isConfiguredAs("deviceAndVaultName", "")),
}); });
new Setting(paneEl).autoWireToggle("autoSweepPlugins", { renderObsidianSetting(paneEl, "autoSweepPlugins", {
onUpdate: visibleOnlyOnPluginSyncEnabled, onUpdate: visibleOnlyOnPluginSyncEnabled,
}); });
new Setting(paneEl).autoWireToggle("autoSweepPluginsPeriodic", { renderObsidianSetting(paneEl, "autoSweepPluginsPeriodic", {
onUpdate: visibleOnly( onUpdate: visibleOnly(
() => this.isConfiguredAs("usePluginSync", true) && this.isConfiguredAs("autoSweepPlugins", true) () => this.isConfiguredAs("usePluginSync", true) && this.isConfiguredAs("autoSweepPlugins", true)
), ),
}); });
new Setting(paneEl).autoWireToggle("notifyPluginOrSettingUpdated", { renderObsidianSetting(paneEl, "notifyPluginOrSettingUpdated", {
onUpdate: visibleOnlyOnPluginSyncEnabled, onUpdate: visibleOnlyOnPluginSyncEnabled,
}); });
@@ -1,6 +1,7 @@
import { $msg, $t } from "@lib/common/i18n.ts"; import { $msg, $t } from "@lib/common/i18n.ts";
import { SUPPORTED_I18N_LANGS, type I18N_LANGS } from "@lib/common/rosetta.ts"; import { SUPPORTED_I18N_LANGS, type I18N_LANGS } from "@lib/common/rosetta.ts";
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
import { visibleOnly } from "./SettingPane.ts"; import { visibleOnly } from "./SettingPane.ts";
@@ -16,20 +17,20 @@ export function paneGeneral(
// ["", $msg("obsidianLiveSyncSettingTab.defaultLanguage")], // ["", $msg("obsidianLiveSyncSettingTab.defaultLanguage")],
...SUPPORTED_I18N_LANGS.map((e) => [e, $t(`lang-${e}`)]), ...SUPPORTED_I18N_LANGS.map((e) => [e, $t(`lang-${e}`)]),
]) as Record<I18N_LANGS, string>; ]) as Record<I18N_LANGS, string>;
new Setting(paneEl).autoWireDropDown("displayLanguage", { renderObsidianSetting(paneEl, "displayLanguage", {
options: languages, options: languages,
}); });
this.addOnSaved("displayLanguage", () => this.display()); this.addOnSaved("displayLanguage", () => this.display());
new Setting(paneEl).autoWireToggle("showStatusOnEditor"); renderObsidianSetting(paneEl, "showStatusOnEditor");
this.addOnSaved("showStatusOnEditor", () => { this.addOnSaved("showStatusOnEditor", () => {
eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR); eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR);
}); });
new Setting(paneEl).autoWireToggle("showOnlyIconsOnEditor", { renderObsidianSetting(paneEl, "showOnlyIconsOnEditor", {
onUpdate: visibleOnly(() => this.isConfiguredAs("showStatusOnEditor", true)), onUpdate: visibleOnly(() => this.isConfiguredAs("showStatusOnEditor", true)),
}); });
new Setting(paneEl).autoWireToggle("showStatusOnStatusbar"); renderObsidianSetting(paneEl, "showStatusOnStatusbar");
new Setting(paneEl).autoWireToggle("hideFileWarningNotice"); renderObsidianSetting(paneEl, "hideFileWarningNotice");
new Setting(paneEl).autoWireDropDown("networkWarningStyle", { renderObsidianSetting(paneEl, "networkWarningStyle", {
options: { options: {
[NetworkWarningStyles.BANNER]: "Show full banner", [NetworkWarningStyles.BANNER]: "Show full banner",
[NetworkWarningStyles.ICON]: "Show icon only", [NetworkWarningStyles.ICON]: "Show icon only",
@@ -43,9 +44,9 @@ export function paneGeneral(
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleLogging")).then((paneEl) => { void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleLogging")).then((paneEl) => {
paneEl.addClass("wizardHidden"); 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)), 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 { HiddenFileSync } from "@/features/HiddenFileSync/CmdHiddenFileSync.ts";
import { EVENT_REQUEST_SHOW_HISTORY } from "@/common/obsidianEvents.ts"; import { EVENT_REQUEST_SHOW_HISTORY } from "@/common/obsidianEvents.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
import { isNotFoundError } from "@lib/common/utils.doc.ts"; import { isNotFoundError } from "@lib/common/utils.doc.ts";
export function paneHatch(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void { 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); eventHub.emitEvent(EVENT_REQUEST_CHECK_REMOTE_SIZE);
}) })
); );
new Setting(paneEl).autoWireToggle("writeLogToTheFile"); renderObsidianSetting(paneEl, "writeLogToTheFile");
}); });
void addPanel(paneEl, "Scram Switches").then((paneEl) => { void addPanel(paneEl, "Scram Switches").then((paneEl) => {
new Setting(paneEl).autoWireToggle("suspendFileWatching"); renderObsidianSetting(paneEl, "suspendFileWatching");
this.addOnSaved("suspendFileWatching", () => this.services.appLifecycle.askRestart()); this.addOnSaved("suspendFileWatching", () => this.services.appLifecycle.askRestart());
new Setting(paneEl).autoWireToggle("suspendParseReplicationResult"); renderObsidianSetting(paneEl, "suspendParseReplicationResult");
this.addOnSaved("suspendParseReplicationResult", () => this.services.appLifecycle.askRestart()); this.addOnSaved("suspendParseReplicationResult", () => this.services.appLifecycle.askRestart());
}); });
@@ -7,6 +7,7 @@ import {
} from "@lib/common/types.ts"; } from "@lib/common/types.ts";
import { Logger } from "@lib/common/logger.ts"; import { Logger } from "@lib/common/logger.ts";
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
import { addObsidianApplyButton, renderObsidianApplyButton, renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
import { visibleOnly } 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 { export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
void addPanel(paneEl, "Compatibility (Metadata)").then((paneEl) => { 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)), onUpdate: visibleOnly(() => this.isConfiguredAs("deleteMetadataOfDeletedFiles", true)),
}); }).setClass("wizardHidden");
}); });
void addPanel(paneEl, "Compatibility (Conflict Behaviour)").then((paneEl) => { void addPanel(paneEl, "Compatibility (Conflict Behaviour)").then((paneEl) => {
paneEl.addClass("wizardHidden"); paneEl.addClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("disableMarkdownAutoMerge"); renderObsidianSetting(paneEl, "disableMarkdownAutoMerge").setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("writeDocumentsIfConflicted"); renderObsidianSetting(paneEl, "writeDocumentsIfConflicted").setClass("wizardHidden");
}); });
void addPanel(paneEl, "Compatibility (Database structure)").then((paneEl) => { 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) => { 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) => { void addPanel(paneEl, "Compatibility (Remote Database)").then((paneEl) => {
new Setting(paneEl).autoWireDropDown("E2EEAlgorithm", { renderObsidianSetting(paneEl, "E2EEAlgorithm", {
options: E2EEAlgorithmNames, options: E2EEAlgorithmNames,
}); });
}); });
new Setting(paneEl).autoWireToggle("useDynamicIterationCount", { renderObsidianSetting(paneEl, "useDynamicIterationCount", {
holdValue: true, holdValue: true,
onUpdate: visibleOnly( onUpdate: visibleOnly(
() => () =>
@@ -134,16 +135,15 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
}); });
void addPanel(paneEl, "Edge case addressing (Database)").then((paneEl) => { void addPanel(paneEl, "Edge case addressing (Database)").then((paneEl) => {
new Setting(paneEl) renderObsidianSetting(paneEl, "additionalSuffixOfDatabaseName");
.autoWireText("additionalSuffixOfDatabaseName", { holdValue: true }) renderObsidianApplyButton(paneEl, "database-suffix");
.addApplyButton(["additionalSuffixOfDatabaseName"]);
this.addOnSaved("additionalSuffixOfDatabaseName", async (key) => { this.addOnSaved("additionalSuffixOfDatabaseName", async (key) => {
Logger("Suffix has been changed. Reopening database...", LOG_LEVEL_NOTICE); Logger("Suffix has been changed. Reopening database...", LOG_LEVEL_NOTICE);
await this.services.databaseEvents.initialiseDatabase(); await this.services.databaseEvents.initialiseDatabase();
}); });
new Setting(paneEl).autoWireDropDown("hashAlg", { renderObsidianSetting(paneEl, "hashAlg", {
options: { options: {
"": "Old Algorithm", "": "Old Algorithm",
xxhash32: "xxhash32 (Fast but less collision resistance)", 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) => { void addPanel(paneEl, "Edge case addressing (Behaviour)").then((paneEl) => {
new Setting(paneEl).autoWireToggle("doNotSuspendOnFetching"); renderObsidianSetting(paneEl, "doNotSuspendOnFetching");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("doNotDeleteFolder"); renderObsidianSetting(paneEl, "doNotDeleteFolder").setClass("wizardHidden");
new Setting(paneEl).autoWireToggle("processSizeMismatchedFiles"); renderObsidianSetting(paneEl, "processSizeMismatchedFiles");
}); });
void addPanel(paneEl, "Edge case addressing (Processing)").then((paneEl) => { 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)), onUpdate: visibleOnly(() => this.isConfiguredAs("disableWorkerForGeneratingChunks", false)),
}); });
}); });
@@ -173,11 +173,11 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
// new Setting(paneEl).autoWireToggle("useRequestAPI"); // new Setting(paneEl).autoWireToggle("useRequestAPI");
// }); // });
void addPanel(paneEl, "Compatibility (Trouble addressed)").then((paneEl) => { void addPanel(paneEl, "Compatibility (Trouble addressed)").then((paneEl) => {
new Setting(paneEl).autoWireToggle("disableCheckingConfigMismatch"); renderObsidianSetting(paneEl, "disableCheckingConfigMismatch");
}); });
void addPanel(paneEl, "Remediation").then((paneEl) => { void addPanel(paneEl, "Remediation").then((paneEl) => {
let dateEl: HTMLSpanElement; let dateEl: HTMLSpanElement;
new Setting(paneEl) const remediationSetting = new Setting(paneEl)
.addText((text) => { .addText((text) => {
const updateDateText = () => { const updateDateText = () => {
if (this.editingSettings.maxMTimeForReflectEvents == 0) { if (this.editingSettings.maxMTimeForReflectEvents == 0) {
@@ -212,8 +212,8 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
updateDateText(); updateDateText();
return text; return text;
}) })
.setAuto("maxMTimeForReflectEvents") .setAuto("maxMTimeForReflectEvents");
.addApplyButton(["maxMTimeForReflectEvents"]); addObsidianApplyButton(remediationSetting, "remediation-reflect-events");
this.addOnSaved("maxMTimeForReflectEvents", async (key) => { this.addOnSaved("maxMTimeForReflectEvents", async (key) => {
const buttons = ["Restart Now", "Later"] as const; const buttons = ["Restart Now", "Later"] as const;
@@ -240,6 +240,6 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
// .setClass("wizardHidden"); // .setClass("wizardHidden");
// new Setting(paneEl).autoWireNumeric("maxAgeInEden", { onUpdate: onlyUsingEden }).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 { 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 { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
@@ -21,14 +21,14 @@ export function panePowerUsers(
this.onlyOnCouchDB this.onlyOnCouchDB
).addClass("wizardHidden"); ).addClass("wizardHidden");
new Setting(paneEl) renderObsidianSetting(paneEl, "batch_size", { clampMin: 2, onUpdate: this.onlyOnCouchDB }).setClass(
.setClass("wizardHidden") "wizardHidden"
.autoWireNumeric("batch_size", { clampMin: 2, onUpdate: this.onlyOnCouchDB }); );
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batches_limit", { renderObsidianSetting(paneEl, "batches_limit", {
clampMin: 2, clampMin: 2,
onUpdate: this.onlyOnCouchDB, onUpdate: this.onlyOnCouchDB,
}); }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("useTimeouts", { onUpdate: this.onlyOnCouchDB }); renderObsidianSetting(paneEl, "useTimeouts", { onUpdate: this.onlyOnCouchDB }).setClass("wizardHidden");
}); });
void addPanel(paneEl, "Configuration Encryption").then((paneEl) => { void addPanel(paneEl, "Configuration Encryption").then((paneEl) => {
const passphrase_options: Record<ConfigPassphraseStore, string> = { const passphrase_options: Record<ConfigPassphraseStore, string> = {
@@ -37,23 +37,18 @@ export function panePowerUsers(
ASK_AT_LAUNCH: "Ask an passphrase at every launch", ASK_AT_LAUNCH: "Ask an passphrase at every launch",
}; };
new Setting(paneEl) renderObsidianSetting(paneEl, "configPassphraseStore", {
.setName("Encrypting sensitive configuration items") options: passphrase_options,
.autoWireDropDown("configPassphraseStore", { }).setClass("wizardHidden");
options: passphrase_options,
holdValue: true,
})
.setClass("wizardHidden");
new Setting(paneEl) renderObsidianSetting(paneEl, "configPassphrase")
.autoWireText("configPassphrase", { isPassword: true, holdValue: true })
.setClass("wizardHidden") .setClass("wizardHidden")
.addOnUpdate(() => ({ .addOnUpdate(() => ({
disabled: !this.isConfiguredAs("configPassphraseStore", "LOCALSTORAGE"), 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) => { 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 { Menu, type ButtonComponent } from "@/deps.ts";
import { $msg } from "@lib/common/i18n.ts"; import { $msg } from "@lib/common/i18n.ts";
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
// import { visibleOnly } from "./SettingPane.ts"; // import { visibleOnly } from "./SettingPane.ts";
@@ -674,7 +675,7 @@ export function paneRemoteConfig(
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleNotification"), () => {}).then((paneEl) => { void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleNotification"), () => {}).then((paneEl) => {
paneEl.addClass("wizardHidden"); paneEl.addClass("wizardHidden");
new Setting(paneEl).autoWireNumeric("notifyThresholdOfRemoteStorageSize", {}).setClass("wizardHidden"); renderObsidianSetting(paneEl, "notifyThresholdOfRemoteStorageSize", {}).setClass("wizardHidden");
}); });
// new Setting(paneEl).setClass("wizardOnly").addButton((button) => // new Setting(paneEl).setClass("wizardOnly").addButton((button) =>
@@ -4,6 +4,7 @@ import MultipleRegExpControl from "./MultipleRegExpControl.svelte";
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts"; import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
import { mount } from "svelte"; import { mount } from "svelte";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
import { visibleOnly } from "./SettingPane.ts"; import { visibleOnly } from "./SettingPane.ts";
export function paneSelector(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void { 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"); renderObsidianSetting(paneEl, "useIgnoreFiles").setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireTextArea("ignoreFiles", { renderObsidianSetting(paneEl, "ignoreFiles", {
onUpdate: visibleOnly(() => this.isConfiguredAs("useIgnoreFiles", true)), onUpdate: visibleOnly(() => this.isConfiguredAs("useIgnoreFiles", true)),
}); }).setClass("wizardHidden");
}); });
void addPanel(paneEl, "Hidden Files", undefined, undefined, LEVEL_ADVANCED).then((paneEl) => { void addPanel(paneEl, "Hidden Files", undefined, undefined, LEVEL_ADVANCED).then((paneEl) => {
const targetPatternSetting = new Setting(paneEl) const targetPatternSetting = new Setting(paneEl)
@@ -15,6 +15,7 @@ import { DEFAULT_SETTINGS } from "@lib/common/types.ts";
import { request } from "@/deps.ts"; import { request } from "@/deps.ts";
import { SetupManager, UserMode } from "@/modules/features/SetupManager.ts"; import { SetupManager, UserMode } from "@/modules/features/SetupManager.ts";
import { LiveSyncError } from "@lib/common/LSError.ts"; import { LiveSyncError } from "@lib/common/LSError.ts";
import { renderObsidianSetting } from "./ObsidianSettingRenderer.ts";
export function paneSetup( export function paneSetup(
this: ObsidianLiveSyncSettingTab, this: ObsidianLiveSyncSettingTab,
paneEl: HTMLElement, paneEl: HTMLElement,
@@ -107,10 +108,9 @@ export function paneSetup(
}); });
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleExtraFeatures")).then((paneEl) => { void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleExtraFeatures")).then((paneEl) => {
new Setting(paneEl).autoWireToggle("useAdvancedMode"); renderObsidianSetting(paneEl, "useAdvancedMode");
renderObsidianSetting(paneEl, "usePowerUserMode");
new Setting(paneEl).autoWireToggle("usePowerUserMode"); renderObsidianSetting(paneEl, "useEdgeCaseMode");
new Setting(paneEl).autoWireToggle("useEdgeCaseMode");
this.addOnSaved("useAdvancedMode", () => this.display()); this.addOnSaved("useAdvancedMode", () => this.display());
this.addOnSaved("usePowerUserMode", () => 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 { Logger } from "@lib/common/logger.ts";
import { $msg } from "@lib/common/i18n.ts"; import { $msg } from "@lib/common/i18n.ts";
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.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 { EVENT_REQUEST_COPY_SETUP_URI, eventHub } from "@/common/events.ts";
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts"; import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
import type { PageFunctions } from "./SettingPane.ts"; import type { PageFunctions } from "./SettingPane.ts";
@@ -31,18 +32,16 @@ export function paneSyncSettings(
DISABLE: $msg("obsidianLiveSyncSettingTab.optionDisableAllAutomatic"), DISABLE: $msg("obsidianLiveSyncSettingTab.optionDisableAllAutomatic"),
}; };
new Setting(paneEl) renderObsidianSetting(paneEl, "preset", {
.autoWireDropDown("preset", { options: options,
options: options, holdValue: true,
holdValue: true, }).addButton((button) => {
}) button.setButtonText($msg("obsidianLiveSyncSettingTab.btnApply"));
.addButton((button) => { button.onClick(async () => {
button.setButtonText($msg("obsidianLiveSyncSettingTab.btnApply")); // await this.saveSettings(["preset"]);
button.onClick(async () => { await this.saveAllDirtySettings();
// await this.saveSettings(["preset"]);
await this.saveAllDirtySettings();
});
}); });
});
this.addOnSaved("preset", async (currentPreset) => { this.addOnSaved("preset", async (currentPreset) => {
if (currentPreset == "") { if (currentPreset == "") {
@@ -136,7 +135,7 @@ export function paneSyncSettings(
const onlyOnNonLiveSync = visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC")); const onlyOnNonLiveSync = visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC"));
const onlyOnPeriodic = visibleOnly(() => this.isConfiguredAs("syncMode", "PERIODIC")); const onlyOnPeriodic = visibleOnly(() => this.isConfiguredAs("syncMode", "PERIODIC"));
const optionsSyncMode = const optionsSyncMode: Record<string, string> =
this.editingSettings.remoteType == REMOTE_COUCHDB this.editingSettings.remoteType == REMOTE_COUCHDB
? { ? {
ONEVENTS: $msg("obsidianLiveSyncSettingTab.optionOnEvents"), ONEVENTS: $msg("obsidianLiveSyncSettingTab.optionOnEvents"),
@@ -148,12 +147,9 @@ export function paneSyncSettings(
PERIODIC: $msg("obsidianLiveSyncSettingTab.optionPeriodicAndEvents"), PERIODIC: $msg("obsidianLiveSyncSettingTab.optionPeriodicAndEvents"),
}; };
new Setting(paneEl) renderObsidianSetting(paneEl, "syncMode", {
.autoWireDropDown("syncMode", { options: optionsSyncMode,
//@ts-ignore }).setClass("wizardHidden");
options: optionsSyncMode,
})
.setClass("wizardHidden");
this.addOnSaved("syncMode", async (value) => { this.addOnSaved("syncMode", async (value) => {
this.editingSettings.liveSync = false; this.editingSettings.liveSync = false;
this.editingSettings.periodicReplication = false; this.editingSettings.periodicReplication = false;
@@ -167,32 +163,28 @@ export function paneSyncSettings(
await this.services.control.applySettings(); await this.services.control.applySettings();
}); });
new Setting(paneEl) renderObsidianSetting(paneEl, "periodicReplicationInterval", {
.autoWireNumeric("periodicReplicationInterval", { clampMax: 5000,
clampMax: 5000, onUpdate: onlyOnPeriodic,
onUpdate: onlyOnPeriodic, }).setClass("wizardHidden");
})
.setClass("wizardHidden");
new Setting(paneEl).autoWireNumeric("syncMinimumInterval", { renderObsidianSetting(paneEl, "syncMinimumInterval", {
onUpdate: onlyOnNonLiveSync, onUpdate: onlyOnNonLiveSync,
}); });
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnSave", { onUpdate: onlyOnNonLiveSync }); renderObsidianSetting(paneEl, "syncOnSave", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
new Setting(paneEl) renderObsidianSetting(paneEl, "syncOnEditorSave", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
.setClass("wizardHidden") renderObsidianSetting(paneEl, "syncOnFileOpen", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
.autoWireToggle("syncOnEditorSave", { onUpdate: onlyOnNonLiveSync }); renderObsidianSetting(paneEl, "syncOnStart", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnFileOpen", { onUpdate: onlyOnNonLiveSync }); renderObsidianSetting(paneEl, "syncAfterMerge", { onUpdate: onlyOnNonLiveSync }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncOnStart", { onUpdate: onlyOnNonLiveSync });
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncAfterMerge", { onUpdate: onlyOnNonLiveSync });
// Desktop app only, and only for the sync modes that keep a background replication channel // 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 // (LiveSync and Periodic). Ignored on mobile, where suspending preserves battery. The
// visibility predicate mirrors the runtime guard in ModuleObsidianEvents. // visibility predicate mirrors the runtime guard in ModuleObsidianEvents.
if (!this.services.API.isMobile()) { if (!this.services.API.isMobile()) {
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("keepReplicationActiveInBackground", { renderObsidianSetting(paneEl, "keepReplicationActiveInBackground", {
onUpdate: visibleOnly( onUpdate: visibleOnly(
() => this.isConfiguredAs("syncMode", "LIVESYNC") || this.isConfiguredAs("syncMode", "PERIODIC") () => this.isConfiguredAs("syncMode", "LIVESYNC") || this.isConfiguredAs("syncMode", "PERIODIC")
), ),
}); }).setClass("wizardHidden");
} }
}); });
@@ -203,15 +195,15 @@ export function paneSyncSettings(
visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC")) visibleOnly(() => !this.isConfiguredAs("syncMode", "LIVESYNC"))
).then((paneEl) => { ).then((paneEl) => {
paneEl.addClass("wizardHidden"); paneEl.addClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("batchSave"); renderObsidianSetting(paneEl, "batchSave").setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batchSaveMinimumDelay", { renderObsidianSetting(paneEl, "batchSaveMinimumDelay", {
acceptZero: true, acceptZero: true,
onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)), onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)),
}); }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("batchSaveMaximumDelay", { renderObsidianSetting(paneEl, "batchSaveMaximumDelay", {
acceptZero: true, acceptZero: true,
onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)), onUpdate: visibleOnly(() => this.isConfiguredAs("batchSave", true)),
}); }).setClass("wizardHidden");
}); });
void addPanel( void addPanel(
@@ -222,9 +214,9 @@ export function paneSyncSettings(
LEVEL_ADVANCED LEVEL_ADVANCED
).then((paneEl) => { ).then((paneEl) => {
paneEl.addClass("wizardHidden"); 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( void addPanel(
paneEl, paneEl,
@@ -235,11 +227,11 @@ export function paneSyncSettings(
).then((paneEl) => { ).then((paneEl) => {
paneEl.addClass("wizardHidden"); 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( void addPanel(
@@ -250,11 +242,12 @@ export function paneSyncSettings(
LEVEL_ADVANCED LEVEL_ADVANCED
).then((paneEl) => { ).then((paneEl) => {
paneEl.addClass("wizardHidden"); 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( void addPanel(
@@ -313,14 +306,14 @@ export function paneSyncSettings(
}); });
} }
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("suppressNotifyHiddenFilesChange", {}); renderObsidianSetting(paneEl, "suppressNotifyHiddenFilesChange", {}).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireToggle("syncInternalFilesBeforeReplication", { renderObsidianSetting(paneEl, "syncInternalFilesBeforeReplication", {
onUpdate: visibleOnly(() => this.isConfiguredAs("watchInternalFileChanges", true)), onUpdate: visibleOnly(() => this.isConfiguredAs("watchInternalFileChanges", true)),
}); }).setClass("wizardHidden");
new Setting(paneEl).setClass("wizardHidden").autoWireNumeric("syncInternalFilesInterval", { renderObsidianSetting(paneEl, "syncInternalFilesInterval", {
clampMin: 10, clampMin: 10,
acceptZero: true, acceptZero: true,
}); }).setClass("wizardHidden");
}); });
} }
@@ -1,5 +1,11 @@
import { $msg } from "@lib/common/i18n"; 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"; import type { AllSettingItemKey, AllSettings } from "./settingConstants";
export const combineOnUpdate = (func1: OnUpdateFunc, func2: OnUpdateFunc): OnUpdateFunc => { export const combineOnUpdate = (func1: OnUpdateFunc, func2: OnUpdateFunc): OnUpdateFunc => {
@@ -77,6 +83,7 @@ export type AutoWireOption = {
invert?: boolean; invert?: boolean;
onUpdate?: OnUpdateFunc; onUpdate?: OnUpdateFunc;
obsolete?: boolean; obsolete?: boolean;
settingDefinition?: SettingDefinition<AllSettingItemKey>;
}; };
export function findAttrFromParent(el: HTMLElement, attr: string): string { export function findAttrFromParent(el: HTMLElement, attr: string): string {