Track left panel width using ResizeObserver

pull/21833/head
Germain Souquet 2021-05-27 12:36:16 +01:00
parent 526bde4d9e
commit fcae19f831
3 changed files with 55 additions and 8 deletions

View File

@ -43,6 +43,7 @@ import TypingStore from "../stores/TypingStore";
import { EventIndexPeg } from "../indexing/EventIndexPeg"; import { EventIndexPeg } from "../indexing/EventIndexPeg";
import {VoiceRecordingStore} from "../stores/VoiceRecordingStore"; import {VoiceRecordingStore} from "../stores/VoiceRecordingStore";
import PerformanceMonitor from "../performance"; import PerformanceMonitor from "../performance";
import UIStore from "../stores/UIStore";
declare global { declare global {
interface Window { interface Window {
@ -82,6 +83,7 @@ declare global {
mxEventIndexPeg: EventIndexPeg; mxEventIndexPeg: EventIndexPeg;
mxPerformanceMonitor: PerformanceMonitor; mxPerformanceMonitor: PerformanceMonitor;
mxPerformanceEntryNames: any; mxPerformanceEntryNames: any;
mxUIStore: UIStore;
} }
interface Document { interface Document {

View File

@ -67,6 +67,7 @@ const cssClasses = [
@replaceableComponent("structures.LeftPanel") @replaceableComponent("structures.LeftPanel")
export default class LeftPanel extends React.Component<IProps, IState> { export default class LeftPanel extends React.Component<IProps, IState> {
private ref: React.RefObject<HTMLDivElement> = createRef();
private listContainerRef: React.RefObject<HTMLDivElement> = createRef(); private listContainerRef: React.RefObject<HTMLDivElement> = createRef();
private groupFilterPanelWatcherRef: string; private groupFilterPanelWatcherRef: string;
private bgImageWatcherRef: string; private bgImageWatcherRef: string;
@ -93,6 +94,10 @@ export default class LeftPanel extends React.Component<IProps, IState> {
}); });
} }
public componentDidMount() {
UIStore.instance.trackElementDimensions("LeftPanel", this.ref.current);
}
public componentWillUnmount() { public componentWillUnmount() {
SettingsStore.unwatchSetting(this.groupFilterPanelWatcherRef); SettingsStore.unwatchSetting(this.groupFilterPanelWatcherRef);
SettingsStore.unwatchSetting(this.bgImageWatcherRef); SettingsStore.unwatchSetting(this.bgImageWatcherRef);
@ -100,6 +105,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate); RoomListStore.instance.off(LISTS_UPDATE_EVENT, this.onBreadcrumbsUpdate);
OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate); OwnProfileStore.instance.off(UPDATE_EVENT, this.onBackgroundImageUpdate);
SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace); SpaceStore.instance.off(UPDATE_SELECTED_SPACE, this.updateActiveSpace);
UIStore.instance.stopTrackingElementDimensions("LeftPanel");
} }
private updateActiveSpace = (activeSpace: Room) => { private updateActiveSpace = (activeSpace: Room) => {
@ -420,7 +426,7 @@ export default class LeftPanel extends React.Component<IProps, IState> {
); );
return ( return (
<div className={containerClasses}> <div className={containerClasses} ref={this.ref}>
{leftLeftPanel} {leftLeftPanel}
<aside className="mx_LeftPanel_roomListContainer"> <aside className="mx_LeftPanel_roomListContainer">
{this.renderHeader()} {this.renderHeader()}

View File

@ -24,12 +24,14 @@ export enum UI_EVENTS {
export type ResizeObserverCallbackFunction = (entries: ResizeObserverEntry[]) => void; export type ResizeObserverCallbackFunction = (entries: ResizeObserverEntry[]) => void;
export default class UIStore extends EventEmitter { export default class UIStore extends EventEmitter {
private static _instance: UIStore = null; private static _instance: UIStore = null;
private resizeObserver: ResizeObserver; private resizeObserver: ResizeObserver;
private uiElementDimensions = new Map<string, DOMRectReadOnly>();
private trackedUiElements = new Map<Element, string>();
public windowWidth: number; public windowWidth: number;
public windowHeight: number; public windowHeight: number;
@ -60,14 +62,51 @@ export default class UIStore extends EventEmitter {
} }
} }
private resizeObserverCallback = (entries: ResizeObserverEntry[]) => { public getElementDimensions(name: string): DOMRectReadOnly {
const { width, height } = entries return this.uiElementDimensions.get(name);
.find(entry => entry.target === document.body) }
.contentRect;
this.windowWidth = width; public trackElementDimensions(name: string, element: Element): void {
this.windowHeight = height; this.trackedUiElements.set(element, name);
this.resizeObserver.observe(element);
}
public stopTrackingElementDimensions(name: string): void {
let trackedElement: Element;
this.trackedUiElements.forEach((trackedElementName, element) => {
if (trackedElementName === name) {
trackedElement = element;
}
});
if (trackedElement) {
this.resizeObserver.unobserve(trackedElement);
this.uiElementDimensions.delete(name);
this.trackedUiElements.delete(trackedElement);
}
}
public isTrackingElementDimensions(name: string): boolean {
return this.uiElementDimensions.has(name);
}
private resizeObserverCallback = (entries: ResizeObserverEntry[]) => {
const windowEntry = entries.find(entry => entry.target === document.body);
if (windowEntry) {
this.windowWidth = windowEntry.contentRect.width;
this.windowHeight = windowEntry.contentRect.height;
}
entries.forEach(entry => {
const trackedElementName = this.trackedUiElements.get(entry.target);
if (trackedElementName) {
this.uiElementDimensions.set(trackedElementName, entry.contentRect);
this.emit(trackedElementName, UI_EVENTS.Resize, entry);
}
});
this.emit(UI_EVENTS.Resize, entries); this.emit(UI_EVENTS.Resize, entries);
} }
} }
window.mxUIStore = UIStore.instance;