make all height changes update component state

also set visibleTiles as side-effect
pull/21833/head
Bruno Windels 2020-07-10 18:36:33 +02:00
parent 652fb9e613
commit 96f2968854
1 changed files with 22 additions and 24 deletions

View File

@ -110,7 +110,7 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
super(props); super(props);
this.layout = RoomListLayoutStore.instance.getLayoutFor(this.props.tagId); this.layout = RoomListLayoutStore.instance.getLayoutFor(this.props.tagId);
this.heightAtStart = 0;
const height = this.calculateInitialHeight(); const height = this.calculateInitialHeight();
this.state = { this.state = {
notificationState: RoomNotificationStateStore.instance.getListState(this.props.tagId), notificationState: RoomNotificationStateStore.instance.getListState(this.props.tagId),
@ -184,47 +184,45 @@ export default class RoomSublist2 extends React.Component<IProps, IState> {
if (this.props.onAddRoom) this.props.onAddRoom(); if (this.props.onAddRoom) this.props.onAddRoom();
}; };
private applyHeightChange(newHeight: number) {
const heightInTiles = Math.ceil(this.layout.pixelsToTiles(newHeight - this.padding));
this.layout.visibleTiles = Math.min(this.numTiles, heightInTiles);
}
private onResize = ( private onResize = (
e: MouseEvent | TouchEvent, e: MouseEvent | TouchEvent,
travelDirection: Direction, travelDirection: Direction,
refToElement: HTMLDivElement, refToElement: HTMLDivElement,
delta: ResizeDelta, delta: ResizeDelta,
) => { ) => {
// Do some sanity checks, but in reality we shouldn't need these. const newHeight = this.heightAtStart + delta.height;
if (travelDirection !== "bottom") return; this.applyHeightChange(newHeight);
if (delta.height === 0) return; // something went wrong, so just ignore it. this.setState({height: newHeight});
// NOTE: the movement in the MouseEvent (not present on a TouchEvent) is inaccurate
// for our purposes. The delta provided by the library is also a change *from when
// resizing started*, meaning it is fairly useless for us. This is why we just use
// the client height and run with it.
const heightBefore = this.layout.visibleTiles;
const heightInTiles = this.layout.pixelsToTiles(refToElement.clientHeight);
this.layout.setVisibleTilesWithin(heightInTiles, this.numTiles);
if (heightBefore === this.layout.visibleTiles) return; // no-op
this.forceUpdate(); // because the layout doesn't trigger a re-render
}; };
private onResizeStart = () => { private onResizeStart = () => {
this.heightAtStart = this.state.height;
this.setState({isResizing: true}); this.setState({isResizing: true});
}; };
private onResizeStop = () => { private onResizeStop = (e, direction, ref, d) => {
this.setState({isResizing: false}); const newHeight = this.heightAtStart + d.height;
this.applyHeightChange(newHeight);
this.setState({isResizing: false, height: newHeight});
}; };
private onShowAllClick = () => { private onShowAllClick = () => {
const numVisibleTiles = this.numVisibleTiles; const newHeight = this.layout.tilesToPixelsWithPadding(this.numTiles, this.padding);
this.layout.visibleTiles = this.layout.tilesWithPadding(this.numTiles, MAX_PADDING_HEIGHT); this.applyHeightChange(newHeight);
this.forceUpdate(); // because the layout doesn't trigger a re-render this.setState({height: newHeight}, () => {
setImmediate(this.focusRoomTile, numVisibleTiles); // focus the tile after the current bottom one this.focusRoomTile(this.numTiles - 1);
});
}; };
private onShowLessClick = () => { private onShowLessClick = () => {
this.layout.visibleTiles = this.layout.defaultVisibleTiles; const newHeight = this.layout.tilesToPixelsWithPadding(this.layout.defaultVisibleTiles, this.padding);
this.forceUpdate(); // because the layout doesn't trigger a re-render this.applyHeightChange(newHeight);
// focus will flow to the show more button here this.setState({height: newHeight});
}; };
private focusRoomTile = (index: number) => { private focusRoomTile = (index: number) => {