Room list: add collapse/expand all sections (#33318)
* chore: update compound design tokens * feat(sc): add collapse/expand button to room list header * feat: add new events to broadcast section state * feat(vm): add expand/collpase event to room list events * test: add e2e tests * chore: fix company name in copyright * chore: use two differant actions for collapse/expand * Update apps/web/src/viewmodels/room-list/RoomListHeaderViewModel.ts Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> * test: fix existing tests --------- Co-authored-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
co-authored by
Michael Telatynski
parent
a7ab72af11
commit
c2e5aa7adc
@@ -26,6 +26,7 @@ import {
|
||||
showSpaceSettings,
|
||||
} from "../../utils/space";
|
||||
import type { ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
|
||||
import type { RoomListSectionsCollapseStateChangedPayload } from "../../dispatcher/payloads/RoomListSectionsCollapseStateChangedPayload";
|
||||
import SettingsStore from "../../settings/SettingsStore";
|
||||
import RoomListStoreV3 from "../../stores/room-list-v3/RoomListStoreV3";
|
||||
import { SortingAlgorithm } from "../../stores/room-list-v3/skip-list/sorters";
|
||||
@@ -77,6 +78,10 @@ export class RoomListHeaderViewModel
|
||||
if (this.activeSpace) {
|
||||
this.disposables.trackListener(this.activeSpace, RoomEvent.Name, this.onSpaceNameChange);
|
||||
}
|
||||
|
||||
// Listen for section collapse state changes from RoomListViewModel
|
||||
const dispatcherRef = defaultDispatcher.register(this.onDispatch);
|
||||
this.disposables.track(() => defaultDispatcher.unregister(dispatcherRef));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -203,6 +208,23 @@ export class RoomListHeaderViewModel
|
||||
public createSection = (): void => {
|
||||
RoomListStoreV3.instance.createSection();
|
||||
};
|
||||
|
||||
public collapseOrExpandSections = (): void => {
|
||||
const action =
|
||||
this.snapshot.current.collapseSections === "expand"
|
||||
? Action.RoomListExpandAllSections
|
||||
: Action.RoomListCollapseAllSections;
|
||||
defaultDispatcher.fire(action);
|
||||
};
|
||||
|
||||
private readonly onDispatch = (payload: { action: string }): void => {
|
||||
if (payload.action === Action.RoomListSectionsCollapseStateChanged) {
|
||||
const { collapseSections } = payload as RoomListSectionsCollapseStateChangedPayload;
|
||||
this.snapshot.merge({
|
||||
collapseSections: collapseSections && (collapseSections === "collapse" ? "expand" : "collapse"),
|
||||
});
|
||||
}
|
||||
};
|
||||
}
|
||||
/**
|
||||
* Get the initial snapshot for the RoomListHeaderViewModel.
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Action } from "../../dispatcher/actions";
|
||||
import dispatcher from "../../dispatcher/dispatcher";
|
||||
import { type ViewRoomDeltaPayload } from "../../dispatcher/payloads/ViewRoomDeltaPayload";
|
||||
import { type ViewRoomPayload } from "../../dispatcher/payloads/ViewRoomPayload";
|
||||
import { type RoomListSectionsCollapseStateChangedPayload } from "../../dispatcher/payloads/RoomListSectionsCollapseStateChangedPayload";
|
||||
import SpaceStore from "../../stores/spaces/SpaceStore";
|
||||
import RoomListStoreV3, {
|
||||
CHATS_TAG,
|
||||
@@ -325,9 +326,24 @@ export class RoomListViewModel
|
||||
// Handle keyboard navigation shortcuts (Alt+ArrowUp/Down)
|
||||
// This was previously handled by useRoomListNavigation hook
|
||||
this.handleViewRoomDelta(payload as ViewRoomDeltaPayload);
|
||||
} else if (payload.action === Action.RoomListCollapseAllSections) {
|
||||
this.onCollapseAllSections(false);
|
||||
} else if (payload.action === Action.RoomListExpandAllSections) {
|
||||
this.onCollapseAllSections(true);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Handles the collapse or expansion of all sections in the room list.
|
||||
* @param expand - Whether to expand or collapse all sections
|
||||
*/
|
||||
private onCollapseAllSections(expand: boolean): void {
|
||||
for (const sectionHeaderVM of this.roomSectionHeaderViewModels.values()) {
|
||||
sectionHeaderVM.isExpanded = expand;
|
||||
}
|
||||
this.updateRoomListData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle keyboard navigation shortcuts (Alt+ArrowUp/Down) to move between rooms.
|
||||
* Supports both regular navigation and unread-only navigation.
|
||||
@@ -581,6 +597,32 @@ export class RoomListViewModel
|
||||
sections: keepIfSame(previousSections, viewSections),
|
||||
isFlatList,
|
||||
});
|
||||
|
||||
this.notifyCollapseState(isFlatList);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the dispatcher about the current collapse state of the room list sections.
|
||||
* @param isFlatList - Whether the room list is currently displayed as a flat list
|
||||
*/
|
||||
private notifyCollapseState(isFlatList: boolean): void {
|
||||
// Hide collapse/expand all button if sections are disabled or if it's a flat list
|
||||
if (!SettingsStore.getValue("feature_room_list_sections") || isFlatList) {
|
||||
dispatcher.dispatch<RoomListSectionsCollapseStateChangedPayload>({
|
||||
action: Action.RoomListSectionsCollapseStateChanged,
|
||||
collapseSections: undefined,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Determine if all sections are currently collapsed
|
||||
const allCollapsed = this.snapshot.current.sections.every(
|
||||
({ id }) => !(this.roomSectionHeaderViewModels.get(id)?.isExpanded ?? true),
|
||||
);
|
||||
dispatcher.dispatch<RoomListSectionsCollapseStateChangedPayload>({
|
||||
action: Action.RoomListSectionsCollapseStateChanged,
|
||||
collapseSections: allCollapsed ? "collapse" : "expand",
|
||||
});
|
||||
}
|
||||
|
||||
public createChatRoom = (): void => {
|
||||
|
||||
Reference in New Issue
Block a user