mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-06-10 01:14:20 -04:00
refactor: Make SpaceRoom::new_from_known async so we can properly compute is_dm
This commit is contained in:
committed by
Jorge Martin Espinosa
parent
58141e422d
commit
29343233b7
@@ -102,7 +102,7 @@ impl LeaveSpaceHandle {
|
||||
let is_last_owner = joined_owner_ids == [room.own_user_id()];
|
||||
|
||||
rooms.push(LeaveSpaceRoom {
|
||||
space_room: SpaceRoom::new_from_known(&room, 0),
|
||||
space_room: SpaceRoom::new_from_known(&room, 0).await,
|
||||
is_last_owner,
|
||||
are_creators_privileged,
|
||||
});
|
||||
|
||||
@@ -318,7 +318,7 @@ impl SpaceService {
|
||||
{
|
||||
let room_id = room.room_id();
|
||||
editable_spaces
|
||||
.push(SpaceRoom::new_from_known(room, graph.children_of(room_id).len() as u64));
|
||||
.push(SpaceRoom::new_from_known(room, graph.children_of(room_id).len() as u64).await);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,14 +334,22 @@ impl SpaceService {
|
||||
pub async fn joined_parents_of_child(&self, child_id: &RoomId) -> Vec<SpaceRoom> {
|
||||
let graph = &self.space_state.lock().await.graph;
|
||||
|
||||
graph
|
||||
let rooms = graph
|
||||
.parents_of(child_id)
|
||||
.into_iter()
|
||||
.filter_map(|parent_id| self.client.get_room(parent_id))
|
||||
.map(|room| {
|
||||
SpaceRoom::new_from_known(&room, graph.children_of(room.room_id()).len() as u64)
|
||||
})
|
||||
.collect()
|
||||
.filter_map(|parent_id| self.client.get_room(parent_id));
|
||||
|
||||
Self::space_rooms_from_known_rooms(rooms, graph).await
|
||||
}
|
||||
|
||||
async fn space_rooms_from_known_rooms(iter: impl Iterator<Item = Room>, graph: &SpaceGraph) -> Vec<SpaceRoom> {
|
||||
let mut result = Vec::new();
|
||||
|
||||
for room in iter {
|
||||
result.push(SpaceRoom::new_from_known(&room, graph.children_of(room.room_id()).len() as u64).await);
|
||||
}
|
||||
|
||||
result
|
||||
}
|
||||
|
||||
/// Returns the corresponding `SpaceRoom` for the given room ID, or `None`
|
||||
@@ -352,7 +360,7 @@ impl SpaceService {
|
||||
if graph.has_node(room_id)
|
||||
&& let Some(room) = self.client.get_room(room_id)
|
||||
{
|
||||
Some(SpaceRoom::new_from_known(&room, graph.children_of(room.room_id()).len() as u64))
|
||||
Some(SpaceRoom::new_from_known(&room, graph.children_of(room.room_id()).len() as u64).await)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
@@ -583,15 +591,14 @@ impl SpaceService {
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let top_level_spaces = top_level_space_rooms
|
||||
.iter()
|
||||
.map(|room| {
|
||||
SpaceRoom::new_from_known(room, graph.children_of(room.room_id()).len() as u64)
|
||||
})
|
||||
.collect();
|
||||
let mut top_level_spaces = Vec::new();
|
||||
|
||||
for room in &top_level_space_rooms {
|
||||
top_level_spaces.push(SpaceRoom::new_from_known(room, graph.children_of(room.room_id()).len() as u64).await);
|
||||
}
|
||||
|
||||
let space_filters =
|
||||
Self::build_space_filters(client, &graph, top_level_space_rooms, space_child_states);
|
||||
Self::build_space_filters(client, &graph, top_level_space_rooms, space_child_states).await;
|
||||
|
||||
(top_level_spaces, space_filters, graph)
|
||||
}
|
||||
@@ -604,7 +611,7 @@ impl SpaceService {
|
||||
/// and second level ones so while the former are already sorted at this
|
||||
/// point the latter need to be manually taken care of here though the use
|
||||
/// of the collected `m.space.child` state event details.
|
||||
fn build_space_filters(
|
||||
async fn build_space_filters(
|
||||
client: &Client,
|
||||
graph: &SpaceGraph,
|
||||
top_level_space_rooms: Vec<&Room>,
|
||||
@@ -619,22 +626,14 @@ impl SpaceService {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
filters.push(SpaceFilter {
|
||||
space_room: SpaceRoom::new_from_known(top_level_space, children.len() as u64),
|
||||
space_room: SpaceRoom::new_from_known(top_level_space, children.len() as u64).await,
|
||||
level: 0,
|
||||
descendants: children.clone(),
|
||||
});
|
||||
|
||||
filters.append(
|
||||
&mut children
|
||||
.iter()
|
||||
.filter_map(|id| client.get_room(id))
|
||||
.filter(|room| room.is_space())
|
||||
.map(|room| {
|
||||
SpaceRoom::new_from_known(
|
||||
&room,
|
||||
graph.children_of(room.room_id()).len() as u64,
|
||||
)
|
||||
})
|
||||
&mut children_rooms(&client, &children, graph).await
|
||||
.into_iter()
|
||||
.sorted_by(|a, b| {
|
||||
let a_state = space_child_states.get(&a.room_id).cloned();
|
||||
let b_state = space_child_states.get(&b.room_id).cloned();
|
||||
@@ -657,6 +656,23 @@ impl SpaceService {
|
||||
}
|
||||
}
|
||||
|
||||
async fn children_rooms(client: &Client, children: &[OwnedRoomId], graph: &SpaceGraph) -> Vec<SpaceRoom> {
|
||||
let mut result = Vec::new();
|
||||
for child_room_id in children {
|
||||
let Some(room) = client.get_room(child_room_id) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if !room.is_space() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let space_room = SpaceRoom::new_from_known(&room, graph.children_of(room.room_id()).len() as u64).await;
|
||||
result.push(space_room);
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
// MSC3230: lexicographically by `order` and then by room ID
|
||||
fn compare_top_level_space_rooms(
|
||||
a: (&RoomId, Option<&SpaceChildOrder>),
|
||||
|
||||
@@ -116,14 +116,14 @@ impl SpaceRoom {
|
||||
}
|
||||
|
||||
/// Build a `SpaceRoom` from a room already known to this client.
|
||||
pub(crate) fn new_from_known(known_room: &Room, children_count: u64) -> Self {
|
||||
pub(crate) async fn new_from_known(known_room: &Room, children_count: u64) -> Self {
|
||||
let room_info = known_room.clone_info();
|
||||
|
||||
let name = room_info.name().map(ToOwned::to_owned);
|
||||
let display_name = matrix_sdk_base::Room::compute_display_name_with_fields(
|
||||
name.clone(),
|
||||
room_info.canonical_alias(),
|
||||
room_info.heroes().to_vec(),
|
||||
known_room.heroes(),
|
||||
known_room.joined_members_count(),
|
||||
)
|
||||
.to_string();
|
||||
@@ -145,10 +145,10 @@ impl SpaceRoom {
|
||||
is_direct: Some(known_room.direct_targets_length() != 0),
|
||||
children_count,
|
||||
state: Some(known_room.state()),
|
||||
heroes: Some(room_info.heroes().to_vec()),
|
||||
heroes: Some(known_room.heroes()),
|
||||
via: vec![],
|
||||
suggested: false,
|
||||
is_dm: Some(known_room.is_dm()),
|
||||
is_dm: known_room.compute_is_dm().await.ok(),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -144,24 +144,32 @@ impl SpaceRoomList {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut mutable_rooms = rooms.lock();
|
||||
|
||||
updates.iter_all_room_ids().for_each(|updated_room_id| {
|
||||
let mut to_set = Vec::new();
|
||||
for updated_room_id in updates.iter_all_room_ids() {
|
||||
let mutable_rooms = rooms.lock();
|
||||
if let Some((position, room)) = mutable_rooms
|
||||
.clone()
|
||||
.iter()
|
||||
.find_position(|room| &room.room_id == updated_room_id)
|
||||
&& let Some(updated_room) = client.get_room(updated_room_id)
|
||||
{
|
||||
mutable_rooms.set(
|
||||
position,
|
||||
SpaceRoom::new_from_known(
|
||||
&updated_room,
|
||||
room.children_count,
|
||||
),
|
||||
);
|
||||
to_set.push((position, room.clone()));
|
||||
}
|
||||
})
|
||||
drop(mutable_rooms);
|
||||
}
|
||||
|
||||
for (pos, room) in to_set {
|
||||
let Some(updated_room) = client.get_room(&room.room_id) else {
|
||||
continue
|
||||
};
|
||||
let space_room = SpaceRoom::new_from_known(
|
||||
&updated_room,
|
||||
room.children_count,
|
||||
).await;
|
||||
let mut mutable_rooms = rooms.lock();
|
||||
mutable_rooms.set(
|
||||
pos,
|
||||
space_room,
|
||||
);
|
||||
}
|
||||
}
|
||||
Err(err) => {
|
||||
error!("error when listening to room updates: {err}");
|
||||
@@ -191,14 +199,14 @@ impl SpaceRoomList {
|
||||
while subscriber.next().await.is_some() {
|
||||
if let Some(room) = client.get_room(&space_id) {
|
||||
space_observable
|
||||
.set(Some(SpaceRoom::new_from_known(&room, children_count)));
|
||||
.set(Some(SpaceRoom::new_from_known(&room, children_count).await));
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.abort_on_drop();
|
||||
|
||||
(Some(SpaceRoom::new_from_known(&parent, children_count)), Some(space_update_handle))
|
||||
(Some(SpaceRoom::new_from_known(&parent, children_count).await), Some(space_update_handle))
|
||||
} else {
|
||||
(None, None)
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user