Move avatars into their own components so I can add functionality like custom default avatars and onerror sources without having to add it in 13 separate places. Add the aforementioned features.

This commit is contained in:
David Baker 2015-08-13 19:30:02 +01:00
parent b580fba7db
commit fec266f1c0
20 changed files with 314 additions and 23 deletions

View file

@ -103,6 +103,8 @@ require('../skins/base/views/molecules/RoomDropTarget');
require('../skins/base/views/molecules/BottomLeftMenu');
require('../skins/base/views/molecules/DateSeparator');
require('../skins/base/views/atoms/voip/VideoFeed');
require('../skins/base/views/atoms/MemberAvatar');
require('../skins/base/views/atoms/RoomAvatar');
require('../skins/base/views/atoms/ImageView');
require('../skins/base/views/molecules/voip/VideoView');
require('../skins/base/views/molecules/voip/CallView');

38
src/DefaultAvatar.js Normal file
View file

@ -0,0 +1,38 @@
/*
Copyright 2015 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.
*/
'use strict';
module.exports = {
defaultAvatarUrlForString: function(s) {
var total = 0;
for (var i = 0; i < s.length; ++i) {
total += s.charCodeAt(i);
}
switch (total % 3) {
case 0:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9QjNbxSKP4eagAFnTseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAABSwCRWJw31gAAAAASUVORK5CYII=";
break;
case 1:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9chOaxgCP4eagAFk9seHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAtKMCks/JG8MAAAAASUVORK5CYII=";
break;
case 2:
return "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAIAAAADnC86AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAADRJREFUeNrszQENADAIACB9YzNayQCP4eagADldseHFErFYLBaLxWKxWCwWi8Vi8cX4CzAAyiACeHwPiu4AAAAASUVORK5CYII=";
break;
}
}
}

View file

@ -0,0 +1,76 @@
/*
Copyright 2015 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.
*/
'use strict';
var MatrixClientPeg = require('../../MatrixClientPeg');
var DefaultAvatar = require('../../DefaultAvatar');
var React = require('react');
module.exports = {
propTypes: {
member: React.PropTypes.object.isRequired,
width: React.PropTypes.number,
height: React.PropTypes.number,
resizeMethod: React.PropTypes.string,
},
getDefaultProps: function() {
return {
width: 40,
height: 40,
resizeMethod: 'crop'
}
},
// takes member as an arg so it can be used if the
// avatars are required outsode of components
// (eg. in html5 desktop notifs)
avatarUrlForMember(member) {
var url = MatrixClientPeg.get().getAvatarUrlForMember(
member,
this.props.width, this.props.height, this.props.resizeMethod,
false
);
if (url === null) {
url = this.defaultAvatarUrl(member);
}
return url;
},
defaultAvatarUrl: function(member) {
return DefaultAvatar.defaultAvatarUrlForString(
member.userId
);
},
onError: function(ev) {
// don't tightloop if the browser can't load a data url
if (ev.target.src == this.defaultAvatarUrl()) {
return;
}
this.setState({
imageUrl: this.defaultAvatarUrl()
});
},
getInitialState: function() {
return {
imageUrl: this.avatarUrlForMember(this.props.member)
};
}
};

View file

@ -0,0 +1,67 @@
/*
Copyright 2015 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.
*/
'use strict';
var MatrixClientPeg = require('../../MatrixClientPeg');
var DefaultAvatar = require('../../DefaultAvatar');
module.exports = {
getDefaultProps: function() {
return {
width: 40,
height: 40,
resizeMethod: 'crop'
}
},
// takes member as an arg so it can be used if the
// avatars are required outsode of components
// (eg. in html5 desktop notifs, although this is not)
avatarUrlForRoom(room) {
var url = MatrixClientPeg.get().getAvatarUrlForRoom(
room,
this.props.width, this.props.height, this.props.resizeMethod,
false
);
if (url === null) {
url = this.defaultAvatarUrl(room);
}
return url;
},
defaultAvatarUrl: function(room) {
return DefaultAvatar.defaultAvatarUrlForString(
this.props.room.roomId
);
},
onError: function(ev) {
// don't tightloop if the browser can't load a data url
if (ev.target.src == this.defaultAvatarUrl()) {
return;
}
this.setState({
imageUrl: this.defaultAvatarUrl()
});
},
getInitialState: function() {
return {
imageUrl: this.avatarUrlForRoom(this.props.room)
};
}
};