matrix_sdk_ui/timeline/event_item/content/
reply.rs1use std::sync::Arc;
16
17use imbl::Vector;
18use matrix_sdk::deserialized_responses::TimelineEvent;
19use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId};
20use tracing::{debug, instrument, warn};
21
22use super::TimelineItemContent;
23use crate::timeline::{
24 controller::TimelineMetadata,
25 event_handler::TimelineAction,
26 event_item::{EventTimelineItem, Profile, TimelineDetails},
27 traits::RoomDataProvider,
28 Error as TimelineError, TimelineEventItemId, TimelineItem,
29};
30
31#[derive(Clone, Debug)]
33pub struct InReplyToDetails {
34 pub event_id: OwnedEventId,
36
37 pub event: TimelineDetails<Box<EmbeddedEvent>>,
44}
45
46impl InReplyToDetails {
47 pub fn new(
48 event_id: OwnedEventId,
49 timeline_items: &Vector<Arc<TimelineItem>>,
50 ) -> InReplyToDetails {
51 let event = timeline_items
52 .iter()
53 .filter_map(|it| it.as_event())
54 .find(|it| it.event_id() == Some(&*event_id))
55 .map(|item| Box::new(EmbeddedEvent::from_timeline_item(item)));
56
57 InReplyToDetails { event_id, event: TimelineDetails::from_initial_value(event) }
58 }
59}
60
61#[derive(Clone, Debug)]
64pub struct EmbeddedEvent {
65 pub content: TimelineItemContent,
67 pub sender: OwnedUserId,
69 pub sender_profile: TimelineDetails<Profile>,
71 pub timestamp: MilliSecondsSinceUnixEpoch,
73 pub identifier: TimelineEventItemId,
78}
79
80impl EmbeddedEvent {
81 pub fn from_timeline_item(timeline_item: &EventTimelineItem) -> Self {
83 Self {
84 content: timeline_item.content.clone(),
85 sender: timeline_item.sender.clone(),
86 sender_profile: timeline_item.sender_profile.clone(),
87 timestamp: timeline_item.timestamp,
88 identifier: timeline_item.identifier(),
89 }
90 }
91
92 #[instrument(skip_all)]
93 pub(in crate::timeline) async fn try_from_timeline_event<P: RoomDataProvider>(
94 timeline_event: TimelineEvent,
95 room_data_provider: &P,
96 meta: &TimelineMetadata,
97 ) -> Result<Option<Self>, TimelineError> {
98 let (raw_event, unable_to_decrypt_info) = match timeline_event.kind {
99 matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt {
100 utd_info,
101 event,
102 } => (event, Some(utd_info)),
103 _ => (timeline_event.kind.into_raw(), None),
104 };
105
106 let event = match raw_event.deserialize() {
107 Ok(event) => event,
108 Err(err) => {
109 warn!("can't get details, event couldn't be deserialized: {err}");
110 return Err(TimelineError::UnsupportedEvent);
111 }
112 };
113
114 debug!(event_type = %event.event_type(), "got deserialized event");
115
116 let in_reply_to = None;
119 let thread_root = None;
120 let thread_summary = None;
121
122 let sender = event.sender().to_owned();
123 let timestamp = event.origin_server_ts();
124 let identifier = TimelineEventItemId::EventId(event.event_id().to_owned());
125 let action = TimelineAction::from_event(
126 event,
127 &raw_event,
128 room_data_provider,
129 unable_to_decrypt_info,
130 meta,
131 in_reply_to,
132 thread_root,
133 thread_summary,
134 )
135 .await;
136
137 let Some(TimelineAction::AddItem { content }) = action else {
138 return Ok(None);
140 };
141
142 let sender_profile = TimelineDetails::from_initial_value(
143 room_data_provider.profile_from_user_id(&sender).await,
144 );
145
146 Ok(Some(Self { content, sender, sender_profile, timestamp, identifier }))
147 }
148}