Factor out avatar stuff to BaseAvatar. Make MemberAvatar use it instead.
							parent
							
								
									b491447702
								
							
						
					
					
						commit
						cfb81a4aec
					
				|  | @ -32,6 +32,7 @@ module.exports.components['structures.RoomView'] = require('./components/structu | |||
| module.exports.components['structures.ScrollPanel'] = require('./components/structures/ScrollPanel'); | ||||
| module.exports.components['structures.UploadBar'] = require('./components/structures/UploadBar'); | ||||
| module.exports.components['structures.UserSettings'] = require('./components/structures/UserSettings'); | ||||
| module.exports.components['views.avatars.BaseAvatar'] = require('./components/views/avatars/BaseAvatar'); | ||||
| module.exports.components['views.avatars.MemberAvatar'] = require('./components/views/avatars/MemberAvatar'); | ||||
| module.exports.components['views.avatars.RoomAvatar'] = require('./components/views/avatars/RoomAvatar'); | ||||
| module.exports.components['views.create_room.CreateRoomButton'] = require('./components/views/create_room/CreateRoomButton'); | ||||
|  |  | |||
|  | @ -0,0 +1,131 @@ | |||
| /* | ||||
| Copyright 2015, 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. | ||||
| */ | ||||
| 
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| var React = require('react'); | ||||
| var AvatarLogic = require("../../../Avatar"); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'BaseAvatar', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         name: React.PropTypes.string.isRequired, | ||||
|         idName: React.PropTypes.string, // ID for generating hash colours
 | ||||
|         title: React.PropTypes.string, | ||||
|         url: React.PropTypes.string, // highest priority of them all
 | ||||
|         urls: React.PropTypes.array, // [highest_priority, ... , lowest_priority]
 | ||||
|         width: React.PropTypes.number, | ||||
|         height: React.PropTypes.number, | ||||
|         resizeMethod: React.PropTypes.string, | ||||
|         defaultToInitialLetter: React.PropTypes.bool | ||||
|     }, | ||||
| 
 | ||||
|     getDefaultProps: function() { | ||||
|         return { | ||||
|             width: 40, | ||||
|             height: 40, | ||||
|             resizeMethod: 'crop', | ||||
|             defaultToInitialLetter: true | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     getInitialState: function() { | ||||
|         var defaultImageUrl = null; | ||||
|         if (this.props.defaultToInitialLetter) { | ||||
|             defaultImageUrl = AvatarLogic.defaultAvatarUrlForString( | ||||
|                 this.props.idName || this.props.name | ||||
|             ); | ||||
|         } | ||||
|         return { | ||||
|             imageUrl: this.props.url || (this.props.urls ? this.props.urls[0] : null), | ||||
|             defaultImageUrl: defaultImageUrl, | ||||
|             urlsIndex: 0 | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
|     componentWillReceiveProps: function(nextProps) { | ||||
|         // retry all the urls again, they may have changed.
 | ||||
|         if (this.props.urls && this.state.urlsIndex > 0) { | ||||
|             this.setState({ | ||||
|                 urlsIndex: 0, | ||||
|                 imageUrl: this.props.urls[0] | ||||
|             }); | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     onError: function(ev) { | ||||
|         var failedUrl = ev.target.src; | ||||
| 
 | ||||
|         if (this.props.urls) { | ||||
|             var nextIndex = this.state.urlsIndex + 1; | ||||
|             if (nextIndex < this.props.urls.length) { | ||||
|                 // try another
 | ||||
|                 this.setState({ | ||||
|                     urlsIndex: nextIndex, | ||||
|                     imageUrl: this.props.urls[nextIndex] | ||||
|                 }); | ||||
|                 return; | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         // either no urls array or we've reached the end of it, we may have a default
 | ||||
|         // we can use...
 | ||||
|         if (this.props.defaultToInitialLetter) { | ||||
|             if (failedUrl === this.state.defaultImageUrl) { | ||||
|                 return; // don't tightloop if the browser can't load the default URL
 | ||||
|             } | ||||
|             this.setState({ imageUrl: this.state.defaultImageUrl }) | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     _getInitialLetter: function() { | ||||
|         var name = this.props.name; | ||||
|         var initial = name[0]; | ||||
|         if (initial === '@' && name[1]) { | ||||
|             initial = name[1]; | ||||
|         } | ||||
|         return initial.toUpperCase(); | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var name = this.props.name; | ||||
| 
 | ||||
|         if (this.state.imageUrl === this.state.defaultImageUrl) { | ||||
|             var initialLetter = this._getInitialLetter(); | ||||
|             return ( | ||||
|                 <span className="mx_MemberAvatar" {...this.props}> | ||||
|                     <span className="mx_MemberAvatar_initial" aria-hidden="true" | ||||
|                             style={{ fontSize: (this.props.width * 0.65) + "px", | ||||
|                                     width: this.props.width + "px", | ||||
|                                     lineHeight: this.props.height + "px" }}> | ||||
|                         { initialLetter } | ||||
|                     </span> | ||||
|                     <img className="mx_MemberAvatar_image" src={this.state.imageUrl} | ||||
|                         title={this.props.title} onError={this.onError} | ||||
|                         width={this.props.width} height={this.props.height} /> | ||||
|                 </span> | ||||
|             );             | ||||
|         } | ||||
|         return ( | ||||
|             <img className="mx_MemberAvatar mx_MemberAvatar_image" src={this.state.imageUrl} | ||||
|                 onError={this.onError} | ||||
|                 width={this.props.width} height={this.props.height} | ||||
|                 title={this.props.title} | ||||
|                 {...this.props} /> | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
|  | @ -18,22 +18,16 @@ limitations under the License. | |||
| 
 | ||||
| var React = require('react'); | ||||
| var Avatar = require('../../../Avatar'); | ||||
| var MatrixClientPeg = require('../../../MatrixClientPeg'); | ||||
| var sdk = require("../../../index"); | ||||
| 
 | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'MemberAvatar', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         member: React.PropTypes.object, | ||||
|         member: React.PropTypes.object.isRequired, | ||||
|         width: React.PropTypes.number, | ||||
|         height: React.PropTypes.number, | ||||
|         resizeMethod: React.PropTypes.string, | ||||
|         /** | ||||
|          * The custom display name to use for this member. This can serve as a | ||||
|          * drop in replacement for RoomMember objects, or as a clobber name on | ||||
|          * an existing RoomMember. Used for 3pid invites. | ||||
|          */ | ||||
|         customDisplayName: React.PropTypes.string | ||||
|         resizeMethod: React.PropTypes.string | ||||
|     }, | ||||
| 
 | ||||
|     getDefaultProps: function() { | ||||
|  | @ -45,77 +39,29 @@ module.exports = React.createClass({ | |||
|     }, | ||||
| 
 | ||||
|     getInitialState: function() { | ||||
|         var defaultImageUrl = Avatar.defaultAvatarUrlForString( | ||||
|             this.props.customDisplayName || this.props.member.userId | ||||
|         ) | ||||
|         return { | ||||
|             imageUrl: this._getMemberImageUrl() || defaultImageUrl, | ||||
|             defaultImageUrl: defaultImageUrl | ||||
|         }; | ||||
|         return this._getState(this.props); | ||||
|     }, | ||||
| 
 | ||||
|     componentWillReceiveProps: function(nextProps) { | ||||
|         this.refreshUrl(); | ||||
|         this.setState(this._getState(nextProps)); | ||||
|     }, | ||||
| 
 | ||||
|     onError: function(ev) { | ||||
|         // don't tightloop if the browser can't load a data url
 | ||||
|         if (ev.target.src == this.state.defaultImageUrl) { | ||||
|             return; | ||||
|         } | ||||
|         this.setState({ | ||||
|             imageUrl: this.state.defaultImageUrl | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
|     _getMemberImageUrl: function() { | ||||
|         if (!this.props.member) { return null; } | ||||
| 
 | ||||
|         return Avatar.avatarUrlForMember(this.props.member, | ||||
|                                          this.props.width, | ||||
|                                          this.props.height, | ||||
|                                          this.props.resizeMethod); | ||||
|     }, | ||||
| 
 | ||||
|     _getInitialLetter: function() { | ||||
|         var name = this.props.customDisplayName || this.props.member.name; | ||||
|         var initial = name[0]; | ||||
|         if (initial === '@' && name[1]) { | ||||
|             initial = name[1]; | ||||
|         } | ||||
|         return initial.toUpperCase(); | ||||
|     }, | ||||
| 
 | ||||
|     refreshUrl: function() { | ||||
|         var newUrl = this._getMemberImageUrl(); | ||||
|         if (newUrl != this.currentUrl) { | ||||
|             this.currentUrl = newUrl; | ||||
|             this.setState({imageUrl: newUrl}); | ||||
|     _getState: function(props) { | ||||
|         return { | ||||
|             name: props.member.name, | ||||
|             title: props.member.userId, | ||||
|             imageUrl: Avatar.avatarUrlForMember(props.member, | ||||
|                                          props.width, | ||||
|                                          props.height, | ||||
|                                          props.resizeMethod) | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var name = this.props.customDisplayName || this.props.member.name; | ||||
| 
 | ||||
|         if (this.state.imageUrl === this.state.defaultImageUrl) { | ||||
|             var initialLetter = this._getInitialLetter(); | ||||
|             return ( | ||||
|                 <span className="mx_MemberAvatar" {...this.props}> | ||||
|                     <span className="mx_MemberAvatar_initial" aria-hidden="true" | ||||
|                           style={{ fontSize: (this.props.width * 0.65) + "px", | ||||
|                                    width: this.props.width + "px", | ||||
|                                    lineHeight: this.props.height + "px" }}>{ initialLetter }</span> | ||||
|                     <img className="mx_MemberAvatar_image" src={this.state.imageUrl} title={name} | ||||
|                          onError={this.onError} width={this.props.width} height={this.props.height} /> | ||||
|                 </span> | ||||
|             );             | ||||
|         } | ||||
|         var BaseAvatar = sdk.getComponent("avatars.BaseAvatar"); | ||||
|         return ( | ||||
|             <img className="mx_MemberAvatar mx_MemberAvatar_image" src={this.state.imageUrl} | ||||
|                 onError={this.onError} | ||||
|                 width={this.props.width} height={this.props.height} | ||||
|                 title={name} | ||||
|                 {...this.props} /> | ||||
|             <BaseAvatar {...this.props} name={this.state.name} title={this.state.title} | ||||
|                 idName={this.props.member.userId} url={this.state.imageUrl} /> | ||||
|         ); | ||||
|     } | ||||
| }); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Kegan Dougal
						Kegan Dougal