diff --git a/crates/ruma-client-api/src/sync/sync_events.rs b/crates/ruma-client-api/src/sync/sync_events.rs index 3c89ab7d..8eef4a61 100644 --- a/crates/ruma-client-api/src/sync/sync_events.rs +++ b/crates/ruma-client-api/src/sync/sync_events.rs @@ -11,10 +11,10 @@ pub mod v3; #[cfg(feature = "unstable-msc3575")] pub mod v4; -/// Unread notifications count. +/// Unread notifications count in threads. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] -pub struct UnreadNotificationsCount { +pub struct UnreadCountThread { /// The last acked/read event or message #[serde(skip_serializing_if = "Option::is_none")] pub last_ack: Option, @@ -38,8 +38,37 @@ pub struct UnreadNotificationsCount { pub messages: Option, } -impl UnreadNotificationsCount { - /// Creates an empty `UnreadNotificationsCount`. +/// Unread notifications count in rooms. +#[derive(Clone, Debug, Default, Deserialize, Serialize)] +#[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] +pub struct UnreadCountRoom { + /// The sum of all threaded `mention_user`s + #[serde(skip_serializing_if = "Option::is_none")] + pub mention_user: Option, + + /// The sum of all threaded `mention_bulk`s + #[serde(skip_serializing_if = "Option::is_none")] + pub mention_bulk: Option, + + /// The sum of all threaded `notify`s + #[serde(skip_serializing_if = "Option::is_none")] + pub notify: Option, + + /// The sum of all threaded `message`s + #[serde(skip_serializing_if = "Option::is_none")] + pub messages: Option, + + /// The total number of threads that don't have an `last_ack` yet + #[serde(skip_serializing_if = "Option::is_none")] + pub threads_unseen: Option, + + /// The total number of unread threads where `messages > 0` / `last_ack` is no longer the latest message + #[serde(skip_serializing_if = "Option::is_none")] + pub threads_unread: Option, +} + +impl UnreadCountThread { + /// Creates an empty `UnreadCountThread`. pub fn new() -> Self { Default::default() } @@ -54,6 +83,23 @@ impl UnreadNotificationsCount { } } +impl UnreadCountRoom { + /// Creates an empty `UnreadCountRoom`. + pub fn new() -> Self { + Default::default() + } + + /// Returns true if there are no notification count updates. + pub fn is_empty(&self) -> bool { + self.mention_user.is_none() + && self.mention_bulk.is_none() + && self.notify.is_none() + && self.messages.is_none() + && self.threads_unseen.is_none() + && self.threads_unread.is_none() + } +} + /// Information on E2E device updates. #[derive(Clone, Debug, Default, Deserialize, Serialize)] #[cfg_attr(not(feature = "unstable-exhaustive-types"), non_exhaustive)] diff --git a/crates/ruma-client-api/src/sync/sync_events/v3.rs b/crates/ruma-client-api/src/sync/sync_events/v3.rs index f94db6c7..e221ee05 100644 --- a/crates/ruma-client-api/src/sync/sync_events/v3.rs +++ b/crates/ruma-client-api/src/sync/sync_events/v3.rs @@ -19,7 +19,7 @@ use ruma_events::{ }; use serde::{Deserialize, Serialize}; -use super::{DeviceLists, UnreadNotificationsCount}; +use super::{DeviceLists, UnreadCountRoom}; use crate::filter::FilterDefinition; const METADATA: Metadata = metadata! { @@ -250,8 +250,8 @@ pub struct JoinedRoom { /// /// [unread notifications]: https://spec.matrix.org/latest/client-server-api/#receiving-notifications /// [`RoomEventFilter`]: crate::filter::RoomEventFilter - #[serde(default, skip_serializing_if = "UnreadNotificationsCount::is_empty")] - pub unread_notifications: UnreadNotificationsCount, + #[serde(default, skip_serializing_if = "UnreadCountRoom::is_empty")] + pub unread_notifications: UnreadCountRoom, /// Counts of [unread notifications] for threads in this room. /// @@ -262,7 +262,7 @@ pub struct JoinedRoom { /// [unread notifications]: https://spec.matrix.org/latest/client-server-api/#receiving-notifications /// [`RoomEventFilter`]: crate::filter::RoomEventFilter #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub unread_thread_notifications: BTreeMap, + pub unread_thread_notifications: BTreeMap, /// The timeline of messages and state changes in the room. #[serde(default, skip_serializing_if = "Timeline::is_empty")] diff --git a/crates/ruma-client-api/src/sync/sync_events/v4.rs b/crates/ruma-client-api/src/sync/sync_events/v4.rs index 2fb90c72..d36d5539 100644 --- a/crates/ruma-client-api/src/sync/sync_events/v4.rs +++ b/crates/ruma-client-api/src/sync/sync_events/v4.rs @@ -21,7 +21,7 @@ use ruma_events::{ }; use serde::{de::Error as _, Deserialize, Serialize}; -use super::{DeviceLists, UnreadNotificationsCount}; +use super::{DeviceLists, UnreadCountRoom, UnreadCountThread}; const METADATA: Metadata = metadata! { method: POST, @@ -424,8 +424,8 @@ pub struct SlidingSyncRoom { pub invite_state: Option>>, /// Counts of unread notifications for this room. - #[serde(default, skip_serializing_if = "UnreadNotificationsCount::is_empty")] - pub unreads: UnreadNotificationsCount, + #[serde(default, skip_serializing_if = "UnreadCountRoom::is_empty")] + pub unreads: UnreadCountRoom, /// Counts of unread notifications for threads in this room. /// @@ -433,7 +433,7 @@ pub struct SlidingSyncRoom { /// /// Only set if `unread_thread_notifications` was set to `true` in the [`RoomEventFilter`]. #[serde(default, skip_serializing_if = "BTreeMap::is_empty")] - pub unreads_threaded: BTreeMap, + pub unreads_threaded: BTreeMap, /// The timeline of messages and state changes in the room. #[serde(default, skip_serializing_if = "Vec::is_empty")]