mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-15 03:25:46 -04:00
Fetch sender profile when returning latest event
This commit is contained in:
@@ -373,8 +373,8 @@ impl RoomListItem {
|
||||
self.inner.unsubscribe();
|
||||
}
|
||||
|
||||
fn latest_event(&self) -> Option<Arc<EventTimelineItem>> {
|
||||
self.inner.latest_event().map(EventTimelineItem).map(Arc::new)
|
||||
async fn latest_event(&self) -> Option<Arc<EventTimelineItem>> {
|
||||
self.inner.latest_event().await.map(EventTimelineItem).map(Arc::new)
|
||||
}
|
||||
|
||||
fn has_unread_notifications(&self) -> bool {
|
||||
|
||||
@@ -135,8 +135,8 @@ impl Room {
|
||||
///
|
||||
/// It's different from `Self::timeline().latest_event()` as it won't track
|
||||
/// the read marker and receipts.
|
||||
pub fn latest_event(&self) -> Option<EventTimelineItem> {
|
||||
self.inner.sliding_sync_room.latest_timeline_item()
|
||||
pub async fn latest_event(&self) -> Option<EventTimelineItem> {
|
||||
self.inner.sliding_sync_room.latest_timeline_item().await
|
||||
}
|
||||
|
||||
/// Is there any unread notifications?
|
||||
|
||||
@@ -83,10 +83,12 @@ impl EventTimelineItem {
|
||||
/// If the supplied low-level SyncTimelineEventy is suitable for use as the
|
||||
/// latest_event in a message preview, wrap it as an EventTimelineItem,
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
pub(crate) fn from_latest_event(
|
||||
pub(crate) async fn from_latest_event(
|
||||
room: &SlidingSyncRoom,
|
||||
sync_event: SyncTimelineEvent,
|
||||
) -> Option<EventTimelineItem> {
|
||||
use super::traits::RoomDataProvider;
|
||||
|
||||
let raw_sync_event = sync_event.event;
|
||||
|
||||
let encryption_info = sync_event.encryption_info;
|
||||
@@ -135,10 +137,15 @@ impl EventTimelineItem {
|
||||
}
|
||||
.into();
|
||||
|
||||
// If we need to sender profiles in the message previews, we will need to
|
||||
// cache the contents of a Profile struct inside RoomInfo similar to how we
|
||||
// are caching the event at the moment.
|
||||
let sender_profile = TimelineDetails::Unavailable;
|
||||
let room = room.client().get_room(room.room_id());
|
||||
let sender_profile = if let Some(room) = room {
|
||||
room.profile(&sender)
|
||||
.await
|
||||
.map(TimelineDetails::Ready)
|
||||
.unwrap_or(TimelineDetails::Unavailable)
|
||||
} else {
|
||||
TimelineDetails::Unavailable
|
||||
};
|
||||
|
||||
Some(EventTimelineItem::new(sender, sender_profile, timestamp, item_content, event_kind))
|
||||
}
|
||||
@@ -480,9 +487,9 @@ mod test {
|
||||
);
|
||||
|
||||
// When we construct a timeline event from it
|
||||
let timeline_item = EventTimelineItem::from_latest_event(&room, event).unwrap();
|
||||
let timeline_item = EventTimelineItem::from_latest_event(&room, event).await.unwrap();
|
||||
|
||||
// Then its properieis correctly translate
|
||||
// Then its properties correctly translate
|
||||
assert_eq!(timeline_item.sender, user_id);
|
||||
assert_matches!(timeline_item.sender_profile, TimelineDetails::Unavailable);
|
||||
assert_eq!(timeline_item.timestamp.0, UInt::new(122344).unwrap());
|
||||
@@ -496,6 +503,77 @@ mod test {
|
||||
}
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
#[cfg(feature = "experimental-sliding-sync")]
|
||||
async fn latest_message_event_can_be_wrapped_as_a_timeline_item_with_sender() {
|
||||
// Given a sync event that is suitable to be used as a latest_event, and a room
|
||||
// with a member event for the sender
|
||||
|
||||
use ruma::owned_mxc_uri;
|
||||
let room_id = room_id!("!q:x.uk");
|
||||
let user_id = user_id!("@t:o.uk");
|
||||
let event = message_event(room_id, user_id, "**My M**", "<b>My M</b>", 122344);
|
||||
let client = logged_in_client(None).await;
|
||||
let mut room = v4::SlidingSyncRoom::new();
|
||||
room.timeline.push(member_event(room_id, user_id, "Alice Margatroid", "mxc://e.org/SEs"));
|
||||
let ss_room =
|
||||
SlidingSyncRoom::new(client.clone(), room_id.to_owned(), room.clone(), Vec::new());
|
||||
|
||||
// And the room is stored in the client so it can be extracted when needed
|
||||
let response = response_with_room(room_id, room).await;
|
||||
client.process_sliding_sync(&response).await.unwrap();
|
||||
|
||||
// When we construct a timeline event from it
|
||||
let timeline_item = EventTimelineItem::from_latest_event(&ss_room, event).await.unwrap();
|
||||
|
||||
// Then its sender is properly populated
|
||||
let profile = assert_matches!(timeline_item.sender_profile, TimelineDetails::Ready(p) => p);
|
||||
assert_eq!(
|
||||
profile,
|
||||
Profile {
|
||||
display_name: Some("Alice Margatroid".to_owned()),
|
||||
display_name_ambiguous: false,
|
||||
avatar_url: Some(owned_mxc_uri!("mxc://e.org/SEs"))
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
fn member_event(
|
||||
room_id: &RoomId,
|
||||
user_id: &UserId,
|
||||
display_name: &str,
|
||||
avatar_url: &str,
|
||||
) -> Raw<AnySyncTimelineEvent> {
|
||||
Raw::from_json_string(
|
||||
json!({
|
||||
"type": "m.room.member",
|
||||
"content": {
|
||||
"avatar_url": avatar_url,
|
||||
"displayname": display_name,
|
||||
"membership": "join",
|
||||
"reason": ""
|
||||
},
|
||||
"event_id": "$143273582443PhrSn:example.org",
|
||||
"origin_server_ts": 143273583,
|
||||
"room_id": room_id,
|
||||
"sender": "@example:example.org",
|
||||
"state_key": user_id,
|
||||
"type": "m.room.member",
|
||||
"unsigned": {
|
||||
"age": 1234
|
||||
}
|
||||
})
|
||||
.to_string(),
|
||||
)
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
async fn response_with_room(room_id: &RoomId, room: v4::SlidingSyncRoom) -> v4::Response {
|
||||
let mut response = v4::Response::new("6".to_owned());
|
||||
response.rooms.insert(room_id.to_owned(), room);
|
||||
response
|
||||
}
|
||||
|
||||
fn message_event(
|
||||
room_id: &RoomId,
|
||||
user_id: &UserId,
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
|
||||
use async_trait::async_trait;
|
||||
use matrix_sdk::SlidingSyncRoom;
|
||||
use tracing::{error, instrument, warn};
|
||||
use tracing::{error, instrument};
|
||||
|
||||
use super::{EventTimelineItem, Timeline, TimelineBuilder};
|
||||
|
||||
@@ -27,7 +27,7 @@ pub trait SlidingSyncRoomExt {
|
||||
///
|
||||
/// Use `Timeline::latest_event` instead if you already have a timeline for
|
||||
/// this `SlidingSyncRoom`.
|
||||
fn latest_timeline_item(&self) -> Option<EventTimelineItem>;
|
||||
async fn latest_timeline_item(&self) -> Option<EventTimelineItem>;
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
@@ -40,8 +40,9 @@ impl SlidingSyncRoomExt for SlidingSyncRoom {
|
||||
/// This method wraps latest_event, converting the event into an
|
||||
/// EventTimelineItem.
|
||||
#[instrument(skip_all)]
|
||||
fn latest_timeline_item(&self) -> Option<EventTimelineItem> {
|
||||
self.latest_event().and_then(|e| EventTimelineItem::from_latest_event(self, e))
|
||||
async fn latest_timeline_item(&self) -> Option<EventTimelineItem> {
|
||||
let latest_event = self.latest_event()?;
|
||||
EventTimelineItem::from_latest_event(self, latest_event).await
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,7 +83,7 @@ mod tests {
|
||||
let room = SlidingSyncRoom::new(client, room_id, v4::SlidingSyncRoom::new(), Vec::new());
|
||||
|
||||
// When we ask for the latest event, it is None
|
||||
assert!(room.latest_timeline_item().is_none());
|
||||
assert!(room.latest_timeline_item().await.is_none());
|
||||
}
|
||||
|
||||
#[async_test]
|
||||
@@ -101,7 +102,7 @@ mod tests {
|
||||
v4::SlidingSyncRoom::new(),
|
||||
Vec::new(),
|
||||
);
|
||||
let actual = room.latest_timeline_item().unwrap();
|
||||
let actual = room.latest_timeline_item().await.unwrap();
|
||||
|
||||
// Then it is wrapped as an EventTimelineItem
|
||||
assert_eq!(actual.sender, user_id);
|
||||
|
||||
Reference in New Issue
Block a user