Skip to content

Commit c7da66a

Browse files
committed
Add i18n support with Chinese translations; based on i18n work by songfei <songfei.org@qq.com>
1 parent 55c7e25 commit c7da66a

35 files changed

Lines changed: 828 additions & 160 deletions

package-lock.json

Lines changed: 83 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
"d3-delaunay": "^6.0.4",
2121
"d3-fisheye": "^2.1.2",
2222
"gcode-toolpath": "^3.0.0",
23+
"i18next": "^24.2.3",
24+
"i18next-browser-languagedetector": "^8.0.4",
2325
"javascript-algorithms": "0.0.5",
2426
"kdbush": "^4.0.2",
2527
"konva": "^10.0.12",
@@ -38,6 +40,7 @@
3840
"react-dom": "^19.2.0",
3941
"react-error-boundary": "^6.0.0",
4042
"react-ga4": "^2.1.0",
43+
"react-i18next": "^15.4.1",
4144
"react-icons": "^5.5.0",
4245
"react-konva": "^19.2.1",
4346
"react-redux": "^9.2.0",

src/components/CheckboxOption.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react"
2+
import { useTranslation } from "react-i18next"
23
import Col from "react-bootstrap/Col"
34
import Row from "react-bootstrap/Row"
45
import Form from "react-bootstrap/Form"
@@ -13,6 +14,7 @@ const CheckboxOption = ({
1314
onChange,
1415
label = true,
1516
}) => {
17+
const { t } = useTranslation()
1618
const option = options[optionKey]
1719
const visible =
1820
option.isVisible === undefined ? true : option.isVisible(model, data)
@@ -36,7 +38,7 @@ const CheckboxOption = ({
3638
htmlFor="options-step"
3739
className="mb-0"
3840
>
39-
{option.title}
41+
{t(option.title)}
4042
</Form.Label>
4143
)}
4244
</Col>

src/components/DropdownOption.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/* global document */
22

33
import React from "react"
4+
import { useTranslation } from "react-i18next"
45
import Col from "react-bootstrap/Col"
56
import Row from "react-bootstrap/Row"
67
import Form from "react-bootstrap/Form"
@@ -14,6 +15,7 @@ const DropdownOption = ({
1415
onChange,
1516
index,
1617
}) => {
18+
const { t } = useTranslation()
1719
const option = options[optionKey]
1820
const currentChoice = data[optionKey]
1921

@@ -24,10 +26,10 @@ const DropdownOption = ({
2426

2527
choices = Array.isArray(choices)
2628
? choices.map((choice) => {
27-
return { value: choice, label: choice }
29+
return { value: choice, label: t(choice) }
2830
})
2931
: Object.keys(choices).map((key) => {
30-
return { value: key, label: choices[key] }
32+
return { value: key, label: t(choices[key]) }
3133
})
3234
const currentLabel = (
3335
choices.find((choice) => choice.value == currentChoice) || choices[0]
@@ -57,7 +59,7 @@ const DropdownOption = ({
5759
className="m-0"
5860
htmlFor="options-dropdown"
5961
>
60-
{option.title}
62+
{t(option.title)}
6163
</Form.Label>
6264
</Col>
6365

src/components/InputOption.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React, { useState, useEffect, useRef } from "react"
2+
import { useTranslation } from "react-i18next"
23
import Col from "react-bootstrap/Col"
34
import Row from "react-bootstrap/Row"
45
import Form from "react-bootstrap/Form"
@@ -16,6 +17,7 @@ const InputOption = ({
1617
label = true,
1718
}) => {
1819
inputRef ||= useRef()
20+
const { t } = useTranslation()
1921
const [value, setValue] = useState(data[optionKey])
2022
const shiftKeyPressed = useKeyPress("Shift", inputRef)
2123

@@ -109,7 +111,7 @@ const InputOption = ({
109111
htmlFor={`option-${optionKey}`}
110112
className="mb-0"
111113
>
112-
{title}
114+
{t(title)}
113115
</Form.Label>
114116
)}
115117
</Col>
@@ -130,7 +132,7 @@ const InputOption = ({
130132
className="me-2 mb-0"
131133
style={{ width: "22px" }}
132134
>
133-
{title}
135+
{t(title)}
134136
</Form.Label>
135137
)}
136138
{renderedInput}

src/components/QuadrantButtonsOption.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from "react"
2+
import { useTranslation } from "react-i18next"
23
import Col from "react-bootstrap/Col"
34
import Row from "react-bootstrap/Row"
45
import Form from "react-bootstrap/Form"
56
import ToggleButton from "react-bootstrap/ToggleButton"
67
import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup"
78

89
const QuadrantButtonsOption = (props) => {
10+
const { t } = useTranslation()
911
const option = props.options[props.optionKey]
1012
const { data } = props
1113
const value = data[props.optionKey]
@@ -22,7 +24,7 @@ const QuadrantButtonsOption = (props) => {
2224
sm={5}
2325
className="mb-1"
2426
>
25-
<Form.Label className="m-0">{option.title}</Form.Label>
27+
<Form.Label className="m-0">{t(option.title)}</Form.Label>
2628
</Col>
2729

2830
<Col
@@ -45,7 +47,7 @@ const QuadrantButtonsOption = (props) => {
4547
className="px-4"
4648
style={{ borderRadius: 0 }}
4749
>
48-
upper left
50+
{t("upper left")}
4951
</ToggleButton>
5052
<ToggleButton
5153
variant="light"
@@ -54,7 +56,7 @@ const QuadrantButtonsOption = (props) => {
5456
className="px-4"
5557
style={{ borderRadius: 0 }}
5658
>
57-
upper right
59+
{t("upper right")}
5860
</ToggleButton>
5961
<ToggleButton
6062
variant="light"
@@ -63,7 +65,7 @@ const QuadrantButtonsOption = (props) => {
6365
className="px-4"
6466
style={{ borderRadius: 0 }}
6567
>
66-
lower left
68+
{t("lower left")}
6769
</ToggleButton>
6870
<ToggleButton
6971
variant="light"
@@ -72,7 +74,7 @@ const QuadrantButtonsOption = (props) => {
7274
className="px-4"
7375
style={{ borderRadius: 0 }}
7476
>
75-
lower right
77+
{t("lower right")}
7678
</ToggleButton>
7779
</ToggleButtonGroup>
7880
</div>

src/components/SliderOption.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Slider from "rc-slider"
22
import React, { useState, useEffect } from "react"
3+
import { useTranslation } from "react-i18next"
34
import Col from "react-bootstrap/Col"
45
import Row from "react-bootstrap/Row"
56
import Form from "react-bootstrap/Form"
@@ -12,6 +13,7 @@ const SliderOption = ({
1213
model,
1314
label = true,
1415
}) => {
16+
const { t } = useTranslation()
1517
const [value, setValue] = useState(data[optionKey])
1618

1719
useEffect(() => {
@@ -114,7 +116,7 @@ const SliderOption = ({
114116
htmlFor={`option-${optionKey}`}
115117
className="mb-0"
116118
>
117-
{title}
119+
{t(title)}
118120
</Form.Label>
119121
)}
120122
</Col>

src/components/ToggleButtonOption.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
import React from "react"
2+
import { useTranslation } from "react-i18next"
23
import Col from "react-bootstrap/Col"
34
import Row from "react-bootstrap/Row"
45
import Form from "react-bootstrap/Form"
56
import ToggleButton from "react-bootstrap/ToggleButton"
67
import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup"
78

89
const ToggleButtonOption = (props) => {
10+
const { t } = useTranslation()
911
const option = props.options[props.optionKey]
1012
const { data } = props
1113
const model = props.model || data
@@ -27,7 +29,7 @@ const ToggleButtonOption = (props) => {
2729
return (
2830
<Row className={"align-items-center mb-1" + (visible ? "" : " d-none")}>
2931
<Col sm={5}>
30-
<Form.Label className="m-0">{option.title}</Form.Label>
32+
<Form.Label className="m-0">{t(option.title)}</Form.Label>
3133
</Col>
3234

3335
<Col sm={7}>
@@ -48,7 +50,7 @@ const ToggleButtonOption = (props) => {
4850
variant="light"
4951
value={choice}
5052
>
51-
{choice}
53+
{t(choice)}
5254
</ToggleButton>
5355
)
5456
})}

src/features/app/About.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from "react"
2+
import { useTranslation } from "react-i18next"
23
import Container from "react-bootstrap/Container"
34
import Row from "react-bootstrap/Row"
45
import Col from "react-bootstrap/Col"
@@ -9,6 +10,8 @@ import { SANDIFY_VERSION } from "@/features/app/appSlice"
910
import "./About.scss"
1011

1112
const About = () => {
13+
const { t } = useTranslation()
14+
1215
return (
1316
<footer className="p-4">
1417
<Container
@@ -27,9 +30,7 @@ const About = () => {
2730
>
2831
v{SANDIFY_VERSION}
2932
</div>
30-
<div className="tagline mb-2">
31-
create patterns for robots that draw in sand with ball bearings
32-
</div>
33+
<div className="tagline mb-2">{t("about.tagline")}</div>
3334
<p>
3435
Sandify turns your cold, empty-hearted, emotionless sand tables
3536
into cold, empty-hearted, emotionless sand table robots with

0 commit comments

Comments
 (0)