import React, { ReactNode } from 'react'; import { Room } from 'matrix-js-sdk'; import { Navigate, useParams } from 'react-router-dom'; import { useSelectedRoom } from '../../../hooks/router/useSelectedRoom'; import { IsOneOnOneProvider, RoomProvider } from '../../../hooks/useRoom'; import { useMatrixClient } from '../../../hooks/useMatrixClient'; import { JoinBeforeNavigate } from '../../../features/join-before-navigate'; import { isSpace } from '../../../utils/room'; import { useIsOneOnOneRoom } from '../../../hooks/useIsOneOnOneRoom'; import { Membership } from '../../../../types/matrix/room'; import { getDirectPath } from '../../pathUtils'; // Inner provider hosts the reactive 1:1 subscription. Hooks can't run inside // the early-return path of the parent, so we split the component once `room` // is known to exist and not be a space. function ResolvedRoomProvider({ room, children }: { room: Room; children: ReactNode }) { const isOneOnOne = useIsOneOnOneRoom(room); return ( {children} ); } export function DirectRouteRoomProvider({ children }: { children: ReactNode }) { const mx = useMatrixClient(); const { roomIdOrAlias, eventId } = useParams(); const roomId = useSelectedRoom(); const room = mx.getRoom(roomId); // Central membership guard: invite-state rooms have no useful Room view — // the Accept/Decline UI lives on the inline DirectInviteRow in the panel. // Push deep links and legacy /home/{roomId}/ shim can both deliver an // invite-room id here; bounce to the bare /direct/ list so the user lands // on the row instead of an empty stripped-state timeline. if (room && room.getMyMembership() === Membership.Invite) { return ; } // After P3c the Direct tab is universal — any joined non-space room renders // here. Spaces (= future Channels) keep their own /{spaceId}/ route. if (!room || isSpace(room)) { if (!roomIdOrAlias) return ; return ; } return {children}; }