diff --git a/src/app/features/common-settings/general/RoomJoinRules.tsx b/src/app/features/common-settings/general/RoomJoinRules.tsx index ebd4cad5..c0d62a6a 100644 --- a/src/app/features/common-settings/general/RoomJoinRules.tsx +++ b/src/app/features/common-settings/general/RoomJoinRules.tsx @@ -2,6 +2,7 @@ import React, { useCallback, useMemo } from 'react'; import { color, Text } from 'folds'; import { JoinRule, MatrixError, RestrictedAllowType } from 'matrix-js-sdk'; import { RoomJoinRulesEventContent } from 'matrix-js-sdk/lib/types'; +import { useAtomValue } from 'jotai'; import { IPowerLevels, powerLevelAPI } from '../../../hooks/usePowerLevels'; import { ExtendedJoinRules, @@ -20,6 +21,12 @@ import { useStateEvent } from '../../../hooks/useStateEvent'; import { useSpaceOptionally } from '../../../hooks/useSpace'; import { AsyncStatus, useAsyncCallback } from '../../../hooks/useAsyncCallback'; import { getStateEvents } from '../../../utils/room'; +import { + useRecursiveChildSpaceScopeFactory, + useSpaceChildren, +} from '../../../state/hooks/roomList'; +import { allRoomsAtom } from '../../../state/room-list/roomList'; +import { roomToParentsAtom } from '../../../state/room/roomToParents'; type RestrictedRoomAllowContent = { room_id: string; @@ -36,7 +43,11 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { const allowKnockRestricted = roomVersion >= 10; const allowRestricted = roomVersion >= 8; const allowKnock = roomVersion >= 7; + + const roomIdToParents = useAtomValue(roomToParentsAtom); const space = useSpaceOptionally(); + const subspacesScope = useRecursiveChildSpaceScopeFactory(mx, roomIdToParents); + const subspaces = useSpaceChildren(allRoomsAtom, space?.roomId ?? '', subspacesScope); const userPowerLevel = powerLevelAPI.getPowerLevel(powerLevels, mx.getSafeUserId()); const canEdit = powerLevelAPI.canSendStateEvent( @@ -74,9 +85,22 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { async (joinRule: ExtendedJoinRules) => { const allow: RestrictedRoomAllowContent[] = []; if (joinRule === JoinRule.Restricted || joinRule === 'knock_restricted') { - const parents = getStateEvents(room, StateEvent.SpaceParent).map((event) => - event.getStateKey() - ); + const roomParents = roomIdToParents.get(room.roomId); + + const parents = getStateEvents(room, StateEvent.SpaceParent) + .map((event) => event.getStateKey()) + .filter((parentId) => typeof parentId === 'string') + .filter((parentId) => roomParents?.has(parentId)); + + if (parents.length === 0 && space && roomParents) { + // if no m.space.parent found + // find parent in current space + const selectedParents = subspaces.filter((rId) => roomParents.has(rId)); + if (roomParents.has(space.roomId)) { + selectedParents.push(space.roomId); + } + selectedParents.forEach((pId) => parents.push(pId)); + } parents.forEach((parentRoomId) => { if (!parentRoomId) return; allow.push({ @@ -92,7 +116,7 @@ export function RoomJoinRules({ powerLevels }: RoomJoinRulesProps) { if (allow.length > 0) c.allow = allow; await mx.sendStateEvent(room.roomId, StateEvent.RoomJoinRules as any, c); }, - [mx, room] + [mx, room, space, subspaces, roomIdToParents] ) );