Internationalization: 7 languages with live switching

Custom signal-based runtime (no i18n dependency): shared src/shared/i18n
dictionaries, ui I18nService.t() reactive by construction so language
switches live, and a backend i18n.ts for native menus + thrown errors.
Every user-facing string keyed across templates, toasts, dialogs, file
kinds, columns, macOS menu/context menus, and errors. Language picker in
Options (auto-detects OS locale, falls back to English); switching
relabels the webview and native chrome instantly. English/Spanish/French/
German fully drafted; Chinese/Japanese/Basque drafted, flagged for native
review. Docs updated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-14 15:52:54 +02:00
co-authored by Claude Fable 5
parent d8cfc54049
commit a0f56822cd
43 changed files with 2755 additions and 322 deletions
+3 -1
View File
@@ -1,4 +1,5 @@
import { Component, ElementRef, afterNextRender, inject, input, viewChild } from '@angular/core';
import { I18nService } from '../i18n.service';
import { DialogsService, type ConfirmRequest } from '../dialogs.service';
import { FocusService } from '../focus.service';
@@ -18,7 +19,7 @@ import { FocusService } from '../focus.service';
(click)="cancel()"
class="rounded-md px-3 py-1.5 text-xs font-medium hover:bg-accent"
>
Cancel
{{ i18n.t('common.cancel') }}
</button>
<button
#confirmBtn
@@ -37,6 +38,7 @@ import { FocusService } from '../focus.service';
`,
})
export class ConfirmDialog {
readonly i18n = inject(I18nService);
readonly request = input.required<ConfirmRequest>();
private readonly confirmBtn = viewChild.required<ElementRef<HTMLButtonElement>>('confirmBtn');