Implement collapsible panels for the new room list (#32742)
* Add `react-resizable-panels` library * Implement a custom SeparatorView * Add a `LeftResizablePanelView` * Add a custom `GroupView` * Export everything from shared-components * Make it possible to track width/collapse state through settings * Add a view model to drive the views * Render views without disrupting the old room list * Fix lint error * Disable user interaction on collapsed panel * Prevent widgets fron hijacking pointer events * Expand to full width on separator click * Separator should be shown when focused via keyboard * Update tests * Use data-attribute for hover * Write stories for SeperatorView * Write vite tests for SeparatorView * Write tests for LeftResizablePanelView * More tests * Fix lint errors * Fix flakey border on the roomlst * Fix storybook axe violation * Update snapshots * Fix playwright tests * Fix sonarcloud issues * Use translated string * Add better js-doc comments * Rename `ResizerSnapshot` to `ResizerViewSnapshot` * Externalize react-resizable-panels * Link figma designs to stories * Write playwright tests * Update screenshots * Fix lint errors * Update more screenshots * Update more screenshots * Fix flaky toast test * Update apps/web/playwright/e2e/crypto/toasts.spec.ts Co-authored-by: Andy Balaam <andy.balaam@matrix.org> * Fix indentation --------- Co-authored-by: Andy Balaam <andy.balaam@matrix.org>
This commit is contained in:
co-authored by
Andy Balaam
parent
89261bbe00
commit
99e6ede9f1
@@ -22,6 +22,7 @@ import {
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { type MatrixCall } from "matrix-js-sdk/src/webrtc/call";
|
||||
import classNames from "classnames";
|
||||
import { GroupView, SeparatorView, Panel, LeftResizablePanelView } from "@element-hq/web-shared-components";
|
||||
|
||||
import { isOnlyCtrlOrCmdKeyEvent, Key } from "../../Keyboard";
|
||||
import PageTypes from "../../PageTypes";
|
||||
@@ -70,6 +71,7 @@ import { MatrixClientContextProvider } from "./MatrixClientContextProvider";
|
||||
import { Landmark, LandmarkNavigation } from "../../accessibility/LandmarkNavigation";
|
||||
import { ModuleApi } from "../../modules/Api.ts";
|
||||
import { SDKContext } from "../../contexts/SDKContext.ts";
|
||||
import { ResizerViewModel } from "../../viewmodels/structures/ResizerViewModel.ts";
|
||||
|
||||
// We need to fetch each pinned message individually (if we don't already have it)
|
||||
// so each pinned message may trigger a request. Limit the number per room for sanity.
|
||||
@@ -136,6 +138,8 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
protected timezoneProfileUpdateRef?: string[];
|
||||
protected resizer?: Resizer<ICollapseConfig, CollapseItem>;
|
||||
|
||||
private resizerViewModel?: ResizerViewModel;
|
||||
|
||||
public static contextType = SDKContext;
|
||||
declare public context: React.ContextType<typeof SDKContext>;
|
||||
|
||||
@@ -198,6 +202,8 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
|
||||
OwnProfileStore.instance.on(UPDATE_EVENT, this.refreshBackgroundImage);
|
||||
this.refreshBackgroundImage();
|
||||
|
||||
this.resizerViewModel = new ResizerViewModel();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -258,6 +264,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
SettingsStore.unwatchSetting(this.backgroundImageWatcherRef);
|
||||
this.timezoneProfileUpdateRef?.forEach((s) => SettingsStore.unwatchSetting(s));
|
||||
this.resizer?.detach();
|
||||
this.resizerViewModel?.dispose();
|
||||
}
|
||||
|
||||
private onCallState = (): void => {
|
||||
@@ -760,6 +767,58 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
});
|
||||
|
||||
const shouldUseMinimizedUI = !useNewRoomList && this.props.collapseLhs;
|
||||
|
||||
const leftPanel = (
|
||||
<div className="mx_LeftPanel_outerWrapper">
|
||||
<LeftPanelLiveShareWarning isMinimized={shouldUseMinimizedUI || false} />
|
||||
<div className={leftPanelWrapperClasses}>
|
||||
{!useNewRoomList && (
|
||||
<BackdropPanel blurMultiplier={0.5} backgroundImage={this.state.backgroundImage} />
|
||||
)}
|
||||
{!useNewRoomList && <SpacePanel />}
|
||||
{!useNewRoomList && <BackdropPanel backgroundImage={this.state.backgroundImage} />}
|
||||
{!moduleRenderer && (
|
||||
<div
|
||||
className="mx_LeftPanel_wrapper--user"
|
||||
ref={this._resizeContainer}
|
||||
data-collapsed={shouldUseMinimizedUI ? true : undefined}
|
||||
>
|
||||
<LeftPanel
|
||||
pageType={this.props.page_type as PageTypes}
|
||||
isMinimized={shouldUseMinimizedUI || false}
|
||||
resizeNotifier={this.context.resizeNotifier}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const roomView = <div className="mx_RoomView_wrapper">{pageElement}</div>;
|
||||
const content =
|
||||
useNewRoomList && this.resizerViewModel ? (
|
||||
<GroupView vm={this.resizerViewModel}>
|
||||
<SpacePanel />
|
||||
<LeftResizablePanelView
|
||||
vm={this.resizerViewModel}
|
||||
className="mx_LeftPanel_panel"
|
||||
minSize="200px"
|
||||
maxSize="370px"
|
||||
defaultSize="370px"
|
||||
>
|
||||
{leftPanel}
|
||||
</LeftResizablePanelView>
|
||||
<SeparatorView className="mx_Separator" vm={this.resizerViewModel} />
|
||||
<Panel className="mx_LeftPanel_panel">{roomView}</Panel>
|
||||
</GroupView>
|
||||
) : (
|
||||
<>
|
||||
{leftPanel}
|
||||
{!moduleRenderer && <ResizeHandle passRef={this.resizeHandler} id="lp-resizer" />}
|
||||
{roomView}
|
||||
</>
|
||||
);
|
||||
|
||||
return (
|
||||
<MatrixClientContextProvider client={this._matrixClient}>
|
||||
<div
|
||||
@@ -769,33 +828,7 @@ class LoggedInView extends React.Component<IProps, IState> {
|
||||
aria-hidden={this.props.hideToSRUsers}
|
||||
>
|
||||
<ToastContainer />
|
||||
<div className={bodyClasses}>
|
||||
<div className="mx_LeftPanel_outerWrapper">
|
||||
<LeftPanelLiveShareWarning isMinimized={shouldUseMinimizedUI || false} />
|
||||
<div className={leftPanelWrapperClasses}>
|
||||
{!useNewRoomList && (
|
||||
<BackdropPanel blurMultiplier={0.5} backgroundImage={this.state.backgroundImage} />
|
||||
)}
|
||||
<SpacePanel />
|
||||
{!useNewRoomList && <BackdropPanel backgroundImage={this.state.backgroundImage} />}
|
||||
{!moduleRenderer && (
|
||||
<div
|
||||
className="mx_LeftPanel_wrapper--user"
|
||||
ref={this._resizeContainer}
|
||||
data-collapsed={shouldUseMinimizedUI ? true : undefined}
|
||||
>
|
||||
<LeftPanel
|
||||
pageType={this.props.page_type as PageTypes}
|
||||
isMinimized={shouldUseMinimizedUI || false}
|
||||
resizeNotifier={this.context.resizeNotifier}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{!moduleRenderer && <ResizeHandle passRef={this.resizeHandler} id="lp-resizer" />}
|
||||
<div className="mx_RoomView_wrapper">{pageElement}</div>
|
||||
</div>
|
||||
<div className={bodyClasses}>{content}</div>
|
||||
</div>
|
||||
<PipContainer />
|
||||
<NonUrgentToastContainer />
|
||||
|
||||
Reference in New Issue
Block a user