Merge pull request #13095 from vector-im/t3chguy/app_load2
App load order changes to catch errors better
This commit is contained in:
commit
c0b4ab9f67
|
@ -14,8 +14,8 @@ See the License for the specific language governing permissions and
|
||||||
limitations under the License.
|
limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {ReactNode} from "react";
|
|
||||||
import "modernizr";
|
import "modernizr";
|
||||||
|
import {Renderer} from "react-dom";
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
interface Window {
|
interface Window {
|
||||||
|
@ -25,7 +25,10 @@ declare global {
|
||||||
};
|
};
|
||||||
|
|
||||||
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
mxSendRageshake: (text: string, withLogs?: boolean) => void;
|
||||||
matrixChat: ReactNode;
|
matrixChat: ReturnType<Renderer>;
|
||||||
|
|
||||||
|
// electron-only
|
||||||
|
ipcRenderer: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
// workaround for https://github.com/microsoft/TypeScript/issues/30933
|
// workaround for https://github.com/microsoft/TypeScript/issues/30933
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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.",
|
"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",
|
"The message from the parser is: %(message)s": "The message from the parser is: %(message)s",
|
||||||
"Invalid JSON": "Invalid JSON",
|
"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.",
|
"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",
|
"Open user settings": "Open user settings",
|
||||||
"Riot Desktop on %(platformName)s": "Riot Desktop on %(platformName)s",
|
"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",
|
"Go to your browser to complete Sign In": "Go to your browser to complete Sign In",
|
||||||
|
|
|
@ -26,7 +26,7 @@ global.React = React;
|
||||||
import * as sdk from 'matrix-react-sdk';
|
import * as sdk from 'matrix-react-sdk';
|
||||||
import PlatformPeg from 'matrix-react-sdk/src/PlatformPeg';
|
import PlatformPeg from 'matrix-react-sdk/src/PlatformPeg';
|
||||||
import * as VectorConferenceHandler from 'matrix-react-sdk/src/VectorConferenceHandler';
|
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 AutoDiscoveryUtils from 'matrix-react-sdk/src/utils/AutoDiscoveryUtils';
|
||||||
import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery";
|
import {AutoDiscovery} from "matrix-js-sdk/src/autodiscovery";
|
||||||
import * as Lifecycle from "matrix-react-sdk/src/Lifecycle";
|
import * as Lifecycle from "matrix-react-sdk/src/Lifecycle";
|
||||||
|
@ -37,10 +37,8 @@ import {parseQs, parseQsFromFragment} from './url_utils';
|
||||||
|
|
||||||
import {MatrixClientPeg} from 'matrix-react-sdk/src/MatrixClientPeg';
|
import {MatrixClientPeg} from 'matrix-react-sdk/src/MatrixClientPeg';
|
||||||
import SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
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 CallHandler from 'matrix-react-sdk/src/CallHandler';
|
||||||
import {loadConfig, preparePlatform, loadLanguage, loadOlm} from "./init";
|
|
||||||
|
|
||||||
let lastLocationHashSet = null;
|
let lastLocationHashSet = null;
|
||||||
|
|
||||||
|
@ -128,7 +126,7 @@ function onTokenLoginCompleted() {
|
||||||
window.location.href = formatted;
|
window.location.href = formatted;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
|
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
|
// 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
|
// but alternatives seem to require changing the interface to passing Workers to js-sdk
|
||||||
const vectorIndexeddbWorkerScript = document.body.dataset.vectorIndexeddbWorkerScript;
|
const vectorIndexeddbWorkerScript = document.body.dataset.vectorIndexeddbWorkerScript;
|
||||||
|
@ -137,63 +135,22 @@ export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
|
||||||
// the bundling. The js-sdk will just fall back to accessing
|
// the bundling. The js-sdk will just fall back to accessing
|
||||||
// indexeddb directly with no worker script, but we want to
|
// indexeddb directly with no worker script, but we want to
|
||||||
// make sure the indexeddb script is present, so fail hard.
|
// 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);
|
MatrixClientPeg.setIndexedDbWorkerScript(vectorIndexeddbWorkerScript);
|
||||||
CallHandler.setConferenceHandler(VectorConferenceHandler);
|
CallHandler.setConferenceHandler(VectorConferenceHandler);
|
||||||
|
|
||||||
window.addEventListener('hashchange', onHashChange);
|
window.addEventListener('hashchange', onHashChange);
|
||||||
|
|
||||||
await loadOlm();
|
|
||||||
|
|
||||||
// set the platform for react sdk
|
|
||||||
preparePlatform();
|
|
||||||
const platform = PlatformPeg.get();
|
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 params = parseQs(window.location);
|
const params = parseQs(window.location);
|
||||||
|
|
||||||
// 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");
|
|
||||||
return <GenericErrorPage message={errorMessage} title={_t("Your Riot is misconfigured")} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
const urlWithoutQuery = window.location.protocol + '//' + window.location.host + window.location.pathname;
|
const urlWithoutQuery = window.location.protocol + '//' + window.location.host + window.location.pathname;
|
||||||
console.log("Vector starting at " + urlWithoutQuery);
|
console.log("Vector starting at " + urlWithoutQuery);
|
||||||
if (configError) {
|
|
||||||
return <div className="error">
|
|
||||||
Unable to load config file: please refresh the page to try again.
|
|
||||||
</div>;
|
|
||||||
} else if (acceptBrowser) {
|
|
||||||
platform.startUpdater();
|
platform.startUpdater();
|
||||||
|
|
||||||
try {
|
|
||||||
// Don't bother loading the app until the config is verified
|
// Don't bother loading the app until the config is verified
|
||||||
const config = await verifyServerConfig();
|
const config = await verifyServerConfig();
|
||||||
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
const MatrixChat = sdk.getComponent('structures.MatrixChat');
|
||||||
|
@ -209,27 +166,6 @@ export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
|
||||||
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
initialScreenAfterLogin={getScreenFromLocation(window.location)}
|
||||||
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
defaultDeviceDisplayName={platform.getDefaultDeviceDisplayName()}
|
||||||
/>;
|
/>;
|
||||||
} catch (err) {
|
|
||||||
console.error(err);
|
|
||||||
|
|
||||||
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");
|
|
||||||
return <GenericErrorPage message={errorMessage} title={_t("Your Riot is misconfigured")} />;
|
|
||||||
}
|
|
||||||
} 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");
|
|
||||||
return <CompatibilityPage onAccept={function() {
|
|
||||||
if (window.localStorage) window.localStorage.setItem('mx_accepts_unsupported_browser', true);
|
|
||||||
console.log("User accepts the compatibility risks.");
|
|
||||||
loadApp();
|
|
||||||
}} />;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifyServerConfig() {
|
async function verifyServerConfig() {
|
||||||
|
|
|
@ -33,13 +33,15 @@ if ('serviceWorker' in navigator) {
|
||||||
navigator.serviceWorker.register('sw.js');
|
navigator.serviceWorker.register('sw.js');
|
||||||
}
|
}
|
||||||
|
|
||||||
async function settled(prom: Promise<any>) {
|
async function settled(...promises: Array<Promise<any>>) {
|
||||||
|
for (const prom of promises) {
|
||||||
try {
|
try {
|
||||||
await prom;
|
await prom;
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(e);
|
console.error(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function checkBrowserFeatures() {
|
function checkBrowserFeatures() {
|
||||||
if (!window.Modernizr) {
|
if (!window.Modernizr) {
|
||||||
|
@ -76,16 +78,37 @@ function checkBrowserFeatures() {
|
||||||
return featureComplete;
|
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
|
// 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.
|
// if modernizr fails we may not have a functional react to show the error message.
|
||||||
// try in react but fallback to an `alert`
|
// 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() {
|
async function start() {
|
||||||
// load init.ts async so that its code is not executed immediately and we can catch any exceptions
|
// load init.ts async so that its code is not executed immediately and we can catch any exceptions
|
||||||
const {rageshakePromise, loadSkin, loadApp} = await import(
|
const {
|
||||||
|
rageshakePromise,
|
||||||
|
preparePlatform,
|
||||||
|
loadOlm,
|
||||||
|
loadConfig,
|
||||||
|
loadSkin,
|
||||||
|
loadLanguage,
|
||||||
|
loadTheme,
|
||||||
|
loadApp,
|
||||||
|
showError,
|
||||||
|
showIncompatibleBrowser,
|
||||||
|
_t,
|
||||||
|
} = await import(
|
||||||
/* webpackChunkName: "init" */
|
/* webpackChunkName: "init" */
|
||||||
/* webpackPreload: true */
|
/* webpackPreload: true */
|
||||||
"./init");
|
"./init");
|
||||||
|
|
||||||
|
try {
|
||||||
await settled(rageshakePromise); // give rageshake a chance to load/fail
|
await settled(rageshakePromise); // give rageshake a chance to load/fail
|
||||||
|
|
||||||
const fragparts = parseQsFromFragment(window.location);
|
const fragparts = parseQsFromFragment(window.location);
|
||||||
|
@ -107,16 +130,78 @@ async function start() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await loadSkin();
|
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
|
||||||
|
|
||||||
let acceptBrowser = checkBrowserFeatures();
|
// Load language after loading config.json so that settingsDefaults.language can be applied
|
||||||
if (!acceptBrowser && window.localStorage) {
|
const loadLanguagePromise = loadLanguage();
|
||||||
acceptBrowser = Boolean(window.localStorage.getItem("mx_accepts_unsupported_browser"));
|
// 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
|
// 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
|
// run on the components.
|
||||||
// import and thus running before the skin can load.
|
await loadApp(fragparts.params);
|
||||||
await loadApp(fragparts.params, acceptBrowser);
|
} 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();
|
}
|
||||||
|
start().catch(err => {
|
||||||
|
console.error(err);
|
||||||
|
if (!acceptBrowser) {
|
||||||
|
// TODO redirect to static incompatible browser page
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
|
@ -21,6 +21,7 @@ limitations under the License.
|
||||||
import olmWasmPath from "olm/olm.wasm";
|
import olmWasmPath from "olm/olm.wasm";
|
||||||
import Olm from 'olm';
|
import Olm from 'olm';
|
||||||
import * as ReactDOM from "react-dom";
|
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 SettingsStore from "matrix-react-sdk/src/settings/SettingsStore";
|
||||||
|
@ -28,6 +29,7 @@ import ElectronPlatform from "./platform/ElectronPlatform";
|
||||||
import WebPlatform from "./platform/WebPlatform";
|
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 SdkConfig from "matrix-react-sdk/src/SdkConfig";
|
||||||
|
import {setTheme} from "matrix-react-sdk/src/theme";
|
||||||
|
|
||||||
import { initRageshake } from "./rageshakesetup";
|
import { initRageshake } from "./rageshakesetup";
|
||||||
|
|
||||||
|
@ -35,7 +37,7 @@ import { initRageshake } from "./rageshakesetup";
|
||||||
export const rageshakePromise = initRageshake();
|
export const rageshakePromise = initRageshake();
|
||||||
|
|
||||||
export function preparePlatform() {
|
export function preparePlatform() {
|
||||||
if ((<any>window).ipcRenderer) {
|
if (window.ipcRenderer) {
|
||||||
console.log("Using Electron platform");
|
console.log("Using Electron platform");
|
||||||
const plaf = new ElectronPlatform();
|
const plaf = new ElectronPlatform();
|
||||||
PlatformPeg.set(plaf);
|
PlatformPeg.set(plaf);
|
||||||
|
@ -45,21 +47,12 @@ export function preparePlatform() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadConfig(): Promise<Error | void> {
|
export async function loadConfig() {
|
||||||
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
|
// 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.
|
// 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.
|
// Note: this isn't called twice for some wrappers, like the Jitsi wrapper.
|
||||||
SdkConfig.put(configJson || {});
|
SdkConfig.put(await PlatformPeg.get().getConfig() || {});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function loadOlm(): Promise<void> {
|
export function loadOlm(): Promise<void> {
|
||||||
|
@ -138,12 +131,36 @@ export async function loadSkin() {
|
||||||
console.log("Skin loaded!");
|
console.log("Skin loaded!");
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function loadApp(fragParams: {}, acceptBrowser: boolean) {
|
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
|
// load app.js async so that its code is not executed immediately and we can catch any exceptions
|
||||||
const module = await import(
|
const module = await import(
|
||||||
/* webpackChunkName: "riot-web-app" */
|
/* webpackChunkName: "riot-web-app" */
|
||||||
/* webpackPreload: true */
|
/* webpackPreload: true */
|
||||||
"./app");
|
"./app");
|
||||||
window.matrixChat = ReactDOM.render(await module.loadApp(fragParams, acceptBrowser),
|
window.matrixChat = ReactDOM.render(await module.loadApp(fragParams),
|
||||||
document.getElementById('matrixchat'));
|
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;
|
Loading…
Reference in New Issue