mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-06-21 22:58:32 -04:00
sdk-base: add pinned events to BaseRoomInfo to keep track of them.
Also add `Room::pinned_events(&self)` to get the current pinned events at any time.
This commit is contained in:
committed by
Jorge Martin Espinosa
parent
99da0ff18d
commit
79010af9e2
@@ -30,6 +30,7 @@ use ruma::{
|
||||
join_rules::RoomJoinRulesEventContent,
|
||||
member::MembershipState,
|
||||
name::RoomNameEventContent,
|
||||
pinned_events::RoomPinnedEventsEventContent,
|
||||
tombstone::RoomTombstoneEventContent,
|
||||
topic::RoomTopicEventContent,
|
||||
},
|
||||
@@ -117,6 +118,8 @@ pub struct BaseRoomInfo {
|
||||
/// others, and this field collects them.
|
||||
#[serde(skip_serializing_if = "RoomNotableTags::is_empty", default)]
|
||||
pub(crate) notable_tags: RoomNotableTags,
|
||||
/// The `m.room.pinned_events` of this room.
|
||||
pub(crate) pinned_events: Option<RoomPinnedEventsEventContent>,
|
||||
}
|
||||
|
||||
impl BaseRoomInfo {
|
||||
@@ -194,6 +197,9 @@ impl BaseRoomInfo {
|
||||
ev.as_original().is_some_and(|o| !o.content.active_memberships(None).is_empty())
|
||||
});
|
||||
}
|
||||
AnySyncStateEvent::RoomPinnedEvents(p) => {
|
||||
self.pinned_events = p.as_original().map(|p| p.content.clone());
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
@@ -253,6 +259,11 @@ impl BaseRoomInfo {
|
||||
// wont have call information.
|
||||
return false;
|
||||
}
|
||||
AnyStrippedStateEvent::RoomPinnedEvents(p) => {
|
||||
if let Some(pinned) = p.content.pinned.clone() {
|
||||
self.pinned_events = Some(RoomPinnedEventsEventContent::new(pinned));
|
||||
}
|
||||
}
|
||||
_ => return false,
|
||||
}
|
||||
|
||||
@@ -349,6 +360,7 @@ impl Default for BaseRoomInfo {
|
||||
rtc_member: BTreeMap::new(),
|
||||
is_marked_unread: false,
|
||||
notable_tags: RoomNotableTags::empty(),
|
||||
pinned_events: None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -947,6 +947,11 @@ impl Room {
|
||||
pub fn recency_stamp(&self) -> Option<u64> {
|
||||
self.inner.read().recency_stamp
|
||||
}
|
||||
|
||||
/// Get the list of event ids for pinned events in this room.
|
||||
pub fn pinned_events(&self) -> Vec<OwnedEventId> {
|
||||
self.inner.get().base_info.pinned_events.map(|content| content.pinned).unwrap_or_default()
|
||||
}
|
||||
}
|
||||
|
||||
/// The underlying pure data structure for joined and left rooms.
|
||||
@@ -1615,10 +1620,11 @@ mod tests {
|
||||
SyncRoomMemberEvent,
|
||||
},
|
||||
name::RoomNameEventContent,
|
||||
pinned_events::RoomPinnedEventsEventContent,
|
||||
},
|
||||
AnySyncStateEvent, EmptyStateKey, StateEventType, StateUnsigned, SyncStateEvent,
|
||||
},
|
||||
room_alias_id, room_id,
|
||||
owned_event_id, room_alias_id, room_id,
|
||||
serde::Raw,
|
||||
user_id, EventEncryptionAlgorithm, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId,
|
||||
UserId,
|
||||
@@ -1671,7 +1677,9 @@ mod tests {
|
||||
latest_event: Some(Box::new(LatestEvent::new(
|
||||
Raw::from_json_string(json!({"sender": "@u:i.uk"}).to_string()).unwrap().into(),
|
||||
))),
|
||||
base_info: Box::new(BaseRoomInfo::new()),
|
||||
base_info: Box::new(
|
||||
assign!(BaseRoomInfo::new(), { pinned_events: Some(RoomPinnedEventsEventContent::new(vec![owned_event_id!("$a")])) }),
|
||||
),
|
||||
read_receipts: Default::default(),
|
||||
warned_about_unknown_room_version: Arc::new(false.into()),
|
||||
cached_display_name: None,
|
||||
@@ -1720,6 +1728,9 @@ mod tests {
|
||||
"name": null,
|
||||
"tombstone": null,
|
||||
"topic": null,
|
||||
"pinned_events": {
|
||||
"pinned": ["$a"]
|
||||
},
|
||||
},
|
||||
"read_receipts": {
|
||||
"num_unread": 0,
|
||||
|
||||
@@ -860,11 +860,12 @@ mod tests {
|
||||
member::{MembershipState, RoomMemberEventContent},
|
||||
message::SyncRoomMessageEvent,
|
||||
name::RoomNameEventContent,
|
||||
pinned_events::RoomPinnedEventsEventContent,
|
||||
},
|
||||
AnySyncMessageLikeEvent, AnySyncTimelineEvent, GlobalAccountDataEventContent,
|
||||
StateEventContent,
|
||||
},
|
||||
mxc_uri, owned_mxc_uri, owned_user_id, room_alias_id, room_id,
|
||||
mxc_uri, owned_event_id, owned_mxc_uri, owned_user_id, room_alias_id, room_id,
|
||||
serde::Raw,
|
||||
uint, user_id, JsOption, MxcUri, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, UserId,
|
||||
};
|
||||
@@ -2178,6 +2179,53 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
async fn test_pinned_events_are_updated_on_sync() {
|
||||
let user_a_id = user_id!("@a:e.uk");
|
||||
let client = logged_in_base_client(Some(user_a_id)).await;
|
||||
let room_id = room_id!("!r:e.uk");
|
||||
let pinned_event_id = owned_event_id!("$an-id:e.uk");
|
||||
|
||||
// Create room
|
||||
let mut room_response = http::response::Room::new();
|
||||
set_room_joined(&mut room_response, user_a_id);
|
||||
let response = response_with_room(room_id, room_response);
|
||||
client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync");
|
||||
|
||||
// The newly created room has no pinned event ids
|
||||
let room = client.get_room(room_id).unwrap();
|
||||
let pinned_event_ids = room.pinned_events();
|
||||
assert!(pinned_event_ids.is_empty());
|
||||
|
||||
// Load new pinned event id
|
||||
let mut room_response = http::response::Room::new();
|
||||
room_response.required_state.push(make_state_event(
|
||||
user_a_id,
|
||||
"",
|
||||
RoomPinnedEventsEventContent::new(vec![pinned_event_id.clone()]),
|
||||
None,
|
||||
));
|
||||
let response = response_with_room(room_id, room_response);
|
||||
client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync");
|
||||
|
||||
let pinned_event_ids = room.pinned_events();
|
||||
assert_eq!(pinned_event_ids.len(), 1);
|
||||
assert_eq!(pinned_event_ids[0], pinned_event_id);
|
||||
|
||||
// Pinned event ids are now empty
|
||||
let mut room_response = http::response::Room::new();
|
||||
room_response.required_state.push(make_state_event(
|
||||
user_a_id,
|
||||
"",
|
||||
RoomPinnedEventsEventContent::new(Vec::new()),
|
||||
None,
|
||||
));
|
||||
let response = response_with_room(room_id, room_response);
|
||||
client.process_sliding_sync(&response, &(), true).await.expect("Failed to process sync");
|
||||
let pinned_event_ids = room.pinned_events();
|
||||
assert!(pinned_event_ids.is_empty());
|
||||
}
|
||||
|
||||
async fn choose_event_to_cache(events: &[SyncTimelineEvent]) -> Option<SyncTimelineEvent> {
|
||||
let room = make_room();
|
||||
let mut room_info = room.clone_info();
|
||||
|
||||
@@ -213,6 +213,7 @@ impl BaseRoomInfoV1 {
|
||||
rtc_member: BTreeMap::new(),
|
||||
is_marked_unread: false,
|
||||
notable_tags: RoomNotableTags::empty(),
|
||||
pinned_events: None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user