diff --git a/bindings/matrix-sdk-ffi/src/identity_status_change.rs b/bindings/matrix-sdk-ffi/src/identity_status_change.rs new file mode 100644 index 00000000000..3fcb5a69142 --- /dev/null +++ b/bindings/matrix-sdk-ffi/src/identity_status_change.rs @@ -0,0 +1,24 @@ +// Copyright 2024 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use matrix_sdk::crypto::IdentityState; + +#[derive(uniffi::Record)] +pub struct IdentityStatusChange { + /// The user ID of the user whose identity status changed + pub user_id: String, + + /// The new state of the identity of the user. + pub changed_to: IdentityState, +} diff --git a/bindings/matrix-sdk-ffi/src/lib.rs b/bindings/matrix-sdk-ffi/src/lib.rs index 47ef7240d3d..801887b6fee 100644 --- a/bindings/matrix-sdk-ffi/src/lib.rs +++ b/bindings/matrix-sdk-ffi/src/lib.rs @@ -11,6 +11,7 @@ mod encryption; mod error; mod event; mod helpers; +mod identity_status_change; mod notification; mod notification_settings; mod platform; diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index c736007e381..8c21f7ca55f 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -1,6 +1,7 @@ -use std::{collections::HashMap, sync::Arc}; +use std::{collections::HashMap, pin::pin, sync::Arc}; use anyhow::{Context, Result}; +use futures_util::StreamExt; use matrix_sdk::{ crypto::LocalTrust, event_cache::paginator::PaginatorError, @@ -35,6 +36,7 @@ use crate::{ chunk_iterator::ChunkIterator, error::{ClientError, MediaInfoError, RoomError}, event::{MessageLikeEventType, StateEventType}, + identity_status_change::IdentityStatusChange, room_info::RoomInfo, room_member::RoomMember, ruma::{ImageInfo, Mentions, NotifyType}, @@ -582,6 +584,31 @@ impl Room { }))) } + pub fn subscribe_to_identity_status_changes( + &self, + listener: Box, + ) -> Arc { + let room = self.inner.clone(); + Arc::new(TaskHandle::new(RUNTIME.spawn(async move { + let status_changes = room.subscribe_to_identity_status_changes().await; + if let Ok(status_changes) = status_changes { + // TODO: what to do with failures? + let mut status_changes = pin!(status_changes); + while let Some(identity_status_changes) = status_changes.next().await { + listener.call( + identity_status_changes + .into_iter() + .map(|change| { + let user_id = change.user_id.to_string(); + IdentityStatusChange { user_id, changed_to: change.changed_to } + }) + .collect(), + ); + } + } + }))) + } + /// Set (or unset) a flag on the room to indicate that the user has /// explicitly marked it as unread. pub async fn set_unread_flag(&self, new_value: bool) -> Result<(), ClientError> { @@ -898,6 +925,11 @@ pub trait TypingNotificationsListener: Sync + Send { fn call(&self, typing_user_ids: Vec); } +#[uniffi::export(callback_interface)] +pub trait IdentityStatusChangeListener: Sync + Send { + fn call(&self, identity_status_change: Vec); +} + #[derive(uniffi::Object)] pub struct RoomMembersIterator { chunk_iterator: ChunkIterator,