mirror of
https://github.com/matrix-org/matrix-rust-sdk.git
synced 2026-05-16 12:43:01 -04:00
room: extend event_with_context so it returns a fully decrypted /context response
This commit is contained in:
@@ -480,8 +480,10 @@ impl NotificationClient {
|
||||
return Err(Error::UnknownRoom);
|
||||
};
|
||||
|
||||
let (mut timeline_event, state_events) =
|
||||
room.event_with_context(event_id, true).await?.ok_or(Error::ContextMissingEvent)?;
|
||||
let response = room.event_with_context(event_id, true, uint!(0)).await?;
|
||||
|
||||
let mut timeline_event = response.event.ok_or(Error::ContextMissingEvent)?;
|
||||
let state_events = response.state;
|
||||
|
||||
if let Some(decrypted_event) =
|
||||
self.retry_decryption(&room, timeline_event.event.cast_ref()).await?
|
||||
|
||||
@@ -121,7 +121,7 @@ impl fmt::Debug for MessagesOptions {
|
||||
}
|
||||
}
|
||||
|
||||
/// The result of a `Room::messages` call.
|
||||
/// The result of a [`super::Room::messages`] call.
|
||||
///
|
||||
/// In short, this is a possibly decrypted version of the response of a
|
||||
/// `room/messages` api call.
|
||||
@@ -139,3 +139,38 @@ pub struct Messages {
|
||||
/// A list of state events relevant to showing the `chunk`.
|
||||
pub state: Vec<Raw<AnyStateEvent>>,
|
||||
}
|
||||
|
||||
/// The result of a [`super::Room::event_with_context`] query.
|
||||
///
|
||||
/// This is a wrapper around
|
||||
/// [`ruma::api::client::context::get_context::v3::Response`], with events
|
||||
/// decrypted if needs be.
|
||||
#[derive(Debug)]
|
||||
pub struct EventWithContextResponse {
|
||||
/// The event targeted by the /context query.
|
||||
pub event: Option<TimelineEvent>,
|
||||
|
||||
/// Events before the target event, if a non-zero context size was
|
||||
/// requested.
|
||||
///
|
||||
/// Like the corresponding Ruma response, these are in reverse chronological
|
||||
/// order.
|
||||
pub events_before: Vec<TimelineEvent>,
|
||||
|
||||
/// Events after the target event, if a non-zero context size was requested.
|
||||
///
|
||||
/// Like the corresponding Ruma response, these are in chronological order.
|
||||
pub events_after: Vec<TimelineEvent>,
|
||||
|
||||
/// Token to paginate backwards, aka "start" token.
|
||||
pub prev_batch_token: Option<String>,
|
||||
|
||||
/// Token to paginate forwards, aka "end" token.
|
||||
pub next_batch_token: Option<String>,
|
||||
|
||||
/// State events related to the request.
|
||||
///
|
||||
/// If lazy-loading of members was requested, this may contain room
|
||||
/// membership events.
|
||||
pub state: Vec<Raw<AnyStateEvent>>,
|
||||
}
|
||||
|
||||
@@ -10,7 +10,10 @@ use std::{
|
||||
|
||||
use eyeball::SharedObservable;
|
||||
use futures_core::Stream;
|
||||
use futures_util::stream::FuturesUnordered;
|
||||
use futures_util::{
|
||||
future::{try_join, try_join_all},
|
||||
stream::FuturesUnordered,
|
||||
};
|
||||
use matrix_sdk_base::{
|
||||
deserialized_responses::{
|
||||
RawAnySyncOrStrippedState, RawSyncOrStrippedState, SyncOrStrippedState, TimelineEvent,
|
||||
@@ -65,14 +68,14 @@ use ruma::{
|
||||
space::{child::SpaceChildEventContent, parent::SpaceParentEventContent},
|
||||
tag::{TagInfo, TagName},
|
||||
typing::SyncTypingEvent,
|
||||
AnyRoomAccountDataEvent, AnyStateEvent, EmptyStateKey, MessageLikeEventContent,
|
||||
AnyRoomAccountDataEvent, AnyTimelineEvent, EmptyStateKey, MessageLikeEventContent,
|
||||
MessageLikeEventType, RedactContent, RedactedStateEventContent, RoomAccountDataEvent,
|
||||
RoomAccountDataEventContent, RoomAccountDataEventType, StateEventContent, StateEventType,
|
||||
StaticEventContent, StaticStateEventContent, SyncStateEvent,
|
||||
},
|
||||
push::{Action, PushConditionRoomCtx},
|
||||
serde::Raw,
|
||||
uint, EventId, Int, MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName,
|
||||
EventId, Int, MatrixToUri, MatrixUri, MxcUri, OwnedEventId, OwnedRoomId, OwnedServerName,
|
||||
OwnedTransactionId, OwnedUserId, TransactionId, UInt, UserId,
|
||||
};
|
||||
use serde::de::DeserializeOwned;
|
||||
@@ -80,7 +83,10 @@ use thiserror::Error;
|
||||
use tokio::sync::broadcast;
|
||||
use tracing::{debug, info, instrument, warn};
|
||||
|
||||
use self::futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent};
|
||||
use self::{
|
||||
futures::{SendAttachment, SendMessageLikeEvent, SendRawMessageLikeEvent},
|
||||
messages::EventWithContextResponse,
|
||||
};
|
||||
pub use self::{
|
||||
member::{RoomMember, RoomMemberRole},
|
||||
messages::{Messages, MessagesOptions},
|
||||
@@ -382,11 +388,12 @@ impl Room {
|
||||
&self,
|
||||
event_id: &EventId,
|
||||
lazy_load_members: bool,
|
||||
) -> Result<Option<(TimelineEvent, Vec<Raw<AnyStateEvent>>)>> {
|
||||
context_size: UInt,
|
||||
) -> Result<EventWithContextResponse> {
|
||||
let mut request =
|
||||
context::get_context::v3::Request::new(self.room_id().to_owned(), event_id.to_owned());
|
||||
|
||||
request.limit = uint!(0);
|
||||
request.limit = context_size;
|
||||
|
||||
if lazy_load_members {
|
||||
request.filter.lazy_load_options =
|
||||
@@ -395,23 +402,44 @@ impl Room {
|
||||
|
||||
let response = self.client.send(request, None).await?;
|
||||
|
||||
let Some(event) = response.event else {
|
||||
return Ok(None);
|
||||
// Decrypts one event, if needs be.
|
||||
let try_decrypt = |event: Raw<AnyTimelineEvent>| async move {
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
if let Ok(AnySyncTimelineEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted(
|
||||
SyncMessageLikeEvent::Original(_),
|
||||
))) = event.deserialize_as::<AnySyncTimelineEvent>()
|
||||
{
|
||||
if let Ok(event) = self.decrypt_event(event.cast_ref()).await {
|
||||
return Result::<_, Error>::Ok(event);
|
||||
}
|
||||
}
|
||||
|
||||
let push_actions = self.event_push_actions(&event).await?;
|
||||
|
||||
Result::<_, Error>::Ok(TimelineEvent {
|
||||
event: event.clone(),
|
||||
encryption_info: None,
|
||||
push_actions,
|
||||
})
|
||||
};
|
||||
|
||||
#[cfg(feature = "e2e-encryption")]
|
||||
if let Ok(AnySyncTimelineEvent::MessageLike(AnySyncMessageLikeEvent::RoomEncrypted(
|
||||
SyncMessageLikeEvent::Original(_),
|
||||
))) = event.deserialize_as::<AnySyncTimelineEvent>()
|
||||
{
|
||||
if let Ok(event) = self.decrypt_event(event.cast_ref()).await {
|
||||
return Ok(Some((event, response.state)));
|
||||
}
|
||||
}
|
||||
let target_event =
|
||||
if let Some(event) = response.event { Some(try_decrypt(event).await?) } else { None };
|
||||
|
||||
let push_actions = self.event_push_actions(&event).await?;
|
||||
let (events_before, events_after) = try_join(
|
||||
try_join_all(response.events_before.into_iter().map(try_decrypt)),
|
||||
try_join_all(response.events_after.into_iter().map(try_decrypt)),
|
||||
)
|
||||
.await?;
|
||||
|
||||
Ok(Some((TimelineEvent { event, encryption_info: None, push_actions }, response.state)))
|
||||
Ok(EventWithContextResponse {
|
||||
event: target_event,
|
||||
events_before,
|
||||
events_after,
|
||||
state: response.state,
|
||||
prev_batch_token: response.start,
|
||||
next_batch_token: response.end,
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) async fn request_members(&self) -> Result<()> {
|
||||
|
||||
Reference in New Issue
Block a user