feat(i18n): standardize bilingual catalogs and tooling

This commit is contained in:
Maofeng
2026-09-20 15:52:31 +08:00
parent ea00a71112
commit 6cd981d6a2
92 changed files with 685 additions and 1986 deletions
@@ -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
@@ -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":
"Linterface utilisera toujours le thème sombre",
"blocks.appearance.mode.light": "Clair",
"blocks.appearance.mode.light.description":
"Linterface utilisera toujours le thème clair",
"blocks.appearance.mode.system": "Système",
"blocks.appearance.mode.system.description":
"Le thème de linterface suivra lapparence 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,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,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 dAriane",
"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>
@@ -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,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 lapplication.",
"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,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": "à linstant",
"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 -10
View File
@@ -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]: {
+5 -1
View File
@@ -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)
}
}