Merge branch 'develop' of github.com:vector-im/riot-web into t3chguy/poc_riot_desktop_sso_multi_profile
This commit is contained in:
commit
99e5271cb8
28 changed files with 1491 additions and 933 deletions
26
src/@types/global.d.ts
vendored
26
src/@types/global.d.ts
vendored
|
@ -14,9 +14,25 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
interface Window {
|
||||
Olm: {
|
||||
init: () => Promise<void>;
|
||||
};
|
||||
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
||||
import "modernizr";
|
||||
import {Renderer} from "react-dom";
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
Modernizr: ModernizrAPI & FeatureDetects;
|
||||
Olm: {
|
||||
init: () => Promise<void>;
|
||||
};
|
||||
|
||||
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
||||
matrixChat: ReturnType<Renderer>;
|
||||
|
||||
// electron-only
|
||||
ipcRenderer: any;
|
||||
}
|
||||
|
||||
// workaround for https://github.com/microsoft/TypeScript/issues/30933
|
||||
interface ObjectConstructor {
|
||||
fromEntries?(xs: [string|number|symbol, any][]): object
|
||||
}
|
||||
}
|
||||
|
|
46
src/components/structures/ErrorView.tsx
Normal file
46
src/components/structures/ErrorView.tsx
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
Copyright 2020 New Vector Ltd
|
||||
|
||||
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 * as React from "react";
|
||||
import * as PropTypes from "prop-types";
|
||||
|
||||
import { _t } from "matrix-react-sdk/src/languageHandler";
|
||||
|
||||
interface IProps {
|
||||
title: string;
|
||||
messages?: string[];
|
||||
}
|
||||
|
||||
const ErrorView: React.FC<IProps> = ({title, messages}) => {
|
||||
return <div className="mx_GenericErrorPage">
|
||||
<div className="mx_GenericErrorPage_box">
|
||||
<h1>{title}</h1>
|
||||
<div>
|
||||
{messages && messages.map(msg => <p key={msg}>
|
||||
{ _t(msg) }
|
||||
</p>)}
|
||||
</div>
|
||||
</div>
|
||||
</div>;
|
||||
};
|
||||
|
||||
ErrorView.propTypes = {
|
||||
title: PropTypes.string.isRequired,
|
||||
messages: PropTypes.arrayOf(PropTypes.string.isRequired),
|
||||
};
|
||||
|
||||
export default ErrorView;
|
||||
|
|
@ -11,7 +11,7 @@
|
|||
"Chat with Riot Bot": "Чати с Riot Bot",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "Може да използвате настройките за собствен сървър за да влезете в друг Matrix сървър, чрез указване на адреса му. Това ви позволява да използвате Riot със съществуващ Matrix акаунт, принадлежащ към друг сървър.",
|
||||
"Sign In": "Вписване",
|
||||
"Create Account": "Създай акаунт",
|
||||
"Create Account": "Създай профил",
|
||||
"Need help?": "Нужда от помощ?",
|
||||
"Explore rooms": "Открий стаи",
|
||||
"Room Directory": "Директория със стаи",
|
||||
|
|
|
@ -21,5 +21,7 @@
|
|||
"Your Riot is misconfigured": "Riot je špatně nakonfigurován",
|
||||
"Unexpected error preparing the app. See console for details.": "Neočekávaná chyba při přípravě aplikace. Podrobnosti najdete v konzoli.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Neplatná konfigurace: je možné specifikovat pouze jednu volbu z default_server_config, default_server_name, nebo default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Neplatná konfigurace: není zadán výchozí server."
|
||||
"Invalid configuration: no default server specified.": "Neplatná konfigurace: není zadán výchozí server.",
|
||||
"Open user settings": "Otevřít uživatelské nastavení",
|
||||
"Go to your browser to complete Sign In": "Přejděte do prohlížeče a dokončete přihlášení"
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
{
|
||||
"Missing indexeddb worker script!": "Missing indexeddb worker script!",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Invalid configuration: no default server specified.",
|
||||
"Your Riot is misconfigured": "Your Riot is misconfigured",
|
||||
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.": "Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.",
|
||||
"The message from the parser is: %(message)s": "The message from the parser is: %(message)s",
|
||||
"Invalid JSON": "Invalid JSON",
|
||||
"Your Riot is misconfigured": "Your Riot is misconfigured",
|
||||
"Unable to load config file: please refresh the page to try again.": "Unable to load config file: please refresh the page to try again.",
|
||||
"Unexpected error preparing the app. See console for details.": "Unexpected error preparing the app. See console for details.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Invalid configuration: no default server specified.",
|
||||
"Open user settings": "Open user settings",
|
||||
"Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s",
|
||||
"Go to your browser to complete Sign In": "Go to your browser to complete Sign In",
|
||||
|
|
|
@ -21,5 +21,7 @@
|
|||
"Invalid configuration: no default server specified.": "Configuración errónea: no se ha especificado servidor.",
|
||||
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.": "Tu configuración de Riot contiene JSON inválido. Por favor corrige el error y recarga la página.",
|
||||
"The message from the parser is: %(message)s": "El mensaje del parser es: %(message)s",
|
||||
"Invalid JSON": "JSON inválido"
|
||||
"Invalid JSON": "JSON inválido",
|
||||
"Open user settings": "Abrir opciones de usuario",
|
||||
"Go to your browser to complete Sign In": "Abre tu navegador web para completar el registro"
|
||||
}
|
||||
|
|
7
src/i18n/strings/et.json
Normal file
7
src/i18n/strings/et.json
Normal file
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.": "Sinu Rioti seadetes on vigane JSON. Palun, tee see korda ja laadi leht uuesti!",
|
||||
"The message from the parser is: %(message)s": "Sõnum parserist on: %(message)s",
|
||||
"Invalid JSON": "Vigane JSON",
|
||||
"Your Riot is misconfigured": "Sinu Riot on valesti seadistatud",
|
||||
"Unknown device": "Tundmatu seade"
|
||||
}
|
|
@ -8,5 +8,12 @@
|
|||
"%(appName)s via %(browserName)s on %(osName)s": "%(appName)s از طریق %(browserName)s بر %(osName)s",
|
||||
"Custom Server Options": "تنظیمات سفارشی برای سرور",
|
||||
"Dismiss": "نادیده بگیر",
|
||||
"You need to be using HTTPS to place a screen-sharing call.": "شما باید از ارتباط امن HTTPS برای بهراهاندازی یک چتِ شامل به اشتراکگذاری صفحهی کامیپوتر استفاده کنید."
|
||||
"You need to be using HTTPS to place a screen-sharing call.": "شما باید از ارتباط امن HTTPS برای بهراهاندازی یک چتِ شامل به اشتراکگذاری صفحهی کامیپوتر استفاده کنید.",
|
||||
"Invalid JSON": "JSON اشتباه",
|
||||
"Open user settings": "تنظییمات کاربری",
|
||||
"Go to your browser to complete Sign In": "برای تکمیل ورود به مرورگر خود بروید",
|
||||
"Sign In": "ورود",
|
||||
"Create Account": "ایجاد اکانت",
|
||||
"Need help?": "به کمک نیازمندید؟",
|
||||
"Explore rooms": "کاوش اتاق"
|
||||
}
|
||||
|
|
|
@ -8,5 +8,12 @@
|
|||
"Welcome to Riot.im": "ברוכים הבאים ל Riot.im",
|
||||
"Chat with Riot Bot": "שיחה עם Riot בוט",
|
||||
"%(appName)s via %(browserName)s on %(osName)s": "%(appName)s באמצעות הדפדפן %(browserName)s על גבי %(osName)s",
|
||||
"Decentralised, encrypted chat & collaboration powered by [matrix]": "צ'ט מוצפן & ושת\"פ נעשה ע\"י ה [matrix]"
|
||||
"Decentralised, encrypted chat & collaboration powered by [matrix]": "צ'ט מוצפן & ושת\"פ נעשה ע\"י ה [matrix]",
|
||||
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.": "תצורת Riot שלך מכילה JSON לא חוקי. אנא תקן את הבעיה וטען מחדש את הדף.",
|
||||
"Invalid JSON": "JSON לא חוקי",
|
||||
"Your Riot is misconfigured": "ה Riot שלך מוגדר באופן שגוי",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "תצורה שגויה: ניתן לציין רק אחד מהבאים, default_server_config, default_server_name, או default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "תצורה שגויה: לא צוין שרת ברירת מחדל.",
|
||||
"Open user settings": "פתיחת הגדרות משתמש",
|
||||
"Go to your browser to complete Sign In": "עבור לדפדפן להמשך ההתחברות"
|
||||
}
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Klaidinga konfigūracija: galima nurodyti tik vieną iš default_server_config, default_server_name, arba default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Klaidinga konfigūracija: nenurodytas numatytasis serveris.",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "Jūs galite naudoti pasirinktinius serverio nustatymus, kad prisijungtumėte prie kitų Matrix serverių, nurodydami kito serverio URL. Tai leidžia jums naudotis Riot su esama Matrix paskyra kitame serveryje.",
|
||||
"Go to your browser to complete Sign In": "Norėdami užbaigti prisijungimą, eikite į naršyklę"
|
||||
"Go to your browser to complete Sign In": "Norėdami užbaigti prisijungimą, eikite į naršyklę",
|
||||
"Open user settings": "Atverti vartotojo nustatymus"
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
"Chat with Riot Bot": "Chat med Riot Bot",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "Du kan bruke instillinger for «egendefinert tjener» til å logge inn på andre Matrix-tjenere ved å spesifisere en annen URL. Dette lar deg bruke Riot med en eksisterende Matrix-konto på en annen hjemmetjener.",
|
||||
"Sign In": "Logg inn",
|
||||
"Create Account": "Lag konto",
|
||||
"Create Account": "Opprett konto",
|
||||
"Need help?": "Trenger du hjelp?",
|
||||
"Room Directory": "Alle rom",
|
||||
"Explore rooms": "Se alle rom",
|
||||
|
@ -21,5 +21,7 @@
|
|||
"Your Riot is misconfigured": "Riot er feilkonfigurert",
|
||||
"Invalid configuration: no default server specified.": "Ugyldig konfigurasjon: ingen standardserver spesifisert.",
|
||||
"Unexpected error preparing the app. See console for details.": "Uventet feil oppsto mens appen ble gjort klar. Se konsollen for detaljer.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Ugyldig konfigurasjon: Spesifiser kun en av følgende: default_server_config, default_server_name eller default_hs_url."
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Ugyldig konfigurasjon: Spesifiser kun en av følgende: default_server_config, default_server_name eller default_hs_url.",
|
||||
"Open user settings": "Åpne brukerinnstillinger",
|
||||
"Go to your browser to complete Sign In": "Gå til nettleseren din for å fullføre innloggingen"
|
||||
}
|
||||
|
|
|
@ -19,7 +19,9 @@
|
|||
"Invalid JSON": "Błędny JSON",
|
||||
"Your Riot is misconfigured": "Twój Riot jest źle skonfigurowany",
|
||||
"Unexpected error preparing the app. See console for details.": "Niespodziewany błąd podczas przygotowywania aplikacji. Otwórz konsolę po szczegóły.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Błędna konfiguracja. Można sprecyzować tylko jedno z: default_server_config, default_server_name, lub default_hs_url.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Błędna konfiguracja. Akceptowalne wartości to: default_server_config, default_server_name, default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Błędna konfiguracja: nie wybrano domyślnego serwera.",
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "Możesz użyć Niestandardowych Opcji Serwera by zalogować się do innych serwerów Matrix poprzez podanie URL innego serwera głównego. Dzięki temu możesz używać Riot z istniejącym kontem z innego serwera głównego."
|
||||
"You can use the custom server options to sign into other Matrix servers by specifying a different homeserver URL. This allows you to use Riot with an existing Matrix account on a different homeserver.": "Możesz użyć Niestandardowych Opcji Serwera by zalogować się do innych serwerów Matrix poprzez podanie URL innego serwera głównego. Dzięki temu możesz używać Riot z istniejącym kontem z innego serwera głównego.",
|
||||
"Open user settings": "Otwórz ustawienia użytkownika",
|
||||
"Go to your browser to complete Sign In": "Aby dokończyć proces rejestracji, przejdź do swojej przeglądarki"
|
||||
}
|
||||
|
|
|
@ -22,5 +22,6 @@
|
|||
"Your Riot configuration contains invalid JSON. Please correct the problem and reload the page.": "Ваша конфигурация Riot содержит нерабочий JSON. Пожалуйста исправьте проблему и перезагрузите страницу.",
|
||||
"The message from the parser is: %(message)s": "Сообщение из парсера: %(message)s",
|
||||
"Invalid JSON": "Нерабочий JSON",
|
||||
"Go to your browser to complete Sign In": "Перейдите в браузер для завершения входа"
|
||||
"Go to your browser to complete Sign In": "Перейдите в браузер для завершения входа",
|
||||
"Open user settings": "Открыть настройки пользователя"
|
||||
}
|
||||
|
|
|
@ -21,5 +21,7 @@
|
|||
"Your Riot is misconfigured": "Riot är felkonfigurerat",
|
||||
"Unexpected error preparing the app. See console for details.": "Oväntat fel vid appstart. Se konsollen för mer information.",
|
||||
"Invalid configuration: can only specify one of default_server_config, default_server_name, or default_hs_url.": "Ogilitiga inställningar: enbart möjligt att specificera en default_config, default_server, eller default_hs_url.",
|
||||
"Invalid configuration: no default server specified.": "Ogilitiga inställningar: ingen standardserver specificerad."
|
||||
"Invalid configuration: no default server specified.": "Ogilitiga inställningar: ingen standardserver specificerad.",
|
||||
"Open user settings": "Öppna användarinställningar",
|
||||
"Go to your browser to complete Sign In": "Gå till din webbläsare för att slutföra inloggningen"
|
||||
}
|
||||
|
|
|
@ -23,11 +23,10 @@ import React from 'react';
|
|||
// access via the console
|
||||
global.React = React;
|
||||
|
||||
import ReactDOM from 'react-dom';
|
||||
import * as sdk from 'matrix-react-sdk';
|
||||
import PlatformPeg from 'matrix-react-sdk/src/PlatformPeg';
|
||||
import * as VectorConferenceHandler from 'matrix-react-sdk/src/VectorConferenceHandler';
|
||||
import {_t, _td, newTranslatableError} from 'matrix-react-sdk/src/languageHandler';
|
||||
import {_td, newTranslatableError} from 'matrix-react-sdk/src/languageHandler';
|
||||
import AutoDiscoveryUtils from 'matrix-react-sdk/src/utils/AutoDiscoveryUtils';
|
||||
import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery";
|
||||
import * as Lifecycle from "matrix-react-sdk/src/Lifecycle";
|
||||
|
@ -38,48 +37,11 @@ import {parseQs, parseQsFromFragment} from './url_utils';
|
|||
|
||||
import {MatrixClientPeg} from 'matrix-react-sdk/src/MatrixClientPeg';
|
||||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||
import {setTheme} from "matrix-react-sdk/src/theme";
|
||||
|
||||
import CallHandler from 'matrix-react-sdk/src/CallHandler';
|
||||
import {loadConfig, preparePlatform, loadLanguage, loadOlm} from "./init";
|
||||
|
||||
let lastLocationHashSet = null;
|
||||
|
||||
function checkBrowserFeatures() {
|
||||
if (!window.Modernizr) {
|
||||
console.error("Cannot check features - Modernizr global is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// custom checks atop Modernizr because it doesn't have ES2018/ES2019 checks in it for some features we depend on,
|
||||
// Modernizr requires rules to be lowercase with no punctuation:
|
||||
// ES2018: http://www.ecma-international.org/ecma-262/9.0/#sec-promise.prototype.finally
|
||||
window.Modernizr.addTest("promiseprototypefinally", () =>
|
||||
window.Promise && window.Promise.prototype && typeof window.Promise.prototype.finally === "function");
|
||||
// ES2019: http://www.ecma-international.org/ecma-262/10.0/#sec-object.fromentries
|
||||
window.Modernizr.addTest("objectfromentries", () =>
|
||||
window.Object && typeof window.Object.fromEntries === "function");
|
||||
|
||||
const featureList = Object.keys(window.Modernizr);
|
||||
|
||||
let featureComplete = true;
|
||||
for (let i = 0; i < featureList.length; i++) {
|
||||
if (window.Modernizr[featureList[i]] === undefined) {
|
||||
console.error(
|
||||
"Looked for feature '%s' but Modernizr has no results for this. " +
|
||||
"Has it been configured correctly?", featureList[i],
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (window.Modernizr[featureList[i]] === false) {
|
||||
console.error("Browser missing feature: '%s'", featureList[i]);
|
||||
// toggle flag rather than return early so we log all missing features rather than just the first.
|
||||
featureComplete = false;
|
||||
}
|
||||
}
|
||||
return featureComplete;
|
||||
}
|
||||
|
||||
// Parse the given window.location and return parameters that can be used when calling
|
||||
// MatrixChat.showScreen(screen, params)
|
||||
function getScreenFromLocation(location) {
|
||||
|
@ -164,7 +126,7 @@ function onTokenLoginCompleted() {
|
|||
window.location.href = formatted;
|
||||
}
|
||||
|
||||
export async function loadApp() {
|
||||
export async function loadApp(fragParams: {}) {
|
||||
// XXX: the way we pass the path to the worker script from webpack via html in body's dataset is a hack
|
||||
// but alternatives seem to require changing the interface to passing Workers to js-sdk
|
||||
const vectorIndexeddbWorkerScript = document.body.dataset.vectorIndexeddbWorkerScript;
|
||||
|
@ -173,133 +135,37 @@ export async function loadApp() {
|
|||
// the bundling. The js-sdk will just fall back to accessing
|
||||
// indexeddb directly with no worker script, but we want to
|
||||
// make sure the indexeddb script is present, so fail hard.
|
||||
throw new Error("Missing indexeddb worker script!");
|
||||
throw newTranslatableError(_td("Missing indexeddb worker script!"));
|
||||
}
|
||||
MatrixClientPeg.setIndexedDbWorkerScript(vectorIndexeddbWorkerScript);
|
||||
CallHandler.setConferenceHandler(VectorConferenceHandler);
|
||||
|
||||
window.addEventListener('hashchange', onHashChange);
|
||||
|
||||
await loadOlm();
|
||||
|
||||
// set the platform for react sdk
|
||||
preparePlatform();
|
||||
const platform = PlatformPeg.get();
|
||||
|
||||
// Load the config from the platform
|
||||
const configError = await loadConfig();
|
||||
|
||||
// Load language after loading config.json so that settingsDefaults.language can be applied
|
||||
await loadLanguage();
|
||||
|
||||
const fragparts = parseQsFromFragment(window.location);
|
||||
const params = parseQs(window.location);
|
||||
|
||||
// don't try to redirect to the native apps if we're
|
||||
// verifying a 3pid (but after we've loaded the config)
|
||||
// or if the user is following a deep link
|
||||
// (https://github.com/vector-im/riot-web/issues/7378)
|
||||
const preventRedirect = fragparts.params.client_secret || fragparts.location.length > 0;
|
||||
|
||||
if (!preventRedirect) {
|
||||
const isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||||
const isAndroid = /Android/.test(navigator.userAgent);
|
||||
if (isIos || isAndroid) {
|
||||
if (document.cookie.indexOf("riot_mobile_redirect_to_guide=false") === -1) {
|
||||
window.location = "mobile_guide/";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// as quickly as we possibly can, set a default theme...
|
||||
await setTheme();
|
||||
|
||||
// Now that we've loaded the theme (CSS), display the config syntax error if needed.
|
||||
if (configError && configError.err && configError.err instanceof SyntaxError) {
|
||||
const errorMessage = (
|
||||
<div>
|
||||
<p>
|
||||
{_t(
|
||||
"Your Riot configuration contains invalid JSON. Please correct the problem " +
|
||||
"and reload the page.",
|
||||
)}
|
||||
</p>
|
||||
<p>
|
||||
{_t(
|
||||
"The message from the parser is: %(message)s",
|
||||
{message: configError.err.message || _t("Invalid JSON")},
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
const GenericErrorPage = sdk.getComponent("structures.GenericErrorPage");
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<GenericErrorPage message={errorMessage} title={_t("Your Riot is misconfigured")} />,
|
||||
document.getElementById('matrixchat'),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const validBrowser = checkBrowserFeatures();
|
||||
|
||||
const acceptInvalidBrowser = window.localStorage && window.localStorage.getItem('mx_accepts_unsupported_browser');
|
||||
|
||||
const urlWithoutQuery = window.location.protocol + '//' + window.location.host + window.location.pathname;
|
||||
console.log("Vector starting at " + urlWithoutQuery);
|
||||
if (configError) {
|
||||
window.matrixChat = ReactDOM.render(<div className="error">
|
||||
Unable to load config file: please refresh the page to try again.
|
||||
</div>, document.getElementById('matrixchat'));
|
||||
} else if (validBrowser || acceptInvalidBrowser) {
|
||||
platform.startUpdater();
|
||||
|
||||
// Don't bother loading the app until the config is verified
|
||||
verifyServerConfig().then((newConfig) => {
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<MatrixChat
|
||||
onNewScreen={onNewScreen}
|
||||
makeRegistrationUrl={makeRegistrationUrl}
|
||||
ConferenceHandler={VectorConferenceHandler}
|
||||
config={newConfig}
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragparts.params}
|
||||
enableGuest={!SdkConfig.get().disable_guests}
|
||||
onTokenLoginCompleted={onTokenLoginCompleted}
|
||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
||||
/>,
|
||||
document.getElementById('matrixchat'),
|
||||
);
|
||||
}).catch(err => {
|
||||
console.error(err);
|
||||
platform.startUpdater();
|
||||
|
||||
let errorMessage = err.translatedMessage
|
||||
|| _t("Unexpected error preparing the app. See console for details.");
|
||||
errorMessage = <span>{errorMessage}</span>;
|
||||
|
||||
// Like the compatibility page, AWOOOOOGA at the user
|
||||
const GenericErrorPage = sdk.getComponent("structures.GenericErrorPage");
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<GenericErrorPage message={errorMessage} title={_t("Your Riot is misconfigured")} />,
|
||||
document.getElementById('matrixchat'),
|
||||
);
|
||||
});
|
||||
} else {
|
||||
console.error("Browser is missing required features.");
|
||||
// take to a different landing page to AWOOOOOGA at the user
|
||||
const CompatibilityPage = sdk.getComponent("structures.CompatibilityPage");
|
||||
window.matrixChat = ReactDOM.render(
|
||||
<CompatibilityPage onAccept={function() {
|
||||
if (window.localStorage) window.localStorage.setItem('mx_accepts_unsupported_browser', true);
|
||||
console.log("User accepts the compatibility risks.");
|
||||
loadApp();
|
||||
}} />,
|
||||
document.getElementById('matrixchat'),
|
||||
);
|
||||
}
|
||||
// Don't bother loading the app until the config is verified
|
||||
const config = await verifyServerConfig();
|
||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||
return <MatrixChat
|
||||
onNewScreen={onNewScreen}
|
||||
makeRegistrationUrl={makeRegistrationUrl}
|
||||
ConferenceHandler={VectorConferenceHandler}
|
||||
config={config}
|
||||
realQueryParams={params}
|
||||
startingFragmentQueryParams={fragParams}
|
||||
enableGuest={!config.disable_guests}
|
||||
onTokenLoginCompleted={onTokenLoginCompleted}
|
||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
||||
/>;
|
||||
}
|
||||
|
||||
async function verifyServerConfig() {
|
||||
|
@ -384,7 +250,6 @@ async function verifyServerConfig() {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
validatedConfig.isDefault = true;
|
||||
|
||||
// Just in case we ever have to debug this
|
||||
|
|
|
@ -1,47 +0,0 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// Require common CSS here; this will make webpack process it into bundle.css.
|
||||
// Our own CSS (which is themed) is imported via separate webpack entry points
|
||||
// in webpack.config.js
|
||||
require('gfm.css/gfm.css');
|
||||
require('highlight.js/styles/github.css');
|
||||
|
||||
// These are things that can run before the skin loads - be careful not to reference the react-sdk though.
|
||||
import './rageshakesetup';
|
||||
import './modernizr';
|
||||
|
||||
// load service worker if available on this platform
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('sw.js');
|
||||
}
|
||||
|
||||
// Ensure the skin is the very first thing to load for the react-sdk. We don't even want to reference
|
||||
// the SDK until we have to in imports.
|
||||
console.log("Loading skin...");
|
||||
import * as sdk from 'matrix-react-sdk';
|
||||
import * as skin from "../component-index";
|
||||
sdk.loadSkin(skin);
|
||||
console.log("Skin loaded!");
|
||||
|
||||
// Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to
|
||||
// run on the components. We use `require` here to make sure webpack doesn't optimize this into an async
|
||||
// import and thus running before the skin can load.
|
||||
require("./app").loadApp();
|
207
src/vector/index.ts
Normal file
207
src/vector/index.ts
Normal file
|
@ -0,0 +1,207 @@
|
|||
/*
|
||||
Copyright 2015, 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
Copyright 2018, 2019 New Vector Ltd
|
||||
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
|
||||
Copyright 2020 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.
|
||||
*/
|
||||
|
||||
// Require common CSS here; this will make webpack process it into bundle.css.
|
||||
// Our own CSS (which is themed) is imported via separate webpack entry points
|
||||
// in webpack.config.js
|
||||
require('gfm.css/gfm.css');
|
||||
require('highlight.js/styles/github.css');
|
||||
|
||||
// These are things that can run before the skin loads - be careful not to reference the react-sdk though.
|
||||
import {parseQsFromFragment} from "./url_utils";
|
||||
import './modernizr';
|
||||
|
||||
// load service worker if available on this platform
|
||||
if ('serviceWorker' in navigator) {
|
||||
navigator.serviceWorker.register('sw.js');
|
||||
}
|
||||
|
||||
async function settled(...promises: Array<Promise<any>>) {
|
||||
for (const prom of promises) {
|
||||
try {
|
||||
await prom;
|
||||
} catch (e) {
|
||||
console.error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkBrowserFeatures() {
|
||||
if (!window.Modernizr) {
|
||||
console.error("Cannot check features - Modernizr global is missing.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// custom checks atop Modernizr because it doesn't have ES2018/ES2019 checks in it for some features we depend on,
|
||||
// Modernizr requires rules to be lowercase with no punctuation:
|
||||
// ES2018: http://www.ecma-international.org/ecma-262/9.0/#sec-promise.prototype.finally
|
||||
window.Modernizr.addTest("promiseprototypefinally", () =>
|
||||
window.Promise && window.Promise.prototype && typeof window.Promise.prototype.finally === "function");
|
||||
// ES2019: http://www.ecma-international.org/ecma-262/10.0/#sec-object.fromentries
|
||||
window.Modernizr.addTest("objectfromentries", () =>
|
||||
window.Object && typeof window.Object.fromEntries === "function");
|
||||
|
||||
const featureList = Object.keys(window.Modernizr);
|
||||
|
||||
let featureComplete = true;
|
||||
for (let i = 0; i < featureList.length; i++) {
|
||||
if (window.Modernizr[featureList[i]] === undefined) {
|
||||
console.error(
|
||||
"Looked for feature '%s' but Modernizr has no results for this. " +
|
||||
"Has it been configured correctly?", featureList[i],
|
||||
);
|
||||
return false;
|
||||
}
|
||||
if (window.Modernizr[featureList[i]] === false) {
|
||||
console.error("Browser missing feature: '%s'", featureList[i]);
|
||||
// toggle flag rather than return early so we log all missing features rather than just the first.
|
||||
featureComplete = false;
|
||||
}
|
||||
}
|
||||
return featureComplete;
|
||||
}
|
||||
|
||||
let acceptBrowser = checkBrowserFeatures();
|
||||
if (!acceptBrowser && window.localStorage) {
|
||||
acceptBrowser = Boolean(window.localStorage.getItem("mx_accepts_unsupported_browser"));
|
||||
}
|
||||
|
||||
// React depends on Map & Set which we check for using modernizr's es6collections
|
||||
// if modernizr fails we may not have a functional react to show the error message.
|
||||
// try in react but fallback to an `alert`
|
||||
// We start loading stuff but don't block on it until as late as possible to allow
|
||||
// the browser to use as much parallelism as it can.
|
||||
// Load parallelism is based on research in https://github.com/vector-im/riot-web/issues/12253
|
||||
async function start() {
|
||||
// load init.ts async so that its code is not executed immediately and we can catch any exceptions
|
||||
const {
|
||||
rageshakePromise,
|
||||
preparePlatform,
|
||||
loadOlm,
|
||||
loadConfig,
|
||||
loadSkin,
|
||||
loadLanguage,
|
||||
loadTheme,
|
||||
loadApp,
|
||||
showError,
|
||||
showIncompatibleBrowser,
|
||||
_t,
|
||||
} = await import(
|
||||
/* webpackChunkName: "init" */
|
||||
/* webpackPreload: true */
|
||||
"./init");
|
||||
|
||||
try {
|
||||
await settled(rageshakePromise); // give rageshake a chance to load/fail
|
||||
|
||||
const fragparts = parseQsFromFragment(window.location);
|
||||
|
||||
// don't try to redirect to the native apps if we're
|
||||
// verifying a 3pid (but after we've loaded the config)
|
||||
// or if the user is following a deep link
|
||||
// (https://github.com/vector-im/riot-web/issues/7378)
|
||||
const preventRedirect = fragparts.params.client_secret || fragparts.location.length > 0;
|
||||
|
||||
if (!preventRedirect) {
|
||||
const isIos = /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||||
const isAndroid = /Android/.test(navigator.userAgent);
|
||||
if (isIos || isAndroid) {
|
||||
if (document.cookie.indexOf("riot_mobile_redirect_to_guide=false") === -1) {
|
||||
window.location.href = "mobile_guide/";
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const loadOlmPromise = loadOlm();
|
||||
// set the platform for react sdk
|
||||
preparePlatform();
|
||||
// load config requires the platform to be ready
|
||||
const loadConfigPromise = loadConfig();
|
||||
await settled(loadConfigPromise); // wait for it to settle
|
||||
// keep initialising so that we can show any possible error with as many features (theme, i18n) as possible
|
||||
|
||||
// Load language after loading config.json so that settingsDefaults.language can be applied
|
||||
const loadLanguagePromise = loadLanguage();
|
||||
// as quickly as we possibly can, set a default theme...
|
||||
const loadThemePromise = loadTheme();
|
||||
const loadSkinPromise = loadSkin();
|
||||
|
||||
// await things settling so that any errors we have to render have features like i18n running
|
||||
await settled(loadSkinPromise, loadThemePromise, loadLanguagePromise);
|
||||
|
||||
// ##########################
|
||||
// error handling begins here
|
||||
// ##########################
|
||||
if (!acceptBrowser) {
|
||||
await new Promise(resolve => {
|
||||
console.error("Browser is missing required features.");
|
||||
// take to a different landing page to AWOOOOOGA at the user
|
||||
showIncompatibleBrowser(() => {
|
||||
if (window.localStorage) {
|
||||
window.localStorage.setItem('mx_accepts_unsupported_browser', String(true));
|
||||
}
|
||||
console.log("User accepts the compatibility risks.");
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
// await config here
|
||||
await loadConfigPromise;
|
||||
} catch (error) {
|
||||
// Now that we've loaded the theme (CSS), display the config syntax error if needed.
|
||||
if (error.err && error.err instanceof SyntaxError) {
|
||||
return showError(_t("Your Riot is misconfigured"), [
|
||||
_t("Your Riot configuration contains invalid JSON. Please correct the problem and reload the page."),
|
||||
_t("The message from the parser is: %(message)s", { message: error.err.message || _t("Invalid JSON")}),
|
||||
]);
|
||||
}
|
||||
return showError(_t("Unable to load config file: please refresh the page to try again."));
|
||||
}
|
||||
|
||||
// ##################################
|
||||
// app load critical path starts here
|
||||
// assert things started successfully
|
||||
// ##################################
|
||||
await rageshakePromise;
|
||||
await loadOlmPromise;
|
||||
await loadSkinPromise;
|
||||
await loadThemePromise;
|
||||
await loadLanguagePromise;
|
||||
|
||||
// Finally, load the app. All of the other react-sdk imports are in this file which causes the skinner to
|
||||
// run on the components.
|
||||
await loadApp(fragparts.params);
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
// Like the compatibility page, AWOOOOOGA at the user
|
||||
await showError(_t("Your Riot is misconfigured"), [
|
||||
err.translatedMessage || _t("Unexpected error preparing the app. See console for details."),
|
||||
]);
|
||||
}
|
||||
}
|
||||
start().catch(err => {
|
||||
console.error(err);
|
||||
if (!acceptBrowser) {
|
||||
// TODO redirect to static incompatible browser page
|
||||
}
|
||||
});
|
|
@ -20,17 +20,24 @@ limitations under the License.
|
|||
// @ts-ignore
|
||||
import olmWasmPath from "olm/olm.wasm";
|
||||
import Olm from 'olm';
|
||||
import * as ReactDOM from "react-dom";
|
||||
import * as React from "react";
|
||||
|
||||
import * as languageHandler from 'matrix-react-sdk/src/languageHandler';
|
||||
import * as languageHandler from "matrix-react-sdk/src/languageHandler";
|
||||
import SettingsStore from "matrix-react-sdk/src/settings/SettingsStore";
|
||||
import ElectronPlatform from "./platform/ElectronPlatform";
|
||||
import WebPlatform from "./platform/WebPlatform";
|
||||
import PlatformPeg from 'matrix-react-sdk/src/PlatformPeg';
|
||||
import PlatformPeg from "matrix-react-sdk/src/PlatformPeg";
|
||||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||
import {setTheme} from "matrix-react-sdk/src/theme";
|
||||
|
||||
import { initRageshake } from "./rageshakesetup";
|
||||
|
||||
|
||||
export const rageshakePromise = initRageshake();
|
||||
|
||||
export function preparePlatform() {
|
||||
if ((<any>window).ipcRenderer) {
|
||||
if (window.ipcRenderer) {
|
||||
console.log("Using Electron platform");
|
||||
const plaf = new ElectronPlatform();
|
||||
PlatformPeg.set(plaf);
|
||||
|
@ -40,21 +47,12 @@ export function preparePlatform() {
|
|||
}
|
||||
}
|
||||
|
||||
export async function loadConfig(): Promise<Error | void> {
|
||||
const platform = PlatformPeg.get();
|
||||
|
||||
let configJson;
|
||||
try {
|
||||
configJson = await platform.getConfig();
|
||||
} catch (e) {
|
||||
return e;
|
||||
} finally {
|
||||
// XXX: We call this twice, once here and once in MatrixChat as a prop. We call it here to ensure
|
||||
// granular settings are loaded correctly and to avoid duplicating the override logic for the theme.
|
||||
//
|
||||
// Note: this isn't called twice for some wrappers, like the Jitsi wrapper.
|
||||
SdkConfig.put(configJson || {});
|
||||
}
|
||||
export async function loadConfig() {
|
||||
// XXX: We call this twice, once here and once in MatrixChat as a prop. We call it here to ensure
|
||||
// granular settings are loaded correctly and to avoid duplicating the override logic for the theme.
|
||||
//
|
||||
// Note: this isn't called twice for some wrappers, like the Jitsi wrapper.
|
||||
SdkConfig.put(await PlatformPeg.get().getConfig() || {});
|
||||
}
|
||||
|
||||
export function loadOlm(): Promise<void> {
|
||||
|
@ -112,3 +110,57 @@ export async function loadLanguage() {
|
|||
console.error("Unable to set language", e);
|
||||
}
|
||||
}
|
||||
|
||||
export async function loadSkin() {
|
||||
// Ensure the skin is the very first thing to load for the react-sdk. We don't even want to reference
|
||||
// the SDK until we have to in imports.
|
||||
console.log("Loading skin...");
|
||||
// load these async so that its code is not executed immediately and we can catch any exceptions
|
||||
const [sdk, skin] = await Promise.all([
|
||||
import(
|
||||
/* webpackChunkName: "matrix-react-sdk" */
|
||||
/* webpackPreload: true */
|
||||
"matrix-react-sdk"),
|
||||
import(
|
||||
/* webpackChunkName: "riot-web-component-index" */
|
||||
/* webpackPreload: true */
|
||||
// @ts-ignore - this module is generated so may fail lint
|
||||
"../component-index"),
|
||||
]);
|
||||
sdk.loadSkin(skin);
|
||||
console.log("Skin loaded!");
|
||||
}
|
||||
|
||||
export async function loadTheme() {
|
||||
setTheme();
|
||||
}
|
||||
|
||||
export async function loadApp(fragParams: {}) {
|
||||
// load app.js async so that its code is not executed immediately and we can catch any exceptions
|
||||
const module = await import(
|
||||
/* webpackChunkName: "riot-web-app" */
|
||||
/* webpackPreload: true */
|
||||
"./app");
|
||||
window.matrixChat = ReactDOM.render(await module.loadApp(fragParams),
|
||||
document.getElementById('matrixchat'));
|
||||
}
|
||||
|
||||
export async function showError(title: string, messages?: string[]) {
|
||||
const ErrorView = (await import(
|
||||
/* webpackChunkName: "error-view" */
|
||||
/* webpackPreload: true */
|
||||
"../components/structures/ErrorView")).default;
|
||||
window.matrixChat = ReactDOM.render(<ErrorView title={title} messages={messages} />,
|
||||
document.getElementById('matrixchat'));
|
||||
}
|
||||
|
||||
export async function showIncompatibleBrowser(onAccept) {
|
||||
const CompatibilityPage = (await import(
|
||||
/* webpackChunkName: "compatibility-page" */
|
||||
/* webpackPreload: true */
|
||||
"matrix-react-sdk/src/components/structures/CompatibilityPage")).default;
|
||||
window.matrixChat = ReactDOM.render(<CompatibilityPage onAccept={onAccept} />,
|
||||
document.getElementById('matrixchat'));
|
||||
}
|
||||
|
||||
export const _t = languageHandler._t;
|
|
@ -30,8 +30,9 @@ import * as rageshake from "matrix-react-sdk/src/rageshake/rageshake";
|
|||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||
import sendBugReport from "matrix-react-sdk/src/rageshake/submit-rageshake";
|
||||
|
||||
function initRageshake() {
|
||||
rageshake.init().then(() => {
|
||||
export function initRageshake() {
|
||||
const prom = rageshake.init();
|
||||
prom.then(() => {
|
||||
console.log("Initialised rageshake.");
|
||||
console.log("To fix line numbers in Chrome: " +
|
||||
"Meatball menu → Settings → Blackboxing → Add /rageshake\\.js$");
|
||||
|
@ -46,10 +47,9 @@ function initRageshake() {
|
|||
}, (err) => {
|
||||
console.error("Failed to initialise rageshake: " + err);
|
||||
});
|
||||
return prom;
|
||||
}
|
||||
|
||||
initRageshake();
|
||||
|
||||
window.mxSendRageshake = function(text: string, withLogs?: boolean) {
|
||||
if (withLogs === undefined) withLogs = true;
|
||||
if (!text || !text.trim()) {
|
||||
|
|
|
@ -32,7 +32,7 @@ export function parseQsFromFragment(location: Location) {
|
|||
|
||||
const result = {
|
||||
location: decodeURIComponent(hashparts[0]),
|
||||
params: {},
|
||||
params: <qs.ParsedUrlQuery>{},
|
||||
};
|
||||
|
||||
if (hashparts.length > 1) {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue