mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-26 05:17:06 +00:00
Refine mobile settings action layout markers
This commit is contained in:
@@ -9,7 +9,7 @@ import { Logger } from "@vrtmrz/livesync-commonlib/compat/common/logger";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import type { PageFunctions } from "./SettingPane.ts";
|
||||
import { visibleOnly } from "./SettingPane.ts";
|
||||
import { markSettingRowWithSubsequentButtons, markSubsequentButton, visibleOnly } from "./SettingPane.ts";
|
||||
import { PouchDB } from "@vrtmrz/livesync-commonlib/compat/pouchdb/pouchdb-browser";
|
||||
import { ExtraSuffixIndexedDB } from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
import { migrateDatabases } from "./settingUtils.ts";
|
||||
@@ -177,7 +177,7 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
new Setting(paneEl).autoWireToggle("disableCheckingConfigMismatch");
|
||||
});
|
||||
void addPanel(paneEl, "Remediation").then((paneEl) => {
|
||||
const setting = new Setting(paneEl).setClass("sls-setting-subsequent-buttons");
|
||||
const setting = markSettingRowWithSubsequentButtons(new Setting(paneEl));
|
||||
const dateEl = setting.controlEl.createSpan();
|
||||
setting
|
||||
.addText((text) => {
|
||||
@@ -215,6 +215,9 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
|
||||
})
|
||||
.setAuto("maxMTimeForReflectEvents")
|
||||
.addApplyButton(["maxMTimeForReflectEvents"]);
|
||||
if (setting.applyButtonComponent) {
|
||||
markSubsequentButton(setting.applyButtonComponent);
|
||||
}
|
||||
|
||||
this.addOnSaved("maxMTimeForReflectEvents", async (key) => {
|
||||
const buttons = ["Restart Now", "Later"] as const;
|
||||
|
||||
@@ -12,9 +12,11 @@ const remediationHarness = vi.hoisted(() => {
|
||||
onChange: vi.fn(),
|
||||
setValue: vi.fn(),
|
||||
};
|
||||
const addButtonClass = vi.fn();
|
||||
const setClass = vi.fn();
|
||||
|
||||
return {
|
||||
addButtonClass,
|
||||
createSpan,
|
||||
dateElement,
|
||||
inputEl,
|
||||
@@ -25,6 +27,11 @@ const remediationHarness = vi.hoisted(() => {
|
||||
|
||||
vi.mock("./LiveSyncSetting.ts", () => ({
|
||||
LiveSyncSetting: class LiveSyncSetting {
|
||||
applyButtonComponent = {
|
||||
buttonEl: {
|
||||
addClass: remediationHarness.addButtonClass,
|
||||
},
|
||||
};
|
||||
controlEl = {
|
||||
createSpan: remediationHarness.createSpan,
|
||||
};
|
||||
@@ -100,6 +107,7 @@ describe("panePatches remediation setting", () => {
|
||||
expect(createSpan).not.toHaveBeenCalled();
|
||||
expect(remediationHarness.createSpan).toHaveBeenCalledOnce();
|
||||
expect(remediationHarness.dateElement.textContent).toBe("No limit configured");
|
||||
expect(remediationHarness.setClass).toHaveBeenCalledWith("sls-setting-subsequent-buttons");
|
||||
expect(remediationHarness.setClass).toHaveBeenCalledWith("sls-setting-row-with-subsequent-buttons");
|
||||
expect(remediationHarness.addButtonClass).toHaveBeenCalledWith("sls-setting-subsequent-button");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -11,7 +11,12 @@ import { Menu, type ButtonComponent } from "@/deps.ts";
|
||||
import { $msg } from "@/common/translation";
|
||||
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
|
||||
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
|
||||
import { setButtonDestructiveState, type PageFunctions } from "./SettingPane.ts";
|
||||
import {
|
||||
markSettingRowWithSubsequentButtons,
|
||||
markSubsequentButton,
|
||||
setButtonDestructiveState,
|
||||
type PageFunctions,
|
||||
} from "./SettingPane.ts";
|
||||
// import { visibleOnly } from "./SettingPane.ts";
|
||||
import InfoPanel from "./InfoPanel.svelte";
|
||||
import { writable } from "svelte/store";
|
||||
@@ -105,12 +110,10 @@ export function paneRemoteConfig(
|
||||
void addPanel(paneEl, "E2EE Configuration", () => {}).then((paneEl) => {
|
||||
const infoPanel = new SveltePanel(InfoPanel, paneEl, E2EESummaryWritable);
|
||||
this.lifetimeComponent.register(() => infoPanel.destroy());
|
||||
const setupButton = new Setting(paneEl)
|
||||
.setName("Configure E2EE")
|
||||
.setClass("sls-setting-subsequent-buttons");
|
||||
const setupButton = markSettingRowWithSubsequentButtons(new Setting(paneEl).setName("Configure E2EE"));
|
||||
setupButton
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
setButtonDestructiveState(markSubsequentButton(button))
|
||||
.onClick(async () => {
|
||||
const setupManager = this.core.getModule(SetupManager);
|
||||
const originalSettings = getSettingsFromEditingSettings(this.editingSettings);
|
||||
@@ -120,7 +123,7 @@ export function paneRemoteConfig(
|
||||
.setButtonText("Configure")
|
||||
)
|
||||
.addButton((button) =>
|
||||
setButtonDestructiveState(button)
|
||||
setButtonDestructiveState(markSubsequentButton(button))
|
||||
.onClick(async () => {
|
||||
const setupManager = this.core.getModule(SetupManager);
|
||||
const originalSettings = getSettingsFromEditingSettings(this.editingSettings);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
|
||||
const runtime = vi.hoisted(() => ({
|
||||
buttonClasses: [] as string[],
|
||||
panels: [] as Array<{ destroy: ReturnType<typeof vi.fn> }>,
|
||||
settingClasses: [] as string[],
|
||||
}));
|
||||
@@ -36,7 +37,20 @@ vi.mock("./LiveSyncSetting.ts", () => ({
|
||||
return this;
|
||||
}
|
||||
|
||||
addButton() {
|
||||
addButton(callback: (button: unknown) => void) {
|
||||
const button = {
|
||||
buttonEl: {
|
||||
addClass: (value: string) => runtime.buttonClasses.push(value),
|
||||
classList: { toggle: vi.fn() },
|
||||
},
|
||||
onClick() {
|
||||
return this;
|
||||
},
|
||||
setButtonText() {
|
||||
return this;
|
||||
},
|
||||
};
|
||||
callback(button);
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -91,6 +105,7 @@ function createPanelElement(): HTMLElement {
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
runtime.buttonClasses.length = 0;
|
||||
runtime.panels.length = 0;
|
||||
runtime.settingClasses.length = 0;
|
||||
vi.clearAllMocks();
|
||||
@@ -103,7 +118,13 @@ describe("paneRemoteConfig", () => {
|
||||
register: vi.fn((callback: () => unknown) => callbacks.push(callback)),
|
||||
unload: vi.fn(() => callbacks.splice(0).forEach((callback) => callback())),
|
||||
};
|
||||
const addPanel = vi.fn((_parent: HTMLElement, _heading: string) => Promise.resolve(createPanelElement()));
|
||||
const addPanel = vi.fn((_parent: HTMLElement, heading: string) => ({
|
||||
then(callback: (paneEl: HTMLElement) => void) {
|
||||
if (heading === "E2EE Configuration") {
|
||||
callback(createPanelElement());
|
||||
}
|
||||
},
|
||||
}));
|
||||
const host = {
|
||||
editingSettings: { remoteConfigurations: {} },
|
||||
core: { settings: { remoteConfigurations: {} } },
|
||||
@@ -112,7 +133,8 @@ describe("paneRemoteConfig", () => {
|
||||
|
||||
paneRemoteConfig.call(host as never, {} as HTMLElement, { addPanel } as never);
|
||||
await vi.waitFor(() => expect(runtime.panels).toHaveLength(1));
|
||||
expect(runtime.settingClasses).toContain("sls-setting-subsequent-buttons");
|
||||
expect(runtime.settingClasses).toContain("sls-setting-row-with-subsequent-buttons");
|
||||
expect(runtime.buttonClasses).toEqual(["sls-setting-subsequent-button", "sls-setting-subsequent-button"]);
|
||||
|
||||
lifetimeComponent.unload();
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
type ConfigLevel,
|
||||
} from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||
import type { AllSettingItemKey, AllSettings } from "./settingConstants";
|
||||
import type { ButtonComponent } from "@/deps.ts";
|
||||
import type { ButtonComponent, Setting } from "@/deps.ts";
|
||||
|
||||
export const combineOnUpdate = (func1: OnUpdateFunc, func2: OnUpdateFunc): OnUpdateFunc => {
|
||||
return () => ({
|
||||
@@ -58,6 +58,18 @@ export function setButtonDestructiveState(button: ButtonComponent, isDestructive
|
||||
return button;
|
||||
}
|
||||
|
||||
/** Marks a setting row whose selected action buttons may wrap onto separate lines. */
|
||||
export function markSettingRowWithSubsequentButtons<T extends Setting>(setting: T): T {
|
||||
setting.setClass("sls-setting-row-with-subsequent-buttons");
|
||||
return setting;
|
||||
}
|
||||
|
||||
/** Marks an action button which may wrap onto a later line in its setting row. */
|
||||
export function markSubsequentButton(button: ButtonComponent): ButtonComponent {
|
||||
button.buttonEl.addClass("sls-setting-subsequent-button");
|
||||
return button;
|
||||
}
|
||||
|
||||
export function visibleOnly(cond: () => boolean): OnUpdateFunc {
|
||||
return () => ({
|
||||
visibility: cond(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { ButtonComponent } from "@/deps.ts";
|
||||
import type { ButtonComponent, Setting } from "@/deps.ts";
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { setButtonDestructiveState } from "./SettingPane.ts";
|
||||
import { markSettingRowWithSubsequentButtons, markSubsequentButton, setButtonDestructiveState } from "./SettingPane.ts";
|
||||
|
||||
type CompatibleButton = ButtonComponent & {
|
||||
setDestructive?: () => ButtonComponent;
|
||||
@@ -10,6 +10,7 @@ type CompatibleButton = ButtonComponent & {
|
||||
function createButton(overrides: Partial<CompatibleButton> = {}): CompatibleButton {
|
||||
return {
|
||||
buttonEl: {
|
||||
addClass: vi.fn(),
|
||||
classList: {
|
||||
toggle: vi.fn(),
|
||||
},
|
||||
@@ -18,6 +19,30 @@ function createButton(overrides: Partial<CompatibleButton> = {}): CompatibleButt
|
||||
} as unknown as CompatibleButton;
|
||||
}
|
||||
|
||||
function createSetting(): Setting {
|
||||
return {
|
||||
setClass: vi.fn().mockReturnThis(),
|
||||
} as unknown as Setting;
|
||||
}
|
||||
|
||||
describe("markSettingRowWithSubsequentButtons", () => {
|
||||
it("marks only the supplied setting row as containing subsequent actions", () => {
|
||||
const setting = createSetting();
|
||||
|
||||
expect(markSettingRowWithSubsequentButtons(setting)).toBe(setting);
|
||||
expect(setting.setClass).toHaveBeenCalledWith("sls-setting-row-with-subsequent-buttons");
|
||||
});
|
||||
});
|
||||
|
||||
describe("markSubsequentButton", () => {
|
||||
it("marks only the supplied button as a subsequent action", () => {
|
||||
const button = createButton();
|
||||
|
||||
expect(markSubsequentButton(button)).toBe(button);
|
||||
expect(button.buttonEl.addClass).toHaveBeenCalledWith("sls-setting-subsequent-button");
|
||||
});
|
||||
});
|
||||
|
||||
describe("setButtonDestructiveState", () => {
|
||||
it("uses the native destructive-button API when it is available", () => {
|
||||
const setDestructive = vi.fn();
|
||||
|
||||
+3
-3
@@ -547,17 +547,17 @@ body.is-mobile .sls-setting button {
|
||||
white-space: normal;
|
||||
}
|
||||
|
||||
body.is-mobile .sls-setting-subsequent-buttons {
|
||||
body.is-mobile .sls-setting-row-with-subsequent-buttons {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
body.is-mobile .sls-setting-subsequent-buttons .setting-item-control {
|
||||
body.is-mobile .sls-setting-row-with-subsequent-buttons .setting-item-control {
|
||||
min-width: 0;
|
||||
flex: 1 1 100%;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
body.is-mobile .sls-setting-subsequent-buttons .setting-item-control > button {
|
||||
body.is-mobile .sls-setting .sls-setting-subsequent-button {
|
||||
flex: 1 1 12rem;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user