ffi: replace some block_on asyncs by async() functions

This commit is contained in:
Benjamin Bouvier
2024-04-30 19:30:32 +02:00
parent d02125ba21
commit ff40ef0176
7 changed files with 239 additions and 318 deletions

View File

@@ -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))
}

View File

@@ -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<String>,
session_delegate: Option<Arc<dyn ClientSessionDelegate>>,
@@ -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<AuthSession>,
) -> 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<Session, ClientError> {
RUNTIME.block_on(async move { Self::session_inner((*self.inner).clone()).await })
pub async fn session(&self) -> Result<Session, ClientError> {
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<String, ClientError> {
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<String, ClientError> {
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<u8>) -> 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<u8>) -> 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, ClientError> {
let url = self.inner.account().get_cached_avatar_url().await?;
Ok(url)
}
pub fn device_id(&self) -> Result<String, ClientError> {
@@ -450,35 +429,31 @@ impl Client {
Ok(device_id.to_string())
}
pub fn create_room(&self, request: CreateRoomParameters) -> Result<String, ClientError> {
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<String, ClientError> {
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<Option<String>, 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<Option<String>, 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<Arc<SessionVerificationController>, 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<Option<String>, ClientError> {
pub async fn logout(&self) -> Result<Option<String>, 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<SearchUsersResults, ClientError> {
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 async fn get_profile(&self, user_id: String) -> Result<UserProfile, ClientError> {
let owned_user_id = UserId::parse(user_id.clone())?;
let response = self.inner.account().fetch_user_profile_of(&owned_user_id).await?;
Ok(UserProfile {
user_id,
display_name: response.displayname.clone(),
avatar_url: response.avatar_url.as_ref().map(|url| url.to_string()),
})
}
pub fn get_profile(&self, user_id: String) -> Result<UserProfile, ClientError> {
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?;
let user_profile = UserProfile {
user_id,
display_name: response.displayname.clone(),
avatar_url: response.avatar_url.as_ref().map(|url| url.to_string()),
};
Ok(user_profile)
})
}
pub fn notification_client(
pub async fn notification_client(
self: Arc<Self>,
process_setup: NotificationProcessSetup,
) -> Result<Arc<NotificationClientBuilder>, ClientError> {
NotificationClientBuilder::new(self.clone(), process_setup.into())
NotificationClientBuilder::new(self.clone(), process_setup.into()).await
}
pub fn sync_service(&self) -> Arc<SyncServiceBuilder> {
SyncServiceBuilder::new((*self.inner).clone())
}
pub fn get_notification_settings(&self) -> Arc<NotificationSettings> {
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<NotificationSettings> {
Arc::new(NotificationSettings::new(
(*self.inner).clone(),
self.inner.notification_settings().await,
))
}
pub fn encryption(&self) -> Arc<Encryption> {

View File

@@ -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?)
}
}

View File

@@ -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<Client>,
process_setup: NotificationProcessSetup,
) -> Result<Arc<Self>, 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<Client>,
}
#[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<Option<NotificationItem>, 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)
}
}
}

View File

@@ -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<String, ClientError> {
let r = self.inner.clone();
RUNTIME.block_on(async move { Ok(r.display_name().await?.to_string()) })
pub async fn display_name(&self) -> Result<String, ClientError> {
Ok(self.inner.display_name().await?.to_string())
}
pub fn is_encrypted(&self) -> Result<bool, ClientError> {
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<bool, ClientError> {
Ok(self.inner.is_encrypted().await?)
}
pub async fn members(&self) -> Result<Arc<RoomMembersIterator>, ClientError> {
@@ -235,28 +230,25 @@ impl Room {
pub async fn member(&self, user_id: String) -> Result<RoomMember, ClientError> {
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<Option<String>, 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<Option<String>, 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<Option<String>, 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<Option<String>, 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<RoomInfo, ClientError> {
@@ -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<String>) -> 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<String>,
) -> 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<i32>,
reason: Option<String>,
) -> 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<u8>,
media_info: Option<ImageInfo>,
) -> 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 async fn remove_avatar(&self) -> Result<(), ClientError> {
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 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<bool, ClientError> {

View File

@@ -125,11 +125,11 @@ impl RoomListService {
})))
}
fn room(&self, room_id: String) -> Result<Arc<RoomListItem>, RoomListError> {
async fn room(&self, room_id: String) -> Result<Arc<RoomListItem>, 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<matrix_sdk_ui::room_list_service::RoomList>,
}
#[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<Arc<RoomListItem>, RoomListError> {
self.room_list_service.room(room_id)
async fn room(&self, room_id: String) -> Result<Arc<RoomListItem>, RoomListError> {
self.room_list_service.room(room_id).await
}
}
@@ -490,16 +490,16 @@ impl RoomListItem {
self.inner.id().to_string()
}
fn name(&self) -> Option<String> {
RUNTIME.block_on(async { self.inner.name().await })
async fn name(&self) -> Option<String> {
self.inner.name().await
}
fn avatar_url(&self) -> Option<String> {
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<String> {

View File

@@ -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<RoomMessageEventContentWithoutRelation>,
reply_item: Arc<EventTimelineItem>,
) -> 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<RoomMessageEventContentWithoutRelation>,
edit_item: Arc<EventTimelineItem>,
) -> 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<EventTimelineItem>,
) -> 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<Self>, 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<Arc<EventTimelineItem>, 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<Arc<RoomMessageEventContentWithoutRelation>, 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();
let item = self
.inner
.item_by_event_id(&event_id)
.await
.context("Item with given event ID not found")?;
Ok(Arc::new(RoomMessageEventContentWithoutRelation::new(msgtype)))
})
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<Arc<EventTimelineItem>> {