Skip to content

Commit f06e529

Browse files
author
Daniel Salinas
committed
Expose the timestamp through the matrix-sdk-ui + FFI layers
1 parent 013da78 commit f06e529

File tree

19 files changed

+156
-84
lines changed

19 files changed

+156
-84
lines changed

bindings/matrix-sdk-ffi/src/timeline/mod.rs

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1005,7 +1005,10 @@ impl TimelineItem {
10051005
#[derive(Clone, uniffi::Enum)]
10061006
pub enum EventSendState {
10071007
/// The local event has not been sent yet.
1008-
NotSentYet,
1008+
NotSentYet {
1009+
/// When the send was first attempted.
1010+
created_at: Option<u64>,
1011+
},
10091012

10101013
/// The local event has been sent to the server, but unsuccessfully: The
10111014
/// sending has failed.
@@ -1019,6 +1022,9 @@ pub enum EventSendState {
10191022
/// while an unrecoverable error will be parked, until the user
10201023
/// decides to cancel sending it.
10211024
is_recoverable: bool,
1025+
1026+
/// When the send was first attempted.
1027+
created_at: Option<u64>,
10221028
},
10231029

10241030
/// The local event has been sent successfully to the server.
@@ -1030,12 +1036,15 @@ impl From<&matrix_sdk_ui::timeline::EventSendState> for EventSendState {
10301036
use matrix_sdk_ui::timeline::EventSendState::*;
10311037

10321038
match value {
1033-
NotSentYet => Self::NotSentYet,
1034-
SendingFailed { error, is_recoverable } => {
1039+
NotSentYet { created_at } => {
1040+
Self::NotSentYet { created_at: created_at.map(|ts| ts.as_secs().into()) }
1041+
}
1042+
SendingFailed { error, is_recoverable, created_at } => {
10351043
let as_queue_wedge_error: matrix_sdk::QueueWedgeError = (&**error).into();
10361044
Self::SendingFailed {
10371045
is_recoverable: *is_recoverable,
10381046
error: as_queue_wedge_error.into(),
1047+
created_at: created_at.map(|ts| ts.as_secs().into()),
10391048
}
10401049
}
10411050
Sent { event_id } => Self::Sent { event_id: event_id.to_string() },

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

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -808,17 +808,18 @@ impl StateStore for MemoryStore {
808808
transaction_id: OwnedTransactionId,
809809
kind: QueuedRequestKind,
810810
priority: usize,
811-
) -> Result<(), Self::Error> {
811+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error> {
812+
let created_at = MilliSecondsSinceUnixEpoch::now();
812813
self.send_queue_events.write().unwrap().entry(room_id.to_owned()).or_default().push(
813814
QueuedRequest {
814815
kind,
815816
transaction_id,
816817
error: None,
817818
priority,
818-
created_at: Some(MilliSecondsSinceUnixEpoch::now()),
819+
created_at: Some(created_at.clone()),
819820
},
820821
);
821-
Ok(())
822+
Ok(created_at)
822823
}
823824

824825
async fn update_send_queue_request(
@@ -908,17 +909,18 @@ impl StateStore for MemoryStore {
908909
parent_transaction_id: &TransactionId,
909910
own_transaction_id: ChildTransactionId,
910911
content: DependentQueuedRequestKind,
911-
) -> Result<(), Self::Error> {
912+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error> {
913+
let created_at = MilliSecondsSinceUnixEpoch::now();
912914
self.dependent_send_queue_events.write().unwrap().entry(room.to_owned()).or_default().push(
913915
DependentQueuedRequest {
914916
kind: content,
915917
parent_transaction_id: parent_transaction_id.to_owned(),
916918
own_transaction_id,
917919
parent_key: None,
918-
created_at: None,
920+
created_at: Some(created_at.clone()),
919921
},
920922
);
921-
Ok(())
923+
Ok(created_at)
922924
}
923925

924926
async fn mark_dependent_queued_requests_as_ready(

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ use ruma::{
3535
},
3636
serde::Raw,
3737
time::SystemTime,
38-
EventId, OwnedEventId, OwnedMxcUri, OwnedRoomId, OwnedTransactionId, OwnedUserId, RoomId,
39-
TransactionId, UserId,
38+
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedMxcUri, OwnedRoomId,
39+
OwnedTransactionId, OwnedUserId, RoomId, TransactionId, UserId,
4040
};
4141
use serde::{Deserialize, Serialize};
4242

@@ -361,7 +361,7 @@ pub trait StateStore: AsyncTraitDeps {
361361
transaction_id: OwnedTransactionId,
362362
request: QueuedRequestKind,
363363
priority: usize,
364-
) -> Result<(), Self::Error>;
364+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error>;
365365

366366
/// Updates a send queue request with the given content, and resets its
367367
/// error status.
@@ -422,7 +422,7 @@ pub trait StateStore: AsyncTraitDeps {
422422
parent_txn_id: &TransactionId,
423423
own_txn_id: ChildTransactionId,
424424
content: DependentQueuedRequestKind,
425-
) -> Result<(), Self::Error>;
425+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error>;
426426

427427
/// Mark a set of dependent send queue requests as ready, using a key
428428
/// identifying the homeserver's response.
@@ -659,7 +659,7 @@ impl<T: StateStore> StateStore for EraseStateStoreError<T> {
659659
transaction_id: OwnedTransactionId,
660660
content: QueuedRequestKind,
661661
priority: usize,
662-
) -> Result<(), Self::Error> {
662+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error> {
663663
self.0
664664
.save_send_queue_request(room_id, transaction_id, content, priority)
665665
.await
@@ -712,7 +712,7 @@ impl<T: StateStore> StateStore for EraseStateStoreError<T> {
712712
parent_txn_id: &TransactionId,
713713
own_txn_id: ChildTransactionId,
714714
content: DependentQueuedRequestKind,
715-
) -> Result<(), Self::Error> {
715+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error> {
716716
self.0
717717
.save_dependent_queued_request(room_id, parent_txn_id, own_txn_id, content)
718718
.await

crates/matrix-sdk-indexeddb/src/state_store/mod.rs

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ use ruma::{
3737
events::{
3838
presence::PresenceEvent,
3939
receipt::{Receipt, ReceiptThread, ReceiptType},
40-
room::member::{
41-
MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent, SyncRoomMemberEvent,
40+
room::{
41+
create,
42+
member::{
43+
MembershipState, RoomMemberEventContent, StrippedRoomMemberEvent,
44+
SyncRoomMemberEvent,
45+
},
4246
},
4347
AnyGlobalAccountDataEvent, AnyRoomAccountDataEvent, AnySyncStateEvent,
4448
GlobalAccountDataEventType, RoomAccountDataEventType, StateEventType, SyncStateEvent,
@@ -442,7 +446,7 @@ struct PersistedQueuedRequest {
442446
/// The time the original message was first attempted to be sent at.
443447
#[serde(skip_serializing_if = "Option::is_none")]
444448
created_at: Option<MilliSecondsSinceUnixEpoch>,
445-
449+
446450
// Migrated fields: keep these private, they're not used anymore elsewhere in the code base.
447451
/// Deprecated (from old format), now replaced with error field.
448452
is_wedged: Option<bool>,
@@ -1370,7 +1374,7 @@ impl_state_store!({
13701374
transaction_id: OwnedTransactionId,
13711375
kind: QueuedRequestKind,
13721376
priority: usize,
1373-
) -> Result<()> {
1377+
) -> Result<MilliSecondsSinceUnixEpoch> {
13741378
let encoded_key = self.encode_key(keys::ROOM_SEND_QUEUE, room_id);
13751379

13761380
let tx = self
@@ -1389,7 +1393,7 @@ impl_state_store!({
13891393
|| Ok(Vec::new()),
13901394
|val| self.deserialize_value::<Vec<PersistedQueuedRequest>>(&val),
13911395
)?;
1392-
1396+
let created_at = MilliSecondsSinceUnixEpoch::now();
13931397
// Push the new request.
13941398
prev.push(PersistedQueuedRequest {
13951399
room_id: room_id.to_owned(),
@@ -1399,15 +1403,15 @@ impl_state_store!({
13991403
is_wedged: None,
14001404
event: None,
14011405
priority: Some(priority),
1402-
created_at: Some(MilliSecondsSinceUnixEpoch::now()),
1406+
created_at: Some(created_at.clone()),
14031407
});
14041408

14051409
// Save the new vector into db.
14061410
obj.put_key_val(&encoded_key, &self.serialize_value(&prev)?)?;
14071411

14081412
tx.await.into_result()?;
14091413

1410-
Ok(())
1414+
Ok(created_at)
14111415
}
14121416

14131417
async fn update_send_queue_request(
@@ -1570,7 +1574,7 @@ impl_state_store!({
15701574
parent_txn_id: &TransactionId,
15711575
own_txn_id: ChildTransactionId,
15721576
content: DependentQueuedRequestKind,
1573-
) -> Result<()> {
1577+
) -> Result<MilliSecondsSinceUnixEpoch> {
15741578
let encoded_key = self.encode_key(keys::DEPENDENT_SEND_QUEUE, room_id);
15751579

15761580
let tx = self.inner.transaction_on_one_with_mode(
@@ -1589,21 +1593,22 @@ impl_state_store!({
15891593
|val| self.deserialize_value::<Vec<DependentQueuedRequest>>(&val),
15901594
)?;
15911595

1596+
let created_at = MilliSecondsSinceUnixEpoch::now();
15921597
// Push the new request.
15931598
prev.push(DependentQueuedRequest {
15941599
kind: content,
15951600
parent_transaction_id: parent_txn_id.to_owned(),
15961601
own_transaction_id: own_txn_id,
15971602
parent_key: None,
1598-
created_at: None,
1603+
created_at: Some(created_at.clone()),
15991604
});
16001605

16011606
// Save the new vector into db.
16021607
obj.put_key_val(&encoded_key, &self.serialize_value(&prev)?)?;
16031608

16041609
tx.await.into_result()?;
16051610

1606-
Ok(())
1611+
Ok(created_at)
16071612
}
16081613

16091614
async fn update_dependent_queued_request(

crates/matrix-sdk-sqlite/src/state_store.rs

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,7 @@ impl StateStore for SqliteStateStore {
17591759
transaction_id: OwnedTransactionId,
17601760
content: QueuedRequestKind,
17611761
priority: usize,
1762-
) -> Result<(), Self::Error> {
1762+
) -> Result<MilliSecondsSinceUnixEpoch, Self::Error> {
17631763
let room_id_key = self.encode_key(keys::SEND_QUEUE, room_id);
17641764
let room_id_value = self.serialize_value(&room_id.to_owned())?;
17651765

@@ -1769,11 +1769,13 @@ impl StateStore for SqliteStateStore {
17691769
// it (with encode_key) or encrypt it (through serialize_value). After
17701770
// all, it carries no personal information, so this is considered fine.
17711771

1772+
let created_at = MilliSecondsSinceUnixEpoch::now();
1773+
let created_at_ts: u64 = created_at.0.into();
17721774
self.acquire()
17731775
.await?
17741776
.with_transaction(move |txn| {
1775-
txn.prepare_cached("INSERT INTO send_queue_events (room_id, room_id_val, transaction_id, content, priority) VALUES (?, ?, ?, ?, ?)")?.execute((room_id_key, room_id_value, transaction_id.to_string(), content, priority))?;
1776-
Ok(())
1777+
txn.prepare_cached("INSERT INTO send_queue_events (room_id, room_id_val, transaction_id, content, priority, created_at) VALUES (?, ?, ?, ?, ?, ?)")?.execute((room_id_key, room_id_value, transaction_id.to_string(), content, priority, created_at_ts))?;
1778+
Ok(created_at)
17771779
})
17781780
.await
17791781
}
@@ -1914,24 +1916,32 @@ impl StateStore for SqliteStateStore {
19141916
parent_txn_id: &TransactionId,
19151917
own_txn_id: ChildTransactionId,
19161918
content: DependentQueuedRequestKind,
1917-
) -> Result<()> {
1919+
) -> Result<MilliSecondsSinceUnixEpoch> {
19181920
let room_id = self.encode_key(keys::DEPENDENTS_SEND_QUEUE, room_id);
19191921
let content = self.serialize_json(&content)?;
19201922

19211923
// See comment in `save_send_queue_event`.
19221924
let parent_txn_id = parent_txn_id.to_string();
19231925
let own_txn_id = own_txn_id.to_string();
19241926

1927+
let created_at = MilliSecondsSinceUnixEpoch::now();
1928+
let created_at_ts: u64 = created_at.0.into();
19251929
self.acquire()
19261930
.await?
19271931
.with_transaction(move |txn| {
19281932
txn.prepare_cached(
19291933
r#"INSERT INTO dependent_send_queue_events
1930-
(room_id, parent_transaction_id, own_transaction_id, content)
1931-
VALUES (?, ?, ?, ?)"#,
1934+
(room_id, parent_transaction_id, own_transaction_id, content, created_at)
1935+
VALUES (?, ?, ?, ?, ?)"#,
19321936
)?
1933-
.execute((room_id, parent_txn_id, own_txn_id, content))?;
1934-
Ok(())
1937+
.execute((
1938+
room_id,
1939+
parent_txn_id,
1940+
own_txn_id,
1941+
content,
1942+
created_at_ts,
1943+
))?;
1944+
Ok(created_at)
19351945
})
19361946
.await
19371947
}

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

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,9 @@ impl<P: RoomDataProvider> TimelineController<P> {
950950
warn!("We looked for a local item, but it transitioned as remote??");
951951
return false;
952952
};
953-
prev_local_item.with_send_state(EventSendState::NotSentYet)
953+
prev_local_item.with_send_state(EventSendState::NotSentYet {
954+
created_at: prev_local_item.send_handle.clone().map(|h| h.created_at).flatten(),
955+
})
954956
};
955957

956958
// Replace the local-related state (kind) and the content state.
@@ -1260,6 +1262,7 @@ impl<P: RoomDataProvider> TimelineController<P> {
12601262
}
12611263
};
12621264

1265+
let created_at = send_handle.created_at.clone();
12631266
self.handle_local_event(
12641267
echo.transaction_id.clone(),
12651268
TimelineEventKind::Message { content, relations: Default::default() },
@@ -1273,6 +1276,7 @@ impl<P: RoomDataProvider> TimelineController<P> {
12731276
EventSendState::SendingFailed {
12741277
error: Arc::new(matrix_sdk::Error::SendQueueWedgeError(send_error)),
12751278
is_recoverable: false,
1279+
created_at,
12761280
},
12771281
)
12781282
.await;
@@ -1356,16 +1360,25 @@ impl<P: RoomDataProvider> TimelineController<P> {
13561360
}
13571361
}
13581362

1359-
RoomSendQueueUpdate::SendError { transaction_id, error, is_recoverable } => {
1363+
RoomSendQueueUpdate::SendError {
1364+
transaction_id,
1365+
error,
1366+
is_recoverable,
1367+
created_at,
1368+
} => {
13601369
self.update_event_send_state(
13611370
&transaction_id,
1362-
EventSendState::SendingFailed { error, is_recoverable },
1371+
EventSendState::SendingFailed { error, is_recoverable, created_at },
13631372
)
13641373
.await;
13651374
}
13661375

1367-
RoomSendQueueUpdate::RetryEvent { transaction_id } => {
1368-
self.update_event_send_state(&transaction_id, EventSendState::NotSentYet).await;
1376+
RoomSendQueueUpdate::RetryEvent { transaction_id, created_at } => {
1377+
self.update_event_send_state(
1378+
&transaction_id,
1379+
EventSendState::NotSentYet { created_at },
1380+
)
1381+
.await;
13691382
}
13701383

13711384
RoomSendQueueUpdate::SentEvent { transaction_id, event_id } => {

crates/matrix-sdk-ui/src/timeline/event_handler.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,9 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
10241024

10251025
let kind: EventTimelineItemKind = match &self.ctx.flow {
10261026
Flow::Local { txn_id, send_handle } => LocalEventTimelineItem {
1027-
send_state: EventSendState::NotSentYet,
1027+
send_state: EventSendState::NotSentYet {
1028+
created_at: send_handle.clone().map(|h| h.created_at).flatten(),
1029+
},
10281030
transaction_id: txn_id.to_owned(),
10291031
send_handle: send_handle.clone(),
10301032
}

crates/matrix-sdk-ui/src/timeline/event_item/local.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::sync::Arc;
1616

1717
use as_variant::as_variant;
1818
use matrix_sdk::{send_queue::SendHandle, Error};
19-
use ruma::{EventId, OwnedEventId, OwnedTransactionId};
19+
use ruma::{EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId};
2020

2121
use super::TimelineEventItemId;
2222

@@ -65,7 +65,10 @@ impl LocalEventTimelineItem {
6565
#[derive(Clone, Debug)]
6666
pub enum EventSendState {
6767
/// The local event has not been sent yet.
68-
NotSentYet,
68+
NotSentYet {
69+
/// When the send was first attempted.
70+
created_at: Option<MilliSecondsSinceUnixEpoch>,
71+
},
6972
/// The local event has been sent to the server, but unsuccessfully: The
7073
/// sending has failed.
7174
SendingFailed {
@@ -77,6 +80,9 @@ pub enum EventSendState {
7780
/// while an unrecoverable error will be parked, until the user
7881
/// decides to cancel sending it.
7982
is_recoverable: bool,
83+
84+
/// When the send was first attempted.
85+
created_at: Option<MilliSecondsSinceUnixEpoch>,
8086
},
8187
/// The local event has been sent successfully to the server.
8288
Sent {

0 commit comments

Comments
 (0)