diff --git a/src/Modal.js b/src/Modal.js
index 44072b9278..c2ce04c4e8 100644
--- a/src/Modal.js
+++ b/src/Modal.js
@@ -19,6 +19,53 @@ limitations under the License.
var React = require('react');
var ReactDOM = require('react-dom');
+import sdk from './index';
+
+/**
+ * Wrap an asynchronous loader function with a react component which shows a
+ * spinner until the real component loads.
+ */
+const AsyncWrapper = React.createClass({
+ propTypes: {
+ /** A function which takes a 'callback' argument which it will call
+ * with the real component once it loads.
+ */
+ loader: React.PropTypes.func.isRequired,
+ },
+
+ getInitialState: function() {
+ return {
+ component: null,
+ }
+ },
+
+ componentWillMount: function() {
+ this._unmounted = false;
+ this.props.loader((e) => {
+ if (this._unmounted) {
+ return;
+ }
+ this.setState({component: e});
+ });
+ },
+
+ componentWillUnmount: function() {
+ this._unmounted = true;
+ },
+
+ render: function() {
+ const {loader, ...otherProps} = this.props;
+
+ if (this.state.component) {
+ const Component = this.state.component;
+ return ;
+ } else {
+ // show a spinner until the component is loaded.
+ const Spinner = sdk.getComponent("elements.Spinner");
+ return ;
+ }
+ },
+});
module.exports = {
DialogContainerId: "mx_Dialog_Container",
@@ -36,8 +83,30 @@ module.exports = {
},
createDialog: function (Element, props, className) {
- var self = this;
+ return this.createDialogAsync((cb) => {cb(Element)}, props, className);
+ },
+ /**
+ * Open a modal view.
+ *
+ * This can be used to display a react component which is loaded as an asynchronous
+ * webpack component. To do this, set 'loader' as:
+ *
+ * (cb) => {
+ * require([''], cb);
+ * }
+ *
+ * @param {Function} loader a function which takes a 'callback' argument,
+ * which it should call with a React component which will be displayed as
+ * the modal view.
+ *
+ * @param {Object} props properties to pass to the displayed
+ * component. (We will also pass an 'onFinished' property.)
+ *
+ * @param {String} className CSS class to apply to the modal wrapper
+ */
+ createDialogAsync: function (loader, props, className) {
+ var self = this;
// never call this via modal.close() from onFinished() otherwise it will loop
var closeDialog = function() {
if (props && props.onFinished) props.onFinished.apply(null, arguments);
@@ -49,7 +118,7 @@ module.exports = {
var dialog = (
diff --git a/src/components/views/dialogs/EncryptedEventDialog.js b/src/async-components/views/dialogs/EncryptedEventDialog.js
similarity index 100%
rename from src/components/views/dialogs/EncryptedEventDialog.js
rename to src/async-components/views/dialogs/EncryptedEventDialog.js
diff --git a/src/component-index.js b/src/component-index.js
index bc3d698cac..e83de8739d 100644
--- a/src/component-index.js
+++ b/src/component-index.js
@@ -75,8 +75,6 @@ import views$dialogs$ChatInviteDialog from './components/views/dialogs/ChatInvit
views$dialogs$ChatInviteDialog && (module.exports.components['views.dialogs.ChatInviteDialog'] = views$dialogs$ChatInviteDialog);
import views$dialogs$DeactivateAccountDialog from './components/views/dialogs/DeactivateAccountDialog';
views$dialogs$DeactivateAccountDialog && (module.exports.components['views.dialogs.DeactivateAccountDialog'] = views$dialogs$DeactivateAccountDialog);
-import views$dialogs$EncryptedEventDialog from './components/views/dialogs/EncryptedEventDialog';
-views$dialogs$EncryptedEventDialog && (module.exports.components['views.dialogs.EncryptedEventDialog'] = views$dialogs$EncryptedEventDialog);
import views$dialogs$ErrorDialog from './components/views/dialogs/ErrorDialog';
views$dialogs$ErrorDialog && (module.exports.components['views.dialogs.ErrorDialog'] = views$dialogs$ErrorDialog);
import views$dialogs$InteractiveAuthDialog from './components/views/dialogs/InteractiveAuthDialog';
diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js
index 42dbe78630..d5a2acfdd6 100644
--- a/src/components/views/rooms/EventTile.js
+++ b/src/components/views/rooms/EventTile.js
@@ -366,10 +366,11 @@ module.exports = WithMatrixClient(React.createClass({
},
onCryptoClicked: function(e) {
- var EncryptedEventDialog = sdk.getComponent("dialogs.EncryptedEventDialog");
var event = this.props.mxEvent;
- Modal.createDialog(EncryptedEventDialog, {
+ Modal.createDialogAsync((cb) => {
+ require(['../../../async-components/views/dialogs/EncryptedEventDialog'], cb)
+ }, {
event: event,
});
},