feat(i18n): standardize bilingual catalogs and tooling
This commit is contained in:
@@ -3,27 +3,15 @@ import { describe, it } from "vitest"
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { appearanceMessages, themeColorMessages } from "../messages"
|
||||
import { appearanceCatalogLocales } from "./catalogs"
|
||||
import { messages as de } from "./de"
|
||||
import { messages as en } from "./en"
|
||||
import { messages as es } from "./es"
|
||||
import { messages as fr } from "./fr"
|
||||
import { messages as ja } from "./ja"
|
||||
import { messages as ko } from "./ko"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
import { messages as zhHant } from "./zh-Hant"
|
||||
|
||||
describe("appearance locale catalogs", () => {
|
||||
it("ship every appearance message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
de,
|
||||
en,
|
||||
es,
|
||||
fr,
|
||||
ja,
|
||||
ko,
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
"zh-Hant": zhHant,
|
||||
},
|
||||
locales: appearanceCatalogLocales,
|
||||
messageIds: [
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "Aktiv",
|
||||
"blocks.appearance.baseColor": "Basisfarbe",
|
||||
"blocks.appearance.color.amber": "Bernstein",
|
||||
"blocks.appearance.color.blue": "Blau",
|
||||
"blocks.appearance.color.cyan": "Cyan",
|
||||
"blocks.appearance.color.emerald": "Smaragd",
|
||||
"blocks.appearance.color.fuchsia": "Fuchsia",
|
||||
"blocks.appearance.color.green": "Grün",
|
||||
"blocks.appearance.color.indigo": "Indigo",
|
||||
"blocks.appearance.color.lime": "Limette",
|
||||
"blocks.appearance.color.mauve": "Malve",
|
||||
"blocks.appearance.color.mist": "Nebel",
|
||||
"blocks.appearance.color.neutral": "Neutral",
|
||||
"blocks.appearance.color.olive": "Oliv",
|
||||
"blocks.appearance.color.orange": "Orange",
|
||||
"blocks.appearance.color.pink": "Rosa",
|
||||
"blocks.appearance.color.purple": "Lila",
|
||||
"blocks.appearance.color.red": "Rot",
|
||||
"blocks.appearance.color.rose": "Rose",
|
||||
"blocks.appearance.color.sky": "Himmelblau",
|
||||
"blocks.appearance.color.stone": "Stein",
|
||||
"blocks.appearance.color.taupe": "Taupe",
|
||||
"blocks.appearance.color.teal": "Blaugrün",
|
||||
"blocks.appearance.color.violet": "Violett",
|
||||
"blocks.appearance.color.yellow": "Gelb",
|
||||
"blocks.appearance.color.zinc": "Zink",
|
||||
"blocks.appearance.command.description":
|
||||
"Design- und Layout-Einstellungen öffnen",
|
||||
"blocks.appearance.compact.description":
|
||||
"Eine kompakte Breite für den Hauptinhalt verwenden",
|
||||
"blocks.appearance.compact.title": "Kompaktes Layout",
|
||||
"blocks.appearance.description": "Design- und Layout-Einstellungen",
|
||||
"blocks.appearance.mode.dark": "Dunkel",
|
||||
"blocks.appearance.mode.dark.description":
|
||||
"Die Oberfläche verwendet immer das dunkle Design",
|
||||
"blocks.appearance.mode.light": "Hell",
|
||||
"blocks.appearance.mode.light.description":
|
||||
"Die Oberfläche verwendet immer das helle Design",
|
||||
"blocks.appearance.mode.system": "System",
|
||||
"blocks.appearance.mode.system.description":
|
||||
"Das Design der Oberfläche folgt der Systemeinstellung",
|
||||
"blocks.appearance.mode.title": "Darstellungsmodus",
|
||||
"blocks.appearance.primaryColor": "Primärfarbe",
|
||||
"blocks.appearance.theme.dark": "Dunkles Design",
|
||||
"blocks.appearance.theme.dark.description":
|
||||
"Dieses Design wird im dunklen Systemmodus verwendet",
|
||||
"blocks.appearance.theme.light": "Helles Design",
|
||||
"blocks.appearance.theme.light.description":
|
||||
"Dieses Design wird im hellen Systemmodus verwendet",
|
||||
"blocks.appearance.title": "Darstellung",
|
||||
"blocks.appearance.toggleTheme": "Design wechseln",
|
||||
"blocks.appearance.toggleTheme.description":
|
||||
"Zwischen hellem und dunklem Design wechseln",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
+1
-1
@@ -3,7 +3,7 @@ import type { MessageDescriptor } from "@workspace/i18n"
|
||||
import { appearanceMessages, themeColorMessages } from "../messages.ts"
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
|
||||
function createSourceCatalog(
|
||||
@@ -1,60 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "Activo",
|
||||
"blocks.appearance.baseColor": "Color base",
|
||||
"blocks.appearance.color.amber": "Ámbar",
|
||||
"blocks.appearance.color.blue": "Azul",
|
||||
"blocks.appearance.color.cyan": "Cian",
|
||||
"blocks.appearance.color.emerald": "Esmeralda",
|
||||
"blocks.appearance.color.fuchsia": "Fucsia",
|
||||
"blocks.appearance.color.green": "Verde",
|
||||
"blocks.appearance.color.indigo": "Índigo",
|
||||
"blocks.appearance.color.lime": "Lima",
|
||||
"blocks.appearance.color.mauve": "Malva",
|
||||
"blocks.appearance.color.mist": "Niebla",
|
||||
"blocks.appearance.color.neutral": "Neutro",
|
||||
"blocks.appearance.color.olive": "Oliva",
|
||||
"blocks.appearance.color.orange": "Naranja",
|
||||
"blocks.appearance.color.pink": "Rosa",
|
||||
"blocks.appearance.color.purple": "Morado",
|
||||
"blocks.appearance.color.red": "Rojo",
|
||||
"blocks.appearance.color.rose": "Rosa intenso",
|
||||
"blocks.appearance.color.sky": "Celeste",
|
||||
"blocks.appearance.color.stone": "Piedra",
|
||||
"blocks.appearance.color.taupe": "Topo",
|
||||
"blocks.appearance.color.teal": "Verde azulado",
|
||||
"blocks.appearance.color.violet": "Violeta",
|
||||
"blocks.appearance.color.yellow": "Amarillo",
|
||||
"blocks.appearance.color.zinc": "Zinc",
|
||||
"blocks.appearance.command.description":
|
||||
"Abrir las preferencias de tema y diseño",
|
||||
"blocks.appearance.compact.description":
|
||||
"Usar un ancho compacto para el contenido principal",
|
||||
"blocks.appearance.compact.title": "Diseño compacto",
|
||||
"blocks.appearance.description": "Preferencias de tema y diseño",
|
||||
"blocks.appearance.mode.dark": "Oscuro",
|
||||
"blocks.appearance.mode.dark.description":
|
||||
"La interfaz siempre usará el tema oscuro",
|
||||
"blocks.appearance.mode.light": "Claro",
|
||||
"blocks.appearance.mode.light.description":
|
||||
"La interfaz siempre usará el tema claro",
|
||||
"blocks.appearance.mode.system": "Sistema",
|
||||
"blocks.appearance.mode.system.description":
|
||||
"El tema de la interfaz seguirá la apariencia del sistema",
|
||||
"blocks.appearance.mode.title": "Modo de tema",
|
||||
"blocks.appearance.primaryColor": "Color principal",
|
||||
"blocks.appearance.theme.dark": "Tema oscuro",
|
||||
"blocks.appearance.theme.dark.description":
|
||||
"Este tema se usa cuando el sistema está en modo oscuro",
|
||||
"blocks.appearance.theme.light": "Tema claro",
|
||||
"blocks.appearance.theme.light.description":
|
||||
"Este tema se usa cuando el sistema está en modo claro",
|
||||
"blocks.appearance.title": "Apariencia",
|
||||
"blocks.appearance.toggleTheme": "Cambiar tema",
|
||||
"blocks.appearance.toggleTheme.description":
|
||||
"Cambiar entre los temas claro y oscuro",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
@@ -1,60 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "Actif",
|
||||
"blocks.appearance.baseColor": "Couleur de base",
|
||||
"blocks.appearance.color.amber": "Ambre",
|
||||
"blocks.appearance.color.blue": "Bleu",
|
||||
"blocks.appearance.color.cyan": "Cyan",
|
||||
"blocks.appearance.color.emerald": "Émeraude",
|
||||
"blocks.appearance.color.fuchsia": "Fuchsia",
|
||||
"blocks.appearance.color.green": "Vert",
|
||||
"blocks.appearance.color.indigo": "Indigo",
|
||||
"blocks.appearance.color.lime": "Citron vert",
|
||||
"blocks.appearance.color.mauve": "Mauve",
|
||||
"blocks.appearance.color.mist": "Brume",
|
||||
"blocks.appearance.color.neutral": "Neutre",
|
||||
"blocks.appearance.color.olive": "Olive",
|
||||
"blocks.appearance.color.orange": "Orange",
|
||||
"blocks.appearance.color.pink": "Rose",
|
||||
"blocks.appearance.color.purple": "Pourpre",
|
||||
"blocks.appearance.color.red": "Rouge",
|
||||
"blocks.appearance.color.rose": "Rose soutenu",
|
||||
"blocks.appearance.color.sky": "Bleu ciel",
|
||||
"blocks.appearance.color.stone": "Pierre",
|
||||
"blocks.appearance.color.taupe": "Taupe",
|
||||
"blocks.appearance.color.teal": "Sarcelle",
|
||||
"blocks.appearance.color.violet": "Violet",
|
||||
"blocks.appearance.color.yellow": "Jaune",
|
||||
"blocks.appearance.color.zinc": "Zinc",
|
||||
"blocks.appearance.command.description":
|
||||
"Ouvrir les préférences de thème et de mise en page",
|
||||
"blocks.appearance.compact.description":
|
||||
"Utiliser une largeur compacte pour le contenu principal",
|
||||
"blocks.appearance.compact.title": "Mise en page compacte",
|
||||
"blocks.appearance.description": "Préférences de thème et de mise en page",
|
||||
"blocks.appearance.mode.dark": "Sombre",
|
||||
"blocks.appearance.mode.dark.description":
|
||||
"L’interface utilisera toujours le thème sombre",
|
||||
"blocks.appearance.mode.light": "Clair",
|
||||
"blocks.appearance.mode.light.description":
|
||||
"L’interface utilisera toujours le thème clair",
|
||||
"blocks.appearance.mode.system": "Système",
|
||||
"blocks.appearance.mode.system.description":
|
||||
"Le thème de l’interface suivra l’apparence du système",
|
||||
"blocks.appearance.mode.title": "Mode du thème",
|
||||
"blocks.appearance.primaryColor": "Couleur principale",
|
||||
"blocks.appearance.theme.dark": "Thème sombre",
|
||||
"blocks.appearance.theme.dark.description":
|
||||
"Ce thème est utilisé lorsque le système est en mode sombre",
|
||||
"blocks.appearance.theme.light": "Thème clair",
|
||||
"blocks.appearance.theme.light.description":
|
||||
"Ce thème est utilisé lorsque le système est en mode clair",
|
||||
"blocks.appearance.title": "Apparence",
|
||||
"blocks.appearance.toggleTheme": "Changer de thème",
|
||||
"blocks.appearance.toggleTheme.description":
|
||||
"Basculer entre les thèmes clair et sombre",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
@@ -1,57 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "使用中",
|
||||
"blocks.appearance.baseColor": "ベースカラー",
|
||||
"blocks.appearance.color.amber": "アンバー",
|
||||
"blocks.appearance.color.blue": "ブルー",
|
||||
"blocks.appearance.color.cyan": "シアン",
|
||||
"blocks.appearance.color.emerald": "エメラルド",
|
||||
"blocks.appearance.color.fuchsia": "フクシア",
|
||||
"blocks.appearance.color.green": "グリーン",
|
||||
"blocks.appearance.color.indigo": "インディゴ",
|
||||
"blocks.appearance.color.lime": "ライム",
|
||||
"blocks.appearance.color.mauve": "モーブ",
|
||||
"blocks.appearance.color.mist": "ミスト",
|
||||
"blocks.appearance.color.neutral": "ニュートラル",
|
||||
"blocks.appearance.color.olive": "オリーブ",
|
||||
"blocks.appearance.color.orange": "オレンジ",
|
||||
"blocks.appearance.color.pink": "ピンク",
|
||||
"blocks.appearance.color.purple": "パープル",
|
||||
"blocks.appearance.color.red": "レッド",
|
||||
"blocks.appearance.color.rose": "ローズ",
|
||||
"blocks.appearance.color.sky": "スカイ",
|
||||
"blocks.appearance.color.stone": "ストーン",
|
||||
"blocks.appearance.color.taupe": "トープ",
|
||||
"blocks.appearance.color.teal": "ティール",
|
||||
"blocks.appearance.color.violet": "バイオレット",
|
||||
"blocks.appearance.color.yellow": "イエロー",
|
||||
"blocks.appearance.color.zinc": "ジンク",
|
||||
"blocks.appearance.command.description": "テーマとレイアウト設定を開く",
|
||||
"blocks.appearance.compact.description":
|
||||
"メインページのコンテンツをコンパクトな幅で表示します",
|
||||
"blocks.appearance.compact.title": "コンパクトレイアウト",
|
||||
"blocks.appearance.description": "テーマとレイアウトの設定",
|
||||
"blocks.appearance.mode.dark": "ダーク",
|
||||
"blocks.appearance.mode.dark.description": "常にダークテーマを使用します",
|
||||
"blocks.appearance.mode.light": "ライト",
|
||||
"blocks.appearance.mode.light.description": "常にライトテーマを使用します",
|
||||
"blocks.appearance.mode.system": "システム",
|
||||
"blocks.appearance.mode.system.description":
|
||||
"インターフェースのテーマをシステムの外観に合わせます",
|
||||
"blocks.appearance.mode.title": "テーマモード",
|
||||
"blocks.appearance.primaryColor": "プライマリカラー",
|
||||
"blocks.appearance.theme.dark": "ダークテーマ",
|
||||
"blocks.appearance.theme.dark.description":
|
||||
"システムがダークモードのときに使用するテーマです",
|
||||
"blocks.appearance.theme.light": "ライトテーマ",
|
||||
"blocks.appearance.theme.light.description":
|
||||
"システムがライトモードのときに使用するテーマです",
|
||||
"blocks.appearance.title": "外観",
|
||||
"blocks.appearance.toggleTheme": "テーマを切り替える",
|
||||
"blocks.appearance.toggleTheme.description":
|
||||
"ライトテーマとダークテーマを切り替えます",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
@@ -1,59 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "사용 중",
|
||||
"blocks.appearance.baseColor": "기본 색상",
|
||||
"blocks.appearance.color.amber": "호박색",
|
||||
"blocks.appearance.color.blue": "파란색",
|
||||
"blocks.appearance.color.cyan": "청록색",
|
||||
"blocks.appearance.color.emerald": "에메랄드",
|
||||
"blocks.appearance.color.fuchsia": "자홍색",
|
||||
"blocks.appearance.color.green": "초록색",
|
||||
"blocks.appearance.color.indigo": "남색",
|
||||
"blocks.appearance.color.lime": "라임",
|
||||
"blocks.appearance.color.mauve": "연보라",
|
||||
"blocks.appearance.color.mist": "안개색",
|
||||
"blocks.appearance.color.neutral": "중성색",
|
||||
"blocks.appearance.color.olive": "올리브",
|
||||
"blocks.appearance.color.orange": "주황색",
|
||||
"blocks.appearance.color.pink": "분홍색",
|
||||
"blocks.appearance.color.purple": "보라색",
|
||||
"blocks.appearance.color.red": "빨간색",
|
||||
"blocks.appearance.color.rose": "장미색",
|
||||
"blocks.appearance.color.sky": "하늘색",
|
||||
"blocks.appearance.color.stone": "돌색",
|
||||
"blocks.appearance.color.taupe": "회갈색",
|
||||
"blocks.appearance.color.teal": "틸",
|
||||
"blocks.appearance.color.violet": "제비꽃색",
|
||||
"blocks.appearance.color.yellow": "노란색",
|
||||
"blocks.appearance.color.zinc": "아연색",
|
||||
"blocks.appearance.command.description": "테마 및 레이아웃 환경설정 열기",
|
||||
"blocks.appearance.compact.description":
|
||||
"기본 페이지 콘텐츠에 좁은 너비를 사용합니다",
|
||||
"blocks.appearance.compact.title": "컴팩트 레이아웃",
|
||||
"blocks.appearance.description": "테마 및 레이아웃 환경설정",
|
||||
"blocks.appearance.mode.dark": "어둡게",
|
||||
"blocks.appearance.mode.dark.description":
|
||||
"인터페이스에서 항상 어두운 테마를 사용합니다",
|
||||
"blocks.appearance.mode.light": "밝게",
|
||||
"blocks.appearance.mode.light.description":
|
||||
"인터페이스에서 항상 밝은 테마를 사용합니다",
|
||||
"blocks.appearance.mode.system": "시스템",
|
||||
"blocks.appearance.mode.system.description":
|
||||
"인터페이스 테마가 시스템 화면 모드를 따릅니다",
|
||||
"blocks.appearance.mode.title": "테마 모드",
|
||||
"blocks.appearance.primaryColor": "주요 색상",
|
||||
"blocks.appearance.theme.dark": "어두운 테마",
|
||||
"blocks.appearance.theme.dark.description":
|
||||
"시스템이 어두운 모드일 때 사용하는 테마입니다",
|
||||
"blocks.appearance.theme.light": "밝은 테마",
|
||||
"blocks.appearance.theme.light.description":
|
||||
"시스템이 밝은 모드일 때 사용하는 테마입니다",
|
||||
"blocks.appearance.title": "화면 모양",
|
||||
"blocks.appearance.toggleTheme": "테마 전환",
|
||||
"blocks.appearance.toggleTheme.description":
|
||||
"밝은 테마와 어두운 테마 사이를 전환합니다",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
@@ -1,52 +0,0 @@
|
||||
import type { AppearanceMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
|
||||
export const messages = {
|
||||
"blocks.appearance.active": "使用中",
|
||||
"blocks.appearance.baseColor": "基礎顏色",
|
||||
"blocks.appearance.color.amber": "琥珀色",
|
||||
"blocks.appearance.color.blue": "藍色",
|
||||
"blocks.appearance.color.cyan": "青色",
|
||||
"blocks.appearance.color.emerald": "翠綠色",
|
||||
"blocks.appearance.color.fuchsia": "紫紅色",
|
||||
"blocks.appearance.color.green": "綠色",
|
||||
"blocks.appearance.color.indigo": "靛藍色",
|
||||
"blocks.appearance.color.lime": "萊姆色",
|
||||
"blocks.appearance.color.mauve": "淡紫色",
|
||||
"blocks.appearance.color.mist": "霧灰色",
|
||||
"blocks.appearance.color.neutral": "中性灰",
|
||||
"blocks.appearance.color.olive": "橄欖色",
|
||||
"blocks.appearance.color.orange": "橙色",
|
||||
"blocks.appearance.color.pink": "粉紅色",
|
||||
"blocks.appearance.color.purple": "紫色",
|
||||
"blocks.appearance.color.red": "紅色",
|
||||
"blocks.appearance.color.rose": "玫瑰色",
|
||||
"blocks.appearance.color.sky": "天藍色",
|
||||
"blocks.appearance.color.stone": "石灰色",
|
||||
"blocks.appearance.color.taupe": "灰褐色",
|
||||
"blocks.appearance.color.teal": "藍綠色",
|
||||
"blocks.appearance.color.violet": "紫羅蘭色",
|
||||
"blocks.appearance.color.yellow": "黃色",
|
||||
"blocks.appearance.color.zinc": "鋅灰色",
|
||||
"blocks.appearance.command.description": "開啟主題與版面配置偏好",
|
||||
"blocks.appearance.compact.description": "使用較緊湊的主頁內容寬度",
|
||||
"blocks.appearance.compact.title": "緊湊版面配置",
|
||||
"blocks.appearance.description": "主題與版面配置偏好",
|
||||
"blocks.appearance.mode.dark": "深色",
|
||||
"blocks.appearance.mode.dark.description": "介面將一律使用深色主題",
|
||||
"blocks.appearance.mode.light": "淺色",
|
||||
"blocks.appearance.mode.light.description": "介面將一律使用淺色主題",
|
||||
"blocks.appearance.mode.system": "系統",
|
||||
"blocks.appearance.mode.system.description": "介面主題將跟隨系統外觀設定",
|
||||
"blocks.appearance.mode.title": "主題模式",
|
||||
"blocks.appearance.primaryColor": "主要顏色",
|
||||
"blocks.appearance.theme.dark": "深色主題",
|
||||
"blocks.appearance.theme.dark.description": "系統使用深色模式時套用此主題",
|
||||
"blocks.appearance.theme.light": "淺色主題",
|
||||
"blocks.appearance.theme.light.description": "系統使用淺色模式時套用此主題",
|
||||
"blocks.appearance.title": "介面外觀",
|
||||
"blocks.appearance.toggleTheme": "切換主題",
|
||||
"blocks.appearance.toggleTheme.description": "在淺色與深色主題之間切換",
|
||||
} as const satisfies AppearanceMessageCatalog
|
||||
@@ -5,7 +5,7 @@ import { I18nProvider } from "@workspace/i18n"
|
||||
import { afterEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { ChatMessageList } from "./chat-message-list"
|
||||
import { messages as englishMessages } from "./locales/en"
|
||||
import { messages as englishMessages } from "./locales/en-US"
|
||||
import type { ChatConversation } from "./types"
|
||||
|
||||
const conversation: ChatConversation = {
|
||||
@@ -57,7 +57,7 @@ describe("ChatMessageList", () => {
|
||||
)
|
||||
|
||||
render(
|
||||
<I18nProvider locale="en" catalogs={{ en: englishMessages }}>
|
||||
<I18nProvider locale="en-US" catalogs={{ "en-US": englishMessages }}>
|
||||
<ChatMessageList
|
||||
conversation={conversation}
|
||||
resolveMediaUrl={resolveMediaUrl}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { I18nProvider } from "@workspace/i18n"
|
||||
import { afterEach, describe, expect, it, vi } from "vitest"
|
||||
|
||||
import { ChatWorkspace } from "./chat-workspace"
|
||||
import { messages as englishMessages } from "./locales/en"
|
||||
import { messages as englishMessages } from "./locales/en-US"
|
||||
import type { ChatConversation, ChatSendHandler } from "./types"
|
||||
|
||||
vi.stubGlobal(
|
||||
@@ -72,7 +72,7 @@ function renderWorkspace({
|
||||
onSend?: ChatSendHandler
|
||||
} = {}) {
|
||||
return render(
|
||||
<I18nProvider locale="en" catalogs={{ en: englishMessages }}>
|
||||
<I18nProvider locale="en-US" catalogs={{ "en-US": englishMessages }}>
|
||||
<ChatWorkspace
|
||||
conversations={conversations}
|
||||
draft={draft}
|
||||
@@ -210,7 +210,7 @@ describe("ChatWorkspace", () => {
|
||||
expect(editor.getAttribute("contenteditable")).toBe("true")
|
||||
|
||||
rerender(
|
||||
<I18nProvider locale="en" catalogs={{ en: englishMessages }}>
|
||||
<I18nProvider locale="en-US" catalogs={{ "en-US": englishMessages }}>
|
||||
<ChatWorkspace conversations={conversations} draft="Lexical draft" />
|
||||
</I18nProvider>
|
||||
)
|
||||
|
||||
@@ -3,27 +3,15 @@ import { describe, it } from "vitest"
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { chatMessages } from "../messages"
|
||||
import { chatCatalogLocales } from "./catalogs"
|
||||
import { messages as de } from "./de"
|
||||
import { messages as en } from "./en"
|
||||
import { messages as es } from "./es"
|
||||
import { messages as fr } from "./fr"
|
||||
import { messages as ja } from "./ja"
|
||||
import { messages as ko } from "./ko"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
import { messages as zhHant } from "./zh-Hant"
|
||||
|
||||
describe("chat locale catalogs", () => {
|
||||
it("ship every chat message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
de,
|
||||
en,
|
||||
es,
|
||||
fr,
|
||||
ja,
|
||||
ko,
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
"zh-Hant": zhHant,
|
||||
},
|
||||
locales: chatCatalogLocales,
|
||||
messageIds: Object.values(chatMessages).map(
|
||||
|
||||
@@ -1,37 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "Dateien hinzufügen",
|
||||
"blocks.chats.actions.addEmoji": "Emoji hinzufügen",
|
||||
"blocks.chats.actions.addImage": "Bild hinzufügen",
|
||||
"blocks.chats.actions.backToConversations": "Zurück zu Unterhaltungen",
|
||||
"blocks.chats.actions.conversationDetails": "Unterhaltungsdetails",
|
||||
"blocks.chats.actions.loadEarlier": "Frühere Nachrichten laden",
|
||||
"blocks.chats.actions.removeAttachment": "{name} entfernen",
|
||||
"blocks.chats.actions.retry": "Erneut versuchen",
|
||||
"blocks.chats.actions.send": "Senden",
|
||||
"blocks.chats.actions.sendOnEnter": "Mit Enter senden",
|
||||
"blocks.chats.actions.sending": "Wird gesendet…",
|
||||
"blocks.chats.emptyConversations.description":
|
||||
"Starte eine Unterhaltung, damit sie hier erscheint.",
|
||||
"blocks.chats.emptyConversations.title": "Keine Unterhaltungen",
|
||||
"blocks.chats.emptyMessages.description":
|
||||
"Nachrichten dieser Unterhaltung werden hier angezeigt.",
|
||||
"blocks.chats.emptyMessages.title": "Noch keine Nachrichten",
|
||||
"blocks.chats.emptySearch": "Keine Unterhaltungen entsprechen deiner Suche.",
|
||||
"blocks.chats.emojiPicker.allEmojis": "Alle Emojis",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "Kürzlich verwendet",
|
||||
"blocks.chats.messagePlaceholder": "Nachricht schreiben…",
|
||||
"blocks.chats.messageStatus.delivered": "Zugestellt",
|
||||
"blocks.chats.messageStatus.failed": "Nicht gesendet",
|
||||
"blocks.chats.messageStatus.read": "Gelesen",
|
||||
"blocks.chats.messageStatus.sending": "Wird gesendet",
|
||||
"blocks.chats.messageStatus.sent": "Gesendet",
|
||||
"blocks.chats.search": "Unterhaltungen suchen",
|
||||
"blocks.chats.selectConversation": "Unterhaltung {title} auswählen",
|
||||
"blocks.chats.selectConversation.description":
|
||||
"Wähle eine Unterhaltung aus der Liste, um ihre Nachrichten zu lesen.",
|
||||
"blocks.chats.title": "Chats",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "Add files",
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "Añadir archivos",
|
||||
"blocks.chats.actions.addEmoji": "Añadir emoji",
|
||||
"blocks.chats.actions.addImage": "Añadir imagen",
|
||||
"blocks.chats.actions.backToConversations": "Volver a conversaciones",
|
||||
"blocks.chats.actions.conversationDetails": "Detalles de la conversación",
|
||||
"blocks.chats.actions.loadEarlier": "Cargar mensajes anteriores",
|
||||
"blocks.chats.actions.removeAttachment": "Quitar {name}",
|
||||
"blocks.chats.actions.retry": "Intentar de nuevo",
|
||||
"blocks.chats.actions.send": "Enviar",
|
||||
"blocks.chats.actions.sendOnEnter": "Enviar con Intro",
|
||||
"blocks.chats.actions.sending": "Enviando…",
|
||||
"blocks.chats.emptyConversations.description":
|
||||
"Inicia una conversación para verla aquí.",
|
||||
"blocks.chats.emptyConversations.title": "No hay conversaciones",
|
||||
"blocks.chats.emptyMessages.description":
|
||||
"Los mensajes de esta conversación aparecerán aquí.",
|
||||
"blocks.chats.emptyMessages.title": "Aún no hay mensajes",
|
||||
"blocks.chats.emptySearch":
|
||||
"No hay conversaciones que coincidan con tu búsqueda.",
|
||||
"blocks.chats.emojiPicker.allEmojis": "Todos los emojis",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "Usados recientemente",
|
||||
"blocks.chats.messagePlaceholder": "Escribe un mensaje…",
|
||||
"blocks.chats.messageStatus.delivered": "Entregado",
|
||||
"blocks.chats.messageStatus.failed": "No enviado",
|
||||
"blocks.chats.messageStatus.read": "Leído",
|
||||
"blocks.chats.messageStatus.sending": "Enviando",
|
||||
"blocks.chats.messageStatus.sent": "Enviado",
|
||||
"blocks.chats.search": "Buscar conversaciones",
|
||||
"blocks.chats.selectConversation": "Seleccionar conversación {title}",
|
||||
"blocks.chats.selectConversation.description":
|
||||
"Elige una conversación de la lista para leer sus mensajes.",
|
||||
"blocks.chats.title": "Chats",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
@@ -1,38 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "Ajouter des fichiers",
|
||||
"blocks.chats.actions.addEmoji": "Ajouter un emoji",
|
||||
"blocks.chats.actions.addImage": "Ajouter une image",
|
||||
"blocks.chats.actions.backToConversations": "Retour aux discussions",
|
||||
"blocks.chats.actions.conversationDetails": "Détails de la discussion",
|
||||
"blocks.chats.actions.loadEarlier": "Charger les messages précédents",
|
||||
"blocks.chats.actions.removeAttachment": "Retirer {name}",
|
||||
"blocks.chats.actions.retry": "Réessayer",
|
||||
"blocks.chats.actions.send": "Envoyer",
|
||||
"blocks.chats.actions.sendOnEnter": "Envoyer avec Entrée",
|
||||
"blocks.chats.actions.sending": "Envoi…",
|
||||
"blocks.chats.emptyConversations.description":
|
||||
"Démarrez une discussion pour la voir ici.",
|
||||
"blocks.chats.emptyConversations.title": "Aucune discussion",
|
||||
"blocks.chats.emptyMessages.description":
|
||||
"Les messages de cette discussion apparaîtront ici.",
|
||||
"blocks.chats.emptyMessages.title": "Pas encore de messages",
|
||||
"blocks.chats.emptySearch":
|
||||
"Aucune discussion ne correspond à votre recherche.",
|
||||
"blocks.chats.emojiPicker.allEmojis": "Tous les emojis",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "Récemment utilisés",
|
||||
"blocks.chats.messagePlaceholder": "Écrivez un message…",
|
||||
"blocks.chats.messageStatus.delivered": "Distribué",
|
||||
"blocks.chats.messageStatus.failed": "Non envoyé",
|
||||
"blocks.chats.messageStatus.read": "Lu",
|
||||
"blocks.chats.messageStatus.sending": "Envoi",
|
||||
"blocks.chats.messageStatus.sent": "Envoyé",
|
||||
"blocks.chats.search": "Rechercher des discussions",
|
||||
"blocks.chats.selectConversation": "Sélectionner la discussion {title}",
|
||||
"blocks.chats.selectConversation.description":
|
||||
"Choisissez une discussion dans la liste pour lire ses messages.",
|
||||
"blocks.chats.title": "Discussions",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
@@ -1,37 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "ファイルを追加",
|
||||
"blocks.chats.actions.addEmoji": "絵文字を追加",
|
||||
"blocks.chats.actions.addImage": "画像を追加",
|
||||
"blocks.chats.actions.backToConversations": "会話一覧に戻る",
|
||||
"blocks.chats.actions.conversationDetails": "会話の詳細",
|
||||
"blocks.chats.actions.loadEarlier": "以前のメッセージを読み込む",
|
||||
"blocks.chats.actions.removeAttachment": "{name} を削除",
|
||||
"blocks.chats.actions.retry": "再試行",
|
||||
"blocks.chats.actions.send": "送信",
|
||||
"blocks.chats.actions.sendOnEnter": "Enter キーで送信",
|
||||
"blocks.chats.actions.sending": "送信中…",
|
||||
"blocks.chats.emptyConversations.description":
|
||||
"会話を始めると、ここに表示されます。",
|
||||
"blocks.chats.emptyConversations.title": "会話はありません",
|
||||
"blocks.chats.emptyMessages.description":
|
||||
"この会話のメッセージはここに表示されます。",
|
||||
"blocks.chats.emptyMessages.title": "メッセージはまだありません",
|
||||
"blocks.chats.emptySearch": "検索に一致する会話はありません。",
|
||||
"blocks.chats.emojiPicker.allEmojis": "すべての絵文字",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "最近使用した絵文字",
|
||||
"blocks.chats.messagePlaceholder": "メッセージを入力…",
|
||||
"blocks.chats.messageStatus.delivered": "配信済み",
|
||||
"blocks.chats.messageStatus.failed": "未送信",
|
||||
"blocks.chats.messageStatus.read": "既読",
|
||||
"blocks.chats.messageStatus.sending": "送信中",
|
||||
"blocks.chats.messageStatus.sent": "送信済み",
|
||||
"blocks.chats.search": "会話を検索",
|
||||
"blocks.chats.selectConversation": "会話 {title} を選択",
|
||||
"blocks.chats.selectConversation.description":
|
||||
"一覧から会話を選択してメッセージを読みます。",
|
||||
"blocks.chats.title": "チャット",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
@@ -1,37 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "파일 추가",
|
||||
"blocks.chats.actions.addEmoji": "이모지 추가",
|
||||
"blocks.chats.actions.addImage": "이미지 추가",
|
||||
"blocks.chats.actions.backToConversations": "대화 목록으로 돌아가기",
|
||||
"blocks.chats.actions.conversationDetails": "대화 세부 정보",
|
||||
"blocks.chats.actions.loadEarlier": "이전 메시지 불러오기",
|
||||
"blocks.chats.actions.removeAttachment": "{name} 제거",
|
||||
"blocks.chats.actions.retry": "다시 시도",
|
||||
"blocks.chats.actions.send": "보내기",
|
||||
"blocks.chats.actions.sendOnEnter": "Enter 키로 전송",
|
||||
"blocks.chats.actions.sending": "보내는 중…",
|
||||
"blocks.chats.emptyConversations.description":
|
||||
"대화를 시작하면 여기에 표시됩니다.",
|
||||
"blocks.chats.emptyConversations.title": "대화가 없습니다",
|
||||
"blocks.chats.emptyMessages.description":
|
||||
"이 대화의 메시지가 여기에 표시됩니다.",
|
||||
"blocks.chats.emptyMessages.title": "아직 메시지가 없습니다",
|
||||
"blocks.chats.emptySearch": "검색과 일치하는 대화가 없습니다.",
|
||||
"blocks.chats.emojiPicker.allEmojis": "모든 이모지",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "최근 사용",
|
||||
"blocks.chats.messagePlaceholder": "메시지 작성…",
|
||||
"blocks.chats.messageStatus.delivered": "전달됨",
|
||||
"blocks.chats.messageStatus.failed": "전송되지 않음",
|
||||
"blocks.chats.messageStatus.read": "읽음",
|
||||
"blocks.chats.messageStatus.sending": "보내는 중",
|
||||
"blocks.chats.messageStatus.sent": "보냄",
|
||||
"blocks.chats.search": "대화 검색",
|
||||
"blocks.chats.selectConversation": "대화 {title} 선택",
|
||||
"blocks.chats.selectConversation.description":
|
||||
"목록에서 대화를 선택하여 메시지를 읽으세요.",
|
||||
"blocks.chats.title": "채팅",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
@@ -1,34 +0,0 @@
|
||||
import type { ChatMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
export const messages = {
|
||||
"blocks.chats.actions.addFiles": "新增檔案",
|
||||
"blocks.chats.actions.addEmoji": "新增表情",
|
||||
"blocks.chats.actions.addImage": "新增圖片",
|
||||
"blocks.chats.actions.backToConversations": "返回對話列表",
|
||||
"blocks.chats.actions.conversationDetails": "對話詳細資料",
|
||||
"blocks.chats.actions.loadEarlier": "載入較早訊息",
|
||||
"blocks.chats.actions.removeAttachment": "移除 {name}",
|
||||
"blocks.chats.actions.retry": "再試一次",
|
||||
"blocks.chats.actions.send": "傳送",
|
||||
"blocks.chats.actions.sendOnEnter": "按 Enter 傳送",
|
||||
"blocks.chats.actions.sending": "傳送中…",
|
||||
"blocks.chats.emptyConversations.description": "開始對話後會顯示在這裡。",
|
||||
"blocks.chats.emptyConversations.title": "沒有對話",
|
||||
"blocks.chats.emptyMessages.description": "此對話的訊息會顯示在這裡。",
|
||||
"blocks.chats.emptyMessages.title": "尚無訊息",
|
||||
"blocks.chats.emptySearch": "沒有符合搜尋條件的對話。",
|
||||
"blocks.chats.emojiPicker.allEmojis": "所有表情",
|
||||
"blocks.chats.emojiPicker.recentEmojis": "最近使用",
|
||||
"blocks.chats.messagePlaceholder": "輸入訊息…",
|
||||
"blocks.chats.messageStatus.delivered": "已送達",
|
||||
"blocks.chats.messageStatus.failed": "未傳送",
|
||||
"blocks.chats.messageStatus.read": "已讀",
|
||||
"blocks.chats.messageStatus.sending": "傳送中",
|
||||
"blocks.chats.messageStatus.sent": "已傳送",
|
||||
"blocks.chats.search": "搜尋對話",
|
||||
"blocks.chats.selectConversation": "選取對話 {title}",
|
||||
"blocks.chats.selectConversation.description": "從列表中選取對話以閱讀訊息。",
|
||||
"blocks.chats.title": "聊天",
|
||||
} as const satisfies ChatMessageCatalog
|
||||
@@ -3,27 +3,15 @@ import { describe, it } from "vitest"
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { layoutMessages } from "../messages"
|
||||
import { layoutCatalogLocales } from "./catalogs"
|
||||
import { messages as de } from "./de"
|
||||
import { messages as en } from "./en"
|
||||
import { messages as es } from "./es"
|
||||
import { messages as fr } from "./fr"
|
||||
import { messages as ja } from "./ja"
|
||||
import { messages as ko } from "./ko"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
import { messages as zhHant } from "./zh-Hant"
|
||||
|
||||
describe("layout locale catalogs", () => {
|
||||
it("ship every layout message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
de,
|
||||
en,
|
||||
es,
|
||||
fr,
|
||||
ja,
|
||||
ko,
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
"zh-Hant": zhHant,
|
||||
},
|
||||
locales: layoutCatalogLocales,
|
||||
messageIds: Object.values(layoutMessages).map(
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "Breadcrumb-Menü öffnen",
|
||||
"blocks.refresh.description": "Daten der aktuellen Seite aktualisieren",
|
||||
"blocks.refresh.label": "Aktuelle Seitendaten aktualisieren",
|
||||
"blocks.userMenu.accountPassword": "Kontopasswort",
|
||||
"blocks.userMenu.appearance": "Darstellung",
|
||||
"blocks.userMenu.keybindings": "Tastenkürzel",
|
||||
"blocks.userMenu.logout": "Abmelden",
|
||||
"blocks.userMenu.open": "Benutzermenü öffnen",
|
||||
"blocks.userMenu.title": "Benutzermenü",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "Open breadcrumb menu",
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "Abrir el menú de ruta de navegación",
|
||||
"blocks.refresh.description": "Actualizar los datos de la página actual",
|
||||
"blocks.refresh.label": "Actualizar datos de la página actual",
|
||||
"blocks.userMenu.accountPassword": "Contraseña de la cuenta",
|
||||
"blocks.userMenu.appearance": "Apariencia",
|
||||
"blocks.userMenu.keybindings": "Atajos de teclado",
|
||||
"blocks.userMenu.logout": "Cerrar sesión",
|
||||
"blocks.userMenu.open": "Abrir menú de usuario",
|
||||
"blocks.userMenu.title": "Menú de usuario",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "Ouvrir le menu du fil d’Ariane",
|
||||
"blocks.refresh.description": "Actualiser les données de la page actuelle",
|
||||
"blocks.refresh.label": "Actualiser les données de la page",
|
||||
"blocks.userMenu.accountPassword": "Mot de passe du compte",
|
||||
"blocks.userMenu.appearance": "Apparence",
|
||||
"blocks.userMenu.keybindings": "Raccourcis clavier",
|
||||
"blocks.userMenu.logout": "Se déconnecter",
|
||||
"blocks.userMenu.open": "Ouvrir le menu utilisateur",
|
||||
"blocks.userMenu.title": "Menu utilisateur",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "パンくずメニューを開く",
|
||||
"blocks.refresh.description": "現在のページのデータを更新します",
|
||||
"blocks.refresh.label": "現在のページを更新",
|
||||
"blocks.userMenu.accountPassword": "アカウントのパスワード",
|
||||
"blocks.userMenu.appearance": "外観",
|
||||
"blocks.userMenu.keybindings": "キーバインド",
|
||||
"blocks.userMenu.logout": "ログアウト",
|
||||
"blocks.userMenu.open": "ユーザーメニューを開く",
|
||||
"blocks.userMenu.title": "ユーザーメニュー",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "이동 경로 메뉴 열기",
|
||||
"blocks.refresh.description": "현재 페이지 데이터를 새로 고칩니다",
|
||||
"blocks.refresh.label": "현재 페이지 데이터 새로 고침",
|
||||
"blocks.userMenu.accountPassword": "계정 비밀번호",
|
||||
"blocks.userMenu.appearance": "화면 모양",
|
||||
"blocks.userMenu.keybindings": "키 바인딩",
|
||||
"blocks.userMenu.logout": "로그아웃",
|
||||
"blocks.userMenu.open": "사용자 메뉴 열기",
|
||||
"blocks.userMenu.title": "사용자 메뉴",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
@@ -1,15 +0,0 @@
|
||||
import type { LayoutMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
export const messages = {
|
||||
"blocks.breadcrumb.menuLabel": "開啟麵包屑選單",
|
||||
"blocks.refresh.description": "重新整理目前頁面的資料",
|
||||
"blocks.refresh.label": "重新整理目前頁面資料",
|
||||
"blocks.userMenu.accountPassword": "帳號密碼",
|
||||
"blocks.userMenu.appearance": "介面外觀",
|
||||
"blocks.userMenu.keybindings": "按鍵綁定",
|
||||
"blocks.userMenu.logout": "登出",
|
||||
"blocks.userMenu.open": "開啟使用者選單",
|
||||
"blocks.userMenu.title": "使用者選單",
|
||||
} as const satisfies LayoutMessageCatalog
|
||||
@@ -0,0 +1,22 @@
|
||||
import { describe, it } from "vitest"
|
||||
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { mediaMessages } from "../messages"
|
||||
import { mediaCatalogLocales } from "./catalogs"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
|
||||
describe("media locale catalogs", () => {
|
||||
it("ships every media message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
},
|
||||
locales: mediaCatalogLocales,
|
||||
messageIds: Object.values(mediaMessages).map(
|
||||
(descriptor) => descriptor.id
|
||||
),
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -1,4 +1,10 @@
|
||||
import type { mediaMessages } from "../messages"
|
||||
import type { BlockMessageCatalog } from "../../../i18n/catalogs"
|
||||
import {
|
||||
blockCatalogLocales,
|
||||
type BlockCatalogLocale,
|
||||
type BlockMessageCatalog,
|
||||
} from "../../../i18n/catalogs"
|
||||
|
||||
export { blockCatalogLocales as mediaCatalogLocales }
|
||||
export type MediaCatalogLocale = BlockCatalogLocale
|
||||
export type MediaMessageCatalog = BlockMessageCatalog<typeof mediaMessages>
|
||||
|
||||
+15
-8
@@ -1,6 +1,6 @@
|
||||
import type { MediaMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
export const messages = {
|
||||
"blocks.media.actions.cancel": "Cancel",
|
||||
@@ -21,10 +21,13 @@ export const messages = {
|
||||
"blocks.media.actions.unfavorite": "Unfavorite",
|
||||
"blocks.media.actions.upload": "Upload",
|
||||
"blocks.media.actions.viewOriginal": "View original",
|
||||
"blocks.media.copy.failed": "Copy failed. Check browser clipboard permissions.",
|
||||
"blocks.media.deleteAsset.description": "This media item will no longer appear in the library.",
|
||||
"blocks.media.copy.failed":
|
||||
"Copy failed. Check browser clipboard permissions.",
|
||||
"blocks.media.deleteAsset.description":
|
||||
"This media item will no longer appear in the library.",
|
||||
"blocks.media.deleteAsset.title": "Delete media",
|
||||
"blocks.media.deleteFolder.description": "This folder and its child folders will be deleted. Their media items will become unclassified.",
|
||||
"blocks.media.deleteFolder.description":
|
||||
"This folder and its child folders will be deleted. Their media items will become unclassified.",
|
||||
"blocks.media.deleteFolder.title": "Delete folder",
|
||||
"blocks.media.details.dimensions": "Dimensions",
|
||||
"blocks.media.details.fileName": "File name",
|
||||
@@ -32,7 +35,8 @@ export const messages = {
|
||||
"blocks.media.details.size": "Size",
|
||||
"blocks.media.details.type": "Type",
|
||||
"blocks.media.details.uploadedAt": "Uploaded",
|
||||
"blocks.media.empty.description": "Upload images or videos to manage them here.",
|
||||
"blocks.media.empty.description":
|
||||
"Upload images or videos to manage them here.",
|
||||
"blocks.media.empty.title": "No media",
|
||||
"blocks.media.emptySearch.description": "No media files match your search.",
|
||||
"blocks.media.filters.all": "All media",
|
||||
@@ -40,7 +44,8 @@ export const messages = {
|
||||
"blocks.media.filters.image": "Images",
|
||||
"blocks.media.filters.unclassified": "Unclassified",
|
||||
"blocks.media.filters.video": "Videos",
|
||||
"blocks.media.folders.classification": "Folders only organize media in this library and do not change file URLs.",
|
||||
"blocks.media.folders.classification":
|
||||
"Folders only organize media in this library and do not change file URLs.",
|
||||
"blocks.media.folders.create": "New folder",
|
||||
"blocks.media.folders.empty": "No folders yet. Create one.",
|
||||
"blocks.media.folders.name": "Folder name",
|
||||
@@ -50,11 +55,13 @@ export const messages = {
|
||||
"blocks.media.folders.title": "Folders",
|
||||
"blocks.media.load.error": "Unable to load media",
|
||||
"blocks.media.loading": "Loading media…",
|
||||
"blocks.media.picker.description": "Choose an uploaded image or video from the media library.",
|
||||
"blocks.media.picker.description":
|
||||
"Choose an uploaded image or video from the media library.",
|
||||
"blocks.media.picker.selectedCount": "{count} selected",
|
||||
"blocks.media.picker.title": "Select media",
|
||||
"blocks.media.picker.useSelected": "Use selected media",
|
||||
"blocks.media.renameMedia.description": "This changes the display name without changing the file or its URL.",
|
||||
"blocks.media.renameMedia.description":
|
||||
"This changes the display name without changing the file or its URL.",
|
||||
"blocks.media.renameMedia.title": "Rename media",
|
||||
"blocks.media.search": "Search media files",
|
||||
"blocks.media.title": "Media library",
|
||||
@@ -72,7 +72,7 @@ function MediaTestProvider({
|
||||
children: ReactNode
|
||||
}) {
|
||||
return (
|
||||
<I18nProvider locale="en">
|
||||
<I18nProvider locale="en-US">
|
||||
<MediaProvider adapter={adapter}>{children}</MediaProvider>
|
||||
</I18nProvider>
|
||||
)
|
||||
|
||||
@@ -3,27 +3,15 @@ import { describe, it } from "vitest"
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { navigationMessages } from "../messages"
|
||||
import { navigationCatalogLocales } from "./catalogs"
|
||||
import { messages as de } from "./de"
|
||||
import { messages as en } from "./en"
|
||||
import { messages as es } from "./es"
|
||||
import { messages as fr } from "./fr"
|
||||
import { messages as ja } from "./ja"
|
||||
import { messages as ko } from "./ko"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
import { messages as zhHant } from "./zh-Hant"
|
||||
|
||||
describe("navigation locale catalogs", () => {
|
||||
it("ship every navigation message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
de,
|
||||
en,
|
||||
es,
|
||||
fr,
|
||||
ja,
|
||||
ko,
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
"zh-Hant": zhHant,
|
||||
},
|
||||
locales: navigationCatalogLocales,
|
||||
messageIds: Object.values(navigationMessages).map(
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "Durch die Anwendung navigieren.",
|
||||
"blocks.navigation.open": "Navigation öffnen",
|
||||
"blocks.navigation.title": "Navigation",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "Navigate through the app.",
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "Navega por la aplicación.",
|
||||
"blocks.navigation.open": "Abrir navegación",
|
||||
"blocks.navigation.title": "Navegación",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "Naviguez dans l’application.",
|
||||
"blocks.navigation.open": "Ouvrir la navigation",
|
||||
"blocks.navigation.title": "Navigation",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "アプリ内のページを移動します。",
|
||||
"blocks.navigation.open": "ナビゲーションを開く",
|
||||
"blocks.navigation.title": "ナビゲーション",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "앱의 페이지를 탐색합니다.",
|
||||
"blocks.navigation.open": "탐색 메뉴 열기",
|
||||
"blocks.navigation.title": "탐색",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { NavigationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
export const messages = {
|
||||
"blocks.navigation.description": "瀏覽應用程式中的頁面。",
|
||||
"blocks.navigation.open": "開啟導覽",
|
||||
"blocks.navigation.title": "導覽",
|
||||
} as const satisfies NavigationMessageCatalog
|
||||
@@ -3,27 +3,15 @@ import { describe, it } from "vitest"
|
||||
import { expectCompleteCatalogs } from "../../../i18n/test-catalogs"
|
||||
import { notificationMessages } from "../messages"
|
||||
import { notificationCatalogLocales } from "./catalogs"
|
||||
import { messages as de } from "./de"
|
||||
import { messages as en } from "./en"
|
||||
import { messages as es } from "./es"
|
||||
import { messages as fr } from "./fr"
|
||||
import { messages as ja } from "./ja"
|
||||
import { messages as ko } from "./ko"
|
||||
import { messages as enUS } from "./en-US"
|
||||
import { messages as zhHans } from "./zh-Hans"
|
||||
import { messages as zhHant } from "./zh-Hant"
|
||||
|
||||
describe("notification locale catalogs", () => {
|
||||
it("ship every notification message in every built-in locale", () => {
|
||||
expectCompleteCatalogs({
|
||||
catalogs: {
|
||||
de,
|
||||
en,
|
||||
es,
|
||||
fr,
|
||||
ja,
|
||||
ko,
|
||||
"en-US": enUS,
|
||||
"zh-Hans": zhHans,
|
||||
"zh-Hant": zhHant,
|
||||
},
|
||||
locales: notificationCatalogLocales,
|
||||
messageIds: Object.values(notificationMessages).map(
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "de"
|
||||
export const languageTag = "de-DE"
|
||||
export const messages = {
|
||||
"blocks.notifications.description":
|
||||
"Benachrichtigungen anzeigen und verwalten",
|
||||
"blocks.notifications.empty.description":
|
||||
"Neue Aktivitäten werden hier angezeigt.",
|
||||
"blocks.notifications.empty.title": "Keine Benachrichtigungen",
|
||||
"blocks.notifications.error.description":
|
||||
"Überprüfen Sie Ihre Netzwerkverbindung und versuchen Sie es erneut.",
|
||||
"blocks.notifications.error.title":
|
||||
"Benachrichtigungen konnten nicht geladen werden",
|
||||
"blocks.notifications.justNow": "gerade eben",
|
||||
"blocks.notifications.loading": "Benachrichtigungen werden geladen…",
|
||||
"blocks.notifications.markAllAsRead": "Alle als gelesen markieren",
|
||||
"blocks.notifications.retry": "Erneut versuchen",
|
||||
"blocks.notifications.title": "Benachrichtigungen",
|
||||
"blocks.notifications.viewAll": "Alle anzeigen",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "en"
|
||||
export const locale = "en-US"
|
||||
export const languageTag = "en-US"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "View and manage notifications",
|
||||
@@ -1,20 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "es"
|
||||
export const languageTag = "es-ES"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "Ver y gestionar notificaciones",
|
||||
"blocks.notifications.empty.description":
|
||||
"La actividad nueva aparecerá aquí.",
|
||||
"blocks.notifications.empty.title": "No hay notificaciones",
|
||||
"blocks.notifications.error.description":
|
||||
"Comprueba la conexión de red e inténtalo de nuevo.",
|
||||
"blocks.notifications.error.title":
|
||||
"No se pudieron cargar las notificaciones",
|
||||
"blocks.notifications.justNow": "ahora mismo",
|
||||
"blocks.notifications.loading": "Cargando notificaciones…",
|
||||
"blocks.notifications.markAllAsRead": "Marcar todo como leído",
|
||||
"blocks.notifications.retry": "Intentar de nuevo",
|
||||
"blocks.notifications.title": "Notificaciones",
|
||||
"blocks.notifications.viewAll": "Ver todo",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "fr"
|
||||
export const languageTag = "fr-FR"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "Afficher et gérer les notifications",
|
||||
"blocks.notifications.empty.description":
|
||||
"Les nouvelles activités apparaîtront ici.",
|
||||
"blocks.notifications.empty.title": "Aucune notification",
|
||||
"blocks.notifications.error.description":
|
||||
"Vérifiez votre connexion réseau et réessayez.",
|
||||
"blocks.notifications.error.title": "Impossible de charger les notifications",
|
||||
"blocks.notifications.justNow": "à l’instant",
|
||||
"blocks.notifications.loading": "Chargement des notifications…",
|
||||
"blocks.notifications.markAllAsRead": "Tout marquer comme lu",
|
||||
"blocks.notifications.retry": "Réessayer",
|
||||
"blocks.notifications.title": "Notifications",
|
||||
"blocks.notifications.viewAll": "Tout afficher",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
@@ -1,19 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ja"
|
||||
export const languageTag = "ja-JP"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "通知を表示・管理します",
|
||||
"blocks.notifications.empty.description":
|
||||
"新しいアクティビティがここに表示されます。",
|
||||
"blocks.notifications.empty.title": "通知はありません",
|
||||
"blocks.notifications.error.description":
|
||||
"ネットワーク接続を確認して、もう一度お試しください。",
|
||||
"blocks.notifications.error.title": "通知を読み込めませんでした",
|
||||
"blocks.notifications.justNow": "たった今",
|
||||
"blocks.notifications.loading": "通知を読み込み中…",
|
||||
"blocks.notifications.markAllAsRead": "すべて既読にする",
|
||||
"blocks.notifications.retry": "再試行",
|
||||
"blocks.notifications.title": "通知",
|
||||
"blocks.notifications.viewAll": "すべて表示",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
@@ -1,18 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "ko"
|
||||
export const languageTag = "ko-KR"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "알림 보기 및 관리",
|
||||
"blocks.notifications.empty.description": "새 활동이 여기에 표시됩니다.",
|
||||
"blocks.notifications.empty.title": "알림 없음",
|
||||
"blocks.notifications.error.description":
|
||||
"네트워크 연결을 확인한 후 다시 시도하세요.",
|
||||
"blocks.notifications.error.title": "알림을 불러올 수 없음",
|
||||
"blocks.notifications.justNow": "방금",
|
||||
"blocks.notifications.loading": "알림 불러오는 중…",
|
||||
"blocks.notifications.markAllAsRead": "모두 읽음으로 표시",
|
||||
"blocks.notifications.retry": "다시 시도",
|
||||
"blocks.notifications.title": "알림",
|
||||
"blocks.notifications.viewAll": "모두 보기",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
@@ -1,17 +0,0 @@
|
||||
import type { NotificationMessageCatalog } from "./catalogs"
|
||||
|
||||
export const locale = "zh-Hant"
|
||||
export const languageTag = "zh-TW"
|
||||
export const messages = {
|
||||
"blocks.notifications.description": "檢視並管理通知",
|
||||
"blocks.notifications.empty.description": "新的動態會顯示在這裡。",
|
||||
"blocks.notifications.empty.title": "沒有通知",
|
||||
"blocks.notifications.error.description": "請檢查網路連線後再試一次。",
|
||||
"blocks.notifications.error.title": "無法載入通知",
|
||||
"blocks.notifications.justNow": "剛剛",
|
||||
"blocks.notifications.loading": "正在載入通知…",
|
||||
"blocks.notifications.markAllAsRead": "全部標示為已讀",
|
||||
"blocks.notifications.retry": "再試一次",
|
||||
"blocks.notifications.title": "通知",
|
||||
"blocks.notifications.viewAll": "檢視全部",
|
||||
} as const satisfies NotificationMessageCatalog
|
||||
@@ -1,13 +1,4 @@
|
||||
export const blockCatalogLocales = [
|
||||
"de",
|
||||
"en",
|
||||
"es",
|
||||
"fr",
|
||||
"ja",
|
||||
"ko",
|
||||
"zh-Hans",
|
||||
"zh-Hant",
|
||||
] as const
|
||||
export const blockCatalogLocales = ["en-US", "zh-Hans"] as const
|
||||
|
||||
interface MessageDescriptorMap {
|
||||
readonly [key: string]: {
|
||||
|
||||
@@ -11,9 +11,13 @@ export function expectCompleteCatalogs({
|
||||
}) {
|
||||
expect(Object.keys(catalogs)).toEqual([...locales])
|
||||
|
||||
const expectedIds = [...messageIds].sort()
|
||||
// ES2022 compatibility: copy before sorting so the input remains immutable.
|
||||
// oxlint-disable-next-line unicorn/no-array-sort
|
||||
const expectedIds = Array.from(messageIds).sort()
|
||||
|
||||
for (const messages of Object.values(catalogs)) {
|
||||
// Object.keys returns a fresh array.
|
||||
// oxlint-disable-next-line unicorn/no-array-sort
|
||||
expect(Object.keys(messages).sort()).toEqual(expectedIds)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user