Migrate RoomSubList to ES6 Class due to new/vs old React API incompat
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>pull/21833/head
parent
d22985f12e
commit
ff71f4ec8d
|
@ -18,7 +18,6 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, {createRef} from 'react';
|
import React, {createRef} from 'react';
|
||||||
import createReactClass from 'create-react-class';
|
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import sdk from '../../index';
|
import sdk from '../../index';
|
||||||
import dis from '../../dispatcher';
|
import dis from '../../dispatcher';
|
||||||
|
@ -36,12 +35,11 @@ import {_t} from "../../languageHandler";
|
||||||
// turn this on for drop & drag console debugging galore
|
// turn this on for drop & drag console debugging galore
|
||||||
const debug = false;
|
const debug = false;
|
||||||
|
|
||||||
const RoomSubList = createReactClass({
|
export default class RoomSubList extends React.PureComponent {
|
||||||
displayName: 'RoomSubList',
|
static displayName = 'RoomSubList';
|
||||||
|
static debug = debug;
|
||||||
|
|
||||||
debug: debug,
|
static propTypes = {
|
||||||
|
|
||||||
propTypes: {
|
|
||||||
list: PropTypes.arrayOf(PropTypes.object).isRequired,
|
list: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
label: PropTypes.string.isRequired,
|
label: PropTypes.string.isRequired,
|
||||||
tagName: PropTypes.string,
|
tagName: PropTypes.string,
|
||||||
|
@ -59,10 +57,26 @@ const RoomSubList = createReactClass({
|
||||||
incomingCall: PropTypes.object,
|
incomingCall: PropTypes.object,
|
||||||
extraTiles: PropTypes.arrayOf(PropTypes.node), // extra elements added beneath tiles
|
extraTiles: PropTypes.arrayOf(PropTypes.node), // extra elements added beneath tiles
|
||||||
forceExpand: PropTypes.bool,
|
forceExpand: PropTypes.bool,
|
||||||
},
|
};
|
||||||
|
|
||||||
getInitialState: function() {
|
static defaultProps = {
|
||||||
|
onHeaderClick: function() {
|
||||||
|
}, // NOP
|
||||||
|
extraTiles: [],
|
||||||
|
isInvite: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
static getDerivedStateFromProps(props, state) {
|
||||||
return {
|
return {
|
||||||
|
listLength: props.list.length,
|
||||||
|
scrollTop: props.list.length === state.listLength ? state.scrollTop : 0,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
|
||||||
|
this.state = {
|
||||||
hidden: this.props.startAsHidden || false,
|
hidden: this.props.startAsHidden || false,
|
||||||
// some values to get LazyRenderList starting
|
// some values to get LazyRenderList starting
|
||||||
scrollerHeight: 800,
|
scrollerHeight: 800,
|
||||||
|
@ -71,53 +85,33 @@ const RoomSubList = createReactClass({
|
||||||
// we have to store the length of the list here so we can see if it's changed or not...
|
// we have to store the length of the list here so we can see if it's changed or not...
|
||||||
listLength: null,
|
listLength: null,
|
||||||
};
|
};
|
||||||
},
|
|
||||||
|
|
||||||
getDefaultProps: function() {
|
|
||||||
return {
|
|
||||||
onHeaderClick: function() {
|
|
||||||
}, // NOP
|
|
||||||
extraTiles: [],
|
|
||||||
isInvite: false,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
|
|
||||||
UNSAFE_componentWillMount: function() {
|
|
||||||
this._header = createRef();
|
this._header = createRef();
|
||||||
this._subList = createRef();
|
this._subList = createRef();
|
||||||
this._scroller = createRef();
|
this._scroller = createRef();
|
||||||
this._headerButton = createRef();
|
this._headerButton = createRef();
|
||||||
},
|
}
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount() {
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
this.dispatcherRef = dis.register(this.onAction);
|
||||||
},
|
}
|
||||||
|
|
||||||
statics: {
|
componentWillUnmount() {
|
||||||
getDerivedStateFromProps: function(props, state) {
|
|
||||||
return {
|
|
||||||
listLength: props.list.length,
|
|
||||||
scrollTop: props.list.length === state.listLength ? state.scrollTop : 0,
|
|
||||||
};
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
|
||||||
dis.unregister(this.dispatcherRef);
|
dis.unregister(this.dispatcherRef);
|
||||||
},
|
}
|
||||||
|
|
||||||
// The header is collapsible if it is hidden or not stuck
|
// The header is collapsible if it is hidden or not stuck
|
||||||
// The dataset elements are added in the RoomList _initAndPositionStickyHeaders method
|
// The dataset elements are added in the RoomList _initAndPositionStickyHeaders method
|
||||||
isCollapsibleOnClick: function() {
|
isCollapsibleOnClick() {
|
||||||
const stuck = this._header.current.dataset.stuck;
|
const stuck = this._header.current.dataset.stuck;
|
||||||
if (!this.props.forceExpand && (this.state.hidden || stuck === undefined || stuck === "none")) {
|
if (!this.props.forceExpand && (this.state.hidden || stuck === undefined || stuck === "none")) {
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
|
|
||||||
onAction: function(payload) {
|
onAction = (payload) => {
|
||||||
// XXX: Previously RoomList would forceUpdate whenever on_room_read is dispatched,
|
// XXX: Previously RoomList would forceUpdate whenever on_room_read is dispatched,
|
||||||
// but this is no longer true, so we must do it here (and can apply the small
|
// but this is no longer true, so we must do it here (and can apply the small
|
||||||
// optimisation of checking that we care about the room being read).
|
// optimisation of checking that we care about the room being read).
|
||||||
|
@ -130,9 +124,9 @@ const RoomSubList = createReactClass({
|
||||||
) {
|
) {
|
||||||
this.forceUpdate();
|
this.forceUpdate();
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
onClick: function(ev) {
|
onClick = (ev) => {
|
||||||
if (this.isCollapsibleOnClick()) {
|
if (this.isCollapsibleOnClick()) {
|
||||||
// The header isCollapsible, so the click is to be interpreted as collapse and truncation logic
|
// The header isCollapsible, so the click is to be interpreted as collapse and truncation logic
|
||||||
const isHidden = !this.state.hidden;
|
const isHidden = !this.state.hidden;
|
||||||
|
@ -143,9 +137,9 @@ const RoomSubList = createReactClass({
|
||||||
// The header is stuck, so the click is to be interpreted as a scroll to the header
|
// The header is stuck, so the click is to be interpreted as a scroll to the header
|
||||||
this.props.onHeaderClick(this.state.hidden, this._header.current.dataset.originalPosition);
|
this.props.onHeaderClick(this.state.hidden, this._header.current.dataset.originalPosition);
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
onHeaderKeyDown: function(ev) {
|
onHeaderKeyDown = (ev) => {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
case Key.TAB:
|
case Key.TAB:
|
||||||
// Prevent LeftPanel handling Tab if focus is on the sublist header itself
|
// Prevent LeftPanel handling Tab if focus is on the sublist header itself
|
||||||
|
@ -173,9 +167,9 @@ const RoomSubList = createReactClass({
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
onKeyDown: function(ev) {
|
onKeyDown = (ev) => {
|
||||||
switch (ev.key) {
|
switch (ev.key) {
|
||||||
// On ARROW_LEFT go to the sublist header
|
// On ARROW_LEFT go to the sublist header
|
||||||
case Key.ARROW_LEFT:
|
case Key.ARROW_LEFT:
|
||||||
|
@ -186,24 +180,24 @@ const RoomSubList = createReactClass({
|
||||||
case Key.ARROW_RIGHT:
|
case Key.ARROW_RIGHT:
|
||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
onRoomTileClick(roomId, ev) {
|
onRoomTileClick = (roomId, ev) => {
|
||||||
dis.dispatch({
|
dis.dispatch({
|
||||||
action: 'view_room',
|
action: 'view_room',
|
||||||
room_id: roomId,
|
room_id: roomId,
|
||||||
clear_search: (ev && (ev.keyCode === KeyCode.ENTER || ev.keyCode === KeyCode.SPACE)),
|
clear_search: (ev && (ev.keyCode === KeyCode.ENTER || ev.keyCode === KeyCode.SPACE)),
|
||||||
});
|
});
|
||||||
},
|
};
|
||||||
|
|
||||||
_updateSubListCount: function() {
|
_updateSubListCount = () => {
|
||||||
// Force an update by setting the state to the current state
|
// Force an update by setting the state to the current state
|
||||||
// Doing it this way rather than using forceUpdate(), so that the shouldComponentUpdate()
|
// Doing it this way rather than using forceUpdate(), so that the shouldComponentUpdate()
|
||||||
// method is honoured
|
// method is honoured
|
||||||
this.setState(this.state);
|
this.setState(this.state);
|
||||||
},
|
};
|
||||||
|
|
||||||
makeRoomTile: function(room) {
|
makeRoomTile = (room) => {
|
||||||
return <RoomTile
|
return <RoomTile
|
||||||
room={room}
|
room={room}
|
||||||
roomSubList={this}
|
roomSubList={this}
|
||||||
|
@ -218,9 +212,9 @@ const RoomSubList = createReactClass({
|
||||||
incomingCall={null}
|
incomingCall={null}
|
||||||
onClick={this.onRoomTileClick}
|
onClick={this.onRoomTileClick}
|
||||||
/>;
|
/>;
|
||||||
},
|
};
|
||||||
|
|
||||||
_onNotifBadgeClick: function(e) {
|
_onNotifBadgeClick = (e) => {
|
||||||
// prevent the roomsublist collapsing
|
// prevent the roomsublist collapsing
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -231,9 +225,9 @@ const RoomSubList = createReactClass({
|
||||||
room_id: room.roomId,
|
room_id: room.roomId,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
_onInviteBadgeClick: function(e) {
|
_onInviteBadgeClick = (e) => {
|
||||||
// prevent the roomsublist collapsing
|
// prevent the roomsublist collapsing
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
@ -253,14 +247,14 @@ const RoomSubList = createReactClass({
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
onAddRoom: function(e) {
|
onAddRoom = (e) => {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
if (this.props.onAddRoom) this.props.onAddRoom();
|
if (this.props.onAddRoom) this.props.onAddRoom();
|
||||||
},
|
};
|
||||||
|
|
||||||
_getHeaderJsx: function(isCollapsed) {
|
_getHeaderJsx(isCollapsed) {
|
||||||
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
const AccessibleButton = sdk.getComponent('elements.AccessibleButton');
|
||||||
const AccessibleTooltipButton = sdk.getComponent('elements.AccessibleTooltipButton');
|
const AccessibleTooltipButton = sdk.getComponent('elements.AccessibleTooltipButton');
|
||||||
const subListNotifications = !this.props.isInvite ?
|
const subListNotifications = !this.props.isInvite ?
|
||||||
|
@ -352,36 +346,36 @@ const RoomSubList = createReactClass({
|
||||||
{ addRoomButton }
|
{ addRoomButton }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
|
|
||||||
checkOverflow: function() {
|
checkOverflow = () => {
|
||||||
if (this._scroller.current) {
|
if (this._scroller.current) {
|
||||||
this._scroller.current.checkOverflow();
|
this._scroller.current.checkOverflow();
|
||||||
}
|
}
|
||||||
},
|
};
|
||||||
|
|
||||||
setHeight: function(height) {
|
setHeight = (height) => {
|
||||||
if (this._subList.current) {
|
if (this._subList.current) {
|
||||||
this._subList.current.style.height = `${height}px`;
|
this._subList.current.style.height = `${height}px`;
|
||||||
}
|
}
|
||||||
this._updateLazyRenderHeight(height);
|
this._updateLazyRenderHeight(height);
|
||||||
},
|
};
|
||||||
|
|
||||||
_updateLazyRenderHeight: function(height) {
|
_updateLazyRenderHeight(height) {
|
||||||
this.setState({scrollerHeight: height});
|
this.setState({scrollerHeight: height});
|
||||||
},
|
}
|
||||||
|
|
||||||
_onScroll: function() {
|
_onScroll = () => {
|
||||||
this.setState({scrollTop: this._scroller.current.getScrollTop()});
|
this.setState({scrollTop: this._scroller.current.getScrollTop()});
|
||||||
},
|
};
|
||||||
|
|
||||||
_canUseLazyListRendering() {
|
_canUseLazyListRendering() {
|
||||||
// for now disable lazy rendering as they are already rendered tiles
|
// for now disable lazy rendering as they are already rendered tiles
|
||||||
// not rooms like props.list we pass to LazyRenderList
|
// not rooms like props.list we pass to LazyRenderList
|
||||||
return !this.props.extraTiles || !this.props.extraTiles.length;
|
return !this.props.extraTiles || !this.props.extraTiles.length;
|
||||||
},
|
}
|
||||||
|
|
||||||
render: function() {
|
render() {
|
||||||
const len = this.props.list.length + this.props.extraTiles.length;
|
const len = this.props.list.length + this.props.extraTiles.length;
|
||||||
const isCollapsed = this.state.hidden && !this.props.forceExpand;
|
const isCollapsed = this.state.hidden && !this.props.forceExpand;
|
||||||
|
|
||||||
|
@ -434,7 +428,5 @@ const RoomSubList = createReactClass({
|
||||||
{ content }
|
{ content }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
module.exports = RoomSubList;
|
|
||||||
|
|
Loading…
Reference in New Issue