Skip to content

Commit c288212

Browse files
committed
feat(send_queue): send redactions via the send queue
Signed-off-by: Johannes Marbach <n0-0ne+github@mailbox.org>
1 parent acda2e8 commit c288212

File tree

7 files changed

+460
-5
lines changed

7 files changed

+460
-5
lines changed

crates/matrix-sdk-base/src/store/send_queue.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,14 @@ pub enum QueuedRequestKind {
117117
#[serde(default)]
118118
accumulated: Vec<AccumulatedSentMediaInfo>,
119119
},
120+
121+
/// A redaction of another event to send.
122+
Redaction {
123+
/// The ID of the event to redact.
124+
redacts: OwnedEventId,
125+
/// The reason for the event being redacted.
126+
reason: Option<String>,
127+
},
120128
}
121129

122130
impl From<SerializableEventContent> for QueuedRequestKind {
@@ -421,12 +429,28 @@ pub enum SentRequestKey {
421429

422430
/// The parent transaction returned an uploaded resource URL.
423431
Media(SentMediaInfo),
432+
433+
/// The parent transaction returned a redaction event when it succeeded.
434+
Redaction {
435+
/// The event ID returned by the server.
436+
event_id: OwnedEventId,
437+
438+
/// The ID of the redacted event.
439+
redacts: OwnedEventId,
440+
441+
/// The reason for the event being redacted.
442+
reason: Option<String>,
443+
},
424444
}
425445

426446
impl SentRequestKey {
427447
/// Converts the current parent key into an event id, if possible.
428448
pub fn into_event_id(self) -> Option<OwnedEventId> {
429-
as_variant!(self, Self::Event { event_id, .. } => event_id)
449+
match self {
450+
Self::Event { event_id, .. } => Some(event_id),
451+
Self::Redaction { event_id, .. } => Some(event_id),
452+
_ => None,
453+
}
430454
}
431455

432456
/// Converts the current parent key into information about a sent media, if

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1268,6 +1268,10 @@ impl<P: RoomDataProvider> TimelineController<P> {
12681268
LocalEchoContent::React { key, send_handle, applies_to } => {
12691269
self.handle_local_reaction(key, send_handle, applies_to).await;
12701270
}
1271+
1272+
LocalEchoContent::Redaction { .. } => {
1273+
// TODO: Handle local redactions in the timeline.
1274+
}
12711275
}
12721276
}
12731277

crates/matrix-sdk/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ All notable changes to this project will be documented in this file.
88

99
### Features
1010

11+
- Enable sending redaction events through the send queue via `RoomSendQueue::send_redaction`.
12+
This includes local echoes for redaction events through the new `LocalEchoContent::Redaction`
13+
variant.
14+
([#6250](https://github.com/matrix-org/matrix-rust-sdk/pull/6250))
1115
- [**breaking**]: The unread count computation has now moved from the sliding sync processing, to
1216
the event cache. As a result, it is necessary to enable the event cache if you want to keep a
1317
precise unread counts, using `Client::event_cache().subscribe()`. The unread counts will now also

crates/matrix-sdk/src/event_cache/tasks.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -313,6 +313,11 @@ async fn handle_thread_subscriber_send_queue_update(
313313
// Nothing to do, reactions don't count as a thread
314314
// subscription.
315315
}
316+
317+
LocalEchoContent::Redaction { .. } => {
318+
// Nothing to do, redactions don't count as a thread
319+
// subscription.
320+
}
316321
}
317322
return true;
318323
}

crates/matrix-sdk/src/latest_events/latest_event/builder.rs

Lines changed: 110 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,11 @@ impl Builder {
210210
}
211211

212212
LocalEchoContent::React { .. } => None,
213+
214+
// TODO: Rework the latest event system to handle local redactions. This will
215+
// require mixing the processing of local and remote events since a local redaction
216+
// will target a previous remote event.
217+
LocalEchoContent::Redaction { .. } => None,
213218
},
214219

215220
// A local event has been cancelled before being sent.
@@ -1639,7 +1644,7 @@ mod builder_tests {
16391644
Client, Error,
16401645
send_queue::{
16411646
AbstractProgress, LocalEcho, LocalEchoContent, RoomSendQueue, SendHandle,
1642-
SendReactionHandle,
1647+
SendReactionHandle, SendRedactionHandle,
16431648
},
16441649
test_utils::mocks::MatrixMockServer,
16451650
};
@@ -3601,4 +3606,108 @@ mod builder_tests {
36013606
);
36023607
assert!(buffer.buffer.is_empty());
36033608
}
3609+
3610+
#[async_test]
3611+
async fn test_local_redaction() {
3612+
let room_id = room_id!("!r0");
3613+
let user_id = user_id!("@mnt_io:matrix.org");
3614+
let event_factory = EventFactory::new().sender(user_id).room(room_id);
3615+
let event_id = event_id!("$ev0");
3616+
3617+
let server = MatrixMockServer::new().await;
3618+
let client = server.client_builder().build().await;
3619+
3620+
// Prelude.
3621+
{
3622+
// Create the room.
3623+
client.base_client().get_or_create_room(room_id, RoomState::Joined);
3624+
3625+
// Initialise the event cache store.
3626+
client
3627+
.event_cache_store()
3628+
.lock()
3629+
.await
3630+
.expect("Could not acquire the event cache lock")
3631+
.as_clean()
3632+
.expect("Could not acquire a clean event cache lock")
3633+
.handle_linked_chunk_updates(
3634+
LinkedChunkId::Room(room_id),
3635+
vec![
3636+
Update::NewItemsChunk {
3637+
previous: None,
3638+
new: ChunkIdentifier::new(0),
3639+
next: None,
3640+
},
3641+
Update::PushItems {
3642+
at: Position::new(ChunkIdentifier::new(0), 0),
3643+
items: vec![event_factory.text_msg("hello").event_id(event_id).into()],
3644+
},
3645+
],
3646+
)
3647+
.await
3648+
.unwrap();
3649+
}
3650+
3651+
let event_cache = client.event_cache();
3652+
event_cache.subscribe().unwrap();
3653+
3654+
let (room_event_cache, _) = event_cache.for_room(room_id).await.unwrap();
3655+
let send_queue = client.send_queue();
3656+
let room = client.get_room(room_id).unwrap();
3657+
let room_send_queue = send_queue.for_room(room);
3658+
3659+
let mut buffer = BufferOfValuesForLocalEvents::new();
3660+
3661+
// We get a `Remote` because there is no `Local*` values!
3662+
assert_remote_value_matches_room_message_with_body!(
3663+
Builder::new_local(
3664+
// An update that won't create a new `LatestEventValue`: it maps
3665+
// to zero existing local value.
3666+
&RoomSendQueueUpdate::SentEvent {
3667+
transaction_id: OwnedTransactionId::from("txnid"),
3668+
event_id: event_id.to_owned(),
3669+
},
3670+
&mut buffer,
3671+
&room_event_cache,
3672+
None,
3673+
user_id,
3674+
None,
3675+
)
3676+
.await
3677+
=> with body = "hello"
3678+
);
3679+
3680+
// A local redaction of the latest event value is being sent
3681+
{
3682+
let transaction_id = OwnedTransactionId::from("txnid0");
3683+
let content = LocalEchoContent::Redaction {
3684+
redacts: event_id.to_owned(),
3685+
reason: Some("whatever".to_owned()),
3686+
send_handle: SendRedactionHandle::new(
3687+
room_send_queue.clone(),
3688+
transaction_id.clone(),
3689+
),
3690+
send_error: None,
3691+
};
3692+
let update = RoomSendQueueUpdate::NewLocalEvent(LocalEcho {
3693+
transaction_id: transaction_id.clone(),
3694+
content,
3695+
});
3696+
3697+
// Local redactions are currently ignored.
3698+
assert_matches!(
3699+
Builder::new_local(
3700+
&update,
3701+
&mut buffer,
3702+
&room_event_cache,
3703+
Some(event_id.to_owned()),
3704+
user_id,
3705+
None
3706+
)
3707+
.await,
3708+
None
3709+
);
3710+
};
3711+
assert_eq!(buffer.buffer.len(), 0);
3712+
}
36043713
}

0 commit comments

Comments
 (0)