From d9b2b53f83a4a4b7fda08077d77acffd746ed078 Mon Sep 17 00:00:00 2001 From: Valere Date: Thu, 11 Jul 2024 13:18:19 +0200 Subject: [PATCH] feat(timeline): Expose shield state for EventTimelineItem (#3679) --- bindings/matrix-sdk-ffi/src/timeline/mod.rs | 31 +++++++++++++++++++ .../src/timeline/event_item/mod.rs | 17 +++++++++- 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/bindings/matrix-sdk-ffi/src/timeline/mod.rs b/bindings/matrix-sdk-ffi/src/timeline/mod.rs index bf24f3454..cbfc9b548 100644 --- a/bindings/matrix-sdk-ffi/src/timeline/mod.rs +++ b/bindings/matrix-sdk-ffi/src/timeline/mod.rs @@ -24,6 +24,7 @@ use matrix_sdk::{ AttachmentConfig, AttachmentInfo, BaseAudioInfo, BaseFileInfo, BaseImageInfo, BaseThumbnailInfo, BaseVideoInfo, Thumbnail, }, + deserialized_responses::ShieldState as RustShieldState, Error, }; use matrix_sdk_ui::timeline::{ @@ -922,6 +923,30 @@ impl From<&matrix_sdk_ui::timeline::EventSendState> for EventSendState { } } +/// Recommended decorations for decrypted messages, representing the message's +/// authenticity properties. +#[derive(uniffi::Enum)] +pub enum ShieldState { + /// A red shield with a tooltip containing the associated message should be + /// presented. + Red { message: String }, + /// A grey shield with a tooltip containing the associated message should be + /// presented. + Grey { message: String }, + /// No shield should be presented. + None, +} + +impl From for ShieldState { + fn from(value: RustShieldState) -> Self { + match value { + RustShieldState::Red { message } => Self::Red { message: message.to_owned() }, + RustShieldState::Grey { message } => Self::Grey { message: message.to_owned() }, + RustShieldState::None => Self::None, + } + } +} + #[derive(uniffi::Object)] pub struct EventTimelineItem(pub(crate) matrix_sdk_ui::timeline::EventTimelineItem); @@ -1008,6 +1033,12 @@ impl EventTimelineItem { pub fn can_be_replied_to(&self) -> bool { self.0.can_be_replied_to() } + + /// Gets the [`ShieldState`] which can be used to decorate messages in the + /// recommended way. + pub fn get_shield(&self, strict: bool) -> Option { + self.0.get_shield(strict).map(Into::into) + } } #[derive(uniffi::Record)] 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 bce3d5139..04fd1fe13 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs @@ -16,7 +16,10 @@ use std::sync::Arc; use as_variant::as_variant; use indexmap::IndexMap; -use matrix_sdk::{deserialized_responses::EncryptionInfo, Client, Error}; +use matrix_sdk::{ + deserialized_responses::{EncryptionInfo, ShieldState}, + Client, Error, +}; use matrix_sdk_base::{deserialized_responses::SyncTimelineEvent, latest_event::LatestEvent}; use once_cell::sync::Lazy; use ruma::{ @@ -335,6 +338,18 @@ impl EventTimelineItem { } } + /// Gets the [`ShieldState`] which can be used to decorate messages in the + /// recommended way. + pub fn get_shield(&self, strict: bool) -> Option { + self.encryption_info().map(|info| { + if strict { + info.verification_state.to_shield_state_strict() + } else { + info.verification_state.to_shield_state_lax() + } + }) + } + /// Check whether this item can be replied to. pub fn can_be_replied_to(&self) -> bool { // This must be in sync with the early returns of `Timeline::send_reply`