forked from matrix/element-web
Merge pull request #5015 from vector-im/dbkr/active_room_observer
Avoid re-rendering RoomList on room switch
This commit is contained in:
commit
f18f13643f
|
@ -30,13 +30,14 @@ import VectorConferenceHandler from '../../VectorConferenceHandler';
|
||||||
var LeftPanel = React.createClass({
|
var LeftPanel = React.createClass({
|
||||||
displayName: 'LeftPanel',
|
displayName: 'LeftPanel',
|
||||||
|
|
||||||
|
// NB. If you add props, don't forget to update
|
||||||
|
// shouldComponentUpdate!
|
||||||
propTypes: {
|
propTypes: {
|
||||||
collapsed: React.PropTypes.bool.isRequired,
|
collapsed: React.PropTypes.bool.isRequired,
|
||||||
},
|
},
|
||||||
|
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
showCallElement: null,
|
|
||||||
searchFilter: '',
|
searchFilter: '',
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -45,26 +46,25 @@ var LeftPanel = React.createClass({
|
||||||
this.focusedElement = null;
|
this.focusedElement = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
shouldComponentUpdate: function(nextProps, nextState) {
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
// MatrixChat will update whenever the user switches
|
||||||
},
|
// rooms, but propagating this change all the way down
|
||||||
|
// the react tree is quite slow, so we cut this off
|
||||||
componentWillReceiveProps: function(newProps) {
|
// here. The RoomTiles listen for the room change
|
||||||
this._recheckCallElement(newProps.selectedRoom);
|
// events themselves to know when to update.
|
||||||
},
|
// We just need to update if any of these things change.
|
||||||
|
if (
|
||||||
componentWillUnmount: function() {
|
this.props.collapsed !== nextProps.collapsed ||
|
||||||
dis.unregister(this.dispatcherRef);
|
this.props.opacity !== nextProps.opacity
|
||||||
},
|
) {
|
||||||
|
return true;
|
||||||
onAction: function(payload) {
|
|
||||||
switch (payload.action) {
|
|
||||||
// listen for call state changes to prod the render method, which
|
|
||||||
// may hide the global CallView if the call it is tracking is dead
|
|
||||||
case 'call_state':
|
|
||||||
this._recheckCallElement(this.props.selectedRoom);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.state.searchFilter !== nextState.searchFilter) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
},
|
},
|
||||||
|
|
||||||
_onFocus: function(ev) {
|
_onFocus: function(ev) {
|
||||||
|
@ -152,74 +152,41 @@ var LeftPanel = React.createClass({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_recheckCallElement: function(selectedRoomId) {
|
|
||||||
// if we aren't viewing a room with an ongoing call, but there is an
|
|
||||||
// active call, show the call element - we need to do this to make
|
|
||||||
// audio/video not crap out
|
|
||||||
var activeCall = CallHandler.getAnyActiveCall();
|
|
||||||
var callForRoom = CallHandler.getCallForRoom(selectedRoomId);
|
|
||||||
var showCall = (activeCall && activeCall.call_state === 'connected' && !callForRoom);
|
|
||||||
this.setState({
|
|
||||||
showCallElement: showCall
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
onHideClick: function() {
|
onHideClick: function() {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'hide_left_panel',
|
action: 'hide_left_panel',
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
onCallViewClick: function() {
|
|
||||||
var call = CallHandler.getAnyActiveCall();
|
|
||||||
if (call) {
|
|
||||||
dis.dispatch({
|
|
||||||
action: 'view_room',
|
|
||||||
room_id: call.groupRoomId || call.roomId,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
onSearch: function(term) {
|
onSearch: function(term) {
|
||||||
this.setState({ searchFilter: term });
|
this.setState({ searchFilter: term });
|
||||||
},
|
},
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
var RoomList = sdk.getComponent('rooms.RoomList');
|
const RoomList = sdk.getComponent('rooms.RoomList');
|
||||||
var BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
|
const BottomLeftMenu = sdk.getComponent('structures.BottomLeftMenu');
|
||||||
|
const CallPreview = sdk.getComponent('voip.CallPreview');
|
||||||
|
|
||||||
var topBox;
|
let topBox;
|
||||||
if (MatrixClientPeg.get().isGuest()) {
|
if (MatrixClientPeg.get().isGuest()) {
|
||||||
var LoginBox = sdk.getComponent('structures.LoginBox');
|
const LoginBox = sdk.getComponent('structures.LoginBox');
|
||||||
topBox = <LoginBox collapsed={ this.props.collapsed }/>;
|
topBox = <LoginBox collapsed={ this.props.collapsed }/>;
|
||||||
}
|
} else {
|
||||||
else {
|
const SearchBox = sdk.getComponent('structures.SearchBox');
|
||||||
var SearchBox = sdk.getComponent('structures.SearchBox');
|
|
||||||
topBox = <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />;
|
topBox = <SearchBox collapsed={ this.props.collapsed } onSearch={ this.onSearch } />;
|
||||||
}
|
}
|
||||||
|
|
||||||
var classes = "mx_LeftPanel mx_fadable";
|
let classes = "mx_LeftPanel mx_fadable";
|
||||||
if (this.props.collapsed) {
|
if (this.props.collapsed) {
|
||||||
classes += " collapsed";
|
classes += " collapsed";
|
||||||
}
|
}
|
||||||
|
|
||||||
var callPreview;
|
|
||||||
if (this.state.showCallElement && !this.props.collapsed) {
|
|
||||||
var CallView = sdk.getComponent('voip.CallView');
|
|
||||||
callPreview = (
|
|
||||||
<CallView
|
|
||||||
className="mx_LeftPanel_callView" showVoice={true} onClick={this.onCallViewClick}
|
|
||||||
ConferenceHandler={VectorConferenceHandler} />
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<aside className={classes} style={{ opacity: this.props.opacity }}
|
<aside className={classes} style={{ opacity: this.props.opacity }}
|
||||||
onKeyDown={ this._onKeyDown } onFocus={ this._onFocus } onBlur={ this._onBlur }>
|
onKeyDown={ this._onKeyDown } onFocus={ this._onFocus } onBlur={ this._onBlur }>
|
||||||
{ topBox }
|
{ topBox }
|
||||||
{ callPreview }
|
<CallPreview ConferenceHandler={VectorConferenceHandler} />
|
||||||
<RoomList
|
<RoomList
|
||||||
selectedRoom={this.props.selectedRoom}
|
|
||||||
collapsed={this.props.collapsed}
|
collapsed={this.props.collapsed}
|
||||||
searchFilter={this.state.searchFilter}
|
searchFilter={this.state.searchFilter}
|
||||||
ConferenceHandler={VectorConferenceHandler} />
|
ConferenceHandler={VectorConferenceHandler} />
|
||||||
|
|
|
@ -75,9 +75,6 @@ var RoomSubList = React.createClass({
|
||||||
|
|
||||||
order: React.PropTypes.string.isRequired,
|
order: React.PropTypes.string.isRequired,
|
||||||
|
|
||||||
// undefined if no room is selected (eg we are showing settings)
|
|
||||||
selectedRoom: React.PropTypes.string,
|
|
||||||
|
|
||||||
// passed through to RoomTile and used to highlight room with `!` regardless of notifications count
|
// passed through to RoomTile and used to highlight room with `!` regardless of notifications count
|
||||||
isInvite: React.PropTypes.bool,
|
isInvite: React.PropTypes.bool,
|
||||||
|
|
||||||
|
@ -370,7 +367,6 @@ var RoomSubList = React.createClass({
|
||||||
var self = this;
|
var self = this;
|
||||||
var DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
|
var DNDRoomTile = sdk.getComponent("rooms.DNDRoomTile");
|
||||||
return this.state.sortedList.map(function(room) {
|
return this.state.sortedList.map(function(room) {
|
||||||
var selected = room.roomId == self.props.selectedRoom;
|
|
||||||
// XXX: is it evil to pass in self as a prop to RoomTile?
|
// XXX: is it evil to pass in self as a prop to RoomTile?
|
||||||
return (
|
return (
|
||||||
<DNDRoomTile
|
<DNDRoomTile
|
||||||
|
@ -378,7 +374,6 @@ var RoomSubList = React.createClass({
|
||||||
roomSubList={ self }
|
roomSubList={ self }
|
||||||
key={ room.roomId }
|
key={ room.roomId }
|
||||||
collapsed={ self.props.collapsed || false}
|
collapsed={ self.props.collapsed || false}
|
||||||
selected={ selected }
|
|
||||||
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
unread={ Unread.doesRoomHaveUnreadMessages(room) }
|
||||||
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.isInvite }
|
highlight={ room.getUnreadNotificationCount('highlight') > 0 || self.props.isInvite }
|
||||||
isInvite={ self.props.isInvite }
|
isInvite={ self.props.isInvite }
|
||||||
|
|
Loading…
Reference in New Issue