diff --git a/src/Velociraptor.js b/src/Velociraptor.js index 6a4666305c8..ad51f66ae31 100644 --- a/src/Velociraptor.js +++ b/src/Velociraptor.js @@ -68,7 +68,9 @@ module.exports = React.createClass({ if (oldNode && oldNode.style.visibility == 'hidden' && c.props.style.visibility == 'visible') { oldNode.style.visibility = c.props.style.visibility; } - self.children[c.key] = old; + // clone the old element with the props (and children) of the new element + // so prop updates are still received by the children. + self.children[c.key] = React.cloneElement(old, c.props, c.props.children); } else { // new element. If we have a startStyle, use that as the style and go through // the enter animations diff --git a/src/components/structures/MessagePanel.js b/src/components/structures/MessagePanel.js index f5fa2ceabfd..bbaea617f4a 100644 --- a/src/components/structures/MessagePanel.js +++ b/src/components/structures/MessagePanel.js @@ -542,7 +542,7 @@ module.exports = React.createClass({ }, // get a list of read receipts that should be shown next to this event - // Receipts are objects which have a 'roomMember' and 'ts'. + // Receipts are objects which have a 'userId', 'roomMember' and 'ts'. _getReadReceiptsForEvent: function(event) { const myUserId = MatrixClientPeg.get().credentials.userId; @@ -560,10 +560,8 @@ module.exports = React.createClass({ return; // ignore ignored users } const member = room.getMember(r.userId); - if (!member) { - return; // ignore unknown user IDs - } receipts.push({ + userId: r.userId, roomMember: member, ts: r.data ? r.data.ts : 0, }); diff --git a/src/components/views/avatars/MemberAvatar.js b/src/components/views/avatars/MemberAvatar.js index a4fe5e280f2..d191368b176 100644 --- a/src/components/views/avatars/MemberAvatar.js +++ b/src/components/views/avatars/MemberAvatar.js @@ -26,7 +26,8 @@ module.exports = React.createClass({ displayName: 'MemberAvatar', propTypes: { - member: PropTypes.object.isRequired, + member: PropTypes.object, + fallbackUserId: PropTypes.string, width: PropTypes.number, height: PropTypes.number, resizeMethod: PropTypes.string, @@ -55,23 +56,30 @@ module.exports = React.createClass({ }, _getState: function(props) { - if (!props.member) { - console.error("MemberAvatar called somehow with null member"); + if (props.member) { + return { + name: props.member.name, + title: props.title || props.member.userId, + imageUrl: Avatar.avatarUrlForMember(props.member, + props.width, + props.height, + props.resizeMethod), + }; + } else if (props.fallbackUserId) { + return { + name: props.fallbackUserId, + title: props.fallbackUserId, + }; + } else { + console.error("MemberAvatar called somehow with null member or fallbackUserId"); } - return { - name: props.member.name, - title: props.title || props.member.userId, - imageUrl: Avatar.avatarUrlForMember(props.member, - props.width, - props.height, - props.resizeMethod), - }; }, render: function() { const BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); - let {member, onClick, viewUserOnClick, ...otherProps} = this.props; + let {member, fallbackUserId, onClick, viewUserOnClick, ...otherProps} = this.props; + let userId = member ? member.userId : fallbackUserId; if (viewUserOnClick) { onClick = () => { @@ -84,7 +92,7 @@ module.exports = React.createClass({ return ( + idName={userId} url={this.state.imageUrl} onClick={onClick} /> ); }, }); diff --git a/src/components/views/rooms/EventTile.js b/src/components/views/rooms/EventTile.js index 8c58863249f..53c73c8f840 100644 --- a/src/components/views/rooms/EventTile.js +++ b/src/components/views/rooms/EventTile.js @@ -277,7 +277,11 @@ module.exports = withMatrixClient(React.createClass({ return false; } for (let j = 0; j < rA.length; j++) { - if (rA[j].roomMember.userId !== rB[j].roomMember.userId) { + if (rA[j].userId !== rB[j].userId) { + return false; + } + // one has a member set and the other doesn't? + if (rA[j].roomMember !== rB[j].roomMember) { return false; } } @@ -359,7 +363,7 @@ module.exports = withMatrixClient(React.createClass({ // else set it proportional to index left = (hidden ? MAX_READ_AVATARS - 1 : i) * -receiptOffset; - const userId = receipt.roomMember.userId; + const userId = receipt.userId; let readReceiptInfo; if (this.props.readReceiptMap) { @@ -373,6 +377,7 @@ module.exports = withMatrixClient(React.createClass({ // add to the start so the most recent is on the end (ie. ends up rightmost) avatars.unshift(