mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-08-30 07:17:05 +00:00
Merge pull request #1123 from nimula/fix/settings-manifest-translator
Wire the display-language translator into the settings manifest
This commit is contained in:
@@ -4,7 +4,8 @@ import {
|
|||||||
TweakValuesShouldMatchedTemplate,
|
TweakValuesShouldMatchedTemplate,
|
||||||
TweakValuesTemplate,
|
TweakValuesTemplate,
|
||||||
IncompatibleChanges,
|
IncompatibleChanges,
|
||||||
confName,
|
configurationNames,
|
||||||
|
statusDisplay,
|
||||||
type TweakValues,
|
type TweakValues,
|
||||||
type ObsidianLiveSyncSettings,
|
type ObsidianLiveSyncSettings,
|
||||||
type RemoteDBSettings,
|
type RemoteDBSettings,
|
||||||
@@ -15,11 +16,21 @@ import {
|
|||||||
} from "@vrtmrz/livesync-commonlib/compat/common/types";
|
} from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||||
import { escapeMarkdownValue } from "@vrtmrz/livesync-commonlib/compat/common/utils";
|
import { escapeMarkdownValue } from "@vrtmrz/livesync-commonlib/compat/common/utils";
|
||||||
import { AbstractModule } from "@/modules/AbstractModule.ts";
|
import { AbstractModule } from "@/modules/AbstractModule.ts";
|
||||||
import { $msg } from "@/common/translation";
|
import { $msg, translateIfAvailable } from "@/common/translation";
|
||||||
import type { InjectableServiceHub } from "@vrtmrz/livesync-commonlib/compat/services/implements/injectable/InjectableServiceHub";
|
import type { InjectableServiceHub } from "@vrtmrz/livesync-commonlib/compat/services/implements/injectable/InjectableServiceHub";
|
||||||
import type { LiveSyncCore } from "@/main.ts";
|
import type { LiveSyncCore } from "@/main.ts";
|
||||||
import { REMOTE_P2P } from "@vrtmrz/livesync-commonlib/compat/common/models/setting.const";
|
import { REMOTE_P2P } from "@vrtmrz/livesync-commonlib/compat/common/models/setting.const";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Localised counterpart of Commonlib's `confName()`, which takes no translator.
|
||||||
|
* Same shape: label plus status suffix, and an empty string for an unknown key.
|
||||||
|
*/
|
||||||
|
function localisedConfName(key: keyof ObsidianLiveSyncSettings): string {
|
||||||
|
const info = configurationNames[key];
|
||||||
|
if (!info) return "";
|
||||||
|
return `${translateIfAvailable(info.name)}${statusDisplay(info.status)}`;
|
||||||
|
}
|
||||||
|
|
||||||
function valueToString(value: string | number | boolean | object | undefined): string {
|
function valueToString(value: string | number | boolean | object | undefined): string {
|
||||||
if (typeof value === "boolean") {
|
if (typeof value === "boolean") {
|
||||||
return value ? "true" : "false";
|
return value ? "true" : "false";
|
||||||
@@ -158,7 +169,7 @@ export class ModuleResolvingMismatchedTweaks extends AbstractModule {
|
|||||||
// table += `| ${confName(key)} | ${valueMine} | ${valuePreferred} | \n`;
|
// table += `| ${confName(key)} | ${valueMine} | ${valuePreferred} | \n`;
|
||||||
tableRows.push(
|
tableRows.push(
|
||||||
$msg("TweakMismatchResolve.Table.Row", {
|
$msg("TweakMismatchResolve.Table.Row", {
|
||||||
name: confName(key),
|
name: localisedConfName(key),
|
||||||
self: valueToString(valueMine),
|
self: valueToString(valueMine),
|
||||||
remote: valueToString(valuePreferred),
|
remote: valueToString(valuePreferred),
|
||||||
})
|
})
|
||||||
@@ -342,7 +353,7 @@ export class ModuleResolvingMismatchedTweaks extends AbstractModule {
|
|||||||
}
|
}
|
||||||
tableRows.push(
|
tableRows.push(
|
||||||
$msg("TweakMismatchResolve.Table.Row", {
|
$msg("TweakMismatchResolve.Table.Row", {
|
||||||
name: confName(key),
|
name: localisedConfName(key),
|
||||||
self: currentValueForDisplay,
|
self: currentValueForDisplay,
|
||||||
remote: remoteValueForDisplay,
|
remote: remoteValueForDisplay,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { describe, expect, it, vi } from "vitest";
|
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||||
import {
|
import {
|
||||||
DEFAULT_SETTINGS,
|
DEFAULT_SETTINGS,
|
||||||
REMOTE_COUCHDB,
|
REMOTE_COUCHDB,
|
||||||
@@ -6,6 +6,7 @@ import {
|
|||||||
type TweakValues,
|
type TweakValues,
|
||||||
} from "@vrtmrz/livesync-commonlib/compat/common/types";
|
} from "@vrtmrz/livesync-commonlib/compat/common/types";
|
||||||
import { ModuleResolvingMismatchedTweaks } from "./ModuleResolveMismatchedTweaks";
|
import { ModuleResolvingMismatchedTweaks } from "./ModuleResolveMismatchedTweaks";
|
||||||
|
import { setLang } from "@/common/translation";
|
||||||
|
|
||||||
function createModule(settingsOverride: Partial<typeof DEFAULT_SETTINGS> = {}) {
|
function createModule(settingsOverride: Partial<typeof DEFAULT_SETTINGS> = {}) {
|
||||||
const askSelectStringDialogue = vi.fn(async (..._args: unknown[]): Promise<string | undefined> => undefined);
|
const askSelectStringDialogue = vi.fn(async (..._args: unknown[]): Promise<string | undefined> => undefined);
|
||||||
@@ -255,3 +256,43 @@ describe("ModuleResolvingMismatchedTweaks", () => {
|
|||||||
expect(calls).toEqual(["save", "reinitialise", "set-preferred"]);
|
expect(calls).toEqual(["save", "reinitialise", "set-preferred"]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("ModuleResolvingMismatchedTweaks setting labels", () => {
|
||||||
|
afterEach(() => setLang("def"));
|
||||||
|
|
||||||
|
async function renderMismatchTable() {
|
||||||
|
const { module, askSelectStringDialogue } = createModule({
|
||||||
|
autoAcceptCompatibleTweak: true,
|
||||||
|
hashAlg: "xxhash64",
|
||||||
|
encrypt: false,
|
||||||
|
tweakModified: 100,
|
||||||
|
});
|
||||||
|
const preferred = {
|
||||||
|
...(DEFAULT_SETTINGS as unknown as TweakValues),
|
||||||
|
hashAlg: "xxhash32",
|
||||||
|
encrypt: true,
|
||||||
|
tweakModified: 200,
|
||||||
|
} as Partial<TweakValues>;
|
||||||
|
|
||||||
|
await module._checkAndAskResolvingMismatchedTweaks(preferred);
|
||||||
|
|
||||||
|
return String(askSelectStringDialogue.mock.calls[0]?.[0] ?? "");
|
||||||
|
}
|
||||||
|
|
||||||
|
it("localises the setting names and keeps the status suffix", async () => {
|
||||||
|
setLang("zh-tw");
|
||||||
|
|
||||||
|
const message = await renderMismatchTable();
|
||||||
|
|
||||||
|
expect(message).toContain("chunk ID 的雜湊演算法 (Experimental)");
|
||||||
|
expect(message).toContain("端對端加密");
|
||||||
|
expect(message).not.toContain("The Hash algorithm for chunk IDs");
|
||||||
|
});
|
||||||
|
|
||||||
|
it("leaves English unchanged", async () => {
|
||||||
|
const message = await renderMismatchTable();
|
||||||
|
|
||||||
|
expect(message).toContain("The Hash algorithm for chunk IDs (Experimental)");
|
||||||
|
expect(message).toContain("End-to-End Encryption");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
@@ -1 +1,37 @@
|
|||||||
export * from "@vrtmrz/livesync-commonlib/compat/common/settingConstants";
|
export {
|
||||||
|
AllSettingDefault,
|
||||||
|
OnDialogSettingsDefault,
|
||||||
|
SettingInformation,
|
||||||
|
} from "@vrtmrz/livesync-commonlib/compat/common/settingConstants";
|
||||||
|
export type {
|
||||||
|
AllSettings,
|
||||||
|
AllSettingItemKey,
|
||||||
|
AllStringItemKey,
|
||||||
|
AllNumericItemKey,
|
||||||
|
AllBooleanItemKey,
|
||||||
|
OnDialogSettings,
|
||||||
|
ValueOf,
|
||||||
|
} from "@vrtmrz/livesync-commonlib/compat/common/settingConstants";
|
||||||
|
|
||||||
|
import {
|
||||||
|
getConfig as getCommonlibConfig,
|
||||||
|
getConfName as getCommonlibConfName,
|
||||||
|
type AllSettingItemKey,
|
||||||
|
} from "@vrtmrz/livesync-commonlib/compat/common/settingConstants";
|
||||||
|
import type { MessageTranslator } from "@vrtmrz/livesync-commonlib/context";
|
||||||
|
import { translateLiveSyncMessage } from "@/common/translation";
|
||||||
|
|
||||||
|
// Commonlib defaults `translate` to its English-only translator, so every caller which omits
|
||||||
|
// it silently renders English regardless of `displayLanguage`. Default it to the LiveSync
|
||||||
|
// catalogue instead, and re-export these wrappers under the original names so that no call
|
||||||
|
// site has to remember the second argument.
|
||||||
|
|
||||||
|
/** `getConfig` with the LiveSync catalogue applied by default. */
|
||||||
|
export function getConfig(key: AllSettingItemKey, translate: MessageTranslator = translateLiveSyncMessage) {
|
||||||
|
return getCommonlibConfig(key, translate);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** `getConfName` with the LiveSync catalogue applied by default. See `getConfig`. */
|
||||||
|
export function getConfName(key: AllSettingItemKey, translate: MessageTranslator = translateLiveSyncMessage) {
|
||||||
|
return getCommonlibConfName(key, translate);
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
import { afterEach, describe, expect, it } from "vitest";
|
||||||
|
|
||||||
|
import { setLang } from "@/common/translation";
|
||||||
|
import { getConfig, getConfName } from "./settingConstants";
|
||||||
|
|
||||||
|
describe("setting manifest labels", () => {
|
||||||
|
afterEach(() => setLang("def"));
|
||||||
|
|
||||||
|
it("renders names and descriptions in the selected display language", () => {
|
||||||
|
setLang("zh-tw");
|
||||||
|
|
||||||
|
expect(getConfName("liveSync")).toBe("同步模式");
|
||||||
|
expect(getConfig("couchDB_URI")).toMatchObject({ name: "伺服器 URI" });
|
||||||
|
expect(getConfig("encrypt")).toMatchObject({
|
||||||
|
name: "端對端加密",
|
||||||
|
desc: "加密遠端資料庫中的內容。如果你使用外掛的同步功能,建議啟用此選項。",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("leaves English untouched, so that the catalogue key and its English value stay interchangeable", () => {
|
||||||
|
expect(getConfName("liveSync")).toBe("Sync Mode");
|
||||||
|
expect(getConfig("encrypt")).toMatchObject({
|
||||||
|
name: "End-to-End Encryption",
|
||||||
|
desc: "Encrypt contents on the remote database. If you use the plugin's synchronization feature, enabling this is recommended.",
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
it("passes through labels which Commonlib owns but the catalogue does not carry", () => {
|
||||||
|
setLang("zh-tw");
|
||||||
|
|
||||||
|
expect(getConfName("chunkSplitterVersion")).toBe("Chunk Splitter");
|
||||||
|
});
|
||||||
|
});
|
||||||
Reference in New Issue
Block a user