mirror of
https://github.com/cinnyapp/cinny.git
synced 2025-11-09 00:30:28 +03:00
fix hierarchy indenting and order
This commit is contained in:
parent
c0799142d6
commit
2fae418132
2 changed files with 68 additions and 36 deletions
|
|
@ -1,6 +1,6 @@
|
||||||
import { atom, useAtom, useAtomValue } from 'jotai';
|
import { atom, useAtom, useAtomValue } from 'jotai';
|
||||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
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 { IHierarchyRoom } from 'matrix-js-sdk/lib/@types/spaces';
|
||||||
import { QueryFunction, useInfiniteQuery } from '@tanstack/react-query';
|
import { QueryFunction, useInfiniteQuery } from '@tanstack/react-query';
|
||||||
import { useMatrixClient } from './useMatrixClient';
|
import { useMatrixClient } from './useMatrixClient';
|
||||||
|
|
@ -18,6 +18,7 @@ export type HierarchyItemSpace = {
|
||||||
ts: number;
|
ts: number;
|
||||||
space: true;
|
space: true;
|
||||||
parentId?: string;
|
parentId?: string;
|
||||||
|
depth: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HierarchyItemRoom = {
|
export type HierarchyItemRoom = {
|
||||||
|
|
@ -25,6 +26,7 @@ export type HierarchyItemRoom = {
|
||||||
content: MSpaceChildContent;
|
content: MSpaceChildContent;
|
||||||
ts: number;
|
ts: number;
|
||||||
parentId: string;
|
parentId: string;
|
||||||
|
depth: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type HierarchyItem = HierarchyItemSpace | HierarchyItemRoom;
|
export type HierarchyItem = HierarchyItemSpace | HierarchyItemRoom;
|
||||||
|
|
@ -35,6 +37,10 @@ const hierarchyItemTs: SortFunc<HierarchyItem> = (a, b) => byTsOldToNew(a.ts, b.
|
||||||
const hierarchyItemByOrder: SortFunc<HierarchyItem> = (a, b) =>
|
const hierarchyItemByOrder: SortFunc<HierarchyItem> = (a, b) =>
|
||||||
byOrderKey(a.content.order, b.content.order);
|
byOrderKey(a.content.order, b.content.order);
|
||||||
|
|
||||||
|
const childEventTs: SortFunc<MatrixEvent> = (a, b) => byTsOldToNew(a.getTs(), b.getTs());
|
||||||
|
const childEventByOrder: SortFunc<MatrixEvent> = (a, b) =>
|
||||||
|
byOrderKey(a.getContent<MSpaceChildContent>().order, b.getContent<MSpaceChildContent>().order);
|
||||||
|
|
||||||
const getHierarchySpaces = (
|
const getHierarchySpaces = (
|
||||||
rootSpaceId: string,
|
rootSpaceId: string,
|
||||||
getRoom: GetRoomCallback,
|
getRoom: GetRoomCallback,
|
||||||
|
|
@ -45,8 +51,9 @@ const getHierarchySpaces = (
|
||||||
content: { via: [] },
|
content: { via: [] },
|
||||||
ts: 0,
|
ts: 0,
|
||||||
space: true,
|
space: true,
|
||||||
|
depth: 0,
|
||||||
};
|
};
|
||||||
let spaceItems: HierarchyItemSpace[] = [];
|
const spaceItems: HierarchyItemSpace[] = [];
|
||||||
|
|
||||||
const findAndCollectHierarchySpaces = (spaceItem: HierarchyItemSpace) => {
|
const findAndCollectHierarchySpaces = (spaceItem: HierarchyItemSpace) => {
|
||||||
if (spaceItems.find((item) => item.roomId === spaceItem.roomId)) return;
|
if (spaceItems.find((item) => item.roomId === spaceItem.roomId)) return;
|
||||||
|
|
@ -55,37 +62,37 @@ const getHierarchySpaces = (
|
||||||
|
|
||||||
if (!space) return;
|
if (!space) return;
|
||||||
const childEvents = getStateEvents(space, StateEvent.SpaceChild);
|
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) => {
|
childEvents.forEach((childEvent) => {
|
||||||
if (!isValidChild(childEvent)) return;
|
|
||||||
const childId = childEvent.getStateKey();
|
const childId = childEvent.getStateKey();
|
||||||
if (!childId || !isRoomId(childId)) return;
|
if (!childId || !isRoomId(childId)) return;
|
||||||
|
|
||||||
// because we can not find if a childId is space without joining
|
const childItem: HierarchyItemSpace = {
|
||||||
// or requesting room summary, we will look it into spaceRooms local
|
roomId: childId,
|
||||||
// cache which we maintain as we load summary in UI.
|
content: childEvent.getContent<MSpaceChildContent>(),
|
||||||
if (getRoom(childId)?.isSpaceRoom() || spaceRooms.has(childId)) {
|
ts: childEvent.getTs(),
|
||||||
const childItem: HierarchyItemSpace = {
|
space: true,
|
||||||
roomId: childId,
|
parentId: spaceItem.roomId,
|
||||||
content: childEvent.getContent<MSpaceChildContent>(),
|
depth: spaceItem.depth + 1,
|
||||||
ts: childEvent.getTs(),
|
};
|
||||||
space: true,
|
findAndCollectHierarchySpaces(childItem);
|
||||||
parentId: spaceItem.roomId,
|
|
||||||
};
|
|
||||||
findAndCollectHierarchySpaces(childItem);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
findAndCollectHierarchySpaces(rootSpaceItem);
|
findAndCollectHierarchySpaces(rootSpaceItem);
|
||||||
|
|
||||||
spaceItems = [
|
|
||||||
rootSpaceItem,
|
|
||||||
...spaceItems
|
|
||||||
.filter((item) => item.roomId !== rootSpaceId)
|
|
||||||
.sort(hierarchyItemTs)
|
|
||||||
.sort(hierarchyItemByOrder),
|
|
||||||
];
|
|
||||||
|
|
||||||
return spaceItems;
|
return spaceItems;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -121,6 +128,7 @@ const getSpaceHierarchy = (
|
||||||
content: childEvent.getContent<MSpaceChildContent>(),
|
content: childEvent.getContent<MSpaceChildContent>(),
|
||||||
ts: childEvent.getTs(),
|
ts: childEvent.getTs(),
|
||||||
parentId: spaceItem.roomId,
|
parentId: spaceItem.roomId,
|
||||||
|
depth: spaceItem.depth,
|
||||||
};
|
};
|
||||||
childItems.push(childItem);
|
childItems.push(childItem);
|
||||||
});
|
});
|
||||||
|
|
@ -208,6 +216,7 @@ const getSpaceJoinedHierarchy = (
|
||||||
content: childEvent.getContent<MSpaceChildContent>(),
|
content: childEvent.getContent<MSpaceChildContent>(),
|
||||||
ts: childEvent.getTs(),
|
ts: childEvent.getTs(),
|
||||||
parentId: spaceItem.roomId,
|
parentId: spaceItem.roomId,
|
||||||
|
depth: spaceItem.depth,
|
||||||
};
|
};
|
||||||
childItems.push(childItem);
|
childItems.push(childItem);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -318,7 +318,8 @@ export function Space() {
|
||||||
useCallback(
|
useCallback(
|
||||||
(parentId, roomId) => {
|
(parentId, roomId) => {
|
||||||
if (!closedCategories.has(makeNavCategoryId(space.roomId, parentId))) {
|
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;
|
const showRoom = roomToUnread.has(roomId) || roomId === selectedRoomId;
|
||||||
if (showRoom) return false;
|
if (showRoom) return false;
|
||||||
|
|
@ -346,6 +347,12 @@ export function Space() {
|
||||||
const getToLink = (roomId: string) =>
|
const getToLink = (roomId: string) =>
|
||||||
getSpaceRoomPath(spaceIdOrAlias, getCanonicalAliasOrRoomId(mx, roomId));
|
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 (
|
return (
|
||||||
<PageNav>
|
<PageNav>
|
||||||
<SpaceHeader />
|
<SpaceHeader />
|
||||||
|
|
@ -392,12 +399,17 @@ export function Space() {
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{virtualizer.getVirtualItems().map((vItem) => {
|
{virtualizer.getVirtualItems().map((vItem) => {
|
||||||
const { roomId } = hierarchy[vItem.index] ?? {};
|
const { roomId, depth } = hierarchy[vItem.index] ?? {};
|
||||||
const room = mx.getRoom(roomId);
|
const room = mx.getRoom(roomId);
|
||||||
if (!room) return null;
|
if (!room) return null;
|
||||||
|
|
||||||
|
const paddingLeft = `calc((${depth} - 1) * ${config.space.S200})`;
|
||||||
|
|
||||||
if (room.isSpaceRoom()) {
|
if (room.isSpaceRoom()) {
|
||||||
const categoryId = makeNavCategoryId(space.roomId, roomId);
|
const categoryId = makeNavCategoryId(space.roomId, roomId);
|
||||||
|
const closed = closedCategories.has(categoryId);
|
||||||
|
|
||||||
|
const paddingTop = getCategoryPadding(depth);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VirtualTile
|
<VirtualTile
|
||||||
|
|
@ -405,12 +417,18 @@ export function Space() {
|
||||||
key={vItem.index}
|
key={vItem.index}
|
||||||
ref={virtualizer.measureElement}
|
ref={virtualizer.measureElement}
|
||||||
>
|
>
|
||||||
<div style={{ paddingTop: vItem.index === 0 ? undefined : config.space.S400 }}>
|
<div
|
||||||
|
style={{
|
||||||
|
paddingTop,
|
||||||
|
paddingLeft,
|
||||||
|
}}
|
||||||
|
>
|
||||||
<NavCategoryHeader>
|
<NavCategoryHeader>
|
||||||
<RoomNavCategoryButton
|
<RoomNavCategoryButton
|
||||||
data-category-id={categoryId}
|
data-category-id={categoryId}
|
||||||
onClick={handleCategoryClick}
|
onClick={handleCategoryClick}
|
||||||
closed={closedCategories.has(categoryId)}
|
closed={closed}
|
||||||
|
aria-expanded={!closed}
|
||||||
>
|
>
|
||||||
{roomId === space.roomId ? 'Rooms' : room?.name}
|
{roomId === space.roomId ? 'Rooms' : room?.name}
|
||||||
</RoomNavCategoryButton>
|
</RoomNavCategoryButton>
|
||||||
|
|
@ -422,14 +440,19 @@ export function Space() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VirtualTile virtualItem={vItem} key={vItem.index} ref={virtualizer.measureElement}>
|
<VirtualTile virtualItem={vItem} key={vItem.index} ref={virtualizer.measureElement}>
|
||||||
<RoomNavItem
|
<div style={{ paddingLeft }}>
|
||||||
room={room}
|
<RoomNavItem
|
||||||
selected={selectedRoomId === roomId}
|
room={room}
|
||||||
showAvatar={mDirects.has(roomId)}
|
selected={selectedRoomId === roomId}
|
||||||
direct={mDirects.has(roomId)}
|
showAvatar={mDirects.has(roomId)}
|
||||||
linkPath={getToLink(roomId)}
|
direct={mDirects.has(roomId)}
|
||||||
notificationMode={getRoomNotificationMode(notificationPreferences, room.roomId)}
|
linkPath={getToLink(roomId)}
|
||||||
/>
|
notificationMode={getRoomNotificationMode(
|
||||||
|
notificationPreferences,
|
||||||
|
room.roomId
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</VirtualTile>
|
</VirtualTile>
|
||||||
);
|
);
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue