Add suport for showing the scalar UI

This commit is contained in:
David Baker 2016-05-06 14:19:56 +01:00
parent b86af8939a
commit 6da4b9d671
4 changed files with 130 additions and 0 deletions

45
src/ScalarAuthClient.js Normal file
View file

@ -0,0 +1,45 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var q = require("q");
var request = require('browser-request');
var SdkConfig = require('./SdkConfig');
class ScalarAuthClient {
getScalarToken(openid_token_object) {
var defer = q.defer();
var scalar_rest_url = SdkConfig.get().integrations_rest_url;
request({
method: 'POST',
uri: scalar_rest_url+'/register',
body: openid_token_object,
json: true,
}, (err, response, body) => {
if (err) {
defer.reject(err);
} else {
defer.resolve(body);
}
});
return defer.promise;
}
}
module.exports = ScalarAuthClient;

45
src/SdkConfig.js Normal file
View file

@ -0,0 +1,45 @@
/*
Copyright 2016 OpenMarket Ltd
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
var DEFAULTS = {
// URL to a page we show in an iframe to configure integrations
integrations_ui_url: "https://scalar.vector.im/",
// Base URL to the REST interface of the integrations server
integrations_rest_url: "https://scalar.vector.im/api",
};
class SdkConfig {
static get() {
return global.mxReactSdkConfig;
}
static put(cfg) {
var defaultKeys = Object.keys(DEFAULTS);
for (var i = 0; i < defaultKeys.length; ++i) {
if (cfg[defaultKeys[i]] === undefined) {
cfg[defaultKeys[i]] = DEFAULTS[defaultKeys[i]];
}
}
global.mxReactSdkConfig = cfg;
}
static unset() {
global.mxReactSdkConfig = undefined;
}
}
module.exports = SdkConfig;

View file

@ -19,6 +19,7 @@ var url = require('url');
var Favico = require('favico.js'); var Favico = require('favico.js');
var MatrixClientPeg = require("../../MatrixClientPeg"); var MatrixClientPeg = require("../../MatrixClientPeg");
var SdkConfig = require("../../SdkConfig");
var Notifier = require("../../Notifier"); var Notifier = require("../../Notifier");
var ContextualMenu = require("../../ContextualMenu"); var ContextualMenu = require("../../ContextualMenu");
var RoomListSorter = require("../../RoomListSorter"); var RoomListSorter = require("../../RoomListSorter");
@ -119,6 +120,7 @@ module.exports = React.createClass({
}, },
componentWillMount: function() { componentWillMount: function() {
SdkConfig.put(this.props.config);
this.favicon = new Favico({animation: 'none'}); this.favicon = new Favico({animation: 'none'});
}, },

View file

@ -17,10 +17,12 @@ limitations under the License.
var q = require("q"); var q = require("q");
var React = require('react'); var React = require('react');
var MatrixClientPeg = require('../../../MatrixClientPeg'); var MatrixClientPeg = require('../../../MatrixClientPeg');
var SdkConfig = require('../../../SdkConfig');
var sdk = require('../../../index'); var sdk = require('../../../index');
var Modal = require('../../../Modal'); var Modal = require('../../../Modal');
var ObjectUtils = require("../../../ObjectUtils"); var ObjectUtils = require("../../../ObjectUtils");
var dis = require("../../../dispatcher"); var dis = require("../../../dispatcher");
var ScalarAuthClient = require("../../../ScalarAuthClient");
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'RoomSettings', displayName: 'RoomSettings',
@ -71,6 +73,10 @@ module.exports = React.createClass({
console.error("Failed to get room visibility: " + err); console.error("Failed to get room visibility: " + err);
}); });
this.getScalarToken().done((token) => {
this.setState({scalar_token: token});
});
dis.dispatch({ dis.dispatch({
action: 'ui_opacity', action: 'ui_opacity',
sideOpacity: 0.3, sideOpacity: 0.3,
@ -359,6 +365,28 @@ module.exports = React.createClass({
roomState.mayClientSendStateEvent("m.room.guest_access", cli)) roomState.mayClientSendStateEvent("m.room.guest_access", cli))
}, },
getScalarInterfaceUrl: function() {
var url = SdkConfig.get().integrations_ui_url;
url += "?token=" + this.state.scalar_token;
return url;
},
getScalarToken() {
var tok = window.localStorage.getItem("mx_scalar_token");
if (tok) return q(tok);
// No saved token, so do the dance to get one. First, we
// need an openid bearer token from the HS.
return MatrixClientPeg.get().getOpenIdToken().then((token_object) => {
// Now we can send that to scalar and exchange it for a scalar token
var scalar_auth_client = new ScalarAuthClient();
return scalar_auth_client.getScalarToken(token_object);
}).then((token_object) => {
window.localStorage.setItem("mx_scalar_token", token_object);
return token_object;
});
},
render: function() { render: function() {
// TODO: go through greying out things you don't have permission to change // TODO: go through greying out things you don't have permission to change
// (or turning them into informative stuff) // (or turning them into informative stuff)
@ -367,6 +395,7 @@ module.exports = React.createClass({
var ColorSettings = sdk.getComponent("room_settings.ColorSettings"); var ColorSettings = sdk.getComponent("room_settings.ColorSettings");
var EditableText = sdk.getComponent('elements.EditableText'); var EditableText = sdk.getComponent('elements.EditableText');
var PowerSelector = sdk.getComponent('elements.PowerSelector'); var PowerSelector = sdk.getComponent('elements.PowerSelector');
var Loader = sdk.getComponent("elements.Spinner")
var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', ''); var power_levels = this.props.room.currentState.getStateEvents('m.room.power_levels', '');
var events_levels = (power_levels ? power_levels.getContent().events : {}) || {}; var events_levels = (power_levels ? power_levels.getContent().events : {}) || {};
@ -533,6 +562,13 @@ module.exports = React.createClass({
</div> </div>
} }
var integrations_section;
if (this.state.scalar_token) {
integrations_section = <iframe src={this.getScalarInterfaceUrl()} width={640} height={600}></iframe>;
} else {
integrations_section = <Loader />;
}
return ( return (
<div className="mx_RoomSettings"> <div className="mx_RoomSettings">
@ -682,6 +718,8 @@ module.exports = React.createClass({
This room's internal ID is <code>{ this.props.room.roomId }</code> This room's internal ID is <code>{ this.props.room.roomId }</code>
</div> </div>
<h3>Integrations</h3>
{ integrations_section }
</div> </div>
); );
} }