track RoomTile focus in RoomList, and stop the RoomList from updating during mouseOver
							parent
							
								
									0a91511f05
								
							
						
					
					
						commit
						691639d1e0
					
				|  | @ -63,12 +63,15 @@ module.exports = React.createClass({ | |||
| 
 | ||||
|         var s = this.getRoomLists(); | ||||
|         this.setState(s); | ||||
| 
 | ||||
|         this.focusedRoomTileRoomId = null; | ||||
|     }, | ||||
| 
 | ||||
|     componentDidMount: function() { | ||||
|         this.dispatcherRef = dis.register(this.onAction); | ||||
|         // Initialise the stickyHeaders when the component is created
 | ||||
|         this._updateStickyHeaders(true); | ||||
|         document.addEventListener('keydown', this._onKeyDown); | ||||
|     }, | ||||
| 
 | ||||
|     componentDidUpdate: function() { | ||||
|  | @ -100,6 +103,8 @@ module.exports = React.createClass({ | |||
|                 // Force an update because the notif count state is too deep to cause
 | ||||
|                 // an update. This forces the local echo of reading notifs to be
 | ||||
|                 // reflected by the RoomTiles.
 | ||||
|                 //
 | ||||
|                 // FIXME: we should surely just be refreshing the right tile...
 | ||||
|                 this.forceUpdate(); | ||||
|                 break; | ||||
|         } | ||||
|  | @ -120,6 +125,8 @@ module.exports = React.createClass({ | |||
|         } | ||||
|         // cancel any pending calls to the rate_limited_funcs
 | ||||
|         this._delayedRefreshRoomList.cancelPendingCall(); | ||||
|         document.removeEventListener('keydown', this._onKeyDown); | ||||
| 
 | ||||
|     }, | ||||
| 
 | ||||
|     onRoom: function(room) { | ||||
|  | @ -149,6 +156,35 @@ module.exports = React.createClass({ | |||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     _onMouseOver: function(ev) { | ||||
|         this._lastMouseOverTs = Date.now(); | ||||
|     }, | ||||
| 
 | ||||
|     _onKeyDown: function(ev) { | ||||
|         if (!this.focusedRoomTileRoomId) return; | ||||
|         let handled = false; | ||||
| 
 | ||||
|         switch (ev.keyCode) { | ||||
|             case KeyCode.UP: | ||||
|                 this._onMoveFocus(true); | ||||
|                 handled = true; | ||||
|                 break; | ||||
|             case KeyCode.DOWN: | ||||
|                 this._onMoveFocus(false); | ||||
|                 handled = true; | ||||
|                 break; | ||||
|         } | ||||
| 
 | ||||
|         if (handled) { | ||||
|             ev.stopPropagation(); | ||||
|             ev.preventDefault(); | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     _onMoveFocus: function(up) { | ||||
| 
 | ||||
|     }, | ||||
| 
 | ||||
|     onSubListHeaderClick: function(isHidden, scrollToPosition) { | ||||
|         // The scroll area has expanded or contracted, so re-calculate sticky headers positions
 | ||||
|         this._updateStickyHeaders(true, scrollToPosition); | ||||
|  | @ -192,7 +228,15 @@ module.exports = React.createClass({ | |||
|     }, | ||||
| 
 | ||||
|     _delayedRefreshRoomList: new rate_limited_func(function() { | ||||
|         this.refreshRoomList(); | ||||
|         // if the mouse has been moving over the RoomList in the last 500ms
 | ||||
|         // then delay the refresh further to avoid bouncing around under the
 | ||||
|         // cursor
 | ||||
|         if (Date.now() - this._lastMouseOverTs > 500) { | ||||
|             this.refreshRoomList(); | ||||
|         } | ||||
|         else { | ||||
|             this._delayedRefreshRoomList(); | ||||
|         } | ||||
|     }, 500), | ||||
| 
 | ||||
|     refreshRoomList: function() { | ||||
|  | @ -207,7 +251,8 @@ module.exports = React.createClass({ | |||
|         // us re-rendering all the sublists every time anything changes anywhere
 | ||||
|         // in the state of the client.
 | ||||
|         this.setState(this.getRoomLists()); | ||||
|         this._lastRefreshRoomListTs = Date.now(); | ||||
|          | ||||
|         // this._lastRefreshRoomListTs = Date.now();
 | ||||
|     }, | ||||
| 
 | ||||
|     getRoomLists: function() { | ||||
|  | @ -457,6 +502,10 @@ module.exports = React.createClass({ | |||
|         this.refs.gemscroll.forceUpdate(); | ||||
|     }, | ||||
| 
 | ||||
|     onRoomTileFocus: function(roomId) { | ||||
|         this.focusedRoomTileRoomId = roomId; | ||||
|     }, | ||||
| 
 | ||||
|     render: function() { | ||||
|         var RoomSubList = sdk.getComponent('structures.RoomSubList'); | ||||
|         var self = this; | ||||
|  | @ -464,7 +513,7 @@ module.exports = React.createClass({ | |||
|         return ( | ||||
|             <GeminiScrollbar className="mx_RoomList_scrollbar" | ||||
|                  autoshow={true} onScroll={ self._whenScrolling } ref="gemscroll"> | ||||
|             <div className="mx_RoomList"> | ||||
|             <div className="mx_RoomList" onMouseOver={ this._onMouseOver }> | ||||
|                 <RoomSubList list={ self.state.lists['im.vector.fake.invite'] } | ||||
|                              label="Invites" | ||||
|                              editable={ false } | ||||
|  | @ -474,6 +523,7 @@ module.exports = React.createClass({ | |||
|                              collapsed={ self.props.collapsed } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
| 
 | ||||
|                 <RoomSubList list={ self.state.lists['m.favourite'] } | ||||
|  | @ -487,6 +537,7 @@ module.exports = React.createClass({ | |||
|                              collapsed={ self.props.collapsed } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
| 
 | ||||
|                 <RoomSubList list={ self.state.lists['im.vector.fake.direct'] } | ||||
|  | @ -501,6 +552,7 @@ module.exports = React.createClass({ | |||
|                              alwaysShowHeader={ true } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
| 
 | ||||
|                 <RoomSubList list={ self.state.lists['im.vector.fake.recent'] } | ||||
|  | @ -513,6 +565,7 @@ module.exports = React.createClass({ | |||
|                              collapsed={ self.props.collapsed } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
| 
 | ||||
|                 { Object.keys(self.state.lists).map(function(tagName) { | ||||
|  | @ -529,6 +582,7 @@ module.exports = React.createClass({ | |||
|                              collapsed={ self.props.collapsed } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } />; | ||||
| 
 | ||||
|                     } | ||||
|  | @ -545,6 +599,7 @@ module.exports = React.createClass({ | |||
|                              collapsed={ self.props.collapsed } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onHeaderClick={ self.onSubListHeaderClick } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
| 
 | ||||
|                 <RoomSubList list={ self.state.lists['im.vector.fake.archived'] } | ||||
|  | @ -559,6 +614,7 @@ module.exports = React.createClass({ | |||
|                              onHeaderClick= { self.onArchivedHeaderClick } | ||||
|                              incomingCall={ self.state.incomingCall } | ||||
|                              searchFilter={ self.props.searchFilter } | ||||
|                              onRoomTileFocus={ self.onRoomTileFocus } | ||||
|                              onShowMoreRooms={ self.onShowMoreRooms } /> | ||||
|             </div> | ||||
|             </GeminiScrollbar> | ||||
|  |  | |||
|  | @ -35,6 +35,7 @@ module.exports = React.createClass({ | |||
|         connectDragSource: React.PropTypes.func, | ||||
|         connectDropTarget: React.PropTypes.func, | ||||
|         onClick: React.PropTypes.func, | ||||
|         onFocus: React.PropTypes.func, | ||||
|         isDragging: React.PropTypes.bool, | ||||
| 
 | ||||
|         room: React.PropTypes.object.isRequired, | ||||
|  | @ -104,6 +105,12 @@ module.exports = React.createClass({ | |||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     onFocus: function() { | ||||
|         if (this.props.onFocus) { | ||||
|             this.props.onFocus(this.props.room.roomId); | ||||
|         } | ||||
|     }, | ||||
| 
 | ||||
|     onMouseEnter: function() { | ||||
|         this.setState( { hover : true }); | ||||
|         this.badgeOnMouseEnter(); | ||||
|  | @ -255,7 +262,9 @@ module.exports = React.createClass({ | |||
| 
 | ||||
|         let ret = ( | ||||
|             <div> { /* Only native elements can be wrapped in a DnD object. */} | ||||
|             <AccessibleButton className={classes} tabIndex="0" onClick={this.onClick} onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave}> | ||||
|             <AccessibleButton className={classes} tabIndex="0" onClick={this.onClick} | ||||
|                               onMouseEnter={this.onMouseEnter} onMouseLeave={this.onMouseLeave} | ||||
|                               onFocus={this.onFocus} onBlur={this.onFocus.bind(this, null)}> | ||||
|                 <div className={avatarClasses}> | ||||
|                     <div className="mx_RoomTile_avatar_container"> | ||||
|                         <RoomAvatar room={this.props.room} width={24} height={24} /> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Matthew Hodgson
						Matthew Hodgson