mirror of
https://github.com/excalidraw/excalidraw.git
synced 2025-05-03 10:00:07 -04:00
Replace i18n by a custom implementation (#638)
There are two problems with the current localization strategy: - We download the translations on-demand, which means that it does a serial roundtrip for nothing. - withTranslation helper actually renders the app 3 times on startup, instead of once (I haven't tried to debug it)
This commit is contained in:
parent
637276301a
commit
e4919e2e6c
21 changed files with 101 additions and 167 deletions
|
@ -4,13 +4,14 @@ import { ColorPicker } from "../components/ColorPicker";
|
|||
import { getDefaultAppState } from "../appState";
|
||||
import { trash } from "../components/icons";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
import { t } from "../i18n";
|
||||
|
||||
export const actionChangeViewBackgroundColor: Action = {
|
||||
name: "changeViewBackgroundColor",
|
||||
perform: (elements, appState, value) => {
|
||||
return { appState: { ...appState, viewBackgroundColor: value } };
|
||||
},
|
||||
PanelComponent: ({ appState, updateData, t }) => {
|
||||
PanelComponent: ({ appState, updateData }) => {
|
||||
return (
|
||||
<div style={{ position: "relative" }}>
|
||||
<ColorPicker
|
||||
|
@ -32,7 +33,7 @@ export const actionClearCanvas: Action = {
|
|||
appState: getDefaultAppState(),
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ updateData, t }) => (
|
||||
PanelComponent: ({ updateData }) => (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={trash}
|
||||
|
|
|
@ -4,13 +4,14 @@ import { ProjectName } from "../components/ProjectName";
|
|||
import { saveAsJSON, loadFromJSON } from "../scene";
|
||||
import { load, save } from "../components/icons";
|
||||
import { ToolButton } from "../components/ToolButton";
|
||||
import { t } from "../i18n";
|
||||
|
||||
export const actionChangeProjectName: Action = {
|
||||
name: "changeProjectName",
|
||||
perform: (elements, appState, value) => {
|
||||
return { appState: { ...appState, name: value } };
|
||||
},
|
||||
PanelComponent: ({ appState, updateData, t }) => (
|
||||
PanelComponent: ({ appState, updateData }) => (
|
||||
<ProjectName
|
||||
label={t("labels.fileTitle")}
|
||||
value={appState.name || "Unnamed"}
|
||||
|
@ -24,7 +25,7 @@ export const actionChangeExportBackground: Action = {
|
|||
perform: (elements, appState, value) => {
|
||||
return { appState: { ...appState, exportBackground: value } };
|
||||
},
|
||||
PanelComponent: ({ appState, updateData, t }) => (
|
||||
PanelComponent: ({ appState, updateData }) => (
|
||||
<label>
|
||||
<input
|
||||
type="checkbox"
|
||||
|
@ -44,7 +45,7 @@ export const actionSaveScene: Action = {
|
|||
saveAsJSON(elements, appState).catch(err => console.error(err));
|
||||
return {};
|
||||
},
|
||||
PanelComponent: ({ updateData, t }) => (
|
||||
PanelComponent: ({ updateData }) => (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={save}
|
||||
|
@ -64,7 +65,7 @@ export const actionLoadScene: Action = {
|
|||
) => {
|
||||
return { elements: loadedElements, appState: loadedAppState };
|
||||
},
|
||||
PanelComponent: ({ updateData, t }) => (
|
||||
PanelComponent: ({ updateData }) => (
|
||||
<ToolButton
|
||||
type="button"
|
||||
icon={load}
|
||||
|
|
|
@ -6,6 +6,7 @@ import { ButtonSelect } from "../components/ButtonSelect";
|
|||
import { isTextElement, redrawTextBoundingBox } from "../element";
|
||||
import { ColorPicker } from "../components/ColorPicker";
|
||||
import { AppState } from "../../src/types";
|
||||
import { t } from "../i18n";
|
||||
|
||||
const changeProperty = (
|
||||
elements: readonly ExcalidrawElement[],
|
||||
|
@ -46,7 +47,7 @@ export const actionChangeStrokeColor: Action = {
|
|||
appState: { ...appState, currentItemStrokeColor: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<>
|
||||
<h3 aria-hidden="true">{t("labels.stroke")}</h3>
|
||||
<ColorPicker
|
||||
|
@ -76,7 +77,7 @@ export const actionChangeBackgroundColor: Action = {
|
|||
appState: { ...appState, currentItemBackgroundColor: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<>
|
||||
<h3 aria-hidden="true">{t("labels.background")}</h3>
|
||||
<ColorPicker
|
||||
|
@ -106,7 +107,7 @@ export const actionChangeFillStyle: Action = {
|
|||
appState: { ...appState, currentItemFillStyle: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fill")}</legend>
|
||||
<ButtonSelect
|
||||
|
@ -142,7 +143,7 @@ export const actionChangeStrokeWidth: Action = {
|
|||
appState: { ...appState, currentItemStrokeWidth: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.strokeWidth")}</legend>
|
||||
<ButtonSelect
|
||||
|
@ -176,7 +177,7 @@ export const actionChangeSloppiness: Action = {
|
|||
appState: { ...appState, currentItemRoughness: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.sloppiness")}</legend>
|
||||
<ButtonSelect
|
||||
|
@ -210,7 +211,7 @@ export const actionChangeOpacity: Action = {
|
|||
appState: { ...appState, currentItemOpacity: value },
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<label className="control-label">
|
||||
{t("labels.opacity")}
|
||||
<input
|
||||
|
@ -256,7 +257,7 @@ export const actionChangeFontSize: Action = {
|
|||
},
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fontSize")}</legend>
|
||||
<ButtonSelect
|
||||
|
@ -304,7 +305,7 @@ export const actionChangeFontFamily: Action = {
|
|||
},
|
||||
};
|
||||
},
|
||||
PanelComponent: ({ elements, appState, updateData, t }) => (
|
||||
PanelComponent: ({ elements, appState, updateData }) => (
|
||||
<fieldset>
|
||||
<legend>{t("labels.fontFamily")}</legend>
|
||||
<ButtonSelect
|
||||
|
|
|
@ -7,7 +7,7 @@ import {
|
|||
} from "./types";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { AppState } from "../types";
|
||||
import { TFunction } from "i18next";
|
||||
import { t } from "../i18n";
|
||||
|
||||
export class ActionManager implements ActionsManagerInterface {
|
||||
actions: { [keyProp: string]: Action } = {};
|
||||
|
@ -48,7 +48,6 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
appState: AppState,
|
||||
updater: UpdaterFn,
|
||||
actionFilter: ActionFilterFn = action => action,
|
||||
t?: TFunction,
|
||||
) {
|
||||
return Object.values(this.actions)
|
||||
.filter(actionFilter)
|
||||
|
@ -59,10 +58,7 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
(b.contextMenuOrder !== undefined ? b.contextMenuOrder : 999),
|
||||
)
|
||||
.map(action => ({
|
||||
label:
|
||||
t && action.contextItemLabel
|
||||
? t(action.contextItemLabel)
|
||||
: action.contextItemLabel!,
|
||||
label: action.contextItemLabel ? t(action.contextItemLabel) : "",
|
||||
action: () => {
|
||||
updater(action.perform(elements, appState, null));
|
||||
},
|
||||
|
@ -74,7 +70,6 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
updater: UpdaterFn,
|
||||
t: TFunction,
|
||||
) {
|
||||
if (this.actions[name] && "PanelComponent" in this.actions[name]) {
|
||||
const action = this.actions[name];
|
||||
|
@ -88,7 +83,6 @@ export class ActionManager implements ActionsManagerInterface {
|
|||
elements={elements}
|
||||
appState={appState}
|
||||
updateData={updateData}
|
||||
t={t}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
import React from "react";
|
||||
import { ExcalidrawElement } from "../element/types";
|
||||
import { AppState } from "../types";
|
||||
import { TFunction } from "i18next";
|
||||
|
||||
export type ActionResult = {
|
||||
elements?: ExcalidrawElement[];
|
||||
|
@ -23,7 +22,6 @@ export interface Action {
|
|||
elements: readonly ExcalidrawElement[];
|
||||
appState: AppState;
|
||||
updateData: (formData: any) => void;
|
||||
t: TFunction;
|
||||
}>;
|
||||
perform: ActionFn;
|
||||
keyPriority?: number;
|
||||
|
@ -57,6 +55,5 @@ export interface ActionsManagerInterface {
|
|||
elements: readonly ExcalidrawElement[],
|
||||
appState: AppState,
|
||||
updater: UpdaterFn,
|
||||
t: TFunction,
|
||||
) => React.ReactElement | null;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue