sdk: Allow to receive ambiguity changes per-room.

Signed-off-by: Kévin Commaille <zecakeh@tedomum.fr>
This commit is contained in:
Kévin Commaille
2024-01-27 16:19:16 +01:00
parent bcf1ee408b
commit f0d722099f
3 changed files with 111 additions and 10 deletions
+2
View File
@@ -5,6 +5,8 @@ Breaking changes:
- Replace the `Notification` type from Ruma in `SyncResponse` and `Client::register_notification_handler`
by a custom one
- `Room::can_user_redact` and `Member::can_redact` are split between `*_redact_own` and `*_redact_other`
- `RoomUpdate` also contains the ambiguity changes of a `Room` with `AmbiguityCache` containing the
room member's user ID.
# 0.7.0
+47 -10
View File
@@ -23,7 +23,7 @@ use std::{
pub use matrix_sdk_base::sync::*;
use matrix_sdk_base::{
debug::{DebugInvitedRoom, DebugListOfRawEventsNoId},
deserialized_responses::AmbiguityChanges,
deserialized_responses::{AmbiguityChange, AmbiguityChanges},
instant::Instant,
sync::SyncResponse as BaseSyncResponse,
};
@@ -31,7 +31,7 @@ use ruma::{
api::client::sync::sync_events::{self, v3::InvitedRoom},
events::{presence::PresenceEvent, AnyGlobalAccountDataEvent, AnyToDeviceEvent},
serde::Raw,
OwnedRoomId, RoomId,
OwnedEventId, OwnedRoomId, RoomId,
};
use tracing::{debug, error, warn};
@@ -103,6 +103,11 @@ pub enum RoomUpdate {
room: Room,
/// Updates to the room.
updates: LeftRoom,
/// Collection of ambiguity changes that room member events trigger.
///
/// This is a map of event ID of the `m.room.member` event to the
/// details of the ambiguity change.
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
},
/// Updates to a room the user is currently in.
Joined {
@@ -110,6 +115,11 @@ pub enum RoomUpdate {
room: Room,
/// Updates to the room.
updates: JoinedRoom,
/// Collection of ambiguity changes that room member events trigger.
///
/// This is a map of event ID of the `m.room.member` event to the
/// details of the ambiguity change.
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
},
/// Updates to a room the user is invited to.
Invited {
@@ -117,6 +127,11 @@ pub enum RoomUpdate {
room: Room,
/// Updates to the room.
updates: InvitedRoom,
/// Collection of ambiguity changes that room member events trigger.
///
/// This is a map of event ID of the `m.room.member` event to the
/// details of the ambiguity change.
ambiguity_changes: BTreeMap<OwnedEventId, AmbiguityChange>,
},
}
@@ -124,16 +139,23 @@ pub enum RoomUpdate {
impl fmt::Debug for RoomUpdate {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::Left { room, updates } => {
f.debug_struct("Left").field("room", room).field("updates", updates).finish()
}
Self::Joined { room, updates } => {
f.debug_struct("Joined").field("room", room).field("updates", updates).finish()
}
Self::Invited { room, updates } => f
Self::Left { room, updates, ambiguity_changes } => f
.debug_struct("Left")
.field("room", room)
.field("updates", updates)
.field("ambiguity_changes", ambiguity_changes)
.finish(),
Self::Joined { room, updates, ambiguity_changes } => f
.debug_struct("Joined")
.field("room", room)
.field("updates", updates)
.field("ambiguity_changes", ambiguity_changes)
.finish(),
Self::Invited { room, updates, ambiguity_changes } => f
.debug_struct("Invited")
.field("room", room)
.field("updates", &DebugInvitedRoom(updates))
.field("ambiguity_changes", ambiguity_changes)
.finish(),
}
}
@@ -169,7 +191,7 @@ impl Client {
presence,
account_data,
to_device,
ambiguity_changes: _,
ambiguity_changes,
notifications,
} = response;
@@ -187,6 +209,11 @@ impl Client {
self.send_room_update(room_id, || RoomUpdate::Joined {
room: room.clone(),
updates: room_info.clone(),
ambiguity_changes: ambiguity_changes
.changes
.get(room_id)
.cloned()
.unwrap_or_default(),
});
let JoinedRoom { unread_notifications: _, timeline, state, account_data, ephemeral } =
@@ -210,6 +237,11 @@ impl Client {
self.send_room_update(room_id, || RoomUpdate::Left {
room: room.clone(),
updates: room_info.clone(),
ambiguity_changes: ambiguity_changes
.changes
.get(room_id)
.cloned()
.unwrap_or_default(),
});
let LeftRoom { timeline, state, account_data } = room_info;
@@ -229,6 +261,11 @@ impl Client {
self.send_room_update(room_id, || RoomUpdate::Invited {
room: room.clone(),
updates: room_info.clone(),
ambiguity_changes: ambiguity_changes
.changes
.get(room_id)
.cloned()
.unwrap_or_default(),
});
let invite_state = &room_info.invite_state.events;
@@ -34,6 +34,8 @@ use ruma::{
uint, user_id, OwnedUserId,
};
use serde_json::{json, Value as JsonValue};
use stream_assert::{assert_next_matches, assert_pending};
use tokio_stream::wrappers::BroadcastStream;
use wiremock::{
matchers::{header, method, path, path_regex},
Mock, Request, ResponseTemplate,
@@ -911,6 +913,9 @@ async fn ambiguity_changes() {
let example_2_id = user_id!("@example2:localhost");
let example_3_id = user_id!("@example3:localhost");
let mut updates = BroadcastStream::new(client.subscribe_to_room_updates(&DEFAULT_TEST_ROOM_ID));
assert_pending!(updates);
// Initial sync, adds 2 members.
mock_sync(&server, &*test_json::SYNC, None).await;
let response = client.sync_once(SyncSettings::default()).await.unwrap();
@@ -938,6 +943,20 @@ async fn ambiguity_changes() {
let example_2 = room.get_member_no_sync(example_2_id).await.unwrap().unwrap();
assert!(!example_2.name_ambiguous());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
let example_change = changes.get(event_id!("$151800140517rfvjc:localhost")).unwrap();
assert_eq!(example_change.member_id, example_id);
assert!(!example_change.member_ambiguous);
assert_eq!(example_change.ambiguated_member, None);
assert_eq!(example_change.disambiguated_member, None);
let example_2_change = changes.get(event_id!("$152034824468gOeNB:localhost")).unwrap();
assert_eq!(example_2_change.member_id, example_2_id);
assert!(!example_2_change.member_ambiguous);
assert_eq!(example_2_change.ambiguated_member, None);
assert_eq!(example_2_change.disambiguated_member, None);
// Add 1 member and set all 3 to the same display name.
let example_2_rename_1_event_id = event_id!("$example_2_rename_1");
let example_3_join_event_id = event_id!("$example_3_join");
@@ -998,6 +1017,20 @@ async fn ambiguity_changes() {
let example_3 = room.get_member_no_sync(example_3_id).await.unwrap().unwrap();
assert!(example_3.name_ambiguous());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
let example_2_change = changes.get(example_2_rename_1_event_id).unwrap();
assert_eq!(example_2_change.member_id, example_2_id);
assert!(example_2_change.member_ambiguous);
assert_eq!(example_2_change.ambiguated_member.as_deref(), Some(example_id));
assert_eq!(example_2_change.disambiguated_member, None);
let example_3_change = changes.get(example_3_join_event_id).unwrap();
assert_eq!(example_3_change.member_id, example_3_id);
assert!(example_3_change.member_ambiguous);
assert_eq!(example_3_change.ambiguated_member, None);
assert_eq!(example_3_change.disambiguated_member, None);
// Rename example 2 to a unique name.
let example_2_rename_2_event_id = event_id!("$example_2_rename_2");
@@ -1036,6 +1069,14 @@ async fn ambiguity_changes() {
let example_3 = room.get_member_no_sync(example_3_id).await.unwrap().unwrap();
assert!(example_3.name_ambiguous());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
let example_2_change = changes.get(example_2_rename_2_event_id).unwrap();
assert_eq!(example_2_change.member_id, example_2_id);
assert!(!example_2_change.member_ambiguous);
assert_eq!(example_2_change.ambiguated_member, None);
assert_eq!(example_2_change.disambiguated_member, None);
// Rename example 3, using the same name as example 2.
let example_3_rename_event_id = event_id!("$example_3_rename");
@@ -1074,6 +1115,14 @@ async fn ambiguity_changes() {
let example_3 = room.get_member_no_sync(example_3_id).await.unwrap().unwrap();
assert!(example_3.name_ambiguous());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
let example_3_change = changes.get(example_3_rename_event_id).unwrap();
assert_eq!(example_3_change.member_id, example_3_id);
assert!(example_3_change.member_ambiguous);
assert_eq!(example_3_change.ambiguated_member.as_deref(), Some(example_2_id));
assert_eq!(example_3_change.disambiguated_member.as_deref(), Some(example_id));
// Rename example, still using a unique name.
let example_rename_event_id = event_id!("$example_rename");
@@ -1112,6 +1161,14 @@ async fn ambiguity_changes() {
let example_3 = room.get_member_no_sync(example_3_id).await.unwrap().unwrap();
assert!(example_3.name_ambiguous());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
let example_change = changes.get(example_rename_event_id).unwrap();
assert_eq!(example_change.member_id, example_id);
assert!(!example_change.member_ambiguous);
assert_eq!(example_change.ambiguated_member, None);
assert_eq!(example_change.disambiguated_member, None);
// Change avatar.
let example_avatar_event_id = event_id!("$example_avatar");
@@ -1136,4 +1193,9 @@ async fn ambiguity_changes() {
// Avatar change does not trigger ambiguity change.
assert!(response.ambiguity_changes.changes.get(*DEFAULT_TEST_ROOM_ID).is_none());
let changes = assert_next_matches!(updates, Ok(RoomUpdate::Joined { ambiguity_changes, .. }) => ambiguity_changes);
assert!(changes.is_empty());
assert_pending!(updates);
}