Skip to content

Commit 6cb485a

Browse files
committed
i18n: refresh runtime translations
1 parent 772b6ec commit 6cb485a

30 files changed

Lines changed: 505 additions & 415 deletions

src/lib

Submodule lib updated 52 files

src/modules/coreFeatures/ModuleRedFlag.ts

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import type { LiveSyncCore } from "../../main.ts";
1212
import FetchEverything from "../features/SetupWizard/dialogs/FetchEverything.svelte";
1313
import RebuildEverything from "../features/SetupWizard/dialogs/RebuildEverything.svelte";
1414
import { extractObject } from "octagonal-wheels/object";
15+
import type { FetchEverythingResult, RebuildEverythingResult } from "../../modules/features/SetupWizard/resultTypes";
1516
import { SvelteDialogManagerBase } from "@lib/UI/svelteDialog.ts";
1617
import type { ServiceContext } from "@lib/services/base/ServiceBase.ts";
18+
import { $msg } from "@lib/common/i18n.ts";
1719

1820
export class ModuleRedFlag extends AbstractModule {
1921
async isFlagFileExist(path: string) {
@@ -72,7 +74,7 @@ export class ModuleRedFlag extends AbstractModule {
7274
if (await this.adjustSettingToRemote(config)) {
7375
config = this.core.settings;
7476
} else {
75-
this._log("Remote configuration not applied.", LOG_LEVEL_NOTICE);
77+
this._log($msg("RedFlag.FetchRemoteConfig.NotApplied"), LOG_LEVEL_NOTICE);
7678
}
7779
console.debug(config);
7880
}
@@ -84,19 +86,19 @@ export class ModuleRedFlag extends AbstractModule {
8486
*/
8587
async adjustSettingToRemote(config: ObsidianLiveSyncSettings) {
8688
// Fetch remote configuration unless prevented.
87-
const SKIP_FETCH = "Skip and proceed";
88-
const RETRY_FETCH = "Retry (recommended)";
89+
const SKIP_FETCH = "RedFlag.FetchRemoteConfig.Buttons.SkipAndProceed";
90+
const RETRY_FETCH = "RedFlag.FetchRemoteConfig.Buttons.Retry";
8991
let canProceed = false;
9092
do {
9193
const remoteTweaks = await this.services.tweakValue.fetchRemotePreferred(config);
9294
if (!remoteTweaks) {
9395
const choice = await this.core.confirm.askSelectStringDialogue(
94-
"Could not fetch configuration from remote. If you are new to the Self-hosted LiveSync, this might be expected. If not, you should check your network or server settings.",
96+
$msg("RedFlag.FetchRemoteConfig.FailedMessage"),
9597
[SKIP_FETCH, RETRY_FETCH] as const,
9698
{
9799
defaultAction: RETRY_FETCH,
98100
timeout: 0,
99-
title: "Fetch Remote Configuration Failed",
101+
title: $msg("RedFlag.FetchRemoteConfig.FailedTitle"),
100102
}
101103
);
102104
if (choice === SKIP_FETCH) {
@@ -109,13 +111,10 @@ export class ModuleRedFlag extends AbstractModule {
109111
return (config as any)[key] !== value;
110112
});
111113
if (differentItems.length === 0) {
112-
this._log(
113-
"Remote configuration matches local configuration. No changes applied.",
114-
LOG_LEVEL_NOTICE
115-
);
114+
this._log($msg("RedFlag.FetchRemoteConfig.MatchesLocal"), LOG_LEVEL_NOTICE);
116115
} else {
117116
await this.core.confirm.askSelectStringDialogue(
118-
"Your settings differed slightly from the server's. The plug-in has supplemented the incompatible parts with the server settings!",
117+
$msg("RedFlag.FetchRemoteConfig.SettingsDiffered"),
119118
["OK"] as const,
120119
{
121120
defaultAction: "OK",
@@ -130,7 +129,7 @@ export class ModuleRedFlag extends AbstractModule {
130129
} satisfies ObsidianLiveSyncSettings;
131130
this.core.settings = config;
132131
await this.core.services.setting.saveSettingData();
133-
this._log("Remote configuration applied.", LOG_LEVEL_NOTICE);
132+
this._log($msg("RedFlag.FetchRemoteConfig.Applied"), LOG_LEVEL_NOTICE);
134133
canProceed = true;
135134
return this.core.settings;
136135
}
@@ -155,12 +154,12 @@ export class ModuleRedFlag extends AbstractModule {
155154
const result = await proc();
156155
return result;
157156
} catch (ex) {
158-
this._log("Error during vault initialisation process.", LOG_LEVEL_NOTICE);
157+
this._log($msg("RedFlag.Log.VaultInitialisationProcessError"), LOG_LEVEL_NOTICE);
159158
this._log(ex, LOG_LEVEL_VERBOSE);
160159
return false;
161160
}
162161
} catch (ex) {
163-
this._log("Error during vault initialisation.", LOG_LEVEL_NOTICE);
162+
this._log($msg("RedFlag.Log.VaultInitialisationError"), LOG_LEVEL_NOTICE);
164163
this._log(ex, LOG_LEVEL_VERBOSE);
165164
return false;
166165
} finally {
@@ -177,10 +176,10 @@ export class ModuleRedFlag extends AbstractModule {
177176
* @returns true if can be continued, false if app restart is needed.
178177
*/
179178
async onRebuildEverythingScheduled() {
180-
const method = await this.dialogManager.openWithExplicitCancel(RebuildEverything);
179+
const method = await this.dialogManager.openWithExplicitCancel<RebuildEverythingResult, undefined>(RebuildEverything);
181180
if (method === "cancelled") {
182181
// Clean up the flag file and restart the app.
183-
this._log("Rebuild everything cancelled by user.", LOG_LEVEL_NOTICE);
182+
this._log($msg("RedFlag.Log.RebuildEverythingCancelled"), LOG_LEVEL_NOTICE);
184183
await this.cleanupRebuildFlag();
185184
this.services.appLifecycle.performRestart();
186185
return false;
@@ -190,7 +189,7 @@ export class ModuleRedFlag extends AbstractModule {
190189
return await this.processVaultInitialisation(async () => {
191190
await this.core.rebuilder.$rebuildEverything();
192191
await this.cleanupRebuildFlag();
193-
this._log("Rebuild everything operation completed.", LOG_LEVEL_NOTICE);
192+
this._log($msg("RedFlag.Log.RebuildEverythingCompleted"), LOG_LEVEL_NOTICE);
194193
return true;
195194
});
196195
}
@@ -199,9 +198,9 @@ export class ModuleRedFlag extends AbstractModule {
199198
* @returns true if can be continued, false if app restart is needed.
200199
*/
201200
async onFetchAllScheduled() {
202-
const method = await this.dialogManager.openWithExplicitCancel(FetchEverything);
201+
const method = await this.dialogManager.openWithExplicitCancel<FetchEverythingResult, undefined>(FetchEverything);
203202
if (method === "cancelled") {
204-
this._log("Fetch everything cancelled by user.", LOG_LEVEL_NOTICE);
203+
this._log($msg("RedFlag.Log.FetchEverythingCancelled"), LOG_LEVEL_NOTICE);
205204
// Clean up the flag file and restart the app.
206205
await this.cleanupFetchAllFlag();
207206
this.services.appLifecycle.performRestart();
@@ -246,7 +245,7 @@ export class ModuleRedFlag extends AbstractModule {
246245
);
247246
await this.core.rebuilder.$fetchLocal(makeLocalChunkBeforeSync, !makeLocalFilesBeforeSync);
248247
await this.cleanupFetchAllFlag();
249-
this._log("Fetch everything operation completed. Vault files will be gradually synced.", LOG_LEVEL_NOTICE);
248+
this._log($msg("RedFlag.Log.FetchEverythingCompleted"), LOG_LEVEL_NOTICE);
250249
return true;
251250
});
252251
}
@@ -270,7 +269,7 @@ export class ModuleRedFlag extends AbstractModule {
270269
}
271270
if (
272271
(await this.core.confirm.askYesNoDialog(
273-
"Do you want to resume file and database processing, and restart obsidian now?",
272+
$msg("RedFlag.ResumeProcessingPrompt"),
274273
{ defaultOption: "Yes", timeout: 15 }
275274
)) != "yes"
276275
) {

src/modules/coreObsidian/UILib/dialogs.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ButtonComponent } from "@/deps.ts";
22
import { App, FuzzySuggestModal, MarkdownRenderer, Modal, Plugin, Setting } from "../../../deps.ts";
33
import { EVENT_PLUGIN_UNLOADED, eventHub } from "../../../common/events.ts";
4+
import { $msg, translateIfAvailable } from "../../../lib/src/common/i18n.ts";
45

56
class AutoClosableModal extends Modal {
67
_closeByUnload() {
@@ -58,7 +59,7 @@ export class InputStringDialog extends AutoClosableModal {
5859
new Setting(formEl)
5960
.addButton((btn) =>
6061
btn
61-
.setButtonText("Ok")
62+
.setButtonText(translateIfAvailable("Ok"))
6263
.setCta()
6364
.onClick(() => {
6465
this.isManuallyClosed = true;
@@ -67,7 +68,7 @@ export class InputStringDialog extends AutoClosableModal {
6768
)
6869
.addButton((btn) =>
6970
btn
70-
.setButtonText("Cancel")
71+
.setButtonText(translateIfAvailable("Cancel"))
7172
.setCta()
7273
.onClick(() => {
7374
this.close();

src/modules/features/ModuleSetupObsidian.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -38,37 +38,37 @@ export class ModuleSetupObsidian extends AbstractModule {
3838
});
3939
} catch (e) {
4040
this._log(
41-
"Failed to register protocol handler. This feature may not work in some environments.",
41+
$msg("Setup.Log.ProtocolHandlerRegistrationFailed"),
4242
LOG_LEVEL_NOTICE
4343
);
4444
this._log(e, LOG_LEVEL_VERBOSE);
4545
}
4646
this.addCommand({
4747
id: "livesync-setting-qr",
48-
name: "Show settings as a QR code",
48+
name: $msg("Setup.Command.ShowSettingsQrCode"),
4949
callback: () => fireAndForget(this.encodeQR()),
5050
});
5151

5252
this.addCommand({
5353
id: "livesync-copysetupuri",
54-
name: "Copy settings as a new setup URI",
54+
name: $msg("Setup.Command.CopySetupUri"),
5555
callback: () => fireAndForget(this.command_copySetupURI()),
5656
});
5757
this.addCommand({
5858
id: "livesync-copysetupuri-short",
59-
name: "Copy settings as a new setup URI (With customization sync)",
59+
name: $msg("Setup.Command.CopySetupUriWithSync"),
6060
callback: () => fireAndForget(this.command_copySetupURIWithSync()),
6161
});
6262

6363
this.addCommand({
6464
id: "livesync-copysetupurifull",
65-
name: "Copy settings as a new setup URI (Full)",
65+
name: $msg("Setup.Command.CopySetupUriFull"),
6666
callback: () => fireAndForget(this.command_copySetupURIFull()),
6767
});
6868

6969
this.addCommand({
7070
id: "livesync-opensetupuri",
71-
name: "Use the copied setup URI (Formerly Open setup URI)",
71+
name: $msg("Setup.Command.OpenSetupUri"),
7272
callback: () => fireAndForget(this.command_openSetupURI()),
7373
});
7474

@@ -89,14 +89,14 @@ export class ModuleSetupObsidian extends AbstractModule {
8989
return "";
9090
}
9191
const msg = $msg("Setup.QRCode", { qr_image: codeSVG });
92-
await this.core.confirm.confirmWithMessage("Settings QR Code", msg, ["OK"], "OK");
92+
await this.core.confirm.confirmWithMessage($msg("Setup.QRCodeTitle"), msg, ["OK"], "OK");
9393
return await Promise.resolve(codeSVG);
9494
}
9595

9696
async askEncryptingPassphrase(): Promise<string | false> {
9797
const encryptingPassphrase = await this.core.confirm.askString(
98-
"Encrypt your settings",
99-
"The passphrase to encrypt the setup URI",
98+
$msg("Setup.EncryptSettingsTitle"),
99+
$msg("Setup.EncryptSettingsPassphrase"),
100100
"",
101101
true
102102
);
@@ -112,8 +112,8 @@ export class ModuleSetupObsidian extends AbstractModule {
112112
[...((stripExtra ? ["pluginSyncExtendedSetting"] : []) as (keyof ObsidianLiveSyncSettings)[])],
113113
true
114114
);
115-
if (await this.services.UI.promptCopyToClipboard("Setup URI", encryptedURI)) {
116-
this._log("Setup URI copied to clipboard", LOG_LEVEL_NOTICE);
115+
if (await this.services.UI.promptCopyToClipboard($msg("Setup.SetupUri"), encryptedURI)) {
116+
this._log($msg("Setup.Log.SetupUriCopiedToClipboard"), LOG_LEVEL_NOTICE);
117117
}
118118
// await navigator.clipboard.writeText(encryptedURI);
119119
}
@@ -123,7 +123,7 @@ export class ModuleSetupObsidian extends AbstractModule {
123123
if (encryptingPassphrase === false) return;
124124
const encryptedURI = await encodeSettingsToSetupURI(this.settings, encryptingPassphrase, [], false);
125125
await navigator.clipboard.writeText(encryptedURI);
126-
this._log("Setup URI copied to clipboard", LOG_LEVEL_NOTICE);
126+
this._log($msg("Setup.Log.SetupUriCopiedToClipboard"), LOG_LEVEL_NOTICE);
127127
}
128128

129129
async command_copySetupURIWithSync() {

src/modules/features/SettingDialogue/LiveSyncSetting.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import {
2323
type AllNumericItemKey,
2424
type AllBooleanItemKey,
2525
} from "./settingConstants.ts";
26-
import { $msg } from "src/lib/src/common/i18n.ts";
26+
import { $msg, translateIfAvailable } from "src/lib/src/common/i18n.ts";
2727
import { findAttrFromParent, wrapMemo, type AutoWireOption, type OnUpdateResult } from "./SettingPane.ts";
2828

2929
export class LiveSyncSetting extends Setting {
@@ -257,6 +257,9 @@ export class LiveSyncSetting extends Setting {
257257

258258
this.invalidateValue = () => setValue(LiveSyncSetting.env.editingSettings[key] || "");
259259
this.invalidateValue();
260+
for (const optionEl of Array.from(dropdown.selectEl.options)) {
261+
optionEl.text = translateIfAvailable(optionEl.text);
262+
}
260263
dropdown.onChange(async (value) => {
261264
await this.commitValue(value);
262265
});

src/modules/features/SettingDialogue/PaneGeneral.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,42 @@
1-
import { $msg, $t } from "../../../lib/src/common/i18n.ts";
1+
import { $msg, setLang } from "../../../lib/src/common/i18n.ts";
22
import { SUPPORTED_I18N_LANGS, type I18N_LANGS } from "../../../lib/src/common/rosetta.ts";
33
import { LiveSyncSetting as Setting } from "./LiveSyncSetting.ts";
44
import type { ObsidianLiveSyncSettingTab } from "./ObsidianLiveSyncSettingTab.ts";
55
import type { PageFunctions } from "./SettingPane.ts";
66
import { visibleOnly } from "./SettingPane.ts";
77
import { EVENT_ON_UNRESOLVED_ERROR, eventHub } from "@/common/events.ts";
88
import { NetworkWarningStyles } from "@lib/common/models/setting.const.ts";
9+
10+
type NamedLanguage = Exclude<I18N_LANGS, "">;
11+
12+
const LANGUAGE_NAMES: Record<NamedLanguage, string> = {
13+
def: "English",
14+
de: "Deutsch",
15+
es: "Español",
16+
ja: "日本語",
17+
ko: "한국어",
18+
ru: "Русский",
19+
zh: "简体中文",
20+
"zh-tw": "繁體中文",
21+
};
22+
923
export function paneGeneral(
1024
this: ObsidianLiveSyncSettingTab,
1125
paneEl: HTMLElement,
1226
{ addPanel, addPane }: PageFunctions
1327
): void {
1428
void addPanel(paneEl, $msg("obsidianLiveSyncSettingTab.titleAppearance")).then((paneEl) => {
1529
const languages = Object.fromEntries([
16-
// ["", $msg("obsidianLiveSyncSettingTab.defaultLanguage")],
17-
...SUPPORTED_I18N_LANGS.map((e) => [e, $t(`lang-${e}`)]),
30+
["", $msg("obsidianLiveSyncSettingTab.defaultLanguage")],
31+
...SUPPORTED_I18N_LANGS.map((e) => [e, LANGUAGE_NAMES[e as NamedLanguage]]),
1832
]) as Record<I18N_LANGS, string>;
1933
new Setting(paneEl).autoWireDropDown("displayLanguage", {
2034
options: languages,
2135
});
22-
this.addOnSaved("displayLanguage", () => this.display());
36+
this.addOnSaved("displayLanguage", (value) => {
37+
setLang(value as I18N_LANGS);
38+
this.display();
39+
});
2340
new Setting(paneEl).autoWireToggle("showStatusOnEditor");
2441
this.addOnSaved("showStatusOnEditor", () => {
2542
eventHub.emitEvent(EVENT_ON_UNRESOLVED_ERROR);

src/modules/features/SettingDialogue/PanePatches.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { visibleOnly } from "./SettingPane.ts";
1313
import { PouchDB } from "../../../lib/src/pouchdb/pouchdb-browser";
1414
import { ExtraSuffixIndexedDB } from "../../../lib/src/common/types.ts";
1515
import { migrateDatabases } from "./settingUtils.ts";
16+
import { $msg } from "../../../lib/src/common/i18n.ts";
1617

1718
export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElement, { addPanel }: PageFunctions): void {
1819
void addPanel(paneEl, "Compatibility (Metadata)").then((paneEl) => {
@@ -216,17 +217,21 @@ export function panePatches(this: ObsidianLiveSyncSettingTab, paneEl: HTMLElemen
216217
.addApplyButton(["maxMTimeForReflectEvents"]);
217218

218219
this.addOnSaved("maxMTimeForReflectEvents", async (key) => {
219-
const buttons = ["Restart Now", "Later"] as const;
220+
const RESTART_NOW = "Ui.Settings.Patches.RemediationRestartNow";
221+
const RESTART_LATER = "Ui.Settings.Patches.RemediationRestartLater";
222+
const RESTART_NOW_TEXT = $msg(RESTART_NOW);
223+
const RESTART_LATER_TEXT = $msg(RESTART_LATER);
224+
const buttons = [RESTART_NOW_TEXT, RESTART_LATER_TEXT] as const;
220225
const reboot = await this.core.confirm.askSelectStringDialogue(
221226
"Restarting Obsidian is strongly recommended. Until restart, some changes may not take effect, and display may be inconsistent. Are you sure to restart now?",
222227
buttons,
223228
{
224-
title: "Remediation Setting Changed",
225-
defaultAction: "Restart Now",
229+
title: $msg("Ui.Settings.Patches.RemediationChanged"),
230+
defaultAction: RESTART_NOW_TEXT,
226231
}
227232
);
228-
if (reboot !== "Later") {
229-
Logger("Remediation setting changed. Restarting Obsidian...", LOG_LEVEL_NOTICE);
233+
if (reboot !== RESTART_LATER_TEXT) {
234+
Logger($msg("Ui.Settings.Patches.RemediationRestarting"), LOG_LEVEL_NOTICE);
230235
this.services.appLifecycle.performRestart();
231236
}
232237
});

0 commit comments

Comments
 (0)