Skip to content

Commit 4a627ba

Browse files
committed
feat(timeline): indicate when the replied-to event is not a standalone item
If the replied-to event is an aggregation, the `RepliedToEvent::try_from_timeline_event` will now return `Ok(None)`, and the caller may handle this as they please. In the FFI layer, this will be filled with an error message indicating that the event is unsupported.
1 parent 560e33c commit 4a627ba

File tree

4 files changed

+42
-20
lines changed

4 files changed

+42
-20
lines changed

bindings/matrix-sdk-ffi/src/timeline/mod.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -687,7 +687,7 @@ impl Timeline {
687687
};
688688

689689
match replied_to {
690-
Ok(replied_to) => Ok(Arc::new(InReplyToDetails::new(
690+
Ok(Some(replied_to)) => Ok(Arc::new(InReplyToDetails::new(
691691
event_id_str,
692692
RepliedToEventDetails::Ready {
693693
content: replied_to.content().clone().into(),
@@ -696,6 +696,11 @@ impl Timeline {
696696
},
697697
))),
698698

699+
Ok(None) => Ok(Arc::new(InReplyToDetails::new(
700+
event_id_str,
701+
RepliedToEventDetails::Error { message: "unsupported event".to_owned() },
702+
))),
703+
699704
Err(e) => Ok(Arc::new(InReplyToDetails::new(
700705
event_id_str,
701706
RepliedToEventDetails::Error { message: e.to_string() },

crates/matrix-sdk-ui/src/timeline/controller/mod.rs

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1336,10 +1336,15 @@ impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
13361336
txn.commit();
13371337
}
13381338

1339+
/// Create a [`RepliedToEvent`] from an arbitrary event, be it in the
1340+
/// timeline or not.
1341+
///
1342+
/// Can be `None` if the event cannot be represented as a standalone item,
1343+
/// because it's an aggregation.
13391344
pub(super) async fn make_replied_to(
13401345
&self,
13411346
event: TimelineEvent,
1342-
) -> Result<RepliedToEvent, Error> {
1347+
) -> Result<Option<RepliedToEvent>, Error> {
13431348
// Reborrow, to avoid that the automatic deref borrows the entire guard (and we
13441349
// can't borrow both items and meta).
13451350
let state = &mut *self.state.write().await;
@@ -1581,17 +1586,25 @@ async fn fetch_replied_to_event(
15811586
let res = match room.load_or_fetch_event(in_reply_to, None).await {
15821587
Ok(timeline_event) => {
15831588
let state = &mut *state_lock.write().await;
1584-
TimelineDetails::Ready(Box::new(
1585-
RepliedToEvent::try_from_timeline_event(
1586-
timeline_event,
1587-
room,
1588-
&state.items,
1589-
&mut state.meta,
1590-
)
1591-
.await?,
1592-
))
1589+
1590+
let replied_to_item = RepliedToEvent::try_from_timeline_event(
1591+
timeline_event,
1592+
room,
1593+
&state.items,
1594+
&mut state.meta,
1595+
)
1596+
.await?;
1597+
1598+
if let Some(item) = replied_to_item {
1599+
TimelineDetails::Ready(Box::new(item))
1600+
} else {
1601+
// The replied-to item is an aggregation, not a standalone item.
1602+
return Err(Error::UnsupportedEvent);
1603+
}
15931604
}
1605+
15941606
Err(e) => TimelineDetails::Error(Arc::new(e)),
15951607
};
1608+
15961609
Ok(res)
15971610
}

crates/matrix-sdk-ui/src/timeline/event_item/content/reply.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use super::TimelineItemContent;
2323
use crate::timeline::{
2424
controller::TimelineMetadata,
2525
event_handler::TimelineAction,
26-
event_item::{content::MsgLikeContent, EventTimelineItem, Profile, TimelineDetails},
26+
event_item::{EventTimelineItem, Profile, TimelineDetails},
2727
traits::RoomDataProvider,
2828
Error as TimelineError, TimelineItem,
2929
};
@@ -97,7 +97,7 @@ impl RepliedToEvent {
9797
room_data_provider: &P,
9898
timeline_items: &Vector<Arc<TimelineItem>>,
9999
meta: &mut TimelineMetadata,
100-
) -> Result<Self, TimelineError> {
100+
) -> Result<Option<Self>, TimelineError> {
101101
let (raw_event, unable_to_decrypt_info) = match timeline_event.kind {
102102
matrix_sdk::deserialized_responses::TimelineEventKind::UnableToDecrypt {
103103
utd_info,
@@ -127,17 +127,15 @@ impl RepliedToEvent {
127127
)
128128
.await;
129129

130-
let content = if let Some(TimelineAction::AddItem { content, .. }) = action {
131-
content
132-
} else {
133-
// TODO: need some kind of "unsupported" event here: return an option
134-
TimelineItemContent::MsgLike(MsgLikeContent::redacted())
130+
let Some(TimelineAction::AddItem { content }) = action else {
131+
// The event can't be represented as a standalone timeline item.
132+
return Ok(None);
135133
};
136134

137135
let sender_profile = TimelineDetails::from_initial_value(
138136
room_data_provider.profile_from_user_id(&sender).await,
139137
);
140138

141-
Ok(Self { content, sender, sender_profile })
139+
Ok(Some(Self { content, sender, sender_profile }))
142140
}
143141
}

crates/matrix-sdk-ui/src/timeline/mod.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,13 @@ impl Timeline {
691691

692692
/// Create a [`RepliedToEvent`] from an arbitrary event, be it in the
693693
/// timeline or not.
694-
pub async fn make_replied_to(&self, event: TimelineEvent) -> Result<RepliedToEvent, Error> {
694+
///
695+
/// Can be `None` if the event cannot be represented as a standalone item,
696+
/// because it's an aggregation.
697+
pub async fn make_replied_to(
698+
&self,
699+
event: TimelineEvent,
700+
) -> Result<Option<RepliedToEvent>, Error> {
695701
self.controller.make_replied_to(event).await
696702
}
697703
}

0 commit comments

Comments
 (0)