feat(ffi): expose Client::register_notification_handler
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
This commit is contained in:
committed by
Damir Jelić
parent
81ff96d569
commit
82c583b5bc
@@ -62,6 +62,8 @@ All notable changes to this project will be documented in this file.
|
||||
|
||||
### Features
|
||||
|
||||
- Add `Client::register_notification_handler` for observing notifications generated from sync responses.
|
||||
([#5831](https://github.com/matrix-org/matrix-rust-sdk/pull/5831))
|
||||
- Add `Room::mark_as_fully_read_unchecked` so clients can mark a room as read without needing a `Timeline` instance. Note this method is not recommended as it can potentially cause incorrect read receipts, but it can needed in certain cases.
|
||||
- Add `Timeline::latest_event_id` to be able to fetch the event id of the latest event of the timeline.
|
||||
- Add `Room::load_or_fetch_event` so we can get a `TimelineEvent` given its event id ([#5678](https://github.com/matrix-org/matrix-rust-sdk/pull/5678)).
|
||||
|
||||
@@ -16,6 +16,7 @@ use matrix_sdk::{
|
||||
authentication::oauth::{
|
||||
AccountManagementActionFull, ClientId, OAuthAuthorizationData, OAuthSession,
|
||||
},
|
||||
deserialized_responses::RawAnySyncOrStrippedTimelineEvent,
|
||||
media::{MediaFormat, MediaRequestParameters, MediaRetentionPolicy, MediaThumbnailSettings},
|
||||
ruma::{
|
||||
api::client::{
|
||||
@@ -101,7 +102,7 @@ use crate::{
|
||||
authentication::{HomeserverLoginDetails, OidcConfiguration, OidcError, SsoError, SsoHandler},
|
||||
client,
|
||||
encryption::Encryption,
|
||||
notification::NotificationClient,
|
||||
notification::{NotificationClient, NotificationEvent},
|
||||
notification_settings::NotificationSettings,
|
||||
qr_code::LoginWithQrCodeHandler,
|
||||
room::{RoomHistoryVisibility, RoomInfoListener, RoomSendQueueUpdate},
|
||||
@@ -225,6 +226,25 @@ pub trait RoomAccountDataListener: SyncOutsideWasm + SendOutsideWasm {
|
||||
fn on_change(&self, event: RoomAccountDataEvent, room_id: String);
|
||||
}
|
||||
|
||||
/// A listener for notifications generated from sync responses.
|
||||
///
|
||||
/// This is called during sync for each event that triggers a notification
|
||||
/// based on the user's push rules.
|
||||
#[matrix_sdk_ffi_macros::export(callback_interface)]
|
||||
pub trait SyncNotificationListener: SyncOutsideWasm + SendOutsideWasm {
|
||||
/// Called when a notifying event is received during sync.
|
||||
fn on_notification(&self, notification: SyncNotification, room_id: String);
|
||||
}
|
||||
|
||||
/// A notification generated from a sync response.
|
||||
#[derive(uniffi::Record)]
|
||||
pub struct SyncNotification {
|
||||
/// The push actions for this notification (notify, sound, highlight, etc.)
|
||||
pub actions: Vec<crate::notification_settings::Action>,
|
||||
/// The event that triggered the notification
|
||||
pub event: NotificationEvent,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, uniffi::Record)]
|
||||
pub struct TransmissionProgress {
|
||||
pub current: u64,
|
||||
@@ -818,6 +838,66 @@ impl Client {
|
||||
}
|
||||
}
|
||||
|
||||
/// Register a handler for notifications generated from sync responses.
|
||||
///
|
||||
/// The handler will be called during sync for each event that triggers
|
||||
/// a notification based on the user's push rules.
|
||||
///
|
||||
/// The handler receives:
|
||||
/// - The notification with push actions and event data
|
||||
/// - The room ID where the notification occurred
|
||||
///
|
||||
/// This is useful for implementing custom notification logic, such as
|
||||
/// displaying local notifications or updating notification badges.
|
||||
pub async fn register_notification_handler(&self, listener: Box<dyn SyncNotificationListener>) {
|
||||
let listener = Arc::new(listener);
|
||||
self.inner
|
||||
.register_notification_handler(move |notification, room, _client| {
|
||||
let listener = listener.clone();
|
||||
let room_id = room.room_id().to_string();
|
||||
|
||||
async move {
|
||||
// Convert SDK actions to FFI type
|
||||
let actions: Vec<crate::notification_settings::Action> = notification
|
||||
.actions
|
||||
.into_iter()
|
||||
.filter_map(|action| action.try_into().ok())
|
||||
.collect();
|
||||
|
||||
// Convert SDK event to FFI type
|
||||
let event = match notification.event {
|
||||
RawAnySyncOrStrippedTimelineEvent::Sync(raw) => match raw.deserialize() {
|
||||
Ok(deserialized) => NotificationEvent::Timeline {
|
||||
event: Arc::new(crate::event::TimelineEvent(Box::new(
|
||||
deserialized,
|
||||
))),
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::warn!("Failed to deserialize timeline event: {err}");
|
||||
return;
|
||||
}
|
||||
},
|
||||
RawAnySyncOrStrippedTimelineEvent::Stripped(raw) => {
|
||||
match raw.deserialize() {
|
||||
Ok(deserialized) => NotificationEvent::Invite {
|
||||
sender: deserialized.sender().to_string(),
|
||||
},
|
||||
Err(err) => {
|
||||
tracing::warn!(
|
||||
"Failed to deserialize stripped state event: {err}"
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
listener.on_notification(SyncNotification { actions, event }, room_id);
|
||||
}
|
||||
})
|
||||
.await;
|
||||
}
|
||||
|
||||
/// Allows generic GET requests to be made through the SDK's internal HTTP
|
||||
/// client. This is useful when the caller's native HTTP client wouldn't
|
||||
/// have the same configuration (such as certificates, proxies, etc.) This
|
||||
|
||||
Reference in New Issue
Block a user