From 21d24f860cff364518e1ce3c3146089a2cd3f99e Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 16 Sep 2025 14:12:40 +0000 Subject: [PATCH 1/6] Upgrade dependency to matrix-js-sdk@38.3.0-rc.0 --- package.json | 2 +- yarn.lock | 19 ++++++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index f5b6464b60..13ddeea72a 100644 --- a/package.json +++ b/package.json @@ -134,7 +134,7 @@ "maplibre-gl": "^5.0.0", "matrix-encrypt-attachment": "^1.0.3", "matrix-events-sdk": "0.0.1", - "matrix-js-sdk": "github:matrix-org/matrix-js-sdk#develop", + "matrix-js-sdk": "38.3.0-rc.0", "matrix-widget-api": "^1.10.0", "memoize-one": "^6.0.0", "mime": "^4.0.4", diff --git a/yarn.lock b/yarn.lock index d4d193357f..ed250ead73 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2652,10 +2652,10 @@ emojibase "^15.3.1" emojibase-data "^15.3.1" -"@matrix-org/matrix-sdk-crypto-wasm@^15.1.0": - version "15.1.0" - resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-15.1.0.tgz#653956f5f6daced55a9df3d2c1114eb2c017b528" - integrity sha512-ZsDdjn46J3+VxsDLmaSODuS+qtGZB/i3Cg9tWL1QPNjvAWzNaTHQ7glleByI2PKVBm83aklfuhGKT2MqE1ZsEA== +"@matrix-org/matrix-sdk-crypto-wasm@^15.2.0": + version "15.3.0" + resolved "https://registry.yarnpkg.com/@matrix-org/matrix-sdk-crypto-wasm/-/matrix-sdk-crypto-wasm-15.3.0.tgz#141fd041ae382b793369bcee4394b0b577bdea0c" + integrity sha512-QyxHvncvkl7nf+tnn92PjQ54gMNV8hMSpiukiDgNrqF6IYwgySTlcSdkPYdw8QjZJ0NR6fnVrNzMec0OohM3wA== "@matrix-org/react-sdk-module-api@^2.4.0": version "2.5.0" @@ -4735,7 +4735,7 @@ classnames "^2.5.1" vaul "^1.0.0" -"@vector-im/matrix-wysiwyg-wasm@link:../../Library/Caches/Yarn/v6/npm-@vector-im-matrix-wysiwyg-2.39.0-a6238e517f23a2f3025d9c65445914771c63b163-integrity/node_modules/bindings/wysiwyg-wasm": +"@vector-im/matrix-wysiwyg-wasm@link:../../../.cache/yarn/v6/npm-@vector-im-matrix-wysiwyg-2.39.0-a6238e517f23a2f3025d9c65445914771c63b163-integrity/node_modules/bindings/wysiwyg-wasm": version "0.0.0" uid "" @@ -11040,12 +11040,13 @@ matrix-events-sdk@0.0.1: resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1.tgz#c8c38911e2cb29023b0bbac8d6f32e0de2c957dd" integrity sha512-1QEOsXO+bhyCroIe2/A5OwaxHvBm7EsSQ46DEDn8RBIfQwN5HWBpFvyWWR4QY0KHPPnnJdI99wgRiAl7Ad5qaA== -"matrix-js-sdk@github:matrix-org/matrix-js-sdk#develop": - version "38.1.0" - resolved "https://codeload.github.com/matrix-org/matrix-js-sdk/tar.gz/82aa04d894d7adc7c6be245220c4a89b69357d26" +matrix-js-sdk@38.3.0-rc.0: + version "38.3.0-rc.0" + resolved "https://registry.yarnpkg.com/matrix-js-sdk/-/matrix-js-sdk-38.3.0-rc.0.tgz#fca926b3495896383d3ba9eb50204dc7359b1d4c" + integrity sha512-7q/xLXWSd4N7c3cymg9uqWgfq9cqnBMHR4/hgBDoNel3EBgK0RFOJuqSvoJCS9rwO7W0TMnjEc8ElnK5LmQFAg== dependencies: "@babel/runtime" "^7.12.5" - "@matrix-org/matrix-sdk-crypto-wasm" "^15.1.0" + "@matrix-org/matrix-sdk-crypto-wasm" "^15.2.0" another-json "^0.2.0" bs58 "^6.0.0" content-type "^1.0.4" From 01bba512005c6174e3a082dfc4b64dd00a72c7d0 Mon Sep 17 00:00:00 2001 From: ElementRobot Date: Tue, 16 Sep 2025 17:52:07 +0100 Subject: [PATCH 2/6] Avoid flicker of the room list filter on resize (#30787) (#30794) * fix: avoid flicker of the room list filter on resize * test: update existing test to render correctly * test: add test to avoid flicker regression (cherry picked from commit 841f12bd46832b5c9d340c5e93a038352bed92d5) Co-authored-by: Florian Duros --- .../RoomListPanel/RoomListPrimaryFilters.tsx | 2 +- .../RoomListPrimaryFilters-test.tsx | 58 ++++++++++++++----- .../RoomListPrimaryFilters-test.tsx.snap | 4 +- 3 files changed, 47 insertions(+), 17 deletions(-) diff --git a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx index a14a39cdc1..e3039bf1cf 100644 --- a/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx +++ b/src/components/views/rooms/RoomListPanel/RoomListPrimaryFilters.tsx @@ -103,7 +103,7 @@ function useCollapseFilters( // If the previous element is on the left element of the current one, it means that the filter is wrapping const previousSibling = child.previousElementSibling as HTMLElement | null; - if (previousSibling && child.offsetLeft < previousSibling.offsetLeft) { + if (previousSibling && child.offsetLeft <= previousSibling.offsetLeft) { if (!isWrapping) setWrappingIndex(i); isWrapping = true; } diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx index d7d4e8314f..8276c7340f 100644 --- a/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx +++ b/test/unit-tests/components/views/rooms/RoomListPanel/RoomListPrimaryFilters-test.tsx @@ -35,15 +35,26 @@ describe("", () => { vm = { primaryFilters: [ - { name: "People", active: false, toggle: filterToggleMocks[0], key: FilterKey.PeopleFilter }, - { name: "Rooms", active: true, toggle: filterToggleMocks[1], key: FilterKey.RoomsFilter }, + { name: "People", active: true, toggle: filterToggleMocks[0], key: FilterKey.PeopleFilter }, + { name: "Rooms", active: false, toggle: filterToggleMocks[1], key: FilterKey.RoomsFilter }, { name: "Unreads", active: false, toggle: filterToggleMocks[2], key: FilterKey.UnreadFilter }, ], } as unknown as RoomListViewState; }); + function mockFiltersOffsetLeft() { + // Use `getByText` instead of `getByRole` to bypass the aria-hidden + jest.spyOn(screen.getByText("People"), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Rooms"), "offsetLeft", "get").mockReturnValue(30); + jest.spyOn(screen.getByText("Unreads"), "offsetLeft", "get").mockReturnValue(60); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + } + it("should renders all filters correctly", () => { const { asFragment } = render(); + mockFiltersOffsetLeft(); // Check that all filters are rendered expect(screen.getByRole("option", { name: "People" })).toBeInTheDocument(); @@ -51,8 +62,8 @@ describe("", () => { expect(screen.getByRole("option", { name: "Unreads" })).toBeInTheDocument(); // Check that the active filter is marked as selected - expect(screen.getByRole("option", { name: "Rooms" })).toHaveAttribute("aria-selected", "true"); - expect(screen.getByRole("option", { name: "People" })).toHaveAttribute("aria-selected", "false"); + expect(screen.getByRole("option", { name: "People" })).toHaveAttribute("aria-selected", "true"); + expect(screen.getByRole("option", { name: "Rooms" })).toHaveAttribute("aria-selected", "false"); expect(screen.getByRole("option", { name: "Unreads" })).toHaveAttribute("aria-selected", "false"); expect(asFragment()).toMatchSnapshot(); @@ -61,6 +72,7 @@ describe("", () => { it("should call toggle function when a filter is clicked", async () => { const user = userEvent.setup(); render(); + mockFiltersOffsetLeft(); // Click on an inactive filter await user.click(screen.getByRole("option", { name: "People" })); @@ -69,24 +81,27 @@ describe("", () => { expect(filterToggleMocks[0]).toHaveBeenCalledTimes(1); }); - function mockFiltersOffsetLeft() { - jest.spyOn(screen.getByRole("option", { name: "People" }), "offsetLeft", "get").mockReturnValue(0); - jest.spyOn(screen.getByRole("option", { name: "Rooms" }), "offsetLeft", "get").mockReturnValue(30); + function makeUnreadWrapping() { + // Use `getByText` instead of `getByRole` to bypass the aria-hidden + jest.spyOn(screen.getByText("People"), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Rooms"), "offsetLeft", "get").mockReturnValue(30); // Unreads is wrapping - jest.spyOn(screen.getByRole("option", { name: "Unreads" }), "offsetLeft", "get").mockReturnValue(0); + jest.spyOn(screen.getByText("Unreads"), "offsetLeft", "get").mockReturnValue(0); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); } it("should hide or display filters if they are wrapping", async () => { const user = userEvent.setup(); render(); + mockFiltersOffsetLeft(); // No filter is wrapping, so chevron shouldn't be visible expect(screen.queryByRole("button", { name: "Expand filter list" })).toBeNull(); expect(screen.queryByRole("option", { name: "Unreads" })).toBeVisible(); - mockFiltersOffsetLeft(); - // @ts-ignore - act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + makeUnreadWrapping(); // The Unreads filter is wrapping, it should not be visible expect(screen.queryByRole("option", { name: "Unreads" })).toBeNull(); @@ -107,9 +122,7 @@ describe("", () => { const user = userEvent.setup(); render(); - mockFiltersOffsetLeft(); - // @ts-ignore - act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + makeUnreadWrapping(); // Unread filter should be moved to the first position expect(screen.getByRole("listbox", { name: "Room list filters" }).children[0]).toBe( @@ -122,4 +135,21 @@ describe("", () => { screen.getByRole("option", { name: "Unreads" }), ); }); + + it("should hide the filter is the previous is on the same vertical position", async () => { + render(); + mockFiltersOffsetLeft(); + + jest.spyOn(screen.getByRole("option", { name: "People" }), "offsetLeft", "get").mockReturnValue(0); + // Rooms is wrapping + jest.spyOn(screen.getByRole("option", { name: "Rooms" }), "offsetLeft", "get").mockReturnValue(0); + + // @ts-ignore + act(() => resizeCallback([{ target: screen.getByRole("listbox", { name: "Room list filters" }) }])); + + // The Unreads filter is wrapping, it should not be visible + expect(screen.queryByRole("option", { name: "Rooms" })).toBeNull(); + // Now filters are wrapping, so chevron should be visible + expect(screen.getByRole("button", { name: "Expand filter list" })).toBeVisible(); + }); }); diff --git a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap index 601a3eb325..cbfab6e2d2 100644 --- a/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap +++ b/test/unit-tests/components/views/rooms/RoomListPanel/__snapshots__/RoomListPrimaryFilters-test.tsx.snap @@ -16,7 +16,7 @@ exports[` should renders all filters correctly 1`] = ` >