Make room switches instant and cut redundant client work.

Keep-alive room cache with CSS-only warm switches, nav loading feedback, and per-context members drawer prefs. Share hierarchy/call/sub-room subscriptions, demux state events, and lazy lobby power-level loading to avoid duplicate scans and listener storms.
This commit is contained in:
2026-07-22 18:00:54 +10:00
parent 821724b594
commit 30edd62d96
62 changed files with 2020 additions and 802 deletions

View File

@@ -0,0 +1,66 @@
import React, { useEffect } from 'react';
import { useAtomValue, useSetAtom } from 'jotai';
import { AnimatedOutlet } from '../../../components/AnimatedOutlet';
import { CachedRooms } from '../../../features/room/CachedRooms';
import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom';
import { useMatrixClient } from '../../../hooks/useMatrixClient';
import { activeRoomIdAtom } from '../../../state/activeRoom';
import { roomViewCacheAtom } from '../../../state/roomViewCache';
import { useHomeRooms } from './useHomeRooms';
/**
* Hosts home room keep-alive OUTSIDE the room route `<Outlet />`.
*/
export function HomeLayout() {
const mx = useMatrixClient();
const selectedRoomId = useSelectedRoom();
const rooms = useHomeRooms();
const cache = useAtomValue(roomViewCacheAtom);
const setActiveRoomId = useSetAtom(activeRoomIdAtom);
const room = selectedRoomId ? mx.getRoom(selectedRoomId) : undefined;
const showingRoom = !!(room && rooms.includes(room.roomId));
const keepHost = showingRoom || cache.length > 0;
useEffect(() => {
if (!showingRoom) setActiveRoomId(undefined);
}, [showingRoom, setActiveRoomId]);
return (
<div
style={{
flex: 1,
minWidth: 0,
minHeight: 0,
position: 'relative',
display: 'flex',
}}
>
{keepHost && (
<div
style={{
flex: 1,
minWidth: 0,
minHeight: 0,
display: showingRoom ? 'flex' : 'none',
position: 'relative',
}}
aria-hidden={!showingRoom}
>
<CachedRooms />
</div>
)}
<div
style={{
flex: 1,
minWidth: 0,
minHeight: 0,
display: showingRoom ? 'none' : 'flex',
position: 'relative',
}}
>
<AnimatedOutlet />
</div>
</div>
);
}