Skip to content

Commit 38c1cee

Browse files
committed
frontend/i18n: translate language names, to make them recognizable; refactoring
1 parent 848d2fc commit 38c1cee

File tree

11 files changed

+142
-45
lines changed

11 files changed

+142
-45
lines changed

src/packages/frontend/account/account-page.tsx

Lines changed: 26 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ import { UpgradesPage } from "./upgrades/upgrades-page";
5151

5252
export const AccountPage: React.FC = () => {
5353
const intl = useIntl();
54-
const { setLocale } = useLocalizationCtx();
54+
const { setLocale, locale } = useLocalizationCtx();
5555

5656
const { width: windowWidth } = useWindowDimensions();
5757
const isWide = windowWidth > 800;
@@ -266,9 +266,12 @@ export const AccountPage: React.FC = () => {
266266
const i18n: Locale = getLocale(other_settings);
267267

268268
const items: MenuProps["items"] =
269-
Object.entries(LOCALIZATIONS).map(([key, { name, flag }]) => {
270-
return { key, label: `${flag} ${name}` };
271-
}) ?? [];
269+
Object.entries(LOCALIZATIONS).map(
270+
([key, { name, trans, native, flag }]) => {
271+
const other = key === locale ? name : intl.formatMessage(trans);
272+
return { key, label: `${flag} ${native} (${other})` };
273+
},
274+
) ?? [];
272275

273276
items.push({ type: "divider" });
274277
items.push({
@@ -285,6 +288,7 @@ export const AccountPage: React.FC = () => {
285288
),
286289
onClick: () =>
287290
Modal.info({
291+
width: "min(90vw, 600px)",
288292
title: intl.formatMessage({
289293
id: "account.account_page.translation.info.title",
290294
defaultMessage: "Translation Information",
@@ -326,16 +330,29 @@ Thank you for your patience and understanding as we work to make our application
326330

327331
const lang_icon = LOCALIZATIONS[i18n]?.flag;
328332

333+
const title =
334+
i18n in LOCALIZATIONS
335+
? intl.formatMessage(LOCALIZATIONS[i18n].trans)
336+
: i18n;
337+
338+
const cur = `${title} (${LOCALIZATIONS[i18n]?.name ?? i18n})`;
339+
const msg = intl.formatMessage(labels.account_language_tooltip);
340+
const tooltip = (
341+
<>
342+
{cur}
343+
<br />
344+
{msg}
345+
<br />({labels.account_language_tooltip.defaultMessage})
346+
</>
347+
);
348+
329349
return (
330-
<Tooltip
331-
title={intl.formatMessage(labels.account_language_tooltip)}
332-
trigger={["hover"]}
333-
>
350+
<Tooltip title={tooltip} trigger={["hover"]}>
334351
<Dropdown menu={menu} trigger={["click"]}>
335352
<Button>
336353
<Space>
337354
{lang_icon}
338-
{isWide ? LOCALIZATIONS[i18n]?.name ?? i18n : undefined}
355+
{isWide ? title : undefined}
339356
<DownOutlined />
340357
</Space>
341358
</Button>

src/packages/frontend/app/context.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { theme, ThemeConfig } from "antd";
77
import type { SizeType } from "antd/es/config-provider/SizeContext";
88
import { debounce } from "lodash";
99
import { createContext, ReactNode, useContext } from "react";
10+
import { useIntl } from "react-intl";
1011

1112
import {
1213
CSS,
@@ -15,9 +16,8 @@ import {
1516
useState,
1617
useTypedRedux,
1718
} from "@cocalc/frontend/app-framework";
18-
import { IntlMessage, isIntlMessage } from "@cocalc/frontend/i18n";
1919
import { COLORS } from "@cocalc/util/theme";
20-
import { useIntl } from "react-intl";
20+
import { IntlMessage, isIntlMessage } from "@cocalc/frontend/i18n";
2121
import {
2222
FONT_SIZE_ICONS_NARROW,
2323
FONT_SIZE_ICONS_NORMAL,

src/packages/frontend/frame-editors/frame-tree/commands/manage.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
/*
2+
* This file is part of CoCalc: Copyright © 2024 Sagemath, Inc.
3+
* License: MS-RSL – see LICENSE.md for details
4+
*/
5+
16
import { Button, Tooltip } from "antd";
27
import { ReactNode } from "react";
38
import { IntlShape } from "react-intl";

src/packages/frontend/i18n/de_DE.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"command.generic.build.title": "Kompiliere das Dokument.{br}Um das automatische Kompilieren beim Speichern ein- oder auszuschalten, klicke den 'Kompiliere beim Speichern' Button oder Menüeintrag.",
1616
"command.generic.force_build.label": "Erzwinge Kompilieren",
1717
"command.generic.force_build.title": "Das gesamte Dokument wird komplett neu kompiliert.",
18+
"i18n.localization.lang.chinese": "Chinesisch",
19+
"i18n.localization.lang.english": "Englisch",
20+
"i18n.localization.lang.german": "Deutsch",
21+
"i18n.localization.lang.spanish": "Spanisch",
1822
"jupyter.select_kernel.footer": "<strong>Hinweis:</strong> Sie können den ausgewählten Kernel später im Kernel-Menü oder durch einen Klick auf das Kernel-Status-Logo oben links jederzeit ändern.",
1923
"labels.acconut.password": "Passwort",
2024
"labels.acconut.password.change": "Passwort Ändern",

src/packages/frontend/i18n/es_ES.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"command.generic.build.title": "",
1616
"command.generic.force_build.label": "",
1717
"command.generic.force_build.title": "",
18+
"i18n.localization.lang.chinese": "Chino",
19+
"i18n.localization.lang.english": "Inglés",
20+
"i18n.localization.lang.german": "Alemán",
21+
"i18n.localization.lang.spanish": "Español",
1822
"jupyter.select_kernel.footer": "<strong>Nota:</strong> Siempre puedes cambiar el kernel seleccionado más tarde en el menú Kernel o haciendo clic en el logotipo de estado del kernel en la parte superior izquierda.",
1923
"labels.acconut.password": "Contraseña",
2024
"labels.acconut.password.change": "Cambiar la contraseña",

src/packages/frontend/i18n/extracted.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,18 @@
5353
"command.generic.force_build.title": {
5454
"defaultMessage": "Force rebuild entire project."
5555
},
56+
"i18n.localization.lang.chinese": {
57+
"defaultMessage": "Chinese"
58+
},
59+
"i18n.localization.lang.english": {
60+
"defaultMessage": "English"
61+
},
62+
"i18n.localization.lang.german": {
63+
"defaultMessage": "German"
64+
},
65+
"i18n.localization.lang.spanish": {
66+
"defaultMessage": "Spanish"
67+
},
5668
"jupyter.select_kernel.footer": {
5769
"defaultMessage": "<strong>Note:</strong> You can always change the selected kernel later in the Kernel menu or by clicking on the kernel status logo in the top left.",
5870
"description": "Jupyter kernel selector, bottom."

src/packages/frontend/i18n/index.ts

Lines changed: 57 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,27 @@
1+
/*
2+
* This file is part of CoCalc: Copyright © 2024 Sagemath, Inc.
3+
* License: MS-RSL – see LICENSE.md for details
4+
*/
5+
16
import {
27
createIntl,
38
createIntlCache,
9+
defineMessage,
410
IntlShape,
5-
MessageDescriptor,
611
MessageFormatElement,
712
} from "react-intl";
813

914
import { AccountState } from "@cocalc/frontend/account/types";
1015
import { redux } from "@cocalc/frontend/app-framework";
11-
import {
12-
DEFAULT_LOCALE,
13-
Locale,
14-
LOCALIZATIONS,
15-
} from "@cocalc/util/consts/locale";
16+
import { DEFAULT_LOCALE, Locale } from "@cocalc/util/consts/locale";
1617
import { unreachable } from "@cocalc/util/misc";
18+
import { IntlMessage, isIntlMessage } from "./types";
1719

1820
export { labels } from "./common";
19-
export { DEFAULT_LOCALE, LOCALIZATIONS };
20-
export type { Locale };
21+
22+
export { DEFAULT_LOCALE, isIntlMessage };
23+
24+
export type { IntlMessage, Locale };
2125

2226
export const OTHER_SETTINGS_LOCALE_KEY = "i18n";
2327

@@ -72,18 +76,48 @@ export async function getIntl(): Promise<IntlShape> {
7276
return createIntl({ locale, messages }, cache);
7377
}
7478

75-
// In CoCalc, we require all message to have an ID and defaultMessage (which is English)
76-
export type IntlMessage = MessageDescriptor & {
77-
id: string;
78-
defaultMessage: string;
79-
};
80-
81-
// For us, the id and defaultMessage must be set to be a MessageDescriptor
82-
export function isIntlMessage(msg: unknown): msg is MessageDescriptor {
83-
return (
84-
typeof msg === "object" &&
85-
msg != null &&
86-
"id" in msg &&
87-
"defaultMessage" in msg
88-
);
89-
}
79+
export const LOCALIZATIONS: {
80+
[key in Locale]: {
81+
name: string;
82+
flag: string;
83+
native: string;
84+
trans: IntlMessage;
85+
};
86+
} = {
87+
en: {
88+
name: "English",
89+
flag: "🇺🇸",
90+
native: "English",
91+
trans: defineMessage({
92+
id: "i18n.localization.lang.english",
93+
defaultMessage: "English",
94+
}),
95+
},
96+
es: {
97+
name: "Spanish",
98+
flag: "🇪🇸",
99+
native: "Español",
100+
trans: defineMessage({
101+
id: "i18n.localization.lang.spanish",
102+
defaultMessage: "Spanish",
103+
}),
104+
},
105+
de: {
106+
name: "German",
107+
flag: "🇩🇪",
108+
native: "Deutsch",
109+
trans: defineMessage({
110+
id: "i18n.localization.lang.german",
111+
defaultMessage: "German",
112+
}),
113+
},
114+
zh: {
115+
name: "Chinese",
116+
flag: "🇨🇳",
117+
native: "中文",
118+
trans: defineMessage({
119+
id: "i18n.localization.lang.chinese",
120+
defaultMessage: "Chinese",
121+
}),
122+
},
123+
} as const;
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
* This file is part of CoCalc: Copyright © 2024 Sagemath, Inc.
3+
* License: MS-RSL – see LICENSE.md for details
4+
*/
5+
6+
import { MessageDescriptor } from "react-intl";
7+
8+
// In CoCalc, we require all message to have an ID and defaultMessage (which is English)
9+
export type IntlMessage = MessageDescriptor & {
10+
id: string;
11+
defaultMessage: string;
12+
};
13+
14+
// For us, the id and defaultMessage must be set to be a MessageDescriptor
15+
export function isIntlMessage(msg: unknown): msg is MessageDescriptor {
16+
return (
17+
typeof msg === "object" &&
18+
msg != null &&
19+
"id" in msg &&
20+
"defaultMessage" in msg
21+
);
22+
}

src/packages/frontend/i18n/zh_CN.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515
"command.generic.build.title": "",
1616
"command.generic.force_build.label": "",
1717
"command.generic.force_build.title": "",
18+
"i18n.localization.lang.chinese": "中文",
19+
"i18n.localization.lang.english": "英语",
20+
"i18n.localization.lang.german": "德语",
21+
"i18n.localization.lang.spanish": "西班牙语",
1822
"jupyter.select_kernel.footer": "<strong>注意:</strong>稍后,您可以通过内核菜单或点击左上角的内核状态徽标更改所选内核。",
1923
"labels.acconut.password": "密码",
2024
"labels.acconut.password.change": "更改密码",

src/packages/frontend/project/page/flyouts/header.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import { redux, useTypedRedux } from "@cocalc/frontend/app-framework";
1212
import { Icon } from "@cocalc/frontend/components";
1313
import { ComputeServerDocStatus } from "@cocalc/frontend/compute/doc-status";
1414
import SelectComputeServerForFileExplorer from "@cocalc/frontend/compute/select-server-for-explorer";
15+
import { isIntlMessage } from "@cocalc/frontend/i18n";
1516
import { useProjectContext } from "@cocalc/frontend/project/context";
1617
import { PathNavigator } from "@cocalc/frontend/project/explorer/path-navigator";
1718
import track from "@cocalc/frontend/user-tracking";
@@ -23,7 +24,6 @@ import { FIXED_TABS_BG_COLOR } from "../tabs";
2324
import { ActiveHeader } from "./active-header";
2425
import { FLYOUT_PADDING } from "./consts";
2526
import { LogHeader } from "./log-header";
26-
import { isIntlMessage } from "../../../i18n";
2727

2828
const FLYOUT_FULLPAGE_TOUR_NAME: TourName = "flyout-fullpage";
2929

0 commit comments

Comments
 (0)