diff --git a/src/skins/vector/skindex.js b/src/skins/vector/skindex.js
index cf279c87..84f26499 100644
--- a/src/skins/vector/skindex.js
+++ b/src/skins/vector/skindex.js
@@ -70,7 +70,6 @@ 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.CasLogin'] = require('./views/organisms/CasLogin');
skin['organisms.CreateRoom'] = require('./views/organisms/CreateRoom');
skin['organisms.ErrorDialog'] = require('./views/organisms/ErrorDialog');
skin['organisms.LeftPanel'] = require('./views/organisms/LeftPanel');
@@ -87,7 +86,7 @@ skin['organisms.UserSettings'] = require('./views/organisms/UserSettings');
skin['organisms.ViewSource'] = require('./views/organisms/ViewSource');
skin['pages.CompatibilityPage'] = require('./views/pages/CompatibilityPage');
skin['pages.MatrixChat'] = require('./views/pages/MatrixChat');
-skin['templates.Login'] = require('./views/templates/Login');
+skin['pages.Login'] = require('./views/pages/Login');
skin['templates.Register'] = require('./views/templates/Register');
module.exports = skin;
\ No newline at end of file
diff --git a/src/skins/vector/views/molecules/ServerConfig.js b/src/skins/vector/views/molecules/ServerConfig.js
index d6947727..8f1eab38 100644
--- a/src/skins/vector/views/molecules/ServerConfig.js
+++ b/src/skins/vector/views/molecules/ServerConfig.js
@@ -20,37 +20,142 @@ var React = require('react');
var Modal = require('matrix-react-sdk/lib/Modal');
var sdk = require('matrix-react-sdk')
-var ServerConfigController = require('matrix-react-sdk/lib/controllers/molecules/ServerConfig')
-
+/**
+ * A pure UI component which displays the HS and IS to use.
+ */
module.exports = React.createClass({
displayName: 'ServerConfig',
- mixins: [ServerConfigController],
+
+ propTypes: {
+ onHsUrlChanged: React.PropTypes.func,
+ onIsUrlChanged: React.PropTypes.func,
+ defaultHsUrl: React.PropTypes.string,
+ defaultIsUrl: React.PropTypes.string,
+ withToggleButton: React.PropTypes.bool,
+ delayTimeMs: React.PropTypes.number // time to wait before invoking onChanged
+ },
+
+ getDefaultProps: function() {
+ return {
+ onHsUrlChanged: function() {},
+ onIsUrlChanged: function() {},
+ withToggleButton: false,
+ delayTimeMs: 0
+ };
+ },
+
+ getInitialState: function() {
+ return {
+ hs_url: this.props.defaultHsUrl,
+ is_url: this.props.defaultIsUrl,
+ original_hs_url: this.props.defaultHsUrl,
+ original_is_url: this.props.defaultIsUrl,
+ // no toggle button = show, toggle button = hide
+ configVisible: !this.props.withToggleButton
+ }
+ },
+
+ onHomeserverChanged: function(ev) {
+ this.setState({hs_url: ev.target.value}, function() {
+ this._hsTimeoutId = this._waitThenInvoke(this._hsTimeoutId, function() {
+ this.props.onHsUrlChanged(this.state.hs_url);
+ });
+ });
+ },
+
+ onIdentityServerChanged: function(ev) {
+ this.setState({is_url: ev.target.value}, function() {
+ this._isTimeoutId = this._waitThenInvoke(this._isTimeoutId, function() {
+ this.props.onIsUrlChanged(this.state.is_url);
+ });
+ });
+ },
+
+ _waitThenInvoke: function(existingTimeoutId, fn) {
+ if (existingTimeoutId) {
+ clearTimeout(existingTimeoutId);
+ }
+ return setTimeout(fn.bind(this), this.props.delayTimeMs);
+ },
+
+ getHsUrl: function() {
+ return this.state.hs_url;
+ },
+
+ getIsUrl: function() {
+ return this.state.is_url;
+ },
+
+ onServerConfigVisibleChange: function(ev) {
+ this.setState({
+ configVisible: ev.target.checked
+ });
+ },
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 use the custom server options to log into other Matrix
+ servers by specifying a different Home server URL.
- You can also set a custom Identity server but this will affect people's ability to find you
- if you use a server in a group other than the main Matrix.org group.
+ This allows you to use Vector with an existing Matrix account on
+ a different Home server.
+
+
+ You can also set a custom Identity server but this will affect
+ people's ability to find you if you use a server in a group other
+ than the main Matrix.org group.
,
button: "Dismiss",
- focus: true,
+ focus: true
});
},
render: function() {
+ var serverConfigStyle = {};
+ serverConfigStyle.display = this.state.configVisible ? 'block' : 'none';
+
+ var toggleButton;
+ if (this.props.withToggleButton) {
+ toggleButton = (
+
);
}
});
diff --git a/src/skins/vector/views/organisms/CasLogin.js b/src/skins/vector/views/organisms/CasLogin.js
deleted file mode 100644
index ad9dbed9..00000000
--- a/src/skins/vector/views/organisms/CasLogin.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');
-
-var CasLoginController = require('matrix-react-sdk/lib/controllers/organisms/CasLogin');
-
-module.exports = React.createClass({
- displayName: 'CasLogin',
- mixins: [CasLoginController],
-
- render: function() {
- return (
-
-
-
- );
- },
-
-});
diff --git a/src/skins/vector/views/pages/Login.js b/src/skins/vector/views/pages/Login.js
new file mode 100644
index 00000000..b8f0e43e
--- /dev/null
+++ b/src/skins/vector/views/pages/Login.js
@@ -0,0 +1,199 @@
+/*
+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 ReactDOM = require('react-dom');
+var sdk = require('matrix-react-sdk');
+var Signup = require("matrix-react-sdk/lib/Signup");
+var PasswordLogin = require("matrix-react-sdk/lib/components/PasswordLogin");
+var CasLogin = require("matrix-react-sdk/lib/components/CasLogin");
+
+/**
+ * A wire component which glues together login UI components and Signup logic
+ */
+module.exports = React.createClass({displayName: 'Login',
+ propTypes: {
+ onLoggedIn: React.PropTypes.func.isRequired,
+ homeserverUrl: React.PropTypes.string,
+ identityServerUrl: React.PropTypes.string,
+ // login shouldn't know or care how registration is done.
+ onRegisterClick: React.PropTypes.func.isRequired
+ },
+
+ getDefaultProps: function() {
+ return {
+ homeserverUrl: 'https://matrix.org/',
+ identityServerUrl: 'https://vector.im'
+ };
+ },
+
+ getInitialState: function() {
+ return {
+ busy: false,
+ errorText: null,
+ enteredHomeserverUrl: this.props.homeserverUrl,
+ enteredIdentityServerUrl: this.props.identityServerUrl
+ };
+ },
+
+ componentWillMount: function() {
+ this._initLoginLogic();
+ },
+
+ onPasswordLogin: function(username, password) {
+ var self = this;
+ self.setState({
+ busy: true
+ });
+
+ this._loginLogic.loginViaPassword(username, password).then(function(data) {
+ self.props.onLoggedIn(data);
+ }, function(error) {
+ self._setErrorTextFromError(error);
+ }).finally(function() {
+ self.setState({
+ busy: false
+ });
+ });
+ },
+
+ onHsUrlChanged: function(newHsUrl) {
+ this._initLoginLogic(newHsUrl);
+ },
+
+ onIsUrlChanged: function(newIsUrl) {
+ this._initLoginLogic(null, newIsUrl);
+ },
+
+ _initLoginLogic: function(hsUrl, isUrl) {
+ var self = this;
+ hsUrl = hsUrl || this.state.enteredHomeserverUrl;
+ isUrl = isUrl || this.state.enteredIdentityServerUrl;
+
+ var loginLogic = new Signup.Login(hsUrl, isUrl);
+ this._loginLogic = loginLogic;
+
+ loginLogic.getFlows().then(function(flows) {
+ // old behaviour was to always use the first flow without presenting
+ // options. This works in most cases (we don't have a UI for multiple
+ // logins so let's skip that for now).
+ loginLogic.chooseFlow(0);
+ }, function(err) {
+ self._setErrorTextFromError(err);
+ }).finally(function() {
+ self.setState({
+ busy: false
+ });
+ });
+
+ this.setState({
+ enteredHomeserverUrl: hsUrl,
+ enteredIdentityServerUrl: isUrl,
+ busy: true,
+ errorText: null // reset err messages
+ });
+ },
+
+ _getCurrentFlowStep: function() {
+ return this._loginLogic ? this._loginLogic.getCurrentFlowStep() : null
+ },
+
+ _setErrorTextFromError: function(err) {
+ if (err.friendlyText) {
+ this.setState({
+ errorText: err.friendlyText
+ });
+ return;
+ }
+
+ var errCode = err.errcode;
+ if (!errCode && err.httpStatus) {
+ errCode = "HTTP " + err.httpStatus;
+ }
+ this.setState({
+ errorText: (
+ "Error: Problem communicating with the given homeserver " +
+ (errCode ? "(" + errCode + ")" : "")
+ )
+ });
+ },
+
+ componentForStep: function(step) {
+ switch (step) {
+ case 'm.login.password':
+ return (
+
+ );
+ case 'm.login.cas':
+ return (
+
+ );
+ default:
+ if (!step) {
+ return;
+ }
+ return (
+
+ Sorry, this homeserver is using a login which is not
+ recognised by Vector ({step})
+