From aaa95b8a5e5389544b3562ccddd0070f14511315 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Wed, 8 Jul 2026 15:29:36 +0200 Subject: [PATCH 1/4] Remove unused Favourites and People metaspaces --- .../dialogs/spotlight/SpotlightDialog.tsx | 5 -- .../tabs/user/SidebarUserSettingsTab.tsx | 9 +-- .../components/views/spaces/SpacePanel.tsx | 32 --------- apps/web/src/stores/spaces/SpaceStore.test.ts | 14 ---- apps/web/src/stores/spaces/SpaceStore.ts | 71 +++---------------- apps/web/src/stores/spaces/index.ts | 14 +--- 6 files changed, 10 insertions(+), 135 deletions(-) diff --git a/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx b/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx index 6215daaf00d..2c5caa402da 100644 --- a/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx +++ b/apps/web/src/components/views/dialogs/spotlight/SpotlightDialog.tsx @@ -35,7 +35,6 @@ import { RoomIcon, SpaceIcon, UserProfileIcon, - FavouriteIcon, HomeIcon, GroupIcon, CloseIcon, @@ -156,10 +155,6 @@ function metaspaceToIcon(key: MetaSpace): JSX.Element | undefined { switch (key) { case MetaSpace.Home: return ; - case MetaSpace.Favourites: - return ; - case MetaSpace.People: - return ; case MetaSpace.Orphans: return ; } diff --git a/apps/web/src/components/views/settings/tabs/user/SidebarUserSettingsTab.tsx b/apps/web/src/components/views/settings/tabs/user/SidebarUserSettingsTab.tsx index 1b494b885f3..31df91ba5e1 100644 --- a/apps/web/src/components/views/settings/tabs/user/SidebarUserSettingsTab.tsx +++ b/apps/web/src/components/views/settings/tabs/user/SidebarUserSettingsTab.tsx @@ -34,14 +34,7 @@ export const onMetaSpaceChangeFactory = PosthogTrackers.trackInteraction( interactionName, e, - [ - MetaSpace.Home, - null, - MetaSpace.Favourites, - MetaSpace.People, - MetaSpace.Orphans, - MetaSpace.VideoRooms, - ].indexOf(metaSpace), + [MetaSpace.Home, null, MetaSpace.Orphans, MetaSpace.VideoRooms].indexOf(metaSpace), ); }; diff --git a/apps/web/src/components/views/spaces/SpacePanel.tsx b/apps/web/src/components/views/spaces/SpacePanel.tsx index 3232ed1b510..03023c5d49a 100644 --- a/apps/web/src/components/views/spaces/SpacePanel.tsx +++ b/apps/web/src/components/views/spaces/SpacePanel.tsx @@ -25,11 +25,9 @@ import { DragDropContext, Draggable, Droppable, type DroppableProvidedProps } fr import classNames from "classnames"; import { type Room } from "matrix-js-sdk/src/matrix"; import { - FavouriteSolidIcon, HomeSolidIcon, RoomIcon, VideoCallSolidIcon, - UserProfileSolidIcon, PlusIcon, ChevronRightIcon, } from "@vector-im/compound-design-tokens/assets/web/icons"; @@ -178,34 +176,6 @@ const HomeButton: React.FC = ({ selected, isPanelCollapsed ); }; -const FavouritesButton: React.FC = ({ selected, isPanelCollapsed }) => { - return ( - } - /> - ); -}; - -const PeopleButton: React.FC = ({ selected, isPanelCollapsed }) => { - return ( - } - /> - ); -}; - const OrphansButton: React.FC = ({ selected, isPanelCollapsed }) => { return ( = { [MetaSpace.Home]: HomeButton, - [MetaSpace.Favourites]: FavouritesButton, - [MetaSpace.People]: PeopleButton, [MetaSpace.Orphans]: OrphansButton, [MetaSpace.VideoRooms]: VideoRoomsButton, }; diff --git a/apps/web/src/stores/spaces/SpaceStore.test.ts b/apps/web/src/stores/spaces/SpaceStore.test.ts index 1cf35e09928..94f4b751db3 100644 --- a/apps/web/src/stores/spaces/SpaceStore.test.ts +++ b/apps/web/src/stores/spaces/SpaceStore.test.ts @@ -134,8 +134,6 @@ describe("SpaceStore", () => { await SettingsStore.setValue("Spaces.enabledMetaSpaces", null, SettingLevel.DEVICE, { [MetaSpace.Home]: true, - [MetaSpace.Favourites]: true, - [MetaSpace.People]: true, [MetaSpace.Orphans]: true, }); @@ -444,12 +442,6 @@ describe("SpaceStore", () => { expect(store.isRoomInSpace(MetaSpace.Home, room1)).toBeTruthy(); }); - it("people space does contain people even if they are also shown in a space", async () => { - expect(store.isRoomInSpace(MetaSpace.People, dm1)).toBeTruthy(); - expect(store.isRoomInSpace(MetaSpace.People, dm2)).toBeTruthy(); - expect(store.isRoomInSpace(MetaSpace.People, dm3)).toBeTruthy(); - }); - it("orphans space does contain orphans even if they are also shown in all rooms", async () => { await setShowAllRooms(true); expect(store.isRoomInSpace(MetaSpace.Orphans, orphan1)).toBeTruthy(); @@ -1259,8 +1251,6 @@ describe("SpaceStore", () => { expect(SpaceStore.instance.spacePanelSpaces).toStrictEqual([rootSpace]); expect(SpaceStore.instance.isRoomInSpace(space1, room1)).toBeTruthy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Home, room1)).toBeFalsy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Favourites, room1)).toBeFalsy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.People, room1)).toBeFalsy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Orphans, room1)).toBeFalsy(); // receive room invite @@ -1273,8 +1263,6 @@ describe("SpaceStore", () => { expect(SpaceStore.instance.spacePanelSpaces).toStrictEqual([rootSpace]); expect(SpaceStore.instance.isRoomInSpace(space1, room2)).toBeTruthy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Home, room2)).toBeTruthy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Favourites, room2)).toBeFalsy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.People, room2)).toBeFalsy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Orphans, room2)).toBeFalsy(); // start DM in space @@ -1314,8 +1302,6 @@ describe("SpaceStore", () => { expect(SpaceStore.instance.spacePanelSpaces).toStrictEqual([rootSpace]); expect(SpaceStore.instance.isRoomInSpace(space1, dm1)).toBeTruthy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Home, dm1)).toBeTruthy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Favourites, dm1)).toBeFalsy(); - expect(SpaceStore.instance.isRoomInSpace(MetaSpace.People, dm1)).toBeTruthy(); expect(SpaceStore.instance.isRoomInSpace(MetaSpace.Orphans, dm1)).toBeFalsy(); // join subspace diff --git a/apps/web/src/stores/spaces/SpaceStore.ts b/apps/web/src/stores/spaces/SpaceStore.ts index 5d8e6801504..56a25ee229b 100644 --- a/apps/web/src/stores/spaces/SpaceStore.ts +++ b/apps/web/src/stores/spaces/SpaceStore.ts @@ -29,7 +29,6 @@ import SettingsStore from "../../settings/SettingsStore"; import DMRoomMap from "../../utils/DMRoomMap"; import { SpaceNotificationState } from "../notifications/SpaceNotificationState"; import { RoomNotificationStateStore } from "../notifications/RoomNotificationStateStore"; -import { DefaultTagID } from "../room-list-v3/skip-list/tag"; import { EnhancedMap, mapDiff } from "../../utils/maps"; import { setDiff, setHasDiff } from "../../utils/sets"; import { Action } from "../../dispatcher/actions"; @@ -451,7 +450,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } // beyond this point we know this is a DM - if (space === MetaSpace.Home || space === MetaSpace.People) { + if (space === MetaSpace.Home) { // these spaces contain all DMs return true; } @@ -648,13 +647,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.roomIdsBySpace.delete(MetaSpace.Home); } - if (enabledMetaSpaces.has(MetaSpace.Favourites)) { - const favourites = visibleRooms.filter((r) => r.tags[DefaultTagID.Favourite]); - this.roomIdsBySpace.set(MetaSpace.Favourites, new Set(favourites.map((r) => r.roomId))); - } else { - this.roomIdsBySpace.delete(MetaSpace.Favourites); - } - // The People metaspace doesn't need maintaining // Populate the orphans space if the Home space is enabled as it is a superset of it. @@ -678,18 +670,13 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const visibleRooms = this.matrixClient.getVisibleRooms(this._msc3946ProcessDynamicPredecessor); let dmBadgeSpace: MetaSpace | undefined; - // only show badges on dms on the most relevant space if such exists - if (enabledMetaSpaces.has(MetaSpace.People)) { - dmBadgeSpace = MetaSpace.People; - } else if (enabledMetaSpaces.has(MetaSpace.Home)) { + // only show badges on home + if (enabledMetaSpaces.has(MetaSpace.Home)) { dmBadgeSpace = MetaSpace.Home; } if (!spaces) { spaces = [...this.roomIdsBySpace.keys()]; - if (dmBadgeSpace === MetaSpace.People) { - spaces.push(MetaSpace.People); - } if (enabledMetaSpaces.has(MetaSpace.Home) && !this.allRoomsInHome) { spaces.push(MetaSpace.Home); } @@ -703,10 +690,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { // Update NotificationStates this.getNotificationState(s).setRooms( visibleRooms.filter((room) => { - if (s === MetaSpace.People) { - return this.isRoomInSpace(MetaSpace.People, room.roomId); - } - if (room.isSpaceRoom() || !flattenedRoomsForSpace.has(room.roomId)) return false; if (dmBadgeSpace && DMRoomMap.shared().getUserIdForRoomId(room.roomId)) { @@ -717,10 +700,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { }), ); }); - - if (dmBadgeSpace !== MetaSpace.People) { - this.notificationStateMap.delete(MetaSpace.People); - } }; private showInHomeSpace = (room: Room): boolean => { @@ -885,13 +864,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.switchSpaceIfNeeded(); } - const notificationStatesToUpdate = [...changeSet]; - // We update the People metaspace even if we didn't detect any changes - // as roomIdsBySpace does not pre-calculate it so we have to assume it could have changed - if (this.enabledMetaSpaces.includes(MetaSpace.People)) { - notificationStatesToUpdate.push(MetaSpace.People); - } - this.updateNotificationStates(notificationStatesToUpdate); + this.updateNotificationStates([...changeSet]); }; private switchSpaceIfNeeded = (roomId = SDKContextClass.instance.roomViewStore.getRoomId()): void => { @@ -1070,27 +1043,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient { if (order !== lastOrder) { this.notifyIfOrderChanged(); } - } else if (ev.getType() === EventType.Tag) { - // If the room was in favourites and now isn't or the opposite then update its position in the trees - const oldTags = lastEv?.getContent()?.tags || {}; - const newTags = ev.getContent()?.tags || {}; - if (!!oldTags[DefaultTagID.Favourite] !== !!newTags[DefaultTagID.Favourite]) { - this.onRoomFavouriteChange(room); - } } }; - private onRoomFavouriteChange(room: Room): void { - if (this.enabledMetaSpaces.includes(MetaSpace.Favourites)) { - if (room.tags[DefaultTagID.Favourite]) { - this.roomIdsBySpace.get(MetaSpace.Favourites)?.add(room.roomId); - } else { - this.roomIdsBySpace.get(MetaSpace.Favourites)?.delete(room.roomId); - } - this.emit(MetaSpace.Favourites); - } - } - private onRoomDmChange(room: Room, isDm: boolean): void { const enabledMetaSpaces = new Set(this.enabledMetaSpaces); @@ -1105,10 +1060,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { this.emit(MetaSpace.Home); } - if (enabledMetaSpaces.has(MetaSpace.People)) { - this.emit(MetaSpace.People); - } - if (enabledMetaSpaces.has(MetaSpace.Orphans) || enabledMetaSpaces.has(MetaSpace.Home)) { if (isDm && this.roomIdsBySpace.get(MetaSpace.Orphans)?.delete(room.roomId)) { this.emit(MetaSpace.Orphans); @@ -1204,8 +1155,6 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const enabled = new Set(this.enabledMetaSpaces); PosthogAnalytics.instance.setProperty("WebMetaSpaceHomeEnabled", enabled.has(MetaSpace.Home)); PosthogAnalytics.instance.setProperty("WebMetaSpaceHomeAllRooms", this.allRoomsInHome); - PosthogAnalytics.instance.setProperty("WebMetaSpacePeopleEnabled", enabled.has(MetaSpace.People)); - PosthogAnalytics.instance.setProperty("WebMetaSpaceFavouritesEnabled", enabled.has(MetaSpace.Favourites)); PosthogAnalytics.instance.setProperty("WebMetaSpaceOrphansEnabled", enabled.has(MetaSpace.Orphans)); } @@ -1292,13 +1241,9 @@ export class SpaceStoreClass extends AsyncStoreWithClient { const newValue = SettingsStore.getValue("Spaces.enabledMetaSpaces"); const enabledMetaSpaces = metaSpaceOrder.filter((k) => newValue[k]); if (arrayHasDiff(this._enabledMetaSpaces, enabledMetaSpaces)) { - const hadPeopleOrHomeEnabled = this.enabledMetaSpaces.some((s) => { - return s === MetaSpace.Home || s === MetaSpace.People; - }); + const hadHomeEnabled = this.enabledMetaSpaces.some((s) => s === MetaSpace.Home); this._enabledMetaSpaces = enabledMetaSpaces; - const hasPeopleOrHomeEnabled = this.enabledMetaSpaces.some((s) => { - return s === MetaSpace.Home || s === MetaSpace.People; - }); + const hasHomeEnabled = this.enabledMetaSpaces.some((s) => s === MetaSpace.Home); // if a metaspace currently being viewed was removed, go to another one if (isMetaSpace(this.activeSpace) && !newValue[this.activeSpace]) { @@ -1306,7 +1251,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { } this.rebuildMetaSpaces(); - if (hadPeopleOrHomeEnabled !== hasPeopleOrHomeEnabled) { + if (hadHomeEnabled !== hasHomeEnabled) { // in this case we have to rebuild everything as DM badges will move to/from real spaces this.updateNotificationStates(); } else { @@ -1323,7 +1268,7 @@ export class SpaceStoreClass extends AsyncStoreWithClient { if (payload.roomId) { // getSpaceFilteredUserIds will return the appropriate value this.emit(payload.roomId); - if (!this.enabledMetaSpaces.some((s) => s === MetaSpace.Home || s === MetaSpace.People)) { + if (!this.enabledMetaSpaces.some((s) => s === MetaSpace.Home)) { this.updateNotificationStates([payload.roomId]); } } diff --git a/apps/web/src/stores/spaces/index.ts b/apps/web/src/stores/spaces/index.ts index fb642b638d5..8c9865d1dce 100644 --- a/apps/web/src/stores/spaces/index.ts +++ b/apps/web/src/stores/spaces/index.ts @@ -21,8 +21,6 @@ export const UPDATE_SUGGESTED_ROOMS = Symbol("suggested-rooms"); export enum MetaSpace { Home = "home-space", - Favourites = "favourites-space", - People = "people-space", Orphans = "orphans-space", VideoRooms = "video-rooms-space", } @@ -31,10 +29,6 @@ export const getMetaSpaceName = (spaceKey: MetaSpace, allRoomsInHome = false): s switch (spaceKey) { case MetaSpace.Home: return allRoomsInHome ? _t("common|all_chats") : _t("common|home"); - case MetaSpace.Favourites: - return _t("common|favourites"); - case MetaSpace.People: - return _t("common|people"); case MetaSpace.Orphans: return _t("common|orphan_rooms"); case MetaSpace.VideoRooms: @@ -57,11 +51,5 @@ export interface ISuggestedRoom extends HierarchyRoom { } export function isMetaSpace(spaceKey?: SpaceKey): spaceKey is MetaSpace { - return ( - spaceKey === MetaSpace.Home || - spaceKey === MetaSpace.Favourites || - spaceKey === MetaSpace.People || - spaceKey === MetaSpace.Orphans || - spaceKey === MetaSpace.VideoRooms - ); + return spaceKey === MetaSpace.Home || spaceKey === MetaSpace.Orphans || spaceKey === MetaSpace.VideoRooms; } From db6525edd40b7e7d3f472883b3a4ad9171b0a213 Mon Sep 17 00:00:00 2001 From: Florian Duros Date: Wed, 8 Jul 2026 15:29:48 +0200 Subject: [PATCH 2/4] Update existing tests --- .../views/dialogs/SpotlightDialog-test.tsx | 25 ++++++++----------- .../tabs/user/SidebarUserSettingsTab-test.tsx | 4 --- .../views/spaces/SpacePanel-test.tsx | 8 +----- .../views/spaces/SpaceTreeLevel-test.tsx | 16 ++++++------ 4 files changed, 19 insertions(+), 34 deletions(-) diff --git a/apps/web/test/unit-tests/components/views/dialogs/SpotlightDialog-test.tsx b/apps/web/test/unit-tests/components/views/dialogs/SpotlightDialog-test.tsx index 1cbb5b3e037..4e22afea187 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/SpotlightDialog-test.tsx +++ b/apps/web/test/unit-tests/components/views/dialogs/SpotlightDialog-test.tsx @@ -706,24 +706,19 @@ describe("Spotlight Dialog", () => { beforeEach(() => { jest.spyOn(SpaceStore.instance, "enabledMetaSpaces", "get").mockReturnValue([ MetaSpace.Home, - MetaSpace.Favourites, - MetaSpace.People, MetaSpace.Orphans, ]); }); - it.each([MetaSpace.Home, MetaSpace.Favourites, MetaSpace.People])( - "should show metaspace %s", - async (metaSpace) => { - const onFinished = jest.fn(); - const { asFragment, container } = render( - , - ); - await waitFor(() => - expect(container.querySelector(".mx_SpotlightDialog_metaspaceResult")).toBeInTheDocument(), - ); - expect(asFragment()).toMatchSnapshot(); - }, - ); + it("should show Home metaspace", async () => { + const onFinished = jest.fn(); + const { asFragment, container } = render( + , + ); + await waitFor(() => + expect(container.querySelector(".mx_SpotlightDialog_metaspaceResult")).toBeInTheDocument(), + ); + expect(asFragment()).toMatchSnapshot(); + }); }); }); diff --git a/apps/web/test/unit-tests/components/views/settings/tabs/user/SidebarUserSettingsTab-test.tsx b/apps/web/test/unit-tests/components/views/settings/tabs/user/SidebarUserSettingsTab-test.tsx index e1c7e4a3273..00a7eea1d10 100644 --- a/apps/web/test/unit-tests/components/views/settings/tabs/user/SidebarUserSettingsTab-test.tsx +++ b/apps/web/test/unit-tests/components/views/settings/tabs/user/SidebarUserSettingsTab-test.tsx @@ -50,8 +50,6 @@ describe("", () => { if (settingName === "Spaces.enabledMetaSpaces") { return { [MetaSpace.Home]: true, - [MetaSpace.Favourites]: true, - [MetaSpace.People]: true, [MetaSpace.Orphans]: true, }; } @@ -77,8 +75,6 @@ describe("", () => { if (settingName === "Spaces.enabledMetaSpaces") { return { [MetaSpace.Home]: false, - [MetaSpace.Favourites]: true, - [MetaSpace.People]: true, [MetaSpace.Orphans]: true, }; } diff --git a/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx b/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx index 455895b2918..598d029f1f8 100644 --- a/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx +++ b/apps/web/test/unit-tests/components/views/spaces/SpacePanel-test.tsx @@ -135,13 +135,7 @@ describe("", () => { }); beforeEach(() => { - SpaceStore.instance.enabledMetaSpaces.push( - MetaSpace.Home, - MetaSpace.Favourites, - MetaSpace.People, - MetaSpace.Orphans, - MetaSpace.VideoRooms, - ); + SpaceStore.instance.enabledMetaSpaces.push(MetaSpace.Home, MetaSpace.Orphans, MetaSpace.VideoRooms); mocked(shouldShowComponent).mockClear().mockReturnValue(true); }); afterEach(() => { diff --git a/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx b/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx index 2dd6ac5016e..87e52f79dfa 100644 --- a/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx +++ b/apps/web/test/unit-tests/components/views/spaces/SpaceTreeLevel-test.tsx @@ -81,9 +81,9 @@ describe("SpaceButton", () => { it("activates the metaspace on click", () => { const { container } = render( , @@ -91,15 +91,15 @@ describe("SpaceButton", () => { expect(SpaceStore.instance.setActiveSpace).not.toHaveBeenCalled(); fireEvent.click(getByTestId(container, "create-space-button")); - expect(SpaceStore.instance.setActiveSpace).toHaveBeenCalledWith(MetaSpace.People); + expect(SpaceStore.instance.setActiveSpace).toHaveBeenCalledWith(MetaSpace.Home); }); it("does nothing on click if already active", () => { const { container } = render( , @@ -108,7 +108,7 @@ describe("SpaceButton", () => { fireEvent.click(getByTestId(container, "create-space-button")); expect(dispatchSpy).not.toHaveBeenCalled(); // Re-activating the metaspace is a no-op - expect(SpaceStore.instance.setActiveSpace).toHaveBeenCalledWith(MetaSpace.People); + expect(SpaceStore.instance.setActiveSpace).toHaveBeenCalledWith(MetaSpace.Home); }); it("should render notificationState if one is provided", () => { @@ -116,9 +116,9 @@ describe("SpaceButton", () => { const { container, asFragment } = render( Date: Wed, 8 Jul 2026 15:29:55 +0200 Subject: [PATCH 3/4] Update snapshots --- .../SpotlightDialog-test.tsx.snap | 508 +----------------- .../__snapshots__/SpacePanel-test.tsx.snap | 83 --- .../SpaceTreeLevel-test.tsx.snap | 4 +- 3 files changed, 3 insertions(+), 592 deletions(-) diff --git a/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/SpotlightDialog-test.tsx.snap b/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/SpotlightDialog-test.tsx.snap index c66af206da8..085cd6fdb74 100644 --- a/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/SpotlightDialog-test.tsx.snap +++ b/apps/web/test/unit-tests/components/views/dialogs/__snapshots__/SpotlightDialog-test.tsx.snap @@ -1,256 +1,6 @@ // Jest Snapshot v1, https://jestjs.io/docs/snapshot-testing -exports[`Spotlight Dialog metaspaces should show metaspace favourites-space 1`] = ` - -
- - Use - - ↓ - - - ↑ - - to scroll - -
-
-