Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spaces support #227

Open
1 of 2 tasks
johannescpk opened this issue May 10, 2021 · 12 comments
Open
1 of 2 tasks

Spaces support #227

johannescpk opened this issue May 10, 2021 · 12 comments
Labels
enhancement New feature or request

Comments

@johannescpk
Copy link
Contributor

johannescpk commented May 10, 2021

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

Related

@MTRNord
Copy link
Contributor

MTRNord commented May 18, 2021

Related ruma PR: ruma/ruma#585

@jplatte jplatte added the enhancement New feature or request label Apr 8, 2022
@orowith2os
Copy link

Any update? Fractal needs this for spaces support.

@Hywan
Copy link
Member

Hywan commented Jul 5, 2023

As far as I know, it's not planned for the next months.

@CyberShadow
Copy link
Contributor

CyberShadow commented Jul 5, 2023

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.

@k8ieone
Copy link

k8ieone commented Jul 6, 2023

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).

@orowith2os
Copy link

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.

@nyabinary
Copy link

Any updates?

@bnjbvr
Copy link
Member

bnjbvr commented Jan 4, 2024

As far as I know, still not planned for the next months by the Element team. Contributions would be appreciated, though 🤓

@nyabinary
Copy link

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?

@manuroe
Copy link
Contributor

manuroe commented Jan 5, 2024

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.

@nyabinary
Copy link

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.

Sorry to bump, but is there any more updates you have on this :P

@manuroe
Copy link
Contributor

manuroe commented Sep 12, 2024

No news on Element as a company side. We have not yet received a sponsorship to implement this feature.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

10 participants