feat: enhance room navigation with sub-room indicators and styling adjustments

This commit is contained in:
2026-03-15 19:23:22 +11:00
parent c980439bc9
commit 12286f57f7
5 changed files with 117 additions and 49 deletions

View File

@@ -445,8 +445,8 @@ export function Space() {
// Flatten hierarchy to include sub-rooms
type HierarchyItem =
| { type: 'hierarchy'; roomId: string }
| { type: 'subroom'; roomId: string; room: Room; depth: number }
| { type: 'unjoined-subroom'; roomId: string; depth: number };
| { type: 'subroom'; roomId: string; room: Room; depth: number; isLast?: boolean }
| { type: 'unjoined-subroom'; roomId: string; depth: number; isLast?: boolean };
const flattenedHierarchy = useMemo(() => {
const items: HierarchyItem[] = [];
@@ -459,19 +459,20 @@ export function Space() {
const subRoomsEvent = room.currentState.getStateEvents(StateEvent.PaarrotSubRooms, '');
const subRooms = subRoomsEvent?.getContent<{ children: string[] }>()?.children ?? [];
subRooms.forEach(subRoomId => {
subRooms.forEach((subRoomId, index) => {
if (processedSubRooms.has(subRoomId)) return;
processedSubRooms.add(subRoomId);
const isLast = index === subRooms.length - 1;
const subRoom = mx.getRoom(subRoomId);
if (subRoom) {
// Joined sub-room
items.push({ type: 'subroom', roomId: subRoomId, room: subRoom, depth: baseDepth + 1 });
items.push({ type: 'subroom', roomId: subRoomId, room: subRoom, depth: baseDepth + 1, isLast });
// Recursively add sub-rooms of sub-rooms
addSubRooms(subRoomId, baseDepth + 1);
} else {
// Unjoined sub-room - show with join button
items.push({ type: 'unjoined-subroom', roomId: subRoomId, depth: baseDepth + 1 });
items.push({ type: 'unjoined-subroom', roomId: subRoomId, depth: baseDepth + 1, isLast });
}
});
};
@@ -562,26 +563,46 @@ export function Space() {
if (item.type === 'unjoined-subroom') {
return (
<VirtualTile virtualItem={vItem} key={vItem.index} ref={virtualizer.measureElement}>
<UnjoinedSubRoomItem roomId={item.roomId} depth={item.depth} />
<UnjoinedSubRoomItem roomId={item.roomId} depth={item.depth} isLast={item.isLast} />
</VirtualTile>
);
}
// Sub-room item (nested under parent)
if (item.type === 'subroom') {
const paddingLeft = `${item.depth * 24}px`;
const paddingLeft = '30px';
let treeIcon = '';
if (item.depth > 0) {
treeIcon = item.isLast ? '╰' : '├';
}
return (
<VirtualTile virtualItem={vItem} key={vItem.index} ref={virtualizer.measureElement}>
<div style={{ paddingLeft }}>
<RoomNavItem
room={item.room}
selected={selectedRoomId === item.roomId}
showAvatar={mDirects.has(item.roomId)}
direct={mDirects.has(item.roomId)}
linkPath={getToLink(item.roomId)}
notificationMode={getRoomNotificationMode(notificationPreferences, item.room.roomId)}
/>
<div style={{ paddingLeft, display: 'flex', alignItems: 'center', minHeight: '1.5rem' }}>
{treeIcon && (
<span style={{
paddingRight: '2px',
opacity: 0.5,
fontFamily: 'monospace',
fontSize: '14px',
lineHeight: '1',
userSelect: 'none'
}}>
{treeIcon}
</span>
)}
<div style={{ flex: 1, minWidth: 0 }}>
<RoomNavItem
room={item.room}
selected={selectedRoomId === item.roomId}
hideIcon={item.depth > 0}
showAvatar={mDirects.has(item.roomId)}
direct={mDirects.has(item.roomId)}
linkPath={getToLink(item.roomId)}
notificationMode={getRoomNotificationMode(notificationPreferences, item.room.roomId)}
/>
</div>
</div>
</VirtualTile>
);