timeline: refactor handling of local redactions too

This commit is contained in:
Benjamin Bouvier
2024-04-19 12:29:56 +02:00
parent 650281b534
commit 621b47d763
5 changed files with 33 additions and 66 deletions

View File

@@ -53,7 +53,6 @@ use tracing::{field, info_span, Instrument as _};
use super::traits::Decryptor;
use super::{
event_handler::TimelineEventKind,
event_item::EventItemIdentifier,
reactions::ReactionToggleResult,
traits::RoomDataProvider,
util::{rfind_event_by_id, rfind_event_item, RelativePosition},
@@ -328,21 +327,15 @@ impl<P: RoomDataProvider> TimelineInner<P> {
(to_redact_local, to_redact_remote) => {
// The reaction exists, redact local echo and/or remote echo
let to_redact = if let Some(to_redact_local) = to_redact_local {
EventItemIdentifier::TransactionId(to_redact_local.clone())
let content = if let Some(to_redact_local) = to_redact_local {
TimelineEventKind::LocalRedaction { redacts: to_redact_local.clone() }
} else if let Some(to_redact_remote) = to_redact_remote {
EventItemIdentifier::EventId(to_redact_remote.clone())
TimelineEventKind::Redaction { redacts: to_redact_remote.clone() }
} else {
error!("Transaction id and event id are both missing");
return Err(super::Error::FailedToToggleReaction);
unreachable!("the None/None case has been handled above")
};
state.handle_local_redaction(
sender,
sender_profile,
TransactionId::new(),
to_redact,
);
state.handle_local_event(sender, sender_profile, TransactionId::new(), content);
// Remember the remote echo to redact on the homeserver
ReactionState::Redacting(to_redact_remote.cloned())
@@ -461,37 +454,18 @@ impl<P: RoomDataProvider> TimelineInner<P> {
.await;
}
/// Handle the creation of a new local event.
/// Creates the local echo for an event we're sending.
#[instrument(skip_all)]
pub(super) async fn handle_local_event(
&self,
txn_id: OwnedTransactionId,
content: AnyMessageLikeEventContent,
content: TimelineEventKind,
) {
let sender = self.room_data_provider.own_user_id().to_owned();
let profile = self.room_data_provider.profile_from_user_id(&sender).await;
let mut state = self.state.write().await;
state.handle_local_event(
sender,
profile,
txn_id,
TimelineEventKind::Message { content, relations: Default::default() },
);
}
/// Handle the redaction of a local event.
#[cfg(test)]
pub(super) async fn handle_local_redaction(
&self,
txn_id: OwnedTransactionId,
to_redact: EventItemIdentifier,
) {
let sender = self.room_data_provider.own_user_id().to_owned();
let profile = self.room_data_provider.profile_from_user_id(&sender).await;
let mut state = self.state.write().await;
state.handle_local_redaction(sender, profile, txn_id, to_redact);
state.handle_local_event(sender, profile, txn_id, content);
}
/// Update the send state of a local event represented by a transaction ID.

View File

@@ -189,27 +189,6 @@ impl TimelineInnerState {
txn.commit();
}
/// Locally handle the redaction of an event, be it a local echo
/// (`LocalRedaction`) or something that already had a remote echo
/// (`Redaction`).
pub(super) fn handle_local_redaction(
&mut self,
own_user_id: OwnedUserId,
own_profile: Option<Profile>,
txn_id: OwnedTransactionId,
to_redact: EventItemIdentifier,
) {
let content = match to_redact {
EventItemIdentifier::TransactionId(txn_id) => {
TimelineEventKind::LocalRedaction { redacts: txn_id }
}
EventItemIdentifier::EventId(event_id) => {
TimelineEventKind::Redaction { redacts: event_id }
}
};
self.handle_local_event(own_user_id, own_profile, txn_id, content);
}
#[cfg(feature = "e2e-encryption")]
pub(super) async fn retry_event_decryption<P: RoomDataProvider, Fut>(
&mut self,

View File

@@ -59,7 +59,7 @@ use thiserror::Error;
use tokio::sync::mpsc::Sender;
use tracing::{debug, error, instrument, trace, warn};
use self::futures::SendAttachment;
use self::{event_handler::TimelineEventKind, futures::SendAttachment};
mod builder;
mod day_dividers;
@@ -273,7 +273,15 @@ impl Timeline {
#[instrument(skip(self, content), fields(room_id = ?self.room().room_id()))]
pub async fn send(&self, content: AnyMessageLikeEventContent) {
let txn_id = TransactionId::new();
self.inner.handle_local_event(txn_id.clone(), content.clone()).await;
self.inner
.handle_local_event(
txn_id.clone(),
TimelineEventKind::Message {
content: content.clone(),
relations: Default::default(),
},
)
.await;
if self.msg_sender.send(LocalMessage { content, txn_id }).await.is_err() {
error!("Internal error: timeline message receiver is closed");
}

View File

@@ -47,7 +47,7 @@ use ruma::{
};
use super::{
event_item::EventItemIdentifier,
event_handler::TimelineEventKind,
inner::{ReactionAction, TimelineEnd, TimelineInnerSettings},
reactions::ReactionToggleResult,
traits::RoomDataProvider,
@@ -213,16 +213,23 @@ impl TestTimeline {
async fn handle_local_event(&self, content: AnyMessageLikeEventContent) -> OwnedTransactionId {
let txn_id = TransactionId::new();
self.inner.handle_local_event(txn_id.clone(), content).await;
self.inner
.handle_local_event(
txn_id.clone(),
TimelineEventKind::Message { content, relations: Default::default() },
)
.await;
txn_id
}
async fn handle_local_redaction_event(
&self,
redacts: EventItemIdentifier,
) -> OwnedTransactionId {
async fn handle_local_redaction_event(&self, redacts: &EventId) -> OwnedTransactionId {
let txn_id = TransactionId::new();
self.inner.handle_local_redaction(txn_id.clone(), redacts).await;
self.inner
.handle_local_event(
txn_id.clone(),
TimelineEventKind::Redaction { redacts: redacts.to_owned() },
)
.await;
txn_id
}

View File

@@ -27,7 +27,6 @@ use ruma::{
use stream_assert::assert_next_matches;
use crate::timeline::{
event_item::EventItemIdentifier,
inner::ReactionAction,
reactions::ReactionToggleResult,
tests::{assert_event_is_updated, assert_no_more_updates, TestTimeline},
@@ -146,7 +145,7 @@ async fn test_redact_reaction_from_non_existing_event() {
let mut stream = timeline.subscribe().await;
let reaction_id = EventId::new(server_name!("example.org")); // non existent event
timeline.handle_local_redaction_event(EventItemIdentifier::EventId(reaction_id)).await;
timeline.handle_local_redaction_event(&reaction_id).await;
assert_no_more_updates(&mut stream).await;
}