mirror of https://github.com/vector-im/riot-web
				
				
				
			Define component directories. Merge MemberAvatar and RoomAvatar to new-style components.
Spoken to @ara4n about names/conventions. Settled on the following layout:
  src/components
      |_____________views
      |               |____ tiles
      |               |       |___ MTextTile.js
      |               |       |___ MNoticeTile.js
      |               |       |___ ...
      |               |
      |               |____ avatars
      |               |       |____ RoomAvatar.js
      |               |       |____ MemberAvatar.js
      |               |       |____ ...
      |               |
      |               |____ ...
      |
      |_____________structures
                      |____ RoomView.js
                      |____ UserSettings.js
                      |____ CreateRoom.js
                      |____ ...
Views are the "pure UI" components which can be reused. Structures are the
wire components which give important contextual information to the views e.g.
a view may be MemberList, but it's where it is in the structure that defines
that it is a *Room* MemberList.
			
			
				pull/21833/head
			
			
		
							parent
							
								
									f5e2a54603
								
							
						
					
					
						commit
						b69fff5b01
					
				|  | @ -17,9 +17,12 @@ limitations under the License. | |||
| 'use strict'; | ||||
| 
 | ||||
| var React = require('react'); | ||||
| var Avatar = require('../../../../Avatar'); | ||||
| var MatrixClientPeg = require('../../MatrixClientPeg'); | ||||
| 
 | ||||
| module.exports = { | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'MemberAvatar', | ||||
| 
 | ||||
|     propTypes: { | ||||
|         member: React.PropTypes.object.isRequired, | ||||
|         width: React.PropTypes.number, | ||||
|  | @ -87,5 +90,53 @@ module.exports = { | |||
|         return { | ||||
|             imageUrl: this._computeUrl() | ||||
|         }; | ||||
|     }, | ||||
| 
 | ||||
| 
 | ||||
|     ///////////////
 | ||||
| 
 | ||||
| 
 | ||||
|     avatarUrlForMember: function(member) { | ||||
|         return Avatar.avatarUrlForMember( | ||||
|             member, | ||||
|             this.props.member, | ||||
|             this.props.width, | ||||
|             this.props.height, | ||||
|             this.props.resizeMethod | ||||
|         ); | ||||
|     }, | ||||
| 
 | ||||
|     skinnedDefaultAvatarUrl: function(member, width, height, resizeMethod) { | ||||
|         return Avatar.defaultAvatarUrlForString(member.userId); | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         // XXX: recalculates default avatar url constantly
 | ||||
|         if (this.state.imageUrl === this.defaultAvatarUrl(this.props.member)) { | ||||
|             var initial; | ||||
|             if (this.props.member.name[0]) | ||||
|                 initial = this.props.member.name[0].toUpperCase(); | ||||
|             if (initial === '@' && this.props.member.name[1]) | ||||
|                 initial = this.props.member.name[1].toUpperCase(); | ||||
|           | ||||
|             return ( | ||||
|                 <span className="mx_MemberAvatar" {...this.props}> | ||||
|                     <span className="mx_MemberAvatar_initial" aria-hidden="true" | ||||
|                           style={{ fontSize: (this.props.width * 0.75) + "px", | ||||
|                                    width: this.props.width + "px", | ||||
|                                    lineHeight: this.props.height*1.2 + "px" }}>{ initial }</span> | ||||
|                     <img className="mx_MemberAvatar_image" src={this.state.imageUrl} title={this.props.member.name} | ||||
|                          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.member.name} | ||||
|                 {...this.props} | ||||
|             /> | ||||
|         ); | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | @ -13,18 +13,12 @@ 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 MatrixClientPeg = require('../../MatrixClientPeg'); | ||||
| 
 | ||||
| /* | ||||
|  * View class should provide: | ||||
|  * - getUrlList() returning an array of URLs to try for the room avatar | ||||
|      in order of preference from the most preferred at index 0. null entries | ||||
|      in the array will be skipped over. | ||||
|  */ | ||||
| module.exports = { | ||||
| module.exports = React.createClass({ | ||||
|     displayName: 'RoomAvatar', | ||||
| 
 | ||||
|     getDefaultProps: function() { | ||||
|         return { | ||||
|             width: 36, | ||||
|  | @ -124,5 +118,58 @@ module.exports = { | |||
|         this.setState({ | ||||
|             imageUrl: this._nextUrl() | ||||
|         }); | ||||
|     }, | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|     ////////////
 | ||||
| 
 | ||||
| 
 | ||||
|     getUrlList: function() { | ||||
|         return [ | ||||
|             this.roomAvatarUrl(), | ||||
|             this.getOneToOneAvatar(), | ||||
|             this.getFallbackAvatar() | ||||
|         ]; | ||||
|     }, | ||||
| 
 | ||||
|     getFallbackAvatar: function() { | ||||
|         var images = [ '76cfa6', '50e2c2', 'f4c371' ]; | ||||
|         var total = 0; | ||||
|         for (var i = 0; i < this.props.room.roomId.length; ++i) { | ||||
|             total += this.props.room.roomId.charCodeAt(i); | ||||
|         } | ||||
|         return 'img/' + images[total % images.length] + '.png'; | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var style = { | ||||
|             width: this.props.width, | ||||
|             height: this.props.height, | ||||
|         }; | ||||
| 
 | ||||
|         // XXX: recalculates fallback avatar constantly
 | ||||
|         if (this.state.imageUrl === this.getFallbackAvatar()) { | ||||
|             var initial; | ||||
|             if (this.props.room.name[0]) | ||||
|                 initial = this.props.room.name[0].toUpperCase(); | ||||
|             if ((initial === '@' || initial === '#') && this.props.room.name[1]) | ||||
|                 initial = this.props.room.name[1].toUpperCase(); | ||||
|           | ||||
|             return ( | ||||
|                 <span> | ||||
|                     <span className="mx_RoomAvatar_initial" aria-hidden="true" | ||||
|                           style={{ fontSize: (this.props.width * 0.75) + "px", | ||||
|                                    width: this.props.width + "px", | ||||
|                                    lineHeight: this.props.height*1.2 + "px" }}>{ initial }</span> | ||||
|                     <img className="mx_RoomAvatar" src={this.state.imageUrl} | ||||
|                             onError={this.onError} style={style} /> | ||||
|                 </span> | ||||
|             ); | ||||
|         } | ||||
|         else { | ||||
|             return <img className="mx_RoomAvatar" src={this.state.imageUrl} | ||||
|                         onError={this.onError} style={style} /> | ||||
|         } | ||||
|     } | ||||
| }; | ||||
| }); | ||||
|  | @ -1,27 +0,0 @@ | |||
| /* | ||||
| 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 dis = require("../../dispatcher"); | ||||
| 
 | ||||
| module.exports = { | ||||
|     onClick: function() { | ||||
|         dis.dispatch({ | ||||
|             action: 'view_user_settings' | ||||
|         }); | ||||
|     }, | ||||
| }; | ||||
		Loading…
	
		Reference in New Issue
	
	 Kegan Dougal
						Kegan Dougal