From 27a28e55d1196afacc5baca0d0ac03c8f5fe4aae Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 2 Sep 2025 16:15:06 +0200 Subject: [PATCH] feat(ui): Add `is_own` and `profile` to `LatestEventValue::Remote`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch adds 2 fields to `LatestEventValue::Remote`: `is_own` and `profile`, which are necessary for the app consumers. --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 28 +++++++++---- .../src/timeline/latest_event.rs | 40 ++++++++++++++----- crates/matrix-sdk-ui/src/timeline/traits.rs | 7 +++- 3 files changed, 58 insertions(+), 17 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index fb3d3c2d5..7171bafa3 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -1289,19 +1289,33 @@ impl LazyTimelineItemProvider { #[derive(Clone, uniffi::Enum)] pub enum LatestEventValue { None, - Remote { timestamp: Timestamp, sender: String, content: TimelineItemContent }, - Local { timestamp: Timestamp, content: TimelineItemContent, is_sending: bool }, + Remote { + timestamp: Timestamp, + sender: String, + is_own: bool, + profile: ProfileDetails, + content: TimelineItemContent, + }, + Local { + timestamp: Timestamp, + content: TimelineItemContent, + is_sending: bool, + }, } impl From for LatestEventValue { fn from(value: UiLatestEventValue) -> Self { match value { UiLatestEventValue::None => Self::None, - UiLatestEventValue::Remote { timestamp, sender, content } => Self::Remote { - timestamp: timestamp.into(), - sender: sender.to_string(), - content: content.into(), - }, + UiLatestEventValue::Remote { timestamp, sender, is_own, profile, content } => { + Self::Remote { + timestamp: timestamp.into(), + sender: sender.to_string(), + is_own, + profile: profile.into(), + content: content.into(), + } + } UiLatestEventValue::Local { timestamp, content, is_sending } => { Self::Local { timestamp: timestamp.into(), content: content.into(), is_sending } } diff --git a/crates/matrix-sdk-ui/src/timeline/latest_event.rs b/crates/matrix-sdk-ui/src/timeline/latest_event.rs index 6607c90da..cd81a3767 100644 --- a/crates/matrix-sdk-ui/src/timeline/latest_event.rs +++ b/crates/matrix-sdk-ui/src/timeline/latest_event.rs @@ -12,11 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -use matrix_sdk::{Room, latest_events::LocalLatestEventValue}; +use matrix_sdk::{Client, Room, latest_events::LocalLatestEventValue}; use matrix_sdk_base::latest_event::LatestEventValue as BaseLatestEventValue; use ruma::{MilliSecondsSinceUnixEpoch, OwnedUserId}; -use crate::timeline::{TimelineItemContent, event_handler::TimelineAction}; +use crate::timeline::{ + Profile, TimelineDetails, TimelineItemContent, event_handler::TimelineAction, + traits::RoomDataProvider, +}; /// A simplified version of [`matrix_sdk_base::latest_event::LatestEventValue`] /// tailored for this `timeline` module. @@ -33,6 +36,12 @@ pub enum LatestEventValue { /// The sender of the remote event. sender: OwnedUserId, + /// Has this event been sent by the current logged user? + is_own: bool, + + /// The sender's profile. + profile: TimelineDetails, + /// The content of the remote event. content: TimelineItemContent, }, @@ -57,6 +66,7 @@ impl LatestEventValue { pub(crate) async fn from_base_latest_event_value( value: BaseLatestEventValue, room: &Room, + client: &Client, ) -> Self { match value { BaseLatestEventValue::None => Self::None, @@ -68,6 +78,12 @@ impl LatestEventValue { let timestamp = any_sync_timeline_event.origin_server_ts(); let sender = any_sync_timeline_event.sender().to_owned(); + let is_own = client.user_id().map(|user_id| user_id == sender).unwrap_or(false); + let profile = room + .profile_from_user_id(&sender) + .await + .map(TimelineDetails::Ready) + .unwrap_or(TimelineDetails::Unavailable); let Some(TimelineAction::AddItem { content }) = TimelineAction::from_event( any_sync_timeline_event, @@ -83,7 +99,7 @@ impl LatestEventValue { return Self::None; }; - Self::Remote { timestamp, sender, content } + Self::Remote { timestamp, sender, is_own, profile, content } } BaseLatestEventValue::LocalIsSending(LocalLatestEventValue { timestamp, @@ -133,7 +149,7 @@ mod tests { use super::{ super::{MsgLikeContent, MsgLikeKind, TimelineItemContent}, - BaseLatestEventValue, LatestEventValue, + BaseLatestEventValue, LatestEventValue, TimelineDetails, }; #[async_test] @@ -143,7 +159,8 @@ mod tests { let room = server.sync_room(&client, JoinedRoomBuilder::new(room_id!("!r0"))).await; let base_value = BaseLatestEventValue::None; - let value = LatestEventValue::from_base_latest_event_value(base_value, &room).await; + let value = + LatestEventValue::from_base_latest_event_value(base_value, &room, &client).await; assert_matches!(value, LatestEventValue::None); } @@ -169,11 +186,14 @@ mod tests { ) .unwrap(), )); - let value = LatestEventValue::from_base_latest_event_value(base_value, &room).await; + let value = + LatestEventValue::from_base_latest_event_value(base_value, &room, &client).await; - assert_matches!(value, LatestEventValue::Remote { timestamp, sender: received_sender, content } => { + assert_matches!(value, LatestEventValue::Remote { timestamp, sender: received_sender, is_own, profile, content } => { assert_eq!(u64::from(timestamp.get()), 42u64); assert_eq!(received_sender, sender); + assert!(is_own.not()); + assert_matches!(profile, TimelineDetails::Unavailable); assert_matches!( content, TimelineItemContent::MsgLike(MsgLikeContent { kind: MsgLikeKind::Message(_), .. }) @@ -197,7 +217,8 @@ mod tests { "m.room.message".to_owned(), ), }); - let value = LatestEventValue::from_base_latest_event_value(base_value, &room).await; + let value = + LatestEventValue::from_base_latest_event_value(base_value, &room, &client).await; assert_matches!(value, LatestEventValue::Local { timestamp, content, is_sending } => { assert_eq!(u64::from(timestamp.get()), 42u64); @@ -225,7 +246,8 @@ mod tests { "m.room.message".to_owned(), ), }); - let value = LatestEventValue::from_base_latest_event_value(base_value, &room).await; + let value = + LatestEventValue::from_base_latest_event_value(base_value, &room, &client).await; assert_matches!(value, LatestEventValue::Local { timestamp, content, is_sending } => { assert_eq!(u64::from(timestamp.get()), 42u64); diff --git a/crates/matrix-sdk-ui/src/timeline/traits.rs b/crates/matrix-sdk-ui/src/timeline/traits.rs index 95d63f81d..b4211c974 100644 --- a/crates/matrix-sdk-ui/src/timeline/traits.rs +++ b/crates/matrix-sdk-ui/src/timeline/traits.rs @@ -91,7 +91,12 @@ impl RoomExt for Room { } async fn new_latest_event(&self) -> LatestEventValue { - LatestEventValue::from_base_latest_event_value((**self).new_latest_event(), self).await + LatestEventValue::from_base_latest_event_value( + (**self).new_latest_event(), + self, + &self.client(), + ) + .await } }