diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 43bfc9dfc..e4c7306bf 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -1259,7 +1259,7 @@ impl Client { SyncServiceBuilder::new((*self.inner).clone(), self.utd_hook_manager.get().cloned()) } - pub fn spaces_service(&self) -> Arc { + pub fn space_service(&self) -> Arc { let inner = UISpaceService::new((*self.inner).clone()); Arc::new(SpaceService::new(inner)) } diff --git a/bindings/matrix-sdk-ffi/src/spaces.rs b/bindings/matrix-sdk-ffi/src/spaces.rs index fc952ead7..5453b6b8f 100644 --- a/bindings/matrix-sdk-ffi/src/spaces.rs +++ b/bindings/matrix-sdk-ffi/src/spaces.rs @@ -17,9 +17,8 @@ use std::{fmt::Debug, sync::Arc}; use futures_util::{pin_mut, StreamExt}; use matrix_sdk_common::{SendOutsideWasm, SyncOutsideWasm}; use matrix_sdk_ui::spaces::{ - room_list::SpaceServiceRoomListPaginationState as UISpaceServiceRoomListPaginationState, - SpaceService as UISpaceService, SpaceServiceRoom as UISpaceServiceRoom, - SpaceServiceRoomList as UISpaceServiceRoomList, + room_list::SpaceRoomListPaginationState, SpaceRoom as UISpaceRoom, + SpaceRoomList as UISpaceRoomList, SpaceService as UISpaceService, }; use ruma::RoomId; @@ -38,14 +37,14 @@ pub struct SpaceService { } impl SpaceService { - pub fn new(inner: UISpaceService) -> Self { + pub(crate) fn new(inner: UISpaceService) -> Self { Self { inner } } } #[matrix_sdk_ffi_macros::export] impl SpaceService { - pub async fn joined_spaces(&self) -> Vec { + pub async fn joined_spaces(&self) -> Vec { self.inner.joined_spaces().await.into_iter().map(Into::into).collect() } @@ -77,32 +76,32 @@ impl SpaceService { pub async fn space_room_list( &self, space_id: String, - ) -> Result, ClientError> { + ) -> Result, ClientError> { let space_id = RoomId::parse(space_id)?; - Ok(Arc::new(SpaceServiceRoomList::new(self.inner.space_room_list(space_id)))) + Ok(Arc::new(SpaceRoomList::new(self.inner.space_room_list(space_id)))) } } #[derive(uniffi::Object)] -pub struct SpaceServiceRoomList { - inner: UISpaceServiceRoomList, +pub struct SpaceRoomList { + inner: UISpaceRoomList, } -impl SpaceServiceRoomList { - pub fn new(inner: UISpaceServiceRoomList) -> Self { +impl SpaceRoomList { + fn new(inner: UISpaceRoomList) -> Self { Self { inner } } } #[matrix_sdk_ffi_macros::export] -impl SpaceServiceRoomList { - pub fn pagination_state(&self) -> SpaceServiceRoomListPaginationState { - self.inner.pagination_state().into() +impl SpaceRoomList { + pub fn pagination_state(&self) -> SpaceRoomListPaginationState { + self.inner.pagination_state() } pub fn subscribe_to_pagination_state_updates( &self, - listener: Box, + listener: Box, ) -> Arc { let pagination_state = self.inner.subscribe_to_pagination_state_updates(); @@ -110,18 +109,18 @@ impl SpaceServiceRoomList { pin_mut!(pagination_state); while let Some(state) = pagination_state.next().await { - listener.on_update(state.into()); + listener.on_update(state); } }))) } - pub fn rooms(&self) -> Vec { + pub fn rooms(&self) -> Vec { self.inner.rooms().into_iter().map(Into::into).collect() } pub fn subscribe_to_room_update( &self, - listener: Box, + listener: Box, ) -> Arc { let entries_stream = self.inner.subscribe_to_room_updates(); @@ -139,44 +138,23 @@ impl SpaceServiceRoomList { } } -#[derive(uniffi::Enum)] -pub enum SpaceServiceRoomListPaginationState { - Idle { end_reached: bool }, - Loading, -} - -impl From for SpaceServiceRoomListPaginationState { - fn from(state: UISpaceServiceRoomListPaginationState) -> Self { - match state { - UISpaceServiceRoomListPaginationState::Idle { end_reached } => { - SpaceServiceRoomListPaginationState::Idle { end_reached } - } - UISpaceServiceRoomListPaginationState::Loading => { - SpaceServiceRoomListPaginationState::Loading - } - } - } +#[matrix_sdk_ffi_macros::export(callback_interface)] +pub trait SpaceRoomListPaginationStateListener: SendOutsideWasm + SyncOutsideWasm + Debug { + fn on_update(&self, pagination_state: SpaceRoomListPaginationState); } #[matrix_sdk_ffi_macros::export(callback_interface)] -pub trait SpaceServiceRoomListPaginationStateListener: - SendOutsideWasm + SyncOutsideWasm + Debug -{ - fn on_update(&self, pagination_state: SpaceServiceRoomListPaginationState); -} - -#[matrix_sdk_ffi_macros::export(callback_interface)] -pub trait SpaceServiceRoomListEntriesListener: SendOutsideWasm + SyncOutsideWasm + Debug { - fn on_update(&self, rooms: Vec); +pub trait SpaceRoomListEntriesListener: SendOutsideWasm + SyncOutsideWasm + Debug { + fn on_update(&self, rooms: Vec); } #[matrix_sdk_ffi_macros::export(callback_interface)] pub trait SpaceServiceJoinedSpacesListener: SendOutsideWasm + SyncOutsideWasm + Debug { - fn on_update(&self, rooms: Vec); + fn on_update(&self, rooms: Vec); } #[derive(uniffi::Record)] -pub struct SpaceServiceRoom { +pub struct SpaceRoom { pub room_id: String, pub canonical_alias: Option, pub name: Option, @@ -193,8 +171,8 @@ pub struct SpaceServiceRoom { pub heroes: Option>, } -impl From for SpaceServiceRoom { - fn from(room: UISpaceServiceRoom) -> Self { +impl From for SpaceRoom { + fn from(room: UISpaceRoom) -> Self { Self { room_id: room.room_id.into(), canonical_alias: room.canonical_alias.map(|alias| alias.into()), diff --git a/crates/matrix-sdk-ui/src/spaces/graph.rs b/crates/matrix-sdk-ui/src/spaces/graph.rs index 202f57834..a173ead23 100644 --- a/crates/matrix-sdk-ui/src/spaces/graph.rs +++ b/crates/matrix-sdk-ui/src/spaces/graph.rs @@ -17,30 +17,30 @@ use std::collections::{BTreeMap, BTreeSet}; use ruma::OwnedRoomId; #[derive(Debug)] -struct SpaceServiceGraphNode { +struct SpaceGraphNode { id: OwnedRoomId, parents: BTreeSet, children: BTreeSet, } -impl SpaceServiceGraphNode { +impl SpaceGraphNode { fn new(id: OwnedRoomId) -> Self { Self { id, parents: BTreeSet::new(), children: BTreeSet::new() } } } #[derive(Debug)] -pub struct SpaceServiceGraph { - nodes: BTreeMap, +pub struct SpaceGraph { + nodes: BTreeMap, } -impl Default for SpaceServiceGraph { +impl Default for SpaceGraph { fn default() -> Self { Self::new() } } -impl SpaceServiceGraph { +impl SpaceGraph { pub fn new() -> Self { Self { nodes: BTreeMap::new() } } @@ -54,15 +54,13 @@ impl SpaceServiceGraph { } pub fn add_node(&mut self, node_id: OwnedRoomId) { - self.nodes.entry(node_id.clone()).or_insert(SpaceServiceGraphNode::new(node_id)); + self.nodes.entry(node_id.clone()).or_insert(SpaceGraphNode::new(node_id)); } pub fn add_edge(&mut self, parent_id: OwnedRoomId, child_id: OwnedRoomId) { - self.nodes - .entry(parent_id.clone()) - .or_insert(SpaceServiceGraphNode::new(parent_id.clone())); + self.nodes.entry(parent_id.clone()).or_insert(SpaceGraphNode::new(parent_id.clone())); - self.nodes.entry(child_id.clone()).or_insert(SpaceServiceGraphNode::new(child_id.clone())); + self.nodes.entry(child_id.clone()).or_insert(SpaceGraphNode::new(child_id.clone())); self.nodes.get_mut(&parent_id).unwrap().children.insert(child_id.clone()); self.nodes.get_mut(&child_id).unwrap().parents.insert(parent_id); @@ -124,7 +122,7 @@ mod tests { #[test] fn test_add_edge_and_root_nodes() { - let mut graph = SpaceServiceGraph::new(); + let mut graph = SpaceGraph::new(); let a = room_id!("!a:example.org").to_owned(); let b = room_id!("!b:example.org").to_owned(); @@ -143,7 +141,7 @@ mod tests { #[test] fn test_remove_cycles() { - let mut graph = SpaceServiceGraph::new(); + let mut graph = SpaceGraph::new(); let a = room_id!("!a:example.org").to_owned(); let b = room_id!("!b:example.org").to_owned(); @@ -163,7 +161,7 @@ mod tests { #[test] fn test_disconnected_graph_roots() { - let mut graph = SpaceServiceGraph::new(); + let mut graph = SpaceGraph::new(); let a = room_id!("!a:example.org").to_owned(); let b = room_id!("!b:example.org").to_owned(); @@ -182,7 +180,7 @@ mod tests { #[test] fn test_multiple_parents() { - let mut graph = SpaceServiceGraph::new(); + let mut graph = SpaceGraph::new(); let a = room_id!("!a:example.org").to_owned(); let b = room_id!("!b:example.org").to_owned(); diff --git a/crates/matrix-sdk-ui/src/spaces/mod.rs b/crates/matrix-sdk-ui/src/spaces/mod.rs index 786277c03..a08b93718 100644 --- a/crates/matrix-sdk-ui/src/spaces/mod.rs +++ b/crates/matrix-sdk-ui/src/spaces/mod.rs @@ -29,8 +29,8 @@ use ruma::{ }; use tracing::error; -use crate::spaces::graph::SpaceServiceGraph; -pub use crate::spaces::{room::SpaceServiceRoom, room_list::SpaceServiceRoomList}; +use crate::spaces::graph::SpaceGraph; +pub use crate::spaces::{room::SpaceRoom, room_list::SpaceRoomList}; pub mod graph; pub mod room; @@ -39,7 +39,7 @@ pub mod room_list; pub struct SpaceService { client: Client, - joined_spaces: SharedObservable>, + joined_spaces: SharedObservable>, room_update_handle: Mutex>>, } @@ -61,7 +61,7 @@ impl SpaceService { } } - pub fn subscribe_to_joined_spaces(&self) -> Subscriber> { + pub fn subscribe_to_joined_spaces(&self) -> Subscriber> { if self.room_update_handle.lock().is_none() { let client_clone = self.client.clone(); let joined_spaces_clone = self.joined_spaces.clone(); @@ -89,7 +89,7 @@ impl SpaceService { self.joined_spaces.subscribe() } - pub async fn joined_spaces(&self) -> Vec { + pub async fn joined_spaces(&self) -> Vec { let spaces = Self::joined_spaces_for(&self.client).await; if spaces != self.joined_spaces.get() { @@ -99,18 +99,18 @@ impl SpaceService { spaces } - pub fn space_room_list(&self, space_id: OwnedRoomId) -> SpaceServiceRoomList { - SpaceServiceRoomList::new(self.client.clone(), space_id) + pub fn space_room_list(&self, space_id: OwnedRoomId) -> SpaceRoomList { + SpaceRoomList::new(self.client.clone(), space_id) } - async fn joined_spaces_for(client: &Client) -> Vec { + async fn joined_spaces_for(client: &Client) -> Vec { let joined_spaces = client .joined_rooms() .into_iter() .filter_map(|room| room.is_space().then_some(room)) .collect::>(); - let mut graph = SpaceServiceGraph::new(); + let mut graph = SpaceGraph::new(); for space in joined_spaces.iter() { graph.add_node(space.room_id().to_owned()); @@ -160,7 +160,7 @@ impl SpaceService { let room_id = room.room_id().to_owned(); if root_notes.contains(&&room_id) { - Some(SpaceServiceRoom::new_from_known( + Some(SpaceRoom::new_from_known( room.clone(), graph.children_of(&room_id).len() as u64, )) @@ -330,7 +330,7 @@ mod tests { assert_eq!( space_service.joined_spaces().await, - vec![SpaceServiceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] + vec![SpaceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] ); // Join the second space @@ -355,8 +355,8 @@ mod tests { assert_eq!( space_service.joined_spaces().await, vec![ - SpaceServiceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0), - SpaceServiceRoom::new_from_known(client.get_room(second_space_id).unwrap(), 1) + SpaceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0), + SpaceRoom::new_from_known(client.get_room(second_space_id).unwrap(), 1) ] ); @@ -364,8 +364,8 @@ mod tests { assert_next_eq!( joined_spaces_subscriber, vec![ - SpaceServiceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0), - SpaceServiceRoom::new_from_known(client.get_room(second_space_id).unwrap(), 1) + SpaceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0), + SpaceRoom::new_from_known(client.get_room(second_space_id).unwrap(), 1) ] ); @@ -374,7 +374,7 @@ mod tests { // and when one is left assert_next_eq!( joined_spaces_subscriber, - vec![SpaceServiceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] + vec![SpaceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] ); // but it doesn't when a non-space room gets joined @@ -390,7 +390,7 @@ mod tests { assert_pending!(joined_spaces_subscriber); assert_eq!( space_service.joined_spaces().await, - vec![SpaceServiceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] + vec![SpaceRoom::new_from_known(client.get_room(first_space_id).unwrap(), 0)] ); } } diff --git a/crates/matrix-sdk-ui/src/spaces/room.rs b/crates/matrix-sdk-ui/src/spaces/room.rs index 11d623273..592d9d0a0 100644 --- a/crates/matrix-sdk-ui/src/spaces/room.rs +++ b/crates/matrix-sdk-ui/src/spaces/room.rs @@ -20,7 +20,7 @@ use ruma::{ }; #[derive(Debug, Clone, PartialEq)] -pub struct SpaceServiceRoom { +pub struct SpaceRoom { pub room_id: OwnedRoomId, pub canonical_alias: Option, pub name: Option, @@ -37,7 +37,7 @@ pub struct SpaceServiceRoom { pub heroes: Option>, } -impl SpaceServiceRoom { +impl SpaceRoom { pub fn new_from_summary( summary: &RoomSummary, known_room: Option, diff --git a/crates/matrix-sdk-ui/src/spaces/room_list.rs b/crates/matrix-sdk-ui/src/spaces/room_list.rs index 293b81516..c15dc11e4 100644 --- a/crates/matrix-sdk-ui/src/spaces/room_list.rs +++ b/crates/matrix-sdk-ui/src/spaces/room_list.rs @@ -21,36 +21,37 @@ use matrix_sdk_common::executor::{JoinHandle, spawn}; use ruma::{OwnedRoomId, api::client::space::get_hierarchy, uint}; use tracing::error; -use crate::spaces::SpaceServiceRoom; +use crate::spaces::SpaceRoom; +#[cfg_attr(feature = "uniffi", derive(uniffi::Enum))] #[derive(Clone, Debug, Eq, PartialEq)] -pub enum SpaceServiceRoomListPaginationState { +pub enum SpaceRoomListPaginationState { Idle { end_reached: bool }, Loading, } -pub struct SpaceServiceRoomList { +pub struct SpaceRoomList { client: Client, parent_space_id: OwnedRoomId, token: Mutex, - pagination_state: SharedObservable, + pagination_state: SharedObservable, - rooms: SharedObservable>, + rooms: SharedObservable>, room_update_handle: JoinHandle<()>, } -impl Drop for SpaceServiceRoomList { +impl Drop for SpaceRoomList { fn drop(&mut self) { self.room_update_handle.abort(); } } -impl SpaceServiceRoomList { +impl SpaceRoomList { pub fn new(client: Client, parent_space_id: OwnedRoomId) -> Self { - let rooms = SharedObservable::new(Vec::::new()); + let rooms = SharedObservable::new(Vec::::new()); let client_clone = client.clone(); let rooms_clone = rooms.clone(); @@ -69,10 +70,7 @@ impl SpaceServiceRoomList { new_rooms.iter_mut().find(|room| &room.room_id == updated_room_id) && let Some(update_room) = client_clone.get_room(updated_room_id) { - *room = SpaceServiceRoom::new_from_known( - update_room, - room.children_count, - ); + *room = SpaceRoom::new_from_known(update_room, room.children_count); } }); @@ -91,7 +89,7 @@ impl SpaceServiceRoomList { client, parent_space_id, token: Mutex::new(None.into()), - pagination_state: SharedObservable::new(SpaceServiceRoomListPaginationState::Idle { + pagination_state: SharedObservable::new(SpaceRoomListPaginationState::Idle { end_reached: false, }), rooms, @@ -99,36 +97,36 @@ impl SpaceServiceRoomList { } } - pub fn pagination_state(&self) -> SpaceServiceRoomListPaginationState { + pub fn pagination_state(&self) -> SpaceRoomListPaginationState { self.pagination_state.get() } pub fn subscribe_to_pagination_state_updates( &self, - ) -> Subscriber { + ) -> Subscriber { self.pagination_state.subscribe() } - pub fn rooms(&self) -> Vec { + pub fn rooms(&self) -> Vec { self.rooms.get() } - pub fn subscribe_to_room_updates(&self) -> Subscriber> { + pub fn subscribe_to_room_updates(&self) -> Subscriber> { self.rooms.subscribe() } pub async fn paginate(&self) -> Result<(), Error> { match *self.pagination_state.read() { - SpaceServiceRoomListPaginationState::Idle { end_reached } if end_reached => { + SpaceRoomListPaginationState::Idle { end_reached } if end_reached => { return Ok(()); } - SpaceServiceRoomListPaginationState::Loading => { + SpaceRoomListPaginationState::Loading => { return Ok(()); } _ => {} } - self.pagination_state.set(SpaceServiceRoomListPaginationState::Loading); + self.pagination_state.set(SpaceRoomListPaginationState::Loading); let mut request = get_hierarchy::v1::Request::new(self.parent_space_id.clone()); request.max_depth = Some(uint!(1)); // We only want the immediate children of the space @@ -159,7 +157,7 @@ impl SpaceServiceRoomList { if room.summary.room_id == self.parent_space_id { None } else { - Some(SpaceServiceRoom::new_from_summary( + Some(SpaceRoom::new_from_summary( &room.summary, self.client.get_room(&room.summary.room_id), room.children_state.len() as u64, @@ -171,7 +169,7 @@ impl SpaceServiceRoomList { self.rooms.set(current_rooms.clone()); - self.pagination_state.set(SpaceServiceRoomListPaginationState::Idle { + self.pagination_state.set(SpaceRoomListPaginationState::Idle { end_reached: result.next_batch.is_none(), }); @@ -179,7 +177,7 @@ impl SpaceServiceRoomList { } Err(err) => { self.pagination_state - .set(SpaceServiceRoomListPaginationState::Idle { end_reached: false }); + .set(SpaceRoomListPaginationState::Idle { end_reached: false }); Err(err.into()) } } @@ -198,9 +196,7 @@ mod tests { }; use stream_assert::{assert_next_eq, assert_next_matches, assert_pending, assert_ready}; - use crate::spaces::{ - SpaceService, SpaceServiceRoom, room_list::SpaceServiceRoomListPaginationState, - }; + use crate::spaces::{SpaceRoom, SpaceService, room_list::SpaceRoomListPaginationState}; #[async_test] async fn test_room_list_pagination() { @@ -217,7 +213,7 @@ mod tests { // Start off idle assert_matches!( room_list.pagination_state(), - SpaceServiceRoomListPaginationState::Idle { end_reached: false } + SpaceRoomListPaginationState::Idle { end_reached: false } ); // without any rooms @@ -251,14 +247,14 @@ mod tests { // informs that the pagination reached the end assert_next_matches!( pagination_state_subscriber, - SpaceServiceRoomListPaginationState::Idle { end_reached: true } + SpaceRoomListPaginationState::Idle { end_reached: true } ); // yields results assert_next_eq!( rooms_subscriber, vec![ - SpaceServiceRoom::new_from_summary( + SpaceRoom::new_from_summary( &RoomSummary::new( child_space_id_1.to_owned(), JoinRuleSummary::Public, @@ -269,7 +265,7 @@ mod tests { None, 1 ), - SpaceServiceRoom::new_from_summary( + SpaceRoom::new_from_summary( &RoomSummary::new( child_space_id_2.to_owned(), JoinRuleSummary::Public,