fix collapse behaviour

This commit is contained in:
Gimle Larpes 2025-06-28 23:59:00 +02:00
parent 2570e5e25d
commit 6ff0260e8d

View file

@ -313,7 +313,37 @@ export function Space() {
[mx, allJoinedRooms] [mx, allJoinedRooms]
); );
// There are a lot better ways to do this /**
* Recursively checks if a given parentId (and its ancestors) is in a closed category.
*
* @param spaceId - The root space ID.
* @param parentId - The parent space ID to start the check from.
* @returns True if parentId or any ancestor is in a closed category.
*/
const getInClosedCategories = useCallback(
(spaceId: string, parentId: string): boolean => {
if (closedCategories.has(makeNavCategoryId(spaceId, parentId))) {
return true;
}
const parentParentIds = roomToParents.get(parentId);
if (!parentParentIds || parentParentIds.size === 0) {
return false;
}
let closed = false;
parentParentIds.forEach((id) => {
if (getInClosedCategories(spaceId, id)) {
closed = true;
}
});
return closed;
},
[closedCategories, roomToParents]
);
// There are better ways to do this
const roomToChildren = useMemo(() => { const roomToChildren = useMemo(() => {
const map = new Map<string, Set<string>>(); const map = new Map<string, Set<string>>();
roomToParents.forEach((parentSet, childId) => { roomToParents.forEach((parentSet, childId) => {
@ -343,7 +373,6 @@ export function Space() {
return false; return false;
} }
// CHILD CATEGORY SHOULD COLLAPSE IF PARENT IS COLLAPSED (but retain their set state when expanded?)
let visible = false; let visible = false;
childIds.forEach((id) => { childIds.forEach((id) => {
if (getContainsShowRoom(id)) { if (getContainsShowRoom(id)) {
@ -356,24 +385,46 @@ export function Space() {
[roomToUnread, selectedRoomId, roomToChildren] [roomToUnread, selectedRoomId, roomToChildren]
); );
/**
* Determines whether all parent categories are collapsed.
*
* @param spaceId - The root space ID.
* @param roomId - The room ID to start the check from.
* @returns True if every parent category is collapsed; false otherwise.
*/
const getAllAncestorsCollapsed = (spaceId: string, roomId: string): boolean => {
const parentIds = roomToParents.get(roomId);
if (!parentIds || parentIds.size === 0) {
return false;
}
let allCollapsed = true;
parentIds.forEach((id) => {
if (!getInClosedCategories(spaceId, id)) {
allCollapsed = false;
}
});
return allCollapsed;
};
const hierarchy = useSpaceJoinedHierarchy( const hierarchy = useSpaceJoinedHierarchy(
space.roomId, space.roomId,
getRoom, getRoom,
useCallback( useCallback(
(parentId, roomId) => { (parentId, roomId) => {
// closedCategories.has(makeNavCategoryId(spaceId, parentId)) if (!getInClosedCategories(space.roomId, parentId)) {
// NOT SURE THIS IS NEEDED - children of hidden spaces are not displayed
if (!closedCategories.has(makeNavCategoryId(space.roomId, parentId))) {
return false; return false;
} }
if (getContainsShowRoom(roomId)) return false; if (getContainsShowRoom(roomId)) return false;
return true; return true;
}, },
[closedCategories, getContainsShowRoom, space.roomId] [getContainsShowRoom, getInClosedCategories, space.roomId]
), ),
useCallback( useCallback(
(sId) => closedCategories.has(makeNavCategoryId(space.roomId, sId)), (sId) => getInClosedCategories(space.roomId, sId),
[closedCategories, space.roomId] [getInClosedCategories, space.roomId]
) )
); );
@ -384,9 +435,18 @@ export function Space() {
overscan: 10, overscan: 10,
}); });
const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => const handleCategoryClick = useCategoryHandler(setClosedCategories, (categoryId) => {
closedCategories.has(categoryId) const collapsed = closedCategories.has(categoryId);
); const [spaceId, roomId] = categoryId.split('|').slice(-2);
// Only prevent collapsing if all parents are collapsed
const toggleable = !getAllAncestorsCollapsed(spaceId, roomId);
if (toggleable) {
return collapsed;
}
return !collapsed;
});
const getToLink = (roomId: string) => const getToLink = (roomId: string) =>
getSpaceRoomPath(spaceIdOrAlias, getCanonicalAliasOrRoomId(mx, roomId)); getSpaceRoomPath(spaceIdOrAlias, getCanonicalAliasOrRoomId(mx, roomId));
@ -451,7 +511,8 @@ export function Space() {
if (room.isSpaceRoom()) { if (room.isSpaceRoom()) {
const categoryId = makeNavCategoryId(space.roomId, roomId); const categoryId = makeNavCategoryId(space.roomId, roomId);
const closed = closedCategories.has(categoryId); const closed = getInClosedCategories(space.roomId, roomId);
const toggleable = !getAllAncestorsCollapsed(space.roomId, roomId);
const paddingTop = getCategoryPadding(depth); const paddingTop = getCategoryPadding(depth);
@ -473,6 +534,7 @@ export function Space() {
onClick={handleCategoryClick} onClick={handleCategoryClick}
closed={closed} closed={closed}
aria-expanded={!closed} aria-expanded={!closed}
aria-disabled={!toggleable}
> >
{roomId === space.roomId ? 'Rooms' : room?.name} {roomId === space.roomId ? 'Rooms' : room?.name}
</RoomNavCategoryButton> </RoomNavCategoryButton>