diff --git a/.gitignore b/.gitignore
index 19177681..13466ce8 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,3 @@
node_modules
-build
-bundle.css
-bundle.js
+vector/bundle.*
+lib
diff --git a/README.md b/README.md
index 59182102..690e1041 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.
+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
+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.
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/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 (
-
- {content.body}
-
- );
- },
-
- 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 @@
-
-
-
-
- Matrix React SDK Custom Example
-
-
-
-
-
-
-
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(
- ,
- 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/examples/vector/README.md
deleted file mode 100644
index ac266277..00000000
--- a/examples/vector/README.md
+++ /dev/null
@@ -1,4 +0,0 @@
-matrix-react-example
-====================
-
-A simple example of how to use the Matrix React SDK
diff --git a/examples/vector/fonts b/examples/vector/fonts
deleted file mode 120000
index 27f04cad..00000000
--- a/examples/vector/fonts
+++ /dev/null
@@ -1 +0,0 @@
-../../skins/base/fonts/
\ No newline at end of file
diff --git a/examples/vector/img b/examples/vector/img
deleted file mode 120000
index 0d3ef0e2..00000000
--- a/examples/vector/img
+++ /dev/null
@@ -1 +0,0 @@
-../../skins/base/img
\ No newline at end of file
diff --git a/examples/vector/package.json b/examples/vector/package.json
deleted file mode 100644
index 230a261b..00000000
--- a/examples/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\""
- }
-}
diff --git a/package.json b/package.json
index 5f99bd51..429e6139 100644
--- a/package.json
+++ b/package.json
@@ -1,40 +1,48 @@
{
- "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",
"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 vector -h src/skins/vector/header",
+ "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",
+ "//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"
},
"dependencies": {
"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",
+ "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",
+ "babel-core": "^5.8.25",
+ "babel-loader": "^5.3.2",
"catw": "^1.0.1",
+ "http-server": "^0.8.4",
+ "json-loader": "^0.5.3",
"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/src/Avatar.js b/src/Avatar.js
index bdfc20ca..2f83ebd9 100644
--- a/src/Avatar.js
+++ b/src/Avatar.js
@@ -16,14 +16,17 @@ 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) {
var url = MatrixClientPeg.get().getAvatarUrlForMember(
- member, width, height, resizeMethod, false
+ member,
+ width,
+ height,
+ resizeMethod
);
- if (url === null) {
+ if (!url) {
url = this.defaultAvatarUrlForString(member.userId);
}
return url;
@@ -37,13 +40,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/CallHandler.js b/src/CallHandler.js
deleted file mode 100644
index 025ece38..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:
- * }
- *
- * 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:
- * }
- *
- * {
- * action: 'incoming_call'
- * call: MatrixCall
- * }
- *
- * {
- * action: 'hangup'
- * room_id:
- * }
- *
- * {
- * action: 'answer'
- * room_id:
- * }
- */
-
-var MatrixClientPeg = require("./MatrixClientPeg");
-var Modal = require("./Modal");
-var ComponentBroker = require('./ComponentBroker');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-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");
- 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;
- }
-};
\ No newline at end of file
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/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/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 = (
-
-
-
-
-
-
- );
-
- 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 ");
- },
-
- 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 ");
- },
-
- // Change the room topic
- topic: function(room_id, args) {
- if (args) {
- return success(
- MatrixClientPeg.get().setRoomTopic(room_id, args)
- );
- }
- return reject("Usage: /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 ");
- },
-
- // 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 ");
- },
-
- 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 []");
- },
-
- // 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 []");
- },
-
- // 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 ");
- },
-
- // 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 []");
- },
-
- // 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 ");
- }
-};
-
-// 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/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= 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/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/CallView.js b/src/controllers/molecules/voip/CallView.js
index a20e4463..d511b9d4 100644
--- a/src/controllers/molecules/voip/CallView.js
+++ b/src/controllers/molecules/voip/CallView.js
@@ -15,9 +15,11 @@ limitations under the License.
*/
'use strict';
-var dis = require("../../../dispatcher");
-var CallHandler = require("../../../CallHandler");
-var MatrixClientPeg = require("../../../MatrixClientPeg");
+var dis = require("matrix-react-sdk/lib/dispatcher");
+var CallHandler = require("matrix-react-sdk/lib/CallHandler");
+var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
+
+var VectorConferenceHandler = require('../../../modules/VectorConferenceHandler');
/*
* State vars:
@@ -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/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 3fb613e0..00000000
--- a/src/controllers/organisms/MemberList.js
+++ /dev/null
@@ -1,184 +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;
-
- // Lazy-load in more than the first N members
- 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) {
- // XXX: evil hack to track the age of this presence info.
- // this should be removed once syjs-28 is resolved in the JS SDK itself.
- user.lastPresenceTs = Date.now();
-
- var tile = self.refs[user.userId];
-
- console.log("presence event " + JSON.stringify(event) + " user = " + user + " tile = " + tile);
-
- if (tile) {
- self._updateList(); // reorder the membership list
- self.forceUpdate(); // FIXME: is the a more efficient way of reordering with react?
- // XXX: do we even need to do this, or is it done by the main list?
- tile.forceUpdate();
- }
- }
- // FIXME: we should probably also reset 'lastActiveAgo' to zero whenever
- // we see a typing notif from a user, as we don't get presence updates for those.
- 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);
-
- // XXX: evil hack until SYJS-28 is fixed
- all_user_ids.map(function(userId) {
- if (all_members[userId].user && !all_members[userId].user.lastPresenceTs) {
- all_members[userId].user.lastPresenceTs = Date.now();
- }
- });
-
- all_user_ids.sort(function(userIdA, userIdB) {
- var userA = all_members[userIdA].user;
- var userB = all_members[userIdB].user;
-
- var latA = userA ? (userA.lastPresenceTs - (userA.lastActiveAgo || userA.lastPresenceTs)) : 0;
- var latB = userB ? (userB.lastPresenceTs - (userB.lastActiveAgo || userB.lastPresenceTs)) : 0;
-
- return latB - latA;
- });
-
- 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') {
- // XXX: this is evil, and relies on the fact that Object.keys() iterates
- // over the keys of a dict in insertion order (if those keys are strings)
- 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
index 3933f53e..2602315a 100644
--- a/src/controllers/organisms/RoomList.js
+++ b/src/controllers/organisms/RoomList.js
@@ -17,15 +17,13 @@ limitations under the License.
'use strict';
var React = require("react");
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var RoomListSorter = require("../../RoomListSorter");
-var dis = require("../../dispatcher");
+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 ComponentBroker = require('../../ComponentBroker');
-var ConferenceHandler = require("../../ConferenceHandler");
-var CallHandler = require("../../CallHandler");
-
-var RoomTile = ComponentBroker.get("molecules/RoomTile");
+var sdk = require('matrix-react-sdk');
+var VectorConferenceHandler = require("../../modules/VectorConferenceHandler");
+var CallHandler = require("matrix-react-sdk/lib/CallHandler");
var HIDE_CONFERENCE_CHANS = true;
@@ -129,7 +127,7 @@ module.exports = {
var otherMember = joinedMembers.filter(function(m) {
return m.userId !== me.userId
})[0];
- if (ConferenceHandler.isConferenceUser(otherMember)) {
+ if (VectorConferenceHandler.isConferenceUser(otherMember)) {
// console.log("Hiding conference 1:1 room %s", room.roomId);
shouldShowRoom = false;
}
@@ -154,6 +152,7 @@ module.exports = {
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 (
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 = ;
- continuation = false;
- }
- }
- if (!TileType) continue;
- ret.unshift(
- // XXX: don't wrap everything in a needless li - make the TileType a li if we must :(
-
- );
- 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/src/ConferenceHandler.js b/src/modules/VectorConferenceHandler.js
similarity index 71%
rename from src/ConferenceHandler.js
rename to src/modules/VectorConferenceHandler.js
index c617672e..637e34f9 100644
--- a/src/ConferenceHandler.js
+++ b/src/modules/VectorConferenceHandler.js
@@ -1,7 +1,25 @@
+/*
+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;
+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.
@@ -90,5 +108,27 @@ module.exports.getConferenceUserIdForRoom = function(roomId) {
return "@" + USER_PREFIX + base64RoomId + ":" + DOMAIN;
};
+module.exports.createNewMatrixCall = function(client, roomId) {
+ 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;
+module.exports.slot = 'conference';
diff --git a/skins/base/css/atoms/MemberAvatar.css b/src/skins/vector/css/atoms/MemberAvatar.css
similarity index 100%
rename from skins/base/css/atoms/MemberAvatar.css
rename to src/skins/vector/css/atoms/MemberAvatar.css
diff --git a/skins/base/css/atoms/MessageTimestamp.css b/src/skins/vector/css/atoms/MessageTimestamp.css
similarity index 100%
rename from skins/base/css/atoms/MessageTimestamp.css
rename to src/skins/vector/css/atoms/MessageTimestamp.css
diff --git a/skins/base/css/common.css b/src/skins/vector/css/common.css
similarity index 100%
rename from skins/base/css/common.css
rename to src/skins/vector/css/common.css
diff --git a/skins/base/css/hide.css b/src/skins/vector/css/hide.css
similarity index 100%
rename from skins/base/css/hide.css
rename to src/skins/vector/css/hide.css
diff --git a/skins/base/css/molecules/MImageTile.css b/src/skins/vector/css/molecules/MImageTile.css
similarity index 100%
rename from skins/base/css/molecules/MImageTile.css
rename to src/skins/vector/css/molecules/MImageTile.css
diff --git a/skins/base/css/molecules/MNoticeTile.css b/src/skins/vector/css/molecules/MNoticeTile.css
similarity index 100%
rename from skins/base/css/molecules/MNoticeTile.css
rename to src/skins/vector/css/molecules/MNoticeTile.css
diff --git a/skins/base/css/molecules/MTextTile.css b/src/skins/vector/css/molecules/MTextTile.css
similarity index 100%
rename from skins/base/css/molecules/MTextTile.css
rename to src/skins/vector/css/molecules/MTextTile.css
diff --git a/skins/base/css/molecules/MatrixToolbar.css b/src/skins/vector/css/molecules/MatrixToolbar.css
similarity index 100%
rename from skins/base/css/molecules/MatrixToolbar.css
rename to src/skins/vector/css/molecules/MatrixToolbar.css
diff --git a/skins/base/css/molecules/MemberInfo.css b/src/skins/vector/css/molecules/MemberInfo.css
similarity index 100%
rename from skins/base/css/molecules/MemberInfo.css
rename to src/skins/vector/css/molecules/MemberInfo.css
diff --git a/skins/base/css/molecules/MemberTile.css b/src/skins/vector/css/molecules/MemberTile.css
similarity index 100%
rename from skins/base/css/molecules/MemberTile.css
rename to src/skins/vector/css/molecules/MemberTile.css
diff --git a/skins/base/css/molecules/MessageComposer.css b/src/skins/vector/css/molecules/MessageComposer.css
similarity index 100%
rename from skins/base/css/molecules/MessageComposer.css
rename to src/skins/vector/css/molecules/MessageComposer.css
diff --git a/skins/base/css/molecules/MessageTile.css b/src/skins/vector/css/molecules/MessageTile.css
similarity index 100%
rename from skins/base/css/molecules/MessageTile.css
rename to src/skins/vector/css/molecules/MessageTile.css
diff --git a/skins/base/css/molecules/ProgressBar.css b/src/skins/vector/css/molecules/ProgressBar.css
similarity index 100%
rename from skins/base/css/molecules/ProgressBar.css
rename to src/skins/vector/css/molecules/ProgressBar.css
diff --git a/skins/base/css/molecules/RoomDropTarget.css b/src/skins/vector/css/molecules/RoomDropTarget.css
similarity index 100%
rename from skins/base/css/molecules/RoomDropTarget.css
rename to src/skins/vector/css/molecules/RoomDropTarget.css
diff --git a/skins/base/css/molecules/RoomHeader.css b/src/skins/vector/css/molecules/RoomHeader.css
similarity index 100%
rename from skins/base/css/molecules/RoomHeader.css
rename to src/skins/vector/css/molecules/RoomHeader.css
diff --git a/skins/base/css/molecules/RoomSettings.css b/src/skins/vector/css/molecules/RoomSettings.css
similarity index 100%
rename from skins/base/css/molecules/RoomSettings.css
rename to src/skins/vector/css/molecules/RoomSettings.css
diff --git a/skins/base/css/molecules/RoomTile.css b/src/skins/vector/css/molecules/RoomTile.css
similarity index 100%
rename from skins/base/css/molecules/RoomTile.css
rename to src/skins/vector/css/molecules/RoomTile.css
diff --git a/skins/base/css/molecules/SenderProfile.css b/src/skins/vector/css/molecules/SenderProfile.css
similarity index 100%
rename from skins/base/css/molecules/SenderProfile.css
rename to src/skins/vector/css/molecules/SenderProfile.css
diff --git a/skins/base/css/molecules/ServerConfig.css b/src/skins/vector/css/molecules/ServerConfig.css
similarity index 100%
rename from skins/base/css/molecules/ServerConfig.css
rename to src/skins/vector/css/molecules/ServerConfig.css
diff --git a/skins/base/css/molecules/voip/CallView.css b/src/skins/vector/css/molecules/voip/CallView.css
similarity index 100%
rename from skins/base/css/molecules/voip/CallView.css
rename to src/skins/vector/css/molecules/voip/CallView.css
diff --git a/skins/base/css/molecules/voip/IncomingCallbox.css b/src/skins/vector/css/molecules/voip/IncomingCallbox.css
similarity index 100%
rename from skins/base/css/molecules/voip/IncomingCallbox.css
rename to src/skins/vector/css/molecules/voip/IncomingCallbox.css
diff --git a/skins/base/css/molecules/voip/VideoView.css b/src/skins/vector/css/molecules/voip/VideoView.css
similarity index 100%
rename from skins/base/css/molecules/voip/VideoView.css
rename to src/skins/vector/css/molecules/voip/VideoView.css
diff --git a/skins/base/css/organisms/CreateRoom.css b/src/skins/vector/css/organisms/CreateRoom.css
similarity index 100%
rename from skins/base/css/organisms/CreateRoom.css
rename to src/skins/vector/css/organisms/CreateRoom.css
diff --git a/skins/base/css/organisms/LeftPanel.css b/src/skins/vector/css/organisms/LeftPanel.css
similarity index 100%
rename from skins/base/css/organisms/LeftPanel.css
rename to src/skins/vector/css/organisms/LeftPanel.css
diff --git a/skins/base/css/organisms/MemberList.css b/src/skins/vector/css/organisms/MemberList.css
similarity index 100%
rename from skins/base/css/organisms/MemberList.css
rename to src/skins/vector/css/organisms/MemberList.css
diff --git a/skins/base/css/organisms/RightPanel.css b/src/skins/vector/css/organisms/RightPanel.css
similarity index 100%
rename from skins/base/css/organisms/RightPanel.css
rename to src/skins/vector/css/organisms/RightPanel.css
diff --git a/skins/base/css/organisms/RoomDirectory.css b/src/skins/vector/css/organisms/RoomDirectory.css
similarity index 100%
rename from skins/base/css/organisms/RoomDirectory.css
rename to src/skins/vector/css/organisms/RoomDirectory.css
diff --git a/skins/base/css/organisms/RoomList.css b/src/skins/vector/css/organisms/RoomList.css
similarity index 100%
rename from skins/base/css/organisms/RoomList.css
rename to src/skins/vector/css/organisms/RoomList.css
diff --git a/skins/base/css/organisms/RoomView.css b/src/skins/vector/css/organisms/RoomView.css
similarity index 100%
rename from skins/base/css/organisms/RoomView.css
rename to src/skins/vector/css/organisms/RoomView.css
diff --git a/skins/base/css/organisms/UserSettings.css b/src/skins/vector/css/organisms/UserSettings.css
similarity index 100%
rename from skins/base/css/organisms/UserSettings.css
rename to src/skins/vector/css/organisms/UserSettings.css
diff --git a/skins/base/css/pages/MatrixChat.css b/src/skins/vector/css/pages/MatrixChat.css
similarity index 100%
rename from skins/base/css/pages/MatrixChat.css
rename to src/skins/vector/css/pages/MatrixChat.css
diff --git a/skins/base/css/templates/Login.css b/src/skins/vector/css/templates/Login.css
similarity index 100%
rename from skins/base/css/templates/Login.css
rename to src/skins/vector/css/templates/Login.css
diff --git a/skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/vector/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from skins/base/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/vector/fonts/22JRxvfANxSmnAhzbFH8PgLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2 b/src/skins/vector/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
similarity index 100%
rename from skins/base/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
rename to src/skins/vector/fonts/8qcEw_nrk_5HEcCpYdJu8BTbgVql8nDJpwnrE27mub0.woff2
diff --git a/skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/vector/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from skins/base/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/vector/fonts/IY9HZVvI1cMoAHxvl0w9LVKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/skins/base/fonts/Lato.css b/src/skins/vector/fonts/Lato.css
similarity index 100%
rename from skins/base/fonts/Lato.css
rename to src/skins/vector/fonts/Lato.css
diff --git a/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 skins/base/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
rename to src/skins/vector/fonts/MDadn8DQ_3oT6kvnUq_2r_esZW2xOQ-xsNqO47m55DA.woff2
diff --git a/skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2 b/src/skins/vector/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
similarity index 100%
rename from skins/base/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
rename to src/skins/vector/fonts/MgNNr5y1C_tIEuLEmicLmwLUuEpTyoUstqEm5AMlJo4.woff2
diff --git a/skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2 b/src/skins/vector/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
similarity index 100%
rename from skins/base/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
rename to src/skins/vector/fonts/rZPI2gHXi8zxUjnybc2ZQFKPGs1ZzpMvnHX-7fPOuAc.woff2
diff --git a/src/controllers/molecules/UnknownMessageTile.js b/src/skins/vector/header
similarity index 93%
rename from src/controllers/molecules/UnknownMessageTile.js
rename to src/skins/vector/header
index d0977e00..fd88ee27 100644
--- a/src/controllers/molecules/UnknownMessageTile.js
+++ b/src/skins/vector/header
@@ -13,8 +13,3 @@ 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/skins/base/img/attach.png b/src/skins/vector/img/attach.png
similarity index 100%
rename from skins/base/img/attach.png
rename to src/skins/vector/img/attach.png
diff --git a/skins/base/img/chevron-left.png b/src/skins/vector/img/chevron-left.png
similarity index 100%
rename from skins/base/img/chevron-left.png
rename to src/skins/vector/img/chevron-left.png
diff --git a/skins/base/img/chevron-right.png b/src/skins/vector/img/chevron-right.png
similarity index 100%
rename from skins/base/img/chevron-right.png
rename to src/skins/vector/img/chevron-right.png
diff --git a/skins/base/img/chevron.png b/src/skins/vector/img/chevron.png
similarity index 100%
rename from skins/base/img/chevron.png
rename to src/skins/vector/img/chevron.png
diff --git a/skins/base/img/close-white.png b/src/skins/vector/img/close-white.png
similarity index 100%
rename from skins/base/img/close-white.png
rename to src/skins/vector/img/close-white.png
diff --git a/skins/base/img/create-big.png b/src/skins/vector/img/create-big.png
similarity index 100%
rename from skins/base/img/create-big.png
rename to src/skins/vector/img/create-big.png
diff --git a/skins/base/img/create.png b/src/skins/vector/img/create.png
similarity index 100%
rename from skins/base/img/create.png
rename to src/skins/vector/img/create.png
diff --git a/skins/base/img/delete.png b/src/skins/vector/img/delete.png
similarity index 100%
rename from skins/base/img/delete.png
rename to src/skins/vector/img/delete.png
diff --git a/skins/base/img/directory-big.png b/src/skins/vector/img/directory-big.png
similarity index 100%
rename from skins/base/img/directory-big.png
rename to src/skins/vector/img/directory-big.png
diff --git a/skins/base/img/download.png b/src/skins/vector/img/download.png
similarity index 100%
rename from skins/base/img/download.png
rename to src/skins/vector/img/download.png
diff --git a/skins/base/img/edit.png b/src/skins/vector/img/edit.png
similarity index 100%
rename from skins/base/img/edit.png
rename to src/skins/vector/img/edit.png
diff --git a/skins/base/img/file.png b/src/skins/vector/img/file.png
similarity index 100%
rename from skins/base/img/file.png
rename to src/skins/vector/img/file.png
diff --git a/skins/base/img/filegrid.png b/src/skins/vector/img/filegrid.png
similarity index 100%
rename from skins/base/img/filegrid.png
rename to src/skins/vector/img/filegrid.png
diff --git a/skins/base/img/filelist.png b/src/skins/vector/img/filelist.png
similarity index 100%
rename from skins/base/img/filelist.png
rename to src/skins/vector/img/filelist.png
diff --git a/skins/base/img/hide.png b/src/skins/vector/img/hide.png
similarity index 100%
rename from skins/base/img/hide.png
rename to src/skins/vector/img/hide.png
diff --git a/skins/base/img/info.png b/src/skins/vector/img/info.png
similarity index 100%
rename from skins/base/img/info.png
rename to src/skins/vector/img/info.png
diff --git a/skins/base/img/logo.png b/src/skins/vector/img/logo.png
similarity index 100%
rename from skins/base/img/logo.png
rename to src/skins/vector/img/logo.png
diff --git a/skins/base/img/members.png b/src/skins/vector/img/members.png
similarity index 100%
rename from skins/base/img/members.png
rename to src/skins/vector/img/members.png
diff --git a/skins/base/img/menu.png b/src/skins/vector/img/menu.png
similarity index 100%
rename from skins/base/img/menu.png
rename to src/skins/vector/img/menu.png
diff --git a/skins/base/img/newmessages.png b/src/skins/vector/img/newmessages.png
similarity index 100%
rename from skins/base/img/newmessages.png
rename to src/skins/vector/img/newmessages.png
diff --git a/skins/base/img/p/p0.png b/src/skins/vector/img/p/p0.png
similarity index 100%
rename from skins/base/img/p/p0.png
rename to src/skins/vector/img/p/p0.png
diff --git a/skins/base/img/p/p1.png b/src/skins/vector/img/p/p1.png
similarity index 100%
rename from skins/base/img/p/p1.png
rename to src/skins/vector/img/p/p1.png
diff --git a/skins/base/img/p/p10.png b/src/skins/vector/img/p/p10.png
similarity index 100%
rename from skins/base/img/p/p10.png
rename to src/skins/vector/img/p/p10.png
diff --git a/skins/base/img/p/p11.png b/src/skins/vector/img/p/p11.png
similarity index 100%
rename from skins/base/img/p/p11.png
rename to src/skins/vector/img/p/p11.png
diff --git a/skins/base/img/p/p12.png b/src/skins/vector/img/p/p12.png
similarity index 100%
rename from skins/base/img/p/p12.png
rename to src/skins/vector/img/p/p12.png
diff --git a/skins/base/img/p/p13.png b/src/skins/vector/img/p/p13.png
similarity index 100%
rename from skins/base/img/p/p13.png
rename to src/skins/vector/img/p/p13.png
diff --git a/skins/base/img/p/p14.png b/src/skins/vector/img/p/p14.png
similarity index 100%
rename from skins/base/img/p/p14.png
rename to src/skins/vector/img/p/p14.png
diff --git a/skins/base/img/p/p15.png b/src/skins/vector/img/p/p15.png
similarity index 100%
rename from skins/base/img/p/p15.png
rename to src/skins/vector/img/p/p15.png
diff --git a/skins/base/img/p/p16.png b/src/skins/vector/img/p/p16.png
similarity index 100%
rename from skins/base/img/p/p16.png
rename to src/skins/vector/img/p/p16.png
diff --git a/skins/base/img/p/p17.png b/src/skins/vector/img/p/p17.png
similarity index 100%
rename from skins/base/img/p/p17.png
rename to src/skins/vector/img/p/p17.png
diff --git a/skins/base/img/p/p18.png b/src/skins/vector/img/p/p18.png
similarity index 100%
rename from skins/base/img/p/p18.png
rename to src/skins/vector/img/p/p18.png
diff --git a/skins/base/img/p/p19.png b/src/skins/vector/img/p/p19.png
similarity index 100%
rename from skins/base/img/p/p19.png
rename to src/skins/vector/img/p/p19.png
diff --git a/skins/base/img/p/p2.png b/src/skins/vector/img/p/p2.png
similarity index 100%
rename from skins/base/img/p/p2.png
rename to src/skins/vector/img/p/p2.png
diff --git a/skins/base/img/p/p20.png b/src/skins/vector/img/p/p20.png
similarity index 100%
rename from skins/base/img/p/p20.png
rename to src/skins/vector/img/p/p20.png
diff --git a/skins/base/img/p/p3.png b/src/skins/vector/img/p/p3.png
similarity index 100%
rename from skins/base/img/p/p3.png
rename to src/skins/vector/img/p/p3.png
diff --git a/skins/base/img/p/p4.png b/src/skins/vector/img/p/p4.png
similarity index 100%
rename from skins/base/img/p/p4.png
rename to src/skins/vector/img/p/p4.png
diff --git a/skins/base/img/p/p5.png b/src/skins/vector/img/p/p5.png
similarity index 100%
rename from skins/base/img/p/p5.png
rename to src/skins/vector/img/p/p5.png
diff --git a/skins/base/img/p/p6.png b/src/skins/vector/img/p/p6.png
similarity index 100%
rename from skins/base/img/p/p6.png
rename to src/skins/vector/img/p/p6.png
diff --git a/skins/base/img/p/p7.png b/src/skins/vector/img/p/p7.png
similarity index 100%
rename from skins/base/img/p/p7.png
rename to src/skins/vector/img/p/p7.png
diff --git a/skins/base/img/p/p8.png b/src/skins/vector/img/p/p8.png
similarity index 100%
rename from skins/base/img/p/p8.png
rename to src/skins/vector/img/p/p8.png
diff --git a/skins/base/img/p/p9.png b/src/skins/vector/img/p/p9.png
similarity index 100%
rename from skins/base/img/p/p9.png
rename to src/skins/vector/img/p/p9.png
diff --git a/skins/base/img/p/piechart.pde b/src/skins/vector/img/p/piechart.pde
similarity index 100%
rename from skins/base/img/p/piechart.pde
rename to src/skins/vector/img/p/piechart.pde
diff --git a/skins/base/img/placeholder.png b/src/skins/vector/img/placeholder.png
similarity index 100%
rename from skins/base/img/placeholder.png
rename to src/skins/vector/img/placeholder.png
diff --git a/skins/base/img/search.png b/src/skins/vector/img/search.png
similarity index 100%
rename from skins/base/img/search.png
rename to src/skins/vector/img/search.png
diff --git a/skins/base/img/settings-big.png b/src/skins/vector/img/settings-big.png
similarity index 100%
rename from skins/base/img/settings-big.png
rename to src/skins/vector/img/settings-big.png
diff --git a/skins/base/img/settings.png b/src/skins/vector/img/settings.png
similarity index 100%
rename from skins/base/img/settings.png
rename to src/skins/vector/img/settings.png
diff --git a/skins/base/img/typing.png b/src/skins/vector/img/typing.png
similarity index 100%
rename from skins/base/img/typing.png
rename to src/skins/vector/img/typing.png
diff --git a/skins/base/img/upload-big.png b/src/skins/vector/img/upload-big.png
similarity index 100%
rename from skins/base/img/upload-big.png
rename to src/skins/vector/img/upload-big.png
diff --git a/skins/base/img/upload.png b/src/skins/vector/img/upload.png
similarity index 100%
rename from skins/base/img/upload.png
rename to src/skins/vector/img/upload.png
diff --git a/skins/base/img/video.png b/src/skins/vector/img/video.png
similarity index 100%
rename from skins/base/img/video.png
rename to src/skins/vector/img/video.png
diff --git a/skins/base/img/voip.png b/src/skins/vector/img/voip.png
similarity index 100%
rename from skins/base/img/voip.png
rename to src/skins/vector/img/voip.png
diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js
new file mode 100644
index 00000000..4f76ad62
--- /dev/null
+++ b/src/skins/vector/skindex.js
@@ -0,0 +1,82 @@
+/*
+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 = {};
+
+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/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/skins/base/views/atoms/EditableText.js b/src/skins/vector/views/atoms/EditableText.js
similarity index 95%
rename from skins/base/views/atoms/EditableText.js
rename to src/skins/vector/views/atoms/EditableText.js
index d4aa2857..1848b029 100644
--- a/skins/base/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/skins/base/views/atoms/EnableNotificationsButton.js b/src/skins/vector/views/atoms/EnableNotificationsButton.js
similarity index 90%
rename from skins/base/views/atoms/EnableNotificationsButton.js
rename to src/skins/vector/views/atoms/EnableNotificationsButton.js
index 7caebb76..edef9edc 100644
--- a/skins/base/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/skins/base/views/atoms/ImageView.js b/src/skins/vector/views/atoms/ImageView.js
similarity index 96%
rename from skins/base/views/atoms/ImageView.js
rename to src/skins/vector/views/atoms/ImageView.js
index 196e92fe..a0d69bcc 100644
--- a/skins/base/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('../../../../controllers/atoms/ImageView')
module.exports = React.createClass({
displayName: 'ImageView',
diff --git a/skins/base/views/atoms/LogoutButton.js b/src/skins/vector/views/atoms/LogoutButton.js
similarity index 90%
rename from skins/base/views/atoms/LogoutButton.js
rename to src/skins/vector/views/atoms/LogoutButton.js
index 8cc5b27d..619160f6 100644
--- a/skins/base/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/skins/base/views/atoms/MemberAvatar.js b/src/skins/vector/views/atoms/MemberAvatar.js
similarity index 64%
rename from skins/base/views/atoms/MemberAvatar.js
rename to src/skins/vector/views/atoms/MemberAvatar.js
index dccf0852..69652e1a 100644
--- a/skins/base/views/atoms/MemberAvatar.js
+++ b/src/skins/vector/views/atoms/MemberAvatar.js
@@ -17,13 +17,28 @@ limitations under the License.
'use strict';
var React = require('react');
+var Avatar = require('../../../../Avatar');
-var MemberAvatarController = require("../../../../src/controllers/atoms/MemberAvatar");
+var MemberAvatarController = require('matrix-react-sdk/lib/controllers/atoms/MemberAvatar')
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 (
: null;
var text = this.getMemberEventText();
if (!text) return ;
+ var MessageTimestamp = sdk.getComponent('atoms.MessageTimestamp');
+ var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
return (
diff --git a/skins/base/views/molecules/MTextTile.js b/src/skins/vector/views/molecules/MTextTile.js
similarity index 91%
rename from skins/base/views/molecules/MTextTile.js
rename to src/skins/vector/views/molecules/MTextTile.js
index d08f42ed..50555f94 100644
--- a/skins/base/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/skins/base/views/molecules/MatrixToolbar.js b/src/skins/vector/views/molecules/MatrixToolbar.js
similarity index 76%
rename from skins/base/views/molecules/MatrixToolbar.js
rename to src/skins/vector/views/molecules/MatrixToolbar.js
index f72304e1..0b6c58e0 100644
--- a/skins/base/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 sdk = require('matrix-react-sdk')
-var LogoutButton = ComponentBroker.get("atoms/LogoutButton");
-var EnableNotificationsButton = ComponentBroker.get("atoms/EnableNotificationsButton");
-
-var MatrixToolbarController = require("../../../../src/controllers/molecules/MatrixToolbar");
-var Notifier = ComponentBroker.get('organisms/Notifier');
+var MatrixToolbarController = require('matrix-react-sdk/lib/controllers/molecules/MatrixToolbar')
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 (
You are not receiving desktop notifications.
diff --git a/skins/base/views/molecules/MemberInfo.js b/src/skins/vector/views/molecules/MemberInfo.js
similarity index 88%
rename from skins/base/views/molecules/MemberInfo.js
rename to src/skins/vector/views/molecules/MemberInfo.js
index b57a5b6f..cc9a8f2d 100644
--- a/skins/base/views/molecules/MemberInfo.js
+++ b/src/skins/vector/views/molecules/MemberInfo.js
@@ -18,10 +18,8 @@ limitations under the License.
var React = require('react');
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var MemberInfoController = require("../../../../src/controllers/molecules/MemberInfo");
-var ComponentBroker = require('../../../../src/ComponentBroker');
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var MemberInfoController = require('matrix-react-sdk/lib/controllers/molecules/MemberInfo')
module.exports = React.createClass({
displayName: 'MemberInfo',
diff --git a/skins/base/views/molecules/MemberTile.js b/src/skins/vector/views/molecules/MemberTile.js
similarity index 91%
rename from skins/base/views/molecules/MemberTile.js
rename to src/skins/vector/views/molecules/MemberTile.js
index d65cd0ed..991616d5 100644
--- a/skins/base/views/molecules/MemberTile.js
+++ b/src/skins/vector/views/molecules/MemberTile.js
@@ -18,14 +18,10 @@ limitations under the License.
var React = require('react');
-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 MemberInfo = ComponentBroker.get('molecules/MemberInfo');
-var ErrorDialog = ComponentBroker.get("organisms/ErrorDialog");
-var MemberAvatar = ComponentBroker.get('atoms/MemberAvatar');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var sdk = require('matrix-react-sdk')
+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.
// Revert to Arial when this happens, which on OSX works at least.
@@ -46,6 +42,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 +150,7 @@ module.exports = React.createClass({
}
+ var MemberAvatar = sdk.getComponent('atoms.MemberAvatar');
return (
diff --git a/skins/base/views/molecules/MessageComposer.js b/src/skins/vector/views/molecules/MessageComposer.js
similarity index 86%
rename from skins/base/views/molecules/MessageComposer.js
rename to src/skins/vector/views/molecules/MessageComposer.js
index a8d8a4eb..c94cade5 100644
--- a/skins/base/views/molecules/MessageComposer.js
+++ b/src/skins/vector/views/molecules/MessageComposer.js
@@ -18,12 +18,10 @@ limitations under the License.
var React = require('react');
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var MessageComposerController = require("../../../../src/controllers/molecules/MessageComposer");
-var ContentMessages = require("../../../../src/ContentMessages");
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var MessageComposerController = require('matrix-react-sdk/lib/controllers/molecules/MessageComposer')
-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 +43,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 (
diff --git a/skins/base/views/molecules/MessageTile.js b/src/skins/vector/views/molecules/MessageTile.js
similarity index 76%
rename from skins/base/views/molecules/MessageTile.js
rename to src/skins/vector/views/molecules/MessageTile.js
index ac6342ac..386b19d3 100644
--- a/skins/base/views/molecules/MessageTile.js
+++ b/src/skins/vector/views/molecules/MessageTile.js
@@ -20,30 +20,29 @@ var React = require('react');
var classNames = require("classnames");
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var sdk = require('matrix-react-sdk')
-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 MessageTileController = require("../../../../src/controllers/molecules/MessageTile");
+var MessageTileController = require('matrix-react-sdk/lib/controllers/molecules/MessageTile')
module.exports = React.createClass({
displayName: 'MessageTile',
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/skins/base/views/molecules/ProgressBar.js b/src/skins/vector/views/molecules/ProgressBar.js
similarity index 92%
rename from skins/base/views/molecules/ProgressBar.js
rename to src/skins/vector/views/molecules/ProgressBar.js
index 0946ffcc..18d1440a 100644
--- a/skins/base/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/skins/base/views/molecules/RoomCreate.js b/src/skins/vector/views/molecules/RoomCreate.js
similarity index 83%
rename from skins/base/views/molecules/RoomCreate.js
rename to src/skins/vector/views/molecules/RoomCreate.js
index 9ad4f428..d66e014d 100644
--- a/skins/base/views/molecules/RoomCreate.js
+++ b/src/skins/vector/views/molecules/RoomCreate.js
@@ -17,15 +17,10 @@ limitations under the License.
'use strict';
var React = require('react');
-var classNames = require('classnames');
-
-//var RoomCreateController = require("../../../../src/controllers/molecules/RoomCreateController");
-
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
module.exports = React.createClass({
displayName: 'RoomCreate',
- // mixins: [RoomCreateController],
+
render: function() {
return (
diff --git a/skins/base/views/molecules/RoomDropTarget.js b/src/skins/vector/views/molecules/RoomDropTarget.js
similarity index 80%
rename from skins/base/views/molecules/RoomDropTarget.js
rename to src/skins/vector/views/molecules/RoomDropTarget.js
index 0a076949..b1e15077 100644
--- a/skins/base/views/molecules/RoomDropTarget.js
+++ b/src/skins/vector/views/molecules/RoomDropTarget.js
@@ -17,11 +17,8 @@ limitations under the License.
'use strict';
var React = require('react');
-var classNames = require('classnames');
-//var RoomDropTargetController = require("../../../../src/controllers/molecules/RoomDropTargetController");
-
-var MatrixClientPeg = require("../../../../src/MatrixClientPeg");
+//var RoomDropTargetController = require('matrix-react-sdk/lib/controllers/molecules/RoomDropTargetController')
module.exports = React.createClass({
displayName: 'RoomDropTarget',
diff --git a/skins/base/views/molecules/RoomHeader.js b/src/skins/vector/views/molecules/RoomHeader.js
similarity index 94%
rename from skins/base/views/molecules/RoomHeader.js
rename to src/skins/vector/views/molecules/RoomHeader.js
index e3003b88..f7d3fe7e 100644
--- a/skins/base/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("../../../../src/controllers/molecules/RoomHeader");
-var EditableText = ComponentBroker.get("atoms/EditableText");
-var RoomAvatar = ComponentBroker.get('atoms/RoomAvatar');
+var MatrixClientPeg = require('matrix-react-sdk/lib/MatrixClientPeg');
+var RoomHeaderController = require('matrix-react-sdk/lib/controllers/molecules/RoomHeader')
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/skins/base/views/molecules/RoomSettings.js b/src/skins/vector/views/molecules/RoomSettings.js
similarity index 98%
rename from skins/base/views/molecules/RoomSettings.js
rename to src/skins/vector/views/molecules/RoomSettings.js
index 7f48df20..d6d36a13 100644
--- a/skins/base/views/molecules/RoomSettings.js
+++ b/src/skins/vector/views/molecules/RoomSettings.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 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/skins/base/views/molecules/RoomTile.js b/src/skins/vector/views/molecules/RoomTile.js
similarity index 89%
rename from skins/base/views/molecules/RoomTile.js
rename to src/skins/vector/views/molecules/RoomTile.js
index b8e41fb8..61fa0021 100644
--- a/skins/base/views/molecules/RoomTile.js
+++ b/src/skins/vector/views/molecules/RoomTile.js
@@ -19,12 +19,11 @@ 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");
+var MatrixClientPeg = require('matrix-react-sdk/lib/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 =
{name}
;
}
*/
+ var RoomAvatar = sdk.getComponent('atoms.RoomAvatar');
return (
diff --git a/skins/base/views/molecules/SenderProfile.js b/src/skins/vector/views/molecules/SenderProfile.js
similarity index 94%
rename from skins/base/views/molecules/SenderProfile.js
rename to src/skins/vector/views/molecules/SenderProfile.js
index f13b29cf..8be3adf2 100644
--- a/skins/base/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/skins/base/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
similarity index 88%
rename from skins/base/views/molecules/ServerConfig.js
rename to src/skins/vector/views/molecules/ServerConfig.js
index 56241a2a..e48487ae 100644
--- a/skins/base/views/molecules/ServerConfig.js
+++ b/src/skins/vector/views/molecules/ServerConfig.js
@@ -17,18 +17,17 @@ limitations under the License.
'use strict';
var React = require('react');
-var Modal = require('../../../../src/Modal');
-var ComponentBroker = require('../../../../src/ComponentBroker');
+var Modal = require('matrix-react-sdk/lib/Modal');
+var sdk = require('matrix-react-sdk')
-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',
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/skins/base/views/molecules/UnknownMessageTile.js b/src/skins/vector/views/molecules/UnknownMessageTile.js
similarity index 89%
rename from skins/base/views/molecules/UnknownMessageTile.js
rename to src/skins/vector/views/molecules/UnknownMessageTile.js
index b965a4a1..d5a20c87 100644
--- a/skins/base/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/skins/base/views/molecules/UserSelector.js b/src/skins/vector/views/molecules/UserSelector.js
similarity index 94%
rename from skins/base/views/molecules/UserSelector.js
rename to src/skins/vector/views/molecules/UserSelector.js
index 8ec00866..6b233690 100644
--- a/skins/base/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/skins/base/views/molecules/voip/CallView.js b/src/skins/vector/views/molecules/voip/CallView.js
similarity index 77%
rename from skins/base/views/molecules/voip/CallView.js
rename to src/skins/vector/views/molecules/voip/CallView.js
index 3642e6b5..07987bd3 100644
--- a/skins/base/views/molecules/voip/CallView.js
+++ b/src/skins/vector/views/molecules/voip/CallView.js
@@ -18,12 +18,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"
+ "../../../../../controllers/molecules/voip/CallView"
);
-var VideoView = ComponentBroker.get('molecules/voip/VideoView');
module.exports = React.createClass({
displayName: 'CallView',
@@ -34,8 +32,9 @@ module.exports = React.createClass({
},
render: function(){
+ var VideoView = sdk.getComponent('molecules.voip.VideoView');
return (
);
}
-});
\ No newline at end of file
+});
diff --git a/skins/base/views/molecules/voip/IncomingCallBox.js b/src/skins/vector/views/molecules/voip/IncomingCallBox.js
similarity index 94%
rename from skins/base/views/molecules/voip/IncomingCallBox.js
rename to src/skins/vector/views/molecules/voip/IncomingCallBox.js
index 5becedb1..ee437f0a 100644
--- a/skins/base/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/skins/base/views/molecules/voip/VideoView.js b/src/skins/vector/views/molecules/voip/VideoView.js
similarity index 81%
rename from skins/base/views/molecules/voip/VideoView.js
rename to src/skins/vector/views/molecules/voip/VideoView.js
index 19ad17a7..80160b78 100644
--- a/skins/base/views/molecules/voip/VideoView.js
+++ b/src/skins/vector/views/molecules/voip/VideoView.js
@@ -18,10 +18,8 @@ limitations under the License.
var React = require('react');
-var MatrixClientPeg = require("../../../../../src/MatrixClientPeg");
-var ComponentBroker = require('../../../../../src/ComponentBroker');
-var VideoViewController = require("../../../../../src/controllers/molecules/voip/VideoView");
-var VideoFeed = ComponentBroker.get('atoms/voip/VideoFeed');
+var sdk = require('matrix-react-sdk')
+var VideoViewController = require('matrix-react-sdk/lib/controllers/molecules/voip/VideoView')
module.exports = React.createClass({
displayName: 'VideoView',
@@ -36,6 +34,7 @@ module.exports = React.createClass({
},
render: function() {
+ var VideoFeed = sdk.getComponent('atoms.voip.VideoFeed');
return (