From 1a427b8ff78522f48d9ca885d277da68b4010363 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 22 Jun 2020 13:09:42 -0600 Subject: [PATCH] Fix sticky headers over/under extending themselves in the new room list Fixes https://github.com/vector-im/riot-web/issues/14095 --- src/components/structures/LeftPanel2.tsx | 35 +++++++++++++++++----- src/components/structures/LoggedInView.tsx | 5 +++- src/utils/ResizeNotifier.js | 21 ++++++++++--- 3 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/components/structures/LeftPanel2.tsx b/src/components/structures/LeftPanel2.tsx index b5da44caef..378a24a70e 100644 --- a/src/components/structures/LeftPanel2.tsx +++ b/src/components/structures/LeftPanel2.tsx @@ -19,7 +19,6 @@ import TagPanel from "./TagPanel"; import classNames from "classnames"; import dis from "../../dispatcher/dispatcher"; import { _t } from "../../languageHandler"; -import SearchBox from "./SearchBox"; import RoomList2 from "../views/rooms/RoomList2"; import { Action } from "../../dispatcher/actions"; import { MatrixClientPeg } from "../../MatrixClientPeg"; @@ -30,6 +29,8 @@ import AccessibleButton from "../views/elements/AccessibleButton"; import RoomBreadcrumbs2 from "../views/rooms/RoomBreadcrumbs2"; import { BreadcrumbsStore } from "../../stores/BreadcrumbsStore"; import { UPDATE_EVENT } from "../../stores/AsyncStore"; +import ResizeNotifier from "../../utils/ResizeNotifier"; +import { createRef } from "react"; /******************************************************************* * CAUTION * @@ -41,6 +42,7 @@ import { UPDATE_EVENT } from "../../stores/AsyncStore"; interface IProps { isMinimized: boolean; + resizeNotifier: ResizeNotifier; } interface IState { @@ -49,6 +51,8 @@ interface IState { } export default class LeftPanel2 extends React.Component { + private listContainerRef: React.RefObject = createRef(); + // TODO: Properly support TagPanel // TODO: Properly support searching/filtering // TODO: Properly support breadcrumbs @@ -65,10 +69,15 @@ export default class LeftPanel2 extends React.Component { }; 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() { BreadcrumbsStore.instance.off(UPDATE_EVENT, this.onBreadcrumbsUpdate); + this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize); } private onSearch = (term: string): void => { @@ -86,9 +95,7 @@ export default class LeftPanel2 extends React.Component { } }; - // TODO: Apply this on resize, init, etc for reliability - private onScroll = (ev: React.MouseEvent) => { - const list = ev.target as HTMLDivElement; + private handleStickyHeaders(list: HTMLDivElement) { const rlRect = list.getBoundingClientRect(); const bottom = rlRect.bottom; const top = rlRect.top; @@ -123,6 +130,18 @@ export default class LeftPanel2 extends React.Component { header.style.top = `unset`; } } + } + + // TODO: Apply this on resize, init, etc for reliability + private onScroll = (ev: React.MouseEvent) => { + 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 { @@ -230,9 +249,11 @@ export default class LeftPanel2 extends React.Component { ); diff --git a/src/components/structures/LoggedInView.tsx b/src/components/structures/LoggedInView.tsx index f37f77b31b..1bc656e6a3 100644 --- a/src/components/structures/LoggedInView.tsx +++ b/src/components/structures/LoggedInView.tsx @@ -677,7 +677,10 @@ class LoggedInView extends React.PureComponent { if (SettingsStore.isFeatureEnabled("feature_new_room_list")) { // TODO: Supply props like collapsed and disabled to LeftPanel2 leftPanel = ( - + ); } diff --git a/src/utils/ResizeNotifier.js b/src/utils/ResizeNotifier.js index d65bc4bd07..f726a43e08 100644 --- a/src/utils/ResizeNotifier.js +++ b/src/utils/ResizeNotifier.js @@ -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" */ +/** + * Fires when the middle panel has been resized by a pixel. + * @event module:utils~ResizeNotifier#"middlePanelResizedNoisy" + */ import { EventEmitter } from "events"; import { throttle } from "lodash"; @@ -29,15 +33,24 @@ export default class ResizeNotifier extends EventEmitter { this._throttledMiddlePanel = throttle(() => this.emit("middlePanelResized"), 200); } + _noisyMiddlePanel() { + this.emit("middlePanelResizedNoisy"); + } + + _updateMiddlePanel() { + this._throttledMiddlePanel(); + this._noisyMiddlePanel(); + } + // can be called in quick succession notifyLeftHandleResized() { // don't emit event for own region - this._throttledMiddlePanel(); + this._updateMiddlePanel(); } // can be called in quick succession notifyRightHandleResized() { - this._throttledMiddlePanel(); + this._updateMiddlePanel(); } // can be called in quick succession @@ -48,7 +61,7 @@ export default class ResizeNotifier extends EventEmitter { // taller than the available space this.emit("leftPanelResized"); - this._throttledMiddlePanel(); + this._updateMiddlePanel(); } }