From de7a50b06324b0a6f5f58ba629b56e316ecc3cc0 Mon Sep 17 00:00:00 2001 From: Daniel Salinas Date: Wed, 11 Dec 2024 10:26:01 -0500 Subject: [PATCH] Remove from LocalSendState, move into a parallel field in the LocalTimelineItem instead --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 17 ++++---------- .../src/state_store/mod.rs | 7 ++---- .../src/timeline/controller/mod.rs | 23 ++++--------------- .../src/timeline/event_handler.rs | 5 ++-- .../src/timeline/event_item/local.rs | 10 +++----- .../src/timeline/event_item/mod.rs | 5 ++++ .../matrix-sdk-ui/src/timeline/tests/echo.rs | 2 +- .../tests/integration/timeline/echo.rs | 4 ++-- .../tests/integration/timeline/edit.rs | 8 +++---- .../tests/integration/timeline/media.rs | 4 ++-- .../tests/integration/timeline/mod.rs | 4 ++-- .../tests/integration/timeline/queue.rs | 4 ++-- .../tests/integration/timeline/replies.rs | 10 ++++---- crates/matrix-sdk/src/send_queue.rs | 15 +++--------- .../tests/integration/send_queue.rs | 4 ++-- .../src/tests/timeline.rs | 2 +- 16 files changed, 46 insertions(+), 78 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index 52e8c2eba54..1d466040b68 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -1005,10 +1005,7 @@ impl TimelineItem { #[derive(Clone, uniffi::Enum)] pub enum EventSendState { /// The local event has not been sent yet. - NotSentYet { - /// When the send was first enqueued by the user. - created_at: Option, - }, + NotSentYet, /// The local event has been sent to the server, but unsuccessfully: The /// sending has failed. @@ -1022,9 +1019,6 @@ pub enum EventSendState { /// while an unrecoverable error will be parked, until the user /// decides to cancel sending it. is_recoverable: bool, - - /// When the send was first enqueued by the user. - created_at: Option, }, /// The local event has been sent successfully to the server. @@ -1036,15 +1030,12 @@ impl From<&matrix_sdk_ui::timeline::EventSendState> for EventSendState { use matrix_sdk_ui::timeline::EventSendState::*; match value { - NotSentYet { created_at } => { - Self::NotSentYet { created_at: created_at.map(|ts| ts.as_secs().into()) } - } - SendingFailed { error, is_recoverable, created_at } => { + NotSentYet => Self::NotSentYet, + SendingFailed { error, is_recoverable } => { let as_queue_wedge_error: matrix_sdk::QueueWedgeError = (&**error).into(); Self::SendingFailed { is_recoverable: *is_recoverable, error: as_queue_wedge_error.into(), - created_at: created_at.map(|ts| ts.as_secs().into()), } } Sent { event_id } => Self::Sent { event_id: event_id.to_string() }, @@ -1093,6 +1084,7 @@ pub struct EventTimelineItem { timestamp: u64, reactions: Vec, local_send_state: Option, + local_created_at: Option, read_receipts: HashMap, origin: Option, can_be_replied_to: bool, @@ -1130,6 +1122,7 @@ impl From for EventTimelineItem { timestamp: item.timestamp().0.into(), reactions, local_send_state: item.send_state().map(|s| s.into()), + local_created_at: item.local_created_at().map(|t| t.0.into()), read_receipts, origin: item.origin(), can_be_replied_to: item.can_be_replied_to(), diff --git a/crates/matrix-sdk-indexeddb/src/state_store/mod.rs b/crates/matrix-sdk-indexeddb/src/state_store/mod.rs index 58ff5de7b53..1714ea252eb 100644 --- a/crates/matrix-sdk-indexeddb/src/state_store/mod.rs +++ b/crates/matrix-sdk-indexeddb/src/state_store/mod.rs @@ -37,11 +37,8 @@ use ruma::{ events::{ presence::PresenceEvent, receipt::{Receipt, ReceiptThread, ReceiptType}, - room::{ - member::{ - MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent, - SyncRoomMemberEvent, - }, + room::member::{ + MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent, SyncRoomMemberEvent, }, AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnySyncStateEvent, GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, SyncStateEvent, diff --git a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs index 5a21a4205db..a90aafd9d91 100644 --- a/crates/matrix-sdk-ui/src/timeline/controller/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/controller/mod.rs @@ -973,9 +973,7 @@ impl TimelineController

{ warn!("We looked for a local item, but it transitioned as remote??"); return false; }; - prev_local_item.with_send_state(EventSendState::NotSentYet { - created_at: prev_local_item.send_handle.clone().and_then(|h| h.created_at), - }) + prev_local_item.with_send_state(EventSendState::NotSentYet) }; // Replace the local-related state (kind) and the content state. @@ -1284,7 +1282,6 @@ impl TimelineController

{ } }; - let created_at = send_handle.created_at; self.handle_local_event( echo.transaction_id.clone(), TimelineEventKind::Message { content, relations: Default::default() }, @@ -1298,7 +1295,6 @@ impl TimelineController

{ EventSendState::SendingFailed { error: Arc::new(matrix_sdk::Error::SendQueueWedgeError(send_error)), is_recoverable: false, - created_at, }, ) .await; @@ -1382,25 +1378,16 @@ impl TimelineController

{ } } - RoomSendQueueUpdate::SendError { - transaction_id, - error, - is_recoverable, - created_at, - } => { + RoomSendQueueUpdate::SendError { transaction_id, error, is_recoverable } => { self.update_event_send_state( &transaction_id, - EventSendState::SendingFailed { error, is_recoverable, created_at }, + EventSendState::SendingFailed { error, is_recoverable }, ) .await; } - RoomSendQueueUpdate::RetryEvent { transaction_id, created_at } => { - self.update_event_send_state( - &transaction_id, - EventSendState::NotSentYet { created_at }, - ) - .await; + RoomSendQueueUpdate::RetryEvent { transaction_id } => { + self.update_event_send_state(&transaction_id, EventSendState::NotSentYet).await; } RoomSendQueueUpdate::SentEvent { transaction_id, event_id } => { diff --git a/crates/matrix-sdk-ui/src/timeline/event_handler.rs b/crates/matrix-sdk-ui/src/timeline/event_handler.rs index 191bd31aaae..9b0ea87d65b 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_handler.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_handler.rs @@ -1030,11 +1030,10 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> { let kind: EventTimelineItemKind = match &self.ctx.flow { Flow::Local { txn_id, send_handle } => LocalEventTimelineItem { - send_state: EventSendState::NotSentYet { - created_at: send_handle.clone().and_then(|h| h.created_at), - }, + send_state: EventSendState::NotSentYet, transaction_id: txn_id.to_owned(), send_handle: send_handle.clone(), + created_at: send_handle.clone().and_then(|h| h.created_at), } .into(), diff --git a/crates/matrix-sdk-ui/src/timeline/event_item/local.rs b/crates/matrix-sdk-ui/src/timeline/event_item/local.rs index 0a86d6f5392..3f5cd48c953 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/local.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/local.rs @@ -30,6 +30,8 @@ pub(in crate::timeline) struct LocalEventTimelineItem { pub transaction_id: OwnedTransactionId, /// A handle to manipulate this event before it is sent, if possible. pub send_handle: Option, + /// The time that the event was created locally + pub created_at: Option, } impl LocalEventTimelineItem { @@ -65,10 +67,7 @@ impl LocalEventTimelineItem { #[derive(Clone, Debug)] pub enum EventSendState { /// The local event has not been sent yet. - NotSentYet { - /// When the send was first enqueued by the user. - created_at: Option, - }, + NotSentYet, /// The local event has been sent to the server, but unsuccessfully: The /// sending has failed. SendingFailed { @@ -80,9 +79,6 @@ pub enum EventSendState { /// while an unrecoverable error will be parked, until the user /// decides to cancel sending it. is_recoverable: bool, - - /// When the send was first enqueued by the user. - created_at: Option, }, /// The local event has been sent successfully to the server. Sent { diff --git a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs index a10f9fc95a6..f632e9371a7 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs @@ -268,6 +268,11 @@ impl EventTimelineItem { as_variant!(&self.kind, EventTimelineItemKind::Local(local) => &local.send_state) } + /// Get the local time that the event was enqueued at. + pub fn local_created_at(&self) -> Option { + as_variant!(&self.kind, EventTimelineItemKind::Local(local) => local.created_at).flatten() + } + /// Get the unique identifier of this item. /// /// Returns the transaction ID for a local echo item that has not been sent diff --git a/crates/matrix-sdk-ui/src/timeline/tests/echo.rs b/crates/matrix-sdk-ui/src/timeline/tests/echo.rs index 51d1fad4c2a..7733383c1fe 100644 --- a/crates/matrix-sdk-ui/src/timeline/tests/echo.rs +++ b/crates/matrix-sdk-ui/src/timeline/tests/echo.rs @@ -50,7 +50,7 @@ async fn test_remote_echo_full_trip() { let item = assert_next_matches!(stream, VectorDiff::PushBack { value } => value); let event_item = item.as_event().unwrap(); assert!(event_item.is_local_echo()); - assert_matches!(event_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(event_item.send_state(), Some(EventSendState::NotSentYet)); assert!(!event_item.can_be_replied_to()); item.unique_id().to_owned() }; diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/echo.rs b/crates/matrix-sdk-ui/tests/integration/timeline/echo.rs index 3d46ad7ca5f..202f294d88f 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/echo.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/echo.rs @@ -85,7 +85,7 @@ async fn test_echo() { assert_let!(Some(VectorDiff::PushBack { value: local_echo }) = timeline_stream.next().await); let item = local_echo.as_event().unwrap(); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); assert_let!(TimelineItemContent::Message(msg) = item.content()); assert_let!(MessageType::Text(text) = msg.msgtype()); assert_eq!(text.body, "Hello, World!"); @@ -253,7 +253,7 @@ async fn test_dedup_by_event_id_late() { let local_echo = assert_next_matches_with_timeout!(timeline_stream, VectorDiff::PushBack { value } => value); let item = local_echo.as_event().unwrap(); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); // Timeline: [date-divider, local echo] let date_divider = assert_next_matches_with_timeout!( timeline_stream, VectorDiff::PushFront { value } => value); diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs b/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs index 5c50da79ffa..9945e6e2c9b 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/edit.rs @@ -206,7 +206,7 @@ async fn test_edit_local_echo() { let internal_id = item.unique_id(); let item = item.as_event().unwrap(); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); assert_let!(Some(VectorDiff::PushFront { value: date_divider }) = timeline_stream.next().await); assert!(date_divider.is_date_divider()); @@ -255,7 +255,7 @@ async fn test_edit_local_echo() { assert!(item.is_local_echo()); // The send state has been reset. - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); let edit_message = item.content().as_message().unwrap(); assert_eq!(edit_message.body(), "hello, world"); @@ -778,7 +778,7 @@ async fn test_edit_local_echo_with_unsupported_content() { assert_let!(Some(VectorDiff::PushBack { value: item }) = timeline_stream.next().await); let item = item.as_event().unwrap(); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); assert_let!(Some(VectorDiff::PushFront { value: date_divider }) = timeline_stream.next().await); assert!(date_divider.is_date_divider()); @@ -831,7 +831,7 @@ async fn test_edit_local_echo_with_unsupported_content() { assert_let!(Some(VectorDiff::PushBack { value: item }) = timeline_stream.next().await); let item = item.as_event().unwrap(); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); // Let's edit the local echo (poll start) with an unsupported type (message). let edit_err = timeline diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/media.rs b/crates/matrix-sdk-ui/tests/integration/timeline/media.rs index 0886b908ef3..e11ea3a8283 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/media.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/media.rs @@ -104,7 +104,7 @@ async fn test_send_attachment() { { assert_let_timeout!(Some(VectorDiff::PushBack { value: item }) = timeline_stream.next()); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); assert_let!(TimelineItemContent::Message(msg) = item.content()); // Body is the caption, because there's both a caption and filename. @@ -125,7 +125,7 @@ async fn test_send_attachment() { Some(VectorDiff::Set { index: 1, value: item }) = timeline_stream.next() ); assert_let!(TimelineItemContent::Message(msg) = item.content()); - assert_matches!(item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(item.send_state(), Some(EventSendState::NotSentYet)); assert_eq!(get_filename_and_caption(msg.msgtype()), ("test.bin", Some("caption"))); // The URI now refers to the final MXC URI. diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/mod.rs b/crates/matrix-sdk-ui/tests/integration/timeline/mod.rs index ad4b70e0c70..570323f4e8c 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/mod.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/mod.rs @@ -287,7 +287,7 @@ async fn test_redact_message() { assert_let!(Some(VectorDiff::PushBack { value: second }) = timeline_stream.next().await); let second = second.as_event().unwrap(); - assert_matches!(second.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(second.send_state(), Some(EventSendState::NotSentYet)); // We haven't set a route for sending events, so this will fail. assert_let!(Some(VectorDiff::Set { index, value: second }) = timeline_stream.next().await); @@ -345,7 +345,7 @@ async fn test_redact_local_sent_message() { assert_let_timeout!(Some(VectorDiff::PushBack { value: item }) = timeline_stream.next()); let event = item.as_event().unwrap(); assert!(event.is_local_echo()); - assert_matches!(event.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(event.send_state(), Some(EventSendState::NotSentYet)); // As well as a date divider. assert_let_timeout!( diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs b/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs index b3c06ca9db2..1ab3357418e 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/queue.rs @@ -374,7 +374,7 @@ async fn test_clear_with_echoes() { // The message that failed to send. assert_matches!(event_items[1].send_state(), Some(EventSendState::SendingFailed { .. })); // The message that is still pending. - assert_matches!(event_items[2].send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(event_items[2].send_state(), Some(EventSendState::NotSentYet)); // When we clear the timeline now, timeline.clear().await; @@ -385,7 +385,7 @@ async fn test_clear_with_echoes() { assert_eq!(event_items.len(), 2); assert_matches!(event_items[0].send_state(), Some(EventSendState::SendingFailed { .. })); - assert_matches!(event_items[1].send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(event_items[1].send_state(), Some(EventSendState::NotSentYet)); } #[async_test] diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/replies.rs b/crates/matrix-sdk-ui/tests/integration/timeline/replies.rs index 06825b32e25..e4a953da94c 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/replies.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/replies.rs @@ -330,7 +330,7 @@ async fn test_send_reply() { let reply_item = assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet)); let reply_message = reply_item.content().as_message().unwrap(); assert_eq!(reply_message.body(), "Replying to Bob"); let in_reply_to = reply_message.in_reply_to().unwrap(); @@ -440,7 +440,7 @@ async fn test_send_reply_to_self() { let reply_item = assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet)); let reply_message = reply_item.content().as_message().unwrap(); assert_eq!(reply_message.body(), "Replying to self"); let in_reply_to = reply_message.in_reply_to().unwrap(); @@ -533,7 +533,7 @@ async fn test_send_reply_to_threaded() { let reply_item = assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet)); let reply_message = reply_item.content().as_message().unwrap(); // The reply should be considered part of the thread. @@ -663,7 +663,7 @@ async fn test_send_reply_with_event_id() { let reply_item = assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet)); let reply_message = reply_item.content().as_message().unwrap(); assert_eq!(reply_message.body(), "Replying to Bob"); let in_reply_to = reply_message.in_reply_to().unwrap(); @@ -779,7 +779,7 @@ async fn test_send_reply_with_event_id_that_is_redacted() { let reply_item = assert_next_matches!(timeline_stream, VectorDiff::PushBack { value } => value); - assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(reply_item.send_state(), Some(EventSendState::NotSentYet)); let reply_message = reply_item.content().as_message().unwrap(); assert_eq!(reply_message.body(), "Replying to Bob"); let in_reply_to = reply_message.in_reply_to().unwrap(); diff --git a/crates/matrix-sdk/src/send_queue.rs b/crates/matrix-sdk/src/send_queue.rs index cc85acd2e7c..a44ca38de7f 100644 --- a/crates/matrix-sdk/src/send_queue.rs +++ b/crates/matrix-sdk/src/send_queue.rs @@ -564,7 +564,6 @@ impl RoomSendQueue { }; let txn_id = queued_request.transaction_id.clone(); - let txn_created_at = queued_request.created_at; trace!(txn_id = %txn_id, "received a request to send!"); let related_txn_id = as_variant!(&queued_request.kind, QueuedRequestKind::MediaUpload { related_to, .. } => related_to.clone()); @@ -664,7 +663,6 @@ impl RoomSendQueue { transaction_id: related_txn_id.unwrap_or(txn_id), error, is_recoverable, - created_at: txn_created_at, }); } } @@ -1807,18 +1805,12 @@ pub enum RoomSendQueueUpdate { /// while an unrecoverable error will be parked, until the user /// decides to cancel sending it. is_recoverable: bool, - - /// When the request was initially sent. - created_at: Option, }, /// The event has been unwedged and sending is now being retried. RetryEvent { /// Transaction id used to identify this event. transaction_id: OwnedTransactionId, - - /// When the request was initially sent. - created_at: Option, }, /// The event has been sent to the server, and the query returned @@ -2091,10 +2083,9 @@ impl SendHandle { // Wake up the queue, in case the room was asleep before unwedging the request. room.notifier.notify_one(); - let _ = room.updates.send(RoomSendQueueUpdate::RetryEvent { - transaction_id: self.transaction_id.clone(), - created_at: self.created_at, - }); + let _ = room + .updates + .send(RoomSendQueueUpdate::RetryEvent { transaction_id: self.transaction_id.clone() }); Ok(()) } diff --git a/crates/matrix-sdk/tests/integration/send_queue.rs b/crates/matrix-sdk/tests/integration/send_queue.rs index 9db20918e8d..70f1181e833 100644 --- a/crates/matrix-sdk/tests/integration/send_queue.rs +++ b/crates/matrix-sdk/tests/integration/send_queue.rs @@ -214,7 +214,7 @@ macro_rules! assert_update { // Check the next stream event is a retry event, with optional checks on txn=$txn ($watch:ident => retry { $(txn=$txn:expr)? }) => { assert_let!( - Ok(Ok(RoomSendQueueUpdate::RetryEvent { transaction_id: _txn, created_at: _created_at })) = + Ok(Ok(RoomSendQueueUpdate::RetryEvent { transaction_id: _txn })) = timeout(Duration::from_secs(1), $watch.recv()).await ); @@ -239,7 +239,7 @@ macro_rules! assert_update { // Returns the error for additional checks. ($watch:ident => error { $(recoverable=$recoverable:expr,)? $(txn=$txn:expr)? }) => {{ assert_let!( - Ok(Ok(RoomSendQueueUpdate::SendError { transaction_id: _txn, error, is_recoverable: _is_recoverable, created_at: _created_at })) = + Ok(Ok(RoomSendQueueUpdate::SendError { transaction_id: _txn, error, is_recoverable: _is_recoverable })) = timeout(Duration::from_secs(10), $watch.recv()).await ); diff --git a/testing/matrix-sdk-integration-testing/src/tests/timeline.rs b/testing/matrix-sdk-integration-testing/src/tests/timeline.rs index 5faaa670694..531ca7a1d21 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/timeline.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/timeline.rs @@ -258,7 +258,7 @@ async fn test_stale_local_echo_time_abort_edit() { } assert!(local_echo.is_editable()); - assert_matches!(local_echo.send_state(), Some(EventSendState::NotSentYet { .. })); + assert_matches!(local_echo.send_state(), Some(EventSendState::NotSentYet)); assert_eq!(local_echo.content().as_message().unwrap().body(), "hi!"); let mut has_sender_profile = local_echo.sender_profile().is_ready();