Skip to content
This repository was archived by the owner on Sep 11, 2024. It is now read-only.

Commit be0fa6d

Browse files
authored
Fix removing a room from a Space and interaction with m.space.parent (#6944)
1 parent c3ad8b4 commit be0fa6d

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

src/components/structures/SpaceHierarchy.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -545,9 +545,19 @@ const ManageButtons = ({ hierarchy, selected, setSelected, setError }: IManageBu
545545
onClick={async () => {
546546
setRemoving(true);
547547
try {
548+
const userId = cli.getUserId();
548549
for (const [parentId, childId] of selectedRelations) {
549550
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, childId);
550551

552+
// remove the child->parent relation too, if we have permission to.
553+
const childRoom = cli.getRoom(childId);
554+
const parentRelation = childRoom?.currentState.getStateEvents(EventType.SpaceParent, parentId);
555+
if (childRoom?.currentState.maySendStateEvent(EventType.SpaceParent, userId) &&
556+
Array.isArray(parentRelation?.getContent().via)
557+
) {
558+
await cli.sendStateEvent(childId, EventType.SpaceParent, {}, parentId);
559+
}
560+
551561
hierarchy.removeRelation(parentId, childId);
552562
}
553563
} catch (e) {

src/stores/SpaceStore.ts

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -307,16 +307,23 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
307307
return room?.currentState.getStateEvents(EventType.SpaceParent)
308308
.map(ev => {
309309
const content = ev.getContent();
310-
if (Array.isArray(content?.via) && (!canonicalOnly || content?.canonical)) {
311-
const parent = this.matrixClient.getRoom(ev.getStateKey());
312-
// only respect the relationship if the sender has sufficient permissions in the parent to set
313-
// child relations, as per MSC1772.
314-
// https://github.com/matrix-org/matrix-doc/blob/main/proposals/1772-groups-as-rooms.md#relationship-between-rooms-and-spaces
315-
if (parent?.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
316-
return parent;
317-
}
310+
if (!Array.isArray(content.via) || (canonicalOnly && !content.canonical)) {
311+
return; // skip
318312
}
319-
// else implicit undefined which causes this element to be filtered out
313+
314+
// only respect the relationship if the sender has sufficient permissions in the parent to set
315+
// child relations, as per MSC1772.
316+
// https://github.com/matrix-org/matrix-doc/blob/main/proposals/1772-groups-as-rooms.md#relationship-between-rooms-and-spaces
317+
const parent = this.matrixClient.getRoom(ev.getStateKey());
318+
const relation = parent.currentState.getStateEvents(EventType.SpaceChild, roomId);
319+
if (!parent?.currentState.maySendStateEvent(EventType.SpaceChild, userId) ||
320+
// also skip this relation if the parent had this child added but then since removed it
321+
(relation && !Array.isArray(relation.getContent().via))
322+
) {
323+
return; // skip
324+
}
325+
326+
return parent;
320327
})
321328
.filter(Boolean) || [];
322329
}

test/stores/SpaceStore-test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ describe("SpaceStore", () => {
281281
mkSpace(space1, [fav1, room1]);
282282
mkSpace(space2, [fav1, fav2, fav3, room1]);
283283
mkSpace(space3, [invite2]);
284-
// client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
284+
client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
285285

286286
[fav1, fav2, fav3].forEach(roomId => {
287287
client.getRoom(roomId).tags = {

0 commit comments

Comments
 (0)