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({
);
}
});
-