Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(timeline): handle more timeline item content kinds in replied-to details #4649

Merged
merged 5 commits into from
Feb 12, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
91 changes: 76 additions & 15 deletions crates/matrix-sdk-ui/src/timeline/event_item/content/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,11 @@
use std::{fmt, sync::Arc};

use imbl::{vector, Vector};
use matrix_sdk::{deserialized_responses::TimelineEvent, Room};
use matrix_sdk::{
crypto::types::events::UtdCause,
deserialized_responses::{TimelineEvent, TimelineEventKind},
Room,
};
use ruma::{
assign,
events::{
Expand All @@ -37,14 +41,15 @@ use ruma::{
serde::Raw,
OwnedEventId, OwnedUserId, UserId,
};
use tracing::{error, trace};
use tracing::{debug, error, instrument, trace, warn};

use super::TimelineItemContent;
use crate::{
timeline::{
event_item::{EventTimelineItem, Profile, TimelineDetails},
traits::RoomDataProvider,
Error as TimelineError, ReactionsByKeyBySender, TimelineItem,
EncryptedMessage, Error as TimelineError, PollState, ReactionsByKeyBySender, Sticker,
TimelineItem,
},
DEFAULT_SANITIZER_MODE,
};
Expand Down Expand Up @@ -354,30 +359,86 @@ impl RepliedToEvent {
Self::try_from_timeline_event(timeline_event, room_data_provider).await
}

#[instrument(skip_all)]
pub(in crate::timeline) async fn try_from_timeline_event<P: RoomDataProvider>(
timeline_event: TimelineEvent,
room_data_provider: &P,
) -> Result<Self, TimelineError> {
let event = match timeline_event.raw().deserialize() {
Ok(AnySyncTimelineEvent::MessageLike(event)) => event,
_ => {
Ok(_) => {
warn!("can't get details, event isn't a message-like event");
return Err(TimelineError::UnsupportedEvent);
}
Err(err) => {
warn!("can't get details, event couldn't be deserialized: {err}");
return Err(TimelineError::UnsupportedEvent);
}
};

let Some(AnyMessageLikeEventContent::RoomMessage(c)) = event.original_content() else {
return Err(TimelineError::UnsupportedEvent);
};
debug!(event_type = %event.event_type(), "got deserialized event");

let content = match event.original_content() {
Some(content) => match content {
AnyMessageLikeEventContent::RoomMessage(c) => {
// Assume we're not interested in reactions in this context: this is
// information for an embedded (replied-to) event, that will usually not
// include detailed information like reactions.
let reactions = ReactionsByKeyBySender::default();

TimelineItemContent::Message(Message::from_event(
c,
extract_room_msg_edit_content(event.relations()),
&vector![],
reactions,
))
}

// Assume we're not interested in reactions in this context.
let reactions = Default::default();
AnyMessageLikeEventContent::Sticker(content) => {
// Assume we're not interested in reactions in this context. (See above an
// explanation as to why that's the case.)
let reactions = ReactionsByKeyBySender::default();
TimelineItemContent::Sticker(Sticker { content, reactions })
}

AnyMessageLikeEventContent::RoomEncrypted(content) => {
let utd_cause = match &timeline_event.kind {
TimelineEventKind::UnableToDecrypt { utd_info, .. } => UtdCause::determine(
timeline_event.raw(),
room_data_provider.crypto_context_info().await,
utd_info,
),
_ => UtdCause::Unknown,
};

TimelineItemContent::UnableToDecrypt(EncryptedMessage::from_content(
content, utd_cause,
))
}

AnyMessageLikeEventContent::UnstablePollStart(
UnstablePollStartEventContent::New(content),
) => {
// Assume we're not interested in reactions in this context. (See above an
// explanation as to why that's the case.)
let reactions = ReactionsByKeyBySender::default();
// TODO: could we provide the bundled edit here?
let poll_state = PollState::new(content, None, reactions);
TimelineItemContent::Poll(poll_state)
}

_ => {
warn!("unsupported event type");
return Err(TimelineError::UnsupportedEvent);
}
},

None => {
// Redacted message.
TimelineItemContent::RedactedMessage
}
};

let content = TimelineItemContent::Message(Message::from_event(
c,
extract_room_msg_edit_content(event.relations()),
&vector![],
reactions,
));
let sender = event.sender().to_owned();
let sender_profile = TimelineDetails::from_initial_value(
room_data_provider.profile_from_user_id(&sender).await,
Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-ui/src/timeline/event_item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ pub struct Profile {
/// [`sync_events`][ruma::api::client::sync::sync_events].
#[derive(Clone, Debug)]
pub enum TimelineDetails<T> {
/// The details are not available yet, and have not been request from the
/// The details are not available yet, and have not been requested from the
/// server.
Unavailable,

Expand Down
Loading
Loading