Fix NPE when we don't know the sender of an event

Fixes a bug introduced in
https://github.com/matrix-org/matrix-react-sdk/pull/426.

Particularly when we are showing search results, we may not recognise the
sender of an event; attempting to create a MemberAvatar for it will lead to
null-reference errors.

Also a bit of untangling of the logic of needsSenderProfile. Since
https://github.com/matrix-org/matrix-react-sdk/pull/422,
EventTileType.needsSenderProfile was only being called on MessageEvents, and
therefore only returned true. It's a shame to see all this logic going into
EventTile rather than the individual EventTileTypes, but since it's there,
let's not leave the unused logic lying around in the EventTileType
implementations.
This commit is contained in:
Richard van der Hoff 2016-08-25 16:55:09 +01:00
parent c1db6fb42d
commit 96567dad0d
3 changed files with 33 additions and 33 deletions

View file

@ -22,12 +22,6 @@ var sdk = require('../../../index');
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'MessageEvent', displayName: 'MessageEvent',
statics: {
needsSenderProfile: function() {
return true;
}
},
propTypes: { propTypes: {
/* the MatrixEvent to show */ /* the MatrixEvent to show */
mxEvent: React.PropTypes.object.isRequired, mxEvent: React.PropTypes.object.isRequired,

View file

@ -24,12 +24,6 @@ import sdk from '../../../index';
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'TextualEvent', displayName: 'TextualEvent',
statics: {
needsSenderProfile: function() {
return false;
}
},
render: function() { render: function() {
const EmojiText = sdk.getComponent('elements.EmojiText'); const EmojiText = sdk.getComponent('elements.EmojiText');
var text = TextForEvent.textForEvent(this.props.mxEvent); var text = TextForEvent.textForEvent(this.props.mxEvent);
@ -39,4 +33,3 @@ module.exports = React.createClass({
); );
}, },
}); });

View file

@ -62,7 +62,7 @@ var MAX_READ_AVATARS = 5;
// '----------------------------------------------------------' // '----------------------------------------------------------'
module.exports = React.createClass({ module.exports = React.createClass({
displayName: 'Event', displayName: 'EventTile',
statics: { statics: {
haveTileForEvent: function(e) { haveTileForEvent: function(e) {
@ -368,7 +368,7 @@ module.exports = React.createClass({
// room, or emote messages // room, or emote messages
var isInfoMessage = (msgtype === 'm.emote' || eventType !== 'm.room.message'); var isInfoMessage = (msgtype === 'm.emote' || eventType !== 'm.room.message');
var EventTileType = sdk.getComponent(eventTileTypes[this.props.mxEvent.getType()]); var EventTileType = sdk.getComponent(eventTileTypes[eventType]);
// This shouldn't happen: the caller should check we support this type // This shouldn't happen: the caller should check we support this type
// before trying to instantiate us // before trying to instantiate us
if (!EventTileType) { if (!EventTileType) {
@ -395,32 +395,45 @@ module.exports = React.createClass({
<MessageTimestamp ts={this.props.mxEvent.getTs()} /> <MessageTimestamp ts={this.props.mxEvent.getTs()} />
</a> </a>
var aux = null; var readAvatars = this.getReadAvatars();
var avatar, sender;
let avatarSize;
let needsSenderProfile;
if (isInfoMessage) {
// a small avatar, with no sender profile, for emotes and
// joins/parts/etc
avatarSize = 14;
needsSenderProfile = false;
} else if (this.props.continuation) {
// no avatar or sender profile for continuation messages
avatarSize = 0;
needsSenderProfile = false;
} else {
avatarSize = 30;
needsSenderProfile = true;
}
if (this.props.mxEvent.sender && avatarSize) {
avatar = (
<div className="mx_EventTile_avatar">
<MemberAvatar member={this.props.mxEvent.sender}
width={avatarSize} height={avatarSize}
onClick={ this.onMemberAvatarClick }
/>
</div>
);
}
if (needsSenderProfile) {
let aux = null;
if (msgtype === 'm.image') aux = "sent an image"; if (msgtype === 'm.image') aux = "sent an image";
else if (msgtype === 'm.video') aux = "sent a video"; else if (msgtype === 'm.video') aux = "sent a video";
else if (msgtype === 'm.file') aux = "uploaded a file"; else if (msgtype === 'm.file') aux = "uploaded a file";
var readAvatars = this.getReadAvatars();
var avatar, sender;
if (isInfoMessage) {
avatar = (
<div className="mx_EventTile_avatar">
<MemberAvatar member={this.props.mxEvent.sender} width={14} height={14} onClick={ this.onMemberAvatarClick } />
</div>
);
} else if (!this.props.continuation) {
if (this.props.mxEvent.sender) {
avatar = (
<div className="mx_EventTile_avatar">
<MemberAvatar member={this.props.mxEvent.sender} width={30} height={30} onClick={ this.onMemberAvatarClick } />
</div>
);
}
if (EventTileType.needsSenderProfile()) {
sender = <SenderProfile onClick={ this.onSenderProfileClick } mxEvent={this.props.mxEvent} aux={aux} />; sender = <SenderProfile onClick={ this.onSenderProfileClick } mxEvent={this.props.mxEvent} aux={aux} />;
} }
}
var editButton = ( var editButton = (
<img className="mx_EventTile_editButton" src="img/icon_context_message.svg" width="19" height="19" alt="Options" title="Options" onClick={this.onEditClicked} /> <img className="mx_EventTile_editButton" src="img/icon_context_message.svg" width="19" height="19" alt="Options" title="Options" onClick={this.onEditClicked} />