Internationalization support (#477)

* add i18next lib
add some translations

* add translations

* fix font-family

* fix pin versions
This commit is contained in:
Fernando Alava Zambrano 2020-01-21 01:14:10 +02:00 committed by Christopher Chedeau
parent 1a03a29025
commit ff7a340d2f
15 changed files with 286 additions and 162 deletions

View file

@ -77,6 +77,8 @@ import Stack from "./components/Stack";
import { FixedSideContainer } from "./components/FixedSideContainer";
import { ToolIcon } from "./components/ToolIcon";
import { ExportDialog } from "./components/ExportDialog";
import { withTranslation } from "react-i18next";
import "./i18n";
let { elements } = createScene();
const { history } = createHistory();
@ -129,7 +131,7 @@ export function viewportCoordsToSceneCoords(
return { x, y };
}
export class App extends React.Component<{}, AppState> {
export class App extends React.Component<any, AppState> {
canvas: HTMLCanvasElement | null = null;
rc: RoughCanvas | null = null;
@ -359,6 +361,7 @@ export class App extends React.Component<{}, AppState> {
};
private renderSelectedShapeActions(elements: readonly ExcalidrawElement[]) {
const { t } = this.props;
const { elementType, editingElement } = this.state;
const selectedElements = elements.filter(el => el.isSelected);
const hasSelectedElements = selectedElements.length > 0;
@ -381,7 +384,8 @@ export class App extends React.Component<{}, AppState> {
"changeStrokeColor",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{(hasBackground(elements) ||
@ -391,14 +395,16 @@ export class App extends React.Component<{}, AppState> {
"changeBackgroundColor",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{this.actionManager.renderAction(
"changeFillStyle",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
<hr />
</>
@ -411,14 +417,16 @@ export class App extends React.Component<{}, AppState> {
"changeStrokeWidth",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{this.actionManager.renderAction(
"changeSloppiness",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
<hr />
</>
@ -430,14 +438,16 @@ export class App extends React.Component<{}, AppState> {
"changeFontSize",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{this.actionManager.renderAction(
"changeFontFamily",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
<hr />
</>
@ -447,14 +457,16 @@ export class App extends React.Component<{}, AppState> {
"changeOpacity",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{this.actionManager.renderAction(
"deleteSelectedElements",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
</div>
</Island>
@ -462,32 +474,38 @@ export class App extends React.Component<{}, AppState> {
}
private renderShapesSwitcher() {
const { t } = this.props;
return (
<>
{SHAPES.map(({ value, icon }, index) => (
<ToolIcon
key={value}
type="radio"
icon={icon}
checked={this.state.elementType === value}
name="editor-current-shape"
title={`${capitalizeString(value)}${
capitalizeString(value)[0]
}, ${index + 1}`}
onChange={() => {
this.setState({ elementType: value });
elements = clearSelection(elements);
document.documentElement.style.cursor =
value === "text" ? "text" : "crosshair";
this.forceUpdate();
}}
></ToolIcon>
))}
{SHAPES.map(({ value, icon }, index) => {
const label = t(`toolBar.${value}`);
return (
<ToolIcon
key={value}
type="radio"
icon={icon}
checked={this.state.elementType === value}
name="editor-current-shape"
title={`${capitalizeString(label)}${
capitalizeString(label)[0]
}, ${index + 1}`}
onChange={() => {
this.setState({ elementType: value });
elements = clearSelection(elements);
document.documentElement.style.cursor =
value === "text" ? "text" : "crosshair";
this.forceUpdate();
}}
></ToolIcon>
);
})}
</>
);
}
private renderCanvasActions() {
const { t } = this.props;
return (
<Stack.Col gap={4}>
<Stack.Row justifyContent={"space-between"}>
@ -495,13 +513,15 @@ export class App extends React.Component<{}, AppState> {
"loadScene",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
{this.actionManager.renderAction(
"saveScene",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
<ExportDialog
elements={elements}
@ -540,14 +560,16 @@ export class App extends React.Component<{}, AppState> {
"clearCanvas",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
</Stack.Row>
{this.actionManager.renderAction(
"changeViewBackgroundColor",
elements,
this.state,
this.syncActionResult
this.syncActionResult,
t
)}
</Stack.Col>
);
@ -556,6 +578,7 @@ export class App extends React.Component<{}, AppState> {
public render() {
const canvasWidth = window.innerWidth - CANVAS_WINDOW_OFFSET_LEFT;
const canvasHeight = window.innerHeight - CANVAS_WINDOW_OFFSET_TOP;
const { t } = this.props;
return (
<div className="container">
@ -624,14 +647,15 @@ export class App extends React.Component<{}, AppState> {
ContextMenu.push({
options: [
navigator.clipboard && {
label: "Paste",
label: t("labels.paste"),
action: () => this.pasteFromClipboard()
},
...this.actionManager.getContextMenuItems(
elements,
this.state,
this.syncActionResult,
action => this.canvasOnlyActions.includes(action)
action => this.canvasOnlyActions.includes(action),
t
)
],
top: e.clientY,
@ -649,18 +673,19 @@ export class App extends React.Component<{}, AppState> {
ContextMenu.push({
options: [
navigator.clipboard && {
label: "Copy",
label: t("labels.copy"),
action: this.copyToClipboard
},
navigator.clipboard && {
label: "Paste",
label: t("labels.paste"),
action: () => this.pasteFromClipboard()
},
...this.actionManager.getContextMenuItems(
elements,
this.state,
this.syncActionResult,
action => !this.canvasOnlyActions.includes(action)
action => !this.canvasOnlyActions.includes(action),
t
)
],
top: e.clientY,
@ -1333,5 +1358,7 @@ export class App extends React.Component<{}, AppState> {
}
}
const AppWithTrans = withTranslation()(App);
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
ReactDOM.render(<AppWithTrans />, rootElement);