diff --git a/src/app/hooks/useSpaceHierarchy.ts b/src/app/hooks/useSpaceHierarchy.ts index ad34e3f4..34f5e123 100644 --- a/src/app/hooks/useSpaceHierarchy.ts +++ b/src/app/hooks/useSpaceHierarchy.ts @@ -1,6 +1,6 @@ import { atom, useAtom, useAtomValue } from 'jotai'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react'; -import { MatrixError, Room } from 'matrix-js-sdk'; +import { MatrixError, MatrixEvent, Room } from 'matrix-js-sdk'; import { IHierarchyRoom } from 'matrix-js-sdk/lib/@types/spaces'; import { QueryFunction, useInfiniteQuery } from '@tanstack/react-query'; import { useMatrixClient } from './useMatrixClient'; @@ -18,6 +18,7 @@ export type HierarchyItemSpace = { ts: number; space: true; parentId?: string; + depth: number; }; export type HierarchyItemRoom = { @@ -25,6 +26,7 @@ export type HierarchyItemRoom = { content: MSpaceChildContent; ts: number; parentId: string; + depth: number; }; export type HierarchyItem = HierarchyItemSpace | HierarchyItemRoom; @@ -35,6 +37,10 @@ const hierarchyItemTs: SortFunc = (a, b) => byTsOldToNew(a.ts, b. const hierarchyItemByOrder: SortFunc = (a, b) => byOrderKey(a.content.order, b.content.order); +const childEventTs: SortFunc = (a, b) => byTsOldToNew(a.getTs(), b.getTs()); +const childEventByOrder: SortFunc = (a, b) => + byOrderKey(a.getContent().order, b.getContent().order); + const getHierarchySpaces = ( rootSpaceId: string, getRoom: GetRoomCallback, @@ -45,8 +51,9 @@ const getHierarchySpaces = ( content: { via: [] }, ts: 0, space: true, + depth: 0, }; - let spaceItems: HierarchyItemSpace[] = []; + const spaceItems: HierarchyItemSpace[] = []; const findAndCollectHierarchySpaces = (spaceItem: HierarchyItemSpace) => { if (spaceItems.find((item) => item.roomId === spaceItem.roomId)) return; @@ -55,37 +62,37 @@ const getHierarchySpaces = ( if (!space) return; const childEvents = getStateEvents(space, StateEvent.SpaceChild); + childEvents + .filter((childEvent) => { + if (!isValidChild(childEvent)) return false; + const childId = childEvent.getStateKey(); + if (!childId || !isRoomId(childId)) return false; + + // because we can not find if a childId is space without joining + // or requesting room summary, we will look it into spaceRooms local + // cache which we maintain as we load summary in UI. + return getRoom(childId)?.isSpaceRoom() || spaceRooms.has(childId); + }) + .sort(childEventTs) + .sort(childEventByOrder); childEvents.forEach((childEvent) => { - if (!isValidChild(childEvent)) return; const childId = childEvent.getStateKey(); if (!childId || !isRoomId(childId)) return; - // because we can not find if a childId is space without joining - // or requesting room summary, we will look it into spaceRooms local - // cache which we maintain as we load summary in UI. - if (getRoom(childId)?.isSpaceRoom() || spaceRooms.has(childId)) { - const childItem: HierarchyItemSpace = { - roomId: childId, - content: childEvent.getContent(), - ts: childEvent.getTs(), - space: true, - parentId: spaceItem.roomId, - }; - findAndCollectHierarchySpaces(childItem); - } + const childItem: HierarchyItemSpace = { + roomId: childId, + content: childEvent.getContent(), + ts: childEvent.getTs(), + space: true, + parentId: spaceItem.roomId, + depth: spaceItem.depth + 1, + }; + findAndCollectHierarchySpaces(childItem); }); }; findAndCollectHierarchySpaces(rootSpaceItem); - spaceItems = [ - rootSpaceItem, - ...spaceItems - .filter((item) => item.roomId !== rootSpaceId) - .sort(hierarchyItemTs) - .sort(hierarchyItemByOrder), - ]; - return spaceItems; }; @@ -121,6 +128,7 @@ const getSpaceHierarchy = ( content: childEvent.getContent(), ts: childEvent.getTs(), parentId: spaceItem.roomId, + depth: spaceItem.depth, }; childItems.push(childItem); }); @@ -208,6 +216,7 @@ const getSpaceJoinedHierarchy = ( content: childEvent.getContent(), ts: childEvent.getTs(), parentId: spaceItem.roomId, + depth: spaceItem.depth, }; childItems.push(childItem); }); diff --git a/src/app/pages/client/space/Space.tsx b/src/app/pages/client/space/Space.tsx index d1009464..2868701f 100644 --- a/src/app/pages/client/space/Space.tsx +++ b/src/app/pages/client/space/Space.tsx @@ -318,7 +318,8 @@ export function Space() { useCallback( (parentId, roomId) => { if (!closedCategories.has(makeNavCategoryId(space.roomId, parentId))) { - return false; + // REWORK HOW THIS WORKS? + return false; // This does not account for sub-subspaces, best way to do? - first fix useSpaceHie... } const showRoom = roomToUnread.has(roomId) || roomId === selectedRoomId; if (showRoom) return false; @@ -346,6 +347,12 @@ export function Space() { const getToLink = (roomId: string) => getSpaceRoomPath(spaceIdOrAlias, getCanonicalAliasOrRoomId(mx, roomId)); + const getCategoryPadding = (depth: number): string | undefined => { + if (depth === 0) return undefined; + if (depth === 1) return config.space.S400; + return config.space.S200; + }; + return ( @@ -392,12 +399,17 @@ export function Space() { }} > {virtualizer.getVirtualItems().map((vItem) => { - const { roomId } = hierarchy[vItem.index] ?? {}; + const { roomId, depth } = hierarchy[vItem.index] ?? {}; const room = mx.getRoom(roomId); if (!room) return null; + const paddingLeft = `calc((${depth} - 1) * ${config.space.S200})`; + if (room.isSpaceRoom()) { const categoryId = makeNavCategoryId(space.roomId, roomId); + const closed = closedCategories.has(categoryId); + + const paddingTop = getCategoryPadding(depth); return ( -
+
{roomId === space.roomId ? 'Rooms' : room?.name} @@ -422,14 +440,19 @@ export function Space() { return ( - +
+ +
); })}