From de36aa63fb61c9aee011221e2db6159fe1653ae9 Mon Sep 17 00:00:00 2001
From: Richard van der Hoff <richard@matrix.org>
Date: Wed, 8 Jun 2016 23:03:46 +0100
Subject: [PATCH] Factor out common parts of room creation

Take the duplicated code out of MatrixChat and MemberInfo, and put it in a
separate 'createRoom' module
---
 src/components/structures/MatrixChat.js  | 46 +------------
 src/components/views/rooms/MemberInfo.js | 51 +++-----------
 src/createRoom.js                        | 86 ++++++++++++++++++++++++
 3 files changed, 97 insertions(+), 86 deletions(-)
 create mode 100644 src/createRoom.js

diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index cca7d1fd9f..461410ae82 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -37,6 +37,8 @@ var MatrixTools = require('../../MatrixTools');
 var linkifyMatrix = require("../../linkify-matrix");
 var KeyCode = require('../../KeyCode');
 
+var createRoom = require("../../createRoom");
+
 module.exports = React.createClass({
     displayName: 'MatrixChat',
 
@@ -467,49 +469,7 @@ module.exports = React.createClass({
                 //this._setPage(this.PageTypes.CreateRoom);
                 //this.notifyNewScreen('new');
 
-                var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
-                var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
-                var Loader = sdk.getComponent("elements.Spinner");
-                var modal = Modal.createDialog(Loader);
-
-                if (MatrixClientPeg.get().isGuest()) {
-                    Modal.createDialog(NeedToRegisterDialog, {
-                        title: "Please Register",
-                        description: "Guest users can't create new rooms. Please register to create room and start a chat."
-                    });
-                    return;
-                }
-
-                // XXX: FIXME: deduplicate this with MemberInfo's 'start chat' impl
-                MatrixClientPeg.get().createRoom({
-                    preset: "private_chat",
-                    // Allow guests by default since the room is private and they'd
-                    // need an invite. This means clicking on a 3pid invite email can
-                    // actually drop you right in to a chat.
-                    initial_state: [
-                        {
-                            content: {
-                                guest_access: 'can_join'
-                            },
-                            type: 'm.room.guest_access',
-                            state_key: '',
-                            visibility: 'private',
-                        }
-                    ],
-                }).done(function(res) {
-                    modal.close();
-                    dis.dispatch({
-                        action: 'view_room',
-                        room_id: res.room_id,
-                        // show_settings: true,
-                    });
-                }, function(err) {
-                    modal.close();
-                    Modal.createDialog(ErrorDialog, {
-                        title: "Failed to create room",
-                        description: err.toString()
-                    });
-                });
+                createRoom().done();
                 break;
             case 'view_room_directory':
                 this._setPage(this.PageTypes.RoomDirectory);
diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js
index c50b6e919e..3cddc582c5 100644
--- a/src/components/views/rooms/MemberInfo.js
+++ b/src/components/views/rooms/MemberInfo.js
@@ -30,6 +30,7 @@ var MatrixClientPeg = require("../../../MatrixClientPeg");
 var dis = require("../../../dispatcher");
 var Modal = require("../../../Modal");
 var sdk = require('../../../index');
+var createRoom = require('../../../createRoom');
 
 module.exports = React.createClass({
     displayName: 'MemberInfo',
@@ -387,51 +388,15 @@ module.exports = React.createClass({
             this.props.onFinished();
         }
         else {
-            if (MatrixClientPeg.get().isGuest()) {
-                var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
-                Modal.createDialog(NeedToRegisterDialog, {
-                    title: "Please Register",
-                    description: "Guest users can't create new rooms. Please register to create room and start a chat."
-                });
-                self.props.onFinished();
-                return;
-            }
-
             self.setState({ updating: self.state.updating + 1 });
-            MatrixClientPeg.get().createRoom({
-                // XXX: FIXME: deduplicate this with "view_create_room" in MatrixChat
-                invite: [this.props.member.userId],
-                preset: "private_chat",
-                // Allow guests by default since the room is private and they'd
-                // need an invite. This means clicking on a 3pid invite email can
-                // actually drop you right in to a chat.
-                initial_state: [
-                    {
-                        content: {
-                            guest_access: 'can_join'
-                        },
-                        type: 'm.room.guest_access',
-                        state_key: '',
-                        visibility: 'private',
-                    }
-                ],
-            }).then(
-                function(res) {
-                    dis.dispatch({
-                        action: 'view_room',
-                        room_id: res.room_id
-                    });
-                    self.props.onFinished();
-                }, function(err) {
-                    Modal.createDialog(ErrorDialog, {
-                        title: "Failure to start chat",
-                        description: err.message
-                    });
-                    self.props.onFinished();
-                }
-            ).finally(()=>{
+            createRoom({
+                createOpts: {
+                    invite: [this.props.member.userId],
+                },
+            }).finally(function() {
+                self.props.onFinished();
                 self.setState({ updating: self.state.updating - 1 });
-            });
+            }).done();
         }
     },
 
diff --git a/src/createRoom.js b/src/createRoom.js
new file mode 100644
index 0000000000..658561e78a
--- /dev/null
+++ b/src/createRoom.js
@@ -0,0 +1,86 @@
+/*
+Copyright 2015, 2016 OpenMarket 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.
+*/
+
+var MatrixClientPeg = require('./MatrixClientPeg');
+var Modal = require('./Modal');
+var sdk = require('./index');
+var dis = require("./dispatcher");
+
+var q = require('q');
+
+/**
+ * Create a new room, and switch to it.
+ *
+ * Returns a promise which resolves to the room id, or null if the
+ * action was aborted or failed.
+ *
+ * @param {object=} opts parameters for creating the room
+ * @param {object=} opts.createOpts set of options to pass to createRoom call.
+ */
+function createRoom(opts) {
+    var opts = opts || {};
+
+    var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+    var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog");
+    var Loader = sdk.getComponent("elements.Spinner");
+
+    var client = MatrixClientPeg.get();
+    if (client.isGuest()) {
+        Modal.createDialog(NeedToRegisterDialog, {
+            title: "Please Register",
+            description: "Guest users can't create new rooms. Please register to create room and start a chat."
+        });
+        return q(null);
+    }
+
+    // set some defaults for the creation
+    var createOpts = opts.createOpts || {};
+    createOpts.preset = createOpts.preset || 'private_chat';
+    createOpts.visibility = createOpts.visibility || 'private';
+
+    // Allow guests by default since the room is private and they'd
+    // need an invite. This means clicking on a 3pid invite email can
+    // actually drop you right in to a chat.
+    createOpts.initial_state = createOpts.initial_state || [
+        {
+            content: {
+                guest_access: 'can_join'
+            },
+            type: 'm.room.guest_access',
+            state_key: '',
+        }
+    ];
+
+    var modal = Modal.createDialog(Loader);
+
+    return client.createRoom(createOpts).finally(function() {
+        modal.close();
+    }).then(function(res) {
+        dis.dispatch({
+            action: 'view_room',
+            room_id: res.room_id
+        });
+        return res.room_id;
+    }, function(err) {
+        Modal.createDialog(ErrorDialog, {
+            title: "Failure to create room",
+            description: err.toString()
+        });
+        return null;
+    });
+}
+
+module.exports = createRoom;