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:
@@ -230,62 +230,76 @@ export function useCallService(): CallContextValue {
|
||||
/**
|
||||
* Hook to check if a call is active in a specific room
|
||||
*/
|
||||
/** Persists across keep-alive remounts so room switches don't re-hit well-known. */
|
||||
const roomCallSupportCache = new Map<string, boolean>();
|
||||
|
||||
export function useRoomCall(roomId: string) {
|
||||
const { activeCall, startCall, endCall, callSupported: globalCallSupported, callSupportLoading: globalCallSupportLoading, callService } = useCall();
|
||||
const mx = useMatrixClient();
|
||||
const [roomCallSupported, setRoomCallSupported] = useState(false);
|
||||
const [roomCallSupportLoading, setRoomCallSupportLoading] = useState(true);
|
||||
const [roomCallSupported, setRoomCallSupported] = useState(
|
||||
() => roomCallSupportCache.get(roomId) ?? false
|
||||
);
|
||||
const [roomCallSupportLoading, setRoomCallSupportLoading] = useState(
|
||||
() => !roomCallSupportCache.has(roomId)
|
||||
);
|
||||
|
||||
// Check if calls are supported for this specific room by checking all priority homeservers
|
||||
useEffect(() => {
|
||||
const cached = roomCallSupportCache.get(roomId);
|
||||
if (cached !== undefined) {
|
||||
setRoomCallSupported(cached);
|
||||
setRoomCallSupportLoading(false);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let cancelled = false;
|
||||
|
||||
const checkRoomCallSupport = async () => {
|
||||
setRoomCallSupportLoading(true);
|
||||
|
||||
|
||||
const room = mx.getRoom(roomId);
|
||||
if (!room) {
|
||||
setRoomCallSupported(false);
|
||||
setRoomCallSupportLoading(false);
|
||||
if (!cancelled) {
|
||||
setRoomCallSupported(false);
|
||||
setRoomCallSupportLoading(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get homeserver priority list for this room
|
||||
const homeserverPriority = getLiveKitHomeserverPriority(
|
||||
room,
|
||||
mx.getHomeserverUrl(),
|
||||
mx.getSafeUserId()
|
||||
);
|
||||
|
||||
console.log(`Checking call support for room ${roomId}, homeserver priority:`, homeserverPriority);
|
||||
|
||||
// Check each homeserver in priority order
|
||||
for (const homeserver of homeserverPriority) {
|
||||
try {
|
||||
console.log(`Fetching well-known from ${homeserver}...`);
|
||||
const wellKnown = await fetchWellKnownWithRTC(homeserver);
|
||||
console.log(`Well-known response from ${homeserver}:`, wellKnown);
|
||||
|
||||
const livekitFocus = getLiveKitFocus(wellKnown);
|
||||
console.log(`LiveKit focus from ${homeserver}:`, livekitFocus);
|
||||
|
||||
if (livekitFocus) {
|
||||
console.log(`Call support found for room ${roomId} on homeserver: ${homeserver}`);
|
||||
setRoomCallSupported(true);
|
||||
setRoomCallSupportLoading(false);
|
||||
roomCallSupportCache.set(roomId, true);
|
||||
if (!cancelled) {
|
||||
setRoomCallSupported(true);
|
||||
setRoomCallSupportLoading(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn(`Failed to check call support on ${homeserver}:`, error);
|
||||
} catch {
|
||||
// Continue to next homeserver
|
||||
}
|
||||
}
|
||||
|
||||
// No homeserver supports calls
|
||||
console.log(`No call support found for room ${roomId}`);
|
||||
setRoomCallSupported(false);
|
||||
setRoomCallSupportLoading(false);
|
||||
roomCallSupportCache.set(roomId, false);
|
||||
if (!cancelled) {
|
||||
setRoomCallSupported(false);
|
||||
setRoomCallSupportLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
checkRoomCallSupport();
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [roomId, mx]);
|
||||
|
||||
const isInCall = activeCall?.roomId === roomId;
|
||||
|
||||
Reference in New Issue
Block a user