Spaces support
Spaces support was merged into the spec (https://github.com/matrix-org/matrix-doc/blob/master/proposals/1772-groups-as-rooms.md). So it might be nice to have some dedicated spaces support in the SDK as well. Since ruma already provides types for spaces it's already possible to work with spaces generally.
Important
-
Normal messages within a space-room are discouraged (but not blocked by the server): user interfaces are not expected to have a way to enter or display such messages. Space-rooms should be created with a power level for events_default of 100, to prevent the rooms accidentally/maliciously clogging up with messages from random members of the space.
Todo
- [ ] Should we make sure that rooms with type
m.spaceare created with required PL 100 forevents_default? Should this happen transparently inClient::create_roomor do we want a dedicatedClient::create_space? - [x] ~~Fix https://github.com/matrix-org/matrix-rust-sdk/issues/247~~
Related
- ruma issue: https://github.com/ruma/ruma/issues/445
- matrix-bot-sdk: https://github.com/turt2live/matrix-bot-sdk/pull/121
- matrix-js-sdk: https://github.com/matrix-org/matrix-js-sdk/pull/1563
- matrix-dart-sdk: https://gitlab.com/famedly/famedlysdk/-/merge_requests/683
- matrix-go-sdk: None yet
- synapse
- https://github.com/matrix-org/synapse/pull/10011
- https://github.com/matrix-org/synapse/pull/9947
Related ruma PR: https://github.com/ruma/ruma/pull/585
Any update? Fractal needs this for spaces support.
As far as I know, it's not planned for the next months.
I got some space support working for a room-sorting bot (pardon the crappy Rust):
let space_id = if spaces.contains_key(&target_space) {
spaces.get(&target_space).unwrap().clone()
} else {
println!(" > Creating space: {}", target_space.name);
let mut request = create_room::v3::Request::new();
let mut creation_content: CreationContent = Default::default();
creation_content.room_type = Some(matrix_sdk::ruma::room::RoomType::Space);
request.creation_content =
Some(Raw::<CreationContent>::new(&creation_content).unwrap());
let creation_state = [
{
let mut content = RoomAvatarEventContent::new();
content.url = Some(OwnedMxcUri::from(target_space.avatar_url.clone()));
let initial_event: InitialStateEvent<RoomAvatarEventContent> =
InitialStateEvent {
content: content,
state_key: EmptyStateKey {},
};
// let any_event: AnyInitialStateEvent = AnyInitialStateEvent::RoomAvatar(initial_event);
Raw::new(&initial_event)
.unwrap()
.cast::<AnyInitialStateEvent>()
},
{
let initial_event: InitialStateEvent<RoomNameEventContent> =
InitialStateEvent {
content: RoomNameEventContent::new(Some(
target_space.name.clone(),
)),
state_key: EmptyStateKey {},
};
Raw::new(&initial_event)
.unwrap()
.cast::<AnyInitialStateEvent>()
},
{
let initial_event: InitialStateEvent<RoomTopicEventContent> =
InitialStateEvent {
content: RoomTopicEventContent::new(
"Automatically created by `b_room_sorting.rs`".to_string(),
),
state_key: EmptyStateKey {},
};
Raw::new(&initial_event)
.unwrap()
.cast::<AnyInitialStateEvent>()
},
];
request.initial_state = &creation_state;
let result = client.create_room(request).await.unwrap();
spaces.insert(target_space, result.room_id.clone());
client
.join_room_by_id(&result.room_id)
.await
.unwrap()
.room_id
};
let mut in_target_space = false;
let mut in_external_space = None::<OwnedRoomId>;
for space in client.joined_rooms() {
if space.is_space() {
if let Some(SyncSpaceChildEvent::Original(event)) = space
.get_state_event_static_for_key(&room.room_id().to_owned())
.await
.unwrap()
.map(|event| event.deserialize().unwrap())
{
// The "via" field is documented as required,
// so its absence indicates a tombstone.
match event.content.via {
Some(_) => {
if space.room_id() == space_id {
in_target_space = true;
} else if space.room_id().server_name().as_str() != "cy.md" {
in_external_space = Some(space.room_id().to_owned());
} else {
println!(
" > Removing room {} from space {}",
room.room_id(),
space.room_id()
);
if do_move {
space
.redact(&event.event_id, None, None)
.await
.unwrap();
}
}
}
None => {
println!(
" > (room {} was once in space {})",
room.room_id(),
space.room_id()
);
}
}
}
}
}
if in_target_space {
println!(
" > Room {} is already in the correct space {}",
room.room_id(),
space_id
);
} else if let Some(external_space_id) = in_external_space {
println!(
" > Room {} is already in the external space {}",
room.room_id(),
external_space_id
);
} else {
println!(" > Adding room {} into space {}", room.room_id(), space_id);
if do_move {
let space_room = client.get_joined_room(&space_id).unwrap();
let mut content = SpaceChildEventContent::new();
content.suggested = Some(false);
content.via = Some(vec![space_id.server_name().to_owned()]);
let result = space_room
.send_state_event_for_key(room.room_id(), content)
.await
.unwrap();
println!(" > Moved: event={}", result.event_id);
}
}
It looks like there is some space support already (Room::is_space()) and the rest are achievable with just reading/sending ruma events. Maybe Fractal could do something like this too for the time being? HTH.
Maybe Fractal could do something like this too for the time being?
@CyberShadow My guess is that Fractal devs won't be exactly fond of doing this themselves. Fractal used to implement all the Matrix-related things, but now with the fractal-next rewrite, they switched to using matrix-rust-sdk. Making exceptions for certain features is a good way to fall down a rabbit hole where everything is implemented in Fractal again.
But I'm just guessing here, I'm not a Fractal dev (nor a Rust dev).
Having everything done in matrix-rust-sdk would be preferable, although I'm not a Fractal dev.
Implementing Matrix features would best be done here, not in downstreams.
Any updates?
As far as I know, still not planned for the next months by the Element team. Contributions would be appreciated, though :nerd_face:
As far as I know, still not planned for the next months by the Element team. Contributions would be appreciated, though 🤓
Oh how is Element X going deal with spaces then?
We do not know yet when and how spaces will be implemented in EX. It will not happen in the 4 next months for sure.