Prevent layout trashing when resizing the window

pull/21833/head
Germain Souquet 2021-05-25 09:50:09 +01:00
parent 2710062df7
commit ac93cc514f
6 changed files with 11 additions and 43 deletions

View File

@ -90,10 +90,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
this.groupFilterPanelWatcherRef = SettingsStore.watchSetting("TagPanel.enableTagPanel", null, () => {
this.setState({showGroupFilterPanel: SettingsStore.getValue("TagPanel.enableTagPanel")});
});
// 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() {
@ -103,7 +99,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate);
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
this.props.resizeNotifier.off("middlePanelResizedNoisy", this.onResize);
}
private updateActiveSpace = (activeSpace: Room) => {
@ -281,11 +276,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
this.handleStickyHeaders(list);
};
private onResize = () => {
if (!this.listContainerRef.current) return; // ignore: no headers to sticky
this.handleStickyHeaders(this.listContainerRef.current);
};
private onFocus = (ev: React.FocusEvent) => {
this.focusedElement = ev.target;
};
@ -420,7 +410,6 @@ export default class LeftPanel extends React.Component<IProps, IState> {
onFocus={this.onFocus}
onBlur={this.onBlur}
isMinimized={this.props.isMinimized}
onResize={this.onResize}
activeSpace={this.state.activeSpace}
/>;
@ -454,7 +443,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
{roomList}
</div>
</div>
{ !this.props.isMinimized && <LeftPanelWidget onResize={this.onResize} /> }
{ !this.props.isMinimized && <LeftPanelWidget /> }
</aside>
</div>
);

View File

@ -14,7 +14,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, {useContext, useEffect, useMemo} from "react";
import React, {useContext, useMemo} from "react";
import {Resizable} from "re-resizable";
import classNames from "classnames";
@ -28,15 +28,11 @@ import {useAccountData} from "../../hooks/useAccountData";
import AppTile from "../views/elements/AppTile";
import {useSettingValue} from "../../hooks/useSettings";
interface IProps {
onResize(): void;
}
const MIN_HEIGHT = 100;
const MAX_HEIGHT = 500; // or 50% of the window height
const INITIAL_HEIGHT = 280;
const LeftPanelWidget: React.FC<IProps> = ({ onResize }) => {
const LeftPanelWidget: React.FC = () => {
const cli = useContext(MatrixClientContext);
const mWidgetsEvent = useAccountData<Record<string, IWidgetEvent>>(cli, "m.widgets");
@ -56,7 +52,6 @@ const LeftPanelWidget: React.FC<IProps> = ({ onResize }) => {
const [height, setHeight] = useLocalStorageState("left-panel-widget-height", INITIAL_HEIGHT);
const [expanded, setExpanded] = useLocalStorageState("left-panel-widget-expanded", true);
useEffect(onResize, [expanded, onResize]);
const [onFocus, isActive, ref] = useRovingTabIndex();
const tabIndex = isActive ? 0 : -1;
@ -69,7 +64,6 @@ const LeftPanelWidget: React.FC<IProps> = ({ onResize }) => {
size={{height} as any}
minHeight={MIN_HEIGHT}
maxHeight={Math.min(window.innerHeight / 2, MAX_HEIGHT)}
onResize={onResize}
onResizeStop={(e, dir, ref, d) => {
setHeight(height + d.height);
}}

View File

@ -87,6 +87,7 @@ import defaultDispatcher from "../../dispatcher/dispatcher";
import SecurityCustomisations from "../../customisations/Security";
import PerformanceMonitor, { PerformanceEntryNames } from "../../performance";
import UIStore, { UI_EVENTS } from "../../stores/UIStore";
/** constants for MatrixChat.state.view */
export enum Views {
@ -225,7 +226,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
firstSyncPromise: IDeferred<void>;
private screenAfterLogin?: IScreen;
private windowWidth: number;
private pageChanging: boolean;
private tokenLogin?: boolean;
private accountPassword?: string;
@ -277,9 +277,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
}
this.windowWidth = 10000;
this.handleResize();
window.addEventListener('resize', this.handleResize);
UIStore.instance.on(UI_EVENTS.Resize, this.handleResize);
this.pageChanging = false;
@ -436,7 +434,7 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
dis.unregister(this.dispatcherRef);
this.themeWatcher.stop();
this.fontWatcher.stop();
window.removeEventListener('resize', this.handleResize);
UIStore.destroy();
this.state.resizeNotifier.removeListener("middlePanelResized", this.dispatchTimelineResize);
if (this.accountPasswordTimer !== null) clearTimeout(this.accountPasswordTimer);
@ -1820,18 +1818,17 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
}
handleResize = () => {
const hideLhsThreshold = 1000;
const showLhsThreshold = 1000;
const LHS_THRESHOLD = 1000;
const width = UIStore.instance.windowWith;
if (this.windowWidth > hideLhsThreshold && window.innerWidth <= hideLhsThreshold) {
if (width <= LHS_THRESHOLD && !this.state.collapseLhs) {
dis.dispatch({ action: 'hide_left_panel' });
}
if (this.windowWidth <= showLhsThreshold && window.innerWidth > showLhsThreshold) {
if (width > LHS_THRESHOLD && this.state.collapseLhs) {
dis.dispatch({ action: 'show_left_panel' });
}
this.state.resizeNotifier.notifyWindowResized();
this.windowWidth = window.innerWidth;
};
private dispatchTimelineResize() {

View File

@ -55,7 +55,6 @@ interface IProps {
onKeyDown: (ev: React.KeyboardEvent) => void;
onFocus: (ev: React.FocusEvent) => void;
onBlur: (ev: React.FocusEvent) => void;
onResize: () => void;
resizeNotifier: ResizeNotifier;
isMinimized: boolean;
activeSpace: Room;
@ -404,9 +403,7 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
const newSublists = objectWithOnly(newLists, newListIds);
const sublists = objectShallowClone(newSublists, (k, v) => arrayFastClone(v));
this.setState({sublists, isNameFiltering}, () => {
this.props.onResize();
});
this.setState({sublists, isNameFiltering});
}
};
@ -537,7 +534,6 @@ export default class RoomList extends React.PureComponent<IProps, IState> {
addRoomLabel={aesthetics.addRoomLabel ? _t(aesthetics.addRoomLabel) : aesthetics.addRoomLabel}
addRoomContextMenu={aesthetics.addRoomContextMenu}
isMinimized={this.props.isMinimized}
onResize={this.props.onResize}
showSkeleton={showSkeleton}
extraTiles={extraTiles}
resizeNotifier={this.props.resizeNotifier}

View File

@ -74,7 +74,6 @@ interface IProps {
addRoomLabel: string;
isMinimized: boolean;
tagId: TagID;
onResize: () => void;
showSkeleton?: boolean;
alwaysVisible?: boolean;
resizeNotifier: ResizeNotifier;
@ -473,7 +472,6 @@ export default class RoomSublist extends React.Component<IProps, IState> {
private toggleCollapsed = () => {
this.layout.isCollapsed = this.state.isExpanded;
this.setState({isExpanded: !this.layout.isCollapsed});
setImmediate(() => this.props.onResize()); // needs to happen when the DOM is updated
};
private onHeaderKeyDown = (ev: React.KeyboardEvent) => {

View File

@ -74,12 +74,6 @@ export default class ResizeNotifier extends EventEmitter {
// can be called in quick succession
notifyWindowResized() {
// no need to throttle this one,
// also it could make scrollbars appear for
// a split second when the room list manual layout is now
// taller than the available space
this.emit("leftPanelResized");
this._updateMiddlePanel();
}
}