Skip to content

Commit ac61fc8

Browse files
committed
ffi: create EventShieldsProvider to load shields on demand in the clients
1 parent 52898fa commit ac61fc8

File tree

4 files changed

+43
-18
lines changed

4 files changed

+43
-18
lines changed

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,7 +1047,7 @@ pub struct EventTimelineItem {
10471047
read_receipts: HashMap<String, Receipt>,
10481048
origin: Option<EventItemOrigin>,
10491049
can_be_replied_to: bool,
1050-
message_shield: Option<ShieldState>,
1050+
shields_provider: Arc<EventShieldsProvider>,
10511051
}
10521052

10531053
impl From<matrix_sdk_ui::timeline::EventTimelineItem> for EventTimelineItem {
@@ -1066,7 +1066,9 @@ impl From<matrix_sdk_ui::timeline::EventTimelineItem> for EventTimelineItem {
10661066
.collect(),
10671067
})
10681068
.collect();
1069+
let value = Arc::new(value);
10691070
let debug_info_provider = Arc::new(EventTimelineItemDebugInfoProvider(value.clone()));
1071+
let shields_provider = Arc::new(EventShieldsProvider(value.clone()));
10701072
let read_receipts =
10711073
value.read_receipts().iter().map(|(k, v)| (k.to_string(), v.clone().into())).collect();
10721074
Self {
@@ -1085,7 +1087,7 @@ impl From<matrix_sdk_ui::timeline::EventTimelineItem> for EventTimelineItem {
10851087
read_receipts,
10861088
origin: value.origin(),
10871089
can_be_replied_to: value.can_be_replied_to(),
1088-
message_shield: value.get_shield(false).map(Into::into),
1090+
shields_provider,
10891091
}
10901092
}
10911093
}
@@ -1104,7 +1106,7 @@ impl From<ruma::events::receipt::Receipt> for Receipt {
11041106
/// Wrapper to retrieve the debug info lazily instead of immediately
11051107
/// transforming it for each timeline event.
11061108
#[derive(uniffi::Object)]
1107-
pub struct EventTimelineItemDebugInfoProvider(matrix_sdk_ui::timeline::EventTimelineItem);
1109+
pub struct EventTimelineItemDebugInfoProvider(Arc<matrix_sdk_ui::timeline::EventTimelineItem>);
11081110

11091111
#[uniffi::export]
11101112
impl EventTimelineItemDebugInfoProvider {
@@ -1267,3 +1269,14 @@ impl TryFrom<EditedContent> for SdkEditedContent {
12671269
}
12681270
}
12691271
}
1272+
1273+
/// Wrapper to retrieve the shields info lazily.
1274+
#[derive(Clone, uniffi::Object)]
1275+
pub struct EventShieldsProvider(Arc<matrix_sdk_ui::timeline::EventTimelineItem>);
1276+
1277+
#[uniffi::export]
1278+
impl EventShieldsProvider {
1279+
fn get_shields(&self, strict: bool) -> Option<ShieldState> {
1280+
self.0.get_shield(strict).map(Into::into)
1281+
}
1282+
}

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,9 @@ pub enum RedactError {
8686
#[error("Local event to redact wasn't found for transaction {0}")]
8787
LocalEventNotFound(OwnedTransactionId),
8888

89+
#[error("Local event with transaction id {0} had a remote `TimelineItemHandle`. This should never happen.")]
90+
InvalidTimelineItemHandle(OwnedTransactionId),
91+
8992
/// An error happened while attempting to redact an event.
9093
#[error(transparent)]
9194
HttpError(#[from] HttpError),

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -605,25 +605,30 @@ impl Timeline {
605605
) -> Result<(), Error> {
606606
match id {
607607
TimelineEventItemId::TransactionId(transaction_id) => {
608-
let Some(event) = self.item_by_transaction_id(transaction_id).await else {
609-
return Err(Error::RedactError(RedactError::LocalEventNotFound(
608+
let item = self.item_by_transaction_id(transaction_id).await;
609+
610+
match item.as_ref().map(|i| i.handle()) {
611+
Some(TimelineItemHandle::Local(handle)) => {
612+
handle.abort().await.map_err(RoomSendQueueError::StorageError)?;
613+
Ok(())
614+
}
615+
Some(TimelineItemHandle::Remote(_)) => Err(Error::RedactError(
616+
RedactError::InvalidTimelineItemHandle(transaction_id.to_owned()),
617+
)),
618+
None => Err(Error::RedactError(RedactError::LocalEventNotFound(
610619
transaction_id.to_owned(),
611-
)));
612-
};
613-
let TimelineItemHandle::Local(handle) = event.handle() else {
614-
panic!("If the item is local, this should never happen");
615-
};
616-
handle.abort().await.map_err(RoomSendQueueError::StorageError)?;
620+
))),
621+
}
617622
}
618623
TimelineEventItemId::EventId(event_id) => {
619624
self.room()
620625
.redact(event_id, reason, None)
621626
.await
622-
.map_err(RedactError::HttpError)
623-
.map_err(Error::RedactError)?;
627+
.map_err(|e| Error::RedactError(RedactError::HttpError(e)))?;
628+
629+
Ok(())
624630
}
625631
}
626-
Ok(())
627632
}
628633

629634
/// Redact an event.

crates/matrix-sdk-ui/tests/integration/timeline/mod.rs

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,23 @@ use matrix_sdk_test::{
3030
};
3131
use matrix_sdk_ui::{
3232
timeline::{
33-
AnyOtherFullStateEventContent, EventSendState, RoomExt, TimelineItemContent,
34-
VirtualTimelineItem,
33+
AnyOtherFullStateEventContent, Error, EventSendState, RedactError, RoomExt,
34+
TimelineEventItemId, TimelineItemContent, VirtualTimelineItem,
3535
},
3636
RoomListService, Timeline,
3737
};
38-
use ruma::{event_id, events::room::{encryption::RoomEncryptionEventContent, message::RoomMessageEventContent}, owned_event_id, room_id, user_id, MilliSecondsSinceUnixEpoch};
38+
use ruma::{
39+
event_id,
40+
events::room::{encryption::RoomEncryptionEventContent, message::RoomMessageEventContent},
41+
owned_event_id, room_id, user_id, MilliSecondsSinceUnixEpoch,
42+
};
3943
use serde_json::json;
4044
use stream_assert::{assert_next_matches, assert_pending};
4145
use wiremock::{
4246
matchers::{header, method, path_regex},
4347
Mock, ResponseTemplate,
4448
};
45-
use matrix_sdk_ui::timeline::{Error, RedactError, TimelineEventItemId};
49+
4650
use crate::mock_sync;
4751

4852
mod echo;

0 commit comments

Comments
 (0)