diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index f18d057a3..c4cc15bd9 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -505,15 +505,18 @@ impl Room { pub async fn typing_notice(&self, is_typing: bool) -> Result<(), ClientError> { Ok(self.inner.typing_notice(is_typing).await?) } + pub async fn subscribe_to_typing_notifications( self: Arc, listener: Box, ) -> Arc { Arc::new(TaskHandle::new(RUNTIME.spawn(async move { - let (_guard, mut subscriber) = self.inner.subscribe_to_typing_notifications(); - while let Ok(typing_users) = subscriber.recv().await { - let typing_users = typing_users.iter().map(|u| u.to_string()).collect(); - listener.call(typing_users); + let (_event_handler_drop_guard, mut subscriber) = + self.inner.subscribe_to_typing_notifications(); + while let Ok(typing_user_ids) = subscriber.recv().await { + let typing_user_ids = + typing_user_ids.into_iter().map(|user_id| user_id.to_string()).collect(); + listener.call(typing_user_ids); } }))) } @@ -526,7 +529,7 @@ pub trait RoomInfoListener: Sync + Send { #[uniffi::export(callback_interface)] pub trait TypingNotificationsListener: Sync + Send { - fn call(&self, typing_users: Vec); + fn call(&self, typing_user_ids: Vec); } #[derive(uniffi::Object)] diff --git a/crates/matrix-sdk/src/room/mod.rs b/crates/matrix-sdk/src/room/mod.rs index 070e7acd7..a4cb63e81 100644 --- a/crates/matrix-sdk/src/room/mod.rs +++ b/crates/matrix-sdk/src/room/mod.rs @@ -325,13 +325,13 @@ impl Room { ) -> (EventHandlerDropGuard, broadcast::Receiver>) { let (sender, receiver) = broadcast::channel(16); let typing_event_handler_handle = self.client.add_room_event_handler(self.room_id(), { - let sender = sender.clone(); - move |ev: SyncTypingEvent| async move { - let _ = sender.send(ev.content.user_ids); + move |event: SyncTypingEvent| async move { + // Ignore the result. It can only fail if there are no listeners. + let _ = sender.send(event.content.user_ids); } }); - let guard = self.client().event_handler_drop_guard(typing_event_handler_handle); - (guard, receiver) + let drop_guard = self.client().event_handler_drop_guard(typing_event_handler_handle); + (drop_guard, receiver) } /// Fetch the event with the given `EventId` in this room. diff --git a/crates/matrix-sdk/tests/integration/room/joined.rs b/crates/matrix-sdk/tests/integration/room/joined.rs index 80e5a0e4a..4983f5f36 100644 --- a/crates/matrix-sdk/tests/integration/room/joined.rs +++ b/crates/matrix-sdk/tests/integration/room/joined.rs @@ -667,17 +667,23 @@ async fn subscribe_to_typing_notifications() { // Send to typing notification let room = client.get_room(room_id).unwrap(); - let typing_seq = Arc::clone(&typing_sequences); - let handle = tokio::spawn(async move { - let (_guard, mut subscriber) = room.subscribe_to_typing_notifications(); - while let Ok(typing_users) = subscriber.recv().await { - let mut typings = typing_seq.lock().unwrap(); - typings.push(typing_users); - if typings.len() == 2 { - break; + let join_handle = tokio::spawn({ + let typing_sequences = Arc::clone(&typing_sequences); + async move { + let (_drop_guard, mut subscriber) = room.subscribe_to_typing_notifications(); + + while let Ok(typing_user_ids) = subscriber.recv().await { + let mut typing_sequences = typing_sequences.lock().unwrap(); + typing_sequences.push(typing_user_ids); + + // When we have received 2 typing notifications, we can stop listening. + if typing_sequences.len() == 2 { + break; + } } } }); + // Then send a typing notification with 2 users typing ev_builder.add_joined_room(JoinedRoomBuilder::new(room_id).add_ephemeral_event( EphemeralTestEvent::Custom(json!({ @@ -709,6 +715,6 @@ async fn subscribe_to_typing_notifications() { let _response = client.sync_once(sync_settings.clone()).await.unwrap(); server.reset().await; - handle.await.unwrap(); + join_handle.await.unwrap(); assert_eq!(typing_sequences.lock().unwrap().to_vec(), asserted_typing_sequences); }