Add allow from currently selected space if no m.space.parent found (#2359)
authorAjay Bura <32841439+ajbura@users.noreply.github.com>
Tue, 10 Jun 2025 13:47:46 +0000 (19:17 +0530)
committerGitHub <noreply@github.com>
Tue, 10 Jun 2025 13:47:46 +0000 (23:47 +1000)
src/app/features/common-settings/general/RoomJoinRules.tsx

index ebd4cad50d66387a36eedde070ab125a74a160ab..c0d62a6acf2bfcea92bb3109245b563ec6fffdc0 100644 (file)
@@ -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]
     )
   );