diff --git a/src/components/views/spaces/SpacePanel.tsx b/src/components/views/spaces/SpacePanel.tsx index 895859b271b2..5035bb5b9ebe 100644 --- a/src/components/views/spaces/SpacePanel.tsx +++ b/src/components/views/spaces/SpacePanel.tsx @@ -1,5 +1,5 @@ /* -Copyright 2021 - 2022 The Matrix.org Foundation C.I.C. +Copyright 2021 - 2023 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -60,7 +60,7 @@ import SettingsStore from "../../../settings/SettingsStore"; import { SettingLevel } from "../../../settings/SettingLevel"; import UIStore from "../../../stores/UIStore"; import QuickSettingsButton from "./QuickSettingsButton"; -import { useSettingValue } from "../../../hooks/useSettings"; +import { useSetting, useSettingValue } from "../../../hooks/useSettings"; import UserMenu from "../../structures/UserMenu"; import IndicatorScrollbar from "../../structures/IndicatorScrollbar"; import { IS_MAC, Key } from "../../../Keyboard"; @@ -329,12 +329,15 @@ const InnerSpacePanel = React.memo( ); const SpacePanel = () => { - const [isPanelCollapsed, setPanelCollapsed] = useState(true); - const ref = useRef(); + const [isPanelCollapsed, setPanelCollapsed] = useSetting("space_panel_collapsed"); + + const ref = useRef(null); useLayoutEffect(() => { + if (!ref.current) return; + UIStore.instance.trackElementDimensions("SpacePanel", ref.current); return () => UIStore.instance.stopTrackingElementDimensions("SpacePanel"); - }, []); + }, [ ref ]); useDispatcher(defaultDispatcher, (payload: ActionPayload) => { if (payload.action === Action.ToggleSpacePanel) { @@ -359,6 +362,7 @@ const SpacePanel = () => { setPanelCollapsed(!isPanelCollapsed)} title={isPanelCollapsed ? _t("Expand") : _t("Collapse")} tooltip={ diff --git a/src/settings/Settings.tsx b/src/settings/Settings.tsx index bfd40e96ce1c..4830a6697977 100644 --- a/src/settings/Settings.tsx +++ b/src/settings/Settings.tsx @@ -768,6 +768,11 @@ export const SETTINGS: { [setting: string]: ISetting } = { supportedLevels: [SettingLevel.ACCOUNT], default: [], // list of room IDs, most recent first }, + "space_panel_collapsed": { + // not really a setting + supportedLevels: LEVELS_DEVICE_ONLY_SETTINGS, + default: true, + }, "room_directory_servers": { supportedLevels: [SettingLevel.ACCOUNT], default: [], diff --git a/test/components/views/spaces/SpacePanel-test.tsx b/test/components/views/spaces/SpacePanel-test.tsx index a84868b46025..419d02ee0854 100644 --- a/test/components/views/spaces/SpacePanel-test.tsx +++ b/test/components/views/spaces/SpacePanel-test.tsx @@ -1,5 +1,5 @@ /* -Copyright 2022 The Matrix.org Foundation C.I.C. +Copyright 2023 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,17 +15,16 @@ limitations under the License. */ import React from "react"; -import { render, screen, fireEvent } from "@testing-library/react"; +import { render, screen, fireEvent, cleanup } from "@testing-library/react"; import { mocked } from "jest-mock"; -import { MatrixClient } from "matrix-js-sdk/src/matrix"; import UnwrappedSpacePanel from "../../../../src/components/views/spaces/SpacePanel"; -import { MatrixClientPeg } from "../../../../src/MatrixClientPeg"; import { SpaceKey } from "../../../../src/stores/spaces"; import { shouldShowComponent } from "../../../../src/customisations/helpers/UIComponents"; import { UIComponent } from "../../../../src/settings/UIFeature"; -import { wrapInSdkContext } from "../../../test-utils"; +import { stubClient, wrapInSdkContext } from "../../../test-utils"; import { SdkContextClass } from "../../../../src/contexts/SDKContext"; +import AbstractLocalStorageSettingsHandler from "../../../../src/settings/handlers/AbstractLocalStorageSettingsHandler"; jest.mock("../../../../src/stores/spaces/SpaceStore", () => { // eslint-disable-next-line @typescript-eslint/no-var-requires @@ -45,16 +44,31 @@ jest.mock("../../../../src/customisations/helpers/UIComponents", () => ({ shouldShowComponent: jest.fn(), })); +// function mockLocalStorage(): Storage { +// const storage = new Map(); + +// return { +// length: 0, +// getItem: (key: string): string | null => { +// if (!storage.has(key)) { +// console.debug("Missing key: " + key); +// return null; +// } +// console.debug("Found key: " + key + "=" + storage.get(key)!); +// return storage.get(key)!; +// }, +// setItem: (key, value) => { +// console.debug(`Setting key ${key}=${value}`); +// storage.set(key, value); +// }, +// } as Storage; +// } + describe("", () => { - const mockClient = { - getUserId: jest.fn().mockReturnValue("@test:test"), - isGuest: jest.fn(), - getAccountData: jest.fn(), - } as unknown as MatrixClient; const SpacePanel = wrapInSdkContext(UnwrappedSpacePanel, SdkContextClass.instance); beforeAll(() => { - jest.spyOn(MatrixClientPeg, "get").mockReturnValue(mockClient); + stubClient(); }); beforeEach(() => { @@ -80,4 +94,34 @@ describe("", () => { screen.getByTestId("create-space-button"); }); }); + + describe("collapsing", () => { + const clickCollapse = () => fireEvent.click(screen.getByTestId("collapse-space-panel-button")); + + beforeEach(() => { + localStorage.clear(); + AbstractLocalStorageSettingsHandler.clear(); + }); + + it("should expand", () => { + const res = render(); + const panel = res.baseElement.querySelector(".mx_SpacePanel"); + expect(panel).toHaveClass("collapsed"); + + clickCollapse(); + expect(panel).not.toHaveClass("collapsed"); + }); + + it("should remember its collapsed state", () => { + // Render a panel and expand it + render(); + clickCollapse(); + cleanup(); + + // Re-render + const res = render(); + const newPanel = res.baseElement.querySelector(".mx_SpacePanel"); + expect(newPanel).not.toHaveClass("collapsed"); + }); + }); });