From ce595ff18c84f95014551cdf0df792ffffbd41f0 Mon Sep 17 00:00:00 2001 From: "Daniel J. Geiger" <1852529+DanielJGeiger@users.noreply.github.com> Date: Sat, 2 Dec 2023 19:07:48 -0600 Subject: [PATCH] chore: Clean up `src/i18n.ts` changes --- src/element/subtypes/index.ts | 9 ++-- .../subtypes/mathjax/implementation.tsx | 19 +++----- src/i18n.ts | 46 +++++++------------ src/tests/subtypes.test.tsx | 21 +++------ 4 files changed, 31 insertions(+), 64 deletions(-) diff --git a/src/element/subtypes/index.ts b/src/element/subtypes/index.ts index 73cb0e130..e8f4a0130 100644 --- a/src/element/subtypes/index.ts +++ b/src/element/subtypes/index.ts @@ -3,7 +3,7 @@ import { ExcalidrawElement, ExcalidrawTextElement, NonDeleted } from "../types"; import { getNonDeletedElements } from "../"; import { getSelectedElements } from "../../scene"; import { AppState, ExcalidrawImperativeAPI, ToolType } from "../../types"; -import { registerAuxLangData } from "../../i18n"; +import { LangLdr, registerCustomLangData } from "../../i18n"; import { Action, @@ -331,10 +331,7 @@ export type SubtypeCheckFn = (element: ExcalidrawElement) => boolean; // Functions to prepare subtypes for use export type SubtypePrepFn = ( addSubtypeAction: (action: Action) => void, - addLangData: ( - fallbackLangData: Object, - setLanguageAux: (langCode: string) => Promise, - ) => void, + addLangData: (fallbackLangData: {}, setLanguageAux: LangLdr) => void, onSubtypeLoaded?: SubtypeLoadedCb, ) => { actions: Action[]; @@ -411,7 +408,7 @@ export const prepareSubtype = ( // Prepare the subtype const { actions, methods } = subtypePrepFn( addSubtypeAction, - registerAuxLangData, + registerCustomLangData, onSubtypeLoaded, ); diff --git a/src/element/subtypes/mathjax/implementation.tsx b/src/element/subtypes/mathjax/implementation.tsx index 429bd9226..24d7f8a6a 100644 --- a/src/element/subtypes/mathjax/implementation.tsx +++ b/src/element/subtypes/mathjax/implementation.tsx @@ -25,7 +25,7 @@ import { getElementAbsoluteCoords } from "../../../element/bounds"; import Scene from "../../../scene/Scene"; // Imports for actions -import { t, registerAuxLangData } from "../../../i18n"; +import { LangLdr, registerCustomLangData, t } from "../../../i18n"; import { Action, makeCustomActionName } from "../../../actions/types"; import { AppState } from "../../../types"; import { @@ -1611,19 +1611,12 @@ export const prepareMathSubtype = function ( methods.render = renderMathElement; methods.renderSvg = renderSvgMathElement; methods.wrapText = wrapMathElement; - const getLangData = async (langCode: string): Promise => { - try { - const condData = await import( - /* webpackChunkName: "locales/[request]" */ `./locales/${langCode}.json` - ); - if (condData) { - return condData; - } - } catch (e) {} - return undefined; - }; + const getLangData: LangLdr = (langCode) => + import( + /* webpackChunkName: "locales/[request]" */ `./locales/${langCode}.json` + ); addLangData(fallbackMathJaxLangData, getLangData); - registerAuxLangData(fallbackMathJaxLangData, getLangData); + registerCustomLangData(fallbackMathJaxLangData, getLangData); const actions = createMathActions(); actions.forEach((action) => addSubtypeAction(action)); diff --git a/src/i18n.ts b/src/i18n.ts index ab97f9613..82922b1ef 100644 --- a/src/i18n.ts +++ b/src/i18n.ts @@ -87,20 +87,15 @@ if (import.meta.env.DEV) { let currentLang: Language = defaultLang; let currentLangData = {}; -const auxCurrentLangData = Array(); -const auxFallbackLangData = Array(); -const auxSetLanguageFuncs = - Array<(langCode: string) => Promise>(); +let fallbackCustomLangData = {}; +const langLoaders: LangLdr[] = []; +export type LangLdr = (langCode: string) => Promise<{}>; -export const registerAuxLangData = ( - fallbackLangData: Object, - setLanguageAux: (langCode: string) => Promise, -) => { - if (auxFallbackLangData.includes(fallbackLangData)) { - return; +export const registerCustomLangData = (fallbackLangData: {}, ldr: LangLdr) => { + if (!langLoaders.includes(ldr)) { + fallbackCustomLangData = { ...fallbackLangData, ...fallbackCustomLangData }; + langLoaders.push(ldr); } - auxFallbackLangData.push(fallbackLangData); - auxSetLanguageFuncs.push(setLanguageAux); }; export const setLanguage = async (lang: Language) => { @@ -115,21 +110,18 @@ export const setLanguage = async (lang: Language) => { currentLangData = await import( /* webpackChunkName: "locales/[request]" */ `./locales/${currentLang.code}.json` ); - // Empty the auxCurrentLangData array - while (auxCurrentLangData.length > 0) { - auxCurrentLangData.pop(); - } - // Fill the auxCurrentLangData array with each locale file found in auxLangDataRoots for this language - auxSetLanguageFuncs.forEach(async (setLanguageFn) => { - const condData = await setLanguageFn(currentLang.code); - if (condData) { - auxCurrentLangData.push(condData); - } - }); } catch (error: any) { console.error(`Failed to load language ${lang.code}:`, error.message); currentLangData = fallbackLangData; } + const auxData = langLoaders.map((fn) => fn(currentLang.code)); + while (auxData.length > 0) { + try { + currentLangData = { ...(await auxData.pop()), ...currentLangData }; + } catch (error: any) { + console.error(`Error loading ${lang.code} extra data:`, error.message); + } + } } jotaiStore.set(editorLangCodeAtom, lang.code); @@ -169,14 +161,8 @@ export const t = ( let translation = findPartsForData(currentLangData, parts) || findPartsForData(fallbackLangData, parts) || + findPartsForData(fallbackCustomLangData, parts) || fallback; - const auxData = Array().concat( - auxCurrentLangData, - auxFallbackLangData, - ); - for (let i = 0; i < auxData.length; i++) { - translation = translation || findPartsForData(auxData[i], parts); - } if (translation === undefined) { const errorMessage = `Can't find translation for ${path}`; // in production, don't blow up the app on a missing translation key diff --git a/src/tests/subtypes.test.tsx b/src/tests/subtypes.test.tsx index b16d5eaa3..68cdb7cb1 100644 --- a/src/tests/subtypes.test.tsx +++ b/src/tests/subtypes.test.tsx @@ -27,7 +27,7 @@ import { } from "../element/types"; import { createIcon, iconFillColor } from "../components/icons"; import { SubtypeButton } from "../components/Subtypes"; -import { registerAuxLangData } from "../i18n"; +import { LangLdr, registerCustomLangData } from "../i18n"; import { getFontString, getShortcutKey } from "../utils"; import * as textElementUtils from "../element/textElement"; import { isTextElement } from "../element"; @@ -46,17 +46,8 @@ const FONTSIZE = 20; const DBFONTSIZE = 40; const TRFONTSIZE = 60; -const getLangData = async (langCode: string): Promise => { - try { - const condData = await import( - /* webpackChunkName: "locales/[request]" */ `./helpers/locales/${langCode}.json` - ); - if (condData) { - return condData; - } - } catch (e) {} - return undefined; -}; +const getLangData: LangLdr = (langCode) => + import(`./helpers/locales/${langCode}.json`); const testSubtypeIcon = ({ theme }: { theme: Theme }) => createIcon( @@ -155,7 +146,7 @@ const prepareTest1Subtype = function ( methods.clean = cleanTestElementUpdate; addLangData(fallbackLangData, getLangData); - registerAuxLangData(fallbackLangData, getLangData); + registerCustomLangData(fallbackLangData, getLangData); const actions = [testAction, test1Button]; actions.forEach((action) => addSubtypeAction(action)); @@ -223,7 +214,7 @@ const prepareTest2Subtype = function ( } as SubtypeMethods; addLangData(fallbackLangData, getLangData); - registerAuxLangData(fallbackLangData, getLangData); + registerCustomLangData(fallbackLangData, getLangData); const actions = [test2Button]; actions.forEach((action) => addSubtypeAction(action)); @@ -241,7 +232,7 @@ const prepareTest3Subtype = function ( const methods = {} as SubtypeMethods; addLangData(fallbackLangData, getLangData); - registerAuxLangData(fallbackLangData, getLangData); + registerCustomLangData(fallbackLangData, getLangData); const actions = [test3Button]; actions.forEach((action) => addSubtypeAction(action));