diff --git a/src/async-components/structures/CompatibilityView.tsx b/src/async-components/structures/CompatibilityView.tsx index c6aafe0f82..4b169f88a0 100644 --- a/src/async-components/structures/CompatibilityView.tsx +++ b/src/async-components/structures/CompatibilityView.tsx @@ -14,13 +14,14 @@ See the License for the specific language governing permissions and limitations under the License. */ -import * as React from "react"; -import { _t } from "matrix-react-sdk/src/languageHandler"; +import React, { ReactNode } from "react"; import SdkConfig from "matrix-react-sdk/src/SdkConfig"; + +import { _t } from "../../languageHandler"; + // directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk // PostCSS variables will be accessible. import "../../../res/css/structures/ErrorView.pcss"; -import { ReactNode } from "react"; interface IProps { onAccept(): void; @@ -112,15 +113,13 @@ const CompatibilityView: React.FC = ({ onAccept }) => {

{_t("Your browser can't run %(brand)s", { brand })}

{_t( - "%(brand)s uses advanced browser features which aren't " + - "supported by your current browser.", + "%(brand)s uses advanced browser features which aren't supported by your current browser.", { brand }, )}

{_t( - "Please install Chrome, Firefox, " + - "or Safari for the best experience.", + "Please install Chrome, Firefox, or Safari for the best experience.", {}, { chromeLink: (sub) => {sub}, @@ -131,8 +130,7 @@ const CompatibilityView: React.FC = ({ onAccept }) => {

{_t( - "You can continue using your current browser, but some or all features may not work " + - "and the look and feel of the application may be incorrect.", + "You can continue using your current browser, but some or all features may not work and the look and feel of the application may be incorrect.", )}

diff --git a/src/async-components/structures/ErrorView.tsx b/src/async-components/structures/ErrorView.tsx index b34226f3b4..0c87f7138e 100644 --- a/src/async-components/structures/ErrorView.tsx +++ b/src/async-components/structures/ErrorView.tsx @@ -15,7 +15,8 @@ limitations under the License. */ import * as React from "react"; -import { _t } from "matrix-react-sdk/src/languageHandler"; + +import { _t } from "../../languageHandler"; // directly import the style here as this layer does not support rethemedex at this time so no matrix-react-sdk // PostCSS variables will be accessible. diff --git a/src/components/views/auth/VectorAuthFooter.tsx b/src/components/views/auth/VectorAuthFooter.tsx index 0ef54ea80d..3e8b506907 100644 --- a/src/components/views/auth/VectorAuthFooter.tsx +++ b/src/components/views/auth/VectorAuthFooter.tsx @@ -17,7 +17,8 @@ limitations under the License. import React, { ReactElement } from "react"; import SdkConfig from "matrix-react-sdk/src/SdkConfig"; -import { _t } from "matrix-react-sdk/src/languageHandler"; + +import { _t } from "../../../languageHandler"; const VectorAuthFooter = (): ReactElement => { const brandingConfig = SdkConfig.getObject("branding"); diff --git a/src/languageHandler.tsx b/src/languageHandler.tsx new file mode 100644 index 0000000000..eb53caa12c --- /dev/null +++ b/src/languageHandler.tsx @@ -0,0 +1,66 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import React from "react"; +import { + IVariables, + TranslatedString, + TranslationKey as ReactTranslationKey, + // eslint-disable-next-line camelcase + _t as react_t, + // eslint-disable-next-line camelcase + _td as react_td, + // eslint-disable-next-line camelcase + _tDom as react_tDom, + Tags, + UserFriendlyError as ReactUserFriendlyError, + ErrorOptions, +} from "matrix-react-sdk/src/languageHandler"; +import { Leaves } from "matrix-react-sdk/src/@types/common"; + +import type ReactEN from "matrix-react-sdk/src/i18n/strings/en_EN.json"; +import type EN from "./i18n/strings/en_EN.json"; + +/** + * This module wraps languageHandler in the matrix-react-sdk and adds type casts to include translations + * which we know will be injected by webpack. + */ + +export type TranslationKey = Leaves; + +export class UserFriendlyError extends ReactUserFriendlyError { + public constructor(message: TranslationKey, substitutionVariablesAndCause?: IVariables & ErrorOptions) { + super(message as ReactTranslationKey, substitutionVariablesAndCause); + } +} + +export function _td(s: TranslationKey): TranslationKey { + return react_td(s as ReactTranslationKey); +} + +// eslint-next-line @typescript-eslint/naming-convention +export function _t(text: TranslationKey, variables?: IVariables): string; +export function _t(text: TranslationKey, variables: IVariables | undefined, tags: Tags): React.ReactNode; +export function _t(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { + return react_t(text as ReactTranslationKey, variables, tags!); +} + +// eslint-next-line @typescript-eslint/naming-convention +export function _tDom(text: TranslationKey, variables?: IVariables): TranslatedString; +export function _tDom(text: TranslationKey, variables: IVariables, tags: Tags): React.ReactNode; +export function _tDom(text: TranslationKey, variables?: IVariables, tags?: Tags): TranslatedString { + return react_tDom(text as ReactTranslationKey, variables!, tags!); +} diff --git a/src/vector/app.tsx b/src/vector/app.tsx index 2e389983ea..dd69320faf 100644 --- a/src/vector/app.tsx +++ b/src/vector/app.tsx @@ -23,7 +23,6 @@ import "matrix-js-sdk/src/browser-index"; import React, { ReactElement } from "react"; import PlatformPeg from "matrix-react-sdk/src/PlatformPeg"; -import { UserFriendlyError } from "matrix-react-sdk/src/languageHandler"; import AutoDiscoveryUtils from "matrix-react-sdk/src/utils/AutoDiscoveryUtils"; import { AutoDiscovery, ClientConfig } from "matrix-js-sdk/src/autodiscovery"; import * as Lifecycle from "matrix-react-sdk/src/Lifecycle"; @@ -38,6 +37,7 @@ import { ValidatedServerConfig } from "matrix-react-sdk/src/utils/ValidatedServe import { parseQs } from "./url_utils"; import VectorBasePlatform from "./platform/VectorBasePlatform"; import { getInitialScreenAfterLogin, getScreenFromLocation, init as initRouting, onNewScreen } from "./routing"; +import { UserFriendlyError } from "../languageHandler"; // add React and ReactPerf to the global namespace, to make them easier to access via the console // this incidentally means we can forget our React imports in JSX files without penalty. @@ -147,8 +147,7 @@ async function verifyServerConfig(): Promise { if (hsUrl && (wkConfig || serverName)) { // noinspection ExceptionCaughtLocallyJS throw new UserFriendlyError( - "Invalid configuration: a default_hs_url can't be specified along with default_server_name " + - "or default_server_config", + "Invalid configuration: a default_hs_url can't be specified along with default_server_name or default_server_config", ); } if (incompatibleOptions.length < 1) { diff --git a/src/vector/index.ts b/src/vector/index.ts index d0a3a6e3ae..b7dc6312f0 100644 --- a/src/vector/index.ts +++ b/src/vector/index.ts @@ -199,8 +199,7 @@ async function start(): Promise { // This uses the default brand since the app config is unavailable. return showError(_t("Your Element is misconfigured"), [ _t( - "Your Element configuration contains invalid JSON. " + - "Please correct the problem and reload the page.", + "Your Element configuration contains invalid JSON. Please correct the problem and reload the page.", ), _t("The message from the parser is: %(message)s", { message: error.message || _t("Invalid JSON"), diff --git a/src/vector/init.tsx b/src/vector/init.tsx index 70518a7700..64cee8df79 100644 --- a/src/vector/init.tsx +++ b/src/vector/init.tsx @@ -184,4 +184,4 @@ export async function loadModules(): Promise { } } -export const _t = languageHandler._t; +export { _t } from "../languageHandler"; diff --git a/src/vector/platform/ElectronPlatform.tsx b/src/vector/platform/ElectronPlatform.tsx index 05c2564395..a3f4a3f6e8 100644 --- a/src/vector/platform/ElectronPlatform.tsx +++ b/src/vector/platform/ElectronPlatform.tsx @@ -21,7 +21,6 @@ limitations under the License. import { UpdateCheckStatus, UpdateStatus } from "matrix-react-sdk/src/BasePlatform"; import BaseEventIndexManager from "matrix-react-sdk/src/indexing/BaseEventIndexManager"; import dis from "matrix-react-sdk/src/dispatcher/dispatcher"; -import { _t } from "matrix-react-sdk/src/languageHandler"; import SdkConfig from "matrix-react-sdk/src/SdkConfig"; import { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions"; import * as rageshake from "matrix-react-sdk/src/rageshake/rageshake"; @@ -48,6 +47,7 @@ import DesktopCapturerSourcePicker from "matrix-react-sdk/src/components/views/e import VectorBasePlatform from "./VectorBasePlatform"; import { SeshatIndexManager } from "./SeshatIndexManager"; import { IPCManager } from "./IPCManager"; +import { _t } from "../../languageHandler"; interface SquirrelUpdate { releaseNotes: string; diff --git a/src/vector/platform/VectorBasePlatform.ts b/src/vector/platform/VectorBasePlatform.ts index 4f67b1e332..949566992c 100644 --- a/src/vector/platform/VectorBasePlatform.ts +++ b/src/vector/platform/VectorBasePlatform.ts @@ -18,11 +18,11 @@ limitations under the License. */ import BasePlatform from "matrix-react-sdk/src/BasePlatform"; -import { _t } from "matrix-react-sdk/src/languageHandler"; import type { IConfigOptions } from "matrix-react-sdk/src/IConfigOptions"; import { getVectorConfig } from "../getconfig"; import Favicon from "../../favicon"; +import { _t } from "../../languageHandler"; /** * Vector-specific extensions to the BasePlatform template diff --git a/src/vector/platform/WebPlatform.ts b/src/vector/platform/WebPlatform.ts index 719ea9c4b2..84da0f92fc 100644 --- a/src/vector/platform/WebPlatform.ts +++ b/src/vector/platform/WebPlatform.ts @@ -18,7 +18,6 @@ limitations under the License. import { UpdateCheckStatus, UpdateStatus } from "matrix-react-sdk/src/BasePlatform"; import dis from "matrix-react-sdk/src/dispatcher/dispatcher"; -import { _t } from "matrix-react-sdk/src/languageHandler"; import { hideToast as hideUpdateToast, showToast as showUpdateToast } from "matrix-react-sdk/src/toasts/UpdateToast"; import { Action } from "matrix-react-sdk/src/dispatcher/actions"; import { CheckUpdatesPayload } from "matrix-react-sdk/src/dispatcher/payloads/CheckUpdatesPayload"; @@ -27,6 +26,7 @@ import { logger } from "matrix-js-sdk/src/logger"; import VectorBasePlatform from "./VectorBasePlatform"; import { parseQs } from "../url_utils"; +import { _t } from "../../languageHandler"; const POKE_RATE_MS = 10 * 60 * 1000; // 10 min