AddAppDialog: Support adding apps to room state

pull/21833/head
Robert Swain 2017-06-13 15:31:37 +02:00
parent a72cb794f2
commit 2aa0aa61e3
3 changed files with 69 additions and 6 deletions

View File

@ -46,10 +46,14 @@ export default React.createClass({
onFormSubmit: function(ev) { onFormSubmit: function(ev) {
ev.preventDefault(); ev.preventDefault();
this.props.onFinished(true, this.state.value); this.props.onFinished(true, 'custom', this.state.value);
return false; return false;
}, },
onTileClick: function(value) {
this.props.onFinished(true, value, null);
},
render: function() { render: function() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog'); const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const appCards = ModularWidgets.widgetTypes.map((widgetType, index) => const appCards = ModularWidgets.widgetTypes.map((widgetType, index) =>
@ -58,7 +62,8 @@ export default React.createClass({
type={widgetType.type} type={widgetType.type}
icon={widgetType.icon} icon={widgetType.icon}
name={widgetType.name} name={widgetType.name}
description={widgetType.description}/>, description={widgetType.description}
onClick={this.onTileClick}/>,
); );
return ( return (

View File

@ -18,6 +18,14 @@ limitations under the License.
import React from 'react'; import React from 'react';
class AppIconTile extends React.Component { class AppIconTile extends React.Component {
constructor(props) {
super(props);
this._onTileClick = this._onTileClick.bind(this);
}
_onTileClick(props) {
this.props.onClick(this.props.type);
}
render() { render() {
const contentClasses = ['mx_AppIconTile']; const contentClasses = ['mx_AppIconTile'];
@ -26,7 +34,7 @@ class AppIconTile extends React.Component {
// } // }
return ( return (
<div className={contentClasses.join(' ')}> <div className={contentClasses.join(' ')} onClick={this._onTileClick}>
<div className="mx_AppIconTile_imageContainer"> <div className="mx_AppIconTile_imageContainer">
<img src={this.props.icon} alt={this.props.name} className="mx_AppIconTile_image"/> <img src={this.props.icon} alt={this.props.name} className="mx_AppIconTile_image"/>
</div> </div>
@ -44,6 +52,7 @@ AppIconTile.propTypes = {
icon: React.PropTypes.string.isRequired, icon: React.PropTypes.string.isRequired,
name: React.PropTypes.string.isRequired, name: React.PropTypes.string.isRequired,
description: React.PropTypes.string.isRequired, description: React.PropTypes.string.isRequired,
onClick: React.PropTypes.func.isRequired,
}; };
export default AppIconTile; export default AppIconTile;

View File

@ -113,10 +113,59 @@ module.exports = React.createClass({
onClickAddWidget: function() { onClickAddWidget: function() {
Modal.createDialog(AddAppDialog, { Modal.createDialog(AddAppDialog, {
onFinished: (proceed, reason) => { onFinished: (proceed, type, value) => {
if (!proceed) return; if (!proceed || !type) return;
if (type === 'custom' && !value) return;
this.state.apps.push(); const appsStateEvents = this.props.room.currentState.getStateEvents('im.vector.modular.widgets', '');
let appsStateEvent = {};
if (appsStateEvents) {
appsStateEvent = appsStateEvents.getContent();
}
if (appsStateEvent[type]) {
return;
}
switch (type) {
case 'etherpad':
appsStateEvent.etherpad = {
type: type,
url: 'http://localhost:8000/etherpad.html',
};
break;
case 'grafana':
appsStateEvent.grafana = {
type: type,
url: 'http://localhost:8000/grafana.html',
};
break;
case 'jitsi':
appsStateEvent.videoConf = {
type: type,
url: 'http://localhost:8000/jitsi.html',
data: {
confId: this.props.room.roomId.replace(/[^A-Za-z0-9]/g, '_') + Date.now(),
},
};
break;
case 'custom':
appsStateEvent.custom = {
type: type,
url: value,
};
break;
default:
console.warn('Unsupported app type:', type);
return;
}
MatrixClientPeg.get().sendStateEvent(
this.props.room.roomId,
'im.vector.modular.widgets',
appsStateEvent,
'',
);
}, },
}); });
}, },