From 688f7029d292dcbcaace4eefeec28837e2978041 Mon Sep 17 00:00:00 2001 From: David Baker Date: Fri, 24 Jan 2020 12:28:03 +0000 Subject: [PATCH] Split AsyncWrapper out from Modal So we can use it outside of modals & dialogs --- src/AsyncWrapper.js | 93 +++++++++++++++++++++++++++++++++++++++++++++ src/Modal.js | 77 +------------------------------------ 2 files changed, 95 insertions(+), 75 deletions(-) create mode 100644 src/AsyncWrapper.js diff --git a/src/AsyncWrapper.js b/src/AsyncWrapper.js new file mode 100644 index 0000000000..63b856a882 --- /dev/null +++ b/src/AsyncWrapper.js @@ -0,0 +1,93 @@ +/* +Copyright 2015, 2016 OpenMarket Ltd +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. +*/ + +import createReactClass from 'create-react-class'; +import Analytics from './Analytics'; +import * as sdk from './index'; +import PropTypes from 'prop-types'; +import { _t } from './languageHandler'; + +/** + * Wrap an asynchronous loader function with a react component which shows a + * spinner until the real component loads. + */ +export default createReactClass({ + propTypes: { + /** A promise which resolves with the real component + */ + prom: PropTypes.object.isRequired, + }, + + getInitialState: function() { + return { + component: null, + error: null, + }; + }, + + componentWillMount: function() { + this._unmounted = false; + // XXX: temporary logging to try to diagnose + // https://github.com/vector-im/riot-web/issues/3148 + console.log('Starting load of AsyncWrapper for modal'); + this.props.prom.then((result) => { + if (this._unmounted) { + return; + } + // Take the 'default' member if it's there, then we support + // passing in just an import()ed module, since ES6 async import + // always returns a module *namespace*. + const component = result.default ? result.default : result; + this.setState({component}); + }).catch((e) => { + console.warn('AsyncWrapper promise failed', e); + this.setState({error: e}); + }); + }, + + componentWillUnmount: function() { + this._unmounted = true; + }, + + _onWrapperCancelClick: function() { + this.props.onFinished(false); + }, + + render: function() { + if (this.state.component) { + const Component = this.state.component; + return ; + } else if (this.state.error) { + const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); + const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); + return + {_t("Unable to load! Check your network connectivity and try again.")} + + ; + } else { + // show a spinner until the component is loaded. + const Spinner = sdk.getComponent("elements.Spinner"); + return ; + } + }, +}); + diff --git a/src/Modal.js b/src/Modal.js index 29d3af2e74..b6215b2b5a 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -17,87 +17,14 @@ limitations under the License. import React from 'react'; import ReactDOM from 'react-dom'; -import PropTypes from 'prop-types'; -import createReactClass from 'create-react-class'; import Analytics from './Analytics'; -import * as sdk from './index'; import dis from './dispatcher'; -import { _t } from './languageHandler'; -import {defer} from "./utils/promise"; +import {defer} from './utils/promise'; +import AsyncWrapper from './AsyncWrapper'; const DIALOG_CONTAINER_ID = "mx_Dialog_Container"; const STATIC_DIALOG_CONTAINER_ID = "mx_Dialog_StaticContainer"; -/** - * Wrap an asynchronous loader function with a react component which shows a - * spinner until the real component loads. - */ -const AsyncWrapper = createReactClass({ - propTypes: { - /** A promise which resolves with the real component - */ - prom: PropTypes.object.isRequired, - }, - - getInitialState: function() { - return { - component: null, - error: null, - }; - }, - - componentWillMount: function() { - this._unmounted = false; - // XXX: temporary logging to try to diagnose - // https://github.com/vector-im/riot-web/issues/3148 - console.log('Starting load of AsyncWrapper for modal'); - this.props.prom.then((result) => { - if (this._unmounted) { - return; - } - // Take the 'default' member if it's there, then we support - // passing in just an import()ed module, since ES6 async import - // always returns a module *namespace*. - const component = result.default ? result.default : result; - this.setState({component}); - }).catch((e) => { - console.warn('AsyncWrapper promise failed', e); - this.setState({error: e}); - }); - }, - - componentWillUnmount: function() { - this._unmounted = true; - }, - - _onWrapperCancelClick: function() { - this.props.onFinished(false); - }, - - render: function() { - if (this.state.component) { - const Component = this.state.component; - return ; - } else if (this.state.error) { - const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); - const DialogButtons = sdk.getComponent('views.elements.DialogButtons'); - return - {_t("Unable to load! Check your network connectivity and try again.")} - - ; - } else { - // show a spinner until the component is loaded. - const Spinner = sdk.getComponent("elements.Spinner"); - return ; - } - }, -}); - class ModalManager { constructor() { this._counter = 0;