diff --git a/apps/web/src/settings/Settings.tsx b/apps/web/src/settings/Settings.tsx index ba6b84e9c1..b027283610 100644 --- a/apps/web/src/settings/Settings.tsx +++ b/apps/web/src/settings/Settings.tsx @@ -1385,11 +1385,11 @@ export const SETTINGS: Settings = { }, /** * Managed by the {@link RoomListStoreV3} - * Store the ordering of the custom sections for the room list + * Store the ordering of the custom sections for the room list, keyed by space/metaspace ID. */ "RoomList.OrderedCustomSections": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, - default: [], + default: {}, }, [UIFeature.RoomHistorySettings]: { supportedLevels: LEVELS_UI_FEATURE, diff --git a/apps/web/src/stores/room-list-v3/RoomListStoreV3.ts b/apps/web/src/stores/room-list-v3/RoomListStoreV3.ts index 60b86ddc81..0516826807 100644 --- a/apps/web/src/stores/room-list-v3/RoomListStoreV3.ts +++ b/apps/web/src/stores/room-list-v3/RoomListStoreV3.ts @@ -442,6 +442,8 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient { private onActiveSpaceChanged(): void { if (!this.roomSkipList) return; + this.loadCustomSections(); + this.roomSkipList.useNewFilters(this.getSkipListFilters()); this.roomSkipList.calculateActiveSpaceForNodes(); this.scheduleEmit(); } @@ -492,7 +494,7 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient { * Emits {@link SECTION_CREATED_EVENT} if the section was successfully created. */ public async createSection(): Promise { - const tag = await createSection(); + const tag = await createSection(SpaceStore.instance.activeSpace); if (!tag) return; this.emit(SECTION_CREATED_EVENT, tag); return tag; @@ -525,11 +527,14 @@ export class RoomListStoreV3Class extends AsyncStoreWithClient { } /** - * Load the custom sections from the settings store and update the sorted tags. + * Load the custom sections from the settings store and update the sorted tags, + * filtering to only those belonging to the currently active space. */ private loadCustomSections(): void { - const orderedCustomSections = SettingsStore.getValue("RoomList.OrderedCustomSections"); - this.sortedTags = [DefaultTagID.Favourite, ...orderedCustomSections, CHATS_TAG, DefaultTagID.LowPriority]; + const activeSpace = SpaceStore.instance.activeSpace; + const orderedCustomSections: Record = SettingsStore.getValue("RoomList.OrderedCustomSections") || {}; + const spaceSections = orderedCustomSections[activeSpace] ?? []; + this.sortedTags = [DefaultTagID.Favourite, ...spaceSections, CHATS_TAG, DefaultTagID.LowPriority]; } } diff --git a/apps/web/src/stores/room-list-v3/section.ts b/apps/web/src/stores/room-list-v3/section.ts index 5cd4f97169..785884cf18 100644 --- a/apps/web/src/stores/room-list-v3/section.ts +++ b/apps/web/src/stores/room-list-v3/section.ts @@ -12,6 +12,7 @@ import SettingsStore from "../../settings/SettingsStore"; import Modal from "../../Modal"; import { CreateSectionDialog } from "../../components/views/dialogs/CreateSectionDialog"; import { RemoveSectionDialog } from "../../components/views/dialogs/RemoveSectionDialog"; +import { type SpaceKey } from "../spaces"; type Tag = string; @@ -35,40 +36,45 @@ export function isCustomSectionTag(tag: string): boolean { type CustomSection = { tag: Tag; name: string; + /** The space or metaspace this section belongs to. */ + spaceId: SpaceKey; }; /** - * The custom sections data is stored as a record in the settings, where the key is the section tag and the value is the section data (name and tag). + * The custom sections data is stored as a record in the settings, where the key is the section tag and the value is the section data (name, tag and spaceId). */ export type CustomSectionsData = Record; /** - * Ordered list of custom section tags. + * Ordered list of custom section tags, keyed by space/metaspace ID. */ -export type OrderedCustomSections = Tag[]; +export type OrderedCustomSections = Record; /** * Creates a new custom section by showing a dialog to the user to enter the section name. * If the user confirms, it generates a unique tag for the section, saves the section data in the settings, and updates the ordered list of sections. * + * @param spaceId - The space or metaspace this section is being created in. * @return A promise that resolves to the new section tag if created, or undefined if cancelled. */ -export async function createSection(): Promise { +export async function createSection(spaceId: SpaceKey): Promise { const modal = Modal.createDialog(CreateSectionDialog); const [shouldCreateSection, sectionName] = await modal.finished; if (!shouldCreateSection || !sectionName) return undefined; const tag = `${CUSTOM_SECTION_TAG_PREFIX}${window.crypto.randomUUID()}`; - const newSection: CustomSection = { tag, name: sectionName }; + const newSection: CustomSection = { tag, name: sectionName, spaceId }; // Save the new section data const sectionData = SettingsStore.getValue("RoomList.CustomSectionData") || {}; sectionData[tag] = newSection; await SettingsStore.setValue("RoomList.CustomSectionData", null, SettingLevel.ACCOUNT, sectionData); - // Add the new section to the ordered list of sections - const orderedSections = SettingsStore.getValue("RoomList.OrderedCustomSections") || []; - orderedSections.push(tag); + // Add the new section to the ordered list of sections for this space + const orderedSections: OrderedCustomSections = SettingsStore.getValue("RoomList.OrderedCustomSections") || {}; + const spaceSections = orderedSections[spaceId] ?? []; + spaceSections.push(tag); + orderedSections[spaceId] = spaceSections; await SettingsStore.setValue("RoomList.OrderedCustomSections", null, SettingLevel.ACCOUNT, orderedSections); return tag; } @@ -112,10 +118,13 @@ export async function deleteSection(tag: string, isEmpty: boolean): Promise sectionTag !== tag); - await SettingsStore.setValue("RoomList.OrderedCustomSections", null, SettingLevel.ACCOUNT, newOrderedSections); + // Remove the section from the ordered list of sections for its space + const spaceId = sectionData[tag].spaceId; + const orderedSections: OrderedCustomSections = SettingsStore.getValue("RoomList.OrderedCustomSections") || {}; + if (orderedSections[spaceId]) { + orderedSections[spaceId] = orderedSections[spaceId].filter((sectionTag) => sectionTag !== tag); + } + await SettingsStore.setValue("RoomList.OrderedCustomSections", null, SettingLevel.ACCOUNT, orderedSections); // Remove the section data delete sectionData[tag];