Compare commits

..

21 Commits

Author SHA1 Message Date
Michael Telatynski
e5e914dd72 Update .editorconfig 2023-08-22 16:54:50 +01:00
Michael Telatynski
469d11ffcb Guard translation methods with typescript to protect against invalid usage (#26021) 2023-08-22 16:32:03 +01:00
Michael Telatynski
86c563cd29 Simplify languages.json file and grab language names from Intl (#26001) 2023-08-22 15:07:17 +01:00
Element Translate Bot
c13816dce4 Translated using Weblate (Georgian) (#26029)
Currently translated at 100.0% (30 of 30 strings)

Translation: Element Web/element-web
Translate-URL: https://translate.element.io/projects/element-web/element-web/ka/

Co-authored-by: Nicholas Winterhalter <gewinum@gmail.com>
Co-authored-by: Weblate <translate@riot.im>
2023-08-22 13:13:19 +00:00
Michael Telatynski
7f3d85c0c5 Remove Exploring public spaces from labs.md (#25991) 2023-08-21 10:39:16 +01:00
Dominik Henneke
65f7545ba5 Bump @matrix-org/react-sdk-module-api from 1.0.0 to 2.0.0 (#25986) 2023-08-18 12:03:28 +00:00
Germain
c026879237 Fix path separator for Windows based systems (#25997) 2023-08-18 11:56:07 +01:00
Germain
d9b4e531b0 Allow external assets loading (#25998) 2023-08-18 09:45:32 +01:00
Michael Telatynski
062e93a5d2 Tidy and improve dev scripts (#25978) 2023-08-18 08:34:56 +01:00
Michael Telatynski
96c652ef08 Switch to nested object pluralisation format for i18n files (#25970) 2023-08-17 09:37:59 +01:00
Michael Telatynski
017fbb3793 Remove redundant makeRegistrationUrl prop (#25953) 2023-08-15 16:18:55 +01:00
ElementRobot
6bce017823 Reset matrix-js-sdk back to develop branch 2023-08-15 13:38:45 +01:00
ElementRobot
f9b7372883 Reset matrix-react-sdk back to develop branch 2023-08-15 13:38:23 +01:00
ElementRobot
6755448e86 Merge branch 'master' into develop
# Conflicts:
#	yarn.lock
2023-08-15 13:37:44 +01:00
renovate[bot]
fb984abf12 Update all non-major dependencies (#25938)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-14 09:16:12 +01:00
Michael Telatynski
7351c722be Fix tests for Matrix v1.1 requirement (#25898) 2023-08-14 09:07:43 +01:00
Michael Telatynski
d1f7b0898a Update setupFilesAfterEnv to TS (#25928) 2023-08-09 09:39:45 +01:00
renovate[bot]
a61ab7c033 Lock file maintenance (#25940)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 15:18:01 +00:00
renovate[bot]
424cbdd47b Update dependency eslint-config-prettier to v9 (#25939)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 14:42:50 +00:00
renovate[bot]
f58b122850 Update babel monorepo to v7.22.10 (#25937)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 14:32:54 +00:00
renovate[bot]
e3bc5f45f5 Update tibdex/backport digest to 9565281 (#25936)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2023-08-08 14:17:41 +00:00
26 changed files with 681 additions and 519 deletions

View File

@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
root = true
[*]

View File

@@ -23,7 +23,7 @@ jobs:
)
)
steps:
- uses: tibdex/backport@2e217641d82d02ba0603f46b1aeedefb258890ac # v2
- uses: tibdex/backport@9565281eda0731b1d20c4025c43339fb0a23812e # v2
with:
labels_template: "<%= JSON.stringify([...labels, 'X-Release-Blocker']) %>"
# We can't use GITHUB_TOKEN here or CI won't run on the new PR

View File

@@ -124,11 +124,6 @@ If you're enabling this at the deployment level, you may also want to reference
Enables rendering of MD / HTML in room topics.
## Exploring public spaces (`feature_exploring_public_spaces`)
Enables exploring public spaces in the new search dialog. Requires the server to
have [MSC3827](https://github.com/matrix-org/matrix-spec-proposals/pull/3827) enabled.
## Use the Rust cryptography implementation (`feature_rust_crypto`) [In Development]
Configures Element to use a new cryptography implementation based on the [matrix-rust-sdk](https://github.com/matrix-org/matrix-rust-sdk).

View File

@@ -25,7 +25,7 @@ const config: Config = {
},
testMatch: ["<rootDir>/test/**/*-test.[tj]s?(x)"],
setupFiles: ["jest-canvas-mock"],
setupFilesAfterEnv: ["<rootDir>/node_modules/matrix-react-sdk/test/setupTests.js"],
setupFilesAfterEnv: ["<rootDir>/node_modules/matrix-react-sdk/test/setupTests.ts"],
moduleNameMapper: {
"\\.(css|scss|pcss)$": "<rootDir>/__mocks__/cssMock.js",
"\\.(gif|png|ttf|woff2)$": "<rootDir>/node_modules/matrix-react-sdk/__mocks__/imageMock.js",

View File

@@ -185,9 +185,20 @@ function getModuleApiVersionFor(moduleName: string): string {
return findDepVersionInPackageJson(moduleApiDepName, pkgJsonStr);
}
// A list of Module API versions that are supported in addition to the currently installed one
// defined in the package.json. This is necessary because semantic versioning is applied to both
// the Module-side surface of the API and the Client-side surface of the API. So breaking changes
// in the Client-side surface lead to a major bump even though the Module-side surface stays
// compatible. We aim to not break the Module-side surface so we maintain a list of compatible
// older versions.
const backwardsCompatibleMajorVersions = ["1.0.0"];
function isModuleVersionCompatible(ourApiVersion: string, moduleApiVersion: string): boolean {
if (!moduleApiVersion) return false;
return semver.satisfies(ourApiVersion, moduleApiVersion);
return (
semver.satisfies(ourApiVersion, moduleApiVersion) ||
backwardsCompatibleMajorVersions.some((version) => semver.satisfies(version, moduleApiVersion))
);
}
function writeModulesTs(content: string): void {

View File

@@ -36,7 +36,7 @@
"clean": "rimraf lib webapp",
"build": "yarn clean && yarn build:genfiles && yarn build:bundle",
"build-stats": "yarn clean && yarn build:genfiles && yarn build:bundle-stats",
"build:jitsi": "node scripts/build-jitsi.js",
"build:jitsi": "ts-node scripts/build-jitsi.ts",
"build:res": "node scripts/copy-res.js",
"build:genfiles": "yarn build:res && yarn build:jitsi && yarn build:module_system",
"build:modernizr": "modernizr -c .modernizr.json -d src/vector/modernizr.js",
@@ -61,7 +61,7 @@
"lint:style": "stylelint \"res/css/**/*.pcss\"",
"test": "jest",
"coverage": "yarn test --coverage",
"analyse:unused-exports": "node ./scripts/analyse_unused_exports.js",
"analyse:unused-exports": "ts-node ./scripts/analyse_unused_exports.ts",
"analyse:webpack-bundles": "webpack-bundle-analyzer webpack-stats.json webapp"
},
"resolutions": {
@@ -70,12 +70,12 @@
},
"dependencies": {
"@matrix-org/olm": "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.14.tgz",
"@matrix-org/react-sdk-module-api": "^1.0.0",
"@matrix-org/react-sdk-module-api": "^2.0.0",
"gfm.css": "^1.1.2",
"jsrsasign": "^10.5.25",
"katex": "^0.16.0",
"matrix-js-sdk": "27.2.0",
"matrix-react-sdk": "3.78.0",
"matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop",
"matrix-react-sdk": "github:matrix-org/matrix-react-sdk#develop",
"matrix-widget-api": "^1.3.1",
"react": "17.0.2",
"react-dom": "17.0.2",
@@ -109,6 +109,7 @@
"@types/jsrsasign": "^10.5.4",
"@types/modernizr": "^3.5.3",
"@types/node": "^16",
"@types/node-fetch": "^2.6.4",
"@types/react": "17.0.58",
"@types/react-dom": "17.0.19",
"@types/ua-parser-js": "^0.7.36",
@@ -124,7 +125,7 @@
"dotenv": "^16.0.2",
"eslint": "8.45.0",
"eslint-config-google": "^0.14.0",
"eslint-config-prettier": "^8.5.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-deprecate": "^0.7.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-matrix-org": "^1.0.0",
@@ -145,7 +146,7 @@
"json-loader": "^0.5.7",
"loader-utils": "^3.0.0",
"matrix-mock-request": "^2.5.0",
"matrix-web-i18n": "^1.4.0",
"matrix-web-i18n": "^2.0.0",
"mini-css-extract-plugin": "^1",
"minimist": "^1.2.6",
"mkdirp": "^3.0.0",
@@ -163,10 +164,10 @@
"postcss-scss": "^4.0.4",
"postcss-simple-vars": "^5.0.2",
"prettier": "2.8.8",
"proxy-agent": "^6.3.0",
"raw-loader": "^4.0.2",
"rimraf": "^5.0.0",
"semver": "^7.5.2",
"simple-proxy-agent": "^1.1.0",
"string-replace-loader": "3",
"style-loader": "2",
"stylelint": "^15.10.1",

View File

@@ -1,13 +1,12 @@
#!/usr/bin/env node
"use strict";
const fs = require("fs");
const { exec } = require("node:child_process");
import * as fs from "node:fs";
import { exec } from "node:child_process";
const includeJSSDK = process.argv.includes("--include-js-sdk");
const ignore = [];
const ignore: string[] = [];
ignore.push(...Object.values(JSON.parse(fs.readFileSync(`${__dirname}/../components.json`))));
ignore.push(...Object.values<string>(JSON.parse(fs.readFileSync(`${__dirname}/../components.json`, "utf-8"))));
ignore.push("/index.ts");
// We ignore js-sdk by default as it may export for other non element-web projects
if (!includeJSSDK) ignore.push("matrix-js-sdk");
@@ -31,7 +30,7 @@ exec(command, (error, stdout, stderr) => {
// won't have an "/" character at the start, so we try to fix that for
// better UX
// TODO: This might break on Windows
lines = lines.reduce((newLines, line) => {
lines = lines.reduce<string[]>((newLines, line) => {
if (!line.startsWith("/")) newLines.push("/" + line);
else newLines.push(line);
return newLines;

View File

@@ -3,11 +3,11 @@
// due to file associations in Windows.
// Sorry.
const fs = require("fs");
const path = require("path");
const { mkdirpSync } = require("mkdirp");
const fetch = require("node-fetch");
const ProxyAgent = require("simple-proxy-agent");
import * as fs from "node:fs";
import * as path from "node:path";
import { mkdirpSync } from "mkdirp";
import fetch from "node-fetch";
import { ProxyAgent } from "proxy-agent";
console.log("Making webapp directory");
mkdirpSync("webapp");
@@ -16,15 +16,12 @@ mkdirpSync("webapp");
console.log("Downloading Jitsi script");
const fname = path.join("webapp", "jitsi_external_api.min.js");
const options = {};
if (process.env.HTTPS_PROXY) {
options.agent = new ProxyAgent(process.env.HTTPS_PROXY, { tunnel: true });
}
fetch("https://meet.element.io/libs/external_api.min.js", options)
fetch("https://meet.element.io/libs/external_api.min.js", {
agent: new ProxyAgent(),
})
.then((res) => {
const stream = fs.createWriteStream(fname);
return new Promise((resolve, reject) => {
return new Promise<void>((resolve, reject) => {
res.body.pipe(stream);
res.body.on("error", (err) => reject(err));
res.body.on("finish", () => resolve());

View File

@@ -1 +0,0 @@
../../matrix-react-sdk/scripts/check-i18n.pl

View File

@@ -5,58 +5,56 @@ const loaderUtils = require("loader-utils");
// copies the resources into the webapp directory.
//
// Languages are listed manually so we can choose when to include
// a translation in the app (because having a translation with only
// 3 strings translated is just frustrating)
// This could readily be automated, but it's nice to explicitly
// control when new languages are available.
// Languages are listed manually, so we can choose when to include a translation in the app
// (because having a translation with only 3 strings translated is just frustrating)
// This could readily be automated, but it's nice to explicitly control when new languages are available.
const INCLUDE_LANGS = [
{ value: "bg", label: "Български" },
{ value: "ca", label: "Català" },
{ value: "cs", label: "čeština" },
{ value: "da", label: "Dansk" },
{ value: "de_DE", label: "Deutsch" },
{ value: "el", label: "Ελληνικά" },
{ value: "en_EN", label: "English" },
{ value: "en_US", label: "English (US)" },
{ value: "eo", label: "Esperanto" },
{ value: "es", label: "Español" },
{ value: "et", label: "Eesti" },
{ value: "eu", label: "Euskara" },
{ value: "fi", label: "Suomi" },
{ value: "fr", label: "Français" },
{ value: "gl", label: "Galego" },
{ value: "he", label: "עברית" },
{ value: "hi", label: "हिन्दी" },
{ value: "hu", label: "Magyar" },
{ value: "id", label: "Bahasa Indonesia" },
{ value: "is", label: "íslenska" },
{ value: "it", label: "Italiano" },
{ value: "ja", label: "日本語" },
{ value: "kab", label: "Taqbaylit" },
{ value: "ko", label: "한국어" },
{ value: "lo", label: "ລາວ" },
{ value: "lt", label: "Lietuvių" },
{ value: "lv", label: "Latviešu" },
{ value: "nb_NO", label: "Norwegian Bokmål" },
{ value: "nl", label: "Nederlands" },
{ value: "nn", label: "Norsk Nynorsk" },
{ value: "pl", label: "Polski" },
{ value: "pt", label: "Português" },
{ value: "pt_BR", label: "Português do Brasil" },
{ value: "ru", label: "Русский" },
{ value: "sk", label: "Slovenčina" },
{ value: "sq", label: "Shqip" },
{ value: "sr", label: "српски" },
{ value: "sv", label: "Svenska" },
{ value: "te", label: "తెలుగు" },
{ value: "th", label: "ไทย" },
{ value: "tr", label: "Türkçe" },
{ value: "uk", label: "українська мова" },
{ value: "vi", label: "Tiếng Việt" },
{ value: "vls", label: "West-Vlaams" },
{ value: "zh_Hans", label: "简体中文" }, // simplified chinese
{ value: "zh_Hant", label: "繁體中文" }, // traditional chinese
"bg",
"ca",
"cs",
"da",
"de_DE",
"el",
"en_EN",
"en_US",
"eo",
"es",
"et",
"eu",
"fi",
"fr",
"gl",
"he",
"hi",
"hu",
"id",
"is",
"it",
"ja",
"kab",
"ko",
"lo",
"lt",
"lv",
"nb_NO",
"nl",
"nn",
"pl",
"pt",
"pt_BR",
"ru",
"sk",
"sq",
"sr",
"sv",
"te",
"th",
"tr",
"uk",
"vi",
"vls",
"zh_Hans",
"zh_Hant",
];
// cpx includes globbed parts of the filename in the destination, but excludes
@@ -81,7 +79,6 @@ const parseArgs = require("minimist");
const Cpx = require("cpx");
const chokidar = require("chokidar");
const fs = require("fs");
const rimraf = require("rimraf");
const argv = parseArgs(process.argv.slice(2), {});
@@ -158,7 +155,7 @@ function genLangFile(lang, dest) {
const reactSdkFile = "node_modules/matrix-react-sdk/src/i18n/strings/" + lang + ".json";
const riotWebFile = "src/i18n/strings/" + lang + ".json";
let translations = {};
const translations = {};
[reactSdkFile, riotWebFile].forEach(function (f) {
if (fs.existsSync(f)) {
try {
@@ -170,8 +167,6 @@ function genLangFile(lang, dest) {
}
});
translations = weblateToCounterpart(translations);
const json = JSON.stringify(translations, null, 4);
const jsonBuffer = Buffer.from(json);
const digest = loaderUtils.getHashDigest(jsonBuffer, null, null, 7);
@@ -188,12 +183,12 @@ function genLangFile(lang, dest) {
function genLangList(langFileMap) {
const languages = {};
INCLUDE_LANGS.forEach(function (lang) {
const normalizedLanguage = lang.value.toLowerCase().replace("_", "-");
const normalizedLanguage = lang.toLowerCase().replace("_", "-");
const languageParts = normalizedLanguage.split("-");
if (languageParts.length == 2 && languageParts[0] == languageParts[1]) {
languages[languageParts[0]] = { fileName: langFileMap[lang.value], label: lang.label };
languages[languageParts[0]] = langFileMap[lang];
} else {
languages[normalizedLanguage] = { fileName: langFileMap[lang.value], label: lang.label };
languages[normalizedLanguage] = langFileMap[lang];
}
});
fs.writeFile("webapp/i18n/languages.json", JSON.stringify(languages, null, 4), function (err) {
@@ -207,51 +202,11 @@ function genLangList(langFileMap) {
}
}
/**
* Convert translation key from weblate format
* (which only supports a single level) to counterpart
* which requires object values for 'count' translations.
*
* eg.
* "there are %(count)s badgers|one": "a badger",
* "there are %(count)s badgers|other": "%(count)s badgers"
* becomes
* "there are %(count)s badgers": {
* "one": "a badger",
* "other": "%(count)s badgers"
* }
/*
* watch the input files for a given language,
* regenerate the file, adding its content-hashed filename to langFileMap
* and regenerating languages.json with the new filename
*/
function weblateToCounterpart(inTrs) {
const outTrs = {};
for (const key of Object.keys(inTrs)) {
const keyParts = key.split("|", 2);
if (keyParts.length === 2) {
let obj = outTrs[keyParts[0]];
if (obj === undefined) {
obj = outTrs[keyParts[0]] = {};
} else if (typeof obj === "string") {
// This is a transitional edge case if a string went from singular to pluralised and both still remain
// in the translation json file. Use the singular translation as `other` and merge pluralisation atop.
obj = outTrs[keyParts[0]] = {
other: inTrs[key],
};
console.warn("Found entry in i18n file in both singular and pluralised form", keyParts[0]);
}
obj[keyParts[1]] = inTrs[key];
} else {
outTrs[key] = inTrs[key];
}
}
return outTrs;
}
/**
watch the input files for a given language,
regenerate the file, adding its content-hashed filename to langFileMap
and regenerating languages.json with the new filename
*/
function watchLanguage(lang, dest, langFileMap) {
const reactSdkFile = "node_modules/matrix-react-sdk/src/i18n/strings/" + lang + ".json";
const riotWebFile = "src/i18n/strings/" + lang + ".json";
@@ -279,8 +234,8 @@ function watchLanguage(lang, dest, langFileMap) {
// language resources
const I18N_DEST = "webapp/i18n/";
const I18N_FILENAME_MAP = INCLUDE_LANGS.reduce((m, l) => {
const filename = genLangFile(l.value, I18N_DEST);
m[l.value] = filename;
const filename = genLangFile(l, I18N_DEST);
m[l] = filename;
return m;
}, {});
genLangList(I18N_FILENAME_MAP);

View File

@@ -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<IProps> = ({ onAccept }) => {
<h2 id="step1_heading">{_t("Your browser can't run %(brand)s", { brand })}</h2>
<p>
{_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 },
)}
</p>
<p>
{_t(
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, " +
"or <safariLink>Safari</safariLink> for the best experience.",
"Please install <chromeLink>Chrome</chromeLink>, <firefoxLink>Firefox</firefoxLink>, or <safariLink>Safari</safariLink> for the best experience.",
{},
{
chromeLink: (sub) => <a href="https://www.google.com/chrome">{sub}</a>,
@@ -131,8 +130,7 @@ const CompatibilityView: React.FC<IProps> = ({ onAccept }) => {
</p>
<p>
{_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.",
)}
</p>
<button onClick={onAccept}>{_t("I understand the risks and wish to continue")}</button>

View File

@@ -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.

View File

@@ -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");

View File

@@ -1 +1 @@
{}
{}

View File

@@ -27,5 +27,6 @@
"%(brand)s uses advanced browser features which aren't supported by your current browser.": "%(brand)s იყენებს ბრაუზერის გაფართოებულ ფუნქციებს, რომლებიც არ არის მხარდაჭერილი თქვენი ამჟამინდელი ბრაუზერის მიერ.",
"%(appName)s: %(browserName)s on %(osName)s": "%(appName)s: %(browserName)s %(osName)s-ზე",
"%(brand)s Desktop: %(platformName)s": "%(brand)s სამუშაო მაგიდა: %(platformName)s",
"The message from the parser is: %(message)s": "პარსერის შეტყობინებაა: %(message)s"
"The message from the parser is: %(message)s": "პარსერის შეტყობინებაა: %(message)s",
"Invalid configuration: a default_hs_url can't be specified along with default_server_name or default_server_config": "არასწორი კონფიგურაცია: default_hs_url არ შეიძლება მითითებული იყოს default_server_name ან default_server_config-თან ერთად"
}

66
src/languageHandler.tsx Normal file
View File

@@ -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<typeof EN & typeof ReactEN, "|", string | { other: string }>;
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!);
}

View File

@@ -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";
@@ -34,11 +33,11 @@ import { createClient } from "matrix-js-sdk/src/matrix";
import { SnakedObject } from "matrix-react-sdk/src/utils/SnakedObject";
import MatrixChat from "matrix-react-sdk/src/components/structures/MatrixChat";
import { ValidatedServerConfig } from "matrix-react-sdk/src/utils/ValidatedServerConfig";
import { QueryDict, encodeParams } from "matrix-js-sdk/src/utils";
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.
@@ -48,31 +47,6 @@ logger.log(`Application is running in ${process.env.NODE_ENV} mode`);
window.matrixLogger = logger;
// We use this to work out what URL the SDK should
// pass through when registering to allow the user to
// click back to the client having registered.
// It's up to us to recognise if we're loaded with
// this URL and tell MatrixClient to resume registration.
//
// If we're in electron, we should never pass through a file:// URL otherwise
// the identity server will try to 302 the browser to it, which breaks horribly.
// so in that instance, hardcode to use app.element.io for now instead.
function makeRegistrationUrl(params: QueryDict): string {
let url: string;
if (window.location.protocol === "vector:") {
url = "https://app.element.io/#/register";
} else {
url = window.location.protocol + "//" + window.location.host + window.location.pathname + "#/register";
}
const encodedParams = encodeParams(params);
if (encodedParams) {
url += "?" + encodedParams;
}
return url;
}
function onTokenLoginCompleted(): void {
// if we did a token login, we're now left with the token, hs and is
// url as query params in the url;
@@ -138,7 +112,6 @@ export async function loadApp(fragParams: {}): Promise<ReactElement> {
return (
<MatrixChat
onNewScreen={onNewScreen}
makeRegistrationUrl={makeRegistrationUrl}
config={config}
realQueryParams={params}
startingFragmentQueryParams={fragParams}
@@ -174,8 +147,7 @@ async function verifyServerConfig(): Promise<IConfigOptions> {
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) {

View File

@@ -199,8 +199,7 @@ async function start(): Promise<void> {
// 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"),

View File

@@ -184,4 +184,4 @@ export async function loadModules(): Promise<void> {
}
}
export const _t = languageHandler._t;
export { _t } from "../languageHandler";

View File

@@ -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;

View File

@@ -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

View File

@@ -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

View File

@@ -143,9 +143,6 @@ describe("loading:", function () {
enableGuest={true}
onTokenLoginCompleted={resolve}
initialScreenAfterLogin={getScreenFromLocation(windowLocation!)}
makeRegistrationUrl={(): string => {
throw new Error("Not implemented");
}}
/>,
);
});
@@ -158,10 +155,8 @@ describe("loading:", function () {
async function expectAndAwaitSync(opts?: { isGuest?: boolean }): Promise<any> {
let syncRequest: (typeof MockHttpBackend.prototype.requests)[number] | null = null;
httpBackend.when("GET", "/_matrix/client/versions").respond(200, {
versions: ["r0.3.0"],
unstable_features: {
"m.lazy_load_members": true,
},
versions: ["v1.1"],
unstable_features: {},
});
const isGuest = opts?.isGuest;
if (!isGuest) {
@@ -220,7 +215,7 @@ describe("loading:", function () {
});
// Pass the liveliness checks
httpBackend.when("GET", "/versions").respond(200, { versions: ["r0.4.0"] });
httpBackend.when("GET", "/versions").respond(200, { versions: ["v1.1"] });
httpBackend.when("GET", "/_matrix/identity/v2").respond(200, {});
return sleep(1)
@@ -270,7 +265,7 @@ describe("loading:", function () {
});
// Pass the liveliness checks
httpBackend.when("GET", "/versions").respond(200, { versions: ["r0.4.0"] });
httpBackend.when("GET", "/versions").respond(200, { versions: ["v1.1"] });
httpBackend.when("GET", "/_matrix/identity/v2").respond(200, {});
return awaitLoginComponent(matrixChat)
@@ -283,7 +278,7 @@ describe("loading:", function () {
// the only outstanding request should be a GET /login
// (in particular there should be no /register request for
// guest registration).
const allowedRequests = ["/_matrix/client/r0/login", "/versions", "/_matrix/identity/v2"];
const allowedRequests = ["/_matrix/client/v3/login", "/versions", "/_matrix/identity/v2"];
for (const req of httpBackend.requests) {
if (req.method === "GET" && allowedRequests.find((p) => req.path.endsWith(p))) {
continue;

View File

@@ -29,7 +29,7 @@ describe("Loading server config", function () {
PlatformPeg.set(new WebPlatform());
fetchMock.get("https://matrix-client.matrix.org/_matrix/client/versions", {
unstable_features: {},
versions: [],
versions: ["v1.1"],
});
fetchMock.get("https://matrix.org/.well-known/matrix/client", {
"m.homeserver": {

View File

@@ -216,6 +216,10 @@ module.exports = (env, argv) => {
// Same goes for js/react-sdk - we don't need two copies.
"matrix-js-sdk": path.resolve(__dirname, "node_modules/matrix-js-sdk"),
"matrix-react-sdk": path.resolve(__dirname, "node_modules/matrix-react-sdk"),
"@matrix-org/react-sdk-module-api": path.resolve(
__dirname,
"node_modules/@matrix-org/react-sdk-module-api",
),
// and matrix-events-sdk & matrix-widget-api
"matrix-events-sdk": path.resolve(__dirname, "node_modules/matrix-events-sdk"),
"matrix-widget-api": path.resolve(__dirname, "node_modules/matrix-widget-api"),
@@ -275,7 +279,7 @@ module.exports = (env, argv) => {
// either webpack or our babel setup.
// When we do get to upgrade our current setup, this should
// probably be removed.
if (f.includes("@vector-im/compound-web")) return true;
if (f.includes(path.join("@vector-im", "compound-web"))) return true;
// but we can't run all of our dependencies through babel (many of them still
// use module.exports which breaks if babel injects an 'include' for its
@@ -725,14 +729,20 @@ module.exports = (env, argv) => {
* @return {string} The returned paths will look like `img/warning.1234567.svg`.
*/
function getAssetOutputPath(url, resourcePath) {
const isKaTeX = resourcePath.includes("KaTeX");
// `res` is the parent dir for our own assets in various layers
// `dist` is the parent dir for KaTeX assets
const prefix = /^.*[/\\](dist|res)[/\\]/;
if (!resourcePath.match(prefix)) {
/**
* Only needed for https://github.com/vector-im/element-web/pull/15939
* If keeping this, we are not able to load external assets such as SVG
* images coming from @vector-im/compound-web.
*/
if (isKaTeX && !resourcePath.match(prefix)) {
throw new Error(`Unexpected asset path: ${resourcePath}`);
}
let outputDir = path.dirname(resourcePath).replace(prefix, "");
if (resourcePath.includes("KaTeX")) {
if (isKaTeX) {
// Add a clearly named directory segment, rather than leaving the KaTeX
// assets loose in each asset type directory.
outputDir = path.join(outputDir, "KaTeX");

795
yarn.lock

File diff suppressed because it is too large Load Diff