Fix removing a room from a Space and interaction with `m.space.parent` (#6944)
parent
c3ad8b4eed
commit
be0fa6da7b
|
@ -545,9 +545,19 @@ const ManageButtons = ({ hierarchy, selected, setSelected, setError }: IManageBu
|
||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
setRemoving(true);
|
setRemoving(true);
|
||||||
try {
|
try {
|
||||||
|
const userId = cli.getUserId();
|
||||||
for (const [parentId, childId] of selectedRelations) {
|
for (const [parentId, childId] of selectedRelations) {
|
||||||
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, childId);
|
await cli.sendStateEvent(parentId, EventType.SpaceChild, {}, childId);
|
||||||
|
|
||||||
|
// remove the child->parent relation too, if we have permission to.
|
||||||
|
const childRoom = cli.getRoom(childId);
|
||||||
|
const parentRelation = childRoom?.currentState.getStateEvents(EventType.SpaceParent, parentId);
|
||||||
|
if (childRoom?.currentState.maySendStateEvent(EventType.SpaceParent, userId) &&
|
||||||
|
Array.isArray(parentRelation?.getContent().via)
|
||||||
|
) {
|
||||||
|
await cli.sendStateEvent(childId, EventType.SpaceParent, {}, parentId);
|
||||||
|
}
|
||||||
|
|
||||||
hierarchy.removeRelation(parentId, childId);
|
hierarchy.removeRelation(parentId, childId);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|
|
@ -307,16 +307,23 @@ export class SpaceStoreClass extends AsyncStoreWithClient<IState> {
|
||||||
return room?.currentState.getStateEvents(EventType.SpaceParent)
|
return room?.currentState.getStateEvents(EventType.SpaceParent)
|
||||||
.map(ev => {
|
.map(ev => {
|
||||||
const content = ev.getContent();
|
const content = ev.getContent();
|
||||||
if (Array.isArray(content?.via) && (!canonicalOnly || content?.canonical)) {
|
if (!Array.isArray(content.via) || (canonicalOnly && !content.canonical)) {
|
||||||
const parent = this.matrixClient.getRoom(ev.getStateKey());
|
return; // skip
|
||||||
// only respect the relationship if the sender has sufficient permissions in the parent to set
|
|
||||||
// child relations, as per MSC1772.
|
|
||||||
// https://github.com/matrix-org/matrix-doc/blob/main/proposals/1772-groups-as-rooms.md#relationship-between-rooms-and-spaces
|
|
||||||
if (parent?.currentState.maySendStateEvent(EventType.SpaceChild, userId)) {
|
|
||||||
return parent;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// else implicit undefined which causes this element to be filtered out
|
|
||||||
|
// only respect the relationship if the sender has sufficient permissions in the parent to set
|
||||||
|
// child relations, as per MSC1772.
|
||||||
|
// https://github.com/matrix-org/matrix-doc/blob/main/proposals/1772-groups-as-rooms.md#relationship-between-rooms-and-spaces
|
||||||
|
const parent = this.matrixClient.getRoom(ev.getStateKey());
|
||||||
|
const relation = parent.currentState.getStateEvents(EventType.SpaceChild, roomId);
|
||||||
|
if (!parent?.currentState.maySendStateEvent(EventType.SpaceChild, userId) ||
|
||||||
|
// also skip this relation if the parent had this child added but then since removed it
|
||||||
|
(relation && !Array.isArray(relation.getContent().via))
|
||||||
|
) {
|
||||||
|
return; // skip
|
||||||
|
}
|
||||||
|
|
||||||
|
return parent;
|
||||||
})
|
})
|
||||||
.filter(Boolean) || [];
|
.filter(Boolean) || [];
|
||||||
}
|
}
|
||||||
|
|
|
@ -281,7 +281,7 @@ describe("SpaceStore", () => {
|
||||||
mkSpace(space1, [fav1, room1]);
|
mkSpace(space1, [fav1, room1]);
|
||||||
mkSpace(space2, [fav1, fav2, fav3, room1]);
|
mkSpace(space2, [fav1, fav2, fav3, room1]);
|
||||||
mkSpace(space3, [invite2]);
|
mkSpace(space3, [invite2]);
|
||||||
// client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
|
client.getRoom.mockImplementation(roomId => rooms.find(room => room.roomId === roomId));
|
||||||
|
|
||||||
[fav1, fav2, fav3].forEach(roomId => {
|
[fav1, fav2, fav3].forEach(roomId => {
|
||||||
client.getRoom(roomId).tags = {
|
client.getRoom(roomId).tags = {
|
||||||
|
|
Loading…
Reference in New Issue