diff --git a/apps/web/src/components/structures/LoggedInView.tsx b/apps/web/src/components/structures/LoggedInView.tsx index ad364a6527..1a736ae696 100644 --- a/apps/web/src/components/structures/LoggedInView.tsx +++ b/apps/web/src/components/structures/LoggedInView.tsx @@ -795,8 +795,12 @@ class LoggedInView extends React.Component { ); const roomView =
{pageElement}
; - const content = - useNewRoomList && this.resizerViewModel ? ( + + let content: React.ReactNode; + if (useNewRoomList && this.resizerViewModel && !moduleRenderer) { + // New room list owned by element-web: resizable layout with a draggable separator. + // The SpacePanel lives inside GroupView (leftPanel omits it when the new room list is enabled). + content = ( { {roomView} - ) : ( + ); + } else { + // Fallback layout: the old room list, or a module's full-screen view (e.g. multiroom) which + // must not use the resizable layout above. SpacePanel is guarded on useNewRoomList to avoid a + // duplicate (the old room list already renders one inside leftPanel); the legacy ResizeHandle is + // dropped for module views, which manage their own layout. + content = ( <> + {useNewRoomList && } {leftPanel} {!moduleRenderer && } {roomView} ); + } return ( diff --git a/apps/web/test/unit-tests/components/structures/LoggedInView-test.tsx b/apps/web/test/unit-tests/components/structures/LoggedInView-test.tsx index 3a3d5bc909..68f8976c25 100644 --- a/apps/web/test/unit-tests/components/structures/LoggedInView-test.tsx +++ b/apps/web/test/unit-tests/components/structures/LoggedInView-test.tsx @@ -39,6 +39,7 @@ import { Action } from "../../../../src/dispatcher/actions"; import Modal from "../../../../src/Modal"; import { SETTINGS } from "../../../../src/settings/Settings"; import ToastStore from "../../../../src/stores/ToastStore"; +import { ModuleApi } from "../../../../src/modules/Api"; // Create a mock resizer instance that can be shared across tests const mockResizerInstance = { @@ -614,6 +615,42 @@ describe("", () => { }); }); + describe("module-rendered fullscreen view (e.g. multiroom)", () => { + // A page_type for which a module registers a custom full-screen renderer. + const modulePageType = "io.element.test_fullscreen"; + + beforeEach(async () => { + await SettingsStore.setValue("feature_new_room_list", null, SettingLevel.DEVICE, true); + ModuleApi.instance.navigation.registerLocationRenderer(modulePageType, () => ( +
+ )); + }); + + afterEach(async () => { + ModuleApi.instance.navigation.locationRenderers.delete(modulePageType); + await SettingsStore.setValue("feature_new_room_list", null, SettingLevel.DEVICE, false); + }); + + it("renders the resizable separator for a normal room view with the new room list", () => { + const { container } = getComponent({ page_type: "room" }); + + // With the new room list and no module renderer, the resizable left panel and its separator are used. + expect(container.querySelector(".mx_Separator")).toBeInTheDocument(); + }); + + it("does not render the resizer for a module-rendered fullscreen view, but keeps the space panel", () => { + const { container, getByTestId } = getComponent({ page_type: modulePageType }); + + // The module's full-screen content is shown... + expect(getByTestId("module-content")).toBeInTheDocument(); + // ...without the resizable separator or the legacy resize handle... + expect(container.querySelector(".mx_Separator")).not.toBeInTheDocument(); + expect(container.querySelector(".mx_ResizeHandle")).not.toBeInTheDocument(); + // ...while the space panel rail remains visible. + expect(container.querySelector(".mx_SpacePanel")).toBeInTheDocument(); + }); + }); + describe("create a new resizer when page_type changes", () => { afterEach(() => { jest.clearAllMocks();