Skip to content

Commit

Permalink
Merge branch 'main' into feat-sdk-sliding-sync-types
Browse files Browse the repository at this point in the history
  • Loading branch information
Hywan committed Jul 11, 2024
2 parents 770d43f + d9b2b53 commit 773e712
Show file tree
Hide file tree
Showing 42 changed files with 486 additions and 172 deletions.
4 changes: 3 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ ruma = { git = "https://github.com/matrix-org/ruma", branch = "feat-sss", featur
"compat-encrypted-stickers",
"unstable-msc3401",
"unstable-msc3266",
"unstable-msc4075"
"unstable-msc4075",
"unstable-msc4140",
] }
ruma-common = { git = "https://github.com/matrix-org/ruma", branch = "feat-sss" }
serde = "1.0.151"
Expand All @@ -67,6 +68,7 @@ tokio = { version = "1.30.0", default-features = false, features = ["sync"] }
tokio-stream = "0.1.14"
tracing = { version = "0.1.40", default-features = false, features = ["std"] }
tracing-core = "0.1.32"
tracing-subscriber = "0.3.18"
uniffi = { version = "0.27.1" }
uniffi_bindgen = { version = "0.27.1" }
url = "2.5.0"
Expand Down
2 changes: 1 addition & 1 deletion benchmarks/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ ruma = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
tempfile = "3.3.0"
tokio = { version = "1.24.2", default-features = false, features = ["rt-multi-thread"] }
tokio = { workspace = true, default-features = false, features = ["rt-multi-thread"] }

[target.'cfg(target_os = "linux")'.dependencies]
pprof = { version = "0.13.0", features = ["flamegraph", "criterion"] }
Expand Down
4 changes: 2 additions & 2 deletions bindings/matrix-sdk-crypto-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ bundled-sqlite = ["matrix-sdk-sqlite/bundled"]

[dependencies]
anyhow = { workspace = true }
futures-util = "0.3.28"
futures-util = { workspace = true }
hmac = "0.12.1"
http = { workspace = true }
matrix-sdk-common = { workspace = true }
Expand All @@ -33,7 +33,7 @@ serde = { workspace = true }
serde_json = { workspace = true }
sha2 = { workspace = true }
thiserror = { workspace = true }
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
# keep in sync with uniffi dependency in matrix-sdk-ffi, and uniffi_bindgen in ffi CI job
uniffi = { workspace = true , features = ["cli"]}
vodozemac = { workspace = true }
Expand Down
4 changes: 2 additions & 2 deletions bindings/matrix-sdk-ffi/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ serde_json = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
tracing-core = { workspace = true }
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
tracing-subscriber = { workspace = true, features = ["env-filter"] }
tracing-appender = { version = "0.2.2" }
tokio = { version = "1", features = ["rt-multi-thread", "macros"] }
tokio = { workspace = true, features = ["rt-multi-thread", "macros"] }
uniffi = { workspace = true, features = ["tokio"] }
url = { workspace = true }
zeroize = { workspace = true }
Expand Down
31 changes: 31 additions & 0 deletions bindings/matrix-sdk-ffi/src/timeline/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<RustShieldState> 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);

Expand Down Expand Up @@ -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<ShieldState> {
self.0.get_shield(strict).map(Into::into)
}
}

#[derive(uniffi::Record)]
Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ futures-util = { workspace = true, features = ["channel"] }
wasm-bindgen-futures = { version = "0.4.33", optional = true }
gloo-timers = { version = "0.3.0", features = ["futures"] }
web-sys = { version = "0.3.60", features = ["console"] }
tracing-subscriber = { version = "0.3.14", default-features = false, features = ["fmt", "ansi"] }
tracing-subscriber = { workspace = true, features = ["fmt", "ansi"] }
wasm-bindgen = "0.2.84"

[dev-dependencies]
Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk-indexeddb/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ matrix-sdk-common = { workspace = true, features = ["js"] }
matrix-sdk-crypto = { workspace = true, features = ["js", "testing"] }
matrix-sdk-test = { workspace = true }
rand = { workspace = true }
tracing-subscriber = { version = "0.3.18", default-features = false, features = ["registry", "tracing-log"] }
tracing-subscriber = { workspace = true, features = ["registry", "tracing-log"] }
uuid = "1.3.0"
wasm-bindgen-test = "0.3.33"

Expand Down
7 changes: 4 additions & 3 deletions crates/matrix-sdk-ui/src/timeline/event_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ pub(super) enum Flow {
raw_event: Raw<AnySyncTimelineEvent>,
/// Where should this be added in the timeline.
position: TimelineItemPosition,
/// Information about the encryption for this event.
encryption_info: Option<EncryptionInfo>,
/// Should this event actually be added, based on the event filters.
should_add: bool,
},
Expand All @@ -98,7 +100,6 @@ pub(super) struct TimelineEventContext {
pub(super) sender_profile: Option<Profile>,
pub(super) timestamp: MilliSecondsSinceUnixEpoch,
pub(super) is_own_event: bool,
pub(super) encryption_info: Option<EncryptionInfo>,
pub(super) read_receipts: IndexMap<OwnedUserId, Receipt>,
pub(super) is_highlighted: bool,
pub(super) flow: Flow,
Expand Down Expand Up @@ -891,7 +892,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
}
.into(),

Flow::Remote { event_id, raw_event, position, txn_id, .. } => {
Flow::Remote { event_id, raw_event, position, txn_id, encryption_info, .. } => {
// Drop pending reactions if the message is redacted.
if let TimelineItemContent::RedactedMessage = content {
if !reactions.is_empty() {
Expand Down Expand Up @@ -921,7 +922,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
read_receipts: self.ctx.read_receipts.clone(),
is_own: self.ctx.is_own_event,
is_highlighted: self.ctx.is_highlighted,
encryption_info: self.ctx.encryption_info.clone(),
encryption_info: encryption_info.clone(),
original_json: Some(raw_event.clone()),
latest_edit_json: None,
origin,
Expand Down
17 changes: 16 additions & 1 deletion crates/matrix-sdk-ui/src/timeline/event_item/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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<ShieldState> {
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`
Expand Down
4 changes: 1 addition & 3 deletions crates/matrix-sdk-ui/src/timeline/inner/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,6 @@ impl TimelineInnerState {
sender_profile: own_profile,
timestamp: MilliSecondsSinceUnixEpoch::now(),
is_own_event: true,
// FIXME: Should we supply something here for encrypted rooms?
encryption_info: None,
read_receipts: Default::default(),
// An event sent by ourself is never matched against push rules.
is_highlighted: false,
Expand Down Expand Up @@ -557,7 +555,6 @@ impl TimelineInnerStateTransaction<'_> {
sender_profile,
timestamp,
is_own_event,
encryption_info: event.encryption_info,
read_receipts: if settings.track_read_receipts && should_add {
self.meta.read_receipts.compute_event_receipts(
&event_id,
Expand All @@ -571,6 +568,7 @@ impl TimelineInnerStateTransaction<'_> {
flow: Flow::Remote {
event_id: event_id.clone(),
raw_event: raw.clone(),
encryption_info: event.encryption_info,
txn_id,
position,
should_add,
Expand Down
2 changes: 2 additions & 0 deletions crates/matrix-sdk/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ Additions:
- Add `send_call_notification` and `send_call_notification_if_needed` methods. This allows to implement sending ring events on call start.
- The `get_media_content`, `get_media_file` and `get_file` methods of the
`Media` api now support the new authenticated media endpoints.
- WidgetDriver: Support the `"future_timeout"` and `"future_group_id"` fields in the `send_event` widget actions.
This allows to send future events, as defined in [MSC4157](https://github.com/matrix-org/matrix-spec-proposals/pull/4157)

# 0.7.0

Expand Down
2 changes: 1 addition & 1 deletion crates/matrix-sdk/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ once_cell = { workspace = true }
serde_urlencoded = "0.7.1"
similar-asserts = { workspace = true }
stream_assert = { workspace = true }
tracing-subscriber = { version = "0.3.11", features = ["env-filter"] }
tracing-subscriber = { workspace = true, features = ["env-filter"] }

[target.'cfg(target_arch = "wasm32")'.dev-dependencies]
wasm-bindgen-test = "0.3.33"
Expand Down
81 changes: 77 additions & 4 deletions crates/matrix-sdk/src/event_cache/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ use matrix_sdk_common::executor::{spawn, JoinHandle};
use ruma::{
events::{AnyRoomAccountDataEvent, AnySyncEphemeralRoomEvent},
serde::Raw,
OwnedEventId, OwnedRoomId, RoomId,
EventId, OwnedEventId, OwnedRoomId, RoomId,
};
use tokio::sync::{
broadcast::{error::RecvError, Receiver, Sender},
Expand Down Expand Up @@ -196,6 +196,23 @@ impl EventCache {
Ok(())
}

/// Try to find an event by its ID in all the rooms.
// NOTE: this does a linear scan, so it could be slow. If performance
// requires it, we could use a direct mapping of event id -> event, and keep it
// in memory until we store it on disk (and this becomes a SQL query by id).
pub async fn event(&self, event_id: &EventId) -> Option<SyncTimelineEvent> {
let by_room = self.inner.by_room.read().await;
for room in by_room.values() {
let events = room.inner.events.read().await;
for (_pos, event) in events.revents() {
if event.event_id().as_deref() == Some(event_id) {
return Some(event.clone());
}
}
}
None
}

#[instrument(skip_all)]
async fn ignore_user_list_update_task(
inner: Arc<EventCacheInner>,
Expand Down Expand Up @@ -759,13 +776,13 @@ pub enum EventsOrigin {
mod tests {
use assert_matches2::assert_matches;
use futures_util::FutureExt as _;
use matrix_sdk_base::sync::JoinedRoomUpdate;
use matrix_sdk_base::sync::{JoinedRoomUpdate, RoomUpdates, Timeline};
use matrix_sdk_test::async_test;
use ruma::{room_id, serde::Raw};
use ruma::{event_id, room_id, serde::Raw, user_id};
use serde_json::json;

use super::{EventCacheError, RoomEventCacheUpdate};
use crate::test_utils::logged_in_client;
use crate::test_utils::{assert_event_matches_msg, events::EventFactory, logged_in_client};

#[async_test]
async fn test_must_explicitly_subscribe() {
Expand Down Expand Up @@ -828,4 +845,60 @@ mod tests {

assert!(stream.recv().now_or_never().is_none());
}

#[async_test]
async fn test_get_event_by_id() {
let client = logged_in_client(None).await;
let room1 = room_id!("!galette:saucisse.bzh");
let room2 = room_id!("!crepe:saucisse.bzh");

let event_cache = client.event_cache();
event_cache.subscribe().unwrap();

// Insert two rooms with a few events.
let f = EventFactory::new().room(room1).sender(user_id!("@ben:saucisse.bzh"));

let eid1 = event_id!("$1");
let eid2 = event_id!("$2");
let eid3 = event_id!("$3");

let joined_room_update1 = JoinedRoomUpdate {
timeline: Timeline {
events: vec![
f.text_msg("hey").event_id(eid1).into(),
f.text_msg("you").event_id(eid2).into(),
],
..Default::default()
},
..Default::default()
};

let joined_room_update2 = JoinedRoomUpdate {
timeline: Timeline {
events: vec![f.text_msg("bjr").event_id(eid3).into()],
..Default::default()
},
..Default::default()
};

let mut updates = RoomUpdates::default();
updates.join.insert(room1.to_owned(), joined_room_update1);
updates.join.insert(room2.to_owned(), joined_room_update2);

// Have the event cache handle them.
event_cache.inner.handle_room_updates(updates).await.unwrap();

// Now retrieve all the events one by one.
let found1 = event_cache.event(eid1).await.unwrap();
assert_event_matches_msg(&found1, "hey");

let found2 = event_cache.event(eid2).await.unwrap();
assert_event_matches_msg(&found2, "you");

let found3 = event_cache.event(eid3).await.unwrap();
assert_event_matches_msg(&found3, "bjr");

// An unknown event won't be found.
assert!(event_cache.event(event_id!("$unknown")).await.is_none());
}
}
Loading

0 comments on commit 773e712

Please sign in to comment.