Merge pull request #4809 from matrix-org/travis/room-list/headers-resize
Fix sticky headers over/under extending themselves in the new room list
This commit is contained in:
commit
6dd20d80a3
3 changed files with 49 additions and 12 deletions
|
@ -19,7 +19,6 @@ import TagPanel from "./TagPanel";
|
||||||
import classNames from "classnames";
|
import classNames from "classnames";
|
||||||
import dis from "../../dispatcher/dispatcher";
|
import dis from "../../dispatcher/dispatcher";
|
||||||
import { _t } from "../../languageHandler";
|
import { _t } from "../../languageHandler";
|
||||||
import SearchBox from "./SearchBox";
|
|
||||||
import RoomList2 from "../views/rooms/RoomList2";
|
import RoomList2 from "../views/rooms/RoomList2";
|
||||||
import { Action } from "../../dispatcher/actions";
|
import { Action } from "../../dispatcher/actions";
|
||||||
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
import { MatrixClientPeg } from "../../MatrixClientPeg";
|
||||||
|
@ -30,6 +29,8 @@ import AccessibleButton from "../views/elements/AccessibleButton";
|
||||||
import RoomBreadcrumbs2 from "../views/rooms/RoomBreadcrumbs2";
|
import RoomBreadcrumbs2 from "../views/rooms/RoomBreadcrumbs2";
|
||||||
import { BreadcrumbsStore } from "../../stores/BreadcrumbsStore";
|
import { BreadcrumbsStore } from "../../stores/BreadcrumbsStore";
|
||||||
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
||||||
|
import ResizeNotifier from "../../utils/ResizeNotifier";
|
||||||
|
import { createRef } from "react";
|
||||||
|
|
||||||
/*******************************************************************
|
/*******************************************************************
|
||||||
* CAUTION *
|
* CAUTION *
|
||||||
|
@ -41,6 +42,7 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
isMinimized: boolean;
|
isMinimized: boolean;
|
||||||
|
resizeNotifier: ResizeNotifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
@ -49,6 +51,8 @@ interface IState {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class LeftPanel2 extends React.Component<IProps, IState> {
|
export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
|
private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
|
||||||
|
|
||||||
// TODO: Properly support TagPanel
|
// TODO: Properly support TagPanel
|
||||||
// TODO: Properly support searching/filtering
|
// TODO: Properly support searching/filtering
|
||||||
// TODO: Properly support breadcrumbs
|
// TODO: Properly support breadcrumbs
|
||||||
|
@ -65,10 +69,15 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
};
|
};
|
||||||
|
|
||||||
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
BreadcrumbsStore.instance.on(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
|
|
||||||
|
// We watch the middle panel because we don't actually get resized, the middle panel does.
|
||||||
|
// We listen to the noisy channel to avoid choppy reaction times.
|
||||||
|
this.props.resizeNotifier.on("middlePanelResizedNoisy", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
public componentWillUnmount() {
|
public componentWillUnmount() {
|
||||||
BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate);
|
||||||
|
this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private onSearch = (term: string): void => {
|
private onSearch = (term: string): void => {
|
||||||
|
@ -86,9 +95,7 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Apply this on resize, init, etc for reliability
|
private handleStickyHeaders(list: HTMLDivElement) {
|
||||||
private onScroll = (ev: React.MouseEvent<HTMLDivElement>) => {
|
|
||||||
const list = ev.target as HTMLDivElement;
|
|
||||||
const rlRect = list.getBoundingClientRect();
|
const rlRect = list.getBoundingClientRect();
|
||||||
const bottom = rlRect.bottom;
|
const bottom = rlRect.bottom;
|
||||||
const top = rlRect.top;
|
const top = rlRect.top;
|
||||||
|
@ -123,6 +130,18 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
header.style.top = `unset`;
|
header.style.top = `unset`;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Apply this on resize, init, etc for reliability
|
||||||
|
private onScroll = (ev: React.MouseEvent<HTMLDivElement>) => {
|
||||||
|
const list = ev.target as HTMLDivElement;
|
||||||
|
this.handleStickyHeaders(list);
|
||||||
|
};
|
||||||
|
|
||||||
|
private onResize = () => {
|
||||||
|
console.log("Resize width");
|
||||||
|
if (!this.listContainerRef.current) return; // ignore: no headers to sticky
|
||||||
|
this.handleStickyHeaders(this.listContainerRef.current);
|
||||||
};
|
};
|
||||||
|
|
||||||
private renderHeader(): React.ReactNode {
|
private renderHeader(): React.ReactNode {
|
||||||
|
@ -230,9 +249,11 @@ export default class LeftPanel2 extends React.Component<IProps, IState> {
|
||||||
<aside className="mx_LeftPanel2_roomListContainer">
|
<aside className="mx_LeftPanel2_roomListContainer">
|
||||||
{this.renderHeader()}
|
{this.renderHeader()}
|
||||||
{this.renderSearchExplore()}
|
{this.renderSearchExplore()}
|
||||||
<div className="mx_LeftPanel2_actualRoomListContainer" onScroll={this.onScroll}>
|
<div
|
||||||
{roomList}
|
className="mx_LeftPanel2_actualRoomListContainer"
|
||||||
</div>
|
onScroll={this.onScroll}
|
||||||
|
ref={this.listContainerRef}
|
||||||
|
>{roomList}</div>
|
||||||
</aside>
|
</aside>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
@ -677,7 +677,10 @@ class LoggedInView extends React.PureComponent<IProps, IState> {
|
||||||
if (SettingsStore.isFeatureEnabled("feature_new_room_list")) {
|
if (SettingsStore.isFeatureEnabled("feature_new_room_list")) {
|
||||||
// TODO: Supply props like collapsed and disabled to LeftPanel2
|
// TODO: Supply props like collapsed and disabled to LeftPanel2
|
||||||
leftPanel = (
|
leftPanel = (
|
||||||
<LeftPanel2 isMinimized={this.props.collapseLhs || false} />
|
<LeftPanel2
|
||||||
|
isMinimized={this.props.collapseLhs || false}
|
||||||
|
resizeNotifier={this.props.resizeNotifier}
|
||||||
|
/>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,9 +15,13 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fires when the middle panel has been resized.
|
* Fires when the middle panel has been resized (throttled).
|
||||||
* @event module:utils~ResizeNotifier#"middlePanelResized"
|
* @event module:utils~ResizeNotifier#"middlePanelResized"
|
||||||
*/
|
*/
|
||||||
|
/**
|
||||||
|
* Fires when the middle panel has been resized by a pixel.
|
||||||
|
* @event module:utils~ResizeNotifier#"middlePanelResizedNoisy"
|
||||||
|
*/
|
||||||
import { EventEmitter } from "events";
|
import { EventEmitter } from "events";
|
||||||
import { throttle } from "lodash";
|
import { throttle } from "lodash";
|
||||||
|
|
||||||
|
@ -29,15 +33,24 @@ export default class ResizeNotifier extends EventEmitter {
|
||||||
this._throttledMiddlePanel = throttle(() => this.emit("middlePanelResized"), 200);
|
this._throttledMiddlePanel = throttle(() => this.emit("middlePanelResized"), 200);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_noisyMiddlePanel() {
|
||||||
|
this.emit("middlePanelResizedNoisy");
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateMiddlePanel() {
|
||||||
|
this._throttledMiddlePanel();
|
||||||
|
this._noisyMiddlePanel();
|
||||||
|
}
|
||||||
|
|
||||||
// can be called in quick succession
|
// can be called in quick succession
|
||||||
notifyLeftHandleResized() {
|
notifyLeftHandleResized() {
|
||||||
// don't emit event for own region
|
// don't emit event for own region
|
||||||
this._throttledMiddlePanel();
|
this._updateMiddlePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be called in quick succession
|
// can be called in quick succession
|
||||||
notifyRightHandleResized() {
|
notifyRightHandleResized() {
|
||||||
this._throttledMiddlePanel();
|
this._updateMiddlePanel();
|
||||||
}
|
}
|
||||||
|
|
||||||
// can be called in quick succession
|
// can be called in quick succession
|
||||||
|
@ -48,7 +61,7 @@ export default class ResizeNotifier extends EventEmitter {
|
||||||
// taller than the available space
|
// taller than the available space
|
||||||
this.emit("leftPanelResized");
|
this.emit("leftPanelResized");
|
||||||
|
|
||||||
this._throttledMiddlePanel();
|
this._updateMiddlePanel();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue