diff --git a/bindings/matrix-sdk-ffi/src/authentication_service.rs b/bindings/matrix-sdk-ffi/src/authentication_service.rs index b1085e4d669..41800b26b73 100644 --- a/bindings/matrix-sdk-ffi/src/authentication_service.rs +++ b/bindings/matrix-sdk-ffi/src/authentication_service.rs @@ -652,7 +652,7 @@ impl AuthenticationService { let client = client.build_inner().await?; // Restore the client using the session from the login request. - client.restore_session_inner(session)?; + client.restore_session_inner(session).await?; Ok(Arc::new(client)) } diff --git a/bindings/matrix-sdk-ffi/src/client.rs b/bindings/matrix-sdk-ffi/src/client.rs index 6d97fcacf61..60ed07e9901 100644 --- a/bindings/matrix-sdk-ffi/src/client.rs +++ b/bindings/matrix-sdk-ffi/src/client.rs @@ -182,7 +182,7 @@ impl Drop for Client { } impl Client { - pub fn new( + pub async fn new( sdk_client: MatrixClient, cross_process_refresh_lock_id: Option, session_delegate: Option>, @@ -212,9 +212,7 @@ impl Client { "missing session delegates when enabling the cross-process lock" ))?; } - RUNTIME.block_on(async { - client.inner.oidc().enable_cross_process_refresh_lock(process_id.clone()).await - })?; + client.inner.oidc().enable_cross_process_refresh_lock(process_id.clone()).await?; } if let Some(session_delegate) = session_delegate { @@ -291,11 +289,11 @@ impl Client { } /// Restores the client from a `Session`. - pub fn restore_session(&self, session: Session) -> Result<(), ClientError> { + pub async fn restore_session(&self, session: Session) -> Result<(), ClientError> { let sliding_sync_proxy = session.sliding_sync_proxy.clone(); let auth_session: AuthSession = session.try_into()?; - self.restore_session_inner(auth_session)?; + self.restore_session_inner(auth_session).await?; if let Some(sliding_sync_proxy) = sliding_sync_proxy { let sliding_sync_proxy = Url::parse(&sliding_sync_proxy) @@ -310,14 +308,12 @@ impl Client { impl Client { /// Restores the client from an `AuthSession`. - pub(crate) fn restore_session_inner( + pub(crate) async fn restore_session_inner( &self, session: impl Into, ) -> anyhow::Result<()> { - RUNTIME.block_on(async move { - self.inner.restore_session(session).await?; - Ok(()) - }) + self.inner.restore_session(session).await?; + Ok(()) } /// The sliding sync proxy of the homeserver. It is either set automatically @@ -370,8 +366,8 @@ impl Client { }) } - pub fn session(&self) -> Result { - RUNTIME.block_on(async move { Self::session_inner((*self.inner).clone()).await }) + pub async fn session(&self) -> Result { + Self::session_inner((*self.inner).clone()).await } pub async fn account_url( @@ -392,57 +388,40 @@ impl Client { Ok(user_id.to_string()) } - pub fn display_name(&self) -> Result { - let l = self.inner.clone(); - RUNTIME.block_on(async move { - let display_name = l.account().get_display_name().await?.context("No User ID found")?; - Ok(display_name) - }) + pub async fn display_name(&self) -> Result { + let display_name = + self.inner.account().get_display_name().await?.context("No User ID found")?; + Ok(display_name) } - pub fn set_display_name(&self, name: String) -> Result<(), ClientError> { - let client = self.inner.clone(); - RUNTIME.block_on(async move { - client - .account() - .set_display_name(Some(name.as_str())) - .await - .context("Unable to set display name")?; - Ok(()) - }) + pub async fn set_display_name(&self, name: String) -> Result<(), ClientError> { + self.inner + .account() + .set_display_name(Some(name.as_str())) + .await + .context("Unable to set display name")?; + Ok(()) } - pub fn upload_avatar(&self, mime_type: String, data: Vec) -> Result<(), ClientError> { - let client = self.inner.clone(); - RUNTIME.block_on(async move { - let mime: Mime = mime_type.parse()?; - client.account().upload_avatar(&mime, data).await?; - Ok(()) - }) + pub async fn upload_avatar(&self, mime_type: String, data: Vec) -> Result<(), ClientError> { + let mime: Mime = mime_type.parse()?; + self.inner.account().upload_avatar(&mime, data).await?; + Ok(()) } - pub fn remove_avatar(&self) -> Result<(), ClientError> { - let client = self.inner.clone(); - RUNTIME.block_on(async move { - client.account().set_avatar_url(None).await?; - Ok(()) - }) + pub async fn remove_avatar(&self) -> Result<(), ClientError> { + self.inner.account().set_avatar_url(None).await?; + Ok(()) } - pub fn avatar_url(&self) -> Result, ClientError> { - let l = self.inner.clone(); - RUNTIME.block_on(async move { - let avatar_url = l.account().get_avatar_url().await?; - Ok(avatar_url.map(|u| u.to_string())) - }) + pub async fn avatar_url(&self) -> Result, ClientError> { + let avatar_url = self.inner.account().get_avatar_url().await?; + Ok(avatar_url.map(|u| u.to_string())) } - pub fn cached_avatar_url(&self) -> Result, ClientError> { - let l = self.inner.clone(); - RUNTIME.block_on(async move { - let url = l.account().get_cached_avatar_url().await?; - Ok(url) - }) + pub async fn cached_avatar_url(&self) -> Result, ClientError> { + let url = self.inner.account().get_cached_avatar_url().await?; + Ok(url) } pub fn device_id(&self) -> Result { @@ -450,35 +429,31 @@ impl Client { Ok(device_id.to_string()) } - pub fn create_room(&self, request: CreateRoomParameters) -> Result { - let client = self.inner.clone(); - - RUNTIME.block_on(async move { - let response = client.create_room(request.into()).await?; - Ok(String::from(response.room_id())) - }) + pub async fn create_room(&self, request: CreateRoomParameters) -> Result { + let response = self.inner.create_room(request.into()).await?; + Ok(String::from(response.room_id())) } /// Get the content of the event of the given type out of the account data /// store. /// /// It will be returned as a JSON string. - pub fn account_data(&self, event_type: String) -> Result, ClientError> { - RUNTIME.block_on(async move { - let event = self.inner.account().account_data_raw(event_type.into()).await?; - Ok(event.map(|e| e.json().get().to_owned())) - }) + pub async fn account_data(&self, event_type: String) -> Result, ClientError> { + let event = self.inner.account().account_data_raw(event_type.into()).await?; + Ok(event.map(|e| e.json().get().to_owned())) } /// Set the given account data content for the given event type. /// /// It should be supplied as a JSON string. - pub fn set_account_data(&self, event_type: String, content: String) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - let raw_content = Raw::from_json_string(content)?; - self.inner.account().set_account_data_raw(event_type.into(), raw_content).await?; - Ok(()) - }) + pub async fn set_account_data( + &self, + event_type: String, + content: String, + ) -> Result<(), ClientError> { + let raw_content = Raw::from_json_string(content)?; + self.inner.account().set_account_data_raw(event_type.into(), raw_content).await?; + Ok(()) } pub async fn upload_media( @@ -542,37 +517,35 @@ impl Client { .await?) } - pub fn get_session_verification_controller( + pub async fn get_session_verification_controller( &self, ) -> Result, ClientError> { - RUNTIME.block_on(async move { - if let Some(session_verification_controller) = - &*self.session_verification_controller.read().await - { - return Ok(Arc::new(session_verification_controller.clone())); - } - let user_id = self.inner.user_id().context("Failed retrieving current user_id")?; - let user_identity = self - .inner - .encryption() - .get_user_identity(user_id) - .await? - .context("Failed retrieving user identity")?; + if let Some(session_verification_controller) = + &*self.session_verification_controller.read().await + { + return Ok(Arc::new(session_verification_controller.clone())); + } + let user_id = self.inner.user_id().context("Failed retrieving current user_id")?; + let user_identity = self + .inner + .encryption() + .get_user_identity(user_id) + .await? + .context("Failed retrieving user identity")?; - let session_verification_controller = - SessionVerificationController::new(self.inner.encryption(), user_identity); + let session_verification_controller = + SessionVerificationController::new(self.inner.encryption(), user_identity); - *self.session_verification_controller.write().await = - Some(session_verification_controller.clone()); + *self.session_verification_controller.write().await = + Some(session_verification_controller.clone()); - Ok(Arc::new(session_verification_controller)) - }) + Ok(Arc::new(session_verification_controller)) } /// Log out the current user. This method returns an optional URL that /// should be presented to the user to complete logout (in the case of /// Session having been authenticated using OIDC). - pub fn logout(&self) -> Result, ClientError> { + pub async fn logout(&self) -> Result, ClientError> { let Some(auth_api) = self.inner.auth_api() else { return Err(anyhow!("Missing authentication API").into()); }; @@ -580,12 +553,13 @@ impl Client { match auth_api { AuthApi::Matrix(a) => { tracing::info!("Logging out via the homeserver."); - RUNTIME.block_on(a.logout())?; + a.logout().await?; Ok(None) } + AuthApi::Oidc(api) => { tracing::info!("Logging out via OIDC."); - let end_session_builder = RUNTIME.block_on(api.logout())?; + let end_session_builder = api.logout().await?; if let Some(builder) = end_session_builder { let url = builder.build()?.url; @@ -644,50 +618,43 @@ impl Client { Ok(dm) } - pub fn search_users( + pub async fn search_users( &self, search_term: String, limit: u64, ) -> Result { - RUNTIME.block_on(async move { - let response = self.inner.search_users(&search_term, limit).await?; - Ok(SearchUsersResults::from(response)) - }) + let response = self.inner.search_users(&search_term, limit).await?; + Ok(SearchUsersResults::from(response)) } - pub fn get_profile(&self, user_id: String) -> Result { - RUNTIME.block_on(async move { - let owned_user_id = UserId::parse(user_id.clone())?; - let response = self.inner.account().fetch_user_profile_of(&owned_user_id).await?; + pub async fn get_profile(&self, user_id: String) -> Result { + let owned_user_id = UserId::parse(user_id.clone())?; - let user_profile = UserProfile { - user_id, - display_name: response.displayname.clone(), - avatar_url: response.avatar_url.as_ref().map(|url| url.to_string()), - }; + let response = self.inner.account().fetch_user_profile_of(&owned_user_id).await?; - Ok(user_profile) + Ok(UserProfile { + user_id, + display_name: response.displayname.clone(), + avatar_url: response.avatar_url.as_ref().map(|url| url.to_string()), }) } - pub fn notification_client( + pub async fn notification_client( self: Arc, process_setup: NotificationProcessSetup, ) -> Result, ClientError> { - NotificationClientBuilder::new(self.clone(), process_setup.into()) + NotificationClientBuilder::new(self.clone(), process_setup.into()).await } pub fn sync_service(&self) -> Arc { SyncServiceBuilder::new((*self.inner).clone()) } - pub fn get_notification_settings(&self) -> Arc { - RUNTIME.block_on(async move { - Arc::new(NotificationSettings::new( - (*self.inner).clone(), - self.inner.notification_settings().await, - )) - }) + pub async fn get_notification_settings(&self) -> Arc { + Arc::new(NotificationSettings::new( + (*self.inner).clone(), + self.inner.notification_settings().await, + )) } pub fn encryption(&self) -> Arc { diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index 09865b68bb0..fb1dcee18f8 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -360,10 +360,7 @@ impl ClientBuilder { sdk_client.set_sliding_sync_proxy(Some(Url::parse(&sliding_sync_proxy)?)); } - Ok(Client::new( - sdk_client, - builder.cross_process_refresh_lock_id, - builder.session_delegate, - )?) + Ok(Client::new(sdk_client, builder.cross_process_refresh_lock_id, builder.session_delegate) + .await?) } } diff --git a/bindings/matrix-sdk-ffi/src/notification.rs b/bindings/matrix-sdk-ffi/src/notification.rs index febe9a05ab2..29012a2b952 100644 --- a/bindings/matrix-sdk-ffi/src/notification.rs +++ b/bindings/matrix-sdk-ffi/src/notification.rs @@ -8,7 +8,7 @@ use matrix_sdk_ui::notification_client::{ use ruma::{EventId, RoomId}; use crate::{ - client::Client, error::ClientError, event::TimelineEvent, helpers::unwrap_or_clone_arc, RUNTIME, + client::Client, error::ClientError, event::TimelineEvent, helpers::unwrap_or_clone_arc, }; #[derive(uniffi::Enum)] @@ -87,13 +87,12 @@ pub struct NotificationClientBuilder { } impl NotificationClientBuilder { - pub(crate) fn new( + pub(crate) async fn new( client: Arc, process_setup: NotificationProcessSetup, ) -> Result, ClientError> { - let builder = RUNTIME.block_on(async { - MatrixNotificationClient::builder((*client.inner).clone(), process_setup).await - })?; + let builder = + MatrixNotificationClient::builder((*client.inner).clone(), process_setup).await?; Ok(Arc::new(Self { builder, client })) } } @@ -126,28 +125,25 @@ pub struct NotificationClient { _client: Arc, } -#[uniffi::export] +#[uniffi::export(async_runtime = "tokio")] impl NotificationClient { /// See also documentation of /// `MatrixNotificationClient::get_notification`. - pub fn get_notification( + pub async fn get_notification( &self, room_id: String, event_id: String, ) -> Result, ClientError> { let room_id = RoomId::parse(room_id)?; let event_id = EventId::parse(event_id)?; - RUNTIME.block_on(async move { - let item = self - .inner - .get_notification(&room_id, &event_id) - .await - .map_err(ClientError::from)?; - if let Some(item) = item { - Ok(Some(NotificationItem::from_inner(item))) - } else { - Ok(None) - } - }) + + let item = + self.inner.get_notification(&room_id, &event_id).await.map_err(ClientError::from)?; + + if let Some(item) = item { + Ok(Some(NotificationItem::from_inner(item))) + } else { + Ok(None) + } } } diff --git a/bindings/matrix-sdk-ffi/src/room.rs b/bindings/matrix-sdk-ffi/src/room.rs index 9abb3237231..c53e65657e2 100644 --- a/bindings/matrix-sdk-ffi/src/room.rs +++ b/bindings/matrix-sdk-ffi/src/room.rs @@ -89,8 +89,8 @@ impl Room { self.inner.avatar_url().map(|m| m.to_string()) } - pub fn is_direct(&self) -> bool { - RUNTIME.block_on(async move { self.inner.is_direct().await.unwrap_or(false) }) + pub async fn is_direct(&self) -> bool { + self.inner.is_direct().await.unwrap_or(false) } pub fn is_public(&self) -> bool { @@ -210,17 +210,12 @@ impl Room { Ok(Timeline::new(timeline)) } - pub fn display_name(&self) -> Result { - let r = self.inner.clone(); - RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) }) + pub async fn display_name(&self) -> Result { + Ok(self.inner.display_name().await?.to_string()) } - pub fn is_encrypted(&self) -> Result { - let room = self.inner.clone(); - RUNTIME.block_on(async move { - let is_encrypted = room.is_encrypted().await?; - Ok(is_encrypted) - }) + pub async fn is_encrypted(&self) -> Result { + Ok(self.inner.is_encrypted().await?) } pub async fn members(&self) -> Result, ClientError> { @@ -235,28 +230,25 @@ impl Room { pub async fn member(&self, user_id: String) -> Result { let user_id = UserId::parse(&*user_id).context("Invalid user id.")?; - let member = self.inner.get_member(&user_id).await?.context("No user found")?; + let member = self.inner.get_member(&user_id).await?.context("User not found")?; Ok(member.into()) } - pub fn member_avatar_url(&self, user_id: String) -> Result, ClientError> { - let room = self.inner.clone(); - RUNTIME.block_on(async move { - let user_id = UserId::parse(&*user_id).context("Invalid user id.")?; - let member = room.get_member(&user_id).await?.context("No user found")?; - let avatar_url_string = member.avatar_url().map(|m| m.to_string()); - Ok(avatar_url_string) - }) + pub async fn member_avatar_url(&self, user_id: String) -> Result, ClientError> { + let user_id = UserId::parse(&*user_id).context("Invalid user id.")?; + let member = self.inner.get_member(&user_id).await?.context("User not found")?; + let avatar_url_string = member.avatar_url().map(|m| m.to_string()); + Ok(avatar_url_string) } - pub fn member_display_name(&self, user_id: String) -> Result, ClientError> { - let room = self.inner.clone(); - RUNTIME.block_on(async move { - let user_id = UserId::parse(&*user_id).context("Invalid user id.")?; - let member = room.get_member(&user_id).await?.context("No user found")?; - let avatar_url_string = member.display_name().map(|m| m.to_owned()); - Ok(avatar_url_string) - }) + pub async fn member_display_name( + &self, + user_id: String, + ) -> Result, ClientError> { + let user_id = UserId::parse(&*user_id).context("Invalid user id.")?; + let member = self.inner.get_member(&user_id).await?.context("User not found")?; + let avatar_url_string = member.display_name().map(|m| m.to_owned()); + Ok(avatar_url_string) } pub async fn room_info(&self) -> Result { @@ -340,12 +332,14 @@ impl Room { /// /// * `reason` - The reason for the event being redacted (optional). /// its transaction ID (optional). If not given one is created. - pub fn redact(&self, event_id: String, reason: Option) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - let event_id = EventId::parse(event_id)?; - self.inner.redact(&event_id, reason.as_deref(), None).await?; - Ok(()) - }) + pub async fn redact( + &self, + event_id: String, + reason: Option, + ) -> Result<(), ClientError> { + let event_id = EventId::parse(event_id)?; + self.inner.redact(&event_id, reason.as_deref(), None).await?; + Ok(()) } pub fn active_members_count(&self) -> u64 { @@ -370,29 +364,27 @@ impl Room { /// /// * `score` - The score to rate this content as where -100 is most /// offensive and 0 is inoffensive (optional). - pub fn report_content( + pub async fn report_content( &self, event_id: String, score: Option, reason: Option, ) -> Result<(), ClientError> { + let event_id = EventId::parse(event_id)?; let int_score = score.map(|value| value.into()); - RUNTIME.block_on(async move { - let event_id = EventId::parse(event_id)?; - self.inner - .client() - .send( - report_content::v3::Request::new( - self.inner.room_id().into(), - event_id, - int_score, - reason, - ), - None, - ) - .await?; - Ok(()) - }) + self.inner + .client() + .send( + report_content::v3::Request::new( + self.inner.room_id().into(), + event_id, + int_score, + reason, + ), + None, + ) + .await?; + Ok(()) } /// Ignores a user. @@ -409,37 +401,29 @@ impl Room { /// Leave this room. /// /// Only invited and joined rooms can be left. - pub fn leave(&self) -> Result<(), ClientError> { - RUNTIME.block_on(async { - self.inner.leave().await?; - Ok(()) - }) + pub async fn leave(&self) -> Result<(), ClientError> { + self.inner.leave().await?; + Ok(()) } /// Join this room. /// /// Only invited and left rooms can be joined via this method. - pub fn join(&self) -> Result<(), ClientError> { - RUNTIME.block_on(async { - self.inner.join().await?; - Ok(()) - }) + pub async fn join(&self) -> Result<(), ClientError> { + self.inner.join().await?; + Ok(()) } /// Sets a new name to the room. - pub fn set_name(&self, name: String) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - self.inner.set_name(name).await?; - Ok(()) - }) + pub async fn set_name(&self, name: String) -> Result<(), ClientError> { + self.inner.set_name(name).await?; + Ok(()) } /// Sets a new topic in the room. - pub fn set_topic(&self, topic: String) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - self.inner.set_room_topic(&topic).await?; - Ok(()) - }) + pub async fn set_topic(&self, topic: String) -> Result<(), ClientError> { + self.inner.set_room_topic(&topic).await?; + Ok(()) } /// Upload and set the room's avatar. @@ -455,43 +439,37 @@ impl Room { /// * `data` - The raw data that will be uploaded to the homeserver's /// content repository /// * `media_info` - The media info used as avatar image info. - pub fn upload_avatar( + pub async fn upload_avatar( &self, mime_type: String, data: Vec, media_info: Option, ) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - let mime: Mime = mime_type.parse()?; - self.inner - .upload_avatar( - &mime, - data, - media_info - .map(TryInto::try_into) - .transpose() - .map_err(|_| RoomError::InvalidMediaInfo)?, - ) - .await?; - Ok(()) - }) + let mime: Mime = mime_type.parse()?; + self.inner + .upload_avatar( + &mime, + data, + media_info + .map(TryInto::try_into) + .transpose() + .map_err(|_| RoomError::InvalidMediaInfo)?, + ) + .await?; + Ok(()) } /// Removes the current room avatar - pub fn remove_avatar(&self) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - self.inner.remove_avatar().await?; - Ok(()) - }) - } - - pub fn invite_user_by_id(&self, user_id: String) -> Result<(), ClientError> { - RUNTIME.block_on(async move { - let user = <&UserId>::try_from(user_id.as_str()) - .context("Could not create user from string")?; - self.inner.invite_user_by_id(user).await?; - Ok(()) - }) + pub async fn remove_avatar(&self) -> Result<(), ClientError> { + self.inner.remove_avatar().await?; + Ok(()) + } + + pub async fn invite_user_by_id(&self, user_id: String) -> Result<(), ClientError> { + let user = + <&UserId>::try_from(user_id.as_str()).context("Could not create user from string")?; + self.inner.invite_user_by_id(user).await?; + Ok(()) } pub async fn can_user_redact_own(&self, user_id: String) -> Result { diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 9f231e83269..8cf412ae533 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -125,11 +125,11 @@ impl RoomListService { }))) } - fn room(&self, room_id: String) -> Result, RoomListError> { + async fn room(&self, room_id: String) -> Result, RoomListError> { let room_id = <&RoomId>::try_from(room_id.as_str()).map_err(RoomListError::from)?; Ok(Arc::new(RoomListItem { - inner: Arc::new(RUNTIME.block_on(async { self.inner.room(room_id).await })?), + inner: Arc::new(self.inner.room(room_id).await?), utd_hook: self.utd_hook.clone(), })) } @@ -179,7 +179,7 @@ pub struct RoomList { inner: Arc, } -#[uniffi::export] +#[uniffi::export(async_runtime = "tokio")] impl RoomList { fn loading_state( &self, @@ -240,8 +240,8 @@ impl RoomList { } } - fn room(&self, room_id: String) -> Result, RoomListError> { - self.room_list_service.room(room_id) + async fn room(&self, room_id: String) -> Result, RoomListError> { + self.room_list_service.room(room_id).await } } @@ -490,16 +490,16 @@ impl RoomListItem { self.inner.id().to_string() } - fn name(&self) -> Option { - RUNTIME.block_on(async { self.inner.name().await }) + async fn name(&self) -> Option { + self.inner.name().await } fn avatar_url(&self) -> Option { self.inner.avatar_url().map(|uri| uri.to_string()) } - fn is_direct(&self) -> bool { - RUNTIME.block_on(async { self.inner.inner_room().is_direct().await.unwrap_or(false) }) + async fn is_direct(&self) -> bool { + self.inner.inner_room().is_direct().await.unwrap_or(false) } fn canonical_alias(&self) -> Option { diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 74006625f58..ffd3a7b10e8 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -190,19 +190,16 @@ impl Timeline { Ok(self.inner.focused_paginate_forwards(num_events).await?) } - pub fn send_read_receipt( + pub async fn send_read_receipt( &self, receipt_type: ReceiptType, event_id: String, ) -> Result<(), ClientError> { let event_id = EventId::parse(event_id)?; - - RUNTIME.block_on(async { - self.inner - .send_single_receipt(receipt_type.into(), ReceiptThread::Unthreaded, event_id) - .await?; - Ok(()) - }) + self.inner + .send_single_receipt(receipt_type.into(), ReceiptThread::Unthreaded, event_id) + .await?; + Ok(()) } /// Mark the room as read by trying to attach an *unthreaded* read receipt @@ -429,29 +426,27 @@ impl Timeline { Ok(()) } - pub fn send_reply( + pub async fn send_reply( &self, msg: Arc, reply_item: Arc, ) -> Result<(), ClientError> { - RUNTIME.block_on(async { - self.inner.send_reply((*msg).clone(), &reply_item.0, ForwardThread::Yes).await?; - anyhow::Ok(()) - })?; - + self.inner + .send_reply((*msg).clone(), &reply_item.0, ForwardThread::Yes) + .await + .map_err(|err| anyhow::anyhow!(err))?; Ok(()) } - pub fn edit( + pub async fn edit( &self, new_content: Arc, edit_item: Arc, ) -> Result<(), ClientError> { - RUNTIME.block_on(async { - self.inner.edit((*new_content).clone().with_relation(None), &edit_item.0).await?; - anyhow::Ok(()) - })?; - + self.inner + .edit((*new_content).clone().with_relation(None), &edit_item.0) + .await + .map_err(|err| anyhow::anyhow!(err))?; Ok(()) } @@ -464,14 +459,10 @@ impl Timeline { edit_item: Arc, ) -> Result<(), ClientError> { let poll_data = PollData { question, answers, max_selections, poll_kind }; - - RUNTIME.block_on(async { - self.inner - .edit_poll(poll_data.fallback_text(), poll_data.try_into()?, &edit_item.0) - .await?; - anyhow::Ok(()) - })?; - + self.inner + .edit_poll(poll_data.fallback_text(), poll_data.try_into()?, &edit_item.0) + .await + .map_err(|err| anyhow::anyhow!(err))?; Ok(()) } @@ -502,20 +493,16 @@ impl Timeline { self.send(Arc::new(room_message_event_content)) } - pub fn toggle_reaction(&self, event_id: String, key: String) -> Result<(), ClientError> { + pub async fn toggle_reaction(&self, event_id: String, key: String) -> Result<(), ClientError> { let event_id = EventId::parse(event_id)?; - RUNTIME.block_on(async { - self.inner.toggle_reaction(&Annotation::new(event_id, key)).await?; - Ok(()) - }) + self.inner.toggle_reaction(&Annotation::new(event_id, key)).await?; + Ok(()) } - pub fn fetch_details_for_event(&self, event_id: String) -> Result<(), ClientError> { + pub async fn fetch_details_for_event(&self, event_id: String) -> Result<(), ClientError> { let event_id = <&EventId>::try_from(event_id.as_str())?; - RUNTIME.block_on(async { - self.inner.fetch_details_for_event(event_id).await.context("Fetching event details")?; - Ok(()) - }) + self.inner.fetch_details_for_event(event_id).await.context("Fetching event details")?; + Ok(()) } pub fn retry_send(self: Arc, txn_id: String) { @@ -534,43 +521,39 @@ impl Timeline { }); } - pub fn get_event_timeline_item_by_event_id( + pub async fn get_event_timeline_item_by_event_id( &self, event_id: String, ) -> Result, ClientError> { let event_id = EventId::parse(event_id)?; - RUNTIME.block_on(async { - let item = self - .inner - .item_by_event_id(&event_id) - .await - .context("Item with given event ID not found")?; - - Ok(Arc::new(EventTimelineItem(item))) - }) + let item = self + .inner + .item_by_event_id(&event_id) + .await + .context("Item with given event ID not found")?; + Ok(Arc::new(EventTimelineItem(item))) } - pub fn get_timeline_event_content_by_event_id( + pub async fn get_timeline_event_content_by_event_id( &self, event_id: String, ) -> Result, ClientError> { let event_id = EventId::parse(event_id)?; - RUNTIME.block_on(async { - let item = self - .inner - .item_by_event_id(&event_id) - .await - .context("Item with given event ID not found")?; - - let msgtype = item - .content() - .as_message() - .context("Item with given event ID is not a message")? - .msgtype() - .to_owned(); - - Ok(Arc::new(RoomMessageEventContentWithoutRelation::new(msgtype))) - }) + + let item = self + .inner + .item_by_event_id(&event_id) + .await + .context("Item with given event ID not found")?; + + let msgtype = item + .content() + .as_message() + .context("Item with given event ID is not a message")? + .msgtype() + .to_owned(); + + Ok(Arc::new(RoomMessageEventContentWithoutRelation::new(msgtype))) } pub async fn latest_event(&self) -> Option> {