mirror of
https://github.com/vrtmrz/obsidian-livesync.git
synced 2026-07-25 14:02:58 +00:00
Improve postponed conflict resolution handling
Keep unresolved conflicts visible after Not now, reopen them only on explicit requests, and clear stale warning and dialogue state when a replicated resolution arrives. Add typed provisional English messages, revision-tree regressions, specifications, and a focused Real Obsidian E2E.
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Canonical English for LiveSync-owned messages whose wording is still being
|
||||
* exercised. These keys remain application-owned and must not be added to
|
||||
* Commonlib merely to make them available to the LiveSync translator.
|
||||
*
|
||||
* Move a message to the YAML catalogue when it is ready for translation, and
|
||||
* remove it from this map in the same change.
|
||||
*/
|
||||
export const liveSyncProvisionalEnglishMessages = {
|
||||
"This file has unresolved conflicts.": "This file has unresolved conflicts.",
|
||||
} as const;
|
||||
|
||||
export type LiveSyncProvisionalMessageKey = keyof typeof liveSyncProvisionalEnglishMessages;
|
||||
@@ -65,7 +65,9 @@ export type I18N_LANGS =
|
||||
export type MESSAGE = { [key in I18N_LANGS]?: string };
|
||||
|
||||
import { Logger } from "octagonal-wheels/common/logger";
|
||||
import type { CommonlibMessageKey } from "@vrtmrz/livesync-commonlib/context";
|
||||
import type { MessageKeys } from "./messages/combinedMessages.dev.ts";
|
||||
import type { LiveSyncProvisionalMessageKey } from "./messages/LiveSyncProvisionalMessages.ts";
|
||||
|
||||
export function expandKeywords<T extends Record<string, U>, U extends Record<string, string>>(
|
||||
message: T,
|
||||
@@ -114,4 +116,8 @@ export function expandKeywords<T extends Record<string, U>, U extends Record<str
|
||||
return ret as T;
|
||||
}
|
||||
|
||||
export type AllMessageKeys = MessageKeys;
|
||||
/** Keys translated by LiveSync itself, including English-only provisional messages. */
|
||||
export type LiveSyncCatalogueMessageKey = MessageKeys | LiveSyncProvisionalMessageKey;
|
||||
|
||||
/** Keys accepted by the composed LiveSync and Commonlib translation boundary. */
|
||||
export type AllMessageKeys = LiveSyncCatalogueMessageKey | CommonlibMessageKey;
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
// Avoid using Obsidian's native function for CLIs.
|
||||
import { getLanguage } from "@vrtmrz/livesync-commonlib/compat/common/coreEnvFunctions";
|
||||
import { englishMessageTranslator, type MessageTranslator } from "@vrtmrz/livesync-commonlib/context";
|
||||
import {
|
||||
commonlibEnglishMessages,
|
||||
englishMessageTranslator,
|
||||
type CommonlibMessageKey,
|
||||
type MessageTranslator,
|
||||
} from "@vrtmrz/livesync-commonlib/context";
|
||||
import { LOG_KIND_WARNING, notice } from "octagonal-wheels/common/logger";
|
||||
import type { TaggedType } from "octagonal-wheels/common/types";
|
||||
import type { AllMessageKeys, I18N_LANGS } from "./rosetta";
|
||||
import type { AllMessageKeys, I18N_LANGS, LiveSyncCatalogueMessageKey } from "./rosetta";
|
||||
import { allMessages } from "./messages/combinedMessages.prod.ts";
|
||||
import {
|
||||
liveSyncProvisionalEnglishMessages,
|
||||
type LiveSyncProvisionalMessageKey,
|
||||
} from "./messages/LiveSyncProvisionalMessages.ts";
|
||||
|
||||
const obsidianLangMap: Record<string, I18N_LANGS> = {
|
||||
de: "de",
|
||||
@@ -58,7 +67,10 @@ export function setLang(lang: I18N_LANGS) {
|
||||
function _getMessage(key: string, lang: I18N_LANGS) {
|
||||
if (key.trim() == "") return key;
|
||||
|
||||
const msgs = allMessages[key] ?? undefined;
|
||||
const provisionalEnglish = liveSyncProvisionalEnglishMessages[key as LiveSyncProvisionalMessageKey];
|
||||
const msgs =
|
||||
allMessages[key] ?? (provisionalEnglish === undefined ? undefined : ({ def: provisionalEnglish } as const));
|
||||
if (msgs === undefined && isCommonlibMessageKey(key)) return englishMessageTranslator(key);
|
||||
const resolvedLang = resolveLanguage(lang);
|
||||
let msg = msgs?.[resolvedLang];
|
||||
|
||||
@@ -87,12 +99,16 @@ export function $t(message: string, lang?: I18N_LANGS) {
|
||||
}
|
||||
|
||||
export function translateIfAvailable(message: string, lang?: I18N_LANGS) {
|
||||
if (message.trim() == "" || allMessages[message] === undefined) return message;
|
||||
if (message.trim() == "" || (!isLiveSyncMessageKey(message) && !isCommonlibMessageKey(message))) return message;
|
||||
return $t(message, lang);
|
||||
}
|
||||
|
||||
function isLiveSyncMessageKey(key: string): key is AllMessageKeys {
|
||||
return key in allMessages;
|
||||
function isCommonlibMessageKey(key: string): key is CommonlibMessageKey {
|
||||
return key in commonlibEnglishMessages;
|
||||
}
|
||||
|
||||
function isLiveSyncMessageKey(key: string): key is LiveSyncCatalogueMessageKey {
|
||||
return key in allMessages || key in liveSyncProvisionalEnglishMessages;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,7 +140,9 @@ export function $msg<T extends AllMessageKeys>(
|
||||
}
|
||||
|
||||
/** Supplies the LiveSync-owned language catalogue through the Commonlib host boundary. */
|
||||
export const translateLiveSyncMessage: MessageTranslator = (key, params) => {
|
||||
if (!isLiveSyncMessageKey(key)) return englishMessageTranslator(key, params);
|
||||
export type LiveSyncMessageTranslator = MessageTranslator<AllMessageKeys>;
|
||||
|
||||
export const translateLiveSyncMessage: LiveSyncMessageTranslator = (key, params) => {
|
||||
if (!isLiveSyncMessageKey(key)) return englishMessageTranslator(key as CommonlibMessageKey, params);
|
||||
return $msg(key, params === undefined ? undefined : { ...params });
|
||||
};
|
||||
|
||||
@@ -25,4 +25,11 @@ describe("LiveSync-owned translation catalogue", () => {
|
||||
|
||||
expect(translateLiveSyncMessage("Active Remote Type")).toBe(englishMessageTranslator("Active Remote Type"));
|
||||
});
|
||||
|
||||
it("uses LiveSync-owned provisional English without extending Commonlib's message contract", () => {
|
||||
expect($msg("This file has unresolved conflicts.")).toBe("This file has unresolved conflicts.");
|
||||
expect(translateLiveSyncMessage("This file has unresolved conflicts.")).toBe(
|
||||
"This file has unresolved conflicts."
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user