From 980c71076ebbe0528314b58c1c8902676265596c Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 8 Sep 2015 17:02:24 +0100
Subject: [PATCH 01/29] Start moving back to basing off react sdk: move vector
 out of examples dir

---
 examples/custom/CustomMTextTile.js            |  40 ------------------
 examples/custom/README.md                     |   4 --
 examples/custom/index.html                    |  12 ------
 examples/custom/index.js                      |  40 ------------------
 examples/custom/package.json                  |  29 -------------
 {examples/vector => vector}/README.md         |   0
 {examples/vector => vector}/fonts             |   0
 .../icons/android-chrome-144x144.png          | Bin
 .../icons/android-chrome-192x192.png          | Bin
 .../icons/android-chrome-36x36.png            | Bin
 .../icons/android-chrome-48x48.png            | Bin
 .../icons/android-chrome-72x72.png            | Bin
 .../icons/android-chrome-96x96.png            | Bin
 .../icons/apple-touch-icon-114x114.png        | Bin
 .../icons/apple-touch-icon-120x120.png        | Bin
 .../icons/apple-touch-icon-144x144.png        | Bin
 .../icons/apple-touch-icon-152x152.png        | Bin
 .../icons/apple-touch-icon-180x180.png        | Bin
 .../icons/apple-touch-icon-57x57.png          | Bin
 .../icons/apple-touch-icon-60x60.png          | Bin
 .../icons/apple-touch-icon-72x72.png          | Bin
 .../icons/apple-touch-icon-76x76.png          | Bin
 .../icons/apple-touch-icon-precomposed.png    | Bin
 .../icons/apple-touch-icon.png                | Bin
 .../vector => vector}/icons/browserconfig.xml |   0
 .../vector => vector}/icons/favicon-16x16.png | Bin
 .../vector => vector}/icons/favicon-32x32.png | Bin
 .../vector => vector}/icons/favicon-96x96.png | Bin
 {examples/vector => vector}/icons/favicon.ico | Bin
 .../vector => vector}/icons/manifest.json     |   0
 .../icons/mstile-144x144.png                  | Bin
 .../icons/mstile-150x150.png                  | Bin
 .../icons/mstile-310x150.png                  | Bin
 .../icons/mstile-310x310.png                  | Bin
 .../vector => vector}/icons/mstile-70x70.png  | Bin
 {examples/vector => vector}/img               |   0
 {examples/vector => vector}/index.html        |   0
 {examples/vector => vector}/index.js          |   0
 {examples/vector => vector}/media/busy.mp3    | Bin
 {examples/vector => vector}/media/busy.ogg    | Bin
 {examples/vector => vector}/media/callend.mp3 | Bin
 {examples/vector => vector}/media/callend.ogg | Bin
 {examples/vector => vector}/media/message.mp3 | Bin
 {examples/vector => vector}/media/message.ogg | Bin
 {examples/vector => vector}/media/ring.mp3    | Bin
 {examples/vector => vector}/media/ring.ogg    | Bin
 .../vector => vector}/media/ringback.mp3      | Bin
 .../vector => vector}/media/ringback.ogg      | Bin
 {examples/vector => vector}/package.json      |   0
 49 files changed, 125 deletions(-)
 delete mode 100644 examples/custom/CustomMTextTile.js
 delete mode 100644 examples/custom/README.md
 delete mode 100644 examples/custom/index.html
 delete mode 100644 examples/custom/index.js
 delete mode 100644 examples/custom/package.json
 rename {examples/vector => vector}/README.md (100%)
 rename {examples/vector => vector}/fonts (100%)
 rename {examples/vector => vector}/icons/android-chrome-144x144.png (100%)
 rename {examples/vector => vector}/icons/android-chrome-192x192.png (100%)
 rename {examples/vector => vector}/icons/android-chrome-36x36.png (100%)
 rename {examples/vector => vector}/icons/android-chrome-48x48.png (100%)
 rename {examples/vector => vector}/icons/android-chrome-72x72.png (100%)
 rename {examples/vector => vector}/icons/android-chrome-96x96.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-114x114.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-120x120.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-144x144.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-152x152.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-180x180.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-57x57.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-60x60.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-72x72.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-76x76.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon-precomposed.png (100%)
 rename {examples/vector => vector}/icons/apple-touch-icon.png (100%)
 rename {examples/vector => vector}/icons/browserconfig.xml (100%)
 rename {examples/vector => vector}/icons/favicon-16x16.png (100%)
 rename {examples/vector => vector}/icons/favicon-32x32.png (100%)
 rename {examples/vector => vector}/icons/favicon-96x96.png (100%)
 rename {examples/vector => vector}/icons/favicon.ico (100%)
 rename {examples/vector => vector}/icons/manifest.json (100%)
 rename {examples/vector => vector}/icons/mstile-144x144.png (100%)
 rename {examples/vector => vector}/icons/mstile-150x150.png (100%)
 rename {examples/vector => vector}/icons/mstile-310x150.png (100%)
 rename {examples/vector => vector}/icons/mstile-310x310.png (100%)
 rename {examples/vector => vector}/icons/mstile-70x70.png (100%)
 rename {examples/vector => vector}/img (100%)
 rename {examples/vector => vector}/index.html (100%)
 rename {examples/vector => vector}/index.js (100%)
 rename {examples/vector => vector}/media/busy.mp3 (100%)
 rename {examples/vector => vector}/media/busy.ogg (100%)
 rename {examples/vector => vector}/media/callend.mp3 (100%)
 rename {examples/vector => vector}/media/callend.ogg (100%)
 rename {examples/vector => vector}/media/message.mp3 (100%)
 rename {examples/vector => vector}/media/message.ogg (100%)
 rename {examples/vector => vector}/media/ring.mp3 (100%)
 rename {examples/vector => vector}/media/ring.ogg (100%)
 rename {examples/vector => vector}/media/ringback.mp3 (100%)
 rename {examples/vector => vector}/media/ringback.ogg (100%)
 rename {examples/vector => vector}/package.json (100%)

diff --git a/examples/custom/CustomMTextTile.js b/examples/custom/CustomMTextTile.js
deleted file mode 100644
index e58ed4c1..00000000
--- a/examples/custom/CustomMTextTile.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-var MTextTileController = require("matrix-react-sdk/src/controllers/molecules/MTextTile");
-
-module.exports = React.createClass({
-    displayName: 'MTextTile',
-    mixins: [MTextTileController],
-
-    render: function() {
-        var content = this.props.mxEvent.getContent();
-        return (
-            <span ref="content" className="mx_MTextTile mx_MessageTile_content" onClick={this.onClick}>
-                {content.body}
-            </span>
-        );
-    },
-
-    onClick: function(ev) {
-        global.alert(this.props.mxEvent.getContent().body);
-    }
-});
-
diff --git a/examples/custom/README.md b/examples/custom/README.md
deleted file mode 100644
index 8125053c..00000000
--- a/examples/custom/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-matrix-react-example
-====================
-
-An example of how to use the Matrix React SDK to build a more customised app
diff --git a/examples/custom/index.html b/examples/custom/index.html
deleted file mode 100644
index 04c1645c..00000000
--- a/examples/custom/index.html
+++ /dev/null
@@ -1,12 +0,0 @@
-<!doctype html>
-<html lang="en" style="height: 100%; overflow: hidden">
-  <head>
-    <meta charset="utf-8">
-    <title>Matrix React SDK Custom Example</title>
-  </head>
-  <body style="height: 100%; ">
-    <section id="matrixchat" style="height: 100%; "></section>
-    <script src="bundle.js"></script>
-    <link rel="stylesheet" href="node_modules/matrix-react-sdk/bundle.css">
-  </body>
-</html>
diff --git a/examples/custom/index.js b/examples/custom/index.js
deleted file mode 100644
index 66602a0a..00000000
--- a/examples/custom/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-// Remember to make your project depend on react directly as soon as
-// you add a require('react') to any file in your project. Do not rely
-// on react being pulled in via matrix-react-sdk: browserify breaks
-// horribly in this situation and can end up pulling in multiple copies
-// of react.
-var React = require("react");
-
-// We pull in the component broker first, separately, as we need to replace
-// components before the SDK loads.
-var ComponentBroker = require("matrix-react-sdk/src/ComponentBroker");
-
-var CustomMTextTile = require('./CustomMTextTile');
-
-ComponentBroker.set('molecules/MTextTile', CustomMTextTile);
-
-var MatrixReactSdk = require("matrix-react-sdk");
-//var MatrixReactSdk = require("../../src/index");
-
-React.render(
-    <MatrixReactSdk.MatrixChat />,
-    document.getElementById('matrixchat')
-);
diff --git a/examples/custom/package.json b/examples/custom/package.json
deleted file mode 100644
index 6acec803..00000000
--- a/examples/custom/package.json
+++ /dev/null
@@ -1,29 +0,0 @@
-{
-  "name": "matrix-react-example",
-  "version": "0.0.1",
-  "description": "Example usage of matrix-react-sdk",
-  "author": "matrix.org",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/matrix-org/matrix-react-sdk"
-  },
-  "license": "Apache-2.0",
-  "devDependencies": {
-    "browserify": "^10.2.3",
-    "envify": "^3.4.0",
-    "http-server": "^0.8.0",
-    "matrix-react-sdk": "../../",
-    "npm-css": "^0.2.3",
-    "parallelshell": "^1.2.0",
-    "reactify": "^1.1.1",
-    "uglify-js": "^2.4.23",
-    "watchify": "^3.2.1"
-  },
-  "scripts": {
-    "build": "browserify -t [ envify --NODE_ENV production ] -g reactify index.js | uglifyjs -c -m -o bundle.js",
-    "start": "parallelshell 'watchify -v -d -g reactify index.js -o bundle.js' 'http-server'"
-  },
-  "dependencies": {
-    "react": "^0.13.3"
-  }
-}
diff --git a/examples/vector/README.md b/vector/README.md
similarity index 100%
rename from examples/vector/README.md
rename to vector/README.md
diff --git a/examples/vector/fonts b/vector/fonts
similarity index 100%
rename from examples/vector/fonts
rename to vector/fonts
diff --git a/examples/vector/icons/android-chrome-144x144.png b/vector/icons/android-chrome-144x144.png
similarity index 100%
rename from examples/vector/icons/android-chrome-144x144.png
rename to vector/icons/android-chrome-144x144.png
diff --git a/examples/vector/icons/android-chrome-192x192.png b/vector/icons/android-chrome-192x192.png
similarity index 100%
rename from examples/vector/icons/android-chrome-192x192.png
rename to vector/icons/android-chrome-192x192.png
diff --git a/examples/vector/icons/android-chrome-36x36.png b/vector/icons/android-chrome-36x36.png
similarity index 100%
rename from examples/vector/icons/android-chrome-36x36.png
rename to vector/icons/android-chrome-36x36.png
diff --git a/examples/vector/icons/android-chrome-48x48.png b/vector/icons/android-chrome-48x48.png
similarity index 100%
rename from examples/vector/icons/android-chrome-48x48.png
rename to vector/icons/android-chrome-48x48.png
diff --git a/examples/vector/icons/android-chrome-72x72.png b/vector/icons/android-chrome-72x72.png
similarity index 100%
rename from examples/vector/icons/android-chrome-72x72.png
rename to vector/icons/android-chrome-72x72.png
diff --git a/examples/vector/icons/android-chrome-96x96.png b/vector/icons/android-chrome-96x96.png
similarity index 100%
rename from examples/vector/icons/android-chrome-96x96.png
rename to vector/icons/android-chrome-96x96.png
diff --git a/examples/vector/icons/apple-touch-icon-114x114.png b/vector/icons/apple-touch-icon-114x114.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-114x114.png
rename to vector/icons/apple-touch-icon-114x114.png
diff --git a/examples/vector/icons/apple-touch-icon-120x120.png b/vector/icons/apple-touch-icon-120x120.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-120x120.png
rename to vector/icons/apple-touch-icon-120x120.png
diff --git a/examples/vector/icons/apple-touch-icon-144x144.png b/vector/icons/apple-touch-icon-144x144.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-144x144.png
rename to vector/icons/apple-touch-icon-144x144.png
diff --git a/examples/vector/icons/apple-touch-icon-152x152.png b/vector/icons/apple-touch-icon-152x152.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-152x152.png
rename to vector/icons/apple-touch-icon-152x152.png
diff --git a/examples/vector/icons/apple-touch-icon-180x180.png b/vector/icons/apple-touch-icon-180x180.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-180x180.png
rename to vector/icons/apple-touch-icon-180x180.png
diff --git a/examples/vector/icons/apple-touch-icon-57x57.png b/vector/icons/apple-touch-icon-57x57.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-57x57.png
rename to vector/icons/apple-touch-icon-57x57.png
diff --git a/examples/vector/icons/apple-touch-icon-60x60.png b/vector/icons/apple-touch-icon-60x60.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-60x60.png
rename to vector/icons/apple-touch-icon-60x60.png
diff --git a/examples/vector/icons/apple-touch-icon-72x72.png b/vector/icons/apple-touch-icon-72x72.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-72x72.png
rename to vector/icons/apple-touch-icon-72x72.png
diff --git a/examples/vector/icons/apple-touch-icon-76x76.png b/vector/icons/apple-touch-icon-76x76.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-76x76.png
rename to vector/icons/apple-touch-icon-76x76.png
diff --git a/examples/vector/icons/apple-touch-icon-precomposed.png b/vector/icons/apple-touch-icon-precomposed.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon-precomposed.png
rename to vector/icons/apple-touch-icon-precomposed.png
diff --git a/examples/vector/icons/apple-touch-icon.png b/vector/icons/apple-touch-icon.png
similarity index 100%
rename from examples/vector/icons/apple-touch-icon.png
rename to vector/icons/apple-touch-icon.png
diff --git a/examples/vector/icons/browserconfig.xml b/vector/icons/browserconfig.xml
similarity index 100%
rename from examples/vector/icons/browserconfig.xml
rename to vector/icons/browserconfig.xml
diff --git a/examples/vector/icons/favicon-16x16.png b/vector/icons/favicon-16x16.png
similarity index 100%
rename from examples/vector/icons/favicon-16x16.png
rename to vector/icons/favicon-16x16.png
diff --git a/examples/vector/icons/favicon-32x32.png b/vector/icons/favicon-32x32.png
similarity index 100%
rename from examples/vector/icons/favicon-32x32.png
rename to vector/icons/favicon-32x32.png
diff --git a/examples/vector/icons/favicon-96x96.png b/vector/icons/favicon-96x96.png
similarity index 100%
rename from examples/vector/icons/favicon-96x96.png
rename to vector/icons/favicon-96x96.png
diff --git a/examples/vector/icons/favicon.ico b/vector/icons/favicon.ico
similarity index 100%
rename from examples/vector/icons/favicon.ico
rename to vector/icons/favicon.ico
diff --git a/examples/vector/icons/manifest.json b/vector/icons/manifest.json
similarity index 100%
rename from examples/vector/icons/manifest.json
rename to vector/icons/manifest.json
diff --git a/examples/vector/icons/mstile-144x144.png b/vector/icons/mstile-144x144.png
similarity index 100%
rename from examples/vector/icons/mstile-144x144.png
rename to vector/icons/mstile-144x144.png
diff --git a/examples/vector/icons/mstile-150x150.png b/vector/icons/mstile-150x150.png
similarity index 100%
rename from examples/vector/icons/mstile-150x150.png
rename to vector/icons/mstile-150x150.png
diff --git a/examples/vector/icons/mstile-310x150.png b/vector/icons/mstile-310x150.png
similarity index 100%
rename from examples/vector/icons/mstile-310x150.png
rename to vector/icons/mstile-310x150.png
diff --git a/examples/vector/icons/mstile-310x310.png b/vector/icons/mstile-310x310.png
similarity index 100%
rename from examples/vector/icons/mstile-310x310.png
rename to vector/icons/mstile-310x310.png
diff --git a/examples/vector/icons/mstile-70x70.png b/vector/icons/mstile-70x70.png
similarity index 100%
rename from examples/vector/icons/mstile-70x70.png
rename to vector/icons/mstile-70x70.png
diff --git a/examples/vector/img b/vector/img
similarity index 100%
rename from examples/vector/img
rename to vector/img
diff --git a/examples/vector/index.html b/vector/index.html
similarity index 100%
rename from examples/vector/index.html
rename to vector/index.html
diff --git a/examples/vector/index.js b/vector/index.js
similarity index 100%
rename from examples/vector/index.js
rename to vector/index.js
diff --git a/examples/vector/media/busy.mp3 b/vector/media/busy.mp3
similarity index 100%
rename from examples/vector/media/busy.mp3
rename to vector/media/busy.mp3
diff --git a/examples/vector/media/busy.ogg b/vector/media/busy.ogg
similarity index 100%
rename from examples/vector/media/busy.ogg
rename to vector/media/busy.ogg
diff --git a/examples/vector/media/callend.mp3 b/vector/media/callend.mp3
similarity index 100%
rename from examples/vector/media/callend.mp3
rename to vector/media/callend.mp3
diff --git a/examples/vector/media/callend.ogg b/vector/media/callend.ogg
similarity index 100%
rename from examples/vector/media/callend.ogg
rename to vector/media/callend.ogg
diff --git a/examples/vector/media/message.mp3 b/vector/media/message.mp3
similarity index 100%
rename from examples/vector/media/message.mp3
rename to vector/media/message.mp3
diff --git a/examples/vector/media/message.ogg b/vector/media/message.ogg
similarity index 100%
rename from examples/vector/media/message.ogg
rename to vector/media/message.ogg
diff --git a/examples/vector/media/ring.mp3 b/vector/media/ring.mp3
similarity index 100%
rename from examples/vector/media/ring.mp3
rename to vector/media/ring.mp3
diff --git a/examples/vector/media/ring.ogg b/vector/media/ring.ogg
similarity index 100%
rename from examples/vector/media/ring.ogg
rename to vector/media/ring.ogg
diff --git a/examples/vector/media/ringback.mp3 b/vector/media/ringback.mp3
similarity index 100%
rename from examples/vector/media/ringback.mp3
rename to vector/media/ringback.mp3
diff --git a/examples/vector/media/ringback.ogg b/vector/media/ringback.ogg
similarity index 100%
rename from examples/vector/media/ringback.ogg
rename to vector/media/ringback.ogg
diff --git a/examples/vector/package.json b/vector/package.json
similarity index 100%
rename from examples/vector/package.json
rename to vector/package.json

From ce9fcdbbb58a4883d94a16cc25c7921bdd765bc8 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 8 Sep 2015 17:06:19 +0100
Subject: [PATCH 02/29] Old, useless README from the trivial react-sdk example

---
 vector/README.md | 4 ----
 1 file changed, 4 deletions(-)
 delete mode 100644 vector/README.md

diff --git a/vector/README.md b/vector/README.md
deleted file mode 100644
index ac266277..00000000
--- a/vector/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-matrix-react-example
-====================
-
-A simple example of how to use the Matrix React SDK

From 901574b56e7fe400d93757f828d88d32362d76f4 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 16 Sep 2015 14:13:16 +0100
Subject: [PATCH 03/29] Update package.json

---
 package.json | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/package.json b/package.json
index 5f99bd51..8f0f1a5a 100644
--- a/package.json
+++ b/package.json
@@ -1,11 +1,11 @@
 {
-  "name": "matrix-react-sdk",
+  "name": "vector-web",
   "version": "0.0.1",
-  "description": "SDK for matrix.org using React",
+  "description": "Vector webapp",
   "author": "matrix.org",
   "repository": {
     "type": "git",
-    "url": "https://github.com/matrix-org/matrix-react-sdk"
+    "url": "https://github.com/vector-im/vector-web"
   },
   "license": "Apache-2.0",
   "main": "src/index.js",
@@ -22,10 +22,10 @@
     "prepublish": "npm run build"
   },
   "dependencies": {
+    "matrix-react-sdk": "^0.0.1",
     "classnames": "^2.1.2",
     "filesize": "^3.1.2",
     "flux": "~2.0.3",
-    "matrix-js-sdk": "git://github.com/matrix-org/matrix-js-sdk.git#develop",
     "q": "^1.4.1",
     "react": "^0.13.3",
     "react-loader": "^1.4.0",

From f1120562f3a61d4a759221b95e4595495dc027da Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 16 Sep 2015 14:14:21 +0100
Subject: [PATCH 04/29] Random console log

---
 skins/base/views/atoms/EditableText.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/skins/base/views/atoms/EditableText.js b/skins/base/views/atoms/EditableText.js
index 38aa5c8d..d4aa2857 100644
--- a/skins/base/views/atoms/EditableText.js
+++ b/skins/base/views/atoms/EditableText.js
@@ -33,7 +33,6 @@ module.exports = React.createClass({
     },
 
     onClickDiv: function() {
-        console.log("onClickDiv triggered");
         this.setState({
             phase: this.Phases.Edit,
         })

From 09b81f46b0ce1a3a04214739c6f1887297072468 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 17:20:22 +0100
Subject: [PATCH 05/29] Remove controllers that all come from react-sdk

---
 package.json                                  |  20 +-
 src/ComponentBroker.js                        | 115 ----
 src/ContentMessages.js                        |  82 ---
 src/MatrixClientPeg.js                        | 101 ----
 src/MatrixTools.js                            |  22 -
 src/Modal.js                                  |  62 ---
 src/Presence.js                               | 107 ----
 src/RoomListSorter.js                         |  36 --
 src/SlashCommands.js                          | 314 -----------
 src/TextForEvent.js                           | 106 ----
 src/WhoIsTyping.js                            |  49 --
 src/controllers/atoms/EditableText.js         |  88 ---
 .../atoms/EnableNotificationsButton.js        |  57 --
 src/controllers/atoms/ImageView.js            |  20 -
 src/controllers/atoms/LogoutButton.js         |  27 -
 src/controllers/atoms/MemberAvatar.js         |  64 ---
 src/controllers/atoms/MessageTimestamp.js     |  21 -
 src/controllers/atoms/RoomAvatar.js           |  64 ---
 .../atoms/create_room/CreateRoomButton.js     |  35 --
 src/controllers/atoms/create_room/Presets.js  |  40 --
 .../atoms/create_room/RoomAlias.js            |  49 --
 src/controllers/atoms/voip/VideoFeed.js       |  21 -
 src/controllers/molecules/ChangeAvatar.js     |  71 ---
 src/controllers/molecules/ChangePassword.js   |  78 ---
 src/controllers/molecules/EventAsTextTile.js  |  21 -
 src/controllers/molecules/MEmoteTile.js       |  30 --
 src/controllers/molecules/MFileTile.js        |  44 --
 src/controllers/molecules/MImageTile.js       |  21 -
 src/controllers/molecules/MNoticeTile.js      |  28 -
 src/controllers/molecules/MTextTile.js        |  30 --
 src/controllers/molecules/MatrixToolbar.js    |  21 -
 src/controllers/molecules/MemberInfo.js       | 319 -----------
 src/controllers/molecules/MemberTile.js       |  69 ---
 src/controllers/molecules/MessageComposer.js  | 414 --------------
 src/controllers/molecules/MessageTile.js      |  50 --
 src/controllers/molecules/ProgressBar.js      |  26 -
 src/controllers/molecules/RoomHeader.js       |  99 ----
 src/controllers/molecules/RoomSettings.js     |  31 --
 src/controllers/molecules/RoomTile.js         |  28 -
 src/controllers/molecules/SenderProfile.js    |  21 -
 src/controllers/molecules/ServerConfig.js     |  64 ---
 .../molecules/UnknownMessageTile.js           |  20 -
 src/controllers/molecules/UserSelector.js     |  45 --
 .../molecules/voip/IncomingCallBox.js         |  75 ---
 src/controllers/molecules/voip/VideoView.js   |  21 -
 src/controllers/organisms/CreateRoom.js       | 135 -----
 src/controllers/organisms/ErrorDialog.js      |  39 --
 src/controllers/organisms/LogoutPrompt.js     |  35 --
 src/controllers/organisms/MemberList.js       | 164 ------
 src/controllers/organisms/Notifier.js         | 129 -----
 src/controllers/organisms/QuestionDialog.js   |  39 --
 src/controllers/organisms/RoomList.js         | 170 ------
 src/controllers/organisms/RoomView.js         | 510 ------------------
 src/controllers/organisms/UserSettings.js     |  72 ---
 src/controllers/pages/MatrixChat.js           | 332 ------------
 src/controllers/templates/Login.js            | 114 ----
 src/controllers/templates/Register.js         | 347 ------------
 src/dispatcher.js                             |  37 --
 src/encryption.js                             |  40 --
 src/extend.js                                 |  26 -
 src/index.js                                  |  19 -
 src/linkify-matrix.js                         | 116 ----
 vector/fonts                                  |   1 -
 vector/img                                    |   1 -
 vector/index.html                             |   2 +-
 vector/package.json                           |  24 -
 66 files changed, 11 insertions(+), 5467 deletions(-)
 delete mode 100644 src/ComponentBroker.js
 delete mode 100644 src/ContentMessages.js
 delete mode 100644 src/MatrixClientPeg.js
 delete mode 100644 src/MatrixTools.js
 delete mode 100644 src/Modal.js
 delete mode 100644 src/Presence.js
 delete mode 100644 src/RoomListSorter.js
 delete mode 100644 src/SlashCommands.js
 delete mode 100644 src/TextForEvent.js
 delete mode 100644 src/WhoIsTyping.js
 delete mode 100644 src/controllers/atoms/EditableText.js
 delete mode 100644 src/controllers/atoms/EnableNotificationsButton.js
 delete mode 100644 src/controllers/atoms/ImageView.js
 delete mode 100644 src/controllers/atoms/LogoutButton.js
 delete mode 100644 src/controllers/atoms/MemberAvatar.js
 delete mode 100644 src/controllers/atoms/MessageTimestamp.js
 delete mode 100644 src/controllers/atoms/RoomAvatar.js
 delete mode 100644 src/controllers/atoms/create_room/CreateRoomButton.js
 delete mode 100644 src/controllers/atoms/create_room/Presets.js
 delete mode 100644 src/controllers/atoms/create_room/RoomAlias.js
 delete mode 100644 src/controllers/atoms/voip/VideoFeed.js
 delete mode 100644 src/controllers/molecules/ChangeAvatar.js
 delete mode 100644 src/controllers/molecules/ChangePassword.js
 delete mode 100644 src/controllers/molecules/EventAsTextTile.js
 delete mode 100644 src/controllers/molecules/MEmoteTile.js
 delete mode 100644 src/controllers/molecules/MFileTile.js
 delete mode 100644 src/controllers/molecules/MImageTile.js
 delete mode 100644 src/controllers/molecules/MNoticeTile.js
 delete mode 100644 src/controllers/molecules/MTextTile.js
 delete mode 100644 src/controllers/molecules/MatrixToolbar.js
 delete mode 100644 src/controllers/molecules/MemberInfo.js
 delete mode 100644 src/controllers/molecules/MemberTile.js
 delete mode 100644 src/controllers/molecules/MessageComposer.js
 delete mode 100644 src/controllers/molecules/MessageTile.js
 delete mode 100644 src/controllers/molecules/ProgressBar.js
 delete mode 100644 src/controllers/molecules/RoomHeader.js
 delete mode 100644 src/controllers/molecules/RoomSettings.js
 delete mode 100644 src/controllers/molecules/RoomTile.js
 delete mode 100644 src/controllers/molecules/SenderProfile.js
 delete mode 100644 src/controllers/molecules/ServerConfig.js
 delete mode 100644 src/controllers/molecules/UnknownMessageTile.js
 delete mode 100644 src/controllers/molecules/UserSelector.js
 delete mode 100644 src/controllers/molecules/voip/IncomingCallBox.js
 delete mode 100644 src/controllers/molecules/voip/VideoView.js
 delete mode 100644 src/controllers/organisms/CreateRoom.js
 delete mode 100644 src/controllers/organisms/ErrorDialog.js
 delete mode 100644 src/controllers/organisms/LogoutPrompt.js
 delete mode 100644 src/controllers/organisms/MemberList.js
 delete mode 100644 src/controllers/organisms/Notifier.js
 delete mode 100644 src/controllers/organisms/QuestionDialog.js
 delete mode 100644 src/controllers/organisms/RoomList.js
 delete mode 100644 src/controllers/organisms/RoomView.js
 delete mode 100644 src/controllers/organisms/UserSettings.js
 delete mode 100644 src/controllers/pages/MatrixChat.js
 delete mode 100644 src/controllers/templates/Login.js
 delete mode 100644 src/controllers/templates/Register.js
 delete mode 100644 src/dispatcher.js
 delete mode 100644 src/encryption.js
 delete mode 100644 src/extend.js
 delete mode 100644 src/index.js
 delete mode 100644 src/linkify-matrix.js
 delete mode 120000 vector/fonts
 delete mode 120000 vector/img
 delete mode 100644 vector/package.json

diff --git a/package.json b/package.json
index 8f0f1a5a..d6be714a 100644
--- a/package.json
+++ b/package.json
@@ -8,18 +8,16 @@
     "url": "https://github.com/vector-im/vector-web"
   },
   "license": "Apache-2.0",
-  "main": "src/index.js",
   "style": "bundle.css",
   "scripts": {
-    "build:skins": "jsx skins build/skins",
-    "build:logic": "jsx src build/src",
-    "build:js": "npm run build:skins && npm run build:logic",
-    "start:js": "jsx -w skins/base/views/ build --source-map-inline",
-    "build:css": "catw 'skins/base/css/**/*.css' -o bundle.css -c uglifycss --no-watch",
-    "start:css": "catw 'skins/base/css/**/*.css' -o bundle.css -v",
-    "build": "npm run build:js && npm run build:css",
-    "start": "parallelshell \"npm run start:js\" \"npm run start:css\"",
-    "prepublish": "npm run build"
+    "reskindex": "reskindex base -h src/skins/base/header",
+    "build": "NODE_ENV=production browserify --ignore olm -t reactify src/index.js | uglifyjs -c -m -o vector/bundle.js",
+    "start": "parallelshell 'watchify --ignore olm -v -d -t reactify src/index.js -o vector/bundle.js' 'npm run start:skins:css' 'http-server vector'",
+    "build:skins:js": "babel src/skins -d lib/skins --source-maps",
+    "build:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
+    "start:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css",
+    "clean": "rimraf lib vector/bundle.css vector/bundle.js",
+    "prepublish": "npm run build:skins"
   },
   "dependencies": {
     "matrix-react-sdk": "^0.0.1",
@@ -32,9 +30,11 @@
     "linkifyjs": "^2.0.0-beta.4"
   },
   "devDependencies": {
+    "babel": "^5.8.23",
     "catw": "^1.0.1",
     "parallelshell": "^1.2.0",
     "react-tools": "^0.13.3",
+    "rimraf": "^2.4.3",
     "uglifycss": "0.0.15"
   }
 }
diff --git a/src/ComponentBroker.js b/src/ComponentBroker.js
deleted file mode 100644
index 61499def..00000000
--- a/src/ComponentBroker.js
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-function load(name) {
-    var module = require("../skins/base/views/"+name);
-    return module;
-};
-
-var ComponentBroker = function() {
-    this.components = {};
-};
-
-ComponentBroker.prototype = {
-    get: function(name) {
-        if (this.components[name]) {
-            return this.components[name];
-        }
-
-        this.components[name] = load(name);
-        return this.components[name];
-    },
-
-    set: function(name, module) {
-        this.components[name] = module;
-    }
-};
-
-// We define one Component Broker globally, because the intention is
-// very much that it is a singleton. Relying on there only being one
-// copy of the module can be dicey and not work as browserify's
-// behaviour with multiple copies of files etc. is erratic at best.
-// XXX: We can still end up with the same file twice in the resulting
-// JS bundle which is nonideal.
-if (global.componentBroker === undefined) {
-    global.componentBroker = new ComponentBroker();
-}
-module.exports = global.componentBroker;
-
-// We need to tell browserify to include all the components
-// by direct require syntax in here, but we don't want them
-// to be evaluated in this file because then we wouldn't be
-// able to override them. if (0) does this.
-// Must be in this file (because the require is file-specific) and
-// must be at the end because the components include this file.
-if (0) {
-require('../skins/base/views/atoms/LogoutButton');
-require('../skins/base/views/atoms/EnableNotificationsButton');
-require('../skins/base/views/atoms/MessageTimestamp');
-require('../skins/base/views/atoms/create_room/CreateRoomButton');
-require('../skins/base/views/atoms/create_room/RoomAlias');
-require('../skins/base/views/atoms/create_room/Presets');
-require('../skins/base/views/atoms/EditableText');
-require('../skins/base/views/molecules/MatrixToolbar');
-require('../skins/base/views/molecules/RoomTile');
-require('../skins/base/views/molecules/MessageTile');
-require('../skins/base/views/molecules/SenderProfile');
-require('../skins/base/views/molecules/UnknownMessageTile');
-require('../skins/base/views/molecules/MTextTile');
-require('../skins/base/views/molecules/MNoticeTile');
-require('../skins/base/views/molecules/MEmoteTile');
-require('../skins/base/views/molecules/MImageTile');
-require('../skins/base/views/molecules/MFileTile');
-require('../skins/base/views/molecules/RoomHeader');
-require('../skins/base/views/molecules/MessageComposer');
-require('../skins/base/views/molecules/ProgressBar');
-require('../skins/base/views/molecules/ServerConfig');
-require('../skins/base/views/organisms/MemberList');
-require('../skins/base/views/molecules/MemberTile');
-require('../skins/base/views/organisms/RoomList');
-require('../skins/base/views/organisms/RoomView');
-require('../skins/base/views/templates/Login');
-require('../skins/base/views/templates/Register');
-require('../skins/base/views/organisms/Notifier');
-require('../skins/base/views/organisms/CreateRoom');
-require('../skins/base/views/molecules/UserSelector');
-require('../skins/base/views/organisms/UserSettings');
-require('../skins/base/views/molecules/ChangeAvatar');
-require('../skins/base/views/molecules/ChangePassword');
-require('../skins/base/views/molecules/RoomSettings');
-// new for vector
-require('../skins/base/views/organisms/LeftPanel');
-require('../skins/base/views/organisms/RightPanel');
-require('../skins/base/views/organisms/LogoutPrompt');
-require('../skins/base/views/organisms/RoomDirectory');
-require('../skins/base/views/molecules/RoomCreate');
-require('../skins/base/views/molecules/RoomDropTarget');
-require('../skins/base/views/molecules/BottomLeftMenu');
-require('../skins/base/views/molecules/DateSeparator');
-require('../skins/base/views/atoms/voip/VideoFeed');
-require('../skins/base/views/atoms/MemberAvatar');
-require('../skins/base/views/atoms/RoomAvatar');
-require('../skins/base/views/atoms/ImageView');
-require('../skins/base/views/molecules/voip/VideoView');
-require('../skins/base/views/molecules/voip/CallView');
-require('../skins/base/views/molecules/voip/IncomingCallBox');
-require('../skins/base/views/molecules/EventAsTextTile');
-require('../skins/base/views/molecules/MemberInfo');
-require('../skins/base/views/organisms/ErrorDialog');
-require('../skins/base/views/organisms/QuestionDialog');
-}
diff --git a/src/ContentMessages.js b/src/ContentMessages.js
deleted file mode 100644
index fdd29fd5..00000000
--- a/src/ContentMessages.js
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var q = require('q');
-var extend = require('./extend');
-
-function infoForImageFile(imageFile) {
-    var deferred = q.defer();
-
-    // Load the file into an html element
-    var img = document.createElement("img");
-
-    var reader = new FileReader();
-    reader.onload = function(e) {
-        img.src = e.target.result;
-
-        // Once ready, returns its size
-        img.onload = function() {
-            deferred.resolve({
-                w: img.width,
-                h: img.height
-            });
-        };
-        img.onerror = function(e) {
-            deferred.reject(e);
-        };
-    };
-    reader.onerror = function(e) {
-        deferred.reject(e);
-    };
-    reader.readAsDataURL(imageFile);
-
-    return deferred.promise;
-}
-
-function sendContentToRoom(file, roomId, matrixClient) {
-    var content = {
-        body: file.name,
-        info: {
-            size: file.size,
-            mimetype: file.type
-        }
-    };
-
-    var def = q.defer();
-    if (file.type.indexOf('image/') == 0) {
-        content.msgtype = 'm.image';
-        infoForImageFile(file).then(function(imageInfo) {
-            extend(content.info, imageInfo);
-            def.resolve();
-        });
-    } else {
-        content.msgtype = 'm.file';
-        def.resolve();
-    }
-
-    return def.promise.then(function() {
-        return matrixClient.uploadContent(file);
-    }).then(function(url) {
-        content.url = url;
-        return matrixClient.sendMessage(roomId, content);
-    });
-}
-
-module.exports = {
-    sendContentToRoom: sendContentToRoom
-};
diff --git a/src/MatrixClientPeg.js b/src/MatrixClientPeg.js
deleted file mode 100644
index 36ccd0a7..00000000
--- a/src/MatrixClientPeg.js
+++ /dev/null
@@ -1,101 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-// A thing that holds your Matrix Client
-var Matrix = require("matrix-js-sdk");
-
-var matrixClient = null;
-
-var localStorage = window.localStorage;
-
-function deviceId() {
-    var id = Math.floor(Math.random()*16777215).toString(16);
-    id = "W" + "000000".substring(id.length) + id;
-    if (localStorage) {
-        id = localStorage.getItem("mx_device_id") || id;
-        localStorage.setItem("mx_device_id", id);
-    }
-    return id;
-}
-
-function createClient(hs_url, is_url, user_id, access_token) {
-    var opts = {
-        baseUrl: hs_url,
-        idBaseUrl: is_url,
-        accessToken: access_token,
-        userId: user_id
-    };
-
-    if (localStorage) {
-        opts.sessionStore = new Matrix.WebStorageSessionStore(localStorage);
-        opts.deviceId = deviceId();
-    }
-
-    matrixClient = Matrix.createClient(opts);
-}
-
-if (localStorage) {
-    var hs_url = localStorage.getItem("mx_hs_url");
-    var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
-    var access_token = localStorage.getItem("mx_access_token");
-    var user_id = localStorage.getItem("mx_user_id");
-    if (access_token && user_id && hs_url) {
-        createClient(hs_url, is_url, user_id, access_token);
-    }
-}
-
-module.exports = {
-    get: function() {
-        return matrixClient;
-    },
-
-    unset: function() {
-        matrixClient = null;
-    },
-
-    replaceUsingUrls: function(hs_url, is_url) {
-        matrixClient = Matrix.createClient({
-            baseUrl: hs_url,
-            idBaseUrl: is_url
-        });
-    },
-
-    replaceUsingAccessToken: function(hs_url, is_url, user_id, access_token) {
-        if (localStorage) {
-            try {
-                localStorage.clear();
-            } catch (e) {
-                console.warn("Error using local storage");
-            }
-        }
-        createClient(hs_url, is_url, user_id, access_token);
-        if (localStorage) {
-            try {
-                localStorage.setItem("mx_hs_url", hs_url);
-                localStorage.setItem("mx_is_url", is_url);
-                localStorage.setItem("mx_user_id", user_id);
-                localStorage.setItem("mx_access_token", access_token);
-            } catch (e) {
-                console.warn("Error using local storage: can't persist session!");
-            }
-        } else {
-            console.warn("No local storage available: can't persist session!");
-        }
-    }
-};
-
diff --git a/src/MatrixTools.js b/src/MatrixTools.js
deleted file mode 100644
index fa9f038b..00000000
--- a/src/MatrixTools.js
+++ /dev/null
@@ -1,22 +0,0 @@
-var MatrixClientPeg = require('./MatrixClientPeg');
-
-module.exports = {
-    /**
-     * Given a room object, return the canonical alias for it
-     * if there is one. Otherwise return null;
-     */
-    getCanonicalAliasForRoom: function(room) {
-        var aliasEvents = room.currentState.getStateEvents(
-            "m.room.aliases"
-        );
-        // Canonical aliases aren't implemented yet, so just return the first
-        for (var j = 0; j < aliasEvents.length; j++) {
-            var aliases = aliasEvents[j].getContent().aliases;
-            if (aliases && aliases.length) {
-                return aliases[0];
-            }
-        }
-        return null;
-    }
-}
-
diff --git a/src/Modal.js b/src/Modal.js
deleted file mode 100644
index ba7660bf..00000000
--- a/src/Modal.js
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-
-'use strict';
-
-var React = require('react');
-var q = require('q');
-
-module.exports = {
-    DialogContainerId: "mx_Dialog_Container",
-
-    getOrCreateContainer: function() {
-        var container = document.getElementById(this.DialogContainerId);
-
-        if (!container) {
-            container = document.createElement("div");
-            container.id = this.DialogContainerId;
-            document.body.appendChild(container);
-        }
-
-        return container;
-    },
-
-    createDialog: function (Element, props) {
-        var self = this;
-
-        var closeDialog = function() {
-            React.unmountComponentAtNode(self.getOrCreateContainer());
-
-            if (props && props.onFinished) props.onFinished.apply(null, arguments);
-        };
-
-        // FIXME: If a dialog uses getDefaultProps it clobbers the onFinished
-        // property set here so you can't close the dialog from a button click!
-        var dialog = (
-            <div className="mx_Dialog_wrapper">
-                <div className="mx_Dialog">
-                    <Element {...props} onFinished={closeDialog}/>
-                </div>
-                <div className="mx_Dialog_background" onClick={closeDialog}></div>
-            </div>
-        );
-
-        React.render(dialog, this.getOrCreateContainer());
-
-        return {close: closeDialog};
-    },
-};
diff --git a/src/Presence.js b/src/Presence.js
deleted file mode 100644
index 558c7e99..00000000
--- a/src/Presence.js
+++ /dev/null
@@ -1,107 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-"use strict";
-var MatrixClientPeg = require("./MatrixClientPeg");
-
- // Time in ms after that a user is considered as unavailable/away
-var UNAVAILABLE_TIME_MS = 3 * 60 * 1000; // 3 mins
-var PRESENCE_STATES = ["online", "offline", "unavailable"];
-
-// The current presence state
-var state, timer;
-
-module.exports = {
-
-    /**
-     * Start listening the user activity to evaluate his presence state.
-     * Any state change will be sent to the Home Server.
-     */
-    start: function() {
-        var self = this;
-        this.running = true;
-        if (undefined === state) {
-            // The user is online if they move the mouse or press a key
-            document.onmousemove = function() { self._resetTimer(); };
-            document.onkeypress = function() { self._resetTimer(); };
-            this._resetTimer();
-        }
-    },
-
-    /**
-     * Stop tracking user activity
-     */
-    stop: function() {
-        this.running = false;
-        if (timer) {
-            clearTimeout(timer);
-            timer = undefined;
-        }
-        state = undefined;
-    },
-
-    /**
-     * Get the current presence state.
-     * @returns {string} the presence state (see PRESENCE enum)
-     */
-    getState: function() {
-        return state;
-    },
-
-    /**
-     * Set the presence state.
-     * If the state has changed, the Home Server will be notified.
-     * @param {string} newState the new presence state (see PRESENCE enum)
-     */
-    setState: function(newState) {
-        if (newState === state) {
-            return;
-        }
-        if (PRESENCE_STATES.indexOf(newState) === -1) {
-            throw new Error("Bad presence state: " + newState);
-        }
-        if (!this.running) {
-            return;
-        }
-        state = newState;
-        MatrixClientPeg.get().setPresence(state).done(function() {
-            console.log("Presence: %s", newState);
-        }, function(err) {
-            console.error("Failed to set presence: %s", err);
-        });
-    },
-
-    /**
-     * Callback called when the user made no action on the page for UNAVAILABLE_TIME ms.
-     * @private
-     */
-    _onUnavailableTimerFire: function() {
-        this.setState("unavailable");
-    },
-
-    /**
-     * Callback called when the user made an action on the page
-     * @private
-     */
-    _resetTimer: function() {
-        var self = this;
-        this.setState("online");
-        // Re-arm the timer
-        clearTimeout(timer);
-        timer = setTimeout(function() {
-            self._onUnavailableTimerFire();
-        }, UNAVAILABLE_TIME_MS);
-    } 
-};
\ No newline at end of file
diff --git a/src/RoomListSorter.js b/src/RoomListSorter.js
deleted file mode 100644
index 730a0de1..00000000
--- a/src/RoomListSorter.js
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-function tsOfNewestEvent(room) {
-    if (room.timeline.length) {
-        return room.timeline[room.timeline.length - 1].getTs();
-    }
-    else {
-        return Number.MAX_SAFE_INTEGER;
-    }
-}
-
-function mostRecentActivityFirst(roomList) {
-    return roomList.sort(function(a,b) {
-        return tsOfNewestEvent(b) - tsOfNewestEvent(a);
-    });
-}
-
-module.exports = {
-    mostRecentActivityFirst: mostRecentActivityFirst
-};
diff --git a/src/SlashCommands.js b/src/SlashCommands.js
deleted file mode 100644
index b47b953a..00000000
--- a/src/SlashCommands.js
+++ /dev/null
@@ -1,314 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("./MatrixClientPeg");
-var dis = require("./dispatcher");
-var encryption = require("./encryption");
-
-var reject = function(msg) {
-    return {
-        error: msg
-    };
-};
-
-var success = function(promise) {
-    return {
-        promise: promise
-    };
-};
-
-var commands = {
-    // Change your nickname
-    nick: function(room_id, args) {
-        if (args) {
-            return success(
-                MatrixClientPeg.get().setDisplayName(args)
-            );
-        }
-        return reject("Usage: /nick <display_name>");
-    },
-
-    encrypt: function(room_id, args) {
-        if (args == "on") {
-            var client = MatrixClientPeg.get();
-            var members = client.getRoom(room_id).currentState.members;
-            var user_ids = Object.keys(members);
-            return success(
-                encryption.enableEncryption(client, room_id, user_ids)
-            );
-        }
-        if (args == "off") {
-            var client = MatrixClientPeg.get();
-            return success(
-                encryption.disableEncryption(client, room_id)
-            );
-
-        }
-        return reject("Usage: encrypt <on/off>");
-    },
-
-    // Change the room topic
-    topic: function(room_id, args) {
-        if (args) {
-            return success(
-                MatrixClientPeg.get().setRoomTopic(room_id, args)
-            );
-        }
-        return reject("Usage: /topic <topic>");
-    },
-
-    // Invite a user
-    invite: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+)$/);
-            if (matches) {
-                return success(
-                    MatrixClientPeg.get().invite(room_id, matches[1])
-                );
-            }
-        }
-        return reject("Usage: /invite <userId>");
-    },
-
-    // Join a room
-    join: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+)$/);
-            if (matches) {
-                var room_alias = matches[1];
-                if (room_alias[0] !== '#') {
-                    return reject("Usage: /join #alias:domain");
-                }
-                if (!room_alias.match(/:/)) {
-                    var domain = MatrixClientPeg.get().credentials.userId.replace(/^.*:/, '');
-                    room_alias += ':' + domain;
-                }
-
-                // Try to find a room with this alias
-                var rooms = MatrixClientPeg.get().getRooms();
-                var roomId;
-                for (var i = 0; i < rooms.length; i++) {
-                    var aliasEvents = rooms[i].currentState.getStateEvents(
-                        "m.room.aliases"
-                    );
-                    for (var j = 0; j < aliasEvents.length; j++) {
-                        var aliases = aliasEvents[j].getContent().aliases || [];
-                        for (var k = 0; k < aliases.length; k++) {
-                            if (aliases[k] === room_alias) {
-                                roomId = rooms[i].roomId;
-                                break;
-                            }
-                        }
-                        if (roomId) { break; }
-                    }
-                    if (roomId) { break; }
-                }
-                if (roomId) { // we've already joined this room, view it.
-                    dis.dispatch({
-                        action: 'view_room',
-                        room_id: roomId
-                    });
-                    return success();
-                }
-                else {
-                    // attempt to join this alias.
-                    return success(
-                        MatrixClientPeg.get().joinRoom(room_alias).then(
-                        function(room) {
-                            dis.dispatch({
-                                action: 'view_room',
-                                room_id: room.roomId
-                            });
-                        })
-                    );
-                }
-            }
-        }
-        return reject("Usage: /join <room_alias>");
-    },
-
-    part: function(room_id, args) {
-        var targetRoomId;
-        if (args) {
-            var matches = args.match(/^(\S+)$/);
-            if (matches) {
-                var room_alias = matches[1];
-                if (room_alias[0] !== '#') {
-                    return reject("Usage: /part [#alias:domain]");
-                }
-                if (!room_alias.match(/:/)) {
-                    var domain = MatrixClientPeg.get().credentials.userId.replace(/^.*:/, '');
-                    room_alias += ':' + domain;
-                }
-
-                // Try to find a room with this alias
-                var rooms = MatrixClientPeg.get().getRooms();
-                for (var i = 0; i < rooms.length; i++) {
-                    var aliasEvents = rooms[i].currentState.getStateEvents(
-                        "m.room.aliases"
-                    );
-                    for (var j = 0; j < aliasEvents.length; j++) {
-                        var aliases = aliasEvents[j].getContent().aliases || [];
-                        for (var k = 0; k < aliases.length; k++) {
-                            if (aliases[k] === room_alias) {
-                                targetRoomId = rooms[i].roomId;
-                                break;
-                            }
-                        }
-                        if (targetRoomId) { break; }
-                    }
-                    if (targetRoomId) { break; }
-                }
-            }
-            if (!targetRoomId) {
-                return reject("Unrecognised room alias: " + room_alias);
-            }
-        }
-        if (!targetRoomId) targetRoomId = room_id;
-        return success(
-            MatrixClientPeg.get().leave(targetRoomId).then(
-            function() {
-                dis.dispatch({action: 'view_next_room'});
-            })
-        );
-    },
-
-    // Kick a user from the room with an optional reason
-    kick: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+?)( +(.*))?$/);
-            if (matches) {
-                return success(
-                    MatrixClientPeg.get().kick(room_id, matches[1], matches[3])
-                );
-            }
-        }
-        return reject("Usage: /kick <userId> [<reason>]");
-    },
-
-    // Ban a user from the room with an optional reason
-    ban: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+?)( +(.*))?$/);
-            if (matches) {
-                return success(
-                    MatrixClientPeg.get().ban(room_id, matches[1], matches[3])
-                );
-            }
-        }
-        return reject("Usage: /ban <userId> [<reason>]");
-    },
-
-    // Unban a user from the room
-    unban: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+)$/);
-            if (matches) {
-                // Reset the user membership to "leave" to unban him
-                return success(
-                    MatrixClientPeg.get().unban(room_id, matches[1])
-                );
-            }
-        }
-        return reject("Usage: /unban <userId>");
-    },
-
-    // Define the power level of a user
-    op: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+?)( +(\d+))?$/);
-            var powerLevel = 50; // default power level for op
-            if (matches) {
-                var user_id = matches[1];
-                if (matches.length === 4 && undefined !== matches[3]) {
-                    powerLevel = parseInt(matches[3]);
-                }
-                if (powerLevel !== NaN) {
-                    var room = MatrixClientPeg.get().getRoom(room_id);
-                    if (!room) {
-                        return reject("Bad room ID: " + room_id);
-                    }
-                    var powerLevelEvent = room.currentState.getStateEvents(
-                        "m.room.power_levels", ""
-                    );
-                    return success(
-                        MatrixClientPeg.get().setPowerLevel(
-                            room_id, user_id, powerLevel, powerLevelEvent
-                        )
-                    );
-                }
-            }
-        }
-        return reject("Usage: /op <userId> [<power level>]");
-    },
-
-    // Reset the power level of a user
-    deop: function(room_id, args) {
-        if (args) {
-            var matches = args.match(/^(\S+)$/);
-            if (matches) {
-                var room = MatrixClientPeg.get().getRoom(room_id);
-                if (!room) {
-                    return reject("Bad room ID: " + room_id);
-                }
-
-                var powerLevelEvent = room.currentState.getStateEvents(
-                    "m.room.power_levels", ""
-                );
-                return success(
-                    MatrixClientPeg.get().setPowerLevel(
-                        room_id, args, undefined, powerLevelEvent
-                    )
-                );
-            }
-        }
-        return reject("Usage: /deop <userId>");
-    }
-};
-
-// helpful aliases
-commands.j = commands.join;
-
-module.exports = {
-    /**
-     * Process the given text for /commands and perform them.
-     * @param {string} roomId The room in which the command was performed.
-     * @param {string} input The raw text input by the user.
-     * @return {Object|null} An object with the property 'error' if there was an error
-     * processing the command, or 'promise' if a request was sent out.
-     * Returns null if the input didn't match a command.
-     */
-    processInput: function(roomId, input) {
-        // trim any trailing whitespace, as it can confuse the parser for 
-        // IRC-style commands
-        input = input.replace(/\s+$/, "");
-        if (input[0] === "/" && input[1] !== "/") {
-            var bits = input.match(/^(\S+?)( +(.*))?$/);
-            var cmd = bits[1].substring(1).toLowerCase();
-            var args = bits[3];
-            if (cmd === "me") return null;
-            if (commands[cmd]) {
-                return commands[cmd](roomId, args);
-            }
-            else {
-                return reject("Unrecognised command: " + input);
-            }
-        }
-        return null; // not a command
-    }
-};
diff --git a/src/TextForEvent.js b/src/TextForEvent.js
deleted file mode 100644
index 3d6ba2cf..00000000
--- a/src/TextForEvent.js
+++ /dev/null
@@ -1,106 +0,0 @@
-
-function textForMemberEvent(ev) {
-    // XXX: SYJS-16
-    var senderName = ev.sender ? ev.sender.name : ev.getSender();
-    var targetName = ev.target ? ev.target.name : ev.getStateKey();
-    var reason = ev.getContent().reason ? (
-        " Reason: " + ev.getContent().reason
-    ) : "";
-    switch (ev.getContent().membership) {
-        case 'invite':
-            return senderName + " invited " + targetName + ".";
-        case 'ban':
-            return senderName + " banned " + targetName + "." + reason;
-        case 'join':
-            if (ev.getPrevContent() && ev.getPrevContent().membership == 'join') {
-                if (ev.getPrevContent().displayname && ev.getContent().displayname && ev.getPrevContent().displayname != ev.getContent().displayname) {
-                    return ev.getSender() + " changed their display name from " +
-                        ev.getPrevContent().displayname + " to " +
-                        ev.getContent().displayname;
-                } else if (!ev.getPrevContent().displayname && ev.getContent().displayname) {
-                    return ev.getSender() + " set their display name to " + ev.getContent().displayname;
-                } else if (ev.getPrevContent().displayname && !ev.getContent().displayname) {
-                    return ev.getSender() + " removed their display name";
-                } else if (ev.getPrevContent().avatar_url && !ev.getContent().avatar_url) {
-                    return ev.getSender() + " removed their profile picture";
-                } else if (ev.getPrevContent().avatar_url && ev.getContent().avatar_url && ev.getPrevContent().avatar_url != ev.getContent().avatar_url) {
-                    return ev.getSender() + " changed their profile picture";
-                } else if (!ev.getPrevContent().avatar_url && ev.getContent().avatar_url) {
-                    return ev.getSender() + " set a profile picture";
-                }
-            } else {
-                if (!ev.target) console.warn("Join message has no target! -- " + ev.getContent().state_key);
-                return targetName + " joined the room.";
-            }
-            return '';
-        case 'leave':
-            if (ev.getSender() === ev.getStateKey()) {
-                return targetName + " left the room.";
-            }
-            else if (ev.getPrevContent().membership === "ban") {
-                return senderName + " unbanned " + targetName + ".";
-            }
-            else if (ev.getPrevContent().membership === "join") {
-                return senderName + " kicked " + targetName + "." + reason;
-            }
-            else {
-                return targetName + " left the room.";
-            }
-    }
-};
-
-function textForTopicEvent(ev) {
-    var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
-
-    return senderDisplayName + ' changed the topic to, "' + ev.getContent().topic + '"';
-};
-
-function textForMessageEvent(ev) {
-    var senderDisplayName = ev.sender && ev.sender.name ? ev.sender.name : ev.getSender();
-
-    var message = senderDisplayName + ': ' + ev.getContent().body;
-    if (ev.getContent().msgtype === "m.emote") {
-        message = "* " + senderDisplayName + " " + message;
-    } else if (ev.getContent().msgtype === "m.image") {
-        message = senderDisplayName + " sent an image.";
-    }
-    return message;
-};
-
-function textForCallAnswerEvent(event) {
-    var senderName = event.sender ? event.sender.name : "Someone";
-    return senderName + " answered the call.";
-};
-
-function textForCallHangupEvent(event) {
-    var senderName = event.sender ? event.sender.name : "Someone";
-    return senderName + " ended the call.";
-};
-
-function textForCallInviteEvent(event) {
-    var senderName = event.sender ? event.sender.name : "Someone";
-    // FIXME: Find a better way to determine this from the event?
-    var type = "voice";
-    if (event.getContent().offer && event.getContent().offer.sdp &&
-            event.getContent().offer.sdp.indexOf('m=video') !== -1) {
-        type = "video";
-    }
-    return senderName + " placed a " + type + " call.";
-};
-
-var handlers = {
-    'm.room.message': textForMessageEvent,
-    'm.room.topic': textForTopicEvent,
-    'm.room.member': textForMemberEvent,
-    'm.call.invite': textForCallInviteEvent,
-    'm.call.answer': textForCallAnswerEvent,
-    'm.call.hangup': textForCallHangupEvent,
-};
-
-module.exports = {
-    textForEvent: function(ev) {
-        var hdlr = handlers[ev.getType()];
-        if (!hdlr) return "";
-        return hdlr(ev);
-    }
-}
diff --git a/src/WhoIsTyping.js b/src/WhoIsTyping.js
deleted file mode 100644
index 4fb53990..00000000
--- a/src/WhoIsTyping.js
+++ /dev/null
@@ -1,49 +0,0 @@
-var MatrixClientPeg = require("./MatrixClientPeg");
-
-module.exports = {
-    usersTypingApartFromMe: function(room) {
-        return this.usersTyping(
-            room, [MatrixClientPeg.get().credentials.userId]
-        );
-    },
-
-    /**
-     * Given a Room object and, optionally, a list of userID strings
-     * to exclude, return a list of user objects who are typing.
-     */
-    usersTyping: function(room, exclude) {
-        var whoIsTyping = [];
-
-        if (exclude === undefined) {
-            exclude = [];
-        }
-
-        var memberKeys = Object.keys(room.currentState.members);
-        for (var i = 0; i < memberKeys.length; ++i) {
-            var userId = memberKeys[i];
-
-            if (room.currentState.members[userId].typing) {
-                if (exclude.indexOf(userId) == -1) {
-                    whoIsTyping.push(room.currentState.members[userId]);
-                }
-            }
-        }
-
-        return whoIsTyping;
-    },
-
-    whoIsTypingString: function(room) {
-        var whoIsTyping = this.usersTypingApartFromMe(room);
-        if (whoIsTyping.length == 0) {
-            return null;
-        } else if (whoIsTyping.length == 1) {
-            return whoIsTyping[0].name + ' is typing';
-        } else {
-            var names = whoIsTyping.map(function(m) {
-                return m.name;
-            });
-            var lastPerson = names.shift();
-            return names.join(', ') + ' and ' + lastPerson + ' are typing';
-        }
-    }
-}
diff --git a/src/controllers/atoms/EditableText.js b/src/controllers/atoms/EditableText.js
deleted file mode 100644
index 5ea4ce8c..00000000
--- a/src/controllers/atoms/EditableText.js
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        onValueChanged: React.PropTypes.func,
-        initialValue: React.PropTypes.string,
-        label: React.PropTypes.string,
-        placeHolder: React.PropTypes.string,
-    },
-
-    Phases: {
-        Display: "display",
-        Edit: "edit",
-    },
-
-    getDefaultProps: function() {
-        return {
-            onValueChanged: function() {},
-            initialValue: '',
-            label: 'Click to set',
-            placeholder: '',
-        };
-    },
-
-    getInitialState: function() {
-        return {
-            value: this.props.initialValue,
-            phase: this.Phases.Display,
-        }
-    },
-
-    componentWillReceiveProps: function(nextProps) {
-        this.setState({
-            value: nextProps.initialValue
-        });
-    },
-
-    getValue: function() {
-        return this.state.value;
-    },
-
-    setValue: function(val, shouldSubmit, suppressListener) {
-        var self = this;
-        this.setState({
-            value: val,
-            phase: this.Phases.Display,
-        }, function() {
-            if (!suppressListener) {
-                self.onValueChanged(shouldSubmit);
-            }
-        });
-    },
-
-    edit: function() {
-        this.setState({
-            phase: this.Phases.Edit,
-        });
-    },
-
-    cancelEdit: function() {
-        this.setState({
-            phase: this.Phases.Display,
-        });
-        this.onValueChanged(false);
-    },
-
-    onValueChanged: function(shouldSubmit) {
-        this.props.onValueChanged(this.state.value, shouldSubmit);
-    },
-};
diff --git a/src/controllers/atoms/EnableNotificationsButton.js b/src/controllers/atoms/EnableNotificationsButton.js
deleted file mode 100644
index d6638b27..00000000
--- a/src/controllers/atoms/EnableNotificationsButton.js
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-var ComponentBroker = require("../../ComponentBroker");
-var Notifier = ComponentBroker.get('organisms/Notifier');
-var dis = require("../../dispatcher");
-
-module.exports = {
-
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-    },
-
-    onAction: function(payload) {
-        if (payload.action !== "notifier_enabled") {
-            return;
-        }
-        this.forceUpdate();
-    },
-
-    enabled: function() {
-        return Notifier.isEnabled();
-    },
-
-    onClick: function() {
-        var self = this;
-        if (!Notifier.supportsDesktopNotifications()) {
-            return;
-        }
-        if (!Notifier.isEnabled()) {
-            Notifier.setEnabled(true, function() {
-                self.forceUpdate();
-            });
-        } else {
-            Notifier.setEnabled(false);
-        }
-        this.forceUpdate();
-    },
-};
diff --git a/src/controllers/atoms/ImageView.js b/src/controllers/atoms/ImageView.js
deleted file mode 100644
index d0977e00..00000000
--- a/src/controllers/atoms/ImageView.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
diff --git a/src/controllers/atoms/LogoutButton.js b/src/controllers/atoms/LogoutButton.js
deleted file mode 100644
index 87cf8148..00000000
--- a/src/controllers/atoms/LogoutButton.js
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var dis = require("../../dispatcher");
-
-module.exports = {
-    onClick: function() {
-        dis.dispatch({
-            action: 'logout'
-        });
-    },
-};
diff --git a/src/controllers/atoms/MemberAvatar.js b/src/controllers/atoms/MemberAvatar.js
deleted file mode 100644
index f29b3544..00000000
--- a/src/controllers/atoms/MemberAvatar.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var Avatar = require('../../Avatar');
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        member: React.PropTypes.object.isRequired,
-        width: React.PropTypes.number,
-        height: React.PropTypes.number,
-        resizeMethod: React.PropTypes.string,
-    },
-
-    getDefaultProps: function() {
-        return {
-            width: 40,
-            height: 40,
-            resizeMethod: 'crop'
-        }
-    },
-
-    defaultAvatarUrl: function(member) {
-        return Avatar.defaultAvatarUrlForString(
-            member.userId
-        );
-    },
-
-    onError: function(ev) {
-        // don't tightloop if the browser can't load a data url
-        if (ev.target.src == this.defaultAvatarUrl(this.props.member)) {
-            return;
-        }
-        this.setState({
-            imageUrl: this.defaultAvatarUrl(this.props.member)
-        });
-    },
-
-    getInitialState: function() {
-        return {
-            imageUrl: Avatar.avatarUrlForMember(
-                this.props.member,
-                this.props.width, this.props.height,
-                this.props.resizeMethod
-            )
-        };
-    }
-};
diff --git a/src/controllers/atoms/MessageTimestamp.js b/src/controllers/atoms/MessageTimestamp.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/atoms/MessageTimestamp.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/atoms/RoomAvatar.js b/src/controllers/atoms/RoomAvatar.js
deleted file mode 100644
index 1504a776..00000000
--- a/src/controllers/atoms/RoomAvatar.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require('../../MatrixClientPeg');
-var Avatar = require('../../Avatar');
-
-module.exports = {
-    getDefaultProps: function() {
-        return {
-            width: 40,
-            height: 40,
-            resizeMethod: 'crop'
-        }
-    },
-
-    avatarUrlForRoom: function(room) {
-        var url = MatrixClientPeg.get().getAvatarUrlForRoom(
-            room,
-            this.props.width, this.props.height, this.props.resizeMethod,
-            false
-        );
-        if (url === null) {
-            url = this.defaultAvatarUrl(room);
-        }
-        return url;
-    },
-
-    defaultAvatarUrl: function(room) {
-        return Avatar.defaultAvatarUrlForString(
-            this.props.room.roomId
-        );
-    },
-
-    onError: function(ev) {
-        // don't tightloop if the browser can't load a data url
-        if (ev.target.src == this.defaultAvatarUrl(this.props.room)) {
-            return;
-        }
-        this.setState({
-            imageUrl: this.defaultAvatarUrl(this.props.room)
-        });
-    },
-
-    getInitialState: function() {
-        return {
-            imageUrl: this.avatarUrlForRoom(this.props.room)
-        };
-    }
-};
diff --git a/src/controllers/atoms/create_room/CreateRoomButton.js b/src/controllers/atoms/create_room/CreateRoomButton.js
deleted file mode 100644
index f03dd56c..00000000
--- a/src/controllers/atoms/create_room/CreateRoomButton.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        onCreateRoom: React.PropTypes.func,
-    },
-
-    getDefaultProps: function() {
-        return {
-            onCreateRoom: function() {},
-        };
-    },
-
-    onClick: function() {
-        this.props.onCreateRoom();
-    },
-};
diff --git a/src/controllers/atoms/create_room/Presets.js b/src/controllers/atoms/create_room/Presets.js
deleted file mode 100644
index bcc2f514..00000000
--- a/src/controllers/atoms/create_room/Presets.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-var Presets = {
-    PrivateChat: "private_chat",
-    PublicChat: "public_chat",
-    Custom: "custom",
-};
-
-module.exports = {
-    propTypes: {
-        onChange: React.PropTypes.func,
-        preset: React.PropTypes.string
-    },
-
-    Presets: Presets,
-
-    getDefaultProps: function() {
-        return {
-            onChange: function() {},
-        };
-    },
-};
diff --git a/src/controllers/atoms/create_room/RoomAlias.js b/src/controllers/atoms/create_room/RoomAlias.js
deleted file mode 100644
index 4b268e90..00000000
--- a/src/controllers/atoms/create_room/RoomAlias.js
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        // Specifying a homeserver will make magical things happen when you,
-        // e.g. start typing in the room alias box.
-        homeserver: React.PropTypes.string,
-        alias: React.PropTypes.string,
-        onChange: React.PropTypes.func,
-    },
-
-    getDefaultProps: function() {
-        return {
-            onChange: function() {},
-            alias: '',
-        };
-    },
-
-    getAliasLocalpart: function() {
-        var room_alias = this.props.alias;
-
-        if (room_alias && this.props.homeserver) {
-            var suffix = ":" + this.props.homeserver;
-            if (room_alias.startsWith("#") && room_alias.endsWith(suffix)) {
-                room_alias = room_alias.slice(1, -suffix.length);
-            }
-        }
-
-        return room_alias;
-    },
-};
diff --git a/src/controllers/atoms/voip/VideoFeed.js b/src/controllers/atoms/voip/VideoFeed.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/atoms/voip/VideoFeed.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/molecules/ChangeAvatar.js b/src/controllers/molecules/ChangeAvatar.js
deleted file mode 100644
index 72a541b1..00000000
--- a/src/controllers/molecules/ChangeAvatar.js
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-var MatrixClientPeg = require("../../MatrixClientPeg");
-
-var dis = require("../../dispatcher");
-
-module.exports = {
-    propTypes: {
-        onFinished: React.PropTypes.func,
-        initialAvatarUrl: React.PropTypes.string.isRequired,
-    },
-
-    Phases: {
-        Display: "display",
-        Uploading: "uploading",
-        Error: "error",
-    },
-
-    getDefaultProps: function() {
-        return {
-            onFinished: function() {},
-        };
-    },
-
-    getInitialState: function() {
-        return {
-            avatarUrl: this.props.initialAvatarUrl,
-            phase: this.Phases.Display,
-        }
-    },
-
-    setAvatarFromFile: function(file) {
-        var newUrl = null;
-
-        this.setState({
-            phase: this.Phases.Uploading
-        });
-        var self = this;
-        MatrixClientPeg.get().uploadContent(file).then(function(url) {
-            newUrl = url;
-            return MatrixClientPeg.get().setAvatarUrl(url);
-        }).done(function() {
-            self.setState({
-                phase: self.Phases.Display,
-                avatarUrl: MatrixClientPeg.get().mxcUrlToHttp(newUrl)
-            });
-        }, function(error) {
-            self.setState({
-                phase: this.Phases.Error
-            });
-            self.onError(error);
-        });
-    },
-}
diff --git a/src/controllers/molecules/ChangePassword.js b/src/controllers/molecules/ChangePassword.js
deleted file mode 100644
index 5cc73c5d..00000000
--- a/src/controllers/molecules/ChangePassword.js
+++ /dev/null
@@ -1,78 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-var MatrixClientPeg = require("../../MatrixClientPeg");
-
-var dis = require("../../dispatcher");
-
-module.exports = {
-    propTypes: {
-        onFinished: React.PropTypes.func,
-    },
-
-    Phases: {
-        Edit: "edit",
-        Uploading: "uploading",
-        Error: "error",
-        Success: "Success"
-    },
-
-    getDefaultProps: function() {
-        return {
-            onFinished: function() {},
-        };
-    },
-
-    getInitialState: function() {
-        return {
-            phase: this.Phases.Edit,
-            errorString: ''
-        }
-    },
-
-    changePassword: function(old_password, new_password) {
-        var cli = MatrixClientPeg.get();
-
-        var authDict = {
-            type: 'm.login.password',
-            user: cli.credentials.userId,
-            password: old_password
-        };
-
-        this.setState({
-            phase: this.Phases.Uploading,
-            errorString: '',
-        })
-
-        var d = cli.setPassword(authDict, new_password);
-
-        var self = this;
-        d.then(function() {
-            self.setState({
-                phase: self.Phases.Success,
-                errorString: '',
-            })
-        }, function(err) {
-            self.setState({
-                phase: self.Phases.Error,
-                errorString: err.toString()
-            })
-        });
-    },
-}
diff --git a/src/controllers/molecules/EventAsTextTile.js b/src/controllers/molecules/EventAsTextTile.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/molecules/EventAsTextTile.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/molecules/MEmoteTile.js b/src/controllers/molecules/MEmoteTile.js
deleted file mode 100644
index 1fb117ce..00000000
--- a/src/controllers/molecules/MEmoteTile.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var linkify = require('linkifyjs');
-var linkifyElement = require('linkifyjs/element');
-var linkifyMatrix = require('../../linkify-matrix');
-
-linkifyMatrix(linkify);
-
-module.exports = {
-    componentDidMount: function() {
-        linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options);
-    }
-};
-
diff --git a/src/controllers/molecules/MFileTile.js b/src/controllers/molecules/MFileTile.js
deleted file mode 100644
index bd3576e5..00000000
--- a/src/controllers/molecules/MFileTile.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var filesize = require('filesize');
-
-module.exports = {
-    presentableTextForFile: function(content) {
-        var linkText = 'Attachment';
-        if (content.body && content.body.length > 0) {
-            linkText = content.body;
-        }
-
-        var additionals = [];
-        if (content.info) {
-            if (content.info.mimetype && content.info.mimetype.length > 0) {
-                additionals.push(content.info.mimetype);
-            }
-            if (content.info.size) {
-                additionals.push(filesize(content.info.size));
-            }
-        }
-
-        if (additionals.length > 0) {
-            linkText += ' (' + additionals.join(', ') + ')';
-        }
-        return linkText;
-    }
-};
-
diff --git a/src/controllers/molecules/MImageTile.js b/src/controllers/molecules/MImageTile.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/molecules/MImageTile.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/molecules/MNoticeTile.js b/src/controllers/molecules/MNoticeTile.js
deleted file mode 100644
index aceb0294..00000000
--- a/src/controllers/molecules/MNoticeTile.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var linkify = require('linkifyjs');
-var linkifyElement = require('linkifyjs/element');
-var linkifyMatrix = require('../../linkify-matrix.js');
-linkifyMatrix(linkify);
-
-module.exports = {
-    componentDidMount: function() {
-        linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options);
-    }
-};
diff --git a/src/controllers/molecules/MTextTile.js b/src/controllers/molecules/MTextTile.js
deleted file mode 100644
index 1fb117ce..00000000
--- a/src/controllers/molecules/MTextTile.js
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var linkify = require('linkifyjs');
-var linkifyElement = require('linkifyjs/element');
-var linkifyMatrix = require('../../linkify-matrix');
-
-linkifyMatrix(linkify);
-
-module.exports = {
-    componentDidMount: function() {
-        linkifyElement(this.refs.content.getDOMNode(), linkifyMatrix.options);
-    }
-};
-
diff --git a/src/controllers/molecules/MatrixToolbar.js b/src/controllers/molecules/MatrixToolbar.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/molecules/MatrixToolbar.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/molecules/MemberInfo.js b/src/controllers/molecules/MemberInfo.js
deleted file mode 100644
index 21cbe7a5..00000000
--- a/src/controllers/molecules/MemberInfo.js
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-/*
- * State vars:
- * 'can': {
- *   kick: boolean,
- *   ban: boolean,
- *   mute: boolean,
- *   modifyLevel: boolean
- * },
- * 'muted': boolean,
- * 'isTargetMod': boolean
- */
-
-'use strict';
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var dis = require("../../dispatcher");
-var Modal = require("../../Modal");
-var ComponentBroker = require('../../ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-var QuestionDialog = ComponentBroker.get("organisms/QuestionDialog");
-var Loader = require("react-loader");
-
-module.exports = {
-    componentDidMount: function() {
-        var self = this;
-
-        // work out the current state
-        if (this.props.member) {
-            var usr = MatrixClientPeg.get().getUser(this.props.member.userId) || {};
-            var memberState = this._calculateOpsPermissions();
-            this.setState(memberState);
-        }
-    },
-
-    onKick: function() {
-        var roomId = this.props.member.roomId;
-        var target = this.props.member.userId;
-        var self = this;
-        MatrixClientPeg.get().kick(roomId, target).done(function() {
-            // NO-OP; rely on the m.room.member event coming down else we could
-            // get out of sync if we force setState here!
-            console.log("Kick success");
-        }, function(err) {
-            Modal.createDialog(ErrorDialog, {
-                title: "Kick error",
-                description: err.message
-            });
-        });
-        this.props.onFinished();
-    },
-
-    onBan: function() {
-        var roomId = this.props.member.roomId;
-        var target = this.props.member.userId;
-        var self = this;
-        MatrixClientPeg.get().ban(roomId, target).done(function() {
-            // NO-OP; rely on the m.room.member event coming down else we could
-            // get out of sync if we force setState here!
-            console.log("Ban success");
-        }, function(err) {
-            Modal.createDialog(ErrorDialog, {
-                title: "Ban error",
-                description: err.message
-            });
-        });
-        this.props.onFinished();
-    },
-
-    onMuteToggle: function() {
-        var roomId = this.props.member.roomId;
-        var target = this.props.member.userId;
-        var self = this;
-        var room = MatrixClientPeg.get().getRoom(roomId);
-        if (!room) {
-            this.props.onFinished();
-            return;
-        }
-        var powerLevelEvent = room.currentState.getStateEvents(
-            "m.room.power_levels", ""
-        );
-        if (!powerLevelEvent) {
-            this.props.onFinished();
-            return;
-        }
-        var isMuted = this.state.muted;
-        var powerLevels = powerLevelEvent.getContent();
-        var levelToSend = (
-            (powerLevels.events ? powerLevels.events["m.room.message"] : null) ||
-            powerLevels.events_default
-        );
-        var level;
-        if (isMuted) { // unmute
-            level = levelToSend;
-        }
-        else { // mute
-            level = levelToSend - 1;
-        }
-
-        MatrixClientPeg.get().setPowerLevel(roomId, target, level, powerLevelEvent).done(
-        function() {
-            // NO-OP; rely on the m.room.member event coming down else we could
-            // get out of sync if we force setState here!
-            console.log("Mute toggle success");
-        }, function(err) {
-            Modal.createDialog(ErrorDialog, {
-                title: "Mute error",
-                description: err.message
-            });
-        });
-        this.props.onFinished();        
-    },
-
-    onModToggle: function() {
-        var roomId = this.props.member.roomId;
-        var target = this.props.member.userId;
-        var room = MatrixClientPeg.get().getRoom(roomId);
-        if (!room) {
-            this.props.onFinished();
-            return;
-        }
-        var powerLevelEvent = room.currentState.getStateEvents(
-            "m.room.power_levels", ""
-        );
-        if (!powerLevelEvent) {
-            this.props.onFinished();
-            return;
-        }
-        var me = room.getMember(MatrixClientPeg.get().credentials.userId);
-        if (!me) {
-            this.props.onFinished();
-            return;
-        }
-        var defaultLevel = powerLevelEvent.getContent().users_default;
-        var modLevel = me.powerLevel - 1;
-        // toggle the level
-        var newLevel = this.state.isTargetMod ? defaultLevel : modLevel;
-        MatrixClientPeg.get().setPowerLevel(roomId, target, newLevel, powerLevelEvent).done(
-        function() {
-            // NO-OP; rely on the m.room.member event coming down else we could
-            // get out of sync if we force setState here!
-            console.log("Mod toggle success");
-        }, function(err) {
-            Modal.createDialog(ErrorDialog, {
-                title: "Mod error",
-                description: err.message
-            });
-        });
-        this.props.onFinished();        
-    },
-
-    onChatClick: function() {
-        // check if there are any existing rooms with just us and them (1:1)
-        // If so, just view that room. If not, create a private room with them.
-        var rooms = MatrixClientPeg.get().getRooms();
-        var userIds = [
-            this.props.member.userId,
-            MatrixClientPeg.get().credentials.userId
-        ];
-        var existingRoomId = null;
-        for (var i = 0; i < rooms.length; i++) {
-            var members = rooms[i].getJoinedMembers();
-            if (members.length === 2) {
-                var hasTargetUsers = true;
-                for (var j = 0; j < members.length; j++) {
-                    if (userIds.indexOf(members[j].userId) === -1) {
-                        hasTargetUsers = false;
-                        break;
-                    }
-                }
-                if (hasTargetUsers) {
-                    existingRoomId = rooms[i].roomId;
-                    break;
-                }
-            }
-        }
-
-        if (existingRoomId) {
-            dis.dispatch({
-                action: 'view_room',
-                room_id: existingRoomId
-            });
-        }
-        else {
-            MatrixClientPeg.get().createRoom({
-                invite: [this.props.member.userId],
-                preset: "private_chat"
-            }).done(function(res) {
-                dis.dispatch({
-                    action: 'view_room',
-                    room_id: res.room_id
-                });
-            }, function(err) {
-                console.error(
-                    "Failed to create room: %s", JSON.stringify(err)
-                );
-            });
-        }
-        this.props.onFinished();                
-    },
-
-    // FIXME: this is horribly duplicated with MemberTile's onLeaveClick.
-    // Not sure what the right solution to this is.
-    onLeaveClick: function() {
-        var roomId = this.props.member.roomId;
-        Modal.createDialog(QuestionDialog, {
-            title: "Leave room",
-            description: "Are you sure you want to leave the room?",
-            onFinished: function(should_leave) {
-                if (should_leave) {
-                    var d = MatrixClientPeg.get().leave(roomId);
-
-                    var modal = Modal.createDialog(Loader);
-
-                    d.then(function() {
-                        modal.close();
-                        dis.dispatch({action: 'view_next_room'});
-                    }, function(err) {
-                        modal.close();
-                        Modal.createDialog(ErrorDialog, {
-                            title: "Failed to leave room",
-                            description: err.toString()
-                        });
-                    });
-                }
-            }
-        });
-        this.props.onFinished();        
-    },
-
-    getInitialState: function() {
-        return {
-            can: {
-                kick: false,
-                ban: false,
-                mute: false,
-                modifyLevel: false
-            },
-            muted: false,
-            isTargetMod: false
-        }
-    },
-
-    _calculateOpsPermissions: function() {
-        var defaultPerms = {
-            can: {},
-            muted: false,
-            modifyLevel: false
-        };
-        var room = MatrixClientPeg.get().getRoom(this.props.member.roomId);
-        if (!room) {
-            return defaultPerms;
-        }
-        var powerLevels = room.currentState.getStateEvents(
-            "m.room.power_levels", ""
-        );
-        if (!powerLevels) {
-            return defaultPerms;
-        }
-        var me = room.getMember(MatrixClientPeg.get().credentials.userId);
-        var them = this.props.member;
-        return {
-            can: this._calculateCanPermissions(
-                me, them, powerLevels.getContent()
-            ),
-            muted: this._isMuted(them, powerLevels.getContent()),
-            isTargetMod: them.powerLevel > powerLevels.getContent().users_default
-        };
-    },
-
-    _calculateCanPermissions: function(me, them, powerLevels) {
-        var can = {
-            kick: false,
-            ban: false,
-            mute: false,
-            modifyLevel: false
-        };
-        var canAffectUser = them.powerLevel < me.powerLevel;
-        if (!canAffectUser) {
-            //console.log("Cannot affect user: %s >= %s", them.powerLevel, me.powerLevel);
-            return can;
-        }
-        var editPowerLevel = (
-            (powerLevels.events ? powerLevels.events["m.room.power_levels"] : null) ||
-            powerLevels.state_default
-        );
-        can.kick = me.powerLevel >= powerLevels.kick;
-        can.ban = me.powerLevel >= powerLevels.ban;
-        can.mute = me.powerLevel >= editPowerLevel;
-        can.modifyLevel = me.powerLevel > them.powerLevel;
-        return can;
-    },
-
-    _isMuted: function(member, powerLevelContent) {
-        if (!powerLevelContent || !member) {
-            return false;
-        }
-        var levelToSend = (
-            (powerLevelContent.events ? powerLevelContent.events["m.room.message"] : null) ||
-            powerLevelContent.events_default
-        );
-        return member.powerLevel < levelToSend;
-    }
-};
-
diff --git a/src/controllers/molecules/MemberTile.js b/src/controllers/molecules/MemberTile.js
deleted file mode 100644
index 43db7d1d..00000000
--- a/src/controllers/molecules/MemberTile.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var dis = require("../../dispatcher");
-var Modal = require("../../Modal");
-var ComponentBroker = require('../../ComponentBroker');
-var QuestionDialog = ComponentBroker.get("organisms/QuestionDialog");
-var Loader = require("react-loader");
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-
-module.exports = {
-    // onClick: function() {
-    //     dis.dispatch({
-    //         action: 'view_user',
-    //         user_id: this.props.member.userId
-    //     });
-    // },
-
-    getInitialState: function() {
-        return {
-            hover: false,
-            menu: false,
-        }
-    },
-
-    onLeaveClick: function(ev) {
-        ev.stopPropagation();
-        ev.preventDefault();
-        var roomId = this.props.member.roomId;
-        Modal.createDialog(QuestionDialog, {
-            title: "Leave room",
-            description: "Are you sure you want to leave the room?",
-            onFinished: function(should_leave) {
-                if (should_leave) {
-                    var d = MatrixClientPeg.get().leave(roomId);
-
-                    var modal = Modal.createDialog(Loader);
-
-                    d.then(function() {
-                        modal.close();
-                        dis.dispatch({action: 'view_next_room'});
-                    }, function(err) {
-                        modal.close();
-                        Modal.createDialog(ErrorDialog, {
-                            title: "Failed to leave room",
-                            description: err.toString()
-                        });
-                    });
-                }
-            }
-        });
-    }    
-};
diff --git a/src/controllers/molecules/MessageComposer.js b/src/controllers/molecules/MessageComposer.js
deleted file mode 100644
index 3bd0f7f8..00000000
--- a/src/controllers/molecules/MessageComposer.js
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var SlashCommands = require("../../SlashCommands");
-var Modal = require("../../Modal");
-var ComponentBroker = require('../../ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-
-var dis = require("../../dispatcher");
-var KeyCode = {
-    ENTER: 13,
-    TAB: 9,
-    SHIFT: 16,
-    UP: 38,
-    DOWN: 40
-};
-
-var TYPING_USER_TIMEOUT = 10000;
-var TYPING_SERVER_TIMEOUT = 30000;
-
-module.exports = {
-    componentWillMount: function() {
-        this.tabStruct = {
-            completing: false,
-            original: null,
-            index: 0
-        };
-        this.sentHistory = {
-            // The list of typed messages. Index 0 is more recent
-            data: [],
-            // The position in data currently displayed
-            position: -1,
-            // The room the history is for.
-            roomId: null,
-            // The original text before they hit UP
-            originalText: null,
-            // The textarea element to set text to.
-            element: null,
-
-            init: function(element, roomId) {
-                this.roomId = roomId;
-                this.element = element;
-                this.position = -1;
-                var storedData = window.sessionStorage.getItem(
-                    "history_" + roomId
-                );
-                if (storedData) {
-                    this.data = JSON.parse(storedData);
-                }
-                if (this.roomId) {
-                    this.setLastTextEntry();
-                }
-            },
-
-            push: function(text) {
-                // store a message in the sent history
-                this.data.unshift(text);
-                window.sessionStorage.setItem(
-                    "history_" + this.roomId,
-                    JSON.stringify(this.data)
-                );
-                // reset history position
-                this.position = -1;
-                this.originalText = null;
-            },
-
-            // move in the history. Returns true if we managed to move.
-            next: function(offset) {
-                if (this.position === -1) {
-                    // user is going into the history, save the current line.
-                    this.originalText = this.element.value;
-                }
-                else {
-                    // user may have modified this line in the history; remember it.
-                    this.data[this.position] = this.element.value;
-                }
-
-                if (offset > 0 && this.position === (this.data.length - 1)) {
-                    // we've run out of history
-                    return false;
-                }
-
-                // retrieve the next item (bounded).
-                var newPosition = this.position + offset;
-                newPosition = Math.max(-1, newPosition);
-                newPosition = Math.min(newPosition, this.data.length - 1);
-                this.position = newPosition;
-
-                if (this.position !== -1) {
-                    // show the message
-                    this.element.value = this.data[this.position];
-                }
-                else if (this.originalText !== undefined) {
-                    // restore the original text the user was typing.
-                    this.element.value = this.originalText;
-                }
-                return true;
-            },
-
-            saveLastTextEntry: function() {
-                // save the currently entered text in order to restore it later.
-                // NB: This isn't 'originalText' because we want to restore
-                // sent history items too!
-                var text = this.element.value;
-                window.sessionStorage.setItem("input_" + this.roomId, text);
-            },
-
-            setLastTextEntry: function() {
-                var text = window.sessionStorage.getItem("input_" + this.roomId);
-                if (text) {
-                    this.element.value = text;
-                }
-            }
-        };
-    },
-
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-        this.sentHistory.init(
-            this.refs.textarea.getDOMNode(),
-            this.props.room.roomId
-        );
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-        this.sentHistory.saveLastTextEntry();
-    },
-
-    onAction: function(payload) {
-        switch (payload.action) {
-            case 'focus_composer':
-                this.refs.textarea.getDOMNode().focus();
-                break;
-        }
-    },
-
-    onKeyDown: function (ev) {
-        if (ev.keyCode === KeyCode.ENTER) {
-            var input = this.refs.textarea.getDOMNode().value;
-            if (input.length === 0) {
-                ev.preventDefault();
-                return;
-            }
-            this.sentHistory.push(input);
-            this.onEnter(ev);
-        }
-        else if (ev.keyCode === KeyCode.TAB) {
-            var members = [];
-            if (this.props.room) {
-                members = this.props.room.getJoinedMembers();
-            }
-            this.onTab(ev, members);
-        }
-        else if (ev.keyCode === KeyCode.UP || ev.keyCode === KeyCode.DOWN) {
-            this.sentHistory.next(
-                ev.keyCode === KeyCode.UP ? 1 : -1
-            );
-            ev.preventDefault();
-        }
-        else if (ev.keyCode !== KeyCode.SHIFT && this.tabStruct.completing) {
-            // they're resuming typing; reset tab complete state vars.
-            this.tabStruct.completing = false;
-            this.tabStruct.index = 0;
-        }
-
-        var self = this;
-        setTimeout(function() {
-            if (self.refs.textarea && self.refs.textarea.getDOMNode().value != '') {
-                self.onTypingActivity();
-            } else {
-                self.onFinishedTyping();
-            }
-        }, 10); // XXX: what is this 10ms setTimeout doing?  Looks hacky :(
-    },
-
-    onEnter: function(ev) {
-        var contentText = this.refs.textarea.getDOMNode().value;
-
-        var cmd = SlashCommands.processInput(this.props.room.roomId, contentText);
-        if (cmd) {
-            ev.preventDefault();
-            if (!cmd.error) {
-                this.refs.textarea.getDOMNode().value = '';
-            }
-            if (cmd.promise) {
-                cmd.promise.done(function() {
-                    console.log("Command success.");
-                }, function(err) {
-                    console.error("Command failure: %s", err);
-                    Modal.createDialog(ErrorDialog, {
-                        title: "Server error",
-                        description: err.message
-                    });
-                });
-            }
-            else if (cmd.error) {
-                console.error(cmd.error);
-                Modal.createDialog(ErrorDialog, {
-                    title: "Command error",
-                    description: cmd.error
-                });
-            }
-            return;
-        }
-
-        var content = null;
-        if (/^\/me /i.test(contentText)) {
-            content = {
-                msgtype: 'm.emote',
-                body: contentText.substring(4)
-            };
-        } else {
-            content = {
-                msgtype: 'm.text',
-                body: contentText
-            };
-        }
-
-        MatrixClientPeg.get().sendMessage(this.props.room.roomId, content).then(function() {
-            dis.dispatch({
-                action: 'message_sent'
-            });
-        }, function() {
-            dis.dispatch({
-                action: 'message_send_failed'
-            });
-        });
-        this.refs.textarea.getDOMNode().value = '';
-        ev.preventDefault();
-    },
-
-    onTab: function(ev, sortedMembers) {
-        var textArea = this.refs.textarea.getDOMNode();
-        if (!this.tabStruct.completing) {
-            this.tabStruct.completing = true;
-            this.tabStruct.index = 0;
-            // cache starting text
-            this.tabStruct.original = textArea.value;
-        }
-
-        // loop in the right direction
-        if (ev.shiftKey) {
-            this.tabStruct.index --;
-            if (this.tabStruct.index < 0) {
-                // wrap to the last search match, and fix up to a real index
-                // value after we've matched.
-                this.tabStruct.index = Number.MAX_VALUE;
-            }
-        }
-        else {
-            this.tabStruct.index++;
-        }
-
-        var searchIndex = 0;
-        var targetIndex = this.tabStruct.index;
-        var text = this.tabStruct.original;
-
-        var search = /@?([a-zA-Z0-9_\-:\.]+)$/.exec(text);
-        // console.log("Searched in '%s' - got %s", text, search);
-        if (targetIndex === 0) { // 0 is always the original text
-            textArea.value = text;
-        }
-        else if (search && search[1]) {
-            // console.log("search found: " + search+" from "+text);
-            var expansion;
-
-            // FIXME: could do better than linear search here
-            for (var i=0; i<sortedMembers.length; i++) {
-                var member = sortedMembers[i];
-                if (member.name && searchIndex < targetIndex) {
-                    if (member.name.toLowerCase().indexOf(search[1].toLowerCase()) === 0) {
-                        expansion = member.name;
-                        searchIndex++;
-                    }
-                }
-            }
-
-            if (searchIndex < targetIndex) { // then search raw mxids
-                for (var i=0; i<sortedMembers.length; i++) {
-                    if (searchIndex >= targetIndex) {
-                        break;
-                    }
-                    var userId = sortedMembers[i].userId;
-                    // === 1 because mxids are @username
-                    if (userId.toLowerCase().indexOf(search[1].toLowerCase()) === 1) {
-                        expansion = userId;
-                        searchIndex++;
-                    }
-                }
-            }
-
-            if (searchIndex === targetIndex ||
-                    targetIndex === Number.MAX_VALUE) {
-                // xchat-style tab complete, add a colon if tab
-                // completing at the start of the text
-                if (search[0].length === text.length) {
-                    expansion += ": ";
-                }
-                else {
-                    expansion += " ";
-                }
-                textArea.value = text.replace(
-                    /@?([a-zA-Z0-9_\-:\.]+)$/, expansion
-                );
-                // cancel blink
-                textArea.style["background-color"] = "";
-                if (targetIndex === Number.MAX_VALUE) {
-                    // wrap the index around to the last index found
-                    this.tabStruct.index = searchIndex;
-                    targetIndex = searchIndex;
-                }
-            }
-            else {
-                // console.log("wrapped!");
-                textArea.style["background-color"] = "#faa";
-                setTimeout(function() {
-                     textArea.style["background-color"] = "";
-                }, 150);
-                textArea.value = text;
-                this.tabStruct.index = 0;
-            }
-        }
-        else {
-            this.tabStruct.index = 0;
-        }
-        // prevent the default TAB operation (typically focus shifting)
-        ev.preventDefault();
-    },
-
-    onTypingActivity: function() {
-        this.isTyping = true;
-        if (!this.userTypingTimer) {
-            this.sendTyping(true);
-        }
-        this.startUserTypingTimer();
-        this.startServerTypingTimer();
-    },
-
-    onFinishedTyping: function() {
-        this.isTyping = false;
-        this.sendTyping(false);
-        this.stopUserTypingTimer();
-        this.stopServerTypingTimer();
-    },
-
-    startUserTypingTimer: function() {
-        this.stopUserTypingTimer();
-        var self = this;
-        this.userTypingTimer = setTimeout(function() {
-            self.isTyping = false;
-            self.sendTyping(self.isTyping);
-            self.userTypingTimer = null;
-        }, TYPING_USER_TIMEOUT);
-    },
-
-    stopUserTypingTimer: function() {
-        if (this.userTypingTimer) {
-            clearTimeout(this.userTypingTimer);
-            this.userTypingTimer = null;
-        }
-    },
-
-    startServerTypingTimer: function() {
-        if (!this.serverTypingTimer) {
-            var self = this;
-            this.serverTypingTimer = setTimeout(function() {
-                if (self.isTyping) {
-                    self.sendTyping(self.isTyping);
-                    self.startServerTypingTimer();
-                }
-            }, TYPING_SERVER_TIMEOUT / 2);
-        }
-    },
-
-    stopServerTypingTimer: function() {
-        if (this.serverTypingTimer) {
-            clearTimeout(this.servrTypingTimer);
-            this.serverTypingTimer = null;
-        }
-    },
-
-    sendTyping: function(isTyping) {
-        MatrixClientPeg.get().sendTyping(
-            this.props.room.roomId,
-            this.isTyping, TYPING_SERVER_TIMEOUT
-        ).done();
-    },
-
-    refreshTyping: function() {
-        if (this.typingTimeout) {
-            clearTimeout(this.typingTimeout);
-            this.typingTimeout = null;
-        }
-
-    }
-};
-
diff --git a/src/controllers/molecules/MessageTile.js b/src/controllers/molecules/MessageTile.js
deleted file mode 100644
index 47b616e7..00000000
--- a/src/controllers/molecules/MessageTile.js
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-
-module.exports = {
-    shouldHighlight: function() {
-        var actions = MatrixClientPeg.get().getPushActionsForEvent(this.props.mxEvent);
-        if (!actions || !actions.tweaks) { return false; }
-        return actions.tweaks.highlight;
-    },
-
-    getInitialState: function() {
-        return {
-            resending: false
-        };
-    },
-
-    onResend: function() {
-        var self = this;
-        self.setState({
-            resending: true
-        });
-        MatrixClientPeg.get().resendEvent(
-            this.props.mxEvent, MatrixClientPeg.get().getRoom(
-                this.props.mxEvent.getRoomId()
-            )
-        ).finally(function() {
-            self.setState({
-                resending: false
-            });
-        })
-    }
-};
-
diff --git a/src/controllers/molecules/ProgressBar.js b/src/controllers/molecules/ProgressBar.js
deleted file mode 100644
index c711650a..00000000
--- a/src/controllers/molecules/ProgressBar.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        value: React.PropTypes.number,
-        max: React.PropTypes.number
-    },
-};
diff --git a/src/controllers/molecules/RoomHeader.js b/src/controllers/molecules/RoomHeader.js
deleted file mode 100644
index c7e023fc..00000000
--- a/src/controllers/molecules/RoomHeader.js
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-/*
- * State vars:
- * this.state.call_state = the UI state of the call (see CallHandler)
- *
- * Props:
- * room (JS SDK Room)
- */
-
-var React = require('react');
-var dis = require("../../dispatcher");
-var CallHandler = require("../../CallHandler");
-
-module.exports = {
-    propTypes: {
-        room: React.PropTypes.object.isRequired,
-        editing: React.PropTypes.bool,
-        onSettingsClick: React.PropTypes.func,
-        onSaveClick: React.PropTypes.func,
-    },
-
-    getDefaultProps: function() {
-        return {
-            editing: false,
-            onSettingsClick: function() {},
-            onSaveClick: function() {},
-        };
-    },
-
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-        if (this.props.room) {
-            var call = CallHandler.getCallForRoom(this.props.room.roomId);
-            var callState = call ? call.call_state : "ended";
-            this.setState({
-                call_state: callState
-            });
-        }
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-    },
-
-    onAction: function(payload) {
-        // don't filter out payloads for room IDs other than props.room because
-        // we may be interested in the conf 1:1 room
-        if (payload.action !== 'call_state' || !payload.room_id) {
-            return;
-        }
-        var call = CallHandler.getCallForRoom(payload.room_id);
-        var callState = call ? call.call_state : "ended";
-        this.setState({
-            call_state: callState
-        });
-    },
-
-    onVideoClick: function() {
-        dis.dispatch({
-            action: 'place_call',
-            type: "video",
-            room_id: this.props.room.roomId
-        });
-    },
-    onVoiceClick: function() {
-        dis.dispatch({
-            action: 'place_call',
-            type: "voice",
-            room_id: this.props.room.roomId
-        });
-    },
-    onHangupClick: function() {
-        var call = CallHandler.getCallForRoom(this.props.room.roomId);
-        if (!call) { return; }
-        dis.dispatch({
-            action: 'hangup',
-            // hangup the call for this room, which may not be the room in props
-            // (e.g. conferences which will hangup the 1:1 room instead)
-            room_id: call.roomId
-        });
-    }
-};
diff --git a/src/controllers/molecules/RoomSettings.js b/src/controllers/molecules/RoomSettings.js
deleted file mode 100644
index fe7cd634..00000000
--- a/src/controllers/molecules/RoomSettings.js
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        room: React.PropTypes.object.isRequired,
-    },
-
-    getInitialState: function() {
-        return {
-            power_levels_changed: false
-        };
-    }
-};
diff --git a/src/controllers/molecules/RoomTile.js b/src/controllers/molecules/RoomTile.js
deleted file mode 100644
index 78927ec5..00000000
--- a/src/controllers/molecules/RoomTile.js
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var dis = require("../../dispatcher");
-
-module.exports = {
-    onClick: function() {
-        dis.dispatch({
-            action: 'view_room',
-            room_id: this.props.room.roomId
-        });
-    },
-};
diff --git a/src/controllers/molecules/SenderProfile.js b/src/controllers/molecules/SenderProfile.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/molecules/SenderProfile.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/molecules/ServerConfig.js b/src/controllers/molecules/ServerConfig.js
deleted file mode 100644
index 3f5dd99b..00000000
--- a/src/controllers/molecules/ServerConfig.js
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-
-module.exports = {
-    propTypes: {
-        onHsUrlChanged: React.PropTypes.func,
-        onIsUrlChanged: React.PropTypes.func,
-        default_hs_url: React.PropTypes.string,
-        default_is_url: React.PropTypes.string
-    },
-
-    getDefaultProps: function() {
-        return {
-            onHsUrlChanged: function() {},
-            onIsUrlChanged: function() {},
-            defaultHsUrl: 'https://matrix.org/',
-            defaultIsUrl: 'https://matrix.org/'
-        };
-    },
-
-    getInitialState: function() {
-        return {
-            hs_url: this.props.defaultHsUrl,
-            is_url: this.props.defaultIsUrl,
-        }
-    },
-
-    hsChanged: function(ev) {
-        this.setState({hs_url: ev.target.value}, function() {
-            this.props.onHsUrlChanged(this.state.hs_url);
-        });
-    },
-
-    isChanged: function(ev) {
-        this.setState({is_url: ev.target.value}, function() {
-            this.props.onIsUrlChanged(this.state.is_url);
-        });
-    },
-
-    getHsUrl: function() {
-        return this.state.hs_url;
-    },
-
-    getIsUrl: function() {
-        return this.state.is_url;
-    },
-};
diff --git a/src/controllers/molecules/UnknownMessageTile.js b/src/controllers/molecules/UnknownMessageTile.js
deleted file mode 100644
index d0977e00..00000000
--- a/src/controllers/molecules/UnknownMessageTile.js
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
diff --git a/src/controllers/molecules/UserSelector.js b/src/controllers/molecules/UserSelector.js
deleted file mode 100644
index 67a56163..00000000
--- a/src/controllers/molecules/UserSelector.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-module.exports = {
-    propTypes: {
-        onChange: React.PropTypes.func,
-        selected_users: React.PropTypes.arrayOf(React.PropTypes.string),
-    },
-
-    getDefaultProps: function() {
-        return {
-            onChange: function() {},
-            selected: [],
-        };
-    },
-
-    addUser: function(user_id) {
-        if (this.props.selected_users.indexOf(user_id == -1)) {
-            this.props.onChange(this.props.selected_users.concat([user_id]));
-        }
-    },
-
-    removeUser: function(user_id) {
-        this.props.onChange(this.props.selected_users.filter(function(e) {
-            return e != user_id;
-        }));
-    },
-};
diff --git a/src/controllers/molecules/voip/IncomingCallBox.js b/src/controllers/molecules/voip/IncomingCallBox.js
deleted file mode 100644
index 809c0833..00000000
--- a/src/controllers/molecules/voip/IncomingCallBox.js
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var dis = require("../../../dispatcher");
-var CallHandler = require("../../../CallHandler");
-
-module.exports = {
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-    },
-
-    getInitialState: function() {
-        return {
-            incomingCall: null
-        }
-    },
-
-    onAction: function(payload) {
-        if (payload.action !== 'call_state') {
-            return;
-        }
-        var call = CallHandler.getCall(payload.room_id);
-        if (!call || call.call_state !== 'ringing') {
-            this.setState({
-                incomingCall: null,
-            });
-            this.getRingAudio().pause();
-            return;
-        }
-        if (call.call_state === "ringing") {
-            this.getRingAudio().load();
-            this.getRingAudio().play();
-        }
-        else {
-            this.getRingAudio().pause();
-        }
-
-        this.setState({
-            incomingCall: call
-        });
-    },
-
-    onAnswerClick: function() {
-        dis.dispatch({
-            action: 'answer',
-            room_id: this.state.incomingCall.roomId
-        });
-    },
-    onRejectClick: function() {
-        dis.dispatch({
-            action: 'hangup',
-            room_id: this.state.incomingCall.roomId
-        });
-    }
-};
-
diff --git a/src/controllers/molecules/voip/VideoView.js b/src/controllers/molecules/voip/VideoView.js
deleted file mode 100644
index 8aa688b2..00000000
--- a/src/controllers/molecules/voip/VideoView.js
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = {
-};
-
diff --git a/src/controllers/organisms/CreateRoom.js b/src/controllers/organisms/CreateRoom.js
deleted file mode 100644
index f6404eb2..00000000
--- a/src/controllers/organisms/CreateRoom.js
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var PresetValues = require('../atoms/create_room/Presets').Presets;
-var q = require('q');
-var encryption = require("../../encryption");
-
-module.exports = {
-    propTypes: {
-        onRoomCreated: React.PropTypes.func,
-    },
-
-    phases: {
-        CONFIG: "CONFIG",  // We're waiting for user to configure and hit create.
-        CREATING: "CREATING",  // We're sending the request.
-        CREATED: "CREATED",  // We successfully created the room.
-        ERROR: "ERROR",  // There was an error while trying to create room.
-    },
-
-    getDefaultProps: function() {
-        return {
-            onRoomCreated: function() {},
-        };
-    },
-
-    getInitialState: function() {
-        return {
-            phase: this.phases.CONFIG,
-            error_string: "",
-            is_private: true,
-            share_history: false,
-            default_preset: PresetValues.PrivateChat,
-            topic: '',
-            room_name: '',
-            invited_users: [],
-        };
-    },
-
-    onCreateRoom: function() {
-        var options = {};
-
-        if (this.state.room_name) {
-            options.name = this.state.room_name;
-        }
-
-        if (this.state.topic) {
-            options.topic = this.state.topic;
-        }
-
-        if (this.state.preset) {
-            if (this.state.preset != PresetValues.Custom) {
-                options.preset = this.state.preset;
-            } else {
-                options.initial_state = [
-                    {
-                        type: "m.room.join_rules",
-                        content: {
-                            "join_rules": this.state.is_private ? "invite" : "public"
-                        }
-                    },
-                    {
-                        type: "m.room.history_visibility",
-                        content: {
-                            "history_visibility": this.state.share_history ? "shared" : "invited"
-                        }
-                    },
-                ];
-            }
-        }
-
-        options.invite = this.state.invited_users;
-
-        var alias = this.getAliasLocalpart();
-        if (alias) {
-            options.room_alias_name = alias;
-        }
-
-        var cli = MatrixClientPeg.get();
-        if (!cli) {
-            // TODO: Error.
-            console.error("Cannot create room: No matrix client.");
-            return;
-        }
-
-        var deferred = cli.createRoom(options);
-
-        var response;
-
-        if (this.state.encrypt) {
-            deferred = deferred.then(function(res) {
-                response = res;
-                return encryption.enableEncryption(
-                    cli, response.roomId, options.invite
-                );
-            }).then(function() {
-                return q(response) }
-            );
-        }
-
-        this.setState({
-            phase: this.phases.CREATING,
-        });
-
-        var self = this;
-
-        deferred.then(function (resp) {
-            self.setState({
-                phase: self.phases.CREATED,
-            });
-            self.props.onRoomCreated(resp.room_id);
-        }, function(err) {
-            self.setState({
-                phase: self.phases.ERROR,
-                error_string: err.toString(),
-            });
-        });
-    }
-};
diff --git a/src/controllers/organisms/ErrorDialog.js b/src/controllers/organisms/ErrorDialog.js
deleted file mode 100644
index 73f66c87..00000000
--- a/src/controllers/organisms/ErrorDialog.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-
-module.exports = {
-    propTypes: {
-        title: React.PropTypes.string,
-        description: React.PropTypes.string,
-        button: React.PropTypes.string,
-        focus: React.PropTypes.bool,
-        onFinished: React.PropTypes.func.isRequired,
-    },
-
-    getDefaultProps: function() {
-        var self = this;
-        return {
-            title: "Error",
-            description: "An error has occurred.",
-            button: "OK",
-            focus: true,
-        };
-    },
-};
diff --git a/src/controllers/organisms/LogoutPrompt.js b/src/controllers/organisms/LogoutPrompt.js
deleted file mode 100644
index 8875a55c..00000000
--- a/src/controllers/organisms/LogoutPrompt.js
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var dis = require("../../dispatcher");
-
-module.exports = {
-    logOut: function() {
-        dis.dispatch({action: 'logout'});
-        if (this.props.onFinished) {
-            this.props.onFinished();
-        }
-    },
-
-    cancelPrompt: function() {
-        if (this.props.onFinished) {
-            this.props.onFinished();
-        }
-    }
-};
-
diff --git a/src/controllers/organisms/MemberList.js b/src/controllers/organisms/MemberList.js
deleted file mode 100644
index 3eef007e..00000000
--- a/src/controllers/organisms/MemberList.js
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var Modal = require("../../Modal");
-var ComponentBroker = require('../../ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-
-var INITIAL_LOAD_NUM_MEMBERS = 50;
-
-module.exports = {
-    getInitialState: function() {
-        var members = this.roomMembers(INITIAL_LOAD_NUM_MEMBERS);
-        return {
-            memberDict: members
-        };
-    },
-
-    componentWillMount: function() {
-        var cli = MatrixClientPeg.get();
-        cli.on("RoomState.members", this.onRoomStateMember);
-        cli.on("Room", this.onRoom); // invites
-    },
-
-    componentWillUnmount: function() {
-        if (MatrixClientPeg.get()) {
-            MatrixClientPeg.get().removeListener("Room", this.onRoom);
-            MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
-            MatrixClientPeg.get().removeListener("User.presence", this.userPresenceFn);
-        }
-    },
-
-    componentDidMount: function() {
-        var self = this;
-        setTimeout(function() {
-            if (!self.isMounted()) return;
-            self.setState({
-                memberDict: self.roomMembers()
-            });
-        }, 50);
-
-        // Attach a SINGLE listener for global presence changes then locate the
-        // member tile and re-render it. This is more efficient than every tile
-        // evar attaching their own listener.
-        function updateUserState(event, user) {
-            var tile = self.refs[user.userId];
-            if (tile) {
-                // update the whole list to get the order right, not just this cell...
-                self.forceUpdate();
-                // tile.forceUpdate();
-            }
-        }
-        MatrixClientPeg.get().on("User.presence", updateUserState);
-        this.userPresenceFn = updateUserState;
-    },
-    // Remember to set 'key' on a MemberList to the ID of the room it's for
-    /*componentWillReceiveProps: function(newProps) {
-    },*/
-
-    onRoom: function(room) {
-        if (room.roomId !== this.props.roomId) {
-            return;
-        }
-        // We listen for room events because when we accept an invite
-        // we need to wait till the room is fully populated with state
-        // before refreshing the member list else we get a stale list.
-        this._updateList();
-    },
-
-    onRoomStateMember: function(ev, state, member) {
-        this._updateList();
-    },
-
-    _updateList: function() {
-        var members = this.roomMembers();
-        this.setState({
-            memberDict: members
-        });
-    },
-
-    onInvite: function(inputText) {
-        var self = this;
-        // sanity check the input
-        inputText = inputText.trim(); // react requires es5-shim so we know trim() exists
-        if (inputText[0] !== '@' || inputText.indexOf(":") === -1) {
-            console.error("Bad user ID to invite: %s", inputText);
-            Modal.createDialog(ErrorDialog, {
-                title: "Invite Error",
-                description: "Malformed user ID. Should look like '@localpart:domain'"
-            });
-            return;
-        }
-        self.setState({
-            inviting: true
-        });
-        console.log("Invite %s to %s", inputText, this.props.roomId);
-        MatrixClientPeg.get().invite(this.props.roomId, inputText).done(
-        function(res) {
-            console.log("Invited");
-            self.setState({
-                inviting: false
-            });
-        }, function(err) {
-            console.error("Failed to invite: %s", JSON.stringify(err));
-            Modal.createDialog(ErrorDialog, {
-                title: "Server error whilst inviting",
-                description: err.message
-            });
-            self.setState({
-                inviting: false
-            });
-        });
-    },
-
-    roomMembers: function(limit) {
-        if (!this.props.roomId) return {};
-        var cli = MatrixClientPeg.get();
-        var room = cli.getRoom(this.props.roomId);
-        if (!room) return {};
-        var all_members = room.currentState.members;
-        var all_user_ids = Object.keys(all_members);
-
-        all_user_ids.sort(function(userIdA, userIdB) {
-            var userA = all_members[userIdA].user;
-            var userB = all_members[userIdB].user;
-
-            var latA = userA ? userA.lastActiveAgo || Number.MAX_VALUE : Number.MAX_VALUE;
-            var latB = userB ? userB.lastActiveAgo || Number.MAX_VALUE : Number.MAX_VALUE;
-
-            return latA - latB;
-        });
-
-
-        var to_display = {};
-        var count = 0;
-        for (var i = 0; i < all_user_ids.length && (limit === undefined || count < limit); ++i) {
-            var user_id = all_user_ids[i];
-            var m = all_members[user_id];
-
-            if (m.membership == 'join' || m.membership == 'invite') {
-                to_display[user_id] = m;
-                ++count;
-            }
-        }
-        return to_display;
-    }
-};
-
diff --git a/src/controllers/organisms/Notifier.js b/src/controllers/organisms/Notifier.js
deleted file mode 100644
index 0d493bf3..00000000
--- a/src/controllers/organisms/Notifier.js
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var dis = require("../../dispatcher");
-
-/*
- * Dispatches:
- * {
- *   action: "notifier_enabled",
- *   value: boolean
- * }
- */
-
-// XXX: This isn't an organism surely in the atomic sense of the word 
-// what on earth is it doing here?!
-
-module.exports = {
-    start: function() {
-        this.boundOnRoomTimeline = this.onRoomTimeline.bind(this);
-        MatrixClientPeg.get().on('Room.timeline', this.boundOnRoomTimeline);
-        this.state = { 'toolbarHidden' : false };
-    },
-
-    stop: function() {
-        if (MatrixClientPeg.get()) {
-            MatrixClientPeg.get().removeListener('Room.timeline', this.boundOnRoomTimeline);
-        }
-    },
-
-    supportsDesktopNotifications: function() {
-        return !!global.Notification;
-    },
-
-    havePermission: function() {
-        if (!this.supportsDesktopNotifications()) return false;
-        return global.Notification.permission == 'granted';
-    },
-
-    setEnabled: function(enable, callback) {
-        console.log("Notifier.setEnabled => %s", enable);
-        if(enable) {
-            if (!this.havePermission()) {
-                var self = this;
-                global.Notification.requestPermission(function() {
-                    if (callback) {
-                        callback();
-                        dis.dispatch({
-                            action: "notifier_enabled",
-                            value: true
-                        });
-                    }
-                });
-            }
-
-            if (!global.localStorage) return;
-            global.localStorage.setItem('notifications_enabled', 'true');
-
-            if (this.havePermission) {
-                dis.dispatch({
-                    action: "notifier_enabled",
-                    value: true
-                });
-            }
-        }
-        else {
-            if (!global.localStorage) return;
-            global.localStorage.setItem('notifications_enabled', 'false');
-            dis.dispatch({
-                action: "notifier_enabled",
-                value: false
-            });
-        }
-
-        this.setToolbarHidden(false);
-    },
-
-    isEnabled: function() {
-        if (!this.havePermission()) return false;
-
-        if (!global.localStorage) return true;
-
-        var enabled = global.localStorage.getItem('notifications_enabled');
-        if (enabled === null) return true;
-        return enabled === 'true';
-    },
-
-    setToolbarHidden: function(hidden) {
-        this.state.toolbarHidden = hidden;
-        dis.dispatch({
-            action: "notifier_enabled",
-            value: this.isEnabled()
-        });
-    },
-
-    isToolbarHidden: function() {
-        return this.state.toolbarHidden;
-    },
-
-    onRoomTimeline: function(ev, room, toStartOfTimeline) {
-        if (toStartOfTimeline) return;
-        if (ev.sender && ev.sender.userId == MatrixClientPeg.get().credentials.userId) return;
-
-        if (!this.isEnabled()) {
-            return;
-        }
-
-        var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
-        if (actions && actions.notify) {
-            this.displayNotification(ev, room);
-        }
-    }
-};
-
diff --git a/src/controllers/organisms/QuestionDialog.js b/src/controllers/organisms/QuestionDialog.js
deleted file mode 100644
index c890d143..00000000
--- a/src/controllers/organisms/QuestionDialog.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-
-module.exports = {
-    propTypes: {
-        title: React.PropTypes.string,
-        description: React.PropTypes.string,
-        button: React.PropTypes.string,
-        focus: React.PropTypes.bool,
-        onFinished: React.PropTypes.func.isRequired,
-    },
-
-    getDefaultProps: function() {
-        var self = this;
-        return {
-            title: "",
-            description: "",
-            button: "OK",
-            focus: true,
-        };
-    },
-};
diff --git a/src/controllers/organisms/RoomList.js b/src/controllers/organisms/RoomList.js
deleted file mode 100644
index 3933f53e..00000000
--- a/src/controllers/organisms/RoomList.js
+++ /dev/null
@@ -1,170 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require("react");
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var RoomListSorter = require("../../RoomListSorter");
-var dis = require("../../dispatcher");
-
-var ComponentBroker = require('../../ComponentBroker');
-var ConferenceHandler = require("../../ConferenceHandler");
-var CallHandler = require("../../CallHandler");
-
-var RoomTile = ComponentBroker.get("molecules/RoomTile");
-
-var HIDE_CONFERENCE_CHANS = true;
-
-module.exports = {
-    componentWillMount: function() {
-        var cli = MatrixClientPeg.get();
-        cli.on("Room", this.onRoom);
-        cli.on("Room.timeline", this.onRoomTimeline);
-        cli.on("Room.name", this.onRoomName);
-
-        var rooms = this.getRoomList();
-        this.setState({
-            roomList: rooms,
-            activityMap: {}
-        });
-    },
-
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-    },
-
-    onAction: function(payload) {
-        switch (payload.action) {
-            // listen for call state changes to prod the render method, which
-            // may hide the global CallView if the call it is tracking is dead
-            case 'call_state':
-                this._recheckCallElement(this.props.selectedRoom);
-                break;
-        }
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-        if (MatrixClientPeg.get()) {
-            MatrixClientPeg.get().removeListener("Room", this.onRoom);
-            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
-            MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
-        }
-    },
-
-    componentWillReceiveProps: function(newProps) {
-        this.state.activityMap[newProps.selectedRoom] = undefined;
-        this._recheckCallElement(newProps.selectedRoom);
-        this.setState({
-            activityMap: this.state.activityMap
-        });
-    },
-
-    onRoom: function(room) {
-        this.refreshRoomList();
-    },
-
-    onRoomTimeline: function(ev, room, toStartOfTimeline) {
-        if (toStartOfTimeline) return;
-
-        var newState = {
-            roomList: this.getRoomList()
-        };
-        if (
-            room.roomId != this.props.selectedRoom &&
-            ev.getSender() != MatrixClientPeg.get().credentials.userId)
-        {
-            var hl = 1;
-
-            var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
-            if (actions && actions.tweaks && actions.tweaks.highlight) {
-                hl = 2;
-            }
-            // obviously this won't deep copy but this shouldn't be necessary
-            var amap = this.state.activityMap;
-            amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);
-
-            newState.activityMap = amap;
-        }
-        this.setState(newState);
-    },
-
-    onRoomName: function(room) {
-        this.refreshRoomList();
-    },
-
-    refreshRoomList: function() {
-        var rooms = this.getRoomList();
-        this.setState({
-            roomList: rooms
-        });
-    },
-
-    getRoomList: function() {
-        return RoomListSorter.mostRecentActivityFirst(
-            MatrixClientPeg.get().getRooms().filter(function(room) {
-                var me = room.getMember(MatrixClientPeg.get().credentials.userId);
-                var shouldShowRoom =  (
-                    me && (me.membership == "join" || me.membership == "invite")
-                );
-                // hiding conf rooms only ever toggles shouldShowRoom to false
-                if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
-                    // we want to hide the 1:1 conf<->user room and not the group chat
-                    var joinedMembers = room.getJoinedMembers();
-                    if (joinedMembers.length === 2) {
-                        var otherMember = joinedMembers.filter(function(m) {
-                            return m.userId !== me.userId
-                        })[0];
-                        if (ConferenceHandler.isConferenceUser(otherMember)) {
-                            // console.log("Hiding conference 1:1 room %s", room.roomId);
-                            shouldShowRoom = false;
-                        }
-                    }
-                }
-                return shouldShowRoom;
-            })
-        );
-    },
-
-    _recheckCallElement: function(selectedRoomId) {
-        // if we aren't viewing a room with an ongoing call, but there is an
-        // active call, show the call element - we need to do this to make
-        // audio/video not crap out
-        var activeCall = CallHandler.getAnyActiveCall();
-        var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
-        var showCall = (activeCall && !callForRoom);
-        this.setState({
-            show_call_element: showCall
-        });
-    },
-
-    makeRoomTiles: function() {
-        var self = this;
-        return this.state.roomList.map(function(room) {
-            var selected = room.roomId == self.props.selectedRoom;
-            return (
-                <RoomTile
-                    room={room}
-                    key={room.roomId}
-                    selected={selected}
-                    unread={self.state.activityMap[room.roomId] === 1}
-                    highlight={self.state.activityMap[room.roomId] === 2}
-                />
-            );
-        });
-    }
-};
diff --git a/src/controllers/organisms/RoomView.js b/src/controllers/organisms/RoomView.js
deleted file mode 100644
index c6881de3..00000000
--- a/src/controllers/organisms/RoomView.js
+++ /dev/null
@@ -1,510 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var React = require("react");
-var q = require("q");
-var ContentMessages = require("../../ContentMessages");
-var WhoIsTyping = require("../../WhoIsTyping");
-var Modal = require("../../Modal");
-var ComponentBroker = require('../../ComponentBroker');
-
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-
-var dis = require("../../dispatcher");
-
-var PAGINATE_SIZE = 20;
-var INITIAL_SIZE = 100;
-
-var ConferenceHandler = require("../../ConferenceHandler");
-var CallHandler = require("../../CallHandler");
-var Notifier = ComponentBroker.get('organisms/Notifier');
-
-var tileTypes = {
-    'm.room.message': ComponentBroker.get('molecules/MessageTile'),
-    'm.room.member' : ComponentBroker.get('molecules/EventAsTextTile'),
-    'm.call.invite' : ComponentBroker.get('molecules/EventAsTextTile'),
-    'm.call.answer' : ComponentBroker.get('molecules/EventAsTextTile'),
-    'm.call.hangup' : ComponentBroker.get('molecules/EventAsTextTile'),
-    'm.room.topic'  : ComponentBroker.get('molecules/EventAsTextTile'),
-};
-
-var DateSeparator = ComponentBroker.get('molecules/DateSeparator');
-
-module.exports = {
-    getInitialState: function() {
-        return {
-            room: this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null,
-            messageCap: INITIAL_SIZE,
-            editingRoomSettings: false,
-            uploadingRoomSettings: false,
-            numUnreadMessages: 0,
-            draggingFile: false,
-        }
-    },
-
-    componentWillMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-        MatrixClientPeg.get().on("Room.timeline", this.onRoomTimeline);
-        MatrixClientPeg.get().on("Room.name", this.onRoomName);
-        MatrixClientPeg.get().on("RoomMember.typing", this.onRoomMemberTyping);
-        MatrixClientPeg.get().on("RoomState.members", this.onRoomStateMember);
-        this.atBottom = true;
-    },
-
-    componentWillUnmount: function() {
-        if (this.refs.messageWrapper) {
-            var messageWrapper = this.refs.messageWrapper.getDOMNode();
-            messageWrapper.removeEventListener('drop', this.onDrop);
-            messageWrapper.removeEventListener('dragover', this.onDragOver);
-            messageWrapper.removeEventListener('dragleave', this.onDragLeaveOrEnd);
-            messageWrapper.removeEventListener('dragend', this.onDragLeaveOrEnd);
-        }
-        dis.unregister(this.dispatcherRef);
-        if (MatrixClientPeg.get()) {
-            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
-            MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
-            MatrixClientPeg.get().removeListener("RoomMember.typing", this.onRoomMemberTyping);
-            MatrixClientPeg.get().removeListener("RoomState.members", this.onRoomStateMember);
-        }
-    },
-
-    onAction: function(payload) {
-        switch (payload.action) {
-            case 'message_send_failed':
-            case 'message_sent':
-                this.setState({
-                    room: MatrixClientPeg.get().getRoom(this.props.roomId)
-                });
-                this.forceUpdate();
-                break;
-            case 'notifier_enabled':
-                this.forceUpdate();
-                break;
-            case 'call_state':
-                if (CallHandler.getCallForRoom(this.props.roomId)) {
-                    // Call state has changed so we may be loading video elements
-                    // which will obscure the message log.
-                    // scroll to bottom
-                    var messageWrapper = this.refs.messageWrapper;
-                    if (messageWrapper) {
-                        messageWrapper = messageWrapper.getDOMNode();
-                        messageWrapper.scrollTop = messageWrapper.scrollHeight;
-                    }
-                }
-
-                // possibly remove the conf call notification if we're now in
-                // the conf
-                this._updateConfCallNotification();
-                break;
-        }
-    },
-
-    // MatrixRoom still showing the messages from the old room?
-    // Set the key to the room_id. Sadly you can no longer get at
-    // the key from inside the component, or we'd check this in code.
-    /*componentWillReceiveProps: function(props) {
-    },*/
-
-    onRoomTimeline: function(ev, room, toStartOfTimeline) {
-        if (!this.isMounted()) return;
-
-        // ignore anything that comes in whilst pagingating: we get one
-        // event for each new matrix event so this would cause a huge
-        // number of UI updates. Just update the UI when the paginate
-        // call returns.
-        if (this.state.paginating) return;
-
-        // no point handling anything while we're waiting for the join to finish:
-        // we'll only be showing a spinner.
-        if (this.state.joining) return;
-        if (room.roomId != this.props.roomId) return;
-
-        if (this.refs.messageWrapper) {
-            var messageWrapper = this.refs.messageWrapper.getDOMNode();
-            this.atBottom = (
-                messageWrapper.scrollHeight - messageWrapper.scrollTop <= 
-                (messageWrapper.clientHeight + 150)
-            );
-        }
-
-        var currentUnread = this.state.numUnreadMessages;
-        if (!toStartOfTimeline && 
-                (ev.getSender() !== MatrixClientPeg.get().credentials.userId)) {
-            // update unread count when scrolled up
-            if (this.atBottom) {
-                currentUnread = 0;
-            }
-            else {
-                currentUnread += 1;
-            }
-        }
-
-
-        this.setState({
-            room: MatrixClientPeg.get().getRoom(this.props.roomId),
-            numUnreadMessages: currentUnread
-        });
-
-        if (toStartOfTimeline && !this.state.paginating) {
-            this.fillSpace();
-        }
-    },
-
-    onRoomName: function(room) {
-        if (room.roomId == this.props.roomId) {
-            this.setState({
-                room: room
-            });
-        }
-    },
-
-    onRoomMemberTyping: function(ev, member) {
-        this.forceUpdate();
-    },
-
-    onRoomStateMember: function(ev, state, member) {
-        if (member.roomId !== this.props.roomId ||
-                member.userId !== ConferenceHandler.getConferenceUserIdForRoom(member.roomId)) {
-            return;
-        }
-        this._updateConfCallNotification();
-    },
-
-    _updateConfCallNotification: function() {
-        var confMember = MatrixClientPeg.get().getRoom(this.props.roomId).getMember(
-            ConferenceHandler.getConferenceUserIdForRoom(this.props.roomId)
-        );
-
-        if (!confMember) {
-            return;
-        }
-        var confCall = CallHandler.getConferenceCall(confMember.roomId);
-
-        // A conf call notification should be displayed if there is an ongoing
-        // conf call but this cilent isn't a part of it.
-        this.setState({
-            displayConfCallNotification: (
-                (!confCall || confCall.call_state === "ended") &&
-                confMember.membership === "join"
-            )
-        });
-    },
-
-    onConferenceNotificationClick: function() {
-        dis.dispatch({
-            action: 'place_call',
-            type: "video",
-            room_id: this.props.roomId
-        });
-    },
-
-    componentDidMount: function() {
-        if (this.refs.messageWrapper) {
-            var messageWrapper = this.refs.messageWrapper.getDOMNode();
-
-            messageWrapper.addEventListener('drop', this.onDrop);
-            messageWrapper.addEventListener('dragover', this.onDragOver);
-            messageWrapper.addEventListener('dragleave', this.onDragLeaveOrEnd);
-            messageWrapper.addEventListener('dragend', this.onDragLeaveOrEnd);
-
-            messageWrapper.scrollTop = messageWrapper.scrollHeight;
-
-            this.fillSpace();
-        }
-        this._updateConfCallNotification();
-    },
-
-    componentDidUpdate: function() {
-        if (!this.refs.messageWrapper) return;
-
-        var messageWrapper = this.refs.messageWrapper.getDOMNode();
-
-        if (this.state.paginating && !this.waiting_for_paginate) {
-            var heightGained = messageWrapper.scrollHeight - this.oldScrollHeight;
-            messageWrapper.scrollTop += heightGained;
-            this.oldScrollHeight = undefined;
-            if (!this.fillSpace()) {
-                this.setState({paginating: false});
-            }
-        } else if (this.atBottom) {
-            messageWrapper.scrollTop = messageWrapper.scrollHeight;
-            if (this.state.numUnreadMessages !== 0) {
-                this.setState({numUnreadMessages: 0});
-            }
-        }
-    },
-
-    fillSpace: function() {
-        if (!this.refs.messageWrapper) return;
-        var messageWrapper = this.refs.messageWrapper.getDOMNode();
-        if (messageWrapper.scrollTop < messageWrapper.clientHeight && this.state.room.oldState.paginationToken) {
-            this.setState({paginating: true});
-
-            this.oldScrollHeight = messageWrapper.scrollHeight;
-
-            if (this.state.messageCap < this.state.room.timeline.length) {
-                this.waiting_for_paginate = false;
-                var cap = Math.min(this.state.messageCap + PAGINATE_SIZE, this.state.room.timeline.length);
-                this.setState({messageCap: cap, paginating: true});
-            } else {
-                this.waiting_for_paginate = true;
-                var cap = this.state.messageCap + PAGINATE_SIZE;
-                this.setState({messageCap: cap, paginating: true});
-                var self = this;
-                MatrixClientPeg.get().scrollback(this.state.room, PAGINATE_SIZE).finally(function() {
-                    self.waiting_for_paginate = false;
-                    if (self.isMounted()) {
-                        self.setState({
-                            room: MatrixClientPeg.get().getRoom(self.props.roomId)
-                        });
-                    }
-                    // wait and set paginating to false when the component updates
-                });
-            }
-
-            return true;
-        }
-        return false;
-    },
-
-    onJoinButtonClicked: function(ev) {
-        var self = this;
-        MatrixClientPeg.get().joinRoom(this.props.roomId).then(function() {
-            self.setState({
-                joining: false,
-                room: MatrixClientPeg.get().getRoom(self.props.roomId)
-            });
-        }, function(error) {
-            self.setState({
-                joining: false,
-                joinError: error
-            });
-        });
-        this.setState({
-            joining: true
-        });
-    },
-
-    onMessageListScroll: function(ev) {
-        if (this.refs.messageWrapper) {
-            var messageWrapper = this.refs.messageWrapper.getDOMNode();
-            var wasAtBottom = this.atBottom;
-            this.atBottom = messageWrapper.scrollHeight - messageWrapper.scrollTop <= messageWrapper.clientHeight;
-            if (this.atBottom && !wasAtBottom) {
-                this.forceUpdate(); // remove unread msg count
-            }
-        }
-        if (!this.state.paginating) this.fillSpace();
-    },
-
-    onDragOver: function(ev) {
-        ev.stopPropagation();
-        ev.preventDefault();
-
-        ev.dataTransfer.dropEffect = 'none';
-
-        var items = ev.dataTransfer.items;
-        if (items.length == 1) {
-            if (items[0].kind == 'file') {
-                this.setState({ draggingFile : true });
-                ev.dataTransfer.dropEffect = 'copy';
-            }
-        }
-    },
-
-    onDrop: function(ev) {
-        ev.stopPropagation();
-        ev.preventDefault();
-        this.setState({ draggingFile : false });
-        var files = ev.dataTransfer.files;
-        if (files.length == 1) {
-            this.uploadFile(files[0]);
-        }
-    },
-
-    onDragLeaveOrEnd: function(ev) {
-        ev.stopPropagation();
-        ev.preventDefault();
-        this.setState({ draggingFile : false });
-    },
-
-    uploadFile: function(file) {
-        this.setState({
-            upload: {
-                fileName: file.name,
-                uploadedBytes: 0,
-                totalBytes: file.size
-            }
-        });
-        var self = this;
-        ContentMessages.sendContentToRoom(
-            file, this.props.roomId, MatrixClientPeg.get()
-        ).progress(function(ev) {
-            //console.log("Upload: "+ev.loaded+" / "+ev.total);
-            self.setState({
-                upload: {
-                    fileName: file.name,
-                    uploadedBytes: ev.loaded,
-                    totalBytes: ev.total
-                }
-            });
-        }).finally(function() {
-            self.setState({
-                upload: undefined
-            });
-        }).done(undefined, function() {
-            // display error message
-        });
-    },
-
-    getWhoIsTypingString: function() {
-        return WhoIsTyping.whoIsTypingString(this.state.room);
-    },
-
-    getEventTiles: function() {
-        var ret = [];
-        var count = 0;
-
-        for (var i = this.state.room.timeline.length-1; i >= 0 && count < this.state.messageCap; --i) {
-            var mxEv = this.state.room.timeline[i];
-            var TileType = tileTypes[mxEv.getType()];
-            var continuation = false;
-            var last = false;
-            var dateSeparator = null;
-            if (i == this.state.room.timeline.length - 1) {
-                last = true;
-            }
-            if (i > 0 && count < this.state.messageCap - 1) {
-                if (this.state.room.timeline[i].sender &&
-                    this.state.room.timeline[i - 1].sender &&
-                    (this.state.room.timeline[i].sender.userId ===
-                        this.state.room.timeline[i - 1].sender.userId) &&
-                    (this.state.room.timeline[i].getType() ==
-                        this.state.room.timeline[i - 1].getType())
-                    )
-                {
-                    continuation = true;
-                }
-
-                var ts0 = this.state.room.timeline[i - 1].getTs();
-                var ts1 = this.state.room.timeline[i].getTs();
-                if (new Date(ts0).toDateString() !== new Date(ts1).toDateString()) {
-                    dateSeparator = <DateSeparator key={ts1} ts={ts1}/>;
-                    continuation = false;
-                }
-            }
-            if (!TileType) continue;
-            ret.unshift(
-                // XXX: don't wrap everything in a needless li - make the TileType a li if we must :(
-                <li key={mxEv.getId()}><TileType mxEvent={mxEv} continuation={continuation} last={last}/></li>
-            );
-            if (dateSeparator) {
-                ret.unshift(dateSeparator);
-            }
-            ++count;
-        }
-        return ret;
-    },
-
-    uploadNewState: function(new_name, new_topic, new_join_rule, new_history_visibility, new_power_levels) {
-        var old_name = this.state.room.name;
-
-        var old_topic = this.state.room.currentState.getStateEvents('m.room.topic', '');
-        if (old_topic) {
-            old_topic = old_topic.getContent().topic;
-        } else {
-            old_topic = "";
-        }
-
-        var old_join_rule = this.state.room.currentState.getStateEvents('m.room.join_rules', '');
-        if (old_join_rule) {
-            old_join_rule = old_join_rule.getContent().join_rule;
-        } else {
-            old_join_rule = "invite";
-        }
-
-        var old_history_visibility = this.state.room.currentState.getStateEvents('m.room.history_visibility', '');
-        if (old_history_visibility) {
-            old_history_visibility = old_history_visibility.getContent().history_visibility;
-        } else {
-            old_history_visibility = "shared";
-        }
-
-        var deferreds = [];
-
-        if (old_name != new_name && new_name != undefined && new_name) {
-            deferreds.push(
-                MatrixClientPeg.get().setRoomName(this.state.room.roomId, new_name)
-            );
-        }
-
-        if (old_topic != new_topic && new_topic != undefined) {
-            deferreds.push(
-                MatrixClientPeg.get().setRoomTopic(this.state.room.roomId, new_topic)
-            );
-        }
-
-        if (old_join_rule != new_join_rule && new_join_rule != undefined) {
-            deferreds.push(
-                MatrixClientPeg.get().sendStateEvent(
-                    this.state.room.roomId, "m.room.join_rules", {
-                        join_rule: new_join_rule,
-                    }, ""
-                )
-            );
-        }
-
-        if (old_history_visibility != new_history_visibility && new_history_visibility != undefined) {
-            deferreds.push(
-                MatrixClientPeg.get().sendStateEvent(
-                    this.state.room.roomId, "m.room.history_visibility", {
-                        history_visibility: new_history_visibility,
-                    }, ""
-                )
-            );
-        }
-
-        if (new_power_levels) {
-            deferreds.push(
-                MatrixClientPeg.get().sendStateEvent(
-                    this.state.room.roomId, "m.room.power_levels", new_power_levels, ""
-                )
-            );
-        }
-
-        if (deferreds.length) {
-            var self = this;
-            q.all(deferreds).fail(function(err) {
-                Modal.createDialog(ErrorDialog, {
-                    title: "Failed to set state",
-                    description: err.toString()
-                });
-            }).finally(function() {
-                self.setState({
-                    uploadingRoomSettings: false,
-                });
-            });
-        } else {
-            this.setState({
-                editingRoomSettings: false,
-                uploadingRoomSettings: false,
-            });
-        }
-    }
-};
diff --git a/src/controllers/organisms/UserSettings.js b/src/controllers/organisms/UserSettings.js
deleted file mode 100644
index 4eb1fd59..00000000
--- a/src/controllers/organisms/UserSettings.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var React = require("react");
-var q = require('q');
-var dis = require("../../dispatcher");
-var version = require('../../../package.json').version;
-
-var ComponentBroker = require('../../ComponentBroker');
-
-module.exports = {
-    Phases: {
-        Loading: "loading",
-        Display: "display",
-    },
-
-    getInitialState: function() {
-        return {
-            displayName: null,
-            avatarUrl: null,
-            threePids: [],
-            clientVersion: version,
-            phase: this.Phases.Loading,
-        };
-    },
-
-    changeDisplayname: function(new_displayname) {
-        if (this.state.displayName == new_displayname) return;
-
-        var self = this;
-        return MatrixClientPeg.get().setDisplayName(new_displayname).then(
-            function() { self.setState({displayName: new_displayname}); },
-            function(err) { console.err(err); }
-        );
-    },
-
-    componentWillMount: function() {
-        var self = this;
-        var cli = MatrixClientPeg.get();
-
-        var profile_d = cli.getProfileInfo(cli.credentials.userId);
-        var threepid_d = cli.getThreePids();
-
-        q.all([profile_d, threepid_d]).then(
-            function(resps) {
-                self.setState({
-                    displayName: resps[0].displayname,
-                    avatarUrl: resps[0].avatar_url,
-                    threepids: resps[1].threepids,
-                    phase: self.Phases.Display,
-                });
-            },
-            function(err) { console.err(err); }
-        );
-    }
-}
diff --git a/src/controllers/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js
deleted file mode 100644
index 08cc652d..00000000
--- a/src/controllers/pages/MatrixChat.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-// should be atomised
-var Loader = require("react-loader");
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var RoomListSorter = require("../../RoomListSorter");
-var Presence = require("../../Presence");
-var dis = require("../../dispatcher");
-var q = require("q");
-
-var ComponentBroker = require('../../ComponentBroker');
-var Notifier = ComponentBroker.get('organisms/Notifier');
-var MatrixTools = require('../../MatrixTools');
-
-module.exports = {
-    PageTypes: {
-        RoomView: "room_view",
-        UserSettings: "user_settings",
-        CreateRoom: "create_room",
-        RoomDirectory: "room_directory",
-    },
-
-    AuxPanel: {
-        RoomSettings: "room_settings",
-    },
-
-    getInitialState: function() {
-        var s = {
-            logged_in: !!(MatrixClientPeg.get() && MatrixClientPeg.get().credentials),
-            ready: false,
-            aux_panel: null,
-        };
-        if (s.logged_in) {
-            if (MatrixClientPeg.get().getRooms().length) {
-                s.page_type = this.PageTypes.RoomView;
-            } else {
-                s.page_type = this.PageTypes.RoomDirectory;
-            }
-        }
-        return s;
-    },
-
-    componentDidMount: function() {
-        this.dispatcherRef = dis.register(this.onAction);
-        if (this.state.logged_in) {
-            this.startMatrixClient();
-        }
-        this.focusComposer = false;
-        document.addEventListener("keydown", this.onKeyDown);
-        window.addEventListener("focus", this.onFocus);
-        if (this.state.logged_in) {
-            this.notifyNewScreen('');
-        } else {
-            this.notifyNewScreen('login');
-        }
-    },
-
-    componentWillUnmount: function() {
-        dis.unregister(this.dispatcherRef);
-        document.removeEventListener("keydown", this.onKeyDown);
-        window.removeEventListener("focus", this.onFocus);
-    },
-
-    componentDidUpdate: function() {
-        if (this.focusComposer) {
-            dis.dispatch({action: 'focus_composer'});
-            this.focusComposer = false;
-        }
-    },
-
-    onAction: function(payload) {
-        var roomIndexDelta = 1;
-
-        switch (payload.action) {
-            case 'logout':
-                this.replaceState({
-                    logged_in: false,
-                    ready: false
-                });
-                if (window.localStorage) {
-                    window.localStorage.clear();
-                }
-                Notifier.stop();
-                Presence.stop();
-                MatrixClientPeg.get().stopClient();
-                MatrixClientPeg.get().removeAllListeners();
-                MatrixClientPeg.unset();
-                this.notifyNewScreen('');
-                break;
-            case 'start_registration':
-                if (this.state.logged_in) return;
-                var newState = payload.params || {};
-                newState.screen = 'register';
-                if (
-                    payload.params &&
-                    payload.params.client_secret &&
-                    payload.params.session_id &&
-                    payload.params.hs_url &&
-                    payload.params.is_url &&
-                    payload.params.sid
-                ) {
-                    newState.register_client_secret = payload.params.client_secret;
-                    newState.register_session_id = payload.params.session_id;
-                    newState.register_hs_url = payload.params.hs_url;
-                    newState.register_is_url = payload.params.is_url;
-                    newState.register_id_sid = payload.params.sid;
-                }
-                this.replaceState(newState);
-                this.notifyNewScreen('register');
-                break;
-            case 'start_login':
-                if (this.state.logged_in) return;
-                this.replaceState({
-                    screen: 'login'
-                });
-                this.notifyNewScreen('login');
-                break;
-            case 'view_room':
-                this.focusComposer = true;
-                this.setState({
-                    currentRoom: payload.room_id,
-                    page_type: this.PageTypes.RoomView,
-                });
-                if (this.sdkReady) {
-                    // if the SDK is not ready yet, remember what room
-                    // we're supposed to be on but don't notify about
-                    // the new screen yet (we won't be showing it yet)
-                    // The normal case where this happens is navigating
-                    // to the room in the URL bar on page load.
-                    var presentedId = payload.room_id;
-                    var room = MatrixClientPeg.get().getRoom(payload.room_id);
-                    if (room) {
-                        var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
-                        if (theAlias) presentedId = theAlias;
-                    }
-                    this.notifyNewScreen('room/'+presentedId);
-                }
-                break;
-            case 'view_prev_room':
-                roomIndexDelta = -1;
-            case 'view_next_room':
-                var allRooms = RoomListSorter.mostRecentActivityFirst(
-                    MatrixClientPeg.get().getRooms()
-                );
-                var roomIndex = -1;
-                for (var i = 0; i < allRooms.length; ++i) {
-                    if (allRooms[i].roomId == this.state.currentRoom) {
-                        roomIndex = i;
-                        break;
-                    }
-                }
-                roomIndex = (roomIndex + roomIndexDelta) % allRooms.length;
-                if (roomIndex < 0) roomIndex = allRooms.length - 1;
-                this.focusComposer = true;
-                this.setState({
-                    currentRoom: allRooms[roomIndex].roomId
-                });
-                this.notifyNewScreen('room/'+allRooms[roomIndex].roomId);
-                break;
-            case 'view_indexed_room':
-                var allRooms = RoomListSorter.mostRecentActivityFirst(
-                    MatrixClientPeg.get().getRooms()
-                );
-                var roomIndex = payload.roomIndex;
-                if (allRooms[roomIndex]) {
-                    this.focusComposer = true;
-                    this.setState({
-                        currentRoom: allRooms[roomIndex].roomId
-                    });
-                    this.notifyNewScreen('room/'+allRooms[roomIndex].roomId);
-                }
-                break;
-            case 'view_user_settings':
-                this.setState({
-                    page_type: this.PageTypes.UserSettings,
-                });
-                break;
-            case 'view_create_room':
-                this.setState({
-                    page_type: this.PageTypes.CreateRoom,
-                });
-                break;
-            case 'view_room_directory':
-                this.setState({
-                    page_type: this.PageTypes.RoomDirectory,
-                });
-                break;
-            case 'notifier_enabled':
-                this.forceUpdate();
-                break;
-        }
-    },
-
-    onLoggedIn: function() {
-        this.setState({
-            screen: undefined,
-            logged_in: true
-        });
-        this.startMatrixClient();
-        this.notifyNewScreen('');
-    },
-
-    startMatrixClient: function() {
-        var cli = MatrixClientPeg.get();
-        var self = this;
-        cli.on('syncComplete', function() {
-            self.sdkReady = true;
-            if (!self.state.currentRoom) {
-                var firstRoom = null;
-                if (cli.getRooms() && cli.getRooms().length) {
-                    firstRoom = RoomListSorter.mostRecentActivityFirst(
-                        cli.getRooms()
-                    )[0].roomId;
-                    self.setState({ready: true, currentRoom: firstRoom, page_type: self.PageTypes.RoomView});
-                } else {
-                    self.setState({ready: true, page_type: self.PageTypes.RoomDirectory});
-                }
-            } else {
-                self.setState({ready: true, currentRoom: self.state.currentRoom});
-            }
-
-            // we notifyNewScreen now because now the room will actually be displayed,
-            // and (mostly) now we can get the correct alias.
-            var presentedId = self.state.currentRoom;
-            var room = MatrixClientPeg.get().getRoom(self.state.currentRoom);
-            if (room) {
-                var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
-                if (theAlias) presentedId = theAlias;
-            }
-            self.notifyNewScreen('room/'+presentedId);
-            dis.dispatch({action: 'focus_composer'});
-        });
-        cli.on('Call.incoming', function(call) {
-            dis.dispatch({
-                action: 'incoming_call',
-                call: call
-            });
-        });
-        Notifier.start();
-        Presence.start();
-        cli.startClient();
-    },
-
-    onKeyDown: function(ev) {
-        if (ev.altKey) {
-            if (ev.ctrlKey && ev.keyCode > 48 && ev.keyCode < 58) {
-                dis.dispatch({
-                    action: 'view_indexed_room',
-                    roomIndex: ev.keyCode - 49,
-                });
-                ev.stopPropagation();
-                ev.preventDefault();
-                return;                
-            }
-            switch (ev.keyCode) {
-                case 38:
-                    dis.dispatch({action: 'view_prev_room'});
-                    ev.stopPropagation();
-                    ev.preventDefault();
-                    break;
-                case 40:
-                    dis.dispatch({action: 'view_next_room'});
-                    ev.stopPropagation();
-                    ev.preventDefault();
-                    break;
-            }
-        }
-    },
-
-    onFocus: function(ev) {
-        dis.dispatch({action: 'focus_composer'});
-    },
-
-    showScreen: function(screen, params) {
-        if (screen == 'register') {
-            dis.dispatch({
-                action: 'start_registration',
-                params: params
-            });
-        } else if (screen == 'login') {
-            dis.dispatch({
-                action: 'start_login',
-                params: params
-            });
-        } else if (screen.indexOf('room/') == 0) {
-            var roomString = screen.split('/')[1];
-            var defer = q.defer();
-            if (roomString[0] == '#') {
-                var self = this;
-                MatrixClientPeg.get().getRoomIdForAlias(roomString).done(function(result) {
-                    if (self.sdkReady) self.setState({ready: true});
-                    defer.resolve(result.room_id);
-                }, function() {
-                    if (self.sdkReady) self.setState({ready: true});
-                    defer.resolve(null);
-                });
-                this.setState({ready: false});
-            } else {
-                defer.resolve(roomString);
-            }
-            defer.promise.done(function(roomId) {
-                dis.dispatch({
-                    action: 'view_room',
-                    room_id: roomId
-                });
-            });
-        }
-    },
-
-    notifyNewScreen: function(screen) {
-        if (this.props.onNewScreen) {
-            this.props.onNewScreen(screen);
-        }
-    }
-};
diff --git a/src/controllers/templates/Login.js b/src/controllers/templates/Login.js
deleted file mode 100644
index f3528e33..00000000
--- a/src/controllers/templates/Login.js
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var Matrix = require("matrix-js-sdk");
-var dis = require("../../dispatcher");
-
-var ComponentBroker = require("../../ComponentBroker");
-
-module.exports = {
-    getInitialState: function() {
-        return {
-            step: 'choose_hs',
-            busy: false,
-            currentStep: 0,
-            totalSteps: 1
-        };
-    },
-
-    setStep: function(step) {
-        this.setState({ step: step, busy: false });
-    },
-
-    onHSChosen: function() {
-        MatrixClientPeg.replaceUsingUrls(
-            this.getHsUrl(),
-            this.getIsUrl()
-        );
-        this.setState({
-            hs_url: this.getHsUrl(),
-            is_url: this.getIsUrl(),
-        });
-        this.setStep("fetch_stages");
-        var cli = MatrixClientPeg.get();
-        this.setState({
-            busy: true,
-            errorText: "",
-        });
-        var self = this;
-        cli.loginFlows().done(function(result) {
-            self.setState({
-                flows: result.flows,
-                currentStep: 1,
-                totalSteps: result.flows.length+1
-            });
-            self.setStep('stage_'+result.flows[0].type);
-        }, function(error) {
-            self.setStep("choose_hs");
-            self.setState({errorText: 'Unable to contact the given Home Server'});
-        });
-    },
-
-    onUserPassEntered: function(ev) {
-        ev.preventDefault();
-        this.setState({
-            busy: true,
-            errorText: "",
-        });
-        var self = this;
-
-        var formVals = this.getFormVals();
-
-        var loginParams = {
-            password: formVals.password
-        };
-        if (formVals.username.indexOf('@') > 0) {
-            loginParams.medium = 'email';
-            loginParams.address = formVals.username;
-        } else {
-            loginParams.user = formVals.username;
-        }
-
-        MatrixClientPeg.get().login('m.login.password', loginParams).done(function(data) {
-            MatrixClientPeg.replaceUsingAccessToken(
-                self.state.hs_url, self.state.is_url,
-                data.user_id, data.access_token
-            );
-            if (self.props.onLoggedIn) {
-                self.props.onLoggedIn();
-            }
-        }, function(error) {
-            self.setStep("stage_m.login.password");
-            if (error.httpStatus == 400 && loginParams.medium) {
-                self.setState({errorText: 'This Home Server does not support login using email address.'});
-            } else {
-                self.setState({errorText: 'Login failed.'});
-            }
-        });
-    },
-
-    showRegister: function(ev) {
-        ev.preventDefault();
-        dis.dispatch({
-            action: 'start_registration'
-        });
-    }
-};
diff --git a/src/controllers/templates/Register.js b/src/controllers/templates/Register.js
deleted file mode 100644
index 5ed5d7dc..00000000
--- a/src/controllers/templates/Register.js
+++ /dev/null
@@ -1,347 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var React = require('react');
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var Matrix = require("matrix-js-sdk");
-var dis = require("../../dispatcher");
-
-var ComponentBroker = require("../../ComponentBroker");
-
-module.exports = {
-    FieldErrors: {
-        PasswordMismatch: 'PasswordMismatch',
-        TooShort: 'TooShort',
-        Missing: 'Missing',
-        InUse: 'InUse'
-    },
-
-    getInitialState: function() {
-        return {
-            step: 'initial',
-            busy: false,
-            currentStep: 0,
-            totalSteps: 1
-        };
-    },
-
-    componentWillMount: function() {
-        this.savedParams = {
-            email: '',
-            username: '',
-            password: '',
-            confirmPassword: ''
-        };
-        this.readNewProps();
-    },
-
-    componentWillReceiveProps: function() {
-        this.readNewProps();
-    },
-
-    readNewProps: function() {
-        if (this.props.clientSecret && this.props.hsUrl &&
-                this.props.isUrl && this.props.sessionId &&
-                this.props.idSid) {
-            this.authSessionId = this.props.sessionId;
-            MatrixClientPeg.replaceUsingUrls(
-                this.props.hsUrl,
-                this.props.isUrl
-            );
-            this.setState({
-                hs_url: this.props.hsUrl,
-                is_url: this.props.isUrl
-            });
-            this.savedParams = {client_secret: this.props.clientSecret};
-            this.setState({busy: true});
-
-            var isLocation = document.createElement('a');
-            isLocation.href = this.props.isUrl;
-
-            var auth = {
-                type: 'm.login.email.identity',
-                threepid_creds: {
-                    sid: this.props.idSid,
-                    client_secret: this.savedParams.client_secret,
-                    id_server: isLocation.host
-                }
-            };
-            this.tryRegister(auth);
-        }
-    },
-
-    componentDidUpdate: function() {
-        // Just putting a script tag into the returned jsx doesn't work, annoyingly,
-        // so we do this instead.
-        if (this.refs.recaptchaContainer) {
-            var scriptTag = document.createElement('script');
-            window.mx_on_recaptcha_loaded = this.onCaptchaLoaded;
-            scriptTag.setAttribute('src', "https://www.google.com/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit");
-            this.refs.recaptchaContainer.getDOMNode().appendChild(scriptTag);
-        }
-    },
-
-    setStep: function(step) {
-        this.setState({ step: step, errorText: '', busy: false });
-    },
-
-    getSupportedStageTypes: function() {
-        return ['m.login.email.identity', 'm.login.recaptcha'];
-    },
-
-    chooseFlow: function(flows) {
-        // this is fairly simple right now
-        var supportedTypes = this.getSupportedStageTypes();
-
-        var emailFlow = null;
-        var otherFlow = null;
-        for (var flowI = 0; flowI < flows.length; ++flowI) {
-            var flow = flows[flowI];
-            var flowHasEmail = false;
-            var flowSupported = true;
-            for (var stageI = 0; stageI < flow.stages.length; ++stageI) {
-                var stage = flow.stages[stageI];
-
-                if (supportedTypes.indexOf(stage) == -1) {
-                    flowSupported = false;
-                }
-
-                if (stage == 'm.login.email.identity') {
-                    flowHasEmail = true;
-                }
-            }
-            if (flowSupported) {
-                if (flowHasEmail) {
-                    emailFlow = flow;
-                } else {
-                    otherFlow = flow;
-                }
-            }
-        }
-
-        if (
-            this.savedParams.email != '' ||
-            this.completedStages.indexOf('m.login.email.identity') > -1
-        ) {
-            return emailFlow;
-        } else {
-            return otherFlow;
-        }
-    },
-
-    firstUncompletedStageIndex: function(flow) {
-        if (this.completedStages === undefined) return 0;
-        for (var i = 0; i < flow.stages.length; ++i) {
-            if (this.completedStages.indexOf(flow.stages[i]) == -1) {
-                return i;
-            }
-        }
-    },
-
-    numCompletedStages: function(flow) {
-        if (this.completedStages === undefined) return 0;
-        var nCompleted = 0;
-        for (var i = 0; i < flow.stages.length; ++i) {
-            if (this.completedStages.indexOf(flow.stages[i]) > -1) {
-                ++nCompleted;
-            }
-        }
-        return nCompleted;
-    },
-
-    onInitialStageSubmit: function(ev) {
-        ev.preventDefault();
-
-        var formVals = this.getRegFormVals();
-        this.savedParams = formVals;
-
-        var badFields = {};
-        if (formVals.password != formVals.confirmPassword) {
-            badFields.confirmPassword = this.FieldErrors.PasswordMismatch;
-        }
-        if (formVals.password == '') {
-            badFields.password = this.FieldErrors.Missing;
-        } else if (formVals.password.length < 6) {
-            badFields.password = this.FieldErrors.Length;
-        }
-        if (formVals.username == '') {
-            badFields.username = this.FieldErrors.Missing;
-        }
-        if (Object.keys(badFields).length > 0) {
-            this.onBadFields(badFields);
-            return;
-        }
-
-        MatrixClientPeg.replaceUsingUrls(
-            this.getHsUrl(),
-            this.getIsUrl()
-        );
-        this.setState({
-            hs_url: this.getHsUrl(),
-            is_url: this.getIsUrl()
-        });
-        var cli = MatrixClientPeg.get();
-        this.setState({busy: true});
-        var self = this;
-
-        this.tryRegister();
-    },
-
-    startStage: function(stageName) {
-        var self = this;
-        this.setStep('stage_'+stageName);
-        switch(stageName) {
-            case 'm.login.email.identity':
-                self.setState({
-                    busy: true
-                });
-                var cli = MatrixClientPeg.get();
-                this.savedParams.client_secret = cli.generateClientSecret();
-                this.savedParams.send_attempt = 1;
-
-                var nextLink = this.props.registrationUrl +
-                               '?client_secret=' +
-                               encodeURIComponent(this.savedParams.client_secret) +
-                               "&hs_url=" +
-                               encodeURIComponent(this.state.hs_url) +
-                               "&is_url=" +
-                               encodeURIComponent(this.state.is_url) +
-                               "&session_id=" +
-                               encodeURIComponent(this.authSessionId);
-
-                cli.requestEmailToken(
-                    this.savedParams.email,
-                    this.savedParams.client_secret,
-                    this.savedParams.send_attempt,
-                    nextLink
-                ).done(function(response) {
-                    self.setState({
-                        busy: false,
-                    });
-                    self.setStep('stage_m.login.email.identity');
-                }, function(error) {
-                    self.setStep('initial');
-                    var newState = {busy: false};
-                    if (error.errcode == 'THREEPID_IN_USE') {
-                        self.onBadFields({email: self.FieldErrors.InUse});
-                    } else {
-                        newState.errorText = 'Unable to contact the given Home Server';
-                    }
-                    self.setState(newState);
-                });
-                break;
-            case 'm.login.recaptcha':
-                if (!this.authParams || !this.authParams['m.login.recaptcha'].public_key) {
-                    this.setState({
-                        errorText: "This server has not supplied enough information for Recaptcha authentication"
-                    });
-                }
-                break;
-        }
-    },
-
-    onRegistered: function(user_id, access_token) {
-        MatrixClientPeg.replaceUsingAccessToken(
-            this.state.hs_url, this.state.is_url, user_id, access_token
-        );
-        if (this.props.onLoggedIn) {
-            this.props.onLoggedIn();
-        }
-    },
-
-    onCaptchaLoaded: function() {
-        if (this.refs.recaptchaContainer) {
-            var sitekey = this.authParams['m.login.recaptcha'].public_key;
-            global.grecaptcha.render('mx_recaptcha', {
-                'sitekey': sitekey,
-                'callback': this.onCaptchaDone
-            });
-        }
-    },
-
-    onCaptchaDone: function(captcha_response) {
-        this.tryRegister({
-            type: 'm.login.recaptcha',
-            response: captcha_response
-        });
-    },
-
-    tryRegister: function(auth) {
-        var self = this;
-        MatrixClientPeg.get().register(
-            this.savedParams.username,
-            this.savedParams.password,
-            this.authSessionId,
-            auth
-        ).done(function(result) {
-            self.onRegistered(result.user_id, result.access_token);
-        }, function(error) {
-            if (error.httpStatus == 401 && error.data.flows) {
-                self.authParams = error.data.params;
-                self.authSessionId = error.data.session;
-
-                self.completedStages = error.data.completed || [];
-
-                var flow = self.chooseFlow(error.data.flows);
-
-                var flowStage = self.firstUncompletedStageIndex(flow);
-                var numDone = self.numCompletedStages(flow);
-
-                self.setState({
-                    busy: false,
-                    flows: flow,
-                    currentStep: 1+numDone,
-                    totalSteps: flow.stages.length+1,
-                    flowStage: flowStage
-                });
-                self.startStage(flow.stages[flowStage]);
-            } else {
-                self.setStep("initial");
-                var newState = {
-                    busy: false,
-                    errorText: "Unable to contact the given Home Server"
-                };
-                if (error.name == 'M_USER_IN_USE') {
-                    delete newState.errorText;
-                    self.onBadFields({
-                        username: self.FieldErrors.InUse
-                    });
-                } else if (error.httpStatus == 401) {
-                    newState.errorText = "Authorisation failed!";
-                } else if (error.httpStatus >= 400 && error.httpStatus < 500) {
-                    newState.errorText = "Registration failed!";
-                } else if (error.httpStatus >= 500 && error.httpStatus < 600) {
-                    newState.errorText = "Server error during registration!";
-                } else if (error.name == "M_MISSING_PARAM") {
-                    // The HS hasn't remembered the login params from
-                    // the first try when the login email was sent.
-                    newState.errorText = "This home server does not support resuming registration.";
-                }
-                self.setState(newState);
-            }
-        });
-    },
-
-    showLogin: function(ev) {
-        ev.preventDefault();
-        dis.dispatch({
-            action: 'start_login'
-        });
-    }
-};
diff --git a/src/dispatcher.js b/src/dispatcher.js
deleted file mode 100644
index 3edb9c69..00000000
--- a/src/dispatcher.js
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var flux = require("flux");
-var extend = require("./extend");
-
-var MatrixDispatcher = function() {
-    flux.Dispatcher.call(this);
-};
-
-extend(MatrixDispatcher.prototype, flux.Dispatcher.prototype);
-MatrixDispatcher.prototype.dispatch = function(payload) {
-    if (this.dispatching) {
-        setTimeout(flux.Dispatcher.prototype.dispatch.bind(this, payload), 0);
-    } else {
-        this.dispatching = true;
-        flux.Dispatcher.prototype.dispatch.call(this, payload);
-        this.dispatching = false;
-    }
-}
-
-module.exports = new MatrixDispatcher();
diff --git a/src/encryption.js b/src/encryption.js
deleted file mode 100644
index dea454a3..00000000
--- a/src/encryption.js
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-function enableEncyption(client, roomId, members) {
-    members = members.slice(0);
-    members.push(client.credentials.userId);
-    // TODO: Check the keys actually match what keys the user has.
-    // TODO: Don't redownload keys each time.
-    return client.downloadKeys(members, "forceDownload").then(function(res) {
-        return client.setRoomEncryption(roomId, {
-            algorithm: "m.olm.v1.curve25519-aes-sha2",
-            members: members,
-        });
-    })
-}
-
-function disableEncryption(client, roomId) {
-    return client.disableRoomEncryption(roomId);
-}
-
-
-module.exports = {
-    enableEncryption: enableEncyption,
-    disableEncryption: disableEncryption,
-}
diff --git a/src/extend.js b/src/extend.js
deleted file mode 100644
index 178748d7..00000000
--- a/src/extend.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports = function(dest, src) {
-    for (var i in src) {
-        if (src.hasOwnProperty(i)) {
-            dest[i] = src[i];
-        }
-    }
-    return dest;
-}
diff --git a/src/index.js b/src/index.js
deleted file mode 100644
index febf8d0d..00000000
--- a/src/index.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-module.exports.MatrixChat = require("../skins/base/views/pages/MatrixChat");
diff --git a/src/linkify-matrix.js b/src/linkify-matrix.js
deleted file mode 100644
index 273fe123..00000000
--- a/src/linkify-matrix.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-var extend = require('./extend');
-
-function matrixLinkify(linkify) {
-    // Text tokens
-    var TT = linkify.scanner.TOKENS;
-    var TextToken = TT.Base;
-    // Multi tokens
-    var MT = linkify.parser.TOKENS;
-    var MultiToken = MT.Base;
-    var S_START = linkify.parser.start;
-
-
-    var ROOMALIAS = function(value) {
-        MultiToken.call(this, value);
-        this.type = 'roomalias';
-        this.isLink = true;
-    };
-    ROOMALIAS.prototype = new MultiToken();
-
-    var S_HASH = new linkify.parser.State();
-    var S_HASH_NAME = new linkify.parser.State();
-    var S_HASH_NAME_COLON = new linkify.parser.State();
-    var S_HASH_NAME_COLON_DOMAIN = new linkify.parser.State();
-    var S_HASH_NAME_COLON_DOMAIN_DOT = new linkify.parser.State();
-    var S_ROOMALIAS = new linkify.parser.State(ROOMALIAS);
-
-    var roomname_tokens = [
-        TT.DOT,
-        TT.PLUS,
-        TT.NUM,
-        TT.DOMAIN,
-        TT.TLD
-    ];
-
-    S_START.on(TT.POUND, S_HASH);
-
-    S_HASH.on(roomname_tokens, S_HASH_NAME);
-    S_HASH_NAME.on(roomname_tokens, S_HASH_NAME);
-    S_HASH_NAME.on(TT.DOMAIN, S_HASH_NAME);
-
-    S_HASH_NAME.on(TT.COLON, S_HASH_NAME_COLON);
-
-    S_HASH_NAME_COLON.on(TT.DOMAIN, S_HASH_NAME_COLON_DOMAIN);
-    S_HASH_NAME_COLON_DOMAIN.on(TT.DOT, S_HASH_NAME_COLON_DOMAIN_DOT);
-    S_HASH_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_HASH_NAME_COLON_DOMAIN);
-    S_HASH_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_ROOMALIAS);
-
-
-    var USERID = function(value) {
-        MultiToken.call(this, value);
-        this.type = 'userid';
-        this.isLink = true;
-    };
-    USERID.prototype = new MultiToken();
-
-    var S_AT = new linkify.parser.State();
-    var S_AT_NAME = new linkify.parser.State();
-    var S_AT_NAME_COLON = new linkify.parser.State();
-    var S_AT_NAME_COLON_DOMAIN = new linkify.parser.State();
-    var S_AT_NAME_COLON_DOMAIN_DOT = new linkify.parser.State();
-    var S_USERID = new linkify.parser.State(USERID);
-
-    var username_tokens = [
-        TT.DOT,
-        TT.PLUS,
-        TT.NUM,
-        TT.DOMAIN,
-        TT.TLD
-    ];
-
-    S_START.on(TT.AT, S_AT);
-
-    S_AT.on(username_tokens, S_AT_NAME);
-    S_AT_NAME.on(username_tokens, S_AT_NAME);
-    S_AT_NAME.on(TT.DOMAIN, S_AT_NAME);
-
-    S_AT_NAME.on(TT.COLON, S_AT_NAME_COLON);
-
-    S_AT_NAME_COLON.on(TT.DOMAIN, S_AT_NAME_COLON_DOMAIN);
-    S_AT_NAME_COLON_DOMAIN.on(TT.DOT, S_AT_NAME_COLON_DOMAIN_DOT);
-    S_AT_NAME_COLON_DOMAIN_DOT.on(TT.DOMAIN, S_AT_NAME_COLON_DOMAIN);
-    S_AT_NAME_COLON_DOMAIN_DOT.on(TT.TLD, S_USERID);
-}
-
-matrixLinkify.options = {
-    formatHref: function (href, type) {
-        switch (type) {
-            case 'roomalias':
-                return '#';
-            case 'userid':
-                return '#';
-            default:
-                return href;
-        }
-    }
-}
-
-module.exports = matrixLinkify;
diff --git a/vector/fonts b/vector/fonts
deleted file mode 120000
index 27f04cad..00000000
--- a/vector/fonts
+++ /dev/null
@@ -1 +0,0 @@
-../../skins/base/fonts/
\ No newline at end of file
diff --git a/vector/img b/vector/img
deleted file mode 120000
index 0d3ef0e2..00000000
--- a/vector/img
+++ /dev/null
@@ -1 +0,0 @@
-../../skins/base/img
\ No newline at end of file
diff --git a/vector/index.html b/vector/index.html
index be9e8f7e..2985994b 100644
--- a/vector/index.html
+++ b/vector/index.html
@@ -41,6 +41,6 @@
     </audio>
     <section id="matrixchat" style="height: 100%;"></section>
     <script src="bundle.js"></script>
-    <link rel="stylesheet" href="node_modules/matrix-react-sdk/bundle.css">
+    <link rel="stylesheet" href="bundle.css">
   </body>
 </html>
diff --git a/vector/package.json b/vector/package.json
deleted file mode 100644
index 230a261b..00000000
--- a/vector/package.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-  "name": "matrix-react-example",
-  "version": "0.0.1",
-  "description": "Example usage of matrix-react-sdk",
-  "author": "matrix.org",
-  "repository": {
-    "type": "git",
-    "url": "https://github.com/matrix-org/matrix-react-sdk"
-  },
-  "license": "Apache-2.0",
-  "devDependencies": {
-    "browserify": "^10.2.3",
-    "http-server": "^0.8.0",
-    "matrix-react-sdk": "../../",
-    "parallelshell": "^1.2.0",
-    "reactify": "^1.1.1",
-    "uglify-js": "^2.4.23",
-    "watchify": "^3.2.1"
-  },
-  "scripts": {
-    "build": "NODE_ENV=production browserify --ignore olm -t reactify index.js | uglifyjs -c -m -o bundle.js",
-    "start": "parallelshell \"watchify --ignore olm -v -d -t reactify index.js -o bundle.js\" \"http-server\""
-  }
-}

From 682392d02a2262e437bb551a512ff0ff6c2bb8e7 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 18:05:31 +0100
Subject: [PATCH 06/29] Move skins dir to src

---
 .../skins}/base/css/atoms/MemberAvatar.css          |   0
 .../skins}/base/css/atoms/MessageTimestamp.css      |   0
 {skins => src/skins}/base/css/common.css            |   0
 {skins => src/skins}/base/css/hide.css              |   0
 .../skins}/base/css/molecules/MImageTile.css        |   0
 .../skins}/base/css/molecules/MNoticeTile.css       |   0
 .../skins}/base/css/molecules/MTextTile.css         |   0
 .../skins}/base/css/molecules/MatrixToolbar.css     |   0
 .../skins}/base/css/molecules/MemberInfo.css        |   0
 .../skins}/base/css/molecules/MemberTile.css        |   0
 .../skins}/base/css/molecules/MessageComposer.css   |   0
 .../skins}/base/css/molecules/MessageTile.css       |   0
 .../skins}/base/css/molecules/ProgressBar.css       |   0
 .../skins}/base/css/molecules/RoomDropTarget.css    |   0
 .../skins}/base/css/molecules/RoomHeader.css        |   0
 .../skins}/base/css/molecules/RoomSettings.css      |   0
 .../skins}/base/css/molecules/RoomTile.css          |   0
 .../skins}/base/css/molecules/SenderProfile.css     |   0
 .../skins}/base/css/molecules/ServerConfig.css      |   0
 .../skins}/base/css/molecules/voip/CallView.css     |   0
 .../base/css/molecules/voip/IncomingCallbox.css     |   0
 .../skins}/base/css/molecules/voip/VideoView.css    |   0
 .../skins}/base/css/organisms/CreateRoom.css        |   0
 .../skins}/base/css/organisms/LeftPanel.css         |   0
 .../skins}/base/css/organisms/MemberList.css        |   0
 .../skins}/base/css/organisms/RightPanel.css        |   0
 .../skins}/base/css/organisms/RoomDirectory.css     |   0
 .../skins}/base/css/organisms/RoomList.css          |   0
 .../skins}/base/css/organisms/RoomView.css          |   0
 .../skins}/base/css/organisms/UserSettings.css      |   0
 {skins => src/skins}/base/css/pages/MatrixChat.css  |   0
 {skins => src/skins}/base/css/templates/Login.css   |   0
 ...2JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 | Bin
 ...qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 | Bin
 ...Y9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 | Bin
 {skins => src/skins}/base/fonts/Lato.css            |   0
 ...Dadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 | Bin
 ...gNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 | Bin
 ...ZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 | Bin
 {skins => src/skins}/base/img/attach.png            | Bin
 {skins => src/skins}/base/img/chevron-left.png      | Bin
 {skins => src/skins}/base/img/chevron-right.png     | Bin
 {skins => src/skins}/base/img/chevron.png           | Bin
 {skins => src/skins}/base/img/close-white.png       | Bin
 {skins => src/skins}/base/img/create-big.png        | Bin
 {skins => src/skins}/base/img/create.png            | Bin
 {skins => src/skins}/base/img/delete.png            | Bin
 {skins => src/skins}/base/img/directory-big.png     | Bin
 {skins => src/skins}/base/img/download.png          | Bin
 {skins => src/skins}/base/img/edit.png              | Bin
 {skins => src/skins}/base/img/file.png              | Bin
 {skins => src/skins}/base/img/filegrid.png          | Bin
 {skins => src/skins}/base/img/filelist.png          | Bin
 {skins => src/skins}/base/img/hide.png              | Bin
 {skins => src/skins}/base/img/info.png              | Bin
 {skins => src/skins}/base/img/logo.png              | Bin
 {skins => src/skins}/base/img/members.png           | Bin
 {skins => src/skins}/base/img/menu.png              | Bin
 {skins => src/skins}/base/img/newmessages.png       | Bin
 {skins => src/skins}/base/img/p/p0.png              | Bin
 {skins => src/skins}/base/img/p/p1.png              | Bin
 {skins => src/skins}/base/img/p/p10.png             | Bin
 {skins => src/skins}/base/img/p/p11.png             | Bin
 {skins => src/skins}/base/img/p/p12.png             | Bin
 {skins => src/skins}/base/img/p/p13.png             | Bin
 {skins => src/skins}/base/img/p/p14.png             | Bin
 {skins => src/skins}/base/img/p/p15.png             | Bin
 {skins => src/skins}/base/img/p/p16.png             | Bin
 {skins => src/skins}/base/img/p/p17.png             | Bin
 {skins => src/skins}/base/img/p/p18.png             | Bin
 {skins => src/skins}/base/img/p/p19.png             | Bin
 {skins => src/skins}/base/img/p/p2.png              | Bin
 {skins => src/skins}/base/img/p/p20.png             | Bin
 {skins => src/skins}/base/img/p/p3.png              | Bin
 {skins => src/skins}/base/img/p/p4.png              | Bin
 {skins => src/skins}/base/img/p/p5.png              | Bin
 {skins => src/skins}/base/img/p/p6.png              | Bin
 {skins => src/skins}/base/img/p/p7.png              | Bin
 {skins => src/skins}/base/img/p/p8.png              | Bin
 {skins => src/skins}/base/img/p/p9.png              | Bin
 {skins => src/skins}/base/img/p/piechart.pde        |   0
 {skins => src/skins}/base/img/placeholder.png       | Bin
 {skins => src/skins}/base/img/search.png            | Bin
 {skins => src/skins}/base/img/settings-big.png      | Bin
 {skins => src/skins}/base/img/settings.png          | Bin
 {skins => src/skins}/base/img/typing.png            | Bin
 {skins => src/skins}/base/img/upload-big.png        | Bin
 {skins => src/skins}/base/img/upload.png            | Bin
 {skins => src/skins}/base/img/video.png             | Bin
 {skins => src/skins}/base/img/voip.png              | Bin
 .../skins}/base/views/atoms/EditableText.js         |   0
 .../base/views/atoms/EnableNotificationsButton.js   |   0
 {skins => src/skins}/base/views/atoms/ImageView.js  |   0
 .../skins}/base/views/atoms/LogoutButton.js         |   0
 .../skins}/base/views/atoms/MemberAvatar.js         |   0
 .../skins}/base/views/atoms/MessageTimestamp.js     |   0
 {skins => src/skins}/base/views/atoms/RoomAvatar.js |   0
 .../views/atoms/create_room/CreateRoomButton.js     |   0
 .../skins}/base/views/atoms/create_room/Presets.js  |   0
 .../base/views/atoms/create_room/RoomAlias.js       |   0
 .../skins}/base/views/atoms/voip/VideoFeed.js       |   0
 .../skins}/base/views/molecules/BottomLeftMenu.js   |   0
 .../skins}/base/views/molecules/ChangeAvatar.js     |   0
 .../skins}/base/views/molecules/ChangePassword.js   |   0
 .../skins}/base/views/molecules/ContextualMenu.js   |   0
 .../skins}/base/views/molecules/DateSeparator.js    |   0
 .../skins}/base/views/molecules/EventAsTextTile.js  |   0
 .../skins}/base/views/molecules/MEmoteTile.js       |   0
 .../skins}/base/views/molecules/MFileTile.js        |   0
 .../skins}/base/views/molecules/MImageTile.js       |   0
 .../skins}/base/views/molecules/MNoticeTile.js      |   0
 .../skins}/base/views/molecules/MRoomMemberTile.js  |   0
 .../skins}/base/views/molecules/MTextTile.js        |   0
 .../skins}/base/views/molecules/MatrixToolbar.js    |   0
 .../skins}/base/views/molecules/MemberInfo.js       |   0
 .../skins}/base/views/molecules/MemberTile.js       |   0
 .../skins}/base/views/molecules/MessageComposer.js  |   0
 .../skins}/base/views/molecules/MessageTile.js      |   0
 .../skins}/base/views/molecules/ProgressBar.js      |   0
 .../skins}/base/views/molecules/RoomCreate.js       |   0
 .../skins}/base/views/molecules/RoomDropTarget.js   |   0
 .../skins}/base/views/molecules/RoomHeader.js       |   0
 .../skins}/base/views/molecules/RoomSettings.js     |   0
 .../skins}/base/views/molecules/RoomTile.js         |   0
 .../skins}/base/views/molecules/SenderProfile.js    |   0
 .../skins}/base/views/molecules/ServerConfig.js     |   0
 .../base/views/molecules/UnknownMessageTile.js      |   0
 .../skins}/base/views/molecules/UserSelector.js     |   0
 .../skins}/base/views/molecules/voip/CallView.js    |   0
 .../base/views/molecules/voip/IncomingCallBox.js    |   0
 .../skins}/base/views/molecules/voip/VideoView.js   |   0
 .../skins}/base/views/organisms/CreateRoom.js       |   0
 .../skins}/base/views/organisms/ErrorDialog.js      |   0
 .../skins}/base/views/organisms/LeftPanel.js        |   0
 .../skins}/base/views/organisms/LogoutPrompt.js     |   0
 .../skins}/base/views/organisms/MemberList.js       |   0
 .../skins}/base/views/organisms/Notifier.js         |   0
 .../skins}/base/views/organisms/QuestionDialog.js   |   0
 .../skins}/base/views/organisms/RightPanel.js       |   0
 .../skins}/base/views/organisms/RoomDirectory.js    |   0
 .../skins}/base/views/organisms/RoomList.js         |   0
 .../skins}/base/views/organisms/RoomView.js         |   0
 .../skins}/base/views/organisms/UserSettings.js     |   0
 {skins => src/skins}/base/views/pages/MatrixChat.js |   0
 {skins => src/skins}/base/views/templates/Login.js  |   0
 .../skins}/base/views/templates/Register.js         |   0
 146 files changed, 0 insertions(+), 0 deletions(-)
 rename {skins => src/skins}/base/css/atoms/MemberAvatar.css (100%)
 rename {skins => src/skins}/base/css/atoms/MessageTimestamp.css (100%)
 rename {skins => src/skins}/base/css/common.css (100%)
 rename {skins => src/skins}/base/css/hide.css (100%)
 rename {skins => src/skins}/base/css/molecules/MImageTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/MNoticeTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/MTextTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/MatrixToolbar.css (100%)
 rename {skins => src/skins}/base/css/molecules/MemberInfo.css (100%)
 rename {skins => src/skins}/base/css/molecules/MemberTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/MessageComposer.css (100%)
 rename {skins => src/skins}/base/css/molecules/MessageTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/ProgressBar.css (100%)
 rename {skins => src/skins}/base/css/molecules/RoomDropTarget.css (100%)
 rename {skins => src/skins}/base/css/molecules/RoomHeader.css (100%)
 rename {skins => src/skins}/base/css/molecules/RoomSettings.css (100%)
 rename {skins => src/skins}/base/css/molecules/RoomTile.css (100%)
 rename {skins => src/skins}/base/css/molecules/SenderProfile.css (100%)
 rename {skins => src/skins}/base/css/molecules/ServerConfig.css (100%)
 rename {skins => src/skins}/base/css/molecules/voip/CallView.css (100%)
 rename {skins => src/skins}/base/css/molecules/voip/IncomingCallbox.css (100%)
 rename {skins => src/skins}/base/css/molecules/voip/VideoView.css (100%)
 rename {skins => src/skins}/base/css/organisms/CreateRoom.css (100%)
 rename {skins => src/skins}/base/css/organisms/LeftPanel.css (100%)
 rename {skins => src/skins}/base/css/organisms/MemberList.css (100%)
 rename {skins => src/skins}/base/css/organisms/RightPanel.css (100%)
 rename {skins => src/skins}/base/css/organisms/RoomDirectory.css (100%)
 rename {skins => src/skins}/base/css/organisms/RoomList.css (100%)
 rename {skins => src/skins}/base/css/organisms/RoomView.css (100%)
 rename {skins => src/skins}/base/css/organisms/UserSettings.css (100%)
 rename {skins => src/skins}/base/css/pages/MatrixChat.css (100%)
 rename {skins => src/skins}/base/css/templates/Login.css (100%)
 rename {skins => src/skins}/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 (100%)
 rename {skins => src/skins}/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 (100%)
 rename {skins => src/skins}/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 (100%)
 rename {skins => src/skins}/base/fonts/Lato.css (100%)
 rename {skins => src/skins}/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 (100%)
 rename {skins => src/skins}/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 (100%)
 rename {skins => src/skins}/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 (100%)
 rename {skins => src/skins}/base/img/attach.png (100%)
 rename {skins => src/skins}/base/img/chevron-left.png (100%)
 rename {skins => src/skins}/base/img/chevron-right.png (100%)
 rename {skins => src/skins}/base/img/chevron.png (100%)
 rename {skins => src/skins}/base/img/close-white.png (100%)
 rename {skins => src/skins}/base/img/create-big.png (100%)
 rename {skins => src/skins}/base/img/create.png (100%)
 rename {skins => src/skins}/base/img/delete.png (100%)
 rename {skins => src/skins}/base/img/directory-big.png (100%)
 rename {skins => src/skins}/base/img/download.png (100%)
 rename {skins => src/skins}/base/img/edit.png (100%)
 rename {skins => src/skins}/base/img/file.png (100%)
 rename {skins => src/skins}/base/img/filegrid.png (100%)
 rename {skins => src/skins}/base/img/filelist.png (100%)
 rename {skins => src/skins}/base/img/hide.png (100%)
 rename {skins => src/skins}/base/img/info.png (100%)
 rename {skins => src/skins}/base/img/logo.png (100%)
 rename {skins => src/skins}/base/img/members.png (100%)
 rename {skins => src/skins}/base/img/menu.png (100%)
 rename {skins => src/skins}/base/img/newmessages.png (100%)
 rename {skins => src/skins}/base/img/p/p0.png (100%)
 rename {skins => src/skins}/base/img/p/p1.png (100%)
 rename {skins => src/skins}/base/img/p/p10.png (100%)
 rename {skins => src/skins}/base/img/p/p11.png (100%)
 rename {skins => src/skins}/base/img/p/p12.png (100%)
 rename {skins => src/skins}/base/img/p/p13.png (100%)
 rename {skins => src/skins}/base/img/p/p14.png (100%)
 rename {skins => src/skins}/base/img/p/p15.png (100%)
 rename {skins => src/skins}/base/img/p/p16.png (100%)
 rename {skins => src/skins}/base/img/p/p17.png (100%)
 rename {skins => src/skins}/base/img/p/p18.png (100%)
 rename {skins => src/skins}/base/img/p/p19.png (100%)
 rename {skins => src/skins}/base/img/p/p2.png (100%)
 rename {skins => src/skins}/base/img/p/p20.png (100%)
 rename {skins => src/skins}/base/img/p/p3.png (100%)
 rename {skins => src/skins}/base/img/p/p4.png (100%)
 rename {skins => src/skins}/base/img/p/p5.png (100%)
 rename {skins => src/skins}/base/img/p/p6.png (100%)
 rename {skins => src/skins}/base/img/p/p7.png (100%)
 rename {skins => src/skins}/base/img/p/p8.png (100%)
 rename {skins => src/skins}/base/img/p/p9.png (100%)
 rename {skins => src/skins}/base/img/p/piechart.pde (100%)
 rename {skins => src/skins}/base/img/placeholder.png (100%)
 rename {skins => src/skins}/base/img/search.png (100%)
 rename {skins => src/skins}/base/img/settings-big.png (100%)
 rename {skins => src/skins}/base/img/settings.png (100%)
 rename {skins => src/skins}/base/img/typing.png (100%)
 rename {skins => src/skins}/base/img/upload-big.png (100%)
 rename {skins => src/skins}/base/img/upload.png (100%)
 rename {skins => src/skins}/base/img/video.png (100%)
 rename {skins => src/skins}/base/img/voip.png (100%)
 rename {skins => src/skins}/base/views/atoms/EditableText.js (100%)
 rename {skins => src/skins}/base/views/atoms/EnableNotificationsButton.js (100%)
 rename {skins => src/skins}/base/views/atoms/ImageView.js (100%)
 rename {skins => src/skins}/base/views/atoms/LogoutButton.js (100%)
 rename {skins => src/skins}/base/views/atoms/MemberAvatar.js (100%)
 rename {skins => src/skins}/base/views/atoms/MessageTimestamp.js (100%)
 rename {skins => src/skins}/base/views/atoms/RoomAvatar.js (100%)
 rename {skins => src/skins}/base/views/atoms/create_room/CreateRoomButton.js (100%)
 rename {skins => src/skins}/base/views/atoms/create_room/Presets.js (100%)
 rename {skins => src/skins}/base/views/atoms/create_room/RoomAlias.js (100%)
 rename {skins => src/skins}/base/views/atoms/voip/VideoFeed.js (100%)
 rename {skins => src/skins}/base/views/molecules/BottomLeftMenu.js (100%)
 rename {skins => src/skins}/base/views/molecules/ChangeAvatar.js (100%)
 rename {skins => src/skins}/base/views/molecules/ChangePassword.js (100%)
 rename {skins => src/skins}/base/views/molecules/ContextualMenu.js (100%)
 rename {skins => src/skins}/base/views/molecules/DateSeparator.js (100%)
 rename {skins => src/skins}/base/views/molecules/EventAsTextTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MEmoteTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MFileTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MImageTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MNoticeTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MRoomMemberTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MTextTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MatrixToolbar.js (100%)
 rename {skins => src/skins}/base/views/molecules/MemberInfo.js (100%)
 rename {skins => src/skins}/base/views/molecules/MemberTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/MessageComposer.js (100%)
 rename {skins => src/skins}/base/views/molecules/MessageTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/ProgressBar.js (100%)
 rename {skins => src/skins}/base/views/molecules/RoomCreate.js (100%)
 rename {skins => src/skins}/base/views/molecules/RoomDropTarget.js (100%)
 rename {skins => src/skins}/base/views/molecules/RoomHeader.js (100%)
 rename {skins => src/skins}/base/views/molecules/RoomSettings.js (100%)
 rename {skins => src/skins}/base/views/molecules/RoomTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/SenderProfile.js (100%)
 rename {skins => src/skins}/base/views/molecules/ServerConfig.js (100%)
 rename {skins => src/skins}/base/views/molecules/UnknownMessageTile.js (100%)
 rename {skins => src/skins}/base/views/molecules/UserSelector.js (100%)
 rename {skins => src/skins}/base/views/molecules/voip/CallView.js (100%)
 rename {skins => src/skins}/base/views/molecules/voip/IncomingCallBox.js (100%)
 rename {skins => src/skins}/base/views/molecules/voip/VideoView.js (100%)
 rename {skins => src/skins}/base/views/organisms/CreateRoom.js (100%)
 rename {skins => src/skins}/base/views/organisms/ErrorDialog.js (100%)
 rename {skins => src/skins}/base/views/organisms/LeftPanel.js (100%)
 rename {skins => src/skins}/base/views/organisms/LogoutPrompt.js (100%)
 rename {skins => src/skins}/base/views/organisms/MemberList.js (100%)
 rename {skins => src/skins}/base/views/organisms/Notifier.js (100%)
 rename {skins => src/skins}/base/views/organisms/QuestionDialog.js (100%)
 rename {skins => src/skins}/base/views/organisms/RightPanel.js (100%)
 rename {skins => src/skins}/base/views/organisms/RoomDirectory.js (100%)
 rename {skins => src/skins}/base/views/organisms/RoomList.js (100%)
 rename {skins => src/skins}/base/views/organisms/RoomView.js (100%)
 rename {skins => src/skins}/base/views/organisms/UserSettings.js (100%)
 rename {skins => src/skins}/base/views/pages/MatrixChat.js (100%)
 rename {skins => src/skins}/base/views/templates/Login.js (100%)
 rename {skins => src/skins}/base/views/templates/Register.js (100%)

diff --git a/skins/base/css/atoms/MemberAvatar.css b/src/skins/base/css/atoms/MemberAvatar.css
similarity index 100%
rename from skins/base/css/atoms/MemberAvatar.css
rename to src/skins/base/css/atoms/MemberAvatar.css
diff --git a/skins/base/css/atoms/MessageTimestamp.css b/src/skins/base/css/atoms/MessageTimestamp.css
similarity index 100%
rename from skins/base/css/atoms/MessageTimestamp.css
rename to src/skins/base/css/atoms/MessageTimestamp.css
diff --git a/skins/base/css/common.css b/src/skins/base/css/common.css
similarity index 100%
rename from skins/base/css/common.css
rename to src/skins/base/css/common.css
diff --git a/skins/base/css/hide.css b/src/skins/base/css/hide.css
similarity index 100%
rename from skins/base/css/hide.css
rename to src/skins/base/css/hide.css
diff --git a/skins/base/css/molecules/MImageTile.css b/src/skins/base/css/molecules/MImageTile.css
similarity index 100%
rename from skins/base/css/molecules/MImageTile.css
rename to src/skins/base/css/molecules/MImageTile.css
diff --git a/skins/base/css/molecules/MNoticeTile.css b/src/skins/base/css/molecules/MNoticeTile.css
similarity index 100%
rename from skins/base/css/molecules/MNoticeTile.css
rename to src/skins/base/css/molecules/MNoticeTile.css
diff --git a/skins/base/css/molecules/MTextTile.css b/src/skins/base/css/molecules/MTextTile.css
similarity index 100%
rename from skins/base/css/molecules/MTextTile.css
rename to src/skins/base/css/molecules/MTextTile.css
diff --git a/skins/base/css/molecules/MatrixToolbar.css b/src/skins/base/css/molecules/MatrixToolbar.css
similarity index 100%
rename from skins/base/css/molecules/MatrixToolbar.css
rename to src/skins/base/css/molecules/MatrixToolbar.css
diff --git a/skins/base/css/molecules/MemberInfo.css b/src/skins/base/css/molecules/MemberInfo.css
similarity index 100%
rename from skins/base/css/molecules/MemberInfo.css
rename to src/skins/base/css/molecules/MemberInfo.css
diff --git a/skins/base/css/molecules/MemberTile.css b/src/skins/base/css/molecules/MemberTile.css
similarity index 100%
rename from skins/base/css/molecules/MemberTile.css
rename to src/skins/base/css/molecules/MemberTile.css
diff --git a/skins/base/css/molecules/MessageComposer.css b/src/skins/base/css/molecules/MessageComposer.css
similarity index 100%
rename from skins/base/css/molecules/MessageComposer.css
rename to src/skins/base/css/molecules/MessageComposer.css
diff --git a/skins/base/css/molecules/MessageTile.css b/src/skins/base/css/molecules/MessageTile.css
similarity index 100%
rename from skins/base/css/molecules/MessageTile.css
rename to src/skins/base/css/molecules/MessageTile.css
diff --git a/skins/base/css/molecules/ProgressBar.css b/src/skins/base/css/molecules/ProgressBar.css
similarity index 100%
rename from skins/base/css/molecules/ProgressBar.css
rename to src/skins/base/css/molecules/ProgressBar.css
diff --git a/skins/base/css/molecules/RoomDropTarget.css b/src/skins/base/css/molecules/RoomDropTarget.css
similarity index 100%
rename from skins/base/css/molecules/RoomDropTarget.css
rename to src/skins/base/css/molecules/RoomDropTarget.css
diff --git a/skins/base/css/molecules/RoomHeader.css b/src/skins/base/css/molecules/RoomHeader.css
similarity index 100%
rename from skins/base/css/molecules/RoomHeader.css
rename to src/skins/base/css/molecules/RoomHeader.css
diff --git a/skins/base/css/molecules/RoomSettings.css b/src/skins/base/css/molecules/RoomSettings.css
similarity index 100%
rename from skins/base/css/molecules/RoomSettings.css
rename to src/skins/base/css/molecules/RoomSettings.css
diff --git a/skins/base/css/molecules/RoomTile.css b/src/skins/base/css/molecules/RoomTile.css
similarity index 100%
rename from skins/base/css/molecules/RoomTile.css
rename to src/skins/base/css/molecules/RoomTile.css
diff --git a/skins/base/css/molecules/SenderProfile.css b/src/skins/base/css/molecules/SenderProfile.css
similarity index 100%
rename from skins/base/css/molecules/SenderProfile.css
rename to src/skins/base/css/molecules/SenderProfile.css
diff --git a/skins/base/css/molecules/ServerConfig.css b/src/skins/base/css/molecules/ServerConfig.css
similarity index 100%
rename from skins/base/css/molecules/ServerConfig.css
rename to src/skins/base/css/molecules/ServerConfig.css
diff --git a/skins/base/css/molecules/voip/CallView.css b/src/skins/base/css/molecules/voip/CallView.css
similarity index 100%
rename from skins/base/css/molecules/voip/CallView.css
rename to src/skins/base/css/molecules/voip/CallView.css
diff --git a/skins/base/css/molecules/voip/IncomingCallbox.css b/src/skins/base/css/molecules/voip/IncomingCallbox.css
similarity index 100%
rename from skins/base/css/molecules/voip/IncomingCallbox.css
rename to src/skins/base/css/molecules/voip/IncomingCallbox.css
diff --git a/skins/base/css/molecules/voip/VideoView.css b/src/skins/base/css/molecules/voip/VideoView.css
similarity index 100%
rename from skins/base/css/molecules/voip/VideoView.css
rename to src/skins/base/css/molecules/voip/VideoView.css
diff --git a/skins/base/css/organisms/CreateRoom.css b/src/skins/base/css/organisms/CreateRoom.css
similarity index 100%
rename from skins/base/css/organisms/CreateRoom.css
rename to src/skins/base/css/organisms/CreateRoom.css
diff --git a/skins/base/css/organisms/LeftPanel.css b/src/skins/base/css/organisms/LeftPanel.css
similarity index 100%
rename from skins/base/css/organisms/LeftPanel.css
rename to src/skins/base/css/organisms/LeftPanel.css
diff --git a/skins/base/css/organisms/MemberList.css b/src/skins/base/css/organisms/MemberList.css
similarity index 100%
rename from skins/base/css/organisms/MemberList.css
rename to src/skins/base/css/organisms/MemberList.css
diff --git a/skins/base/css/organisms/RightPanel.css b/src/skins/base/css/organisms/RightPanel.css
similarity index 100%
rename from skins/base/css/organisms/RightPanel.css
rename to src/skins/base/css/organisms/RightPanel.css
diff --git a/skins/base/css/organisms/RoomDirectory.css b/src/skins/base/css/organisms/RoomDirectory.css
similarity index 100%
rename from skins/base/css/organisms/RoomDirectory.css
rename to src/skins/base/css/organisms/RoomDirectory.css
diff --git a/skins/base/css/organisms/RoomList.css b/src/skins/base/css/organisms/RoomList.css
similarity index 100%
rename from skins/base/css/organisms/RoomList.css
rename to src/skins/base/css/organisms/RoomList.css
diff --git a/skins/base/css/organisms/RoomView.css b/src/skins/base/css/organisms/RoomView.css
similarity index 100%
rename from skins/base/css/organisms/RoomView.css
rename to src/skins/base/css/organisms/RoomView.css
diff --git a/skins/base/css/organisms/UserSettings.css b/src/skins/base/css/organisms/UserSettings.css
similarity index 100%
rename from skins/base/css/organisms/UserSettings.css
rename to src/skins/base/css/organisms/UserSettings.css
diff --git a/skins/base/css/pages/MatrixChat.css b/src/skins/base/css/pages/MatrixChat.css
similarity index 100%
rename from skins/base/css/pages/MatrixChat.css
rename to src/skins/base/css/pages/MatrixChat.css
diff --git a/skins/base/css/templates/Login.css b/src/skins/base/css/templates/Login.css
similarity index 100%
rename from skins/base/css/templates/Login.css
rename to src/skins/base/css/templates/Login.css
diff --git a/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 b/src/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
similarity index 100%
rename from skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
rename to src/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
diff --git a/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/skins/base/fonts/Lato.css b/src/skins/base/fonts/Lato.css
similarity index 100%
rename from skins/base/fonts/Lato.css
rename to src/skins/base/fonts/Lato.css
diff --git a/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 b/src/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
similarity index 100%
rename from skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
rename to src/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
diff --git a/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/skins/base/img/attach.png b/src/skins/base/img/attach.png
similarity index 100%
rename from skins/base/img/attach.png
rename to src/skins/base/img/attach.png
diff --git a/skins/base/img/chevron-left.png b/src/skins/base/img/chevron-left.png
similarity index 100%
rename from skins/base/img/chevron-left.png
rename to src/skins/base/img/chevron-left.png
diff --git a/skins/base/img/chevron-right.png b/src/skins/base/img/chevron-right.png
similarity index 100%
rename from skins/base/img/chevron-right.png
rename to src/skins/base/img/chevron-right.png
diff --git a/skins/base/img/chevron.png b/src/skins/base/img/chevron.png
similarity index 100%
rename from skins/base/img/chevron.png
rename to src/skins/base/img/chevron.png
diff --git a/skins/base/img/close-white.png b/src/skins/base/img/close-white.png
similarity index 100%
rename from skins/base/img/close-white.png
rename to src/skins/base/img/close-white.png
diff --git a/skins/base/img/create-big.png b/src/skins/base/img/create-big.png
similarity index 100%
rename from skins/base/img/create-big.png
rename to src/skins/base/img/create-big.png
diff --git a/skins/base/img/create.png b/src/skins/base/img/create.png
similarity index 100%
rename from skins/base/img/create.png
rename to src/skins/base/img/create.png
diff --git a/skins/base/img/delete.png b/src/skins/base/img/delete.png
similarity index 100%
rename from skins/base/img/delete.png
rename to src/skins/base/img/delete.png
diff --git a/skins/base/img/directory-big.png b/src/skins/base/img/directory-big.png
similarity index 100%
rename from skins/base/img/directory-big.png
rename to src/skins/base/img/directory-big.png
diff --git a/skins/base/img/download.png b/src/skins/base/img/download.png
similarity index 100%
rename from skins/base/img/download.png
rename to src/skins/base/img/download.png
diff --git a/skins/base/img/edit.png b/src/skins/base/img/edit.png
similarity index 100%
rename from skins/base/img/edit.png
rename to src/skins/base/img/edit.png
diff --git a/skins/base/img/file.png b/src/skins/base/img/file.png
similarity index 100%
rename from skins/base/img/file.png
rename to src/skins/base/img/file.png
diff --git a/skins/base/img/filegrid.png b/src/skins/base/img/filegrid.png
similarity index 100%
rename from skins/base/img/filegrid.png
rename to src/skins/base/img/filegrid.png
diff --git a/skins/base/img/filelist.png b/src/skins/base/img/filelist.png
similarity index 100%
rename from skins/base/img/filelist.png
rename to src/skins/base/img/filelist.png
diff --git a/skins/base/img/hide.png b/src/skins/base/img/hide.png
similarity index 100%
rename from skins/base/img/hide.png
rename to src/skins/base/img/hide.png
diff --git a/skins/base/img/info.png b/src/skins/base/img/info.png
similarity index 100%
rename from skins/base/img/info.png
rename to src/skins/base/img/info.png
diff --git a/skins/base/img/logo.png b/src/skins/base/img/logo.png
similarity index 100%
rename from skins/base/img/logo.png
rename to src/skins/base/img/logo.png
diff --git a/skins/base/img/members.png b/src/skins/base/img/members.png
similarity index 100%
rename from skins/base/img/members.png
rename to src/skins/base/img/members.png
diff --git a/skins/base/img/menu.png b/src/skins/base/img/menu.png
similarity index 100%
rename from skins/base/img/menu.png
rename to src/skins/base/img/menu.png
diff --git a/skins/base/img/newmessages.png b/src/skins/base/img/newmessages.png
similarity index 100%
rename from skins/base/img/newmessages.png
rename to src/skins/base/img/newmessages.png
diff --git a/skins/base/img/p/p0.png b/src/skins/base/img/p/p0.png
similarity index 100%
rename from skins/base/img/p/p0.png
rename to src/skins/base/img/p/p0.png
diff --git a/skins/base/img/p/p1.png b/src/skins/base/img/p/p1.png
similarity index 100%
rename from skins/base/img/p/p1.png
rename to src/skins/base/img/p/p1.png
diff --git a/skins/base/img/p/p10.png b/src/skins/base/img/p/p10.png
similarity index 100%
rename from skins/base/img/p/p10.png
rename to src/skins/base/img/p/p10.png
diff --git a/skins/base/img/p/p11.png b/src/skins/base/img/p/p11.png
similarity index 100%
rename from skins/base/img/p/p11.png
rename to src/skins/base/img/p/p11.png
diff --git a/skins/base/img/p/p12.png b/src/skins/base/img/p/p12.png
similarity index 100%
rename from skins/base/img/p/p12.png
rename to src/skins/base/img/p/p12.png
diff --git a/skins/base/img/p/p13.png b/src/skins/base/img/p/p13.png
similarity index 100%
rename from skins/base/img/p/p13.png
rename to src/skins/base/img/p/p13.png
diff --git a/skins/base/img/p/p14.png b/src/skins/base/img/p/p14.png
similarity index 100%
rename from skins/base/img/p/p14.png
rename to src/skins/base/img/p/p14.png
diff --git a/skins/base/img/p/p15.png b/src/skins/base/img/p/p15.png
similarity index 100%
rename from skins/base/img/p/p15.png
rename to src/skins/base/img/p/p15.png
diff --git a/skins/base/img/p/p16.png b/src/skins/base/img/p/p16.png
similarity index 100%
rename from skins/base/img/p/p16.png
rename to src/skins/base/img/p/p16.png
diff --git a/skins/base/img/p/p17.png b/src/skins/base/img/p/p17.png
similarity index 100%
rename from skins/base/img/p/p17.png
rename to src/skins/base/img/p/p17.png
diff --git a/skins/base/img/p/p18.png b/src/skins/base/img/p/p18.png
similarity index 100%
rename from skins/base/img/p/p18.png
rename to src/skins/base/img/p/p18.png
diff --git a/skins/base/img/p/p19.png b/src/skins/base/img/p/p19.png
similarity index 100%
rename from skins/base/img/p/p19.png
rename to src/skins/base/img/p/p19.png
diff --git a/skins/base/img/p/p2.png b/src/skins/base/img/p/p2.png
similarity index 100%
rename from skins/base/img/p/p2.png
rename to src/skins/base/img/p/p2.png
diff --git a/skins/base/img/p/p20.png b/src/skins/base/img/p/p20.png
similarity index 100%
rename from skins/base/img/p/p20.png
rename to src/skins/base/img/p/p20.png
diff --git a/skins/base/img/p/p3.png b/src/skins/base/img/p/p3.png
similarity index 100%
rename from skins/base/img/p/p3.png
rename to src/skins/base/img/p/p3.png
diff --git a/skins/base/img/p/p4.png b/src/skins/base/img/p/p4.png
similarity index 100%
rename from skins/base/img/p/p4.png
rename to src/skins/base/img/p/p4.png
diff --git a/skins/base/img/p/p5.png b/src/skins/base/img/p/p5.png
similarity index 100%
rename from skins/base/img/p/p5.png
rename to src/skins/base/img/p/p5.png
diff --git a/skins/base/img/p/p6.png b/src/skins/base/img/p/p6.png
similarity index 100%
rename from skins/base/img/p/p6.png
rename to src/skins/base/img/p/p6.png
diff --git a/skins/base/img/p/p7.png b/src/skins/base/img/p/p7.png
similarity index 100%
rename from skins/base/img/p/p7.png
rename to src/skins/base/img/p/p7.png
diff --git a/skins/base/img/p/p8.png b/src/skins/base/img/p/p8.png
similarity index 100%
rename from skins/base/img/p/p8.png
rename to src/skins/base/img/p/p8.png
diff --git a/skins/base/img/p/p9.png b/src/skins/base/img/p/p9.png
similarity index 100%
rename from skins/base/img/p/p9.png
rename to src/skins/base/img/p/p9.png
diff --git a/skins/base/img/p/piechart.pde b/src/skins/base/img/p/piechart.pde
similarity index 100%
rename from skins/base/img/p/piechart.pde
rename to src/skins/base/img/p/piechart.pde
diff --git a/skins/base/img/placeholder.png b/src/skins/base/img/placeholder.png
similarity index 100%
rename from skins/base/img/placeholder.png
rename to src/skins/base/img/placeholder.png
diff --git a/skins/base/img/search.png b/src/skins/base/img/search.png
similarity index 100%
rename from skins/base/img/search.png
rename to src/skins/base/img/search.png
diff --git a/skins/base/img/settings-big.png b/src/skins/base/img/settings-big.png
similarity index 100%
rename from skins/base/img/settings-big.png
rename to src/skins/base/img/settings-big.png
diff --git a/skins/base/img/settings.png b/src/skins/base/img/settings.png
similarity index 100%
rename from skins/base/img/settings.png
rename to src/skins/base/img/settings.png
diff --git a/skins/base/img/typing.png b/src/skins/base/img/typing.png
similarity index 100%
rename from skins/base/img/typing.png
rename to src/skins/base/img/typing.png
diff --git a/skins/base/img/upload-big.png b/src/skins/base/img/upload-big.png
similarity index 100%
rename from skins/base/img/upload-big.png
rename to src/skins/base/img/upload-big.png
diff --git a/skins/base/img/upload.png b/src/skins/base/img/upload.png
similarity index 100%
rename from skins/base/img/upload.png
rename to src/skins/base/img/upload.png
diff --git a/skins/base/img/video.png b/src/skins/base/img/video.png
similarity index 100%
rename from skins/base/img/video.png
rename to src/skins/base/img/video.png
diff --git a/skins/base/img/voip.png b/src/skins/base/img/voip.png
similarity index 100%
rename from skins/base/img/voip.png
rename to src/skins/base/img/voip.png
diff --git a/skins/base/views/atoms/EditableText.js b/src/skins/base/views/atoms/EditableText.js
similarity index 100%
rename from skins/base/views/atoms/EditableText.js
rename to src/skins/base/views/atoms/EditableText.js
diff --git a/skins/base/views/atoms/EnableNotificationsButton.js b/src/skins/base/views/atoms/EnableNotificationsButton.js
similarity index 100%
rename from skins/base/views/atoms/EnableNotificationsButton.js
rename to src/skins/base/views/atoms/EnableNotificationsButton.js
diff --git a/skins/base/views/atoms/ImageView.js b/src/skins/base/views/atoms/ImageView.js
similarity index 100%
rename from skins/base/views/atoms/ImageView.js
rename to src/skins/base/views/atoms/ImageView.js
diff --git a/skins/base/views/atoms/LogoutButton.js b/src/skins/base/views/atoms/LogoutButton.js
similarity index 100%
rename from skins/base/views/atoms/LogoutButton.js
rename to src/skins/base/views/atoms/LogoutButton.js
diff --git a/skins/base/views/atoms/MemberAvatar.js b/src/skins/base/views/atoms/MemberAvatar.js
similarity index 100%
rename from skins/base/views/atoms/MemberAvatar.js
rename to src/skins/base/views/atoms/MemberAvatar.js
diff --git a/skins/base/views/atoms/MessageTimestamp.js b/src/skins/base/views/atoms/MessageTimestamp.js
similarity index 100%
rename from skins/base/views/atoms/MessageTimestamp.js
rename to src/skins/base/views/atoms/MessageTimestamp.js
diff --git a/skins/base/views/atoms/RoomAvatar.js b/src/skins/base/views/atoms/RoomAvatar.js
similarity index 100%
rename from skins/base/views/atoms/RoomAvatar.js
rename to src/skins/base/views/atoms/RoomAvatar.js
diff --git a/skins/base/views/atoms/create_room/CreateRoomButton.js b/src/skins/base/views/atoms/create_room/CreateRoomButton.js
similarity index 100%
rename from skins/base/views/atoms/create_room/CreateRoomButton.js
rename to src/skins/base/views/atoms/create_room/CreateRoomButton.js
diff --git a/skins/base/views/atoms/create_room/Presets.js b/src/skins/base/views/atoms/create_room/Presets.js
similarity index 100%
rename from skins/base/views/atoms/create_room/Presets.js
rename to src/skins/base/views/atoms/create_room/Presets.js
diff --git a/skins/base/views/atoms/create_room/RoomAlias.js b/src/skins/base/views/atoms/create_room/RoomAlias.js
similarity index 100%
rename from skins/base/views/atoms/create_room/RoomAlias.js
rename to src/skins/base/views/atoms/create_room/RoomAlias.js
diff --git a/skins/base/views/atoms/voip/VideoFeed.js b/src/skins/base/views/atoms/voip/VideoFeed.js
similarity index 100%
rename from skins/base/views/atoms/voip/VideoFeed.js
rename to src/skins/base/views/atoms/voip/VideoFeed.js
diff --git a/skins/base/views/molecules/BottomLeftMenu.js b/src/skins/base/views/molecules/BottomLeftMenu.js
similarity index 100%
rename from skins/base/views/molecules/BottomLeftMenu.js
rename to src/skins/base/views/molecules/BottomLeftMenu.js
diff --git a/skins/base/views/molecules/ChangeAvatar.js b/src/skins/base/views/molecules/ChangeAvatar.js
similarity index 100%
rename from skins/base/views/molecules/ChangeAvatar.js
rename to src/skins/base/views/molecules/ChangeAvatar.js
diff --git a/skins/base/views/molecules/ChangePassword.js b/src/skins/base/views/molecules/ChangePassword.js
similarity index 100%
rename from skins/base/views/molecules/ChangePassword.js
rename to src/skins/base/views/molecules/ChangePassword.js
diff --git a/skins/base/views/molecules/ContextualMenu.js b/src/skins/base/views/molecules/ContextualMenu.js
similarity index 100%
rename from skins/base/views/molecules/ContextualMenu.js
rename to src/skins/base/views/molecules/ContextualMenu.js
diff --git a/skins/base/views/molecules/DateSeparator.js b/src/skins/base/views/molecules/DateSeparator.js
similarity index 100%
rename from skins/base/views/molecules/DateSeparator.js
rename to src/skins/base/views/molecules/DateSeparator.js
diff --git a/skins/base/views/molecules/EventAsTextTile.js b/src/skins/base/views/molecules/EventAsTextTile.js
similarity index 100%
rename from skins/base/views/molecules/EventAsTextTile.js
rename to src/skins/base/views/molecules/EventAsTextTile.js
diff --git a/skins/base/views/molecules/MEmoteTile.js b/src/skins/base/views/molecules/MEmoteTile.js
similarity index 100%
rename from skins/base/views/molecules/MEmoteTile.js
rename to src/skins/base/views/molecules/MEmoteTile.js
diff --git a/skins/base/views/molecules/MFileTile.js b/src/skins/base/views/molecules/MFileTile.js
similarity index 100%
rename from skins/base/views/molecules/MFileTile.js
rename to src/skins/base/views/molecules/MFileTile.js
diff --git a/skins/base/views/molecules/MImageTile.js b/src/skins/base/views/molecules/MImageTile.js
similarity index 100%
rename from skins/base/views/molecules/MImageTile.js
rename to src/skins/base/views/molecules/MImageTile.js
diff --git a/skins/base/views/molecules/MNoticeTile.js b/src/skins/base/views/molecules/MNoticeTile.js
similarity index 100%
rename from skins/base/views/molecules/MNoticeTile.js
rename to src/skins/base/views/molecules/MNoticeTile.js
diff --git a/skins/base/views/molecules/MRoomMemberTile.js b/src/skins/base/views/molecules/MRoomMemberTile.js
similarity index 100%
rename from skins/base/views/molecules/MRoomMemberTile.js
rename to src/skins/base/views/molecules/MRoomMemberTile.js
diff --git a/skins/base/views/molecules/MTextTile.js b/src/skins/base/views/molecules/MTextTile.js
similarity index 100%
rename from skins/base/views/molecules/MTextTile.js
rename to src/skins/base/views/molecules/MTextTile.js
diff --git a/skins/base/views/molecules/MatrixToolbar.js b/src/skins/base/views/molecules/MatrixToolbar.js
similarity index 100%
rename from skins/base/views/molecules/MatrixToolbar.js
rename to src/skins/base/views/molecules/MatrixToolbar.js
diff --git a/skins/base/views/molecules/MemberInfo.js b/src/skins/base/views/molecules/MemberInfo.js
similarity index 100%
rename from skins/base/views/molecules/MemberInfo.js
rename to src/skins/base/views/molecules/MemberInfo.js
diff --git a/skins/base/views/molecules/MemberTile.js b/src/skins/base/views/molecules/MemberTile.js
similarity index 100%
rename from skins/base/views/molecules/MemberTile.js
rename to src/skins/base/views/molecules/MemberTile.js
diff --git a/skins/base/views/molecules/MessageComposer.js b/src/skins/base/views/molecules/MessageComposer.js
similarity index 100%
rename from skins/base/views/molecules/MessageComposer.js
rename to src/skins/base/views/molecules/MessageComposer.js
diff --git a/skins/base/views/molecules/MessageTile.js b/src/skins/base/views/molecules/MessageTile.js
similarity index 100%
rename from skins/base/views/molecules/MessageTile.js
rename to src/skins/base/views/molecules/MessageTile.js
diff --git a/skins/base/views/molecules/ProgressBar.js b/src/skins/base/views/molecules/ProgressBar.js
similarity index 100%
rename from skins/base/views/molecules/ProgressBar.js
rename to src/skins/base/views/molecules/ProgressBar.js
diff --git a/skins/base/views/molecules/RoomCreate.js b/src/skins/base/views/molecules/RoomCreate.js
similarity index 100%
rename from skins/base/views/molecules/RoomCreate.js
rename to src/skins/base/views/molecules/RoomCreate.js
diff --git a/skins/base/views/molecules/RoomDropTarget.js b/src/skins/base/views/molecules/RoomDropTarget.js
similarity index 100%
rename from skins/base/views/molecules/RoomDropTarget.js
rename to src/skins/base/views/molecules/RoomDropTarget.js
diff --git a/skins/base/views/molecules/RoomHeader.js b/src/skins/base/views/molecules/RoomHeader.js
similarity index 100%
rename from skins/base/views/molecules/RoomHeader.js
rename to src/skins/base/views/molecules/RoomHeader.js
diff --git a/skins/base/views/molecules/RoomSettings.js b/src/skins/base/views/molecules/RoomSettings.js
similarity index 100%
rename from skins/base/views/molecules/RoomSettings.js
rename to src/skins/base/views/molecules/RoomSettings.js
diff --git a/skins/base/views/molecules/RoomTile.js b/src/skins/base/views/molecules/RoomTile.js
similarity index 100%
rename from skins/base/views/molecules/RoomTile.js
rename to src/skins/base/views/molecules/RoomTile.js
diff --git a/skins/base/views/molecules/SenderProfile.js b/src/skins/base/views/molecules/SenderProfile.js
similarity index 100%
rename from skins/base/views/molecules/SenderProfile.js
rename to src/skins/base/views/molecules/SenderProfile.js
diff --git a/skins/base/views/molecules/ServerConfig.js b/src/skins/base/views/molecules/ServerConfig.js
similarity index 100%
rename from skins/base/views/molecules/ServerConfig.js
rename to src/skins/base/views/molecules/ServerConfig.js
diff --git a/skins/base/views/molecules/UnknownMessageTile.js b/src/skins/base/views/molecules/UnknownMessageTile.js
similarity index 100%
rename from skins/base/views/molecules/UnknownMessageTile.js
rename to src/skins/base/views/molecules/UnknownMessageTile.js
diff --git a/skins/base/views/molecules/UserSelector.js b/src/skins/base/views/molecules/UserSelector.js
similarity index 100%
rename from skins/base/views/molecules/UserSelector.js
rename to src/skins/base/views/molecules/UserSelector.js
diff --git a/skins/base/views/molecules/voip/CallView.js b/src/skins/base/views/molecules/voip/CallView.js
similarity index 100%
rename from skins/base/views/molecules/voip/CallView.js
rename to src/skins/base/views/molecules/voip/CallView.js
diff --git a/skins/base/views/molecules/voip/IncomingCallBox.js b/src/skins/base/views/molecules/voip/IncomingCallBox.js
similarity index 100%
rename from skins/base/views/molecules/voip/IncomingCallBox.js
rename to src/skins/base/views/molecules/voip/IncomingCallBox.js
diff --git a/skins/base/views/molecules/voip/VideoView.js b/src/skins/base/views/molecules/voip/VideoView.js
similarity index 100%
rename from skins/base/views/molecules/voip/VideoView.js
rename to src/skins/base/views/molecules/voip/VideoView.js
diff --git a/skins/base/views/organisms/CreateRoom.js b/src/skins/base/views/organisms/CreateRoom.js
similarity index 100%
rename from skins/base/views/organisms/CreateRoom.js
rename to src/skins/base/views/organisms/CreateRoom.js
diff --git a/skins/base/views/organisms/ErrorDialog.js b/src/skins/base/views/organisms/ErrorDialog.js
similarity index 100%
rename from skins/base/views/organisms/ErrorDialog.js
rename to src/skins/base/views/organisms/ErrorDialog.js
diff --git a/skins/base/views/organisms/LeftPanel.js b/src/skins/base/views/organisms/LeftPanel.js
similarity index 100%
rename from skins/base/views/organisms/LeftPanel.js
rename to src/skins/base/views/organisms/LeftPanel.js
diff --git a/skins/base/views/organisms/LogoutPrompt.js b/src/skins/base/views/organisms/LogoutPrompt.js
similarity index 100%
rename from skins/base/views/organisms/LogoutPrompt.js
rename to src/skins/base/views/organisms/LogoutPrompt.js
diff --git a/skins/base/views/organisms/MemberList.js b/src/skins/base/views/organisms/MemberList.js
similarity index 100%
rename from skins/base/views/organisms/MemberList.js
rename to src/skins/base/views/organisms/MemberList.js
diff --git a/skins/base/views/organisms/Notifier.js b/src/skins/base/views/organisms/Notifier.js
similarity index 100%
rename from skins/base/views/organisms/Notifier.js
rename to src/skins/base/views/organisms/Notifier.js
diff --git a/skins/base/views/organisms/QuestionDialog.js b/src/skins/base/views/organisms/QuestionDialog.js
similarity index 100%
rename from skins/base/views/organisms/QuestionDialog.js
rename to src/skins/base/views/organisms/QuestionDialog.js
diff --git a/skins/base/views/organisms/RightPanel.js b/src/skins/base/views/organisms/RightPanel.js
similarity index 100%
rename from skins/base/views/organisms/RightPanel.js
rename to src/skins/base/views/organisms/RightPanel.js
diff --git a/skins/base/views/organisms/RoomDirectory.js b/src/skins/base/views/organisms/RoomDirectory.js
similarity index 100%
rename from skins/base/views/organisms/RoomDirectory.js
rename to src/skins/base/views/organisms/RoomDirectory.js
diff --git a/skins/base/views/organisms/RoomList.js b/src/skins/base/views/organisms/RoomList.js
similarity index 100%
rename from skins/base/views/organisms/RoomList.js
rename to src/skins/base/views/organisms/RoomList.js
diff --git a/skins/base/views/organisms/RoomView.js b/src/skins/base/views/organisms/RoomView.js
similarity index 100%
rename from skins/base/views/organisms/RoomView.js
rename to src/skins/base/views/organisms/RoomView.js
diff --git a/skins/base/views/organisms/UserSettings.js b/src/skins/base/views/organisms/UserSettings.js
similarity index 100%
rename from skins/base/views/organisms/UserSettings.js
rename to src/skins/base/views/organisms/UserSettings.js
diff --git a/skins/base/views/pages/MatrixChat.js b/src/skins/base/views/pages/MatrixChat.js
similarity index 100%
rename from skins/base/views/pages/MatrixChat.js
rename to src/skins/base/views/pages/MatrixChat.js
diff --git a/skins/base/views/templates/Login.js b/src/skins/base/views/templates/Login.js
similarity index 100%
rename from skins/base/views/templates/Login.js
rename to src/skins/base/views/templates/Login.js
diff --git a/skins/base/views/templates/Register.js b/src/skins/base/views/templates/Register.js
similarity index 100%
rename from skins/base/views/templates/Register.js
rename to src/skins/base/views/templates/Register.js

From 148dbc23ed12fa19de7dee013a7442e9f582508b Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 18:05:55 +0100
Subject: [PATCH 07/29] Rename base skin to vector

---
 .../{base => vector}/css/atoms/MemberAvatar.css     |   0
 .../{base => vector}/css/atoms/MessageTimestamp.css |   0
 src/skins/{base => vector}/css/common.css           |   0
 src/skins/{base => vector}/css/hide.css             |   0
 .../{base => vector}/css/molecules/MImageTile.css   |   0
 .../{base => vector}/css/molecules/MNoticeTile.css  |   0
 .../{base => vector}/css/molecules/MTextTile.css    |   0
 .../css/molecules/MatrixToolbar.css                 |   0
 .../{base => vector}/css/molecules/MemberInfo.css   |   0
 .../{base => vector}/css/molecules/MemberTile.css   |   0
 .../css/molecules/MessageComposer.css               |   0
 .../{base => vector}/css/molecules/MessageTile.css  |   0
 .../{base => vector}/css/molecules/ProgressBar.css  |   0
 .../css/molecules/RoomDropTarget.css                |   0
 .../{base => vector}/css/molecules/RoomHeader.css   |   0
 .../{base => vector}/css/molecules/RoomSettings.css |   0
 .../{base => vector}/css/molecules/RoomTile.css     |   0
 .../css/molecules/SenderProfile.css                 |   0
 .../{base => vector}/css/molecules/ServerConfig.css |   0
 .../css/molecules/voip/CallView.css                 |   0
 .../css/molecules/voip/IncomingCallbox.css          |   0
 .../css/molecules/voip/VideoView.css                |   0
 .../{base => vector}/css/organisms/CreateRoom.css   |   0
 .../{base => vector}/css/organisms/LeftPanel.css    |   0
 .../{base => vector}/css/organisms/MemberList.css   |   0
 .../{base => vector}/css/organisms/RightPanel.css   |   0
 .../css/organisms/RoomDirectory.css                 |   0
 .../{base => vector}/css/organisms/RoomList.css     |   0
 .../{base => vector}/css/organisms/RoomView.css     |   0
 .../{base => vector}/css/organisms/UserSettings.css |   0
 src/skins/{base => vector}/css/pages/MatrixChat.css |   0
 src/skins/{base => vector}/css/templates/Login.css  |   0
 ...2JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 | Bin
 ...qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 | Bin
 ...Y9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 | Bin
 src/skins/{base => vector}/fonts/Lato.css           |   0
 ...Dadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 | Bin
 ...gNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 | Bin
 ...ZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 | Bin
 src/skins/{base => vector}/img/attach.png           | Bin
 src/skins/{base => vector}/img/chevron-left.png     | Bin
 src/skins/{base => vector}/img/chevron-right.png    | Bin
 src/skins/{base => vector}/img/chevron.png          | Bin
 src/skins/{base => vector}/img/close-white.png      | Bin
 src/skins/{base => vector}/img/create-big.png       | Bin
 src/skins/{base => vector}/img/create.png           | Bin
 src/skins/{base => vector}/img/delete.png           | Bin
 src/skins/{base => vector}/img/directory-big.png    | Bin
 src/skins/{base => vector}/img/download.png         | Bin
 src/skins/{base => vector}/img/edit.png             | Bin
 src/skins/{base => vector}/img/file.png             | Bin
 src/skins/{base => vector}/img/filegrid.png         | Bin
 src/skins/{base => vector}/img/filelist.png         | Bin
 src/skins/{base => vector}/img/hide.png             | Bin
 src/skins/{base => vector}/img/info.png             | Bin
 src/skins/{base => vector}/img/logo.png             | Bin
 src/skins/{base => vector}/img/members.png          | Bin
 src/skins/{base => vector}/img/menu.png             | Bin
 src/skins/{base => vector}/img/newmessages.png      | Bin
 src/skins/{base => vector}/img/p/p0.png             | Bin
 src/skins/{base => vector}/img/p/p1.png             | Bin
 src/skins/{base => vector}/img/p/p10.png            | Bin
 src/skins/{base => vector}/img/p/p11.png            | Bin
 src/skins/{base => vector}/img/p/p12.png            | Bin
 src/skins/{base => vector}/img/p/p13.png            | Bin
 src/skins/{base => vector}/img/p/p14.png            | Bin
 src/skins/{base => vector}/img/p/p15.png            | Bin
 src/skins/{base => vector}/img/p/p16.png            | Bin
 src/skins/{base => vector}/img/p/p17.png            | Bin
 src/skins/{base => vector}/img/p/p18.png            | Bin
 src/skins/{base => vector}/img/p/p19.png            | Bin
 src/skins/{base => vector}/img/p/p2.png             | Bin
 src/skins/{base => vector}/img/p/p20.png            | Bin
 src/skins/{base => vector}/img/p/p3.png             | Bin
 src/skins/{base => vector}/img/p/p4.png             | Bin
 src/skins/{base => vector}/img/p/p5.png             | Bin
 src/skins/{base => vector}/img/p/p6.png             | Bin
 src/skins/{base => vector}/img/p/p7.png             | Bin
 src/skins/{base => vector}/img/p/p8.png             | Bin
 src/skins/{base => vector}/img/p/p9.png             | Bin
 src/skins/{base => vector}/img/p/piechart.pde       |   0
 src/skins/{base => vector}/img/placeholder.png      | Bin
 src/skins/{base => vector}/img/search.png           | Bin
 src/skins/{base => vector}/img/settings-big.png     | Bin
 src/skins/{base => vector}/img/settings.png         | Bin
 src/skins/{base => vector}/img/typing.png           | Bin
 src/skins/{base => vector}/img/upload-big.png       | Bin
 src/skins/{base => vector}/img/upload.png           | Bin
 src/skins/{base => vector}/img/video.png            | Bin
 src/skins/{base => vector}/img/voip.png             | Bin
 .../{base => vector}/views/atoms/EditableText.js    |   0
 .../views/atoms/EnableNotificationsButton.js        |   0
 src/skins/{base => vector}/views/atoms/ImageView.js |   0
 .../{base => vector}/views/atoms/LogoutButton.js    |   0
 .../{base => vector}/views/atoms/MemberAvatar.js    |   0
 .../views/atoms/MessageTimestamp.js                 |   0
 .../{base => vector}/views/atoms/RoomAvatar.js      |   0
 .../views/atoms/create_room/CreateRoomButton.js     |   0
 .../views/atoms/create_room/Presets.js              |   0
 .../views/atoms/create_room/RoomAlias.js            |   0
 .../{base => vector}/views/atoms/voip/VideoFeed.js  |   0
 .../views/molecules/BottomLeftMenu.js               |   0
 .../views/molecules/ChangeAvatar.js                 |   0
 .../views/molecules/ChangePassword.js               |   0
 .../views/molecules/ContextualMenu.js               |   0
 .../views/molecules/DateSeparator.js                |   0
 .../views/molecules/EventAsTextTile.js              |   0
 .../{base => vector}/views/molecules/MEmoteTile.js  |   0
 .../{base => vector}/views/molecules/MFileTile.js   |   0
 .../{base => vector}/views/molecules/MImageTile.js  |   0
 .../{base => vector}/views/molecules/MNoticeTile.js |   0
 .../views/molecules/MRoomMemberTile.js              |   0
 .../{base => vector}/views/molecules/MTextTile.js   |   0
 .../views/molecules/MatrixToolbar.js                |   0
 .../{base => vector}/views/molecules/MemberInfo.js  |   0
 .../{base => vector}/views/molecules/MemberTile.js  |   0
 .../views/molecules/MessageComposer.js              |   0
 .../{base => vector}/views/molecules/MessageTile.js |   0
 .../{base => vector}/views/molecules/ProgressBar.js |   0
 .../{base => vector}/views/molecules/RoomCreate.js  |   0
 .../views/molecules/RoomDropTarget.js               |   0
 .../{base => vector}/views/molecules/RoomHeader.js  |   0
 .../views/molecules/RoomSettings.js                 |   0
 .../{base => vector}/views/molecules/RoomTile.js    |   0
 .../views/molecules/SenderProfile.js                |   0
 .../views/molecules/ServerConfig.js                 |   0
 .../views/molecules/UnknownMessageTile.js           |   0
 .../views/molecules/UserSelector.js                 |   0
 .../views/molecules/voip/CallView.js                |   0
 .../views/molecules/voip/IncomingCallBox.js         |   0
 .../views/molecules/voip/VideoView.js               |   0
 .../{base => vector}/views/organisms/CreateRoom.js  |   0
 .../{base => vector}/views/organisms/ErrorDialog.js |   0
 .../{base => vector}/views/organisms/LeftPanel.js   |   0
 .../views/organisms/LogoutPrompt.js                 |   0
 .../{base => vector}/views/organisms/MemberList.js  |   0
 .../{base => vector}/views/organisms/Notifier.js    |   0
 .../views/organisms/QuestionDialog.js               |   0
 .../{base => vector}/views/organisms/RightPanel.js  |   0
 .../views/organisms/RoomDirectory.js                |   0
 .../{base => vector}/views/organisms/RoomList.js    |   0
 .../{base => vector}/views/organisms/RoomView.js    |   0
 .../views/organisms/UserSettings.js                 |   0
 .../{base => vector}/views/pages/MatrixChat.js      |   0
 src/skins/{base => vector}/views/templates/Login.js |   0
 .../{base => vector}/views/templates/Register.js    |   0
 146 files changed, 0 insertions(+), 0 deletions(-)
 rename src/skins/{base => vector}/css/atoms/MemberAvatar.css (100%)
 rename src/skins/{base => vector}/css/atoms/MessageTimestamp.css (100%)
 rename src/skins/{base => vector}/css/common.css (100%)
 rename src/skins/{base => vector}/css/hide.css (100%)
 rename src/skins/{base => vector}/css/molecules/MImageTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/MNoticeTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/MTextTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/MatrixToolbar.css (100%)
 rename src/skins/{base => vector}/css/molecules/MemberInfo.css (100%)
 rename src/skins/{base => vector}/css/molecules/MemberTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/MessageComposer.css (100%)
 rename src/skins/{base => vector}/css/molecules/MessageTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/ProgressBar.css (100%)
 rename src/skins/{base => vector}/css/molecules/RoomDropTarget.css (100%)
 rename src/skins/{base => vector}/css/molecules/RoomHeader.css (100%)
 rename src/skins/{base => vector}/css/molecules/RoomSettings.css (100%)
 rename src/skins/{base => vector}/css/molecules/RoomTile.css (100%)
 rename src/skins/{base => vector}/css/molecules/SenderProfile.css (100%)
 rename src/skins/{base => vector}/css/molecules/ServerConfig.css (100%)
 rename src/skins/{base => vector}/css/molecules/voip/CallView.css (100%)
 rename src/skins/{base => vector}/css/molecules/voip/IncomingCallbox.css (100%)
 rename src/skins/{base => vector}/css/molecules/voip/VideoView.css (100%)
 rename src/skins/{base => vector}/css/organisms/CreateRoom.css (100%)
 rename src/skins/{base => vector}/css/organisms/LeftPanel.css (100%)
 rename src/skins/{base => vector}/css/organisms/MemberList.css (100%)
 rename src/skins/{base => vector}/css/organisms/RightPanel.css (100%)
 rename src/skins/{base => vector}/css/organisms/RoomDirectory.css (100%)
 rename src/skins/{base => vector}/css/organisms/RoomList.css (100%)
 rename src/skins/{base => vector}/css/organisms/RoomView.css (100%)
 rename src/skins/{base => vector}/css/organisms/UserSettings.css (100%)
 rename src/skins/{base => vector}/css/pages/MatrixChat.css (100%)
 rename src/skins/{base => vector}/css/templates/Login.css (100%)
 rename src/skins/{base => vector}/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 (100%)
 rename src/skins/{base => vector}/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 (100%)
 rename src/skins/{base => vector}/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 (100%)
 rename src/skins/{base => vector}/fonts/Lato.css (100%)
 rename src/skins/{base => vector}/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 (100%)
 rename src/skins/{base => vector}/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 (100%)
 rename src/skins/{base => vector}/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 (100%)
 rename src/skins/{base => vector}/img/attach.png (100%)
 rename src/skins/{base => vector}/img/chevron-left.png (100%)
 rename src/skins/{base => vector}/img/chevron-right.png (100%)
 rename src/skins/{base => vector}/img/chevron.png (100%)
 rename src/skins/{base => vector}/img/close-white.png (100%)
 rename src/skins/{base => vector}/img/create-big.png (100%)
 rename src/skins/{base => vector}/img/create.png (100%)
 rename src/skins/{base => vector}/img/delete.png (100%)
 rename src/skins/{base => vector}/img/directory-big.png (100%)
 rename src/skins/{base => vector}/img/download.png (100%)
 rename src/skins/{base => vector}/img/edit.png (100%)
 rename src/skins/{base => vector}/img/file.png (100%)
 rename src/skins/{base => vector}/img/filegrid.png (100%)
 rename src/skins/{base => vector}/img/filelist.png (100%)
 rename src/skins/{base => vector}/img/hide.png (100%)
 rename src/skins/{base => vector}/img/info.png (100%)
 rename src/skins/{base => vector}/img/logo.png (100%)
 rename src/skins/{base => vector}/img/members.png (100%)
 rename src/skins/{base => vector}/img/menu.png (100%)
 rename src/skins/{base => vector}/img/newmessages.png (100%)
 rename src/skins/{base => vector}/img/p/p0.png (100%)
 rename src/skins/{base => vector}/img/p/p1.png (100%)
 rename src/skins/{base => vector}/img/p/p10.png (100%)
 rename src/skins/{base => vector}/img/p/p11.png (100%)
 rename src/skins/{base => vector}/img/p/p12.png (100%)
 rename src/skins/{base => vector}/img/p/p13.png (100%)
 rename src/skins/{base => vector}/img/p/p14.png (100%)
 rename src/skins/{base => vector}/img/p/p15.png (100%)
 rename src/skins/{base => vector}/img/p/p16.png (100%)
 rename src/skins/{base => vector}/img/p/p17.png (100%)
 rename src/skins/{base => vector}/img/p/p18.png (100%)
 rename src/skins/{base => vector}/img/p/p19.png (100%)
 rename src/skins/{base => vector}/img/p/p2.png (100%)
 rename src/skins/{base => vector}/img/p/p20.png (100%)
 rename src/skins/{base => vector}/img/p/p3.png (100%)
 rename src/skins/{base => vector}/img/p/p4.png (100%)
 rename src/skins/{base => vector}/img/p/p5.png (100%)
 rename src/skins/{base => vector}/img/p/p6.png (100%)
 rename src/skins/{base => vector}/img/p/p7.png (100%)
 rename src/skins/{base => vector}/img/p/p8.png (100%)
 rename src/skins/{base => vector}/img/p/p9.png (100%)
 rename src/skins/{base => vector}/img/p/piechart.pde (100%)
 rename src/skins/{base => vector}/img/placeholder.png (100%)
 rename src/skins/{base => vector}/img/search.png (100%)
 rename src/skins/{base => vector}/img/settings-big.png (100%)
 rename src/skins/{base => vector}/img/settings.png (100%)
 rename src/skins/{base => vector}/img/typing.png (100%)
 rename src/skins/{base => vector}/img/upload-big.png (100%)
 rename src/skins/{base => vector}/img/upload.png (100%)
 rename src/skins/{base => vector}/img/video.png (100%)
 rename src/skins/{base => vector}/img/voip.png (100%)
 rename src/skins/{base => vector}/views/atoms/EditableText.js (100%)
 rename src/skins/{base => vector}/views/atoms/EnableNotificationsButton.js (100%)
 rename src/skins/{base => vector}/views/atoms/ImageView.js (100%)
 rename src/skins/{base => vector}/views/atoms/LogoutButton.js (100%)
 rename src/skins/{base => vector}/views/atoms/MemberAvatar.js (100%)
 rename src/skins/{base => vector}/views/atoms/MessageTimestamp.js (100%)
 rename src/skins/{base => vector}/views/atoms/RoomAvatar.js (100%)
 rename src/skins/{base => vector}/views/atoms/create_room/CreateRoomButton.js (100%)
 rename src/skins/{base => vector}/views/atoms/create_room/Presets.js (100%)
 rename src/skins/{base => vector}/views/atoms/create_room/RoomAlias.js (100%)
 rename src/skins/{base => vector}/views/atoms/voip/VideoFeed.js (100%)
 rename src/skins/{base => vector}/views/molecules/BottomLeftMenu.js (100%)
 rename src/skins/{base => vector}/views/molecules/ChangeAvatar.js (100%)
 rename src/skins/{base => vector}/views/molecules/ChangePassword.js (100%)
 rename src/skins/{base => vector}/views/molecules/ContextualMenu.js (100%)
 rename src/skins/{base => vector}/views/molecules/DateSeparator.js (100%)
 rename src/skins/{base => vector}/views/molecules/EventAsTextTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MEmoteTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MFileTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MImageTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MNoticeTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MRoomMemberTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MTextTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MatrixToolbar.js (100%)
 rename src/skins/{base => vector}/views/molecules/MemberInfo.js (100%)
 rename src/skins/{base => vector}/views/molecules/MemberTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/MessageComposer.js (100%)
 rename src/skins/{base => vector}/views/molecules/MessageTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/ProgressBar.js (100%)
 rename src/skins/{base => vector}/views/molecules/RoomCreate.js (100%)
 rename src/skins/{base => vector}/views/molecules/RoomDropTarget.js (100%)
 rename src/skins/{base => vector}/views/molecules/RoomHeader.js (100%)
 rename src/skins/{base => vector}/views/molecules/RoomSettings.js (100%)
 rename src/skins/{base => vector}/views/molecules/RoomTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/SenderProfile.js (100%)
 rename src/skins/{base => vector}/views/molecules/ServerConfig.js (100%)
 rename src/skins/{base => vector}/views/molecules/UnknownMessageTile.js (100%)
 rename src/skins/{base => vector}/views/molecules/UserSelector.js (100%)
 rename src/skins/{base => vector}/views/molecules/voip/CallView.js (100%)
 rename src/skins/{base => vector}/views/molecules/voip/IncomingCallBox.js (100%)
 rename src/skins/{base => vector}/views/molecules/voip/VideoView.js (100%)
 rename src/skins/{base => vector}/views/organisms/CreateRoom.js (100%)
 rename src/skins/{base => vector}/views/organisms/ErrorDialog.js (100%)
 rename src/skins/{base => vector}/views/organisms/LeftPanel.js (100%)
 rename src/skins/{base => vector}/views/organisms/LogoutPrompt.js (100%)
 rename src/skins/{base => vector}/views/organisms/MemberList.js (100%)
 rename src/skins/{base => vector}/views/organisms/Notifier.js (100%)
 rename src/skins/{base => vector}/views/organisms/QuestionDialog.js (100%)
 rename src/skins/{base => vector}/views/organisms/RightPanel.js (100%)
 rename src/skins/{base => vector}/views/organisms/RoomDirectory.js (100%)
 rename src/skins/{base => vector}/views/organisms/RoomList.js (100%)
 rename src/skins/{base => vector}/views/organisms/RoomView.js (100%)
 rename src/skins/{base => vector}/views/organisms/UserSettings.js (100%)
 rename src/skins/{base => vector}/views/pages/MatrixChat.js (100%)
 rename src/skins/{base => vector}/views/templates/Login.js (100%)
 rename src/skins/{base => vector}/views/templates/Register.js (100%)

diff --git a/src/skins/base/css/atoms/MemberAvatar.css b/src/skins/vector/css/atoms/MemberAvatar.css
similarity index 100%
rename from src/skins/base/css/atoms/MemberAvatar.css
rename to src/skins/vector/css/atoms/MemberAvatar.css
diff --git a/src/skins/base/css/atoms/MessageTimestamp.css b/src/skins/vector/css/atoms/MessageTimestamp.css
similarity index 100%
rename from src/skins/base/css/atoms/MessageTimestamp.css
rename to src/skins/vector/css/atoms/MessageTimestamp.css
diff --git a/src/skins/base/css/common.css b/src/skins/vector/css/common.css
similarity index 100%
rename from src/skins/base/css/common.css
rename to src/skins/vector/css/common.css
diff --git a/src/skins/base/css/hide.css b/src/skins/vector/css/hide.css
similarity index 100%
rename from src/skins/base/css/hide.css
rename to src/skins/vector/css/hide.css
diff --git a/src/skins/base/css/molecules/MImageTile.css b/src/skins/vector/css/molecules/MImageTile.css
similarity index 100%
rename from src/skins/base/css/molecules/MImageTile.css
rename to src/skins/vector/css/molecules/MImageTile.css
diff --git a/src/skins/base/css/molecules/MNoticeTile.css b/src/skins/vector/css/molecules/MNoticeTile.css
similarity index 100%
rename from src/skins/base/css/molecules/MNoticeTile.css
rename to src/skins/vector/css/molecules/MNoticeTile.css
diff --git a/src/skins/base/css/molecules/MTextTile.css b/src/skins/vector/css/molecules/MTextTile.css
similarity index 100%
rename from src/skins/base/css/molecules/MTextTile.css
rename to src/skins/vector/css/molecules/MTextTile.css
diff --git a/src/skins/base/css/molecules/MatrixToolbar.css b/src/skins/vector/css/molecules/MatrixToolbar.css
similarity index 100%
rename from src/skins/base/css/molecules/MatrixToolbar.css
rename to src/skins/vector/css/molecules/MatrixToolbar.css
diff --git a/src/skins/base/css/molecules/MemberInfo.css b/src/skins/vector/css/molecules/MemberInfo.css
similarity index 100%
rename from src/skins/base/css/molecules/MemberInfo.css
rename to src/skins/vector/css/molecules/MemberInfo.css
diff --git a/src/skins/base/css/molecules/MemberTile.css b/src/skins/vector/css/molecules/MemberTile.css
similarity index 100%
rename from src/skins/base/css/molecules/MemberTile.css
rename to src/skins/vector/css/molecules/MemberTile.css
diff --git a/src/skins/base/css/molecules/MessageComposer.css b/src/skins/vector/css/molecules/MessageComposer.css
similarity index 100%
rename from src/skins/base/css/molecules/MessageComposer.css
rename to src/skins/vector/css/molecules/MessageComposer.css
diff --git a/src/skins/base/css/molecules/MessageTile.css b/src/skins/vector/css/molecules/MessageTile.css
similarity index 100%
rename from src/skins/base/css/molecules/MessageTile.css
rename to src/skins/vector/css/molecules/MessageTile.css
diff --git a/src/skins/base/css/molecules/ProgressBar.css b/src/skins/vector/css/molecules/ProgressBar.css
similarity index 100%
rename from src/skins/base/css/molecules/ProgressBar.css
rename to src/skins/vector/css/molecules/ProgressBar.css
diff --git a/src/skins/base/css/molecules/RoomDropTarget.css b/src/skins/vector/css/molecules/RoomDropTarget.css
similarity index 100%
rename from src/skins/base/css/molecules/RoomDropTarget.css
rename to src/skins/vector/css/molecules/RoomDropTarget.css
diff --git a/src/skins/base/css/molecules/RoomHeader.css b/src/skins/vector/css/molecules/RoomHeader.css
similarity index 100%
rename from src/skins/base/css/molecules/RoomHeader.css
rename to src/skins/vector/css/molecules/RoomHeader.css
diff --git a/src/skins/base/css/molecules/RoomSettings.css b/src/skins/vector/css/molecules/RoomSettings.css
similarity index 100%
rename from src/skins/base/css/molecules/RoomSettings.css
rename to src/skins/vector/css/molecules/RoomSettings.css
diff --git a/src/skins/base/css/molecules/RoomTile.css b/src/skins/vector/css/molecules/RoomTile.css
similarity index 100%
rename from src/skins/base/css/molecules/RoomTile.css
rename to src/skins/vector/css/molecules/RoomTile.css
diff --git a/src/skins/base/css/molecules/SenderProfile.css b/src/skins/vector/css/molecules/SenderProfile.css
similarity index 100%
rename from src/skins/base/css/molecules/SenderProfile.css
rename to src/skins/vector/css/molecules/SenderProfile.css
diff --git a/src/skins/base/css/molecules/ServerConfig.css b/src/skins/vector/css/molecules/ServerConfig.css
similarity index 100%
rename from src/skins/base/css/molecules/ServerConfig.css
rename to src/skins/vector/css/molecules/ServerConfig.css
diff --git a/src/skins/base/css/molecules/voip/CallView.css b/src/skins/vector/css/molecules/voip/CallView.css
similarity index 100%
rename from src/skins/base/css/molecules/voip/CallView.css
rename to src/skins/vector/css/molecules/voip/CallView.css
diff --git a/src/skins/base/css/molecules/voip/IncomingCallbox.css b/src/skins/vector/css/molecules/voip/IncomingCallbox.css
similarity index 100%
rename from src/skins/base/css/molecules/voip/IncomingCallbox.css
rename to src/skins/vector/css/molecules/voip/IncomingCallbox.css
diff --git a/src/skins/base/css/molecules/voip/VideoView.css b/src/skins/vector/css/molecules/voip/VideoView.css
similarity index 100%
rename from src/skins/base/css/molecules/voip/VideoView.css
rename to src/skins/vector/css/molecules/voip/VideoView.css
diff --git a/src/skins/base/css/organisms/CreateRoom.css b/src/skins/vector/css/organisms/CreateRoom.css
similarity index 100%
rename from src/skins/base/css/organisms/CreateRoom.css
rename to src/skins/vector/css/organisms/CreateRoom.css
diff --git a/src/skins/base/css/organisms/LeftPanel.css b/src/skins/vector/css/organisms/LeftPanel.css
similarity index 100%
rename from src/skins/base/css/organisms/LeftPanel.css
rename to src/skins/vector/css/organisms/LeftPanel.css
diff --git a/src/skins/base/css/organisms/MemberList.css b/src/skins/vector/css/organisms/MemberList.css
similarity index 100%
rename from src/skins/base/css/organisms/MemberList.css
rename to src/skins/vector/css/organisms/MemberList.css
diff --git a/src/skins/base/css/organisms/RightPanel.css b/src/skins/vector/css/organisms/RightPanel.css
similarity index 100%
rename from src/skins/base/css/organisms/RightPanel.css
rename to src/skins/vector/css/organisms/RightPanel.css
diff --git a/src/skins/base/css/organisms/RoomDirectory.css b/src/skins/vector/css/organisms/RoomDirectory.css
similarity index 100%
rename from src/skins/base/css/organisms/RoomDirectory.css
rename to src/skins/vector/css/organisms/RoomDirectory.css
diff --git a/src/skins/base/css/organisms/RoomList.css b/src/skins/vector/css/organisms/RoomList.css
similarity index 100%
rename from src/skins/base/css/organisms/RoomList.css
rename to src/skins/vector/css/organisms/RoomList.css
diff --git a/src/skins/base/css/organisms/RoomView.css b/src/skins/vector/css/organisms/RoomView.css
similarity index 100%
rename from src/skins/base/css/organisms/RoomView.css
rename to src/skins/vector/css/organisms/RoomView.css
diff --git a/src/skins/base/css/organisms/UserSettings.css b/src/skins/vector/css/organisms/UserSettings.css
similarity index 100%
rename from src/skins/base/css/organisms/UserSettings.css
rename to src/skins/vector/css/organisms/UserSettings.css
diff --git a/src/skins/base/css/pages/MatrixChat.css b/src/skins/vector/css/pages/MatrixChat.css
similarity index 100%
rename from src/skins/base/css/pages/MatrixChat.css
rename to src/skins/vector/css/pages/MatrixChat.css
diff --git a/src/skins/base/css/templates/Login.css b/src/skins/vector/css/templates/Login.css
similarity index 100%
rename from src/skins/base/css/templates/Login.css
rename to src/skins/vector/css/templates/Login.css
diff --git a/src/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/vector/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from src/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/vector/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/src/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 b/src/skins/vector/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
similarity index 100%
rename from src/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
rename to src/skins/vector/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
diff --git a/src/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/vector/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from src/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/vector/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/src/skins/base/fonts/Lato.css b/src/skins/vector/fonts/Lato.css
similarity index 100%
rename from src/skins/base/fonts/Lato.css
rename to src/skins/vector/fonts/Lato.css
diff --git a/src/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2 b/src/skins/vector/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
similarity index 100%
rename from src/skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
rename to src/skins/vector/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
diff --git a/src/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/vector/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from src/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/vector/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/src/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/vector/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from src/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/vector/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/src/skins/base/img/attach.png b/src/skins/vector/img/attach.png
similarity index 100%
rename from src/skins/base/img/attach.png
rename to src/skins/vector/img/attach.png
diff --git a/src/skins/base/img/chevron-left.png b/src/skins/vector/img/chevron-left.png
similarity index 100%
rename from src/skins/base/img/chevron-left.png
rename to src/skins/vector/img/chevron-left.png
diff --git a/src/skins/base/img/chevron-right.png b/src/skins/vector/img/chevron-right.png
similarity index 100%
rename from src/skins/base/img/chevron-right.png
rename to src/skins/vector/img/chevron-right.png
diff --git a/src/skins/base/img/chevron.png b/src/skins/vector/img/chevron.png
similarity index 100%
rename from src/skins/base/img/chevron.png
rename to src/skins/vector/img/chevron.png
diff --git a/src/skins/base/img/close-white.png b/src/skins/vector/img/close-white.png
similarity index 100%
rename from src/skins/base/img/close-white.png
rename to src/skins/vector/img/close-white.png
diff --git a/src/skins/base/img/create-big.png b/src/skins/vector/img/create-big.png
similarity index 100%
rename from src/skins/base/img/create-big.png
rename to src/skins/vector/img/create-big.png
diff --git a/src/skins/base/img/create.png b/src/skins/vector/img/create.png
similarity index 100%
rename from src/skins/base/img/create.png
rename to src/skins/vector/img/create.png
diff --git a/src/skins/base/img/delete.png b/src/skins/vector/img/delete.png
similarity index 100%
rename from src/skins/base/img/delete.png
rename to src/skins/vector/img/delete.png
diff --git a/src/skins/base/img/directory-big.png b/src/skins/vector/img/directory-big.png
similarity index 100%
rename from src/skins/base/img/directory-big.png
rename to src/skins/vector/img/directory-big.png
diff --git a/src/skins/base/img/download.png b/src/skins/vector/img/download.png
similarity index 100%
rename from src/skins/base/img/download.png
rename to src/skins/vector/img/download.png
diff --git a/src/skins/base/img/edit.png b/src/skins/vector/img/edit.png
similarity index 100%
rename from src/skins/base/img/edit.png
rename to src/skins/vector/img/edit.png
diff --git a/src/skins/base/img/file.png b/src/skins/vector/img/file.png
similarity index 100%
rename from src/skins/base/img/file.png
rename to src/skins/vector/img/file.png
diff --git a/src/skins/base/img/filegrid.png b/src/skins/vector/img/filegrid.png
similarity index 100%
rename from src/skins/base/img/filegrid.png
rename to src/skins/vector/img/filegrid.png
diff --git a/src/skins/base/img/filelist.png b/src/skins/vector/img/filelist.png
similarity index 100%
rename from src/skins/base/img/filelist.png
rename to src/skins/vector/img/filelist.png
diff --git a/src/skins/base/img/hide.png b/src/skins/vector/img/hide.png
similarity index 100%
rename from src/skins/base/img/hide.png
rename to src/skins/vector/img/hide.png
diff --git a/src/skins/base/img/info.png b/src/skins/vector/img/info.png
similarity index 100%
rename from src/skins/base/img/info.png
rename to src/skins/vector/img/info.png
diff --git a/src/skins/base/img/logo.png b/src/skins/vector/img/logo.png
similarity index 100%
rename from src/skins/base/img/logo.png
rename to src/skins/vector/img/logo.png
diff --git a/src/skins/base/img/members.png b/src/skins/vector/img/members.png
similarity index 100%
rename from src/skins/base/img/members.png
rename to src/skins/vector/img/members.png
diff --git a/src/skins/base/img/menu.png b/src/skins/vector/img/menu.png
similarity index 100%
rename from src/skins/base/img/menu.png
rename to src/skins/vector/img/menu.png
diff --git a/src/skins/base/img/newmessages.png b/src/skins/vector/img/newmessages.png
similarity index 100%
rename from src/skins/base/img/newmessages.png
rename to src/skins/vector/img/newmessages.png
diff --git a/src/skins/base/img/p/p0.png b/src/skins/vector/img/p/p0.png
similarity index 100%
rename from src/skins/base/img/p/p0.png
rename to src/skins/vector/img/p/p0.png
diff --git a/src/skins/base/img/p/p1.png b/src/skins/vector/img/p/p1.png
similarity index 100%
rename from src/skins/base/img/p/p1.png
rename to src/skins/vector/img/p/p1.png
diff --git a/src/skins/base/img/p/p10.png b/src/skins/vector/img/p/p10.png
similarity index 100%
rename from src/skins/base/img/p/p10.png
rename to src/skins/vector/img/p/p10.png
diff --git a/src/skins/base/img/p/p11.png b/src/skins/vector/img/p/p11.png
similarity index 100%
rename from src/skins/base/img/p/p11.png
rename to src/skins/vector/img/p/p11.png
diff --git a/src/skins/base/img/p/p12.png b/src/skins/vector/img/p/p12.png
similarity index 100%
rename from src/skins/base/img/p/p12.png
rename to src/skins/vector/img/p/p12.png
diff --git a/src/skins/base/img/p/p13.png b/src/skins/vector/img/p/p13.png
similarity index 100%
rename from src/skins/base/img/p/p13.png
rename to src/skins/vector/img/p/p13.png
diff --git a/src/skins/base/img/p/p14.png b/src/skins/vector/img/p/p14.png
similarity index 100%
rename from src/skins/base/img/p/p14.png
rename to src/skins/vector/img/p/p14.png
diff --git a/src/skins/base/img/p/p15.png b/src/skins/vector/img/p/p15.png
similarity index 100%
rename from src/skins/base/img/p/p15.png
rename to src/skins/vector/img/p/p15.png
diff --git a/src/skins/base/img/p/p16.png b/src/skins/vector/img/p/p16.png
similarity index 100%
rename from src/skins/base/img/p/p16.png
rename to src/skins/vector/img/p/p16.png
diff --git a/src/skins/base/img/p/p17.png b/src/skins/vector/img/p/p17.png
similarity index 100%
rename from src/skins/base/img/p/p17.png
rename to src/skins/vector/img/p/p17.png
diff --git a/src/skins/base/img/p/p18.png b/src/skins/vector/img/p/p18.png
similarity index 100%
rename from src/skins/base/img/p/p18.png
rename to src/skins/vector/img/p/p18.png
diff --git a/src/skins/base/img/p/p19.png b/src/skins/vector/img/p/p19.png
similarity index 100%
rename from src/skins/base/img/p/p19.png
rename to src/skins/vector/img/p/p19.png
diff --git a/src/skins/base/img/p/p2.png b/src/skins/vector/img/p/p2.png
similarity index 100%
rename from src/skins/base/img/p/p2.png
rename to src/skins/vector/img/p/p2.png
diff --git a/src/skins/base/img/p/p20.png b/src/skins/vector/img/p/p20.png
similarity index 100%
rename from src/skins/base/img/p/p20.png
rename to src/skins/vector/img/p/p20.png
diff --git a/src/skins/base/img/p/p3.png b/src/skins/vector/img/p/p3.png
similarity index 100%
rename from src/skins/base/img/p/p3.png
rename to src/skins/vector/img/p/p3.png
diff --git a/src/skins/base/img/p/p4.png b/src/skins/vector/img/p/p4.png
similarity index 100%
rename from src/skins/base/img/p/p4.png
rename to src/skins/vector/img/p/p4.png
diff --git a/src/skins/base/img/p/p5.png b/src/skins/vector/img/p/p5.png
similarity index 100%
rename from src/skins/base/img/p/p5.png
rename to src/skins/vector/img/p/p5.png
diff --git a/src/skins/base/img/p/p6.png b/src/skins/vector/img/p/p6.png
similarity index 100%
rename from src/skins/base/img/p/p6.png
rename to src/skins/vector/img/p/p6.png
diff --git a/src/skins/base/img/p/p7.png b/src/skins/vector/img/p/p7.png
similarity index 100%
rename from src/skins/base/img/p/p7.png
rename to src/skins/vector/img/p/p7.png
diff --git a/src/skins/base/img/p/p8.png b/src/skins/vector/img/p/p8.png
similarity index 100%
rename from src/skins/base/img/p/p8.png
rename to src/skins/vector/img/p/p8.png
diff --git a/src/skins/base/img/p/p9.png b/src/skins/vector/img/p/p9.png
similarity index 100%
rename from src/skins/base/img/p/p9.png
rename to src/skins/vector/img/p/p9.png
diff --git a/src/skins/base/img/p/piechart.pde b/src/skins/vector/img/p/piechart.pde
similarity index 100%
rename from src/skins/base/img/p/piechart.pde
rename to src/skins/vector/img/p/piechart.pde
diff --git a/src/skins/base/img/placeholder.png b/src/skins/vector/img/placeholder.png
similarity index 100%
rename from src/skins/base/img/placeholder.png
rename to src/skins/vector/img/placeholder.png
diff --git a/src/skins/base/img/search.png b/src/skins/vector/img/search.png
similarity index 100%
rename from src/skins/base/img/search.png
rename to src/skins/vector/img/search.png
diff --git a/src/skins/base/img/settings-big.png b/src/skins/vector/img/settings-big.png
similarity index 100%
rename from src/skins/base/img/settings-big.png
rename to src/skins/vector/img/settings-big.png
diff --git a/src/skins/base/img/settings.png b/src/skins/vector/img/settings.png
similarity index 100%
rename from src/skins/base/img/settings.png
rename to src/skins/vector/img/settings.png
diff --git a/src/skins/base/img/typing.png b/src/skins/vector/img/typing.png
similarity index 100%
rename from src/skins/base/img/typing.png
rename to src/skins/vector/img/typing.png
diff --git a/src/skins/base/img/upload-big.png b/src/skins/vector/img/upload-big.png
similarity index 100%
rename from src/skins/base/img/upload-big.png
rename to src/skins/vector/img/upload-big.png
diff --git a/src/skins/base/img/upload.png b/src/skins/vector/img/upload.png
similarity index 100%
rename from src/skins/base/img/upload.png
rename to src/skins/vector/img/upload.png
diff --git a/src/skins/base/img/video.png b/src/skins/vector/img/video.png
similarity index 100%
rename from src/skins/base/img/video.png
rename to src/skins/vector/img/video.png
diff --git a/src/skins/base/img/voip.png b/src/skins/vector/img/voip.png
similarity index 100%
rename from src/skins/base/img/voip.png
rename to src/skins/vector/img/voip.png
diff --git a/src/skins/base/views/atoms/EditableText.js b/src/skins/vector/views/atoms/EditableText.js
similarity index 100%
rename from src/skins/base/views/atoms/EditableText.js
rename to src/skins/vector/views/atoms/EditableText.js
diff --git a/src/skins/base/views/atoms/EnableNotificationsButton.js b/src/skins/vector/views/atoms/EnableNotificationsButton.js
similarity index 100%
rename from src/skins/base/views/atoms/EnableNotificationsButton.js
rename to src/skins/vector/views/atoms/EnableNotificationsButton.js
diff --git a/src/skins/base/views/atoms/ImageView.js b/src/skins/vector/views/atoms/ImageView.js
similarity index 100%
rename from src/skins/base/views/atoms/ImageView.js
rename to src/skins/vector/views/atoms/ImageView.js
diff --git a/src/skins/base/views/atoms/LogoutButton.js b/src/skins/vector/views/atoms/LogoutButton.js
similarity index 100%
rename from src/skins/base/views/atoms/LogoutButton.js
rename to src/skins/vector/views/atoms/LogoutButton.js
diff --git a/src/skins/base/views/atoms/MemberAvatar.js b/src/skins/vector/views/atoms/MemberAvatar.js
similarity index 100%
rename from src/skins/base/views/atoms/MemberAvatar.js
rename to src/skins/vector/views/atoms/MemberAvatar.js
diff --git a/src/skins/base/views/atoms/MessageTimestamp.js b/src/skins/vector/views/atoms/MessageTimestamp.js
similarity index 100%
rename from src/skins/base/views/atoms/MessageTimestamp.js
rename to src/skins/vector/views/atoms/MessageTimestamp.js
diff --git a/src/skins/base/views/atoms/RoomAvatar.js b/src/skins/vector/views/atoms/RoomAvatar.js
similarity index 100%
rename from src/skins/base/views/atoms/RoomAvatar.js
rename to src/skins/vector/views/atoms/RoomAvatar.js
diff --git a/src/skins/base/views/atoms/create_room/CreateRoomButton.js b/src/skins/vector/views/atoms/create_room/CreateRoomButton.js
similarity index 100%
rename from src/skins/base/views/atoms/create_room/CreateRoomButton.js
rename to src/skins/vector/views/atoms/create_room/CreateRoomButton.js
diff --git a/src/skins/base/views/atoms/create_room/Presets.js b/src/skins/vector/views/atoms/create_room/Presets.js
similarity index 100%
rename from src/skins/base/views/atoms/create_room/Presets.js
rename to src/skins/vector/views/atoms/create_room/Presets.js
diff --git a/src/skins/base/views/atoms/create_room/RoomAlias.js b/src/skins/vector/views/atoms/create_room/RoomAlias.js
similarity index 100%
rename from src/skins/base/views/atoms/create_room/RoomAlias.js
rename to src/skins/vector/views/atoms/create_room/RoomAlias.js
diff --git a/src/skins/base/views/atoms/voip/VideoFeed.js b/src/skins/vector/views/atoms/voip/VideoFeed.js
similarity index 100%
rename from src/skins/base/views/atoms/voip/VideoFeed.js
rename to src/skins/vector/views/atoms/voip/VideoFeed.js
diff --git a/src/skins/base/views/molecules/BottomLeftMenu.js b/src/skins/vector/views/molecules/BottomLeftMenu.js
similarity index 100%
rename from src/skins/base/views/molecules/BottomLeftMenu.js
rename to src/skins/vector/views/molecules/BottomLeftMenu.js
diff --git a/src/skins/base/views/molecules/ChangeAvatar.js b/src/skins/vector/views/molecules/ChangeAvatar.js
similarity index 100%
rename from src/skins/base/views/molecules/ChangeAvatar.js
rename to src/skins/vector/views/molecules/ChangeAvatar.js
diff --git a/src/skins/base/views/molecules/ChangePassword.js b/src/skins/vector/views/molecules/ChangePassword.js
similarity index 100%
rename from src/skins/base/views/molecules/ChangePassword.js
rename to src/skins/vector/views/molecules/ChangePassword.js
diff --git a/src/skins/base/views/molecules/ContextualMenu.js b/src/skins/vector/views/molecules/ContextualMenu.js
similarity index 100%
rename from src/skins/base/views/molecules/ContextualMenu.js
rename to src/skins/vector/views/molecules/ContextualMenu.js
diff --git a/src/skins/base/views/molecules/DateSeparator.js b/src/skins/vector/views/molecules/DateSeparator.js
similarity index 100%
rename from src/skins/base/views/molecules/DateSeparator.js
rename to src/skins/vector/views/molecules/DateSeparator.js
diff --git a/src/skins/base/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
similarity index 100%
rename from src/skins/base/views/molecules/EventAsTextTile.js
rename to src/skins/vector/views/molecules/EventAsTextTile.js
diff --git a/src/skins/base/views/molecules/MEmoteTile.js b/src/skins/vector/views/molecules/MEmoteTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MEmoteTile.js
rename to src/skins/vector/views/molecules/MEmoteTile.js
diff --git a/src/skins/base/views/molecules/MFileTile.js b/src/skins/vector/views/molecules/MFileTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MFileTile.js
rename to src/skins/vector/views/molecules/MFileTile.js
diff --git a/src/skins/base/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MImageTile.js
rename to src/skins/vector/views/molecules/MImageTile.js
diff --git a/src/skins/base/views/molecules/MNoticeTile.js b/src/skins/vector/views/molecules/MNoticeTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MNoticeTile.js
rename to src/skins/vector/views/molecules/MNoticeTile.js
diff --git a/src/skins/base/views/molecules/MRoomMemberTile.js b/src/skins/vector/views/molecules/MRoomMemberTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MRoomMemberTile.js
rename to src/skins/vector/views/molecules/MRoomMemberTile.js
diff --git a/src/skins/base/views/molecules/MTextTile.js b/src/skins/vector/views/molecules/MTextTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MTextTile.js
rename to src/skins/vector/views/molecules/MTextTile.js
diff --git a/src/skins/base/views/molecules/MatrixToolbar.js b/src/skins/vector/views/molecules/MatrixToolbar.js
similarity index 100%
rename from src/skins/base/views/molecules/MatrixToolbar.js
rename to src/skins/vector/views/molecules/MatrixToolbar.js
diff --git a/src/skins/base/views/molecules/MemberInfo.js b/src/skins/vector/views/molecules/MemberInfo.js
similarity index 100%
rename from src/skins/base/views/molecules/MemberInfo.js
rename to src/skins/vector/views/molecules/MemberInfo.js
diff --git a/src/skins/base/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MemberTile.js
rename to src/skins/vector/views/molecules/MemberTile.js
diff --git a/src/skins/base/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
similarity index 100%
rename from src/skins/base/views/molecules/MessageComposer.js
rename to src/skins/vector/views/molecules/MessageComposer.js
diff --git a/src/skins/base/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
similarity index 100%
rename from src/skins/base/views/molecules/MessageTile.js
rename to src/skins/vector/views/molecules/MessageTile.js
diff --git a/src/skins/base/views/molecules/ProgressBar.js b/src/skins/vector/views/molecules/ProgressBar.js
similarity index 100%
rename from src/skins/base/views/molecules/ProgressBar.js
rename to src/skins/vector/views/molecules/ProgressBar.js
diff --git a/src/skins/base/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
similarity index 100%
rename from src/skins/base/views/molecules/RoomCreate.js
rename to src/skins/vector/views/molecules/RoomCreate.js
diff --git a/src/skins/base/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
similarity index 100%
rename from src/skins/base/views/molecules/RoomDropTarget.js
rename to src/skins/vector/views/molecules/RoomDropTarget.js
diff --git a/src/skins/base/views/molecules/RoomHeader.js b/src/skins/vector/views/molecules/RoomHeader.js
similarity index 100%
rename from src/skins/base/views/molecules/RoomHeader.js
rename to src/skins/vector/views/molecules/RoomHeader.js
diff --git a/src/skins/base/views/molecules/RoomSettings.js b/src/skins/vector/views/molecules/RoomSettings.js
similarity index 100%
rename from src/skins/base/views/molecules/RoomSettings.js
rename to src/skins/vector/views/molecules/RoomSettings.js
diff --git a/src/skins/base/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
similarity index 100%
rename from src/skins/base/views/molecules/RoomTile.js
rename to src/skins/vector/views/molecules/RoomTile.js
diff --git a/src/skins/base/views/molecules/SenderProfile.js b/src/skins/vector/views/molecules/SenderProfile.js
similarity index 100%
rename from src/skins/base/views/molecules/SenderProfile.js
rename to src/skins/vector/views/molecules/SenderProfile.js
diff --git a/src/skins/base/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
similarity index 100%
rename from src/skins/base/views/molecules/ServerConfig.js
rename to src/skins/vector/views/molecules/ServerConfig.js
diff --git a/src/skins/base/views/molecules/UnknownMessageTile.js b/src/skins/vector/views/molecules/UnknownMessageTile.js
similarity index 100%
rename from src/skins/base/views/molecules/UnknownMessageTile.js
rename to src/skins/vector/views/molecules/UnknownMessageTile.js
diff --git a/src/skins/base/views/molecules/UserSelector.js b/src/skins/vector/views/molecules/UserSelector.js
similarity index 100%
rename from src/skins/base/views/molecules/UserSelector.js
rename to src/skins/vector/views/molecules/UserSelector.js
diff --git a/src/skins/base/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
similarity index 100%
rename from src/skins/base/views/molecules/voip/CallView.js
rename to src/skins/vector/views/molecules/voip/CallView.js
diff --git a/src/skins/base/views/molecules/voip/IncomingCallBox.js b/src/skins/vector/views/molecules/voip/IncomingCallBox.js
similarity index 100%
rename from src/skins/base/views/molecules/voip/IncomingCallBox.js
rename to src/skins/vector/views/molecules/voip/IncomingCallBox.js
diff --git a/src/skins/base/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
similarity index 100%
rename from src/skins/base/views/molecules/voip/VideoView.js
rename to src/skins/vector/views/molecules/voip/VideoView.js
diff --git a/src/skins/base/views/organisms/CreateRoom.js b/src/skins/vector/views/organisms/CreateRoom.js
similarity index 100%
rename from src/skins/base/views/organisms/CreateRoom.js
rename to src/skins/vector/views/organisms/CreateRoom.js
diff --git a/src/skins/base/views/organisms/ErrorDialog.js b/src/skins/vector/views/organisms/ErrorDialog.js
similarity index 100%
rename from src/skins/base/views/organisms/ErrorDialog.js
rename to src/skins/vector/views/organisms/ErrorDialog.js
diff --git a/src/skins/base/views/organisms/LeftPanel.js b/src/skins/vector/views/organisms/LeftPanel.js
similarity index 100%
rename from src/skins/base/views/organisms/LeftPanel.js
rename to src/skins/vector/views/organisms/LeftPanel.js
diff --git a/src/skins/base/views/organisms/LogoutPrompt.js b/src/skins/vector/views/organisms/LogoutPrompt.js
similarity index 100%
rename from src/skins/base/views/organisms/LogoutPrompt.js
rename to src/skins/vector/views/organisms/LogoutPrompt.js
diff --git a/src/skins/base/views/organisms/MemberList.js b/src/skins/vector/views/organisms/MemberList.js
similarity index 100%
rename from src/skins/base/views/organisms/MemberList.js
rename to src/skins/vector/views/organisms/MemberList.js
diff --git a/src/skins/base/views/organisms/Notifier.js b/src/skins/vector/views/organisms/Notifier.js
similarity index 100%
rename from src/skins/base/views/organisms/Notifier.js
rename to src/skins/vector/views/organisms/Notifier.js
diff --git a/src/skins/base/views/organisms/QuestionDialog.js b/src/skins/vector/views/organisms/QuestionDialog.js
similarity index 100%
rename from src/skins/base/views/organisms/QuestionDialog.js
rename to src/skins/vector/views/organisms/QuestionDialog.js
diff --git a/src/skins/base/views/organisms/RightPanel.js b/src/skins/vector/views/organisms/RightPanel.js
similarity index 100%
rename from src/skins/base/views/organisms/RightPanel.js
rename to src/skins/vector/views/organisms/RightPanel.js
diff --git a/src/skins/base/views/organisms/RoomDirectory.js b/src/skins/vector/views/organisms/RoomDirectory.js
similarity index 100%
rename from src/skins/base/views/organisms/RoomDirectory.js
rename to src/skins/vector/views/organisms/RoomDirectory.js
diff --git a/src/skins/base/views/organisms/RoomList.js b/src/skins/vector/views/organisms/RoomList.js
similarity index 100%
rename from src/skins/base/views/organisms/RoomList.js
rename to src/skins/vector/views/organisms/RoomList.js
diff --git a/src/skins/base/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js
similarity index 100%
rename from src/skins/base/views/organisms/RoomView.js
rename to src/skins/vector/views/organisms/RoomView.js
diff --git a/src/skins/base/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
similarity index 100%
rename from src/skins/base/views/organisms/UserSettings.js
rename to src/skins/vector/views/organisms/UserSettings.js
diff --git a/src/skins/base/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
similarity index 100%
rename from src/skins/base/views/pages/MatrixChat.js
rename to src/skins/vector/views/pages/MatrixChat.js
diff --git a/src/skins/base/views/templates/Login.js b/src/skins/vector/views/templates/Login.js
similarity index 100%
rename from src/skins/base/views/templates/Login.js
rename to src/skins/vector/views/templates/Login.js
diff --git a/src/skins/base/views/templates/Register.js b/src/skins/vector/views/templates/Register.js
similarity index 100%
rename from src/skins/base/views/templates/Register.js
rename to src/skins/vector/views/templates/Register.js

From dd4cfb25f8ad6626336bc817798d005d43b2bf55 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 18:06:43 +0100
Subject: [PATCH 08/29] Replace symlinks

---
 vector/fonts | 1 +
 vector/img   | 1 +
 2 files changed, 2 insertions(+)
 create mode 120000 vector/fonts
 create mode 120000 vector/img

diff --git a/vector/fonts b/vector/fonts
new file mode 120000
index 00000000..7df9446b
--- /dev/null
+++ b/vector/fonts
@@ -0,0 +1 @@
+src/skins/vector/fonts
\ No newline at end of file
diff --git a/vector/img b/vector/img
new file mode 120000
index 00000000..52ed4fae
--- /dev/null
+++ b/vector/img
@@ -0,0 +1 @@
+src/skins/vector/img
\ No newline at end of file

From 40594fc5fa0c44577306ccafea58810913a4d7ac Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 18:17:19 +0100
Subject: [PATCH 09/29] Fix up controller requires

---
 src/skins/vector/views/atoms/EditableText.js                 | 2 +-
 src/skins/vector/views/atoms/EnableNotificationsButton.js    | 2 +-
 src/skins/vector/views/atoms/ImageView.js                    | 2 +-
 src/skins/vector/views/atoms/LogoutButton.js                 | 2 +-
 src/skins/vector/views/atoms/MemberAvatar.js                 | 2 +-
 src/skins/vector/views/atoms/MessageTimestamp.js             | 2 +-
 src/skins/vector/views/atoms/RoomAvatar.js                   | 2 +-
 src/skins/vector/views/atoms/create_room/CreateRoomButton.js | 2 +-
 src/skins/vector/views/atoms/create_room/Presets.js          | 2 +-
 src/skins/vector/views/atoms/create_room/RoomAlias.js        | 2 +-
 src/skins/vector/views/atoms/voip/VideoFeed.js               | 2 +-
 src/skins/vector/views/molecules/ChangeAvatar.js             | 2 +-
 src/skins/vector/views/molecules/ChangePassword.js           | 2 +-
 src/skins/vector/views/molecules/EventAsTextTile.js          | 2 +-
 src/skins/vector/views/molecules/MEmoteTile.js               | 2 +-
 src/skins/vector/views/molecules/MFileTile.js                | 2 +-
 src/skins/vector/views/molecules/MImageTile.js               | 2 +-
 src/skins/vector/views/molecules/MNoticeTile.js              | 2 +-
 src/skins/vector/views/molecules/MRoomMemberTile.js          | 2 +-
 src/skins/vector/views/molecules/MTextTile.js                | 2 +-
 src/skins/vector/views/molecules/MatrixToolbar.js            | 2 +-
 src/skins/vector/views/molecules/MemberInfo.js               | 2 +-
 src/skins/vector/views/molecules/MemberTile.js               | 2 +-
 src/skins/vector/views/molecules/MessageComposer.js          | 2 +-
 src/skins/vector/views/molecules/MessageTile.js              | 2 +-
 src/skins/vector/views/molecules/ProgressBar.js              | 2 +-
 src/skins/vector/views/molecules/RoomCreate.js               | 2 +-
 src/skins/vector/views/molecules/RoomDropTarget.js           | 2 +-
 src/skins/vector/views/molecules/RoomHeader.js               | 2 +-
 src/skins/vector/views/molecules/RoomSettings.js             | 2 +-
 src/skins/vector/views/molecules/RoomTile.js                 | 2 +-
 src/skins/vector/views/molecules/SenderProfile.js            | 2 +-
 src/skins/vector/views/molecules/ServerConfig.js             | 2 +-
 src/skins/vector/views/molecules/UnknownMessageTile.js       | 2 +-
 src/skins/vector/views/molecules/UserSelector.js             | 2 +-
 src/skins/vector/views/molecules/voip/CallView.js            | 2 +-
 src/skins/vector/views/molecules/voip/VideoView.js           | 4 ++--
 src/skins/vector/views/organisms/CreateRoom.js               | 2 +-
 src/skins/vector/views/organisms/ErrorDialog.js              | 2 +-
 src/skins/vector/views/organisms/LogoutPrompt.js             | 2 +-
 src/skins/vector/views/organisms/MemberList.js               | 2 +-
 src/skins/vector/views/organisms/Notifier.js                 | 2 +-
 src/skins/vector/views/organisms/QuestionDialog.js           | 2 +-
 src/skins/vector/views/organisms/RoomList.js                 | 2 +-
 src/skins/vector/views/organisms/RoomView.js                 | 2 +-
 src/skins/vector/views/organisms/UserSettings.js             | 2 +-
 src/skins/vector/views/pages/MatrixChat.js                   | 2 +-
 src/skins/vector/views/templates/Login.js                    | 2 +-
 src/skins/vector/views/templates/Register.js                 | 2 +-
 49 files changed, 50 insertions(+), 50 deletions(-)

diff --git a/src/skins/vector/views/atoms/EditableText.js b/src/skins/vector/views/atoms/EditableText.js
index d4aa2857..1848b029 100644
--- a/src/skins/vector/views/atoms/EditableText.js
+++ b/src/skins/vector/views/atoms/EditableText.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var EditableTextController = require("../../../../src/controllers/atoms/EditableText");
+var EditableTextController = require('matrix-react-sdk/lib/controllers/atoms/EditableText')
 
 module.exports = React.createClass({
     displayName: 'EditableText',
diff --git a/src/skins/vector/views/atoms/EnableNotificationsButton.js b/src/skins/vector/views/atoms/EnableNotificationsButton.js
index 7caebb76..edef9edc 100644
--- a/src/skins/vector/views/atoms/EnableNotificationsButton.js
+++ b/src/skins/vector/views/atoms/EnableNotificationsButton.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var EnableNotificationsButtonController = require("../../../../src/controllers/atoms/EnableNotificationsButton");
+var EnableNotificationsButtonController = require('matrix-react-sdk/lib/controllers/atoms/EnableNotificationsButton')
 
 module.exports = React.createClass({
     displayName: 'EnableNotificationsButton',
diff --git a/src/skins/vector/views/atoms/ImageView.js b/src/skins/vector/views/atoms/ImageView.js
index 196e92fe..d5c57141 100644
--- a/src/skins/vector/views/atoms/ImageView.js
+++ b/src/skins/vector/views/atoms/ImageView.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var ImageViewController = require("../../../../src/controllers/atoms/ImageView");
+var ImageViewController = require('matrix-react-sdk/lib/controllers/atoms/ImageView')
 
 module.exports = React.createClass({
     displayName: 'ImageView',
diff --git a/src/skins/vector/views/atoms/LogoutButton.js b/src/skins/vector/views/atoms/LogoutButton.js
index 8cc5b27d..619160f6 100644
--- a/src/skins/vector/views/atoms/LogoutButton.js
+++ b/src/skins/vector/views/atoms/LogoutButton.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var LogoutButtonController = require("../../../../src/controllers/atoms/LogoutButton");
+var LogoutButtonController = require('matrix-react-sdk/lib/controllers/atoms/LogoutButton')
 
 module.exports = React.createClass({
     displayName: 'LogoutButton',
diff --git a/src/skins/vector/views/atoms/MemberAvatar.js b/src/skins/vector/views/atoms/MemberAvatar.js
index dccf0852..bd20723d 100644
--- a/src/skins/vector/views/atoms/MemberAvatar.js
+++ b/src/skins/vector/views/atoms/MemberAvatar.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MemberAvatarController = require("../../../../src/controllers/atoms/MemberAvatar");
+var MemberAvatarController = require('matrix-react-sdk/lib/controllers/atoms/MemberAvatar')
 
 module.exports = React.createClass({
     displayName: 'MemberAvatar',
diff --git a/src/skins/vector/views/atoms/MessageTimestamp.js b/src/skins/vector/views/atoms/MessageTimestamp.js
index 52eb1462..ef866afa 100644
--- a/src/skins/vector/views/atoms/MessageTimestamp.js
+++ b/src/skins/vector/views/atoms/MessageTimestamp.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MessageTimestampController = require("../../../../src/controllers/atoms/MessageTimestamp");
+var MessageTimestampController = require('matrix-react-sdk/lib/controllers/atoms/MessageTimestamp')
 
 module.exports = React.createClass({
     displayName: 'MessageTimestamp',
diff --git a/src/skins/vector/views/atoms/RoomAvatar.js b/src/skins/vector/views/atoms/RoomAvatar.js
index 48dbadef..ec2bf5ec 100644
--- a/src/skins/vector/views/atoms/RoomAvatar.js
+++ b/src/skins/vector/views/atoms/RoomAvatar.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var RoomAvatarController = require("../../../../src/controllers/atoms/RoomAvatar");
+var RoomAvatarController = require('matrix-react-sdk/lib/controllers/atoms/RoomAvatar')
 
 module.exports = React.createClass({
     displayName: 'RoomAvatar',
diff --git a/src/skins/vector/views/atoms/create_room/CreateRoomButton.js b/src/skins/vector/views/atoms/create_room/CreateRoomButton.js
index 2f9ccae0..2fc9d057 100644
--- a/src/skins/vector/views/atoms/create_room/CreateRoomButton.js
+++ b/src/skins/vector/views/atoms/create_room/CreateRoomButton.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var CreateRoomButtonController = require("../../../../../src/controllers/atoms/create_room/CreateRoomButton");
+var CreateRoomButtonController = require('matrix-react-sdk/lib/controllers/atoms/create_room/CreateRoomButton')
 
 module.exports = React.createClass({
     displayName: 'CreateRoomButton',
diff --git a/src/skins/vector/views/atoms/create_room/Presets.js b/src/skins/vector/views/atoms/create_room/Presets.js
index 271702b1..a098a7d7 100644
--- a/src/skins/vector/views/atoms/create_room/Presets.js
+++ b/src/skins/vector/views/atoms/create_room/Presets.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var PresetsController = require("../../../../../src/controllers/atoms/create_room/Presets");
+var PresetsController = require('matrix-react-sdk/lib/controllers/atoms/create_room/Presets')
 
 module.exports = React.createClass({
     displayName: 'CreateRoomPresets',
diff --git a/src/skins/vector/views/atoms/create_room/RoomAlias.js b/src/skins/vector/views/atoms/create_room/RoomAlias.js
index a59a8e69..0a8cadc8 100644
--- a/src/skins/vector/views/atoms/create_room/RoomAlias.js
+++ b/src/skins/vector/views/atoms/create_room/RoomAlias.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var RoomAliasController = require("../../../../../src/controllers/atoms/create_room/RoomAlias");
+var RoomAliasController = require('matrix-react-sdk/lib/controllers/atoms/create_room/RoomAlias')
 
 module.exports = React.createClass({
     displayName: 'RoomAlias',
diff --git a/src/skins/vector/views/atoms/voip/VideoFeed.js b/src/skins/vector/views/atoms/voip/VideoFeed.js
index 7fbee436..748a431a 100644
--- a/src/skins/vector/views/atoms/voip/VideoFeed.js
+++ b/src/skins/vector/views/atoms/voip/VideoFeed.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var VideoFeedController = require("../../../../../src/controllers/atoms/voip/VideoFeed");
+var VideoFeedController = require('matrix-react-sdk/lib/controllers/atoms/voip/VideoFeed')
 
 module.exports = React.createClass({
     displayName: 'VideoFeed',
diff --git a/src/skins/vector/views/molecules/ChangeAvatar.js b/src/skins/vector/views/molecules/ChangeAvatar.js
index e70da3a7..8fafacc8 100644
--- a/src/skins/vector/views/molecules/ChangeAvatar.js
+++ b/src/skins/vector/views/molecules/ChangeAvatar.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var ChangeAvatarController = require("../../../../src/controllers/molecules/ChangeAvatar");
+var ChangeAvatarController = require('matrix-react-sdk/lib/controllers/molecules/ChangeAvatar')
 
 var Loader = require("react-loader");
 
diff --git a/src/skins/vector/views/molecules/ChangePassword.js b/src/skins/vector/views/molecules/ChangePassword.js
index 2f92f9ab..004fed39 100644
--- a/src/skins/vector/views/molecules/ChangePassword.js
+++ b/src/skins/vector/views/molecules/ChangePassword.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var ChangePasswordController = require("../../../../src/controllers/molecules/ChangePassword");
+var ChangePasswordController = require('matrix-react-sdk/lib/controllers/molecules/ChangePassword')
 var Loader = require("react-loader");
 
 
diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
index c22db0c4..ded32b22 100644
--- a/src/skins/vector/views/molecules/EventAsTextTile.js
+++ b/src/skins/vector/views/molecules/EventAsTextTile.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var EventAsTextTileController = require("../../../../src/controllers/molecules/EventAsTextTile");
+var EventAsTextTileController = require('matrix-react-sdk/lib/controllers/molecules/EventAsTextTile')
 var ComponentBroker = require('../../../../src/ComponentBroker');
 var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
 var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
diff --git a/src/skins/vector/views/molecules/MEmoteTile.js b/src/skins/vector/views/molecules/MEmoteTile.js
index 1125a307..de2d9365 100644
--- a/src/skins/vector/views/molecules/MEmoteTile.js
+++ b/src/skins/vector/views/molecules/MEmoteTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MEmoteTileController = require("../../../../src/controllers/molecules/MEmoteTile");
+var MEmoteTileController = require('matrix-react-sdk/lib/controllers/molecules/MEmoteTile')
 
 module.exports = React.createClass({
     displayName: 'MEmoteTile',
diff --git a/src/skins/vector/views/molecules/MFileTile.js b/src/skins/vector/views/molecules/MFileTile.js
index a0b4465e..f0c2ab67 100644
--- a/src/skins/vector/views/molecules/MFileTile.js
+++ b/src/skins/vector/views/molecules/MFileTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MFileTileController = require("../../../../src/controllers/molecules/MFileTile");
+var MFileTileController = require('matrix-react-sdk/lib/controllers/molecules/MFileTile')
 
 var MatrixClientPeg = require('../../../../src/MatrixClientPeg');
 
diff --git a/src/skins/vector/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js
index 6b95f7ef..de6feb68 100644
--- a/src/skins/vector/views/molecules/MImageTile.js
+++ b/src/skins/vector/views/molecules/MImageTile.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var filesize = require('filesize');
 
-var MImageTileController = require("../../../../src/controllers/molecules/MImageTile");
+var MImageTileController = require('matrix-react-sdk/lib/controllers/molecules/MImageTile')
 
 var MatrixClientPeg = require('../../../../src/MatrixClientPeg');
 var Modal = require('../../../../src/Modal');
diff --git a/src/skins/vector/views/molecules/MNoticeTile.js b/src/skins/vector/views/molecules/MNoticeTile.js
index f63a8c2c..aa886127 100644
--- a/src/skins/vector/views/molecules/MNoticeTile.js
+++ b/src/skins/vector/views/molecules/MNoticeTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MNoticeTileController = require("../../../../src/controllers/molecules/MNoticeTile");
+var MNoticeTileController = require('matrix-react-sdk/lib/controllers/molecules/MNoticeTile')
 
 module.exports = React.createClass({
     displayName: 'MNoticeTile',
diff --git a/src/skins/vector/views/molecules/MRoomMemberTile.js b/src/skins/vector/views/molecules/MRoomMemberTile.js
index fb65d375..8a08a9a6 100644
--- a/src/skins/vector/views/molecules/MRoomMemberTile.js
+++ b/src/skins/vector/views/molecules/MRoomMemberTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MRoomMemberTileController = require("../../../../src/controllers/molecules/MRoomMemberTile");
+var MRoomMemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MRoomMemberTile')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var ComponentBroker = require('../../../../src/ComponentBroker');
diff --git a/src/skins/vector/views/molecules/MTextTile.js b/src/skins/vector/views/molecules/MTextTile.js
index d08f42ed..50555f94 100644
--- a/src/skins/vector/views/molecules/MTextTile.js
+++ b/src/skins/vector/views/molecules/MTextTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MTextTileController = require("../../../../src/controllers/molecules/MTextTile");
+var MTextTileController = require('matrix-react-sdk/lib/controllers/molecules/MTextTile')
 
 module.exports = React.createClass({
     displayName: 'MTextTile',
diff --git a/src/skins/vector/views/molecules/MatrixToolbar.js b/src/skins/vector/views/molecules/MatrixToolbar.js
index f72304e1..7d9cfa65 100644
--- a/src/skins/vector/views/molecules/MatrixToolbar.js
+++ b/src/skins/vector/views/molecules/MatrixToolbar.js
@@ -23,7 +23,7 @@ var ComponentBroker = require('../../../../src/ComponentBroker');
 var LogoutButton = ComponentBroker.get("atoms/LogoutButton");
 var EnableNotificationsButton = ComponentBroker.get("atoms/EnableNotificationsButton");
 
-var MatrixToolbarController = require("../../../../src/controllers/molecules/MatrixToolbar");
+var MatrixToolbarController = require('matrix-react-sdk/lib/controllers/molecules/MatrixToolbar')
 var Notifier = ComponentBroker.get('organisms/Notifier');
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/molecules/MemberInfo.js b/src/skins/vector/views/molecules/MemberInfo.js
index b57a5b6f..94ee19cf 100644
--- a/src/skins/vector/views/molecules/MemberInfo.js
+++ b/src/skins/vector/views/molecules/MemberInfo.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var MemberInfoController = require("../../../../src/controllers/molecules/MemberInfo");
+var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo')
 var ComponentBroker = require('../../../../src/ComponentBroker');
 var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
 
diff --git a/src/skins/vector/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
index 1414b562..00e220e2 100644
--- a/src/skins/vector/views/molecules/MemberTile.js
+++ b/src/skins/vector/views/molecules/MemberTile.js
@@ -22,7 +22,7 @@ var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var ComponentBroker = require('../../../../src/ComponentBroker');
 var Modal = require("../../../../src/Modal");
 var ContextualMenu = require("../../../../src/ContextualMenu");
-var MemberTileController = require("../../../../src/controllers/molecules/MemberTile");
+var MemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MemberTile')
 var MemberInfo = ComponentBroker.get('molecules/MemberInfo');
 var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
 var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
diff --git a/src/skins/vector/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
index a8d8a4eb..82da557a 100644
--- a/src/skins/vector/views/molecules/MessageComposer.js
+++ b/src/skins/vector/views/molecules/MessageComposer.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var MessageComposerController = require("../../../../src/controllers/molecules/MessageComposer");
+var MessageComposerController = require('matrix-react-sdk/lib/controllers/molecules/MessageComposer')
 var ContentMessages = require("../../../../src/ContentMessages");
 
 var ComponentBroker = require('../../../../src/ComponentBroker');
diff --git a/src/skins/vector/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
index ac6342ac..db6816b7 100644
--- a/src/skins/vector/views/molecules/MessageTile.js
+++ b/src/skins/vector/views/molecules/MessageTile.js
@@ -37,7 +37,7 @@ var tileTypes = {
     'm.file': ComponentBroker.get('molecules/MFileTile')
 };
 
-var MessageTileController = require("../../../../src/controllers/molecules/MessageTile");
+var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
 
 module.exports = React.createClass({
     displayName: 'MessageTile',
diff --git a/src/skins/vector/views/molecules/ProgressBar.js b/src/skins/vector/views/molecules/ProgressBar.js
index 0946ffcc..18d1440a 100644
--- a/src/skins/vector/views/molecules/ProgressBar.js
+++ b/src/skins/vector/views/molecules/ProgressBar.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var ProgressBarController = require("../../../../src/controllers/molecules/ProgressBar");
+var ProgressBarController = require('matrix-react-sdk/lib/controllers/molecules/ProgressBar')
 
 module.exports = React.createClass({
     displayName: 'ProgressBar',
diff --git a/src/skins/vector/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
index 9ad4f428..bb824578 100644
--- a/src/skins/vector/views/molecules/RoomCreate.js
+++ b/src/skins/vector/views/molecules/RoomCreate.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-//var RoomCreateController = require("../../../../src/controllers/molecules/RoomCreateController");
+//var RoomCreateController = require('matrix-react-sdk/lib/controllers/molecules/RoomCreateController')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
diff --git a/src/skins/vector/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
index 0a076949..ac9c8d44 100644
--- a/src/skins/vector/views/molecules/RoomDropTarget.js
+++ b/src/skins/vector/views/molecules/RoomDropTarget.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-//var RoomDropTargetController = require("../../../../src/controllers/molecules/RoomDropTargetController");
+//var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
diff --git a/src/skins/vector/views/molecules/RoomHeader.js b/src/skins/vector/views/molecules/RoomHeader.js
index e3003b88..3753a5de 100644
--- a/src/skins/vector/views/molecules/RoomHeader.js
+++ b/src/skins/vector/views/molecules/RoomHeader.js
@@ -20,7 +20,7 @@ var React = require('react');
 var ComponentBroker = require('../../../../src/ComponentBroker');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var RoomHeaderController = require("../../../../src/controllers/molecules/RoomHeader");
+var RoomHeaderController = require('matrix-react-sdk/lib/controllers/molecules/RoomHeader')
 var EditableText = ComponentBroker.get("atoms/EditableText");
 var RoomAvatar = ComponentBroker.get('atoms/RoomAvatar');
 
diff --git a/src/skins/vector/views/molecules/RoomSettings.js b/src/skins/vector/views/molecules/RoomSettings.js
index 7f48df20..05bdae8f 100644
--- a/src/skins/vector/views/molecules/RoomSettings.js
+++ b/src/skins/vector/views/molecules/RoomSettings.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
-var RoomSettingsController = require("../../../../src/controllers/molecules/RoomSettings");
+var RoomSettingsController = require('matrix-react-sdk/lib/controllers/molecules/RoomSettings')
 
 module.exports = React.createClass({
     displayName: 'RoomSettings',
diff --git a/src/skins/vector/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
index b8e41fb8..fdcbc713 100644
--- a/src/skins/vector/views/molecules/RoomTile.js
+++ b/src/skins/vector/views/molecules/RoomTile.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-var RoomTileController = require("../../../../src/controllers/molecules/RoomTile");
+var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/RoomTile')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
diff --git a/src/skins/vector/views/molecules/SenderProfile.js b/src/skins/vector/views/molecules/SenderProfile.js
index f13b29cf..8be3adf2 100644
--- a/src/skins/vector/views/molecules/SenderProfile.js
+++ b/src/skins/vector/views/molecules/SenderProfile.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var classNames = require("classnames");
 
-var SenderProfileController = require("../../../../src/controllers/molecules/SenderProfile");
+var SenderProfileController = require('matrix-react-sdk/lib/controllers/molecules/SenderProfile')
 
 // The Lato WOFF doesn't include sensible combining diacritics, so Chrome chokes on rendering them.
 // Revert to Arial when this happens, which on OSX works at least.
diff --git a/src/skins/vector/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
index 56241a2a..e19c89bb 100644
--- a/src/skins/vector/views/molecules/ServerConfig.js
+++ b/src/skins/vector/views/molecules/ServerConfig.js
@@ -22,7 +22,7 @@ var ComponentBroker = require('../../../../src/ComponentBroker');
 
 var ErrorDialog = ComponentBroker.get('organisms/ErrorDialog');
 
-var ServerConfigController = require("../../../../src/controllers/molecules/ServerConfig");
+var ServerConfigController = require('matrix-react-sdk/lib/controllers/molecules/ServerConfig')
 
 module.exports = React.createClass({
     displayName: 'ServerConfig',
diff --git a/src/skins/vector/views/molecules/UnknownMessageTile.js b/src/skins/vector/views/molecules/UnknownMessageTile.js
index b965a4a1..d5a20c87 100644
--- a/src/skins/vector/views/molecules/UnknownMessageTile.js
+++ b/src/skins/vector/views/molecules/UnknownMessageTile.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var UnknownMessageTileController = require("../../../../src/controllers/molecules/UnknownMessageTile");
+var UnknownMessageTileController = require('matrix-react-sdk/lib/controllers/molecules/UnknownMessageTile')
 
 module.exports = React.createClass({
     displayName: 'UnknownMessageTile',
diff --git a/src/skins/vector/views/molecules/UserSelector.js b/src/skins/vector/views/molecules/UserSelector.js
index 8ec00866..6b233690 100644
--- a/src/skins/vector/views/molecules/UserSelector.js
+++ b/src/skins/vector/views/molecules/UserSelector.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var UserSelectorController = require("../../../../src/controllers/molecules/UserSelector");
+var UserSelectorController = require('matrix-react-sdk/lib/controllers/molecules/UserSelector')
 
 module.exports = React.createClass({
     displayName: 'UserSelector',
diff --git a/src/skins/vector/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
index 3642e6b5..6957c6d8 100644
--- a/src/skins/vector/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -38,4 +38,4 @@ module.exports = React.createClass({
             <VideoView ref="video"/>
         );
     }
-});
\ No newline at end of file
+});
diff --git a/src/skins/vector/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
index 19ad17a7..0917aabd 100644
--- a/src/skins/vector/views/molecules/voip/VideoView.js
+++ b/src/skins/vector/views/molecules/voip/VideoView.js
@@ -20,7 +20,7 @@ var React = require('react');
 
 var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
 var ComponentBroker = require('../../../../../src/ComponentBroker');
-var VideoViewController = require("../../../../../src/controllers/molecules/voip/VideoView");
+var VideoViewController = require('matrix-react-sdk/lib/controllers/molecules/voip/VideoView')
 var VideoFeed = ComponentBroker.get('atoms/voip/VideoFeed');
 
 module.exports = React.createClass({
@@ -47,4 +47,4 @@ module.exports = React.createClass({
             </div>
         );
     }
-});
\ No newline at end of file
+});
diff --git a/src/skins/vector/views/organisms/CreateRoom.js b/src/skins/vector/views/organisms/CreateRoom.js
index b362db78..3766404a 100644
--- a/src/skins/vector/views/organisms/CreateRoom.js
+++ b/src/skins/vector/views/organisms/CreateRoom.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var CreateRoomController = require("../../../../src/controllers/organisms/CreateRoom");
+var CreateRoomController = require('matrix-react-sdk/lib/controllers/organisms/CreateRoom')
 
 var ComponentBroker = require('../../../../src/ComponentBroker');
 
diff --git a/src/skins/vector/views/organisms/ErrorDialog.js b/src/skins/vector/views/organisms/ErrorDialog.js
index 68d597cb..992ea050 100644
--- a/src/skins/vector/views/organisms/ErrorDialog.js
+++ b/src/skins/vector/views/organisms/ErrorDialog.js
@@ -28,7 +28,7 @@ limitations under the License.
  */
 
 var React = require('react');
-var ErrorDialogController = require("../../../../src/controllers/organisms/ErrorDialog");
+var ErrorDialogController = require('matrix-react-sdk/lib/controllers/organisms/ErrorDialog')
 
 module.exports = React.createClass({
     displayName: 'ErrorDialog',
diff --git a/src/skins/vector/views/organisms/LogoutPrompt.js b/src/skins/vector/views/organisms/LogoutPrompt.js
index 10ed07ed..6e347a4e 100644
--- a/src/skins/vector/views/organisms/LogoutPrompt.js
+++ b/src/skins/vector/views/organisms/LogoutPrompt.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var LogoutPromptController = require("../../../../src/controllers/organisms/LogoutPrompt");
+var LogoutPromptController = require('matrix-react-sdk/lib/controllers/organisms/LogoutPrompt')
 
 module.exports = React.createClass({
     displayName: 'LogoutPrompt',
diff --git a/src/skins/vector/views/organisms/MemberList.js b/src/skins/vector/views/organisms/MemberList.js
index a9a3c782..861fd370 100644
--- a/src/skins/vector/views/organisms/MemberList.js
+++ b/src/skins/vector/views/organisms/MemberList.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-var MemberListController = require("../../../../src/controllers/organisms/MemberList");
+var MemberListController = require('matrix-react-sdk/lib/controllers/organisms/MemberList')
 
 var ComponentBroker = require('../../../../src/ComponentBroker');
 
diff --git a/src/skins/vector/views/organisms/Notifier.js b/src/skins/vector/views/organisms/Notifier.js
index 556d6b3a..8ffc924f 100644
--- a/src/skins/vector/views/organisms/Notifier.js
+++ b/src/skins/vector/views/organisms/Notifier.js
@@ -16,7 +16,7 @@ limitations under the License.
 
 'use strict';
 
-var NotifierController = require("../../../../src/controllers/organisms/Notifier");
+var NotifierController = require('matrix-react-sdk/lib/controllers/organisms/Notifier')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var TextForEvent = require("../../../../src/TextForEvent");
diff --git a/src/skins/vector/views/organisms/QuestionDialog.js b/src/skins/vector/views/organisms/QuestionDialog.js
index cff9aa2f..3941b1f9 100644
--- a/src/skins/vector/views/organisms/QuestionDialog.js
+++ b/src/skins/vector/views/organisms/QuestionDialog.js
@@ -28,7 +28,7 @@ limitations under the License.
  */
 
 var React = require('react');
-var QuestionDialogController = require("../../../../src/controllers/organisms/QuestionDialog");
+var QuestionDialogController = require('matrix-react-sdk/lib/controllers/organisms/QuestionDialog')
 
 module.exports = React.createClass({
     displayName: 'QuestionDialog',
diff --git a/src/skins/vector/views/organisms/RoomList.js b/src/skins/vector/views/organisms/RoomList.js
index a3d02066..4a75f7d5 100644
--- a/src/skins/vector/views/organisms/RoomList.js
+++ b/src/skins/vector/views/organisms/RoomList.js
@@ -21,7 +21,7 @@ var ComponentBroker = require('../../../../src/ComponentBroker');
 var CallView = ComponentBroker.get('molecules/voip/CallView');
 var RoomDropTarget = ComponentBroker.get('molecules/RoomDropTarget');
 
-var RoomListController = require("../../../../src/controllers/organisms/RoomList");
+var RoomListController = require('matrix-react-sdk/lib/controllers/organisms/RoomList')
 
 module.exports = React.createClass({
     displayName: 'RoomList',
diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js
index 520c1d6b..fabf739e 100644
--- a/src/skins/vector/views/organisms/RoomView.js
+++ b/src/skins/vector/views/organisms/RoomView.js
@@ -30,7 +30,7 @@ var RoomHeader = ComponentBroker.get('molecules/RoomHeader');
 var MessageComposer = ComponentBroker.get('molecules/MessageComposer');
 var CallView = ComponentBroker.get("molecules/voip/CallView");
 var RoomSettings = ComponentBroker.get("molecules/RoomSettings");
-var RoomViewController = require("../../../../src/controllers/organisms/RoomView");
+var RoomViewController = require('matrix-react-sdk/lib/controllers/organisms/RoomView')
 
 var Loader = require("react-loader");
 
diff --git a/src/skins/vector/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
index 58a82487..fcd085ee 100644
--- a/src/skins/vector/views/organisms/UserSettings.js
+++ b/src/skins/vector/views/organisms/UserSettings.js
@@ -17,7 +17,7 @@ var React = require('react');
 var ComponentBroker = require('../../../../src/ComponentBroker');
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
-var UserSettingsController = require("../../../../src/controllers/organisms/UserSettings");
+var UserSettingsController = require('matrix-react-sdk/lib/controllers/organisms/UserSettings')
 
 var EditableText = ComponentBroker.get('atoms/EditableText');
 var EnableNotificationsButton = ComponentBroker.get('atoms/EnableNotificationsButton');
diff --git a/src/skins/vector/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
index 0fb627ab..2ece7bc6 100644
--- a/src/skins/vector/views/pages/MatrixChat.js
+++ b/src/skins/vector/views/pages/MatrixChat.js
@@ -30,7 +30,7 @@ var RoomDirectory = ComponentBroker.get('organisms/RoomDirectory');
 var MatrixToolbar = ComponentBroker.get('molecules/MatrixToolbar');
 var Notifier = ComponentBroker.get('organisms/Notifier');
 
-var MatrixChatController = require('../../../../src/controllers/pages/MatrixChat');
+var MatrixChatController = require('matrix-react-sdk/lib/controllers/pages/MatrixChat')
 
 // should be atomised
 var Loader = require("react-loader");
diff --git a/src/skins/vector/views/templates/Login.js b/src/skins/vector/views/templates/Login.js
index 4e13aaba..e3d406c5 100644
--- a/src/skins/vector/views/templates/Login.js
+++ b/src/skins/vector/views/templates/Login.js
@@ -24,7 +24,7 @@ var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var ProgressBar = ComponentBroker.get("molecules/ProgressBar");
 var Loader = require("react-loader");
 
-var LoginController = require("../../../../src/controllers/templates/Login");
+var LoginController = require('matrix-react-sdk/lib/controllers/templates/Login')
 
 var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
 
diff --git a/src/skins/vector/views/templates/Register.js b/src/skins/vector/views/templates/Register.js
index 10d04c83..087f3321 100644
--- a/src/skins/vector/views/templates/Register.js
+++ b/src/skins/vector/views/templates/Register.js
@@ -22,7 +22,7 @@ var ComponentBroker = require("../../../../src/ComponentBroker");
 
 var Loader = require("react-loader");
 
-var RegisterController = require("../../../../src/controllers/templates/Register");
+var RegisterController = require('matrix-react-sdk/lib/controllers/templates/Register')
 
 var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
 

From 7e72ee891aec0d7f51f18fcacd0410b367575531 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 18:49:04 +0100
Subject: [PATCH 10/29] More fixing up of vector skin

---
 package.json                                  |  6 +-
 src/skins/vector/header                       | 15 +++
 src/skins/vector/skindex.js                   | 92 +++++++++++++++++++
 src/skins/vector/skinfo.json                  |  3 +
 .../vector/views/molecules/EventAsTextTile.js |  5 +-
 .../vector/views/molecules/MImageTile.js      |  5 +-
 .../vector/views/molecules/MRoomMemberTile.js |  6 +-
 .../vector/views/molecules/MatrixToolbar.js   |  8 +-
 .../vector/views/molecules/MemberInfo.js      |  2 -
 .../vector/views/molecules/MemberTile.js      |  7 +-
 .../vector/views/molecules/MessageComposer.js |  4 +-
 .../vector/views/molecules/MessageTile.js     | 30 +++---
 .../vector/views/molecules/RoomHeader.js      |  6 +-
 src/skins/vector/views/molecules/RoomTile.js  |  4 +-
 .../vector/views/molecules/ServerConfig.js    |  5 +-
 .../vector/views/molecules/voip/CallView.js   |  6 +-
 .../vector/views/molecules/voip/VideoView.js  |  4 +-
 .../vector/views/organisms/CreateRoom.js      | 15 +--
 src/skins/vector/views/organisms/LeftPanel.js | 12 +--
 .../vector/views/organisms/MemberList.js      |  8 +-
 .../vector/views/organisms/RightPanel.js      |  5 +-
 .../vector/views/organisms/RoomDirectory.js   |  6 +-
 src/skins/vector/views/organisms/RoomList.js  |  7 +-
 src/skins/vector/views/organisms/RoomView.js  | 12 +--
 .../vector/views/organisms/UserSettings.js    | 12 +--
 src/skins/vector/views/pages/MatrixChat.js    | 23 +++--
 src/skins/vector/views/templates/Login.js     |  7 +-
 src/skins/vector/views/templates/Register.js  |  5 +-
 vector/index.js                               | 11 +--
 29 files changed, 216 insertions(+), 115 deletions(-)
 create mode 100644 src/skins/vector/header
 create mode 100644 src/skins/vector/skindex.js
 create mode 100644 src/skins/vector/skinfo.json

diff --git a/package.json b/package.json
index d6be714a..bff74693 100644
--- a/package.json
+++ b/package.json
@@ -10,9 +10,9 @@
   "license": "Apache-2.0",
   "style": "bundle.css",
   "scripts": {
-    "reskindex": "reskindex base -h src/skins/base/header",
-    "build": "NODE_ENV=production browserify --ignore olm -t reactify src/index.js | uglifyjs -c -m -o vector/bundle.js",
-    "start": "parallelshell 'watchify --ignore olm -v -d -t reactify src/index.js -o vector/bundle.js' 'npm run start:skins:css' 'http-server vector'",
+    "reskindex": "reskindex vector -h src/skins/vector/header",
+    "build": "NODE_ENV=production browserify --ignore olm -t reactify vector/index.js | uglifyjs -c -m -o vector/bundle.js",
+    "start": "parallelshell 'watchify --ignore olm -v -d -t reactify vector/index.js -o vector/bundle.js' 'npm run start:skins:css' 'http-server vector'",
     "build:skins:js": "babel src/skins -d lib/skins --source-maps",
     "build:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
     "start:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css",
diff --git a/src/skins/vector/header b/src/skins/vector/header
new file mode 100644
index 00000000..fd88ee27
--- /dev/null
+++ b/src/skins/vector/header
@@ -0,0 +1,15 @@
+/*
+Copyright 2015 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.
+*/
diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js
new file mode 100644
index 00000000..2b0bf28a
--- /dev/null
+++ b/src/skins/vector/skindex.js
@@ -0,0 +1,92 @@
+/*
+Copyright 2015 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.
+*/
+
+/*
+ * THIS FILE IS AUTO-GENERATED
+ * You can edit it you like, but your changes will be overwritten,
+ * so you'd just be trying to swim upstream like a salmon.
+ * You are not a salmon.
+ */
+
+var skin = {
+    atoms: {},
+    molecules: {},
+    organisms: {},
+    templates: {},
+    pages: {}
+};
+
+skin.atoms.EditableText = require('./views/atoms/EditableText');
+skin.atoms.EnableNotificationsButton = require('./views/atoms/EnableNotificationsButton');
+skin.atoms.ImageView = require('./views/atoms/ImageView');
+skin.atoms.LogoutButton = require('./views/atoms/LogoutButton');
+skin.atoms.MemberAvatar = require('./views/atoms/MemberAvatar');
+skin.atoms.MessageTimestamp = require('./views/atoms/MessageTimestamp');
+skin.atoms.RoomAvatar = require('./views/atoms/RoomAvatar');
+skin.atoms.create_room = {};
+skin.atoms.create_room.CreateRoomButton = require('./views/atoms/create_room/CreateRoomButton');
+skin.atoms.create_room.Presets = require('./views/atoms/create_room/Presets');
+skin.atoms.create_room.RoomAlias = require('./views/atoms/create_room/RoomAlias');
+skin.atoms.voip = {};
+skin.atoms.voip.VideoFeed = require('./views/atoms/voip/VideoFeed');
+skin.molecules.BottomLeftMenu = require('./views/molecules/BottomLeftMenu');
+skin.molecules.ChangeAvatar = require('./views/molecules/ChangeAvatar');
+skin.molecules.ChangePassword = require('./views/molecules/ChangePassword');
+skin.molecules.ContextualMenu = require('./views/molecules/ContextualMenu');
+skin.molecules.DateSeparator = require('./views/molecules/DateSeparator');
+skin.molecules.EventAsTextTile = require('./views/molecules/EventAsTextTile');
+skin.molecules.MEmoteTile = require('./views/molecules/MEmoteTile');
+skin.molecules.MFileTile = require('./views/molecules/MFileTile');
+skin.molecules.MImageTile = require('./views/molecules/MImageTile');
+skin.molecules.MNoticeTile = require('./views/molecules/MNoticeTile');
+skin.molecules.MRoomMemberTile = require('./views/molecules/MRoomMemberTile');
+skin.molecules.MTextTile = require('./views/molecules/MTextTile');
+skin.molecules.MatrixToolbar = require('./views/molecules/MatrixToolbar');
+skin.molecules.MemberInfo = require('./views/molecules/MemberInfo');
+skin.molecules.MemberTile = require('./views/molecules/MemberTile');
+skin.molecules.MessageComposer = require('./views/molecules/MessageComposer');
+skin.molecules.MessageTile = require('./views/molecules/MessageTile');
+skin.molecules.ProgressBar = require('./views/molecules/ProgressBar');
+skin.molecules.RoomCreate = require('./views/molecules/RoomCreate');
+skin.molecules.RoomDropTarget = require('./views/molecules/RoomDropTarget');
+skin.molecules.RoomHeader = require('./views/molecules/RoomHeader');
+skin.molecules.RoomSettings = require('./views/molecules/RoomSettings');
+skin.molecules.RoomTile = require('./views/molecules/RoomTile');
+skin.molecules.SenderProfile = require('./views/molecules/SenderProfile');
+skin.molecules.ServerConfig = require('./views/molecules/ServerConfig');
+skin.molecules.UnknownMessageTile = require('./views/molecules/UnknownMessageTile');
+skin.molecules.UserSelector = require('./views/molecules/UserSelector');
+skin.molecules.voip = {};
+skin.molecules.voip.CallView = require('./views/molecules/voip/CallView');
+skin.molecules.voip.IncomingCallBox = require('./views/molecules/voip/IncomingCallBox');
+skin.molecules.voip.VideoView = require('./views/molecules/voip/VideoView');
+skin.organisms.CreateRoom = require('./views/organisms/CreateRoom');
+skin.organisms.ErrorDialog = require('./views/organisms/ErrorDialog');
+skin.organisms.LeftPanel = require('./views/organisms/LeftPanel');
+skin.organisms.LogoutPrompt = require('./views/organisms/LogoutPrompt');
+skin.organisms.MemberList = require('./views/organisms/MemberList');
+skin.organisms.Notifier = require('./views/organisms/Notifier');
+skin.organisms.QuestionDialog = require('./views/organisms/QuestionDialog');
+skin.organisms.RightPanel = require('./views/organisms/RightPanel');
+skin.organisms.RoomDirectory = require('./views/organisms/RoomDirectory');
+skin.organisms.RoomList = require('./views/organisms/RoomList');
+skin.organisms.RoomView = require('./views/organisms/RoomView');
+skin.organisms.UserSettings = require('./views/organisms/UserSettings');
+skin.pages.MatrixChat = require('./views/pages/MatrixChat');
+skin.templates.Login = require('./views/templates/Login');
+skin.templates.Register = require('./views/templates/Register');
+
+module.exports = skin;
\ No newline at end of file
diff --git a/src/skins/vector/skinfo.json b/src/skins/vector/skinfo.json
new file mode 100644
index 00000000..287ff9e2
--- /dev/null
+++ b/src/skins/vector/skinfo.json
@@ -0,0 +1,3 @@
+{
+    "baseSkin": ""
+}
diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
index ded32b22..16a1e613 100644
--- a/src/skins/vector/views/molecules/EventAsTextTile.js
+++ b/src/skins/vector/views/molecules/EventAsTextTile.js
@@ -20,7 +20,7 @@ var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var EventAsTextTileController = require('matrix-react-sdk/lib/controllers/molecules/EventAsTextTile')
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
 var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
 var TextForEvent = require("../../../../src/TextForEvent");
@@ -30,6 +30,9 @@ module.exports = React.createClass({
     mixins: [EventAsTextTileController],
 
     render: function() {
+        var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
+
         var text = TextForEvent.textForEvent(this.props.mxEvent);
         if (text == null || text.length == 0) return null;
 
diff --git a/src/skins/vector/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js
index de6feb68..ca7b4cb6 100644
--- a/src/skins/vector/views/molecules/MImageTile.js
+++ b/src/skins/vector/views/molecules/MImageTile.js
@@ -23,9 +23,7 @@ var MImageTileController = require('matrix-react-sdk/lib/controllers/molecules/M
 
 var MatrixClientPeg = require('../../../../src/MatrixClientPeg');
 var Modal = require('../../../../src/Modal');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var ImageView = ComponentBroker.get("atoms/ImageView");
+var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
     displayName: 'MImageTile',
@@ -59,6 +57,7 @@ module.exports = React.createClass({
             ev.preventDefault();
             var content = this.props.mxEvent.getContent();
             var httpUrl = MatrixClientPeg.get().mxcUrlToHttp(content.url);
+            var ImageView = sdk.getComponent("atoms.ImageView");
             Modal.createDialog(ImageView, {
                 src: httpUrl,
                 width: content.info.w,
diff --git a/src/skins/vector/views/molecules/MRoomMemberTile.js b/src/skins/vector/views/molecules/MRoomMemberTile.js
index 8a08a9a6..6e70f496 100644
--- a/src/skins/vector/views/molecules/MRoomMemberTile.js
+++ b/src/skins/vector/views/molecules/MRoomMemberTile.js
@@ -21,10 +21,8 @@ var React = require('react');
 var MRoomMemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MRoomMemberTile')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var TextForEvent = require('../../../../src/TextForEvent');
-var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
 
 module.exports = React.createClass({
     displayName: 'MRoomMemberTile',
@@ -39,6 +37,8 @@ module.exports = React.createClass({
         var timestamp = this.props.last ? <MessageTimestamp ts={this.props.mxEvent.getTs()} /> : null;
         var text = this.getMemberEventText();
         if (!text) return <div/>;
+        var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
         return (
             <div className="mx_MessageTile mx_MessageTile_notice">
                 <div className="mx_MessageTile_avatar">
diff --git a/src/skins/vector/views/molecules/MatrixToolbar.js b/src/skins/vector/views/molecules/MatrixToolbar.js
index 7d9cfa65..0b6c58e0 100644
--- a/src/skins/vector/views/molecules/MatrixToolbar.js
+++ b/src/skins/vector/views/molecules/MatrixToolbar.js
@@ -18,23 +18,21 @@ limitations under the License.
 
 var React = require('react');
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var LogoutButton = ComponentBroker.get("atoms/LogoutButton");
-var EnableNotificationsButton = ComponentBroker.get("atoms/EnableNotificationsButton");
+var sdk = require('matrix-react-sdk')
 
 var MatrixToolbarController = require('matrix-react-sdk/lib/controllers/molecules/MatrixToolbar')
-var Notifier = ComponentBroker.get('organisms/Notifier');
 
 module.exports = React.createClass({
     displayName: 'MatrixToolbar',
     mixins: [MatrixToolbarController],
 
     hideToolbar: function() {
+        var Notifier = sdk.getComponent('organisms.Notifier');
         Notifier.setToolbarHidden(true);
     },
 
     render: function() {
+        var EnableNotificationsButton = sdk.getComponent("atoms.EnableNotificationsButton");
         return (
             <div className="mx_MatrixToolbar">
                 You are not receiving desktop notifications. <EnableNotificationsButton />
diff --git a/src/skins/vector/views/molecules/MemberInfo.js b/src/skins/vector/views/molecules/MemberInfo.js
index 94ee19cf..6d2d0dd7 100644
--- a/src/skins/vector/views/molecules/MemberInfo.js
+++ b/src/skins/vector/views/molecules/MemberInfo.js
@@ -20,8 +20,6 @@ var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo')
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
 
 module.exports = React.createClass({
     displayName: 'MemberInfo',
diff --git a/src/skins/vector/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
index 00e220e2..0c0181db 100644
--- a/src/skins/vector/views/molecules/MemberTile.js
+++ b/src/skins/vector/views/molecules/MemberTile.js
@@ -19,13 +19,10 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var Modal = require("../../../../src/Modal");
 var ContextualMenu = require("../../../../src/ContextualMenu");
 var MemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MemberTile')
-var MemberInfo = ComponentBroker.get('molecules/MemberInfo');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
 
 // The Lato WOFF doesn't include sensible combining diacritics, so Chrome chokes on rendering them.
 // Revert to Arial when this happens, which on OSX works at least.
@@ -46,6 +43,7 @@ module.exports = React.createClass({
     onClick: function(e) {
         var self = this;
         self.setState({ 'menu': true });
+        var MemberInfo = sdk.getComponent('molecules.MemberInfo');
         ContextualMenu.createMenu(MemberInfo, {
             member: self.props.member,
             right: window.innerWidth - e.pageX,
@@ -153,6 +151,7 @@ module.exports = React.createClass({
                 </div>
         }
 
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
         return (
             <div className={mainClassName} title={ this.getPowerLabel() } onClick={ this.onClick } onMouseEnter={ this.mouseEnter } onMouseLeave={ this.mouseLeave }>
                 <div className="mx_MemberTile_avatar">
diff --git a/src/skins/vector/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
index 82da557a..6b6eeba9 100644
--- a/src/skins/vector/views/molecules/MessageComposer.js
+++ b/src/skins/vector/views/molecules/MessageComposer.js
@@ -22,8 +22,7 @@ var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var MessageComposerController = require('matrix-react-sdk/lib/controllers/molecules/MessageComposer')
 var ContentMessages = require("../../../../src/ContentMessages");
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
+var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
     displayName: 'MessageComposer',
@@ -45,6 +44,7 @@ module.exports = React.createClass({
     render: function() {
         var me = this.props.room.getMember(MatrixClientPeg.get().credentials.userId);
         var uploadInputStyle = {display: 'none'};
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
         return (
             <div className="mx_MessageComposer">
                 <div className="mx_MessageComposer_wrapper">
diff --git a/src/skins/vector/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
index db6816b7..09cb0743 100644
--- a/src/skins/vector/views/molecules/MessageTile.js
+++ b/src/skins/vector/views/molecules/MessageTile.js
@@ -21,21 +21,7 @@ var React = require('react');
 var classNames = require("classnames");
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
-var SenderProfile = ComponentBroker.get('molecules/SenderProfile');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
-
-var UnknownMessageTile = ComponentBroker.get('molecules/UnknownMessageTile');
-
-var tileTypes = {
-    'm.text': ComponentBroker.get('molecules/MTextTile'),
-    'm.notice': ComponentBroker.get('molecules/MNoticeTile'),
-    'm.emote': ComponentBroker.get('molecules/MEmoteTile'),
-    'm.image': ComponentBroker.get('molecules/MImageTile'),
-    'm.file': ComponentBroker.get('molecules/MFileTile')
-};
+var sdk = require('matrix-react-sdk')
 
 var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
 
@@ -44,6 +30,20 @@ module.exports = React.createClass({
     mixins: [MessageTileController],
 
     render: function() {
+        var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
+        var SenderProfile = sdk.getComponent('molecules.SenderProfile');
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
+
+        var UnknownMessageTile = sdk.getComponent('molecules.UnknownMessageTile');
+
+        var tileTypes = {
+            'm.text': sdk.getComponent('molecules.MTextTile'),
+            'm.notice': sdk.getComponent('molecules.MNoticeTile'),
+            'm.emote': sdk.getComponent('molecules.MEmoteTile'),
+            'm.image': sdk.getComponent('molecules.MImageTile'),
+            'm.file': sdk.getComponent('molecules.MFileTile')
+        };
+
         var content = this.props.mxEvent.getContent();
         var msgtype = content.msgtype;
         var TileType = UnknownMessageTile;
diff --git a/src/skins/vector/views/molecules/RoomHeader.js b/src/skins/vector/views/molecules/RoomHeader.js
index 3753a5de..02b2ea33 100644
--- a/src/skins/vector/views/molecules/RoomHeader.js
+++ b/src/skins/vector/views/molecules/RoomHeader.js
@@ -17,12 +17,10 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var RoomHeaderController = require('matrix-react-sdk/lib/controllers/molecules/RoomHeader')
-var EditableText = ComponentBroker.get("atoms/EditableText");
-var RoomAvatar = ComponentBroker.get('atoms/RoomAvatar');
 
 module.exports = React.createClass({
     displayName: 'RoomHeader',
@@ -39,6 +37,8 @@ module.exports = React.createClass({
     },
 
     render: function() {
+        var EditableText = sdk.getComponent("atoms.EditableText");
+        var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
 
         var header;
         if (this.props.simpleHeader) {
diff --git a/src/skins/vector/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
index fdcbc713..d1ac3750 100644
--- a/src/skins/vector/views/molecules/RoomTile.js
+++ b/src/skins/vector/views/molecules/RoomTile.js
@@ -23,8 +23,7 @@ var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/Roo
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var RoomAvatar = ComponentBroker.get('atoms/RoomAvatar');
+var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
     displayName: 'RoomTile',
@@ -58,6 +57,7 @@ module.exports = React.createClass({
             nameCell = <div className="mx_RoomTile_name">{name}</div>;
         }
         */
+        var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
         return (
             <div className={classes} onClick={this.onClick}>
                 <div className="mx_RoomTile_avatar">
diff --git a/src/skins/vector/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
index e19c89bb..d2dd23b6 100644
--- a/src/skins/vector/views/molecules/ServerConfig.js
+++ b/src/skins/vector/views/molecules/ServerConfig.js
@@ -18,9 +18,7 @@ limitations under the License.
 
 var React = require('react');
 var Modal = require('../../../../src/Modal');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var ErrorDialog = ComponentBroker.get('organisms/ErrorDialog');
+var sdk = require('matrix-react-sdk')
 
 var ServerConfigController = require('matrix-react-sdk/lib/controllers/molecules/ServerConfig')
 
@@ -29,6 +27,7 @@ module.exports = React.createClass({
     mixins: [ServerConfigController],
 
     showHelpPopup: function() {
+        var ErrorDialog = sdk.getComponent('organisms.ErrorDialog');
         Modal.createDialog(ErrorDialog, {
           title: 'Custom Server Options',
           description: "You can use the custom server options to log into other Matrix servers by specifying a different Home server URL. This allows you to use Vector with an existing Matrix account on a different Home server. You can also set a cutom Identity server but this will affect people ability to find you if you use a server in a group other than tha main Matrix.org group.",
diff --git a/src/skins/vector/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
index 6957c6d8..b55f7b0d 100644
--- a/src/skins/vector/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -19,11 +19,10 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var CallViewController = require(
-    "../../../../../src/controllers/molecules/voip/CallView"
+    "matrix-react-sdk/lib/controllers/molecules/voip/CallView"
 );
-var VideoView = ComponentBroker.get('molecules/voip/VideoView');
 
 module.exports = React.createClass({
     displayName: 'CallView',
@@ -34,6 +33,7 @@ module.exports = React.createClass({
     },
 
     render: function(){
+        var VideoView = sdk.getComponent('molecules.voip.VideoView');
         return (
             <VideoView ref="video"/>
         );
diff --git a/src/skins/vector/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
index 0917aabd..aa6897eb 100644
--- a/src/skins/vector/views/molecules/voip/VideoView.js
+++ b/src/skins/vector/views/molecules/voip/VideoView.js
@@ -19,9 +19,8 @@ limitations under the License.
 var React = require('react');
 
 var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var VideoViewController = require('matrix-react-sdk/lib/controllers/molecules/voip/VideoView')
-var VideoFeed = ComponentBroker.get('atoms/voip/VideoFeed');
 
 module.exports = React.createClass({
     displayName: 'VideoView',
@@ -36,6 +35,7 @@ module.exports = React.createClass({
     },
 
     render: function() {
+        var VideoFeed = sdk.getComponent('atoms.voip.VideoFeed');
         return (
             <div className="mx_VideoView">
                 <div className="mx_VideoView_remoteVideoFeed">
diff --git a/src/skins/vector/views/organisms/CreateRoom.js b/src/skins/vector/views/organisms/CreateRoom.js
index 3766404a..82883d1e 100644
--- a/src/skins/vector/views/organisms/CreateRoom.js
+++ b/src/skins/vector/views/organisms/CreateRoom.js
@@ -20,16 +20,10 @@ var React = require('react');
 
 var CreateRoomController = require('matrix-react-sdk/lib/controllers/organisms/CreateRoom')
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 
 var PresetValues = require('../../../../src/controllers/atoms/create_room/Presets').Presets;
 
-var CreateRoomButton = ComponentBroker.get("atoms/create_room/CreateRoomButton");
-var RoomAlias = ComponentBroker.get("atoms/create_room/RoomAlias");
-var Presets = ComponentBroker.get("atoms/create_room/Presets");
-var UserSelector = ComponentBroker.get("molecules/UserSelector");
-var RoomHeader = ComponentBroker.get("molecules/RoomHeader");
-
 var Loader = require("react-loader");
 
 
@@ -140,6 +134,13 @@ module.exports = React.createClass({
                     </div>
                 );
             }
+
+            var CreateRoomButton = sdk.getComponent("atoms.create_room.CreateRoomButton");
+            var RoomAlias = sdk.getComponent("atoms.create_room.RoomAlias");
+            var Presets = sdk.getComponent("atoms.create_room.Presets");
+            var UserSelector = sdk.getComponent("molecules.UserSelector");
+            var RoomHeader = sdk.getComponent("molecules.RoomHeader");
+
             return (
                 <div className="mx_CreateRoom">
                     <RoomHeader simpleHeader="Create room" />
diff --git a/src/skins/vector/views/organisms/LeftPanel.js b/src/skins/vector/views/organisms/LeftPanel.js
index a7c2a8b9..9941cfa2 100644
--- a/src/skins/vector/views/organisms/LeftPanel.js
+++ b/src/skins/vector/views/organisms/LeftPanel.js
@@ -17,17 +17,17 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var RoomList = ComponentBroker.get('organisms/RoomList');
-var BottomLeftMenu = ComponentBroker.get('molecules/BottomLeftMenu');
-var IncomingCallBox = ComponentBroker.get('molecules/voip/IncomingCallBox');
-var RoomCreate = ComponentBroker.get('molecules/RoomCreate');
+var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
     displayName: 'LeftPanel',
 
     render: function() {
+        var RoomList = sdk.getComponent('organisms.RoomList');
+        var BottomLeftMenu = sdk.getComponent('molecules.BottomLeftMenu');
+        var IncomingCallBox = sdk.getComponent('molecules.voip.IncomingCallBox');
+        var RoomCreate = sdk.getComponent('molecules.RoomCreate');
+
         return (
             <aside className="mx_LeftPanel">
                 <img className="mx_LeftPanel_hideButton" src="img/hide.png" width="32" height="32" alt="<"/>
diff --git a/src/skins/vector/views/organisms/MemberList.js b/src/skins/vector/views/organisms/MemberList.js
index 861fd370..47d1d0f1 100644
--- a/src/skins/vector/views/organisms/MemberList.js
+++ b/src/skins/vector/views/organisms/MemberList.js
@@ -21,10 +21,7 @@ var classNames = require('classnames');
 
 var MemberListController = require('matrix-react-sdk/lib/controllers/organisms/MemberList')
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var MemberTile = ComponentBroker.get("molecules/MemberTile");
-var EditableText = ComponentBroker.get("atoms/EditableText");
+var sdk = require('matrix-react-sdk')
 
 
 module.exports = React.createClass({
@@ -48,6 +45,8 @@ module.exports = React.createClass({
     },
 
     makeMemberTiles: function() {
+        var MemberTile = sdk.getComponent("molecules.MemberTile");
+
         var self = this;
         return Object.keys(self.state.memberDict).map(function(userId) {
             var m = self.state.memberDict[userId];
@@ -81,6 +80,7 @@ module.exports = React.createClass({
             mx_MemberTile_inviteEditing: this.state.editing,
         });
 
+        var EditableText = sdk.getComponent("atoms.EditableText");
         return (
             <div className={ classes } onClick={ this.onClickInvite } >
                 <div className="mx_MemberTile_avatar"><img src="img/create-big.png" width="40" height="40" alt=""/></div>            
diff --git a/src/skins/vector/views/organisms/RightPanel.js b/src/skins/vector/views/organisms/RightPanel.js
index db463420..83b1491d 100644
--- a/src/skins/vector/views/organisms/RightPanel.js
+++ b/src/skins/vector/views/organisms/RightPanel.js
@@ -17,9 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var MemberList = ComponentBroker.get('organisms/MemberList');
+var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
     displayName: 'RightPanel',
@@ -47,6 +45,7 @@ module.exports = React.createClass({
     },
 
     render: function() {
+        var MemberList = sdk.getComponent('organisms.MemberList');
         var buttonGroup;
         var panel;
         if (this.props.roomId) {
diff --git a/src/skins/vector/views/organisms/RoomDirectory.js b/src/skins/vector/views/organisms/RoomDirectory.js
index 0ae1f467..9b7572da 100644
--- a/src/skins/vector/views/organisms/RoomDirectory.js
+++ b/src/skins/vector/views/organisms/RoomDirectory.js
@@ -20,9 +20,7 @@ var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 var Modal = require("../../../../src/Modal");
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-var RoomHeader = ComponentBroker.get('molecules/RoomHeader');
+var sdk = require('matrix-react-sdk')
 var dis = require("../../../../src/dispatcher");
 
 var Loader = require("react-loader");
@@ -44,6 +42,7 @@ module.exports = React.createClass({
             if (err) {
                 self.setState({ loading: false });                
                 console.error("Failed to get publicRooms: %s", JSON.stringify(err));
+                var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
                 Modal.createDialog(ErrorDialog, {
                     title: "Failed to get public room list",
                     description: err.message
@@ -128,6 +127,7 @@ module.exports = React.createClass({
             );
         }
 
+        var RoomHeader = sdk.getComponent('molecules.RoomHeader');
         return (
             <div className="mx_RoomDirectory">
                 <RoomHeader simpleHeader="Public Rooms" />
diff --git a/src/skins/vector/views/organisms/RoomList.js b/src/skins/vector/views/organisms/RoomList.js
index 4a75f7d5..7c992566 100644
--- a/src/skins/vector/views/organisms/RoomList.js
+++ b/src/skins/vector/views/organisms/RoomList.js
@@ -17,9 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var CallView = ComponentBroker.get('molecules/voip/CallView');
-var RoomDropTarget = ComponentBroker.get('molecules/RoomDropTarget');
+var sdk = require('matrix-react-sdk')
 
 var RoomListController = require('matrix-react-sdk/lib/controllers/organisms/RoomList')
 
@@ -28,6 +26,9 @@ module.exports = React.createClass({
     mixins: [RoomListController],
 
     render: function() {
+        var CallView = sdk.getComponent('molecules.voip.CallView');
+        var RoomDropTarget = sdk.getComponent('molecules.RoomDropTarget');
+
         var callElement;
         if (this.state.show_call_element) {
             callElement = <CallView className="mx_MatrixChat_callView"/>
diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js
index fabf739e..e791bc12 100644
--- a/src/skins/vector/views/organisms/RoomView.js
+++ b/src/skins/vector/views/organisms/RoomView.js
@@ -20,16 +20,11 @@ var React = require('react');
 
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var classNames = require("classnames");
 var filesize = require('filesize');
 var q = require('q');
 
-var MessageTile = ComponentBroker.get('molecules/MessageTile');
-var RoomHeader = ComponentBroker.get('molecules/RoomHeader');
-var MessageComposer = ComponentBroker.get('molecules/MessageComposer');
-var CallView = ComponentBroker.get("molecules/voip/CallView");
-var RoomSettings = ComponentBroker.get("molecules/RoomSettings");
 var RoomViewController = require('matrix-react-sdk/lib/controllers/organisms/RoomView')
 
 var Loader = require("react-loader");
@@ -82,6 +77,11 @@ module.exports = React.createClass({
     },
 
     render: function() {
+        var RoomHeader = sdk.getComponent('molecules.RoomHeader');
+        var MessageComposer = sdk.getComponent('molecules.MessageComposer');
+        var CallView = sdk.getComponent("molecules.voip.CallView");
+        var RoomSettings = sdk.getComponent("molecules.RoomSettings");
+
         if (!this.state.room) {
             if (this.props.roomId) {
                 return (
diff --git a/src/skins/vector/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
index fcd085ee..819e3f31 100644
--- a/src/skins/vector/views/organisms/UserSettings.js
+++ b/src/skins/vector/views/organisms/UserSettings.js
@@ -14,16 +14,11 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
 var UserSettingsController = require('matrix-react-sdk/lib/controllers/organisms/UserSettings')
 
-var EditableText = ComponentBroker.get('atoms/EditableText');
-var EnableNotificationsButton = ComponentBroker.get('atoms/EnableNotificationsButton');
-var ChangeAvatar = ComponentBroker.get('molecules/ChangeAvatar');
-var ChangePassword = ComponentBroker.get('molecules/ChangePassword');
-var LogoutPrompt = ComponentBroker.get('organisms/LogoutPrompt');
 var Loader = require("react-loader");
 
 var Modal = require("../../../../src/Modal");
@@ -34,6 +29,7 @@ module.exports = React.createClass({
 
     editAvatar: function() {
         var url = MatrixClientPeg.get().mxcUrlToHttp(this.state.avatarUrl);
+        var ChangeAvatar = sdk.getComponent('molecules.ChangeAvatar');
         Modal.createDialog(ChangeAvatar, {initialAvatarUrl: url});
     },
 
@@ -50,6 +46,7 @@ module.exports = React.createClass({
     },
 
     onLogoutClicked: function(ev) {
+        var LogoutPrompt = sdk.getComponent('organisms.LogoutPrompt');
         this.logoutModal = Modal.createDialog(LogoutPrompt, {onCancel: this.onLogoutPromptCancel});
     },
 
@@ -62,6 +59,9 @@ module.exports = React.createClass({
             case this.Phases.Loading:
                 return <Loader />
             case this.Phases.Display:
+                var EditableText = sdk.getComponent('atoms/EditableText');
+                var EnableNotificationsButton = sdk.getComponent('atoms/EnableNotificationsButton');
+                var ChangePassword = sdk.getComponent('molecules/ChangePassword');
                 return (
                     <div className="mx_UserSettings">
                         <div className="mx_UserSettings_User">
diff --git a/src/skins/vector/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
index 2ece7bc6..7fba6c5d 100644
--- a/src/skins/vector/views/pages/MatrixChat.js
+++ b/src/skins/vector/views/pages/MatrixChat.js
@@ -17,18 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var ComponentBroker = require('../../../../src/ComponentBroker');
-
-var LeftPanel = ComponentBroker.get('organisms/LeftPanel');
-var RoomView = ComponentBroker.get('organisms/RoomView');
-var RightPanel = ComponentBroker.get('organisms/RightPanel');
-var Login = ComponentBroker.get('templates/Login');
-var UserSettings = ComponentBroker.get('organisms/UserSettings');
-var Register = ComponentBroker.get('templates/Register');
-var CreateRoom = ComponentBroker.get('organisms/CreateRoom');
-var RoomDirectory = ComponentBroker.get('organisms/RoomDirectory');
-var MatrixToolbar = ComponentBroker.get('molecules/MatrixToolbar');
-var Notifier = ComponentBroker.get('organisms/Notifier');
+var sdk = require('matrix-react-sdk')
 
 var MatrixChatController = require('matrix-react-sdk/lib/controllers/pages/MatrixChat')
 
@@ -52,6 +41,16 @@ module.exports = React.createClass({
 
     render: function() {
         if (this.state.logged_in && this.state.ready) {
+            var LeftPanel = sdk.getComponent('organisms.LeftPanel');
+            var RoomView = sdk.getComponent('organisms.RoomView');
+            var RightPanel = sdk.getComponent('organisms.RightPanel');
+            var Login = sdk.getComponent('templates.Login');
+            var UserSettings = sdk.getComponent('organisms.UserSettings');
+            var Register = sdk.getComponent('templates.Register');
+            var CreateRoom = sdk.getComponent('organisms.CreateRoom');
+            var RoomDirectory = sdk.getComponent('organisms.RoomDirectory');
+            var MatrixToolbar = sdk.getComponent('molecules.MatrixToolbar');
+            var Notifier = sdk.getComponent('organisms.Notifier');
 
             var page_element;
             var right_panel = "";
diff --git a/src/skins/vector/views/templates/Login.js b/src/skins/vector/views/templates/Login.js
index e3d406c5..e6e63a14 100644
--- a/src/skins/vector/views/templates/Login.js
+++ b/src/skins/vector/views/templates/Login.js
@@ -18,16 +18,13 @@ limitations under the License.
 
 var React = require('react');
 
-var ComponentBroker = require("../../../../src/ComponentBroker");
+var sdk = require('matrix-react-sdk')
 var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
 
-var ProgressBar = ComponentBroker.get("molecules/ProgressBar");
 var Loader = require("react-loader");
 
 var LoginController = require('matrix-react-sdk/lib/controllers/templates/Login')
 
-var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
-
 module.exports = React.createClass({
     DEFAULT_HS_URL: 'https://matrix.org',
     DEFAULT_IS_URL: 'https://vector.im',
@@ -119,6 +116,8 @@ module.exports = React.createClass({
             case 'fetch_stages':
                 var serverConfigStyle = {};
                 serverConfigStyle.display = this.state.serverConfigVisible ? 'block' : 'none';
+                var ServerConfig = sdk.getComponent("molecules.ServerConfig");
+
                 return (
                     <div>
                         <input className="mx_Login_checkbox" id="advanced" type="checkbox" checked={this.state.serverConfigVisible} onChange={this.onServerConfigVisibleChange} />
diff --git a/src/skins/vector/views/templates/Register.js b/src/skins/vector/views/templates/Register.js
index 087f3321..d0c3b146 100644
--- a/src/skins/vector/views/templates/Register.js
+++ b/src/skins/vector/views/templates/Register.js
@@ -18,14 +18,12 @@ limitations under the License.
 
 var React = require('react');
 
-var ComponentBroker = require("../../../../src/ComponentBroker");
+var sdk = require('matrix-react-sdk')
 
 var Loader = require("react-loader");
 
 var RegisterController = require('matrix-react-sdk/lib/controllers/templates/Register')
 
-var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
-
 module.exports = React.createClass({
     DEFAULT_HS_URL: 'https://matrix.org',
     DEFAULT_IS_URL: 'https://vector.im',
@@ -98,6 +96,7 @@ module.exports = React.createClass({
             case 'initial':
                 var serverConfigStyle = {};
                 serverConfigStyle.display = this.state.serverConfigVisible ? 'block' : 'none';
+                var ServerConfig = sdk.getComponent("molecules.ServerConfig");
                 return (
                     <div>
                         <form onSubmit={this.onInitialStageSubmit}>
diff --git a/vector/index.js b/vector/index.js
index 1e1ec91b..9eaecc08 100644
--- a/vector/index.js
+++ b/vector/index.js
@@ -17,12 +17,8 @@ limitations under the License.
 'use strict';
 
 var React = require("react");
-// In normal usage of the module:
-//var MatrixReactSdk = require("matrix-react-sdk");
-// Or to import the source directly from the file system:
-// (This is useful for debugging the SDK as it seems source
-// maps cannot pass through two stages).
-var MatrixReactSdk = require("../../src/index");
+var sdk = require("matrix-react-sdk");
+sdk.loadSkin(require('../src/skins/vector/skindex'));
 
 var lastLocationHashSet = null;
 
@@ -78,8 +74,9 @@ var makeRegistrationUrl = function() {
            '#/register';
 }
 
+var MatrixChat = sdk.getComponent('pages.MatrixChat');
 window.matrixChat = React.render(
-    <MatrixReactSdk.MatrixChat onNewScreen={onNewScreen} registrationUrl={makeRegistrationUrl()} />,
+    <MatrixChat onNewScreen={onNewScreen} registrationUrl={makeRegistrationUrl()} />,
     document.getElementById('matrixchat')
 );
 

From b11abae8e8e3d8d2f23c332e032f8837132d3030 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Tue, 22 Sep 2015 19:09:23 +0100
Subject: [PATCH 11/29] More fixing up of paths, requires etc

---
 src/Avatar.js                                 |  2 +-
 src/CallHandler.js                            | 10 +++++-----
 src/controllers/atoms/ImageView.js            | 20 +++++++++++++++++++
 src/skins/vector/views/atoms/ImageView.js     |  2 +-
 .../vector/views/molecules/BottomLeftMenu.js  |  4 ++--
 .../vector/views/molecules/ContextualMenu.js  |  4 ++--
 .../vector/views/molecules/EventAsTextTile.js |  8 ++++----
 src/skins/vector/views/molecules/MFileTile.js |  2 +-
 .../vector/views/molecules/MImageTile.js      |  4 ++--
 .../vector/views/molecules/MRoomMemberTile.js |  4 ++--
 .../vector/views/molecules/MemberInfo.js      |  2 +-
 .../vector/views/molecules/MemberTile.js      |  6 +++---
 .../vector/views/molecules/MessageComposer.js |  4 ++--
 .../vector/views/molecules/MessageTile.js     |  2 +-
 .../vector/views/molecules/RoomCreate.js      |  2 +-
 .../vector/views/molecules/RoomDropTarget.js  |  2 +-
 .../vector/views/molecules/RoomHeader.js      |  2 +-
 .../vector/views/molecules/RoomSettings.js    |  2 +-
 src/skins/vector/views/molecules/RoomTile.js  |  2 +-
 .../vector/views/molecules/ServerConfig.js    |  2 +-
 .../vector/views/molecules/voip/CallView.js   |  2 +-
 .../views/molecules/voip/IncomingCallBox.js   |  4 ++--
 .../vector/views/molecules/voip/VideoView.js  |  2 +-
 .../vector/views/organisms/CreateRoom.js      |  2 +-
 src/skins/vector/views/organisms/Notifier.js  | 10 +++++-----
 .../vector/views/organisms/RoomDirectory.js   |  6 +++---
 src/skins/vector/views/organisms/RoomView.js  |  2 +-
 .../vector/views/organisms/UserSettings.js    |  4 ++--
 src/skins/vector/views/pages/MatrixChat.js    |  2 +-
 src/skins/vector/views/templates/Login.js     |  2 +-
 vector/fonts                                  |  2 +-
 vector/img                                    |  2 +-
 32 files changed, 73 insertions(+), 53 deletions(-)
 create mode 100644 src/controllers/atoms/ImageView.js

diff --git a/src/Avatar.js b/src/Avatar.js
index bdfc20ca..9889b480 100644
--- a/src/Avatar.js
+++ b/src/Avatar.js
@@ -16,7 +16,7 @@ limitations under the License.
 
 'use strict';
 
-var MatrixClientPeg = require('./MatrixClientPeg');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = {
     avatarUrlForMember: function(member, width, height, resizeMethod) {
diff --git a/src/CallHandler.js b/src/CallHandler.js
index 025ece38..17754d55 100644
--- a/src/CallHandler.js
+++ b/src/CallHandler.js
@@ -53,10 +53,9 @@ limitations under the License.
  * }
  */
 
-var MatrixClientPeg = require("./MatrixClientPeg");
-var Modal = require("./Modal");
-var ComponentBroker = require('./ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
+var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
+var Modal = require("matrix-react-sdk/lib/Modal");
+var sdk = require('matrix-react-sdk');
 var ConferenceCall = require("./ConferenceHandler").ConferenceCall;
 var ConferenceHandler = require("./ConferenceHandler");
 var Matrix = require("matrix-js-sdk");
@@ -118,6 +117,7 @@ function _setCallListeners(call) {
             _setCallState(call, call.roomId, "busy");
             pause("ringbackAudio");
             play("busyAudio");
+            var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
             Modal.createDialog(ErrorDialog, {
                 title: "Call Timeout",
                 description: "The remote side failed to pick up."
@@ -278,4 +278,4 @@ module.exports = {
         }
         return null;
     }
-};
\ No newline at end of file
+};
diff --git a/src/controllers/atoms/ImageView.js b/src/controllers/atoms/ImageView.js
new file mode 100644
index 00000000..d0977e00
--- /dev/null
+++ b/src/controllers/atoms/ImageView.js
@@ -0,0 +1,20 @@
+/*
+Copyright 2015 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.
+*/
+
+'use strict';
+
+module.exports = {
+};
diff --git a/src/skins/vector/views/atoms/ImageView.js b/src/skins/vector/views/atoms/ImageView.js
index d5c57141..a0d69bcc 100644
--- a/src/skins/vector/views/atoms/ImageView.js
+++ b/src/skins/vector/views/atoms/ImageView.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var ImageViewController = require('matrix-react-sdk/lib/controllers/atoms/ImageView')
+var ImageViewController = require('../../../../controllers/atoms/ImageView')
 
 module.exports = React.createClass({
     displayName: 'ImageView',
diff --git a/src/skins/vector/views/molecules/BottomLeftMenu.js b/src/skins/vector/views/molecules/BottomLeftMenu.js
index be46febc..d7a25221 100644
--- a/src/skins/vector/views/molecules/BottomLeftMenu.js
+++ b/src/skins/vector/views/molecules/BottomLeftMenu.js
@@ -19,9 +19,9 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-var dis = require("../../../../src/dispatcher");
+var dis = require('matrix-react-sdk/lib/dispatcher');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'BottomLeftMenu',
diff --git a/src/skins/vector/views/molecules/ContextualMenu.js b/src/skins/vector/views/molecules/ContextualMenu.js
index 58c542ee..1f0069de 100644
--- a/src/skins/vector/views/molecules/ContextualMenu.js
+++ b/src/skins/vector/views/molecules/ContextualMenu.js
@@ -19,9 +19,9 @@ limitations under the License.
 var React = require('react');
 var classNames = require('classnames');
 
-var dis = require("../../../../src/dispatcher");
+var dis = require('matrix-react-sdk/lib/dispatcher');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'ContextualMenu',
diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
index 16a1e613..b9d729eb 100644
--- a/src/skins/vector/views/molecules/EventAsTextTile.js
+++ b/src/skins/vector/views/molecules/EventAsTextTile.js
@@ -18,12 +18,10 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var EventAsTextTileController = require('matrix-react-sdk/lib/controllers/molecules/EventAsTextTile')
 var sdk = require('matrix-react-sdk')
-var MessageTimestamp = ComponentBroker.get('atoms/MessageTimestamp');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
-var TextForEvent = require("../../../../src/TextForEvent");
+var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
 
 module.exports = React.createClass({
     displayName: 'EventAsTextTile',
@@ -36,6 +34,8 @@ module.exports = React.createClass({
         var text = TextForEvent.textForEvent(this.props.mxEvent);
         if (text == null || text.length == 0) return null;
 
+        var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
+        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
         var timestamp = this.props.last ? <MessageTimestamp ts={this.props.mxEvent.getTs()} /> : null;
         var avatar = this.props.mxEvent.sender ? <MemberAvatar member={this.props.mxEvent.sender} /> : null;
         return (
diff --git a/src/skins/vector/views/molecules/MFileTile.js b/src/skins/vector/views/molecules/MFileTile.js
index f0c2ab67..f7e8991f 100644
--- a/src/skins/vector/views/molecules/MFileTile.js
+++ b/src/skins/vector/views/molecules/MFileTile.js
@@ -20,7 +20,7 @@ var React = require('react');
 
 var MFileTileController = require('matrix-react-sdk/lib/controllers/molecules/MFileTile')
 
-var MatrixClientPeg = require('../../../../src/MatrixClientPeg');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'MFileTile',
diff --git a/src/skins/vector/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js
index ca7b4cb6..63825359 100644
--- a/src/skins/vector/views/molecules/MImageTile.js
+++ b/src/skins/vector/views/molecules/MImageTile.js
@@ -21,8 +21,8 @@ var filesize = require('filesize');
 
 var MImageTileController = require('matrix-react-sdk/lib/controllers/molecules/MImageTile')
 
-var MatrixClientPeg = require('../../../../src/MatrixClientPeg');
-var Modal = require('../../../../src/Modal');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var Modal = require('matrix-react-sdk/lib/Modal');
 var sdk = require('matrix-react-sdk')
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/molecules/MRoomMemberTile.js b/src/skins/vector/views/molecules/MRoomMemberTile.js
index 6e70f496..d20b248e 100644
--- a/src/skins/vector/views/molecules/MRoomMemberTile.js
+++ b/src/skins/vector/views/molecules/MRoomMemberTile.js
@@ -20,9 +20,9 @@ var React = require('react');
 
 var MRoomMemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MRoomMemberTile')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
-var TextForEvent = require('../../../../src/TextForEvent');
+var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
 
 module.exports = React.createClass({
     displayName: 'MRoomMemberTile',
diff --git a/src/skins/vector/views/molecules/MemberInfo.js b/src/skins/vector/views/molecules/MemberInfo.js
index 6d2d0dd7..cc9a8f2d 100644
--- a/src/skins/vector/views/molecules/MemberInfo.js
+++ b/src/skins/vector/views/molecules/MemberInfo.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo')
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
index 0c0181db..30ac6880 100644
--- a/src/skins/vector/views/molecules/MemberTile.js
+++ b/src/skins/vector/views/molecules/MemberTile.js
@@ -18,10 +18,10 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
-var Modal = require("../../../../src/Modal");
-var ContextualMenu = require("../../../../src/ContextualMenu");
+var Modal = require('matrix-react-sdk/lib/Modal');
+var ContextualMenu = require('../../../../ContextualMenu');
 var MemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MemberTile')
 
 // The Lato WOFF doesn't include sensible combining diacritics, so Chrome chokes on rendering them.
diff --git a/src/skins/vector/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
index 6b6eeba9..8b6ff6af 100644
--- a/src/skins/vector/views/molecules/MessageComposer.js
+++ b/src/skins/vector/views/molecules/MessageComposer.js
@@ -18,9 +18,9 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var MessageComposerController = require('matrix-react-sdk/lib/controllers/molecules/MessageComposer')
-var ContentMessages = require("../../../../src/ContentMessages");
+var ContentMessages = require('matrix-react-sdk/lib/ContentMessages');
 
 var sdk = require('matrix-react-sdk')
 
diff --git a/src/skins/vector/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
index 09cb0743..357d4bf9 100644
--- a/src/skins/vector/views/molecules/MessageTile.js
+++ b/src/skins/vector/views/molecules/MessageTile.js
@@ -20,7 +20,7 @@ var React = require('react');
 
 var classNames = require("classnames");
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 
 var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
diff --git a/src/skins/vector/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
index bb824578..d4541f42 100644
--- a/src/skins/vector/views/molecules/RoomCreate.js
+++ b/src/skins/vector/views/molecules/RoomCreate.js
@@ -21,7 +21,7 @@ var classNames = require('classnames');
 
 //var RoomCreateController = require('matrix-react-sdk/lib/controllers/molecules/RoomCreateController')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'RoomCreate',
diff --git a/src/skins/vector/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
index ac9c8d44..c3e8aa1f 100644
--- a/src/skins/vector/views/molecules/RoomDropTarget.js
+++ b/src/skins/vector/views/molecules/RoomDropTarget.js
@@ -21,7 +21,7 @@ var classNames = require('classnames');
 
 //var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'RoomDropTarget',
diff --git a/src/skins/vector/views/molecules/RoomHeader.js b/src/skins/vector/views/molecules/RoomHeader.js
index 02b2ea33..f7d3fe7e 100644
--- a/src/skins/vector/views/molecules/RoomHeader.js
+++ b/src/skins/vector/views/molecules/RoomHeader.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var sdk = require('matrix-react-sdk')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var RoomHeaderController = require('matrix-react-sdk/lib/controllers/molecules/RoomHeader')
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/molecules/RoomSettings.js b/src/skins/vector/views/molecules/RoomSettings.js
index 05bdae8f..d6d36a13 100644
--- a/src/skins/vector/views/molecules/RoomSettings.js
+++ b/src/skins/vector/views/molecules/RoomSettings.js
@@ -17,7 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 var RoomSettingsController = require('matrix-react-sdk/lib/controllers/molecules/RoomSettings')
 
diff --git a/src/skins/vector/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
index d1ac3750..61fa0021 100644
--- a/src/skins/vector/views/molecules/RoomTile.js
+++ b/src/skins/vector/views/molecules/RoomTile.js
@@ -21,7 +21,7 @@ var classNames = require('classnames');
 
 var RoomTileController = require('matrix-react-sdk/lib/controllers/molecules/RoomTile')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 var sdk = require('matrix-react-sdk')
 
diff --git a/src/skins/vector/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
index d2dd23b6..e48487ae 100644
--- a/src/skins/vector/views/molecules/ServerConfig.js
+++ b/src/skins/vector/views/molecules/ServerConfig.js
@@ -17,7 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var Modal = require('../../../../src/Modal');
+var Modal = require('matrix-react-sdk/lib/Modal');
 var sdk = require('matrix-react-sdk')
 
 var ServerConfigController = require('matrix-react-sdk/lib/controllers/molecules/ServerConfig')
diff --git a/src/skins/vector/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
index b55f7b0d..b674fe2c 100644
--- a/src/skins/vector/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 var CallViewController = require(
     "matrix-react-sdk/lib/controllers/molecules/voip/CallView"
diff --git a/src/skins/vector/views/molecules/voip/IncomingCallBox.js b/src/skins/vector/views/molecules/voip/IncomingCallBox.js
index 5becedb1..ee437f0a 100644
--- a/src/skins/vector/views/molecules/voip/IncomingCallBox.js
+++ b/src/skins/vector/views/molecules/voip/IncomingCallBox.js
@@ -17,9 +17,9 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var IncomingCallBoxController = require(
-    "../../../../../src/controllers/molecules/voip/IncomingCallBox"
+    "matrix-react-sdk/lib/controllers/molecules/voip/IncomingCallBox"
 );
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
index aa6897eb..d3b8636e 100644
--- a/src/skins/vector/views/molecules/voip/VideoView.js
+++ b/src/skins/vector/views/molecules/voip/VideoView.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
 var sdk = require('matrix-react-sdk')
 var VideoViewController = require('matrix-react-sdk/lib/controllers/molecules/voip/VideoView')
 
diff --git a/src/skins/vector/views/organisms/CreateRoom.js b/src/skins/vector/views/organisms/CreateRoom.js
index 82883d1e..64f5b861 100644
--- a/src/skins/vector/views/organisms/CreateRoom.js
+++ b/src/skins/vector/views/organisms/CreateRoom.js
@@ -22,7 +22,7 @@ var CreateRoomController = require('matrix-react-sdk/lib/controllers/organisms/C
 
 var sdk = require('matrix-react-sdk')
 
-var PresetValues = require('../../../../src/controllers/atoms/create_room/Presets').Presets;
+var PresetValues = require('matrix-react-sdk/lib/controllers/atoms/create_room/Presets').Presets;
 
 var Loader = require("react-loader");
 
diff --git a/src/skins/vector/views/organisms/Notifier.js b/src/skins/vector/views/organisms/Notifier.js
index 8ffc924f..dad456cd 100644
--- a/src/skins/vector/views/organisms/Notifier.js
+++ b/src/skins/vector/views/organisms/Notifier.js
@@ -18,12 +18,12 @@ limitations under the License.
 
 var NotifierController = require('matrix-react-sdk/lib/controllers/organisms/Notifier')
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var TextForEvent = require("../../../../src/TextForEvent");
-var extend = require("../../../../src/extend");
-var dis = require("../../../../src/dispatcher");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
+var extend = require('matrix-react-sdk/lib/extend');
+var dis = require('matrix-react-sdk/lib/dispatcher');
 
-var Avatar = require("../../../../src/Avatar");
+var Avatar = require('../../../../Avatar');
 
 
 var NotifierView = {
diff --git a/src/skins/vector/views/organisms/RoomDirectory.js b/src/skins/vector/views/organisms/RoomDirectory.js
index 9b7572da..5f5717c8 100644
--- a/src/skins/vector/views/organisms/RoomDirectory.js
+++ b/src/skins/vector/views/organisms/RoomDirectory.js
@@ -18,10 +18,10 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var Modal = require("../../../../src/Modal");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var Modal = require('matrix-react-sdk/lib/Modal');
 var sdk = require('matrix-react-sdk')
-var dis = require("../../../../src/dispatcher");
+var dis = require('matrix-react-sdk/lib/dispatcher');
 
 var Loader = require("react-loader");
 
diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js
index e791bc12..81f95fd4 100644
--- a/src/skins/vector/views/organisms/RoomView.js
+++ b/src/skins/vector/views/organisms/RoomView.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 var sdk = require('matrix-react-sdk')
 var classNames = require("classnames");
diff --git a/src/skins/vector/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
index 819e3f31..515a71aa 100644
--- a/src/skins/vector/views/organisms/UserSettings.js
+++ b/src/skins/vector/views/organisms/UserSettings.js
@@ -15,13 +15,13 @@ limitations under the License.
 
 var React = require('react');
 var sdk = require('matrix-react-sdk')
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 var UserSettingsController = require('matrix-react-sdk/lib/controllers/organisms/UserSettings')
 
 var Loader = require("react-loader");
 
-var Modal = require("../../../../src/Modal");
+var Modal = require('matrix-react-sdk/lib/Modal');
 
 module.exports = React.createClass({
     displayName: 'UserSettings',
diff --git a/src/skins/vector/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
index 7fba6c5d..da30dffb 100644
--- a/src/skins/vector/views/pages/MatrixChat.js
+++ b/src/skins/vector/views/pages/MatrixChat.js
@@ -25,7 +25,7 @@ var MatrixChatController = require('matrix-react-sdk/lib/controllers/pages/Matri
 var Loader = require("react-loader");
 var classNames = require("classnames");
 
-var dis = require("../../../../src/dispatcher");
+var dis = require('matrix-react-sdk/lib/dispatcher');
 
 
 module.exports = React.createClass({
diff --git a/src/skins/vector/views/templates/Login.js b/src/skins/vector/views/templates/Login.js
index e6e63a14..2a0068f4 100644
--- a/src/skins/vector/views/templates/Login.js
+++ b/src/skins/vector/views/templates/Login.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 
 var sdk = require('matrix-react-sdk')
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 var Loader = require("react-loader");
 
diff --git a/vector/fonts b/vector/fonts
index 7df9446b..1c206eff 120000
--- a/vector/fonts
+++ b/vector/fonts
@@ -1 +1 @@
-src/skins/vector/fonts
\ No newline at end of file
+../src/skins/vector/fonts
\ No newline at end of file
diff --git a/vector/img b/vector/img
index 52ed4fae..8f1382c0 120000
--- a/vector/img
+++ b/vector/img
@@ -1 +1 @@
-src/skins/vector/img
\ No newline at end of file
+../src/skins/vector/img
\ No newline at end of file

From c21dd853f959bf082e3488225111c80592f41250 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 23 Sep 2015 09:48:18 +0100
Subject: [PATCH 12/29] Update package.json for renamed skin

---
 package.json | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/package.json b/package.json
index bff74693..1a2f8118 100644
--- a/package.json
+++ b/package.json
@@ -14,8 +14,8 @@
     "build": "NODE_ENV=production browserify --ignore olm -t reactify vector/index.js | uglifyjs -c -m -o vector/bundle.js",
     "start": "parallelshell 'watchify --ignore olm -v -d -t reactify vector/index.js -o vector/bundle.js' 'npm run start:skins:css' 'http-server vector'",
     "build:skins:js": "babel src/skins -d lib/skins --source-maps",
-    "build:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
-    "start:skins:css": "catw 'src/skins/base/css/**/*.css' -o vector/bundle.css",
+    "build:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
+    "start:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css",
     "clean": "rimraf lib vector/bundle.css vector/bundle.js",
     "prepublish": "npm run build:skins"
   },

From bfa4cda2c617d1f63e5b5ef923f94c672ef6897f Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 23 Sep 2015 10:14:38 +0100
Subject: [PATCH 13/29] build is no longer used

---
 .gitignore | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.gitignore b/.gitignore
index 19177681..a8857988 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
 node_modules
-build
 bundle.css
 bundle.js

From f020f4397c1929d20ccf4e2c98715eee686bcefb Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 25 Sep 2015 11:43:28 +0100
Subject: [PATCH 14/29] Switch to webpack

Webapck actually supports loading input source maps and generally seems a lot
more solid then browserify (even if their website has an annoying animated
logo).
---
 .gitignore                      |  4 ++--
 package.json                    | 19 ++++++++++++-------
 {vector => src/vector}/index.js |  2 +-
 webpack.config.js               | 25 +++++++++++++++++++++++++
 4 files changed, 40 insertions(+), 10 deletions(-)
 rename {vector => src/vector}/index.js (98%)
 create mode 100644 webpack.config.js

diff --git a/.gitignore b/.gitignore
index a8857988..13466ce8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
 node_modules
-bundle.css
-bundle.js
+vector/bundle.*
+lib
diff --git a/package.json b/package.json
index 1a2f8118..24c1849e 100644
--- a/package.json
+++ b/package.json
@@ -11,13 +11,15 @@
   "style": "bundle.css",
   "scripts": {
     "reskindex": "reskindex vector -h src/skins/vector/header",
-    "build": "NODE_ENV=production browserify --ignore olm -t reactify vector/index.js | uglifyjs -c -m -o vector/bundle.js",
-    "start": "parallelshell 'watchify --ignore olm -v -d -t reactify vector/index.js -o vector/bundle.js' 'npm run start:skins:css' 'http-server vector'",
-    "build:skins:js": "babel src/skins -d lib/skins --source-maps",
-    "build:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
+    "build:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
+    "build:compile": "babel --source-maps -d lib src",
+    "build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
+    "build": "npm run build:css && npm run build:compile && npm run build:bundle",
+    "start:js": "webpack -w src/vector/index.js vector/bundle.js",
     "start:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css",
-    "clean": "rimraf lib vector/bundle.css vector/bundle.js",
-    "prepublish": "npm run build:skins"
+    "start": "parallelshell 'npm run start:js' 'npm run start:skins:css' 'http-server vector'",
+    "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/bundle.webpack.js vector/bundle.webpack.js.map",
+    "prepublish": "npm run build:css && npm run build:compile"
   },
   "dependencies": {
     "matrix-react-sdk": "^0.0.1",
@@ -31,10 +33,13 @@
   },
   "devDependencies": {
     "babel": "^5.8.23",
+    "babel-core": "^5.8.25",
+    "babel-loader": "^5.3.2",
     "catw": "^1.0.1",
+    "http-server": "^0.8.4",
     "parallelshell": "^1.2.0",
-    "react-tools": "^0.13.3",
     "rimraf": "^2.4.3",
+    "source-map-loader": "^0.1.5",
     "uglifycss": "0.0.15"
   }
 }
diff --git a/vector/index.js b/src/vector/index.js
similarity index 98%
rename from vector/index.js
rename to src/vector/index.js
index 9eaecc08..accba178 100644
--- a/vector/index.js
+++ b/src/vector/index.js
@@ -18,7 +18,7 @@ limitations under the License.
 
 var React = require("react");
 var sdk = require("matrix-react-sdk");
-sdk.loadSkin(require('../src/skins/vector/skindex'));
+sdk.loadSkin(require('../skins/vector/skindex'));
 
 var lastLocationHashSet = null;
 
diff --git a/webpack.config.js b/webpack.config.js
new file mode 100644
index 00000000..6e557ae6
--- /dev/null
+++ b/webpack.config.js
@@ -0,0 +1,25 @@
+var path = require('path');
+var webpack = require('webpack');
+
+module.exports = {
+    module: {
+        preLoaders: [
+            { test: /\.js$/, loader: "source-map-loader" }
+        ],
+        loaders: [
+            { test: /\.json$/, loader: "json" },
+            { test: /\.js$/, loader: "babel", include: path.resolve('./src') },
+        ]
+    },
+    resolve: {
+        alias: {
+            // alias any requires to the react module to the one in our path, otherwise
+            // we tend to get the react source included twice when using npm link.
+            react: path.resolve('./node_modules/react'),
+        },
+    },
+    plugins: [
+        new webpack.IgnorePlugin(/^olm/)
+    ],
+    devtool: 'source-map'
+};

From 409697b35baa64b37e68805ce2ef56a63de8de9c Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 25 Sep 2015 11:46:06 +0100
Subject: [PATCH 15/29] Oops, these were just at the wrong scope

---
 src/skins/vector/views/pages/MatrixChat.js | 22 +++++++++++-----------
 1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/src/skins/vector/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
index da30dffb..2b912df4 100644
--- a/src/skins/vector/views/pages/MatrixChat.js
+++ b/src/skins/vector/views/pages/MatrixChat.js
@@ -40,18 +40,18 @@ module.exports = React.createClass({
     },
 
     render: function() {
-        if (this.state.logged_in && this.state.ready) {
-            var LeftPanel = sdk.getComponent('organisms.LeftPanel');
-            var RoomView = sdk.getComponent('organisms.RoomView');
-            var RightPanel = sdk.getComponent('organisms.RightPanel');
-            var Login = sdk.getComponent('templates.Login');
-            var UserSettings = sdk.getComponent('organisms.UserSettings');
-            var Register = sdk.getComponent('templates.Register');
-            var CreateRoom = sdk.getComponent('organisms.CreateRoom');
-            var RoomDirectory = sdk.getComponent('organisms.RoomDirectory');
-            var MatrixToolbar = sdk.getComponent('molecules.MatrixToolbar');
-            var Notifier = sdk.getComponent('organisms.Notifier');
+        var LeftPanel = sdk.getComponent('organisms.LeftPanel');
+        var RoomView = sdk.getComponent('organisms.RoomView');
+        var RightPanel = sdk.getComponent('organisms.RightPanel');
+        var Login = sdk.getComponent('templates.Login');
+        var UserSettings = sdk.getComponent('organisms.UserSettings');
+        var Register = sdk.getComponent('templates.Register');
+        var CreateRoom = sdk.getComponent('organisms.CreateRoom');
+        var RoomDirectory = sdk.getComponent('organisms.RoomDirectory');
+        var MatrixToolbar = sdk.getComponent('molecules.MatrixToolbar');
+        var Notifier = sdk.getComponent('organisms.Notifier');
 
+        if (this.state.logged_in && this.state.ready) {
             var page_element;
             var right_panel = "";
 

From 796f424a3f39410f2d5cab956e2b6a4c166cd1ac Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 25 Sep 2015 11:51:35 +0100
Subject: [PATCH 16/29] Didn't need these in the end

---
 package.json | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 24c1849e..002c0661 100644
--- a/package.json
+++ b/package.json
@@ -18,7 +18,7 @@
     "start:js": "webpack -w src/vector/index.js vector/bundle.js",
     "start:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css",
     "start": "parallelshell 'npm run start:js' 'npm run start:skins:css' 'http-server vector'",
-    "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map vector/bundle.webpack.js vector/bundle.webpack.js.map",
+    "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
     "prepublish": "npm run build:css && npm run build:compile"
   },
   "dependencies": {

From f778f6adf98c353af95a81ceeeaefcebfdc9b5bb Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 25 Sep 2015 15:33:38 +0100
Subject: [PATCH 17/29] Remove unused stuff

---
 src/Avatar.js                                      |  3 ---
 src/ContextualMenu.js                              |  1 -
 src/skins/vector/views/molecules/BottomLeftMenu.js |  3 ---
 src/skins/vector/views/molecules/ContextualMenu.js |  5 -----
 .../vector/views/molecules/EventAsTextTile.js      |  1 -
 src/skins/vector/views/molecules/MImageTile.js     |  1 -
 .../vector/views/molecules/MRoomMemberTile.js      |  1 -
 src/skins/vector/views/molecules/MemberTile.js     |  1 -
 .../vector/views/molecules/MessageComposer.js      |  1 -
 src/skins/vector/views/molecules/MessageTile.js    |  1 -
 src/skins/vector/views/molecules/RoomCreate.js     |  3 ---
 src/skins/vector/views/molecules/RoomDropTarget.js |  3 ---
 src/skins/vector/views/molecules/voip/CallView.js  |  1 -
 src/skins/vector/views/molecules/voip/VideoView.js |  1 -
 src/skins/vector/views/organisms/LeftPanel.js      |  1 -
 src/skins/vector/views/organisms/Notifier.js       |  1 -
 src/skins/vector/views/organisms/RoomView.js       |  1 -
 src/skins/vector/views/organisms/UserSettings.js   |  2 +-
 src/skins/vector/views/pages/MatrixChat.js         |  1 -
 src/skins/vector/views/templates/Register.js       | 14 +-------------
 20 files changed, 2 insertions(+), 44 deletions(-)

diff --git a/src/Avatar.js b/src/Avatar.js
index 9889b480..74b279c6 100644
--- a/src/Avatar.js
+++ b/src/Avatar.js
@@ -37,13 +37,10 @@ module.exports = {
         switch (total % 3) {
             case 0:
                 return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII=";
-                break;
             case 1:
                 return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII=";
-                break;
             case 2:
                 return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII=";
-                break;
         }
     }
 }
diff --git a/src/ContextualMenu.js b/src/ContextualMenu.js
index cabab0c3..cdfff952 100644
--- a/src/ContextualMenu.js
+++ b/src/ContextualMenu.js
@@ -18,7 +18,6 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var q = require('q');
 
 // Shamelessly ripped off Modal.js.  There's probably a better way
 // of doing reusable widgets like dialog boxes & menus where we go and
diff --git a/src/skins/vector/views/molecules/BottomLeftMenu.js b/src/skins/vector/views/molecules/BottomLeftMenu.js
index d7a25221..809da0ee 100644
--- a/src/skins/vector/views/molecules/BottomLeftMenu.js
+++ b/src/skins/vector/views/molecules/BottomLeftMenu.js
@@ -17,12 +17,9 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var classNames = require('classnames');
 
 var dis = require('matrix-react-sdk/lib/dispatcher');
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
-
 module.exports = React.createClass({
     displayName: 'BottomLeftMenu',
 
diff --git a/src/skins/vector/views/molecules/ContextualMenu.js b/src/skins/vector/views/molecules/ContextualMenu.js
index 1f0069de..e2d75da7 100644
--- a/src/skins/vector/views/molecules/ContextualMenu.js
+++ b/src/skins/vector/views/molecules/ContextualMenu.js
@@ -17,11 +17,6 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var classNames = require('classnames');
-
-var dis = require('matrix-react-sdk/lib/dispatcher');
-
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = React.createClass({
     displayName: 'ContextualMenu',
diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
index b9d729eb..698d2c15 100644
--- a/src/skins/vector/views/molecules/EventAsTextTile.js
+++ b/src/skins/vector/views/molecules/EventAsTextTile.js
@@ -18,7 +18,6 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var EventAsTextTileController = require('matrix-react-sdk/lib/controllers/molecules/EventAsTextTile')
 var sdk = require('matrix-react-sdk')
 var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
diff --git a/src/skins/vector/views/molecules/MImageTile.js b/src/skins/vector/views/molecules/MImageTile.js
index 63825359..34c2c576 100644
--- a/src/skins/vector/views/molecules/MImageTile.js
+++ b/src/skins/vector/views/molecules/MImageTile.js
@@ -52,7 +52,6 @@ module.exports = React.createClass({
     },
 
     onClick: function(ev) {
-        var ms = ev.getModifierState();
         if (ev.button == 0 && !ev.metaKey) {
             ev.preventDefault();
             var content = this.props.mxEvent.getContent();
diff --git a/src/skins/vector/views/molecules/MRoomMemberTile.js b/src/skins/vector/views/molecules/MRoomMemberTile.js
index d20b248e..4e163e1d 100644
--- a/src/skins/vector/views/molecules/MRoomMemberTile.js
+++ b/src/skins/vector/views/molecules/MRoomMemberTile.js
@@ -20,7 +20,6 @@ var React = require('react');
 
 var MRoomMemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MRoomMemberTile')
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
 
diff --git a/src/skins/vector/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
index 30ac6880..e8b9eeac 100644
--- a/src/skins/vector/views/molecules/MemberTile.js
+++ b/src/skins/vector/views/molecules/MemberTile.js
@@ -20,7 +20,6 @@ var React = require('react');
 
 var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
-var Modal = require('matrix-react-sdk/lib/Modal');
 var ContextualMenu = require('../../../../ContextualMenu');
 var MemberTileController = require('matrix-react-sdk/lib/controllers/molecules/MemberTile')
 
diff --git a/src/skins/vector/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
index 8b6ff6af..c94cade5 100644
--- a/src/skins/vector/views/molecules/MessageComposer.js
+++ b/src/skins/vector/views/molecules/MessageComposer.js
@@ -20,7 +20,6 @@ var React = require('react');
 
 var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var MessageComposerController = require('matrix-react-sdk/lib/controllers/molecules/MessageComposer')
-var ContentMessages = require('matrix-react-sdk/lib/ContentMessages');
 
 var sdk = require('matrix-react-sdk')
 
diff --git a/src/skins/vector/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
index 357d4bf9..386b19d3 100644
--- a/src/skins/vector/views/molecules/MessageTile.js
+++ b/src/skins/vector/views/molecules/MessageTile.js
@@ -20,7 +20,6 @@ var React = require('react');
 
 var classNames = require("classnames");
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 
 var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
diff --git a/src/skins/vector/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
index d4541f42..cadc0fc0 100644
--- a/src/skins/vector/views/molecules/RoomCreate.js
+++ b/src/skins/vector/views/molecules/RoomCreate.js
@@ -17,12 +17,9 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var classNames = require('classnames');
 
 //var RoomCreateController = require('matrix-react-sdk/lib/controllers/molecules/RoomCreateController')
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
-
 module.exports = React.createClass({
     displayName: 'RoomCreate',
     // mixins: [RoomCreateController],
diff --git a/src/skins/vector/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
index c3e8aa1f..b1e15077 100644
--- a/src/skins/vector/views/molecules/RoomDropTarget.js
+++ b/src/skins/vector/views/molecules/RoomDropTarget.js
@@ -17,12 +17,9 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
-var classNames = require('classnames');
 
 //var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
-
 module.exports = React.createClass({
     displayName: 'RoomDropTarget',
     // mixins: [RoomDropTargetController],
diff --git a/src/skins/vector/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
index b674fe2c..8cccc3c3 100644
--- a/src/skins/vector/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -18,7 +18,6 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 var CallViewController = require(
     "matrix-react-sdk/lib/controllers/molecules/voip/CallView"
diff --git a/src/skins/vector/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
index d3b8636e..80160b78 100644
--- a/src/skins/vector/views/molecules/voip/VideoView.js
+++ b/src/skins/vector/views/molecules/voip/VideoView.js
@@ -18,7 +18,6 @@ limitations under the License.
 
 var React = require('react');
 
-var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
 var sdk = require('matrix-react-sdk')
 var VideoViewController = require('matrix-react-sdk/lib/controllers/molecules/voip/VideoView')
 
diff --git a/src/skins/vector/views/organisms/LeftPanel.js b/src/skins/vector/views/organisms/LeftPanel.js
index 9941cfa2..15612704 100644
--- a/src/skins/vector/views/organisms/LeftPanel.js
+++ b/src/skins/vector/views/organisms/LeftPanel.js
@@ -26,7 +26,6 @@ module.exports = React.createClass({
         var RoomList = sdk.getComponent('organisms.RoomList');
         var BottomLeftMenu = sdk.getComponent('molecules.BottomLeftMenu');
         var IncomingCallBox = sdk.getComponent('molecules.voip.IncomingCallBox');
-        var RoomCreate = sdk.getComponent('molecules.RoomCreate');
 
         return (
             <aside className="mx_LeftPanel">
diff --git a/src/skins/vector/views/organisms/Notifier.js b/src/skins/vector/views/organisms/Notifier.js
index dad456cd..bbd2563d 100644
--- a/src/skins/vector/views/organisms/Notifier.js
+++ b/src/skins/vector/views/organisms/Notifier.js
@@ -18,7 +18,6 @@ limitations under the License.
 
 var NotifierController = require('matrix-react-sdk/lib/controllers/organisms/Notifier')
 
-var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var TextForEvent = require('matrix-react-sdk/lib/TextForEvent');
 var extend = require('matrix-react-sdk/lib/extend');
 var dis = require('matrix-react-sdk/lib/dispatcher');
diff --git a/src/skins/vector/views/organisms/RoomView.js b/src/skins/vector/views/organisms/RoomView.js
index 81f95fd4..17b6aac3 100644
--- a/src/skins/vector/views/organisms/RoomView.js
+++ b/src/skins/vector/views/organisms/RoomView.js
@@ -23,7 +23,6 @@ var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 var sdk = require('matrix-react-sdk')
 var classNames = require("classnames");
 var filesize = require('filesize');
-var q = require('q');
 
 var RoomViewController = require('matrix-react-sdk/lib/controllers/organisms/RoomView')
 
diff --git a/src/skins/vector/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
index 515a71aa..75951651 100644
--- a/src/skins/vector/views/organisms/UserSettings.js
+++ b/src/skins/vector/views/organisms/UserSettings.js
@@ -42,6 +42,7 @@ module.exports = React.createClass({
     },
 
     changePassword: function() {
+        var ChangePassword = sdk.getComponent('molecules/ChangePassword');
         Modal.createDialog(ChangePassword);
     },
 
@@ -61,7 +62,6 @@ module.exports = React.createClass({
             case this.Phases.Display:
                 var EditableText = sdk.getComponent('atoms/EditableText');
                 var EnableNotificationsButton = sdk.getComponent('atoms/EnableNotificationsButton');
-                var ChangePassword = sdk.getComponent('molecules/ChangePassword');
                 return (
                     <div className="mx_UserSettings">
                         <div className="mx_UserSettings_User">
diff --git a/src/skins/vector/views/pages/MatrixChat.js b/src/skins/vector/views/pages/MatrixChat.js
index 2b912df4..5c72ff70 100644
--- a/src/skins/vector/views/pages/MatrixChat.js
+++ b/src/skins/vector/views/pages/MatrixChat.js
@@ -23,7 +23,6 @@ var MatrixChatController = require('matrix-react-sdk/lib/controllers/pages/Matri
 
 // should be atomised
 var Loader = require("react-loader");
-var classNames = require("classnames");
 
 var dis = require('matrix-react-sdk/lib/dispatcher');
 
diff --git a/src/skins/vector/views/templates/Register.js b/src/skins/vector/views/templates/Register.js
index d0c3b146..fa4a3e18 100644
--- a/src/skins/vector/views/templates/Register.js
+++ b/src/skins/vector/views/templates/Register.js
@@ -73,18 +73,6 @@ module.exports = React.createClass({
         });
     },
 
-    getUserIdSuffix: function() {
-        return '';
-        var actualHsUrl = document.createElement('a');
-        actualHsUrl.href = this.getHsUrl();
-        var defaultHsUrl = document.createElement('a');
-        defaultHsUrl.href = this.DEFAULT_HS_URL;
-        if (actualHsUrl.host == defaultHsUrl.host) {
-            return ':matrix.org';
-        }
-        return '';
-    },
-
     onServerUrlChanged: function(newUrl) {
         this.customHsUrl = this.refs.serverConfig.getHsUrl();
         this.customIsUrl = this.refs.serverConfig.getIsUrl();
@@ -101,7 +89,7 @@ module.exports = React.createClass({
                     <div>
                         <form onSubmit={this.onInitialStageSubmit}>
                         <input className="mx_Login_field" type="text" ref="email" placeholder="Email address" defaultValue={this.savedParams.email} /><br />
-                        <input className="mx_Login_field" type="text" ref="username" placeholder="User name" defaultValue={this.savedParams.username} />{this.getUserIdSuffix()}<br />
+                        <input className="mx_Login_field" type="text" ref="username" placeholder="User name" defaultValue={this.savedParams.username} /><br />
                         <input className="mx_Login_field" type="password" ref="password" placeholder="Password" defaultValue={this.savedParams.password} /><br />
                         <input className="mx_Login_field" type="password" ref="confirmPassword" placeholder="Confirm password" defaultValue={this.savedParams.confirmPassword} /><br />
 

From 3ecf19df49e4df3f8c40f11dc98258d94f98f8f7 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 25 Sep 2015 17:38:51 +0100
Subject: [PATCH 18/29] Disable caching on the local http server as commented

---
 package.json | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/package.json b/package.json
index 002c0661..74cfe58b 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,8 @@
     "build": "npm run build:css && npm run build:compile && npm run build:bundle",
     "start:js": "webpack -w src/vector/index.js vector/bundle.js",
     "start:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css",
-    "start": "parallelshell 'npm run start:js' 'npm run start:skins:css' 'http-server vector'",
+    "//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
+    "start": "parallelshell 'npm run start:js' 'npm run start:skins:css' 'http-server -c 1 vector'",
     "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
     "prepublish": "npm run build:css && npm run build:compile"
   },

From 588dbf5693e02f0eeacbbe2cc4da410abe144b7e Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Mon, 28 Sep 2015 11:34:11 +0100
Subject: [PATCH 19/29] reskindex

---
 src/skins/vector/skindex.js | 1 -
 1 file changed, 1 deletion(-)

diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js
index 2b0bf28a..9afaddd6 100644
--- a/src/skins/vector/skindex.js
+++ b/src/skins/vector/skindex.js
@@ -45,7 +45,6 @@ skin.atoms.voip.VideoFeed = require('./views/atoms/voip/VideoFeed');
 skin.molecules.BottomLeftMenu = require('./views/molecules/BottomLeftMenu');
 skin.molecules.ChangeAvatar = require('./views/molecules/ChangeAvatar');
 skin.molecules.ChangePassword = require('./views/molecules/ChangePassword');
-skin.molecules.ContextualMenu = require('./views/molecules/ContextualMenu');
 skin.molecules.DateSeparator = require('./views/molecules/DateSeparator');
 skin.molecules.EventAsTextTile = require('./views/molecules/EventAsTextTile');
 skin.molecules.MEmoteTile = require('./views/molecules/MEmoteTile');

From c3f32b74e4321b5865ad7afc0cfaf339c45ab977 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Mon, 28 Sep 2015 14:48:07 +0100
Subject: [PATCH 20/29] Some missed '/' / '.' replacemement

---
 src/skins/vector/views/organisms/UserSettings.js | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/skins/vector/views/organisms/UserSettings.js b/src/skins/vector/views/organisms/UserSettings.js
index 75951651..64aac34b 100644
--- a/src/skins/vector/views/organisms/UserSettings.js
+++ b/src/skins/vector/views/organisms/UserSettings.js
@@ -42,7 +42,7 @@ module.exports = React.createClass({
     },
 
     changePassword: function() {
-        var ChangePassword = sdk.getComponent('molecules/ChangePassword');
+        var ChangePassword = sdk.getComponent('molecules.ChangePassword');
         Modal.createDialog(ChangePassword);
     },
 
@@ -60,8 +60,8 @@ module.exports = React.createClass({
             case this.Phases.Loading:
                 return <Loader />
             case this.Phases.Display:
-                var EditableText = sdk.getComponent('atoms/EditableText');
-                var EnableNotificationsButton = sdk.getComponent('atoms/EnableNotificationsButton');
+                var EditableText = sdk.getComponent('atoms.EditableText');
+                var EnableNotificationsButton = sdk.getComponent('atoms.EnableNotificationsButton');
                 return (
                     <div className="mx_UserSettings">
                         <div className="mx_UserSettings_User">

From 7d540572fd667330e4578d6eeb06d3b41e8d61e8 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Mon, 28 Sep 2015 17:06:39 +0100
Subject: [PATCH 21/29] Update for new default avatar API.

---
 src/Avatar.js                                | 10 ----------
 src/skins/vector/views/atoms/MemberAvatar.js | 15 +++++++++++++++
 2 files changed, 15 insertions(+), 10 deletions(-)

diff --git a/src/Avatar.js b/src/Avatar.js
index 74b279c6..a5b59a72 100644
--- a/src/Avatar.js
+++ b/src/Avatar.js
@@ -19,16 +19,6 @@ limitations under the License.
 var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = {
-    avatarUrlForMember: function(member, width, height, resizeMethod) {
-        var url = MatrixClientPeg.get().getAvatarUrlForMember(
-            member, width, height, resizeMethod, false
-        );
-        if (url === null) {
-            url = this.defaultAvatarUrlForString(member.userId);
-        }
-        return url;
-    },
-
     defaultAvatarUrlForString: function(s) {
         var total = 0;
         for (var i = 0; i < s.length; ++i) {
diff --git a/src/skins/vector/views/atoms/MemberAvatar.js b/src/skins/vector/views/atoms/MemberAvatar.js
index bd20723d..69652e1a 100644
--- a/src/skins/vector/views/atoms/MemberAvatar.js
+++ b/src/skins/vector/views/atoms/MemberAvatar.js
@@ -17,6 +17,7 @@ limitations under the License.
 'use strict';
 
 var React = require('react');
+var Avatar = require('../../../../Avatar');
 
 var MemberAvatarController = require('matrix-react-sdk/lib/controllers/atoms/MemberAvatar')
 
@@ -24,6 +25,20 @@ module.exports = React.createClass({
     displayName: 'MemberAvatar',
     mixins: [MemberAvatarController],
 
+    avatarUrlForMember: function(member) {
+        return Avatar.avatarUrlForMember(
+            member,
+            this.props.member,
+            this.props.width,
+            this.props.height,
+            this.props.resizeMethod
+        );
+    },
+
+    skinnedDefaultAvatarUrl: function(member, width, height, resizeMethod) {
+        return Avatar.defaultAvatarUrlForString(member.userId);
+    },
+
     render: function() {
         return (
             <img className="mx_MemberAvatar" src={this.state.imageUrl}

From fd6e7663cb60281138aa0b6e53a9e01ebeeb674b Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Mon, 28 Sep 2015 17:52:34 +0100
Subject: [PATCH 22/29] Fix notifications

---
 src/Avatar.js | 13 +++++++++++++
 1 file changed, 13 insertions(+)

diff --git a/src/Avatar.js b/src/Avatar.js
index a5b59a72..2f83ebd9 100644
--- a/src/Avatar.js
+++ b/src/Avatar.js
@@ -19,6 +19,19 @@ limitations under the License.
 var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
 
 module.exports = {
+    avatarUrlForMember: function(member, width, height, resizeMethod) {
+        var url = MatrixClientPeg.get().getAvatarUrlForMember(
+            member,
+            width,
+            height,
+            resizeMethod
+        );
+        if (!url) {
+            url = this.defaultAvatarUrlForString(member.userId);
+        }
+        return url;
+    },
+
     defaultAvatarUrlForString: function(s) {
         var total = 0;
         for (var i = 0; i < s.length; ++i) {

From 94a6f856d1e5b09a96b04e08466a155fa0fe4d07 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 30 Sep 2015 16:52:45 +0100
Subject: [PATCH 23/29] Use the new interface for providing conf call
 functionality. Doesn't shoe it in the right room yet.

---
 package.json                                  |   7 +-
 src/CallHandler.js                            | 281 ------------------
 src/controllers/molecules/voip/CallView.js    |   9 +-
 .../VectorConferenceHandler.js}               |  24 ++
 src/skins/vector/skindex.js                   | 121 ++++----
 src/vector/index.js                           |   1 +
 6 files changed, 92 insertions(+), 351 deletions(-)
 delete mode 100644 src/CallHandler.js
 rename src/{ConferenceHandler.js => modules/VectorConferenceHandler.js} (81%)

diff --git a/package.json b/package.json
index 74cfe58b..7199ba1b 100644
--- a/package.json
+++ b/package.json
@@ -23,14 +23,15 @@
     "prepublish": "npm run build:css && npm run build:compile"
   },
   "dependencies": {
-    "matrix-react-sdk": "^0.0.1",
     "classnames": "^2.1.2",
     "filesize": "^3.1.2",
     "flux": "~2.0.3",
+    "linkifyjs": "^2.0.0-beta.4",
+    "matrix-js-sdk": "^0.2.1",
+    "matrix-react-sdk": "^0.0.1",
     "q": "^1.4.1",
     "react": "^0.13.3",
-    "react-loader": "^1.4.0",
-    "linkifyjs": "^2.0.0-beta.4"
+    "react-loader": "^1.4.0"
   },
   "devDependencies": {
     "babel": "^5.8.23",
diff --git a/src/CallHandler.js b/src/CallHandler.js
deleted file mode 100644
index 17754d55..00000000
--- a/src/CallHandler.js
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
-Copyright 2015 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.
-*/
-
-'use strict';
-
-/*
- * Manages a list of all the currently active calls.
- *
- * This handler dispatches when voip calls are added/updated/removed from this list:
- * {
- *   action: 'call_state'
- *   room_id: <room ID of the call>
- * }
- *
- * To know the state of the call, this handler exposes a getter to
- * obtain the call for a room:
- *   var call = CallHandler.getCall(roomId)
- *   var state = call.call_state; // ringing|ringback|connected|ended|busy|stop_ringback|stop_ringing
- *
- * This handler listens for and handles the following actions:
- * {
- *   action: 'place_call',
- *   type: 'voice|video',
- *   room_id: <room that the place call button was pressed in>
- * }
- *
- * {
- *   action: 'incoming_call'
- *   call: MatrixCall
- * }
- *
- * {
- *   action: 'hangup'
- *   room_id: <room that the hangup button was pressed in>
- * }
- *
- * {
- *   action: 'answer'
- *   room_id: <room that the answer button was pressed in>
- * }
- */
-
-var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
-var Modal = require("matrix-react-sdk/lib/Modal");
-var sdk = require('matrix-react-sdk');
-var ConferenceCall = require("./ConferenceHandler").ConferenceCall;
-var ConferenceHandler = require("./ConferenceHandler");
-var Matrix = require("matrix-js-sdk");
-var dis = require("./dispatcher");
-
-var calls = {
-    //room_id: MatrixCall
-};
-
-function play(audioId) {
-    // TODO: Attach an invisible element for this instead
-    // which listens?
-    var audio = document.getElementById(audioId);
-    if (audio) {
-        audio.load();
-        audio.play();
-    }
-}
-
-function pause(audioId) {
-    // TODO: Attach an invisible element for this instead
-    // which listens?
-    var audio = document.getElementById(audioId);
-    if (audio) {
-        audio.pause();
-    }
-}
-
-function _setCallListeners(call) {
-    call.on("error", function(err) {
-        console.error("Call error: %s", err);
-        console.error(err.stack);
-        call.hangup();
-        _setCallState(undefined, call.roomId, "ended");
-    });
-    call.on("hangup", function() {
-        _setCallState(undefined, call.roomId, "ended");
-    });
-    // map web rtc states to dummy UI state
-    // ringing|ringback|connected|ended|busy|stop_ringback|stop_ringing
-    call.on("state", function(newState, oldState) {
-        if (newState === "ringing") {
-            _setCallState(call, call.roomId, "ringing");
-            pause("ringbackAudio");
-        }
-        else if (newState === "invite_sent") {
-            _setCallState(call, call.roomId, "ringback");
-            play("ringbackAudio");
-        }
-        else if (newState === "ended" && oldState === "connected") {
-            _setCallState(undefined, call.roomId, "ended");
-            pause("ringbackAudio");
-            play("callendAudio");
-        }
-        else if (newState === "ended" && oldState === "invite_sent" &&
-                (call.hangupParty === "remote" ||
-                (call.hangupParty === "local" && call.hangupReason === "invite_timeout")
-                )) {
-            _setCallState(call, call.roomId, "busy");
-            pause("ringbackAudio");
-            play("busyAudio");
-            var ErrorDialog = sdk.getComponent("organisms.ErrorDialog");
-            Modal.createDialog(ErrorDialog, {
-                title: "Call Timeout",
-                description: "The remote side failed to pick up."
-            });
-        }
-        else if (oldState === "invite_sent") {
-            _setCallState(call, call.roomId, "stop_ringback");
-            pause("ringbackAudio");
-        }
-        else if (oldState === "ringing") {
-            _setCallState(call, call.roomId, "stop_ringing");
-            pause("ringbackAudio");
-        }
-        else if (newState === "connected") {
-            _setCallState(call, call.roomId, "connected");
-            pause("ringbackAudio");
-        }
-    });
-}
-
-function _setCallState(call, roomId, status) {
-    console.log(
-        "Call state in %s changed to %s (%s)", roomId, status, (call ? call.state : "-")
-    );
-    calls[roomId] = call;
-    if (call) {
-        call.call_state = status;
-    }
-    dis.dispatch({
-        action: 'call_state',
-        room_id: roomId
-    });
-}
-
-dis.register(function(payload) {
-    switch (payload.action) {
-        case 'place_call':
-            if (module.exports.getAnyActiveCall()) {
-                Modal.createDialog(ErrorDialog, {
-                    title: "Existing Call",
-                    description: "You are already in a call."
-                });
-                return; // don't allow >1 call to be placed.
-            }
-            var room = MatrixClientPeg.get().getRoom(payload.room_id);
-            if (!room) {
-                console.error("Room %s does not exist.", payload.room_id);
-                return;
-            }
-
-            function placeCall(newCall) {
-                _setCallListeners(newCall);
-                _setCallState(newCall, newCall.roomId, "ringback");
-                if (payload.type === 'voice') {
-                    newCall.placeVoiceCall();
-                }
-                else if (payload.type === 'video') {
-                    newCall.placeVideoCall(
-                        payload.remote_element,
-                        payload.local_element
-                    );
-                }
-                else {
-                    console.error("Unknown conf call type: %s", payload.type);
-                }
-            }
-
-            var members = room.getJoinedMembers();
-            if (members.length <= 1) {
-                Modal.createDialog(ErrorDialog, {
-                    description: "You cannot place a call with yourself."
-                });
-                return;
-            }
-            else if (members.length === 2) {
-                console.log("Place %s call in %s", payload.type, payload.room_id);
-                var call = Matrix.createNewMatrixCall(
-                    MatrixClientPeg.get(), payload.room_id
-                );
-                placeCall(call);
-            }
-            else { // > 2
-                console.log("Place conference call in %s", payload.room_id);
-                var confCall = new ConferenceCall(
-                    MatrixClientPeg.get(), payload.room_id
-                );
-                confCall.setup().done(function(call) {
-                    placeCall(call);
-                }, function(err) {
-                    console.error("Failed to setup conference call: %s", err);
-                });
-            }
-            break;
-        case 'incoming_call':
-            if (module.exports.getAnyActiveCall()) {
-                payload.call.hangup("busy");
-                return; // don't allow >1 call to be received, hangup newer one.
-            }
-            var call = payload.call;
-            _setCallListeners(call);
-            _setCallState(call, call.roomId, "ringing");
-            break;
-        case 'hangup':
-            if (!calls[payload.room_id]) {
-                return; // no call to hangup
-            }
-            calls[payload.room_id].hangup();
-            _setCallState(null, payload.room_id, "ended");
-            break;
-        case 'answer':
-            if (!calls[payload.room_id]) {
-                return; // no call to answer
-            }
-            calls[payload.room_id].answer();
-            _setCallState(calls[payload.room_id], payload.room_id, "connected");
-            dis.dispatch({
-                action: "view_room",
-                room_id: payload.room_id
-            });
-            break;
-    }
-});
-
-module.exports = {
-
-    getCallForRoom: function(roomId) {
-        return (
-            module.exports.getCall(roomId) ||
-            module.exports.getConferenceCall(roomId)
-        );
-    },
-
-    getCall: function(roomId) {
-        return calls[roomId] || null;
-    },
-
-    getConferenceCall: function(roomId) {
-        // search for a conference 1:1 call for this group chat room ID
-        var activeCall = module.exports.getAnyActiveCall();
-        if (activeCall && activeCall.confUserId) {
-            var thisRoomConfUserId = ConferenceHandler.getConferenceUserIdForRoom(
-                roomId
-            );
-            if (thisRoomConfUserId === activeCall.confUserId) {
-                return activeCall;
-            }
-        }
-        return null;
-    },
-
-    getAnyActiveCall: function() {
-        var roomsWithCalls = Object.keys(calls);
-        for (var i = 0; i < roomsWithCalls.length; i++) {
-            if (calls[roomsWithCalls[i]] &&
-                    calls[roomsWithCalls[i]].call_state !== "ended") {
-                return calls[roomsWithCalls[i]];
-            }
-        }
-        return null;
-    }
-};
diff --git a/src/controllers/molecules/voip/CallView.js b/src/controllers/molecules/voip/CallView.js
index a20e4463..e782f228 100644
--- a/src/controllers/molecules/voip/CallView.js
+++ b/src/controllers/molecules/voip/CallView.js
@@ -16,9 +16,11 @@ limitations under the License.
 
 'use strict';
 var dis = require("../../../dispatcher");
-var CallHandler = require("../../../CallHandler");
+var CallHandler = require("matrix-react-sdk/lib/CallHandler");
 var MatrixClientPeg = require("../../../MatrixClientPeg");
 
+var VectorConferenceHandler = require('./VectorConferenceHandler');
+
 /*
  * State vars:
  * this.state.call = MatrixCall|null
@@ -66,7 +68,10 @@ module.exports = {
     },
 
     showCall: function(roomId) {
-        var call = CallHandler.getCallForRoom(roomId);
+        var call = (
+            CallHandler.getCallForRoom(roomId) ||
+            VectorConferenceHandler.getConferenceCallForRoom(roomId)
+        );
         if (call) {
             call.setLocalVideoElement(this.getVideoView().getLocalVideoElement());
             // N.B. the remote video element is used for playback for audio for voice calls
diff --git a/src/ConferenceHandler.js b/src/modules/VectorConferenceHandler.js
similarity index 81%
rename from src/ConferenceHandler.js
rename to src/modules/VectorConferenceHandler.js
index c617672e..0d42461f 100644
--- a/src/ConferenceHandler.js
+++ b/src/modules/VectorConferenceHandler.js
@@ -1,4 +1,21 @@
+/*
+Copyright 2015 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.
+*/
+
 "use strict";
+
 var q = require("q");
 var Matrix = require("matrix-js-sdk");
 var Room = Matrix.Room;
@@ -90,5 +107,12 @@ module.exports.getConferenceUserIdForRoom = function(roomId) {
     return "@" + USER_PREFIX + base64RoomId + ":" + DOMAIN;
 };
 
+module.exports.createNewMatrixCall = function(client, roomId) {
+    return new ConferenceCall(
+        client, roomId
+    );
+};
+
 module.exports.ConferenceCall = ConferenceCall;
 
+module.exports.slot = 'conference';
diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js
index 9afaddd6..4f76ad62 100644
--- a/src/skins/vector/skindex.js
+++ b/src/skins/vector/skindex.js
@@ -21,71 +21,62 @@ limitations under the License.
  * You are not a salmon.
  */
 
-var skin = {
-    atoms: {},
-    molecules: {},
-    organisms: {},
-    templates: {},
-    pages: {}
-};
+var skin = {};
 
-skin.atoms.EditableText = require('./views/atoms/EditableText');
-skin.atoms.EnableNotificationsButton = require('./views/atoms/EnableNotificationsButton');
-skin.atoms.ImageView = require('./views/atoms/ImageView');
-skin.atoms.LogoutButton = require('./views/atoms/LogoutButton');
-skin.atoms.MemberAvatar = require('./views/atoms/MemberAvatar');
-skin.atoms.MessageTimestamp = require('./views/atoms/MessageTimestamp');
-skin.atoms.RoomAvatar = require('./views/atoms/RoomAvatar');
-skin.atoms.create_room = {};
-skin.atoms.create_room.CreateRoomButton = require('./views/atoms/create_room/CreateRoomButton');
-skin.atoms.create_room.Presets = require('./views/atoms/create_room/Presets');
-skin.atoms.create_room.RoomAlias = require('./views/atoms/create_room/RoomAlias');
-skin.atoms.voip = {};
-skin.atoms.voip.VideoFeed = require('./views/atoms/voip/VideoFeed');
-skin.molecules.BottomLeftMenu = require('./views/molecules/BottomLeftMenu');
-skin.molecules.ChangeAvatar = require('./views/molecules/ChangeAvatar');
-skin.molecules.ChangePassword = require('./views/molecules/ChangePassword');
-skin.molecules.DateSeparator = require('./views/molecules/DateSeparator');
-skin.molecules.EventAsTextTile = require('./views/molecules/EventAsTextTile');
-skin.molecules.MEmoteTile = require('./views/molecules/MEmoteTile');
-skin.molecules.MFileTile = require('./views/molecules/MFileTile');
-skin.molecules.MImageTile = require('./views/molecules/MImageTile');
-skin.molecules.MNoticeTile = require('./views/molecules/MNoticeTile');
-skin.molecules.MRoomMemberTile = require('./views/molecules/MRoomMemberTile');
-skin.molecules.MTextTile = require('./views/molecules/MTextTile');
-skin.molecules.MatrixToolbar = require('./views/molecules/MatrixToolbar');
-skin.molecules.MemberInfo = require('./views/molecules/MemberInfo');
-skin.molecules.MemberTile = require('./views/molecules/MemberTile');
-skin.molecules.MessageComposer = require('./views/molecules/MessageComposer');
-skin.molecules.MessageTile = require('./views/molecules/MessageTile');
-skin.molecules.ProgressBar = require('./views/molecules/ProgressBar');
-skin.molecules.RoomCreate = require('./views/molecules/RoomCreate');
-skin.molecules.RoomDropTarget = require('./views/molecules/RoomDropTarget');
-skin.molecules.RoomHeader = require('./views/molecules/RoomHeader');
-skin.molecules.RoomSettings = require('./views/molecules/RoomSettings');
-skin.molecules.RoomTile = require('./views/molecules/RoomTile');
-skin.molecules.SenderProfile = require('./views/molecules/SenderProfile');
-skin.molecules.ServerConfig = require('./views/molecules/ServerConfig');
-skin.molecules.UnknownMessageTile = require('./views/molecules/UnknownMessageTile');
-skin.molecules.UserSelector = require('./views/molecules/UserSelector');
-skin.molecules.voip = {};
-skin.molecules.voip.CallView = require('./views/molecules/voip/CallView');
-skin.molecules.voip.IncomingCallBox = require('./views/molecules/voip/IncomingCallBox');
-skin.molecules.voip.VideoView = require('./views/molecules/voip/VideoView');
-skin.organisms.CreateRoom = require('./views/organisms/CreateRoom');
-skin.organisms.ErrorDialog = require('./views/organisms/ErrorDialog');
-skin.organisms.LeftPanel = require('./views/organisms/LeftPanel');
-skin.organisms.LogoutPrompt = require('./views/organisms/LogoutPrompt');
-skin.organisms.MemberList = require('./views/organisms/MemberList');
-skin.organisms.Notifier = require('./views/organisms/Notifier');
-skin.organisms.QuestionDialog = require('./views/organisms/QuestionDialog');
-skin.organisms.RightPanel = require('./views/organisms/RightPanel');
-skin.organisms.RoomDirectory = require('./views/organisms/RoomDirectory');
-skin.organisms.RoomList = require('./views/organisms/RoomList');
-skin.organisms.RoomView = require('./views/organisms/RoomView');
-skin.organisms.UserSettings = require('./views/organisms/UserSettings');
-skin.pages.MatrixChat = require('./views/pages/MatrixChat');
-skin.templates.Login = require('./views/templates/Login');
-skin.templates.Register = require('./views/templates/Register');
+skin['atoms.EditableText'] = require('./views/atoms/EditableText');
+skin['atoms.EnableNotificationsButton'] = require('./views/atoms/EnableNotificationsButton');
+skin['atoms.ImageView'] = require('./views/atoms/ImageView');
+skin['atoms.LogoutButton'] = require('./views/atoms/LogoutButton');
+skin['atoms.MemberAvatar'] = require('./views/atoms/MemberAvatar');
+skin['atoms.MessageTimestamp'] = require('./views/atoms/MessageTimestamp');
+skin['atoms.RoomAvatar'] = require('./views/atoms/RoomAvatar');
+skin['atoms.create_room.CreateRoomButton'] = require('./views/atoms/create_room/CreateRoomButton');
+skin['atoms.create_room.Presets'] = require('./views/atoms/create_room/Presets');
+skin['atoms.create_room.RoomAlias'] = require('./views/atoms/create_room/RoomAlias');
+skin['atoms.voip.VideoFeed'] = require('./views/atoms/voip/VideoFeed');
+skin['molecules.BottomLeftMenu'] = require('./views/molecules/BottomLeftMenu');
+skin['molecules.ChangeAvatar'] = require('./views/molecules/ChangeAvatar');
+skin['molecules.ChangePassword'] = require('./views/molecules/ChangePassword');
+skin['molecules.DateSeparator'] = require('./views/molecules/DateSeparator');
+skin['molecules.EventAsTextTile'] = require('./views/molecules/EventAsTextTile');
+skin['molecules.MEmoteTile'] = require('./views/molecules/MEmoteTile');
+skin['molecules.MFileTile'] = require('./views/molecules/MFileTile');
+skin['molecules.MImageTile'] = require('./views/molecules/MImageTile');
+skin['molecules.MNoticeTile'] = require('./views/molecules/MNoticeTile');
+skin['molecules.MRoomMemberTile'] = require('./views/molecules/MRoomMemberTile');
+skin['molecules.MTextTile'] = require('./views/molecules/MTextTile');
+skin['molecules.MatrixToolbar'] = require('./views/molecules/MatrixToolbar');
+skin['molecules.MemberInfo'] = require('./views/molecules/MemberInfo');
+skin['molecules.MemberTile'] = require('./views/molecules/MemberTile');
+skin['molecules.MessageComposer'] = require('./views/molecules/MessageComposer');
+skin['molecules.MessageTile'] = require('./views/molecules/MessageTile');
+skin['molecules.ProgressBar'] = require('./views/molecules/ProgressBar');
+skin['molecules.RoomCreate'] = require('./views/molecules/RoomCreate');
+skin['molecules.RoomDropTarget'] = require('./views/molecules/RoomDropTarget');
+skin['molecules.RoomHeader'] = require('./views/molecules/RoomHeader');
+skin['molecules.RoomSettings'] = require('./views/molecules/RoomSettings');
+skin['molecules.RoomTile'] = require('./views/molecules/RoomTile');
+skin['molecules.SenderProfile'] = require('./views/molecules/SenderProfile');
+skin['molecules.ServerConfig'] = require('./views/molecules/ServerConfig');
+skin['molecules.UnknownMessageTile'] = require('./views/molecules/UnknownMessageTile');
+skin['molecules.UserSelector'] = require('./views/molecules/UserSelector');
+skin['molecules.voip.CallView'] = require('./views/molecules/voip/CallView');
+skin['molecules.voip.IncomingCallBox'] = require('./views/molecules/voip/IncomingCallBox');
+skin['molecules.voip.VideoView'] = require('./views/molecules/voip/VideoView');
+skin['organisms.CreateRoom'] = require('./views/organisms/CreateRoom');
+skin['organisms.ErrorDialog'] = require('./views/organisms/ErrorDialog');
+skin['organisms.LeftPanel'] = require('./views/organisms/LeftPanel');
+skin['organisms.LogoutPrompt'] = require('./views/organisms/LogoutPrompt');
+skin['organisms.MemberList'] = require('./views/organisms/MemberList');
+skin['organisms.Notifier'] = require('./views/organisms/Notifier');
+skin['organisms.QuestionDialog'] = require('./views/organisms/QuestionDialog');
+skin['organisms.RightPanel'] = require('./views/organisms/RightPanel');
+skin['organisms.RoomDirectory'] = require('./views/organisms/RoomDirectory');
+skin['organisms.RoomList'] = require('./views/organisms/RoomList');
+skin['organisms.RoomView'] = require('./views/organisms/RoomView');
+skin['organisms.UserSettings'] = require('./views/organisms/UserSettings');
+skin['pages.MatrixChat'] = require('./views/pages/MatrixChat');
+skin['templates.Login'] = require('./views/templates/Login');
+skin['templates.Register'] = require('./views/templates/Register');
 
 module.exports = skin;
\ No newline at end of file
diff --git a/src/vector/index.js b/src/vector/index.js
index accba178..597803f7 100644
--- a/src/vector/index.js
+++ b/src/vector/index.js
@@ -19,6 +19,7 @@ limitations under the License.
 var React = require("react");
 var sdk = require("matrix-react-sdk");
 sdk.loadSkin(require('../skins/vector/skindex'));
+sdk.loadModule(require('../modules/VectorConferenceHandler'));
 
 var lastLocationHashSet = null;
 

From 3845a989f6cbd9585807aa34c545ac9191f02b62 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Wed, 30 Sep 2015 18:22:15 +0100
Subject: [PATCH 24/29] Get conf calling working, apart from the end call
 button showing in the right room.

---
 src/controllers/molecules/voip/CallView.js     |  6 +++---
 src/modules/VectorConferenceHandler.js         | 18 +++++++++++++++++-
 .../vector/views/molecules/voip/CallView.js    |  2 +-
 3 files changed, 21 insertions(+), 5 deletions(-)

diff --git a/src/controllers/molecules/voip/CallView.js b/src/controllers/molecules/voip/CallView.js
index e782f228..d511b9d4 100644
--- a/src/controllers/molecules/voip/CallView.js
+++ b/src/controllers/molecules/voip/CallView.js
@@ -15,11 +15,11 @@ limitations under the License.
 */
 
 'use strict';
-var dis = require("../../../dispatcher");
+var dis = require("matrix-react-sdk/lib/dispatcher");
 var CallHandler = require("matrix-react-sdk/lib/CallHandler");
-var MatrixClientPeg = require("../../../MatrixClientPeg");
+var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
 
-var VectorConferenceHandler = require('./VectorConferenceHandler');
+var VectorConferenceHandler = require('../../../modules/VectorConferenceHandler');
 
 /*
  * State vars:
diff --git a/src/modules/VectorConferenceHandler.js b/src/modules/VectorConferenceHandler.js
index 0d42461f..637e34f9 100644
--- a/src/modules/VectorConferenceHandler.js
+++ b/src/modules/VectorConferenceHandler.js
@@ -19,6 +19,7 @@ limitations under the License.
 var q = require("q");
 var Matrix = require("matrix-js-sdk");
 var Room = Matrix.Room;
+var CallHandler = require('matrix-react-sdk/lib/CallHandler');
 
 // FIXME: This currently forces Vector to try to hit the matrix.org AS for conferencing.
 // This is bad because it prevents people running their own ASes from being used.
@@ -108,9 +109,24 @@ module.exports.getConferenceUserIdForRoom = function(roomId) {
 };
 
 module.exports.createNewMatrixCall = function(client, roomId) {
-    return new ConferenceCall(
+    var confCall = new ConferenceCall(
         client, roomId
     );
+    return confCall.setup();
+};
+
+module.exports.getConferenceCallForRoom = function(roomId) {
+    // search for a conference 1:1 call for this group chat room ID
+    var activeCall = CallHandler.getAnyActiveCall();
+    if (activeCall && activeCall.confUserId) {
+        var thisRoomConfUserId = module.exports.getConferenceUserIdForRoom(
+            roomId
+        );
+        if (thisRoomConfUserId === activeCall.confUserId) {
+            return activeCall;
+        }
+    }
+    return null;
 };
 
 module.exports.ConferenceCall = ConferenceCall;
diff --git a/src/skins/vector/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
index 8cccc3c3..07987bd3 100644
--- a/src/skins/vector/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -20,7 +20,7 @@ var React = require('react');
 
 var sdk = require('matrix-react-sdk')
 var CallViewController = require(
-    "matrix-react-sdk/lib/controllers/molecules/voip/CallView"
+    "../../../../../controllers/molecules/voip/CallView"
 );
 
 module.exports = React.createClass({

From c687f32f39fe706c89fdcef5418cf98a90a14374 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Thu, 1 Oct 2015 10:46:42 +0100
Subject: [PATCH 25/29] Port over custom vector roomlist controller with mini
 callview

---
 src/controllers/organisms/RoomList.js        | 169 +++++++++++++++++++
 src/skins/vector/views/organisms/RoomList.js |   2 +-
 2 files changed, 170 insertions(+), 1 deletion(-)
 create mode 100644 src/controllers/organisms/RoomList.js

diff --git a/src/controllers/organisms/RoomList.js b/src/controllers/organisms/RoomList.js
new file mode 100644
index 00000000..2602315a
--- /dev/null
+++ b/src/controllers/organisms/RoomList.js
@@ -0,0 +1,169 @@
+/*
+Copyright 2015 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.
+*/
+
+'use strict';
+
+var React = require("react");
+var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
+var RoomListSorter = require("matrix-react-sdk/lib/RoomListSorter");
+var dis = require("matrix-react-sdk/lib/dispatcher");
+
+var sdk = require('matrix-react-sdk');
+var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
+var CallHandler = require("matrix-react-sdk/lib/CallHandler");
+
+var HIDE_CONFERENCE_CHANS = true;
+
+module.exports = {
+    componentWillMount: function() {
+        var cli = MatrixClientPeg.get();
+        cli.on("Room", this.onRoom);
+        cli.on("Room.timeline", this.onRoomTimeline);
+        cli.on("Room.name", this.onRoomName);
+
+        var rooms = this.getRoomList();
+        this.setState({
+            roomList: rooms,
+            activityMap: {}
+        });
+    },
+
+    componentDidMount: function() {
+        this.dispatcherRef = dis.register(this.onAction);
+    },
+
+    onAction: function(payload) {
+        switch (payload.action) {
+            // listen for call state changes to prod the render method, which
+            // may hide the global CallView if the call it is tracking is dead
+            case 'call_state':
+                this._recheckCallElement(this.props.selectedRoom);
+                break;
+        }
+    },
+
+    componentWillUnmount: function() {
+        dis.unregister(this.dispatcherRef);
+        if (MatrixClientPeg.get()) {
+            MatrixClientPeg.get().removeListener("Room", this.onRoom);
+            MatrixClientPeg.get().removeListener("Room.timeline", this.onRoomTimeline);
+            MatrixClientPeg.get().removeListener("Room.name", this.onRoomName);
+        }
+    },
+
+    componentWillReceiveProps: function(newProps) {
+        this.state.activityMap[newProps.selectedRoom] = undefined;
+        this._recheckCallElement(newProps.selectedRoom);
+        this.setState({
+            activityMap: this.state.activityMap
+        });
+    },
+
+    onRoom: function(room) {
+        this.refreshRoomList();
+    },
+
+    onRoomTimeline: function(ev, room, toStartOfTimeline) {
+        if (toStartOfTimeline) return;
+
+        var newState = {
+            roomList: this.getRoomList()
+        };
+        if (
+            room.roomId != this.props.selectedRoom &&
+            ev.getSender() != MatrixClientPeg.get().credentials.userId)
+        {
+            var hl = 1;
+
+            var actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
+            if (actions && actions.tweaks && actions.tweaks.highlight) {
+                hl = 2;
+            }
+            // obviously this won't deep copy but this shouldn't be necessary
+            var amap = this.state.activityMap;
+            amap[room.roomId] = Math.max(amap[room.roomId] || 0, hl);
+
+            newState.activityMap = amap;
+        }
+        this.setState(newState);
+    },
+
+    onRoomName: function(room) {
+        this.refreshRoomList();
+    },
+
+    refreshRoomList: function() {
+        var rooms = this.getRoomList();
+        this.setState({
+            roomList: rooms
+        });
+    },
+
+    getRoomList: function() {
+        return RoomListSorter.mostRecentActivityFirst(
+            MatrixClientPeg.get().getRooms().filter(function(room) {
+                var me = room.getMember(MatrixClientPeg.get().credentials.userId);
+                var shouldShowRoom =  (
+                    me && (me.membership == "join" || me.membership == "invite")
+                );
+                // hiding conf rooms only ever toggles shouldShowRoom to false
+                if (shouldShowRoom && HIDE_CONFERENCE_CHANS) {
+                    // we want to hide the 1:1 conf<->user room and not the group chat
+                    var joinedMembers = room.getJoinedMembers();
+                    if (joinedMembers.length === 2) {
+                        var otherMember = joinedMembers.filter(function(m) {
+                            return m.userId !== me.userId
+                        })[0];
+                        if (VectorConferenceHandler.isConferenceUser(otherMember)) {
+                            // console.log("Hiding conference 1:1 room %s", room.roomId);
+                            shouldShowRoom = false;
+                        }
+                    }
+                }
+                return shouldShowRoom;
+            })
+        );
+    },
+
+    _recheckCallElement: function(selectedRoomId) {
+        // if we aren't viewing a room with an ongoing call, but there is an
+        // active call, show the call element - we need to do this to make
+        // audio/video not crap out
+        var activeCall = CallHandler.getAnyActiveCall();
+        var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
+        var showCall = (activeCall && !callForRoom);
+        this.setState({
+            show_call_element: showCall
+        });
+    },
+
+    makeRoomTiles: function() {
+        var self = this;
+        var RoomTile = sdk.getComponent("molecules.RoomTile");
+        return this.state.roomList.map(function(room) {
+            var selected = room.roomId == self.props.selectedRoom;
+            return (
+                <RoomTile
+                    room={room}
+                    key={room.roomId}
+                    selected={selected}
+                    unread={self.state.activityMap[room.roomId] === 1}
+                    highlight={self.state.activityMap[room.roomId] === 2}
+                />
+            );
+        });
+    }
+};
diff --git a/src/skins/vector/views/organisms/RoomList.js b/src/skins/vector/views/organisms/RoomList.js
index 7c992566..779fd1c6 100644
--- a/src/skins/vector/views/organisms/RoomList.js
+++ b/src/skins/vector/views/organisms/RoomList.js
@@ -19,7 +19,7 @@ limitations under the License.
 var React = require('react');
 var sdk = require('matrix-react-sdk')
 
-var RoomListController = require('matrix-react-sdk/lib/controllers/organisms/RoomList')
+var RoomListController = require('../../../../controllers/organisms/RoomList')
 
 module.exports = React.createClass({
     displayName: 'RoomList',

From 7b9cd7c23229edfe2e5119e800bdbf03499e4548 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Thu, 1 Oct 2015 16:02:44 +0100
Subject: [PATCH 26/29] Update readme

---
 README.md | 148 +++++++-----------------------------------------------
 1 file changed, 18 insertions(+), 130 deletions(-)

diff --git a/README.md b/README.md
index 59182102..2d3dfba3 100644
--- a/README.md
+++ b/README.md
@@ -10,145 +10,33 @@ Getting started
 2. Clone the repo: `git clone https://github.com/vector-im/vector-web.git` 
 3. Switch to the SDK directory: `cd vector-web`
 4. Install the prerequisites: `npm install`
-5. Switch to the example directory: `cd examples/vector`
-6. Install the example app prerequisites: `npm install`
-7. Build the example and start a server: `npm start`
+5. Start the development builder and a testing server: `npm start`
+6. Wait a few seconds for the initial build to finish.
+7. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
 
-Now open http://127.0.0.1:8080/ in your browser to see your newly built
-Vector.
+Wiht `npm start`, Any changes you make to the source files will cause a rebuild so
+your changes will show up when you refresh.
+
+For production use, run `npm run build` to build all the necessary files
+into the `vector` directory and run your own server.
 
 Development
 ===========
-
-To work on the CSS and Javascript and have the bundle files update as you
-change the source files, you'll need to do two extra things:
+You can work on any of the source files within Vector with the setup above,
+and your changes will cause an instant rebuild. If you also need to make
+changes to the react sdk, you can:
 
 1. Link the react sdk package into the example:
-   `cd vector-web/examples/vector; npm link ../../`
-2. Start a watcher for the CSS files:
-   `cd vector-web; npm run start:css`
+   `npm link path/to/your/react/sdk`
+2. Start the development rebuilder in your react SDK directory:
+   `npm start`
 
-Note that you may need to restart the CSS builder if you add a new file. Note
-that `npm start` builds debug versions of the javascript and CSS, which are
-much larger than the production versions build by the `npm run build` commands.
-
-IMPORTANT: If you customise components in your application (and hence require
-react from your app) you must be sure to:
-
-1. Make your app depend on react directly
-2. If you `npm link` matrix-react-sdk, manually remove the 'react' directory
-   from matrix-react-sdk's `node_modules` folder, otherwise browserify will
-   pull in both copies of react which causes the app to break.
+If you add or remove any components from the Vector skin, you will need to rebuild
+the skin's index by running, `npm run reskindex`.
 
 Deployment
 ==========
 
-Just run `npm build` in the `examples/vector` directory, and then mount the
-`examples/vector` directory on your webserver to actually serve up the app,
-which is entirely static content.
+Just run `npm build` and then mount the `vector` directory on your webserver to
+actually serve up the app, which is entirely static content.
 
-How to customise the SDK
-========================
-
-The matrix-react-sdk provides well-defined reusable UI components which may be
-customised/replaced by the developer to build into an app.  A set of consistent
-UI components (View + CSS classes) is called a 'skin' - currently the SDK
-provides a very vanilla whitelabelled 'base skin'.  In future the SDK could
-provide alternative skins (probably by extending the base skin) that provide more
-specific look and feels (e.g. "IRC-style", "Skype-style") etc.  However, unlike
-Wordpress themes and similar, we don't normally expect app developers to define
-reusable skins.  Instead you just go and incorporate your view customisations
-into your actual app.
-
-The SDK uses the 'atomic' design pattern as seen at http://patternlab.io to
-encourage a very modular and reusable architecture, making it easy to
-customise and use UI widgets independently of the rest of the SDK and your app.
-In practice this means:
-
- * The UI of the app is strictly split up into a hierarchy of components.
- 
- * Each component has its own:
-   * View object defined as a React javascript class containing embedded
-     HTML expressed in React's JSX notation.
-   * CSS file, which defines the styling specific to that component.
- 
- * Components are loosely grouped into the 5 levels outlined by atomic design:
-   * atoms: fundamental building blocks (e.g. a timestamp tag)
-   * molecules: "group of atoms which functions together as a unit"
-     (e.g. a message in a chat timeline)
-   * organisms: "groups of molecules (and atoms) which form a distinct section
-     of a UI" (e.g. a view of a chat room)
-   * templates: "a reusable configuration of organisms" - used to combine and
-     style organisms into a well-defined global look and feel
-   * pages: specific instances of templates.
-
- Good separation between the components is maintained by adopting various best
- practices that anyone working with the SDK needs to be be aware of and uphold:
-
-  * Views are named with upper camel case (e.g. molecules/MessageTile.js)
-
-  * The view's CSS file MUST have the same name (e.g. molecules/MessageTile.css)
-
-  * Per-view CSS is optional - it could choose to inherit all its styling from
-    the context of the rest of the app, although this is unusual for any but 
-    the simplest atoms and molecules.
-
-  * The view MUST *only* refer to the CSS rules defined in its own CSS file.
-    'Stealing' styling information from other components (including parents)
-    is not cool, as it breaks the independence of the components.
-
-  * CSS classes are named with an app-specific namespacing prefix to try to avoid
-    CSS collisions.  The base skin shipped by Matrix.org with the matrix-react-sdk
-    uses the naming prefix "mx_".  A company called Yoyodyne Inc might use a
-    prefix like "yy_" for its app-specific classes.
-
-  * CSS classes use upper camel case when they describe React components - e.g.
-    .mx_MessageTile is the selector for the CSS applied to a MessageTile view.
-
-  * CSS classes for DOM elements within a view which aren't components are named
-    by appending a lower camel case identifier to the view's class name - e.g.
-    .mx_MessageTile_randomDiv is how you'd name the class of an arbitrary div
-    within the MessageTile view.
-
-  * We deliberately use vanilla CSS 3.0 to avoid adding any more magic
-    dependencies into the mix than we already have.  App developers are welcome
-    to use whatever floats their boat however.
-
-  * The CSS for a component can however override the rules for child components.
-    For instance, .mx_RoomList .mx_RoomTile {} would be the selector to override
-    styles of RoomTiles when viewed in the context of a RoomList view.
-    Overrides *must* be scoped to the View's CSS class - i.e. don't just define
-    .mx_RoomTile {} in RoomList.css - only RoomTile.css is allowed to define its
-    own CSS.  Instead, say .mx_RoomList .mx_RoomTile {} to scope the override
-    only to the context of RoomList views.  N.B. overrides should be relatively
-    rare as in general CSS inheritence should be enough.
-
-  * Components should render only within the bounding box of their outermost DOM
-    element. Page-absolute positioning and negative CSS margins and similar are
-    generally not cool and stop the component from being reused easily in
-    different places.
-
-  * We don't use the atomify library itself, as React already provides most
-    of the modularity requirements it brings to the table.
-
-With all this in mind, here's how you go about skinning the react SDK UI
-components to embed a Matrix client into your app:
-
-  * Create a new NPM project. Be sure to directly depend on react, (otherwise
-    you can end up with two copies of react).
-  * Create an index.js file that sets up react. Add require statements for
-    React, the ComponentBroker and matrix-react-sdk and a call to Render
-    the root React element as in the examples.
-  * Create React classes for any custom components you wish to add. These
-    can be based off the files in `views` in the `matrix-react-sdk` package,
-    modifying the require() statement appropriately.
-    You only need to copy files you want to customise.
-  * Add a ComponentBroker.set() call for each of your custom components. These
-    must come *before* `require("matrix-react-sdk")`.
-  * Add a way to build your project: we suggest copying the browserify calls
-    from the example projects, but you could use grunt or gulp.
-  * Create an index.html file pulling in your compiled index.js file, the
-    CSS bundle from matrix-react-sdk.
-
-For more specific detail on any of these steps, look at the `custom` example in
-matrix-react-sdk/examples.

From 2247d951d66a0862a8a7bc2893bdb2a6083f0162 Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 2 Oct 2015 11:48:52 +0100
Subject: [PATCH 27/29] Add config file for default hs/is urls

---
 config.json                               |  4 ++++
 package.json                              |  1 +
 src/skins/vector/views/templates/Login.js | 13 ++++++-------
 3 files changed, 11 insertions(+), 7 deletions(-)
 create mode 100644 config.json

diff --git a/config.json b/config.json
new file mode 100644
index 00000000..923d23ab
--- /dev/null
+++ b/config.json
@@ -0,0 +1,4 @@
+{
+    "default_hs_url": "https://matrix.org",
+    "default_is_url": "https://vector.im"
+}
diff --git a/package.json b/package.json
index 7199ba1b..58e6439f 100644
--- a/package.json
+++ b/package.json
@@ -39,6 +39,7 @@
     "babel-loader": "^5.3.2",
     "catw": "^1.0.1",
     "http-server": "^0.8.4",
+    "json-loader": "^0.5.3",
     "parallelshell": "^1.2.0",
     "rimraf": "^2.4.3",
     "source-map-loader": "^0.1.5",
diff --git a/src/skins/vector/views/templates/Login.js b/src/skins/vector/views/templates/Login.js
index 2a0068f4..4e78dce9 100644
--- a/src/skins/vector/views/templates/Login.js
+++ b/src/skins/vector/views/templates/Login.js
@@ -25,10 +25,9 @@ var Loader = require("react-loader");
 
 var LoginController = require('matrix-react-sdk/lib/controllers/templates/Login')
 
-module.exports = React.createClass({
-    DEFAULT_HS_URL: 'https://matrix.org',
-    DEFAULT_IS_URL: 'https://vector.im',
+var config = require('../../../../../config.json');
 
+module.exports = React.createClass({
     displayName: 'Login',
     mixins: [LoginController],
 
@@ -40,15 +39,15 @@ module.exports = React.createClass({
 
     componentWillMount: function() {
         this.onHSChosen();
-        this.customHsUrl = this.DEFAULT_HS_URL;
-        this.customIsUrl = this.DEFAULT_IS_URL;
+        this.customHsUrl = config.default_hs_url;
+        this.customIsUrl = config.default_is_url;
     },
 
     getHsUrl: function() {
         if (this.state.serverConfigVisible) {
             return this.customHsUrl;
         } else {
-            return this.DEFAULT_HS_URL;
+            return config.default_hs_url;
         }
     },
 
@@ -56,7 +55,7 @@ module.exports = React.createClass({
         if (this.state.serverConfigVisible) {
             return this.customIsUrl;
         } else {
-            return this.DEFAULT_IS_URL;
+            return config.default_is_url;
         }
     },
 

From df39c3a281d5bfdbe2048ba667ac41df28c58d2c Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Fri, 2 Oct 2015 16:44:35 +0100
Subject: [PATCH 28/29] Changes from PR feedback

---
 README.md                                           | 2 +-
 src/skins/vector/views/molecules/EventAsTextTile.js | 2 --
 src/skins/vector/views/molecules/RoomCreate.js      | 4 +---
 3 files changed, 2 insertions(+), 6 deletions(-)

diff --git a/README.md b/README.md
index 2d3dfba3..690e1041 100644
--- a/README.md
+++ b/README.md
@@ -14,7 +14,7 @@ Getting started
 6. Wait a few seconds for the initial build to finish.
 7. Open http://127.0.0.1:8080/ in your browser to see your newly built Vector.
 
-Wiht `npm start`, Any changes you make to the source files will cause a rebuild so
+With `npm start`, any changes you make to the source files will cause a rebuild so
 your changes will show up when you refresh.
 
 For production use, run `npm run build` to build all the necessary files
diff --git a/src/skins/vector/views/molecules/EventAsTextTile.js b/src/skins/vector/views/molecules/EventAsTextTile.js
index 698d2c15..e8beddf2 100644
--- a/src/skins/vector/views/molecules/EventAsTextTile.js
+++ b/src/skins/vector/views/molecules/EventAsTextTile.js
@@ -33,8 +33,6 @@ module.exports = React.createClass({
         var text = TextForEvent.textForEvent(this.props.mxEvent);
         if (text == null || text.length == 0) return null;
 
-        var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
-        var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
         var timestamp = this.props.last ? <MessageTimestamp ts={this.props.mxEvent.getTs()} /> : null;
         var avatar = this.props.mxEvent.sender ? <MemberAvatar member={this.props.mxEvent.sender} /> : null;
         return (
diff --git a/src/skins/vector/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
index cadc0fc0..d66e014d 100644
--- a/src/skins/vector/views/molecules/RoomCreate.js
+++ b/src/skins/vector/views/molecules/RoomCreate.js
@@ -18,11 +18,9 @@ limitations under the License.
 
 var React = require('react');
 
-//var RoomCreateController = require('matrix-react-sdk/lib/controllers/molecules/RoomCreateController')
-
 module.exports = React.createClass({
     displayName: 'RoomCreate',
-    // mixins: [RoomCreateController],
+
     render: function() {
         return (
             <div className="mx_RoomCreate">

From 53c8b9bcf734648df60261d59a4047773669aa8d Mon Sep 17 00:00:00 2001
From: David Baker <dave@matrix.org>
Date: Mon, 5 Oct 2015 10:20:02 +0100
Subject: [PATCH 29/29] no single quotes because windows

---
 package.json | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/package.json b/package.json
index 58e6439f..429e6139 100644
--- a/package.json
+++ b/package.json
@@ -11,14 +11,14 @@
   "style": "bundle.css",
   "scripts": {
     "reskindex": "reskindex vector -h src/skins/vector/header",
-    "build:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css -c uglifycss --no-watch",
+    "build:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css -c uglifycss --no-watch",
     "build:compile": "babel --source-maps -d lib src",
     "build:bundle": "NODE_ENV=production webpack -p lib/vector/index.js vector/bundle.js",
     "build": "npm run build:css && npm run build:compile && npm run build:bundle",
     "start:js": "webpack -w src/vector/index.js vector/bundle.js",
-    "start:skins:css": "catw 'src/skins/vector/css/**/*.css' -o vector/bundle.css",
+    "start:skins:css": "catw \"src/skins/vector/css/**/*.css\" -o vector/bundle.css",
     "//cache": "Note the -c 1 below due to https://code.google.com/p/chromium/issues/detail?id=508270",
-    "start": "parallelshell 'npm run start:js' 'npm run start:skins:css' 'http-server -c 1 vector'",
+    "start": "parallelshell \"npm run start:js\" \"npm run start:skins:css\" \"http-server -c 1 vector\"",
     "clean": "rimraf lib vector/bundle.css vector/bundle.js vector/bundle.js.map",
     "prepublish": "npm run build:css && npm run build:compile"
   },