diff --git a/src/component-index.js b/src/component-index.js index 967cc5d685..3570523bde 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -79,6 +79,7 @@ module.exports.components['views.rooms.EntityTile'] = require('./components/view module.exports.components['views.rooms.EventTile'] = require('./components/views/rooms/EventTile'); module.exports.components['views.rooms.InviteMemberList'] = require('./components/views/rooms/InviteMemberList'); module.exports.components['views.rooms.LinkPreviewWidget'] = require('./components/views/rooms/LinkPreviewWidget'); +module.exports.components['views.rooms.MemberDeviceInfo'] = require('./components/views/rooms/MemberDeviceInfo'); module.exports.components['views.rooms.MemberInfo'] = require('./components/views/rooms/MemberInfo'); module.exports.components['views.rooms.MemberList'] = require('./components/views/rooms/MemberList'); module.exports.components['views.rooms.MemberTile'] = require('./components/views/rooms/MemberTile'); diff --git a/src/components/views/rooms/MemberDeviceInfo.js b/src/components/views/rooms/MemberDeviceInfo.js new file mode 100644 index 0000000000..6af7b848c0 --- /dev/null +++ b/src/components/views/rooms/MemberDeviceInfo.js @@ -0,0 +1,58 @@ +/* +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 React = require('react'); +var MatrixClientPeg = require("../../../MatrixClientPeg"); + +module.exports = React.createClass({ + displayName: 'MemberDeviceInfo', + propTypes: { + userId: React.PropTypes.string.isRequired, + device: React.PropTypes.object.isRequired, + }, + + onVerifyClick: function() { + MatrixClientPeg.get().setDeviceVerified(this.props.userId, + this.props.device.id); + // TODO: wire this up properly + this.props.device.verified = true; + this.forceUpdate(); + }, + + render: function() { + var indicator = null, button = null; + if (this.props.device.verified) { + indicator = ( +
+ ); + } else { + button = ( +
+ Verify +
+ ); + } + return ( +
+
{this.props.device.id}
+
{this.props.device.key}
+ {indicator} + {button} +
+ ); + }, +}); diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index ba4a3734f5..385f9dee19 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -34,23 +34,81 @@ var sdk = require('../../../index'); module.exports = React.createClass({ displayName: 'MemberInfo', + propTypes: { + member: React.PropTypes.object.isRequired, + onFinished: React.PropTypes.func, + }, + getDefaultProps: function() { return { onFinished: function() {} }; }, - componentDidMount: function() { - // work out the current state - if (this.props.member) { - var memberState = this._calculateOpsPermissions(this.props.member); - this.setState(memberState); + getInitialState: function() { + return { + can: { + kick: false, + ban: false, + mute: false, + modifyLevel: false + }, + muted: false, + isTargetMod: false, + updating: 0, + devices: null, // null means device list is loading } }, + + componentWillMount: function() { + this._cancelDeviceList = null; + }, + + componentDidMount: function() { + this._updateStateForNewMember(this.props.member); + }, + componentWillReceiveProps: function(newProps) { - var memberState = this._calculateOpsPermissions(newProps.member); - this.setState(memberState); + if (this.props.member.userId != newProps.member.userId) { + this._updateStateForNewMember(newProps.member); + } + }, + + componentWillUnmount: function() { + if (this._cancelDeviceList) { + this._cancelDeviceList(); + } + }, + + _updateStateForNewMember: function(member) { + var newState = this._calculateOpsPermissions(member); + newState.devices = null; + this.setState(newState); + + if (this._cancelDeviceList) { + this._cancelDeviceList(); + this._cancelDeviceList = null; + } + + this._downloadDeviceList(member); + }, + + _downloadDeviceList: function(member) { + var cancelled = false; + this._cancelDeviceList = function() { cancelled = true; } + + var client = MatrixClientPeg.get(); + var self = this; + client.downloadKeys([member.userId], true).done(function() { + if (cancelled) { + // we got cancelled - presumably a different user now + return; + } + self._cancelDeviceList = null; + var devices = client.listDeviceKeys(member.userId); + self.setState({devices: devices}); + }); }, onKick: function() { @@ -371,20 +429,6 @@ module.exports = React.createClass({ this.props.onFinished(); }, - getInitialState: function() { - return { - can: { - kick: false, - ban: false, - mute: false, - modifyLevel: false - }, - muted: false, - isTargetMod: false, - updating: 0, - } - }, - _calculateOpsPermissions: function(member) { var defaultPerms = { can: {}, @@ -476,6 +520,32 @@ module.exports = React.createClass({ Modal.createDialog(ImageView, params, "mx_Dialog_lightbox"); }, + _renderDevices: function() { + var devices = this.state.devices; + var MemberDeviceInfo = sdk.getComponent('rooms.MemberDeviceInfo'); + var Spinner = sdk.getComponent("elements.Spinner"); + + var devComponents; + if (devices === null) { + // still loading + devComponents = ; + } else { + devComponents = []; + for (var i = 0; i < devices.length; i++) { + devComponents.push(); + } + } + + return ( +
+

Devices

+ {devComponents} +
+ ); + }, + render: function() { var startChat, kickButton, banButton, muteButton, giveModButton, spinner; if (this.props.member.userId !== MatrixClientPeg.get().credentials.userId) { @@ -552,6 +622,8 @@ module.exports = React.createClass({ { startChat } + { this._renderDevices() } + { adminTools } { spinner } @@ -559,4 +631,3 @@ module.exports = React.createClass({ ); } }); -