You've already forked matrix-react-sdk
							
							
				mirror of
				https://github.com/matrix-org/matrix-react-sdk.git
				synced 2025-11-03 00:33:22 +03:00 
			
		
		
		
	Fix resizer on left panel
This commit is contained in:
		@@ -14,7 +14,9 @@ See the License for the specific language governing permissions and
 | 
				
			|||||||
limitations under the License.
 | 
					limitations under the License.
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$roomListCollapsedWidth: 68px;
 | 
					:root {
 | 
				
			||||||
 | 
					    --room-list-collapsed-width: 68px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mx_MatrixChat--with-avatar {
 | 
					.mx_MatrixChat--with-avatar {
 | 
				
			||||||
    .mx_LeftPanel,
 | 
					    .mx_LeftPanel,
 | 
				
			||||||
@@ -32,10 +34,6 @@ $roomListCollapsedWidth: 68px;
 | 
				
			|||||||
        display: flex;
 | 
					        display: flex;
 | 
				
			||||||
        overflow: hidden;
 | 
					        overflow: hidden;
 | 
				
			||||||
        position: relative;
 | 
					        position: relative;
 | 
				
			||||||
 | 
					 | 
				
			||||||
        .mx_ResizeHandle.mx_ResizeHandle_horizontal {
 | 
					 | 
				
			||||||
            margin: 0;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,12 +42,12 @@ $roomListCollapsedWidth: 68px;
 | 
				
			|||||||
.mx_LeftPanel {
 | 
					.mx_LeftPanel {
 | 
				
			||||||
    background-color: $roomlist-bg-color;
 | 
					    background-color: $roomlist-bg-color;
 | 
				
			||||||
    // TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel
 | 
					    // TODO decrease this once Spaces launches as it'll no longer need to include the 56px Community Panel
 | 
				
			||||||
    min-width: 206px;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Create a row-based flexbox for the GroupFilterPanel and the room list
 | 
					    // Create a row-based flexbox for the GroupFilterPanel and the room list
 | 
				
			||||||
    display: flex;
 | 
					    display: flex;
 | 
				
			||||||
    contain: content;
 | 
					    contain: content;
 | 
				
			||||||
    position: relative;
 | 
					    position: relative;
 | 
				
			||||||
 | 
					    flex-grow: 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // Note: The 'room list' in this context is actually everything that isn't the tag
 | 
					    // Note: The 'room list' in this context is actually everything that isn't the tag
 | 
				
			||||||
    // panel, such as the menu options, breadcrumbs, filtering, etc
 | 
					    // panel, such as the menu options, breadcrumbs, filtering, etc
 | 
				
			||||||
@@ -182,6 +180,8 @@ $roomListCollapsedWidth: 68px;
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .mx_LeftPanel_roomListWrapper {
 | 
					        .mx_LeftPanel_roomListWrapper {
 | 
				
			||||||
 | 
					            // Make the y-scrollbar more responsive
 | 
				
			||||||
 | 
					            padding-right: 2px;
 | 
				
			||||||
            overflow: hidden;
 | 
					            overflow: hidden;
 | 
				
			||||||
            margin-top: 10px; // so we're not up against the search/filter
 | 
					            margin-top: 10px; // so we're not up against the search/filter
 | 
				
			||||||
            flex: 1 0 0; // needed in Safari to properly set flex-basis
 | 
					            flex: 1 0 0; // needed in Safari to properly set flex-basis
 | 
				
			||||||
@@ -203,11 +203,12 @@ $roomListCollapsedWidth: 68px;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    // These styles override the defaults for the minimized (66px) layout
 | 
					    // These styles override the defaults for the minimized (66px) layout
 | 
				
			||||||
    &.mx_LeftPanel_minimized {
 | 
					    &.mx_LeftPanel_minimized {
 | 
				
			||||||
 | 
					        flex-grow: 0;
 | 
				
			||||||
        min-width: unset;
 | 
					        min-width: unset;
 | 
				
			||||||
        width: unset !important;
 | 
					        width: unset !important;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        .mx_LeftPanel_roomListContainer {
 | 
					        .mx_LeftPanel_roomListContainer {
 | 
				
			||||||
            width: $roomListCollapsedWidth;
 | 
					            width: var(--room-list-collapsed-width);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            .mx_LeftPanel_userHeader {
 | 
					            .mx_LeftPanel_userHeader {
 | 
				
			||||||
                flex-direction: row;
 | 
					                flex-direction: row;
 | 
				
			||||||
@@ -233,4 +234,5 @@ $roomListCollapsedWidth: 68px;
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -151,7 +151,8 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
    private dispatcherRef: string;
 | 
					    private dispatcherRef: string;
 | 
				
			||||||
    protected readonly _matrixClient: MatrixClient;
 | 
					    protected readonly _matrixClient: MatrixClient;
 | 
				
			||||||
    protected readonly _roomView: React.RefObject<any>;
 | 
					    protected readonly _roomView: React.RefObject<any>;
 | 
				
			||||||
    protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
 | 
					    protected readonly _resizeContainer: React.RefObject<HTMLDivElement>;
 | 
				
			||||||
 | 
					    protected readonly resizeHandler: React.RefObject<HTMLDivElement>;
 | 
				
			||||||
    protected compactLayoutWatcherRef: string;
 | 
					    protected compactLayoutWatcherRef: string;
 | 
				
			||||||
    protected backgroundImageWatcherRef: string;
 | 
					    protected backgroundImageWatcherRef: string;
 | 
				
			||||||
    protected resizer: Resizer;
 | 
					    protected resizer: Resizer;
 | 
				
			||||||
@@ -176,6 +177,7 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        this._roomView = React.createRef();
 | 
					        this._roomView = React.createRef();
 | 
				
			||||||
        this._resizeContainer = React.createRef();
 | 
					        this._resizeContainer = React.createRef();
 | 
				
			||||||
 | 
					        this.resizeHandler = React.createRef();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount() {
 | 
					    componentDidMount() {
 | 
				
			||||||
@@ -280,6 +282,7 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
            isItemCollapsed: domNode => {
 | 
					            isItemCollapsed: domNode => {
 | 
				
			||||||
                return domNode.classList.contains("mx_LeftPanel_minimized");
 | 
					                return domNode.classList.contains("mx_LeftPanel_minimized");
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            handler: this.resizeHandler.current,
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        const resizer = new Resizer(this._resizeContainer.current, CollapseDistributor, collapseConfig);
 | 
					        const resizer = new Resizer(this._resizeContainer.current, CollapseDistributor, collapseConfig);
 | 
				
			||||||
        resizer.setClassNames({
 | 
					        resizer.setClassNames({
 | 
				
			||||||
@@ -681,16 +684,20 @@ class LoggedInView extends React.Component<IProps, IState> {
 | 
				
			|||||||
                                backgroundImage={this.state.backgroundImage}
 | 
					                                backgroundImage={this.state.backgroundImage}
 | 
				
			||||||
                            />
 | 
					                            />
 | 
				
			||||||
                            <div
 | 
					                            <div
 | 
				
			||||||
                                ref={this._resizeContainer}
 | 
					 | 
				
			||||||
                                className="mx_LeftPanel_wrapper--user"
 | 
					                                className="mx_LeftPanel_wrapper--user"
 | 
				
			||||||
 | 
					                                ref={this._resizeContainer}
 | 
				
			||||||
 | 
					                                style={{
 | 
				
			||||||
 | 
					                                    maxWidth: this.props.collapseLhs ? getComputedStyle(document.documentElement)
 | 
				
			||||||
 | 
					                                        .getPropertyValue('--room-list-collapsed-width') : undefined,
 | 
				
			||||||
 | 
					                                }}
 | 
				
			||||||
                            >
 | 
					                            >
 | 
				
			||||||
                                <LeftPanel
 | 
					                                <LeftPanel
 | 
				
			||||||
                                    isMinimized={this.props.collapseLhs || false}
 | 
					                                    isMinimized={this.props.collapseLhs || false}
 | 
				
			||||||
                                    resizeNotifier={this.props.resizeNotifier}
 | 
					                                    resizeNotifier={this.props.resizeNotifier}
 | 
				
			||||||
                                />
 | 
					                                />
 | 
				
			||||||
                                <ResizeHandle id="lp-resizer" />
 | 
					 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <ResizeHandle passRef={this.resizeHandler} id="lp-resizer" />
 | 
				
			||||||
                        <div className="mx_RoomView_wrapper">
 | 
					                        <div className="mx_RoomView_wrapper">
 | 
				
			||||||
                            { pageElement }
 | 
					                            { pageElement }
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,10 @@ interface IResizeHandleProps {
 | 
				
			|||||||
    vertical?: boolean;
 | 
					    vertical?: boolean;
 | 
				
			||||||
    reverse?: boolean;
 | 
					    reverse?: boolean;
 | 
				
			||||||
    id?: string;
 | 
					    id?: string;
 | 
				
			||||||
 | 
					    passRef?: React.RefObject<HTMLDivElement>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const ResizeHandle: React.FC<IResizeHandleProps> = ({ vertical, reverse, id }) => {
 | 
					const ResizeHandle: React.FC<IResizeHandleProps> = ({ vertical, reverse, id, passRef }) => {
 | 
				
			||||||
    const classNames = ['mx_ResizeHandle'];
 | 
					    const classNames = ['mx_ResizeHandle'];
 | 
				
			||||||
    if (vertical) {
 | 
					    if (vertical) {
 | 
				
			||||||
        classNames.push('mx_ResizeHandle_vertical');
 | 
					        classNames.push('mx_ResizeHandle_vertical');
 | 
				
			||||||
@@ -19,7 +20,7 @@ const ResizeHandle: React.FC<IResizeHandleProps> = ({ vertical, reverse, id }) =
 | 
				
			|||||||
        classNames.push('mx_ResizeHandle_reverse');
 | 
					        classNames.push('mx_ResizeHandle_reverse');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return (
 | 
					    return (
 | 
				
			||||||
        <div className={classNames.join(' ')} data-id={id}><div /></div>
 | 
					        <div ref={passRef} className={classNames.join(' ')} data-id={id}><div /></div>
 | 
				
			||||||
    );
 | 
					    );
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,8 +40,8 @@ class CollapseItem extends ResizeItem<ICollapseConfig> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class CollapseDistributor extends FixedDistributor<ICollapseConfig, CollapseItem> {
 | 
					export default class CollapseDistributor extends FixedDistributor<ICollapseConfig, CollapseItem> {
 | 
				
			||||||
    static createItem(resizeHandle: HTMLDivElement, resizer: Resizer<ICollapseConfig>, sizer: Sizer) {
 | 
					    static createItem(resizeHandle: HTMLDivElement, resizer: Resizer<ICollapseConfig>, sizer: Sizer, container?: HTMLElement): CollapseItem {
 | 
				
			||||||
        return new CollapseItem(resizeHandle, resizer, sizer);
 | 
					        return new CollapseItem(resizeHandle, resizer, sizer, container);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private readonly toggleSize: number;
 | 
					    private readonly toggleSize: number;
 | 
				
			||||||
@@ -55,12 +55,9 @@ export default class CollapseDistributor extends FixedDistributor<ICollapseConfi
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    public resize(newSize: number) {
 | 
					    public resize(newSize: number) {
 | 
				
			||||||
        const isCollapsedSize = newSize < this.toggleSize;
 | 
					        const isCollapsedSize = newSize < this.toggleSize;
 | 
				
			||||||
        if (isCollapsedSize && !this.isCollapsed) {
 | 
					        if (isCollapsedSize !== this.isCollapsed) {
 | 
				
			||||||
            this.isCollapsed = true;
 | 
					            this.isCollapsed = isCollapsedSize;
 | 
				
			||||||
            this.item.notifyCollapsed(true);
 | 
					            this.item.notifyCollapsed(isCollapsedSize);
 | 
				
			||||||
        } else if (!isCollapsedSize && this.isCollapsed) {
 | 
					 | 
				
			||||||
            this.item.notifyCollapsed(false);
 | 
					 | 
				
			||||||
            this.isCollapsed = false;
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (!isCollapsedSize) {
 | 
					        if (!isCollapsedSize) {
 | 
				
			||||||
            super.resize(newSize);
 | 
					            super.resize(newSize);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -26,15 +26,20 @@ export default class ResizeItem<C extends IConfig = IConfig> {
 | 
				
			|||||||
        handle: HTMLElement,
 | 
					        handle: HTMLElement,
 | 
				
			||||||
        public readonly resizer: Resizer<C>,
 | 
					        public readonly resizer: Resizer<C>,
 | 
				
			||||||
        public readonly sizer: Sizer,
 | 
					        public readonly sizer: Sizer,
 | 
				
			||||||
 | 
					        public readonly container?: HTMLElement,
 | 
				
			||||||
    ) {
 | 
					    ) {
 | 
				
			||||||
        this.reverse = resizer.isReverseResizeHandle(handle);
 | 
					        this.reverse = resizer.isReverseResizeHandle(handle);
 | 
				
			||||||
 | 
					        if (container) {
 | 
				
			||||||
 | 
					            this.domNode = <HTMLElement>(container);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
            this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling);
 | 
					            this.domNode = <HTMLElement>(this.reverse ? handle.nextElementSibling : handle.previousElementSibling);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        this.id = handle.getAttribute("data-id");
 | 
					        this.id = handle.getAttribute("data-id");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private copyWith(handle: HTMLElement, resizer: Resizer, sizer: Sizer) {
 | 
					    private copyWith(handle: HTMLElement, resizer: Resizer, sizer: Sizer, container?: HTMLElement) {
 | 
				
			||||||
        const Ctor = this.constructor as typeof ResizeItem;
 | 
					        const Ctor = this.constructor as typeof ResizeItem;
 | 
				
			||||||
        return new Ctor(handle, resizer, sizer);
 | 
					        return new Ctor(handle, resizer, sizer, container);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private advance(forwards: boolean) {
 | 
					    private advance(forwards: boolean) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,6 +35,7 @@ export interface IConfig {
 | 
				
			|||||||
    onResizeStart?(): void;
 | 
					    onResizeStart?(): void;
 | 
				
			||||||
    onResizeStop?(): void;
 | 
					    onResizeStop?(): void;
 | 
				
			||||||
    onResized?(size: number, id: string, element: HTMLElement): void;
 | 
					    onResized?(size: number, id: string, element: HTMLElement): void;
 | 
				
			||||||
 | 
					    handler?: HTMLDivElement;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default class Resizer<C extends IConfig = IConfig> {
 | 
					export default class Resizer<C extends IConfig = IConfig> {
 | 
				
			||||||
@@ -46,7 +47,7 @@ export default class Resizer<C extends IConfig = IConfig> {
 | 
				
			|||||||
        public container: HTMLElement,
 | 
					        public container: HTMLElement,
 | 
				
			||||||
        private readonly distributorCtor: {
 | 
					        private readonly distributorCtor: {
 | 
				
			||||||
            new(item: ResizeItem): FixedDistributor<C, any>;
 | 
					            new(item: ResizeItem): FixedDistributor<C, any>;
 | 
				
			||||||
            createItem(resizeHandle: HTMLDivElement, resizer: Resizer, sizer: Sizer): ResizeItem;
 | 
					            createItem(resizeHandle: HTMLDivElement, resizer: Resizer, sizer: Sizer, container: HTMLElement): ResizeItem;
 | 
				
			||||||
            createSizer(containerElement: HTMLElement, vertical: boolean, reverse: boolean): Sizer;
 | 
					            createSizer(containerElement: HTMLElement, vertical: boolean, reverse: boolean): Sizer;
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        public readonly config?: C,
 | 
					        public readonly config?: C,
 | 
				
			||||||
@@ -68,12 +69,14 @@ export default class Resizer<C extends IConfig = IConfig> {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public attach() {
 | 
					    public attach() {
 | 
				
			||||||
        this.container.addEventListener("mousedown", this.onMouseDown, false);
 | 
					        const attachment = this?.config?.handler.parentElement ?? this.container;
 | 
				
			||||||
 | 
					        attachment.addEventListener("mousedown", this.onMouseDown, false);
 | 
				
			||||||
        window.addEventListener("resize", this.onResize);
 | 
					        window.addEventListener("resize", this.onResize);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public detach() {
 | 
					    public detach() {
 | 
				
			||||||
        this.container.removeEventListener("mousedown", this.onMouseDown, false);
 | 
					        const attachment = this?.config?.handler.parentElement ?? this.container;
 | 
				
			||||||
 | 
					        attachment.removeEventListener("mousedown", this.onMouseDown, false);
 | 
				
			||||||
        window.removeEventListener("resize", this.onResize);
 | 
					        window.removeEventListener("resize", this.onResize);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -113,7 +116,8 @@ export default class Resizer<C extends IConfig = IConfig> {
 | 
				
			|||||||
        // use closest in case the resize handle contains
 | 
					        // use closest in case the resize handle contains
 | 
				
			||||||
        // child dom nodes that can be the target
 | 
					        // child dom nodes that can be the target
 | 
				
			||||||
        const resizeHandle = event.target && (<HTMLDivElement>event.target).closest(`.${this.classNames.handle}`);
 | 
					        const resizeHandle = event.target && (<HTMLDivElement>event.target).closest(`.${this.classNames.handle}`);
 | 
				
			||||||
        if (!resizeHandle || resizeHandle.parentElement !== this.container) {
 | 
					        const hasHandler = this?.config?.handler;
 | 
				
			||||||
 | 
					        if (!resizeHandle || (!hasHandler && resizeHandle.parentElement !== this.container)) {
 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        // prevent starting a drag operation
 | 
					        // prevent starting a drag operation
 | 
				
			||||||
@@ -175,12 +179,15 @@ export default class Resizer<C extends IConfig = IConfig> {
 | 
				
			|||||||
        const reverse = this.isReverseResizeHandle(resizeHandle);
 | 
					        const reverse = this.isReverseResizeHandle(resizeHandle);
 | 
				
			||||||
        const Distributor = this.distributorCtor;
 | 
					        const Distributor = this.distributorCtor;
 | 
				
			||||||
        const sizer = Distributor.createSizer(this.container, vertical, reverse);
 | 
					        const sizer = Distributor.createSizer(this.container, vertical, reverse);
 | 
				
			||||||
        const item = Distributor.createItem(resizeHandle, this, sizer);
 | 
					        const item = Distributor.createItem(resizeHandle, this, sizer, this.container);
 | 
				
			||||||
        const distributor = new Distributor(item);
 | 
					        const distributor = new Distributor(item);
 | 
				
			||||||
        return { sizer, distributor };
 | 
					        return { sizer, distributor };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private getResizeHandles() {
 | 
					    private getResizeHandles() {
 | 
				
			||||||
 | 
					        if (this?.config?.handler) {
 | 
				
			||||||
 | 
					            return [this.config.handler];
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (!this.container.children) return [];
 | 
					        if (!this.container.children) return [];
 | 
				
			||||||
        return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`)) as HTMLElement[];
 | 
					        return Array.from(this.container.querySelectorAll(`.${this.classNames.handle}`)) as HTMLElement[];
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user