From 72d16be43dc65d9868d5b43b2a01a2f31f984b36 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Fri, 12 Jul 2024 12:35:07 +0200 Subject: [PATCH 01/11] feat(client): Add the `Client::is_simplified_sliding_sync_enabled` field. This patch is the first over two patches to change the support of Simplified MSC3575 from a compiler feature flag to a runtime configuration. This configuration is held by the `Client`. By default, it's turned off inside `matrix-sdk-ffi` and `matrix-sdk-integration-testing`, otherwise it's turned on. --- bindings/matrix-sdk-ffi/src/client_builder.rs | 12 ++++++++++++ crates/matrix-sdk/src/client/builder.rs | 14 ++++++++++++++ crates/matrix-sdk/src/client/mod.rs | 17 +++++++++++++++++ crates/matrix-sdk/src/sliding_sync/builder.rs | 1 + .../src/helpers.rs | 3 +++ .../src/tests/sliding_sync/room.rs | 9 +++++++-- 6 files changed, 54 insertions(+), 2 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/client_builder.rs b/bindings/matrix-sdk-ffi/src/client_builder.rs index c1e9f87119c..a7cca427b28 100644 --- a/bindings/matrix-sdk-ffi/src/client_builder.rs +++ b/bindings/matrix-sdk-ffi/src/client_builder.rs @@ -251,6 +251,7 @@ pub struct ClientBuilder { user_agent: Option, requires_sliding_sync: bool, sliding_sync_proxy: Option, + is_simplified_sliding_sync_enabled: bool, proxy: Option, disable_ssl_verification: bool, disable_automatic_token_refresh: bool, @@ -272,6 +273,8 @@ impl ClientBuilder { user_agent: None, requires_sliding_sync: false, sliding_sync_proxy: None, + // By default, Simplified MSC3575 is turned off. + is_simplified_sliding_sync_enabled: false, proxy: None, disable_ssl_verification: false, disable_automatic_token_refresh: false, @@ -366,6 +369,12 @@ impl ClientBuilder { Arc::new(builder) } + pub fn simplified_sliding_sync(self: Arc, enable: bool) -> Arc { + let mut builder = unwrap_or_clone_arc(self); + builder.is_simplified_sliding_sync_enabled = enable; + Arc::new(builder) + } + pub fn proxy(self: Arc, url: String) -> Arc { let mut builder = unwrap_or_clone_arc(self); builder.proxy = Some(url); @@ -499,6 +508,9 @@ impl ClientBuilder { inner_builder = inner_builder.with_encryption_settings(builder.encryption_settings); + inner_builder = + inner_builder.simplified_sliding_sync(builder.is_simplified_sliding_sync_enabled); + if builder.requires_sliding_sync { inner_builder = inner_builder.requires_sliding_sync(); } diff --git a/crates/matrix-sdk/src/client/builder.rs b/crates/matrix-sdk/src/client/builder.rs index 61854d71636..a342b5a870c 100644 --- a/crates/matrix-sdk/src/client/builder.rs +++ b/crates/matrix-sdk/src/client/builder.rs @@ -88,6 +88,8 @@ pub struct ClientBuilder { requires_sliding_sync: bool, #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy: Option, + #[cfg(feature = "experimental-sliding-sync")] + is_simplified_sliding_sync_enabled: bool, http_cfg: Option, store_config: BuilderStoreConfig, request_config: RequestConfig, @@ -107,6 +109,9 @@ impl ClientBuilder { requires_sliding_sync: false, #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy: None, + // Simplified MSC3575 is turned on by default for the SDK. + #[cfg(feature = "experimental-sliding-sync")] + is_simplified_sliding_sync_enabled: true, http_cfg: None, store_config: BuilderStoreConfig::Custom(StoreConfig::default()), request_config: Default::default(), @@ -157,6 +162,13 @@ impl ClientBuilder { self } + /// Enable or disable Simplified MSC3575. + #[cfg(feature = "experimental-sliding-sync")] + pub fn simplified_sliding_sync(mut self, enable: bool) -> Self { + self.is_simplified_sliding_sync_enabled = enable; + self + } + /// Set the server name to discover the homeserver from. /// /// We assume we can connect in HTTPS to that server. If that's not the @@ -489,6 +501,8 @@ impl ClientBuilder { homeserver, #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy, + #[cfg(feature = "experimental-sliding-sync")] + self.is_simplified_sliding_sync_enabled, http_client, base_client, server_capabilities, diff --git a/crates/matrix-sdk/src/client/mod.rs b/crates/matrix-sdk/src/client/mod.rs index b4edd53ef3b..afb1327f269 100644 --- a/crates/matrix-sdk/src/client/mod.rs +++ b/crates/matrix-sdk/src/client/mod.rs @@ -232,6 +232,12 @@ pub(crate) struct ClientInner { #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy: StdRwLock>, + /// Whether Simplified MSC3575 is used or not. + /// + /// This value must not be changed during the lifetime of the `Client`. + #[cfg(feature = "experimental-sliding-sync")] + is_simplified_sliding_sync_enabled: bool, + /// The underlying HTTP client. pub(crate) http_client: HttpClient, @@ -305,6 +311,7 @@ impl ClientInner { auth_ctx: Arc, homeserver: Url, #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy: Option, + #[cfg(feature = "experimental-sliding-sync")] is_simplified_sliding_sync_enabled: bool, http_client: HttpClient, base_client: BaseClient, server_capabilities: ClientServerCapabilities, @@ -318,6 +325,8 @@ impl ClientInner { auth_ctx, #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy: StdRwLock::new(sliding_sync_proxy), + #[cfg(feature = "experimental-sliding-sync")] + is_simplified_sliding_sync_enabled, http_client, base_client, locks: Default::default(), @@ -471,6 +480,12 @@ impl Client { *lock = sliding_sync_proxy; } + /// Check whether Simplified MSC3575 must be used. + #[cfg(feature = "experimental-sliding-sync")] + pub(crate) fn is_simplified_sliding_sync_enabled(&self) -> bool { + self.inner.is_simplified_sliding_sync_enabled + } + /// Get the Matrix user session meta information. /// /// If the client is currently logged in, this will return a @@ -2175,6 +2190,8 @@ impl Client { self.homeserver(), #[cfg(feature = "experimental-sliding-sync")] sliding_sync_proxy, + #[cfg(feature = "experimental-sliding-sync")] + self.inner.is_simplified_sliding_sync_enabled, self.inner.http_client.clone(), self.inner.base_client.clone_with_in_memory_state_store(), self.inner.server_capabilities.read().await.clone(), diff --git a/crates/matrix-sdk/src/sliding_sync/builder.rs b/crates/matrix-sdk/src/sliding_sync/builder.rs index c1d2ba1c2e6..a3cc3776511 100644 --- a/crates/matrix-sdk/src/sliding_sync/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/builder.rs @@ -50,6 +50,7 @@ impl SlidingSyncBuilder { } else { let storage_key = format_storage_key_prefix(&id, client.user_id().ok_or(Error::UnauthenticatedUser)?); + Ok(Self { id, storage_key, diff --git a/testing/matrix-sdk-integration-testing/src/helpers.rs b/testing/matrix-sdk-integration-testing/src/helpers.rs index a16506566bf..dc8a63de381 100644 --- a/testing/matrix-sdk-integration-testing/src/helpers.rs +++ b/testing/matrix-sdk-integration-testing/src/helpers.rs @@ -88,6 +88,9 @@ impl TestClientBuilder { .user_agent("matrix-sdk-integration-tests") .homeserver_url(homeserver_url) .sliding_sync_proxy(sliding_sync_proxy_url) + // Disable Simplified MSC3575 for the integration tests as, at the time of writing, we + // use a Synapse version that doesn't support Simplified MSC3575. + .simplified_sliding_sync(false) .with_encryption_settings(self.encryption_settings) .request_config(RequestConfig::short_retry()); diff --git a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs index 5567ff225cf..083b5ec2892 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs @@ -273,8 +273,13 @@ async fn test_joined_user_can_create_push_context_with_room_list_service() -> Re let sliding_sync_url = alice.sliding_sync_proxy(); let alice_id = alice.user_id().unwrap().localpart().to_owned(); - let alice = Client::new(hs).await?; - alice.set_sliding_sync_proxy(sliding_sync_url); + let alice = Client::builder() + .homeserver_url(hs) + .simplified_sliding_sync(false) + .sliding_sync_proxy(sliding_sync_url.unwrap()) + .build() + .await + .unwrap(); alice.matrix_auth().login_username(&alice_id, &alice_id).await?; let room_list_service = Arc::new(RoomListService::new(alice.clone()).await?); From 065a8c4bd3951064501d55e976c6365e521f0e2e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 9 Jul 2024 10:00:50 +0200 Subject: [PATCH 02/11] chore(base): Move `sliding_sync` into its own module. This patch moves the `sliding_sync` file into its own module. --- .../matrix-sdk-base/src/{sliding_sync.rs => sliding_sync/mod.rs} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename crates/matrix-sdk-base/src/{sliding_sync.rs => sliding_sync/mod.rs} (100%) diff --git a/crates/matrix-sdk-base/src/sliding_sync.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs similarity index 100% rename from crates/matrix-sdk-base/src/sliding_sync.rs rename to crates/matrix-sdk-base/src/sliding_sync/mod.rs From b8033ef1f410e7123cd352ac870bdbcfe51fa3a8 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Tue, 9 Jul 2024 10:39:05 +0200 Subject: [PATCH 03/11] feat(base): Create an `http` module for `sliding_sync`. This patch creates an `http` module containing all the sliding sync types types (from Simplified MSC3575 or simply MSC3575). --- Cargo.lock | 21 ++++---- Cargo.toml | 4 +- crates/matrix-sdk-base/Cargo.toml | 5 +- .../matrix-sdk-base/src/sliding_sync/http.rs | 49 +++++++++++++++++++ .../matrix-sdk-base/src/sliding_sync/mod.rs | 2 + 5 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 crates/matrix-sdk-base/src/sliding_sync/http.rs diff --git a/Cargo.lock b/Cargo.lock index b8cd6efb5d6..9fe47df6e4b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3891,7 +3891,7 @@ name = "oauth2" version = "5.0.0-alpha.4" source = "git+https://github.com/poljar/oauth2-rs?rev=f8e28ce5a7f3278ac85b8593ecdd86f2cf51fa2e#f8e28ce5a7f3278ac85b8593ecdd86f2cf51fa2e" dependencies = [ - "base64 0.22.1", + "base64 0.21.7", "chrono", "getrandom", "http 1.1.0", @@ -5005,7 +5005,7 @@ dependencies = [ [[package]] name = "ruma" version = "0.10.1" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "assign", "js_int", @@ -5022,7 +5022,7 @@ dependencies = [ [[package]] name = "ruma-client-api" version = "0.18.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "as_variant", "assign", @@ -5045,7 +5045,7 @@ dependencies = [ [[package]] name = "ruma-common" version = "0.13.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "as_variant", "base64 0.22.1", @@ -5077,7 +5077,7 @@ dependencies = [ [[package]] name = "ruma-events" version = "0.28.1" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "as_variant", "indexmap 2.2.6", @@ -5095,13 +5095,14 @@ dependencies = [ "thiserror", "tracing", "url", + "web-time", "wildmatch", ] [[package]] name = "ruma-federation-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "js_int", "ruma-common", @@ -5113,7 +5114,7 @@ dependencies = [ [[package]] name = "ruma-html" version = "0.2.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "as_variant", "html5ever", @@ -5125,7 +5126,7 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" version = "0.9.5" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "js_int", "thiserror", @@ -5134,7 +5135,7 @@ dependencies = [ [[package]] name = "ruma-macros" version = "0.13.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "once_cell", "proc-macro-crate", @@ -5149,7 +5150,7 @@ dependencies = [ [[package]] name = "ruma-push-gateway-api" version = "0.9.0" -source = "git+https://github.com/ruma/ruma?rev=c37843e9be619ffac8c4d33ad3a6a175cc32610c#c37843e9be619ffac8c4d33ad3a6a175cc32610c" +source = "git+https://github.com/matrix-org/ruma?rev=4d3d8b46fd519012e4585ccf00dbea1eb602c028#4d3d8b46fd519012e4585ccf00dbea1eb602c028" dependencies = [ "js_int", "ruma-common", diff --git a/Cargo.toml b/Cargo.toml index cef583e1295..651ca1aa483 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,7 @@ once_cell = "1.16.0" pin-project-lite = "0.2.9" rand = "0.8.5" reqwest = { version = "0.12.4", default-features = false } -ruma = { git = "https://github.com/ruma/ruma", rev = "c37843e9be619ffac8c4d33ad3a6a175cc32610c", features = [ +ruma = { git = "https://github.com/matrix-org/ruma", rev = "4d3d8b46fd519012e4585ccf00dbea1eb602c028", features = [ "client-api-c", "compat-upload-signatures", "compat-user-id", @@ -59,7 +59,7 @@ ruma = { git = "https://github.com/ruma/ruma", rev = "c37843e9be619ffac8c4d33ad3 "unstable-msc4075", "unstable-msc4140", ] } -ruma-common = { git = "https://github.com/ruma/ruma", rev = "c37843e9be619ffac8c4d33ad3a6a175cc32610c" } +ruma-common = { git = "https://github.com/matrix-org/ruma", rev = "4d3d8b46fd519012e4585ccf00dbea1eb602c028" } serde = "1.0.151" serde_html_form = "0.2.0" serde_json = "1.0.91" diff --git a/crates/matrix-sdk-base/Cargo.toml b/crates/matrix-sdk-base/Cargo.toml index fcf46c0ff52..3bc12814811 100644 --- a/crates/matrix-sdk-base/Cargo.toml +++ b/crates/matrix-sdk-base/Cargo.toml @@ -22,7 +22,10 @@ js = ["matrix-sdk-common/js", "matrix-sdk-crypto?/js", "ruma/js", "matrix-sdk-st qrcode = ["matrix-sdk-crypto?/qrcode"] automatic-room-key-forwarding = ["matrix-sdk-crypto?/automatic-room-key-forwarding"] message-ids = ["matrix-sdk-crypto?/message-ids"] -experimental-sliding-sync = ["ruma/unstable-msc3575"] +experimental-sliding-sync = [ + "ruma/unstable-msc3575", + "ruma/unstable-simplified-msc3575", +] uniffi = ["dep:uniffi", "matrix-sdk-crypto?/uniffi"] # helpers for testing features build upon this diff --git a/crates/matrix-sdk-base/src/sliding_sync/http.rs b/crates/matrix-sdk-base/src/sliding_sync/http.rs new file mode 100644 index 00000000000..0d4215fe2c2 --- /dev/null +++ b/crates/matrix-sdk-base/src/sliding_sync/http.rs @@ -0,0 +1,49 @@ +// Copyright 2023 The Matrix.org Foundation C.I.C. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//! HTTP types for (Simplified) MSC3575. +//! +//! This module provides a unified namings for types from MSC3575 and +//! Simplified MSC3575, in addition to provide conversion from one +//! format to another. + +/// HTTP types from MSC3575, renamed to match the Simplified MSC3575 namings. +pub mod msc3575 { + use ruma::api::client::sync::sync_events::v4; + pub use v4::{Request, Response}; + + /// HTTP types related to a `Request`. + pub mod request { + pub use super::v4::{ + AccountDataConfig as AccountData, ExtensionsConfig as Extensions, + ReceiptsConfig as Receipts, RoomDetailsConfig as RoomDetails, RoomSubscription, + SyncRequestList as List, SyncRequestListFilters as ListFilters, + ToDeviceConfig as ToDevice, TypingConfig as Typing, + }; + } + + /// HTTP types related to a `Response`. + pub mod response { + pub use super::v4::{ + AccountData, Extensions, Receipts, SlidingSyncRoom as Room, + SlidingSyncRoomHero as RoomHero, SyncList as List, ToDevice, Typing, + }; + } +} + +pub mod simplified_msc3575 { + pub use ruma::api::client::sync::sync_events::v5::*; +} + +pub use simplified_msc3575::*; diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index 0509afe48c5..a69ba08fc38 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +pub mod http; + use std::collections::BTreeMap; #[cfg(feature = "e2e-encryption")] use std::ops::Deref; From 9f3bbaf5e0371b553b62e8fb280cf59dd0e55afe Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 13:34:46 +0200 Subject: [PATCH 04/11] feat(sdk) Transform Simplified MSC3575 to MSC3575 in `SlidingSync::sync_once`. This patch extracts most of `SlidingSync::sync_once` into a method named `SlidingSync::send_sync_request`. The name mimics the `SlidingSync::generate_sync_request` similar method: first we _generate_, then we _send_. The `SlidingSync::send_sync_request` is generic over the `Request` and `::sync_once` passes the correct type depending of whether Simplified MSC3575 is enabled. --- crates/matrix-sdk/src/sliding_sync/mod.rs | 93 +++++++++++++++++------ 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index 523e35ad4f8..5d9883c7fb3 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -39,6 +39,7 @@ use ruma::{ api::client::{ error::ErrorKind, sync::sync_events::v4::{self, ExtensionsConfig}, + OutgoingRequest, }, assign, OwnedEventId, OwnedRoomId, RoomId, }; @@ -58,7 +59,7 @@ use self::{ client::SlidingSyncResponseProcessor, sticky_parameters::{LazyTransactionId, SlidingSyncStickyManager, StickyData}, }; -use crate::{config::RequestConfig, Client, Result}; +use crate::{config::RequestConfig, Client, HttpError, Result}; /// The Sliding Sync instance. /// @@ -555,30 +556,26 @@ impl SlidingSync { )) } - /// Is the e2ee extension enabled for this sliding sync instance? - #[cfg(feature = "e2e-encryption")] - fn is_e2ee_enabled(&self) -> bool { - self.inner.sticky.read().unwrap().data().extensions.e2ee.enabled == Some(true) - } - - #[cfg(not(feature = "e2e-encryption"))] - fn is_e2ee_enabled(&self) -> bool { - false - } - - /// Should we process the room's subpart of a response? - async fn must_process_rooms_response(&self) -> bool { - // We consider that we must, if there's any room subscription or there's any - // list. - !self.inner.sticky.read().unwrap().data().room_subscriptions.is_empty() - || !self.inner.lists.read().await.is_empty() - } - - #[instrument(skip_all, fields(pos))] - async fn sync_once(&self) -> Result { - let (request, request_config, requested_room_unsubscriptions, mut position_guard) = - self.generate_sync_request(&mut LazyTransactionId::new()).await?; - + /// Send a sliding sync request. + /// + /// This method contains the sending logic. It takes a generic `Request` + /// because it can be a Simplified MSC3575 or a MSC3575 `Request`. + async fn send_sync_request( + &self, + request: Request, + request_config: RequestConfig, + mut position_guard: OwnedMutexGuard, + ) -> Result + where + Request: OutgoingRequest + Clone + Debug + Send + Sync + 'static, + Request::IncomingResponse: Send + + Sync + + + // This is required to get back a Simplified MSC3575 `Response` whatever the + // `Request` type. + Into, + HttpError: From>, + { debug!("Sending request"); // Prepare the request. @@ -644,6 +641,12 @@ impl SlidingSync { #[cfg(not(feature = "e2e-encryption"))] let response = request.await?; + // The code manipulates `Request` and `Response` from Simplified MSC3575 because + // it's the future standard. But this function may have received a `Request` + // from Simplified MSC3575 or MSC3575. We need to get back a + // Simplified MSC3575 `Response`. + let response = Into::::into(response); + debug!("Received response"); // At this point, the request has been sent, and a response has been received. @@ -694,6 +697,46 @@ impl SlidingSync { spawn(future.instrument(Span::current())).await.unwrap() } + /// Is the e2ee extension enabled for this sliding sync instance? + #[cfg(feature = "e2e-encryption")] + fn is_e2ee_enabled(&self) -> bool { + self.inner.sticky.read().unwrap().data().extensions.e2ee.enabled == Some(true) + } + + #[cfg(not(feature = "e2e-encryption"))] + fn is_e2ee_enabled(&self) -> bool { + false + } + + /// Should we process the room's subpart of a response? + async fn must_process_rooms_response(&self) -> bool { + // We consider that we must, if there's any room subscription or there's any + // list. + !self.inner.sticky.read().unwrap().data().room_subscriptions.is_empty() + || !self.inner.lists.read().await.is_empty() + } + + #[instrument(skip_all, fields(pos))] + async fn sync_once(&self) -> Result { + let (request, request_config, position_guard) = + self.generate_sync_request(&mut LazyTransactionId::new()).await?; + + // The code manipulates `Request` and `Response` from Simplified MSC3575 + // because it's the future standard. If + // `Client::is_simplified_sliding_sync_enabled` is turned off, the + // Simplified MSC3575 `Request` must be transformed into a MSC3575 `Request`. + if !self.inner.client.is_simplified_sliding_sync_enabled() { + self.send_sync_request( + Into::::into(request), + request_config, + position_guard, + ) + .await + } else { + self.send_sync_request(request, request_config, position_guard).await + } + } + /// Create a _new_ Sliding Sync sync loop. /// /// This method returns a `Stream`, which will send requests and will handle From b0466971c7ba3809a53d4e96a572554a36f635ee Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 14:54:11 +0200 Subject: [PATCH 05/11] feat(sdk): Remove `SlidingSync::unsubscribe_from_room`. Simplified sliding sync no longer has the concept of unsubscribing from a room. This patch removes this API. --- bindings/matrix-sdk-ffi/src/room_list.rs | 4 - .../src/room_list_service/room.rs | 7 -- .../tests/integration/room_list_service.rs | 22 ----- crates/matrix-sdk/src/sliding_sync/README.md | 6 -- crates/matrix-sdk/src/sliding_sync/builder.rs | 1 - crates/matrix-sdk/src/sliding_sync/mod.rs | 97 +++---------------- labs/multiverse/src/main.rs | 6 +- 7 files changed, 18 insertions(+), 125 deletions(-) diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index 5198cb02e84..a325289f47e 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -653,10 +653,6 @@ impl RoomListItem { self.inner.subscribe(settings.map(Into::into)); } - fn unsubscribe(&self) { - self.inner.unsubscribe(); - } - async fn latest_event(&self) -> Option> { self.inner.latest_event().await.map(EventTimelineItem).map(Arc::new) } diff --git a/crates/matrix-sdk-ui/src/room_list_service/room.rs b/crates/matrix-sdk-ui/src/room_list_service/room.rs index 99651d52b60..bc28a8f1bc5 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room.rs @@ -109,13 +109,6 @@ impl Room { .subscribe_to_room(self.inner.room.room_id().to_owned(), Some(settings)) } - /// Unsubscribe to this room. - /// - /// It's the opposite method of [Self::subscribe`]. - pub fn unsubscribe(&self) { - self.inner.sliding_sync.unsubscribe_from_room(self.inner.room.room_id().to_owned()) - } - /// Get the timeline of the room if one exists. pub fn timeline(&self) -> Option> { self.inner.timeline.get().cloned() diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index 15638a26e05..d5e28773b59 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -2140,28 +2140,6 @@ async fn test_room_subscription() -> Result<(), Error> { }, }; - // Unsubscribe. - - room1.unsubscribe(); - room_list.room(room_id_2)?.unsubscribe(); // unsubscribe from a room that has no subscription. - - sync_then_assert_request_and_fake_response! { - [server, room_list, sync] - assert request >= { - "lists": { - ALL_ROOMS: { - "ranges": [[0, 2]], - }, - }, - "unsubscribe_rooms": [room_id_1, /* `room_id_2` is absent */], - }, - respond with = { - "pos": "2", - "lists": {}, - "rooms": {}, - }, - }; - Ok(()) } diff --git a/crates/matrix-sdk/src/sliding_sync/README.md b/crates/matrix-sdk/src/sliding_sync/README.md index 1e46b18b739..95893b235bf 100644 --- a/crates/matrix-sdk/src/sliding_sync/README.md +++ b/crates/matrix-sdk/src/sliding_sync/README.md @@ -145,12 +145,6 @@ visible in any list. The most common case for using this API is when the user enters a room - as we want to receive the incoming new messages regardless of whether the room is pushed out of the lists room list. -### Unsubscribe - -Don't forget to [unsubscribe](`SlidingSync::unsubscribe_from_room`) when the -data isn't needed to be updated anymore, e.g. when the user leaves the room, to -reduce the bandwidth back down to what is really needed. - ## Extensions Additionally to the room list and rooms with their state and latest diff --git a/crates/matrix-sdk/src/sliding_sync/builder.rs b/crates/matrix-sdk/src/sliding_sync/builder.rs index a3cc3776511..83855bf4f26 100644 --- a/crates/matrix-sdk/src/sliding_sync/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/builder.rs @@ -296,7 +296,6 @@ impl SlidingSyncBuilder { self.extensions.unwrap_or_default(), ), )), - room_unsubscriptions: Default::default(), internal_channel: internal_channel_sender, diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index 5d9883c7fb3..fb79852a354 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -25,7 +25,7 @@ mod sticky_parameters; mod utils; use std::{ - collections::{BTreeMap, BTreeSet, HashSet}, + collections::{BTreeMap, HashSet}, fmt::Debug, future::Future, sync::{Arc, RwLock as StdRwLock}, @@ -127,9 +127,6 @@ pub(super) struct SlidingSyncInner { /// Request parameters that are sticky. sticky: StdRwLock>, - /// Rooms to unsubscribe, see [`Self::room_subscriptions`]. - room_unsubscriptions: StdRwLock>, - /// Internal channel used to pass messages between Sliding Sync and other /// types. internal_channel: Sender, @@ -171,26 +168,6 @@ impl SlidingSync { ); } - /// Unsubscribe from a given room. - pub fn unsubscribe_from_room(&self, room_id: OwnedRoomId) { - // Note: we don't use `BTreeMap::remove` here, because that would require - // mutable access thus calling `data_mut()`, which in turn would - // invalidate the sticky parameters even if the `room_id` wasn't in the - // mapping. - - // If there's a subscription… - if self.inner.sticky.read().unwrap().data().room_subscriptions.contains_key(&room_id) { - // Remove it… - self.inner.sticky.write().unwrap().data_mut().room_subscriptions.remove(&room_id); - // … then keep the unsubscription for the next request. - self.inner.room_unsubscriptions.write().unwrap().insert(room_id); - - self.inner.internal_channel_send_if_possible( - SlidingSyncInternalMessage::SyncLoopSkipOverCurrentIteration, - ); - } - } - /// Lookup a specific room pub async fn get_room(&self, room_id: &RoomId) -> Option { self.inner.rooms.read().await.get(room_id).cloned() @@ -459,12 +436,7 @@ impl SlidingSync { async fn generate_sync_request( &self, txn_id: &mut LazyTransactionId, - ) -> Result<( - v4::Request, - RequestConfig, - BTreeSet, - OwnedMutexGuard, - )> { + ) -> Result<(v4::Request, RequestConfig, OwnedMutexGuard)> { // Collect requests for lists. let mut requests_lists = BTreeMap::new(); @@ -519,16 +491,12 @@ impl SlidingSync { Span::current().record("pos", &pos); - // Collect other data. - let room_unsubscriptions = self.inner.room_unsubscriptions.read().unwrap().clone(); - let mut request = assign!(v4::Request::new(), { conn_id: Some(self.inner.id.clone()), delta_token, pos, timeout: Some(self.inner.poll_timeout), lists: requests_lists, - unsubscribe_rooms: room_unsubscriptions.iter().cloned().collect(), }); // Apply sticky parameters, if needs be. @@ -551,7 +519,6 @@ impl SlidingSync { // Configure long-polling. We need some time for the long-poll itself, // and extra time for the network delays. RequestConfig::default().timeout(self.inner.poll_timeout + self.inner.network_timeout), - room_unsubscriptions, position_guard, )) } @@ -669,17 +636,6 @@ impl SlidingSync { // ensure responses are handled one at a time. At this point we still own // `position_guard`, so we're fine. - // Room unsubscriptions have been received by the server. We can update the - // unsubscriptions buffer. However, it would be an error to empty it entirely as - // more unsubscriptions could have been inserted during the request/response - // dance. So let's cherry-pick which unsubscriptions to remove. - if !requested_room_unsubscriptions.is_empty() { - let room_unsubscriptions = &mut *this.inner.room_unsubscriptions.write().unwrap(); - - room_unsubscriptions - .retain(|room_id| !requested_room_unsubscriptions.contains(room_id)); - } - // Handle the response. let updates = this.handle_response(response, &mut position_guard).await?; @@ -1233,27 +1189,6 @@ mod tests { assert!(!room_subscriptions.contains_key(&room_id_2.to_owned())); } - sliding_sync.unsubscribe_from_room(room_id_0.to_owned()); - sliding_sync.unsubscribe_from_room(room_id_2.to_owned()); - - { - let sticky = sliding_sync.inner.sticky.read().unwrap(); - let room_subscriptions = &sticky.data().room_subscriptions; - - assert!(!room_subscriptions.contains_key(&room_id_0.to_owned())); - assert!(room_subscriptions.contains_key(&room_id_1.to_owned())); - assert!(!room_subscriptions.contains_key(&room_id_2.to_owned())); - - let room_unsubscriptions = sliding_sync.inner.room_unsubscriptions.read().unwrap(); - - assert!(room_unsubscriptions.contains(&room_id_0.to_owned())); - assert!(!room_unsubscriptions.contains(&room_id_1.to_owned())); - assert!(!room_unsubscriptions.contains(&room_id_2.to_owned())); - } - - // this test also ensures that Tokio is not panicking when calling - // `subscribe_to_room` and `unsubscribe_from_room`. - Ok(()) } @@ -1429,7 +1364,7 @@ mod tests { // Even without a since token, the first request will contain the extensions // configuration, at least. let txn_id = TransactionId::new(); - let (request, _, _, _) = sync + let (request, _, _) = sync .generate_sync_request(&mut LazyTransactionId::from_owned(txn_id.to_owned())) .await?; @@ -1449,7 +1384,7 @@ mod tests { // Regenerating a request will yield the same one. let txn_id2 = TransactionId::new(); - let (request, _, _, _) = sync + let (request, _, _) = sync .generate_sync_request(&mut LazyTransactionId::from_owned(txn_id2.to_owned())) .await?; @@ -1469,7 +1404,7 @@ mod tests { // The next request should contain no sticky parameters. let txn_id = TransactionId::new(); - let (request, _, _, _) = sync + let (request, _, _) = sync .generate_sync_request(&mut LazyTransactionId::from_owned(txn_id.to_owned())) .await?; assert!(request.extensions.e2ee.enabled.is_none()); @@ -1496,7 +1431,7 @@ mod tests { } let txn_id = TransactionId::new(); - let (request, _, _, _) = sync + let (request, _, _) = sync .generate_sync_request(&mut LazyTransactionId::from_owned(txn_id.to_owned())) .await?; @@ -1521,7 +1456,7 @@ mod tests { .await?; // First request asks to enable the extension. - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.extensions.to_device.enabled.is_some()); @@ -1563,7 +1498,7 @@ mod tests { } // Next request doesn't ask to enable the extension. - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.extensions.to_device.enabled.is_none()); @@ -1666,7 +1601,7 @@ mod tests { assert!(sliding_sync.inner.past_positions.read().unwrap().is_empty()); // Next request asks to enable the extension again. - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.extensions.to_device.enabled.is_some()); @@ -1716,7 +1651,7 @@ mod tests { { assert!(sliding_sync.inner.position.lock().await.pos.is_none()); - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.pos.is_none()); } @@ -1758,7 +1693,7 @@ mod tests { // It's still 0, not "yolo". { assert_eq!(sliding_sync.inner.position.lock().await.pos.as_deref(), Some("0")); - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert_eq!(request.pos.as_deref(), Some("0")); } @@ -1809,7 +1744,7 @@ mod tests { // `pos` is `None` to start with. { - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.pos.is_none()); @@ -1850,7 +1785,7 @@ mod tests { // It's alright, the next request will load it from the database. { - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert_eq!(request.pos.as_deref(), Some("42")); assert_eq!(sliding_sync.inner.position.lock().await.pos.as_deref(), Some("42")); @@ -1861,7 +1796,7 @@ mod tests { let sliding_sync = client.sliding_sync("elephant-sync")?.share_pos().build().await?; assert_eq!(sliding_sync.inner.position.lock().await.pos.as_deref(), Some("42")); - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert_eq!(request.pos.as_deref(), Some("42")); } @@ -1873,7 +1808,7 @@ mod tests { { assert!(sliding_sync.inner.position.lock().await.pos.is_none()); - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.pos.is_none()); } @@ -1883,7 +1818,7 @@ mod tests { let sliding_sync = client.sliding_sync("elephant-sync")?.share_pos().build().await?; assert!(sliding_sync.inner.position.lock().await.pos.is_none()); - let (request, _, _, _) = + let (request, _, _) = sliding_sync.generate_sync_request(&mut LazyTransactionId::new()).await?; assert!(request.pos.is_none()); } diff --git a/labs/multiverse/src/main.rs b/labs/multiverse/src/main.rs index 48d852822b9..db7c765b8c9 100644 --- a/labs/multiverse/src/main.rs +++ b/labs/multiverse/src/main.rs @@ -390,10 +390,8 @@ impl App { } fn subscribe_to_selected_room(&mut self, selected: usize) { - // Delete the subscription to the previous room, if any. - if let Some(room) = self.current_room_subscription.take() { - room.unsubscribe(); - } + // Cancel the subscription to the previous room, if any. + self.current_room_subscription.take(); // Subscribe to the new room. if let Some(room) = self From b6ff5a12d0b7cc5f032f06748dc10feee74d7305 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 15:05:25 +0200 Subject: [PATCH 06/11] feat(base): Rename `recency_timestamp` to `recency_stamp`. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch renames “recency timestamp” to “recency stamp”. It prepares the fact that simplified sliding sync has a `bump_stamp` instead of a `timestamp`. The notion of _timestamp_ must be removed. --- crates/matrix-sdk-base/src/rooms/normal.rs | 32 +++++----- .../matrix-sdk-base/src/sliding_sync/mod.rs | 62 ++++++++----------- .../src/store/migration_helpers.rs | 2 +- .../src/room_list_service/room_list.rs | 2 +- .../src/room_list_service/sorters/recency.rs | 57 +++++++---------- 5 files changed, 68 insertions(+), 87 deletions(-) diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index c84636cf894..ddb50f06f9c 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -91,8 +91,8 @@ bitflags! { /// The reason why a [`RoomInfoNotableUpdate`] is emitted. #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub struct RoomInfoNotableUpdateReasons: u8 { - /// The recency timestamp of the `Room` has changed. - const RECENCY_TIMESTAMP = 0b0000_0001; + /// The recency stamp of the `Room` has changed. + const RECENCY_STAMP = 0b0000_0001; /// The latest event of the `Room` has changed. const LATEST_EVENT = 0b0000_0010; @@ -940,12 +940,12 @@ impl Room { self.inner.read().base_info.is_marked_unread } - /// Returns the recency timestamp of the room. + /// Returns the recency stamp of the room. /// - /// Please read `RoomInfo::recency_timestamp` to learn more. + /// Please read `RoomInfo::recency_stamp` to learn more. #[cfg(feature = "experimental-sliding-sync")] - pub fn recency_timestamp(&self) -> Option { - self.inner.read().recency_timestamp + pub fn recency_stamp(&self) -> Option { + self.inner.read().recency_stamp } } @@ -1006,15 +1006,15 @@ pub struct RoomInfo { #[serde(default, skip_serializing_if = "Option::is_none")] pub(crate) cached_display_name: Option, - /// The recency timestamp of this room. + /// The recency stamp of this room. /// /// It's not to be confused with `origin_server_ts` of the latest event. /// Sliding Sync might "ignore” some events when computing the recency - /// timestamp of the room. Thus, using this `recency_timestamp` value is + /// stamp of the room. Thus, using this `recency_stamp` value is /// more accurate than relying on the latest event. #[cfg(feature = "experimental-sliding-sync")] #[serde(default)] - pub(crate) recency_timestamp: Option, + pub(crate) recency_stamp: Option, } #[derive(Clone, Debug, Serialize, Deserialize, PartialEq, Eq)] @@ -1053,7 +1053,7 @@ impl RoomInfo { warned_about_unknown_room_version: Arc::new(false.into()), cached_display_name: None, #[cfg(feature = "experimental-sliding-sync")] - recency_timestamp: None, + recency_stamp: None, } } @@ -1459,12 +1459,12 @@ impl RoomInfo { self.latest_event.as_deref() } - /// Updates the recency timestamp of this room. + /// Updates the recency stamp of this room. /// - /// Please read [`Self::recency_timestamp`] to learn more. + /// Please read [`Self::recency_stamp`] to learn more. #[cfg(feature = "experimental-sliding-sync")] - pub(crate) fn update_recency_timestamp(&mut self, timestamp: MilliSecondsSinceUnixEpoch) { - self.recency_timestamp = Some(timestamp); + pub(crate) fn update_recency_stamp(&mut self, stamp: u64) { + self.recency_stamp = Some(stamp); } } @@ -1675,7 +1675,7 @@ mod tests { read_receipts: Default::default(), warned_about_unknown_room_version: Arc::new(false.into()), cached_display_name: None, - recency_timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), + recency_stamp: Some(42), }; let info_json = json!({ @@ -1728,7 +1728,7 @@ mod tests { "latest_active": null, "pending": [] }, - "recency_timestamp": 42, + "recency_stamp": 42, }); assert_eq!(serde_json::to_value(info).unwrap(), info_json); diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index a69ba08fc38..c20d270d76d 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -29,7 +29,7 @@ use ruma::{ }, events::{AnyRoomAccountDataEvent, AnySyncStateEvent, AnySyncTimelineEvent}, serde::Raw, - JsOption, OwnedRoomId, RoomId, + JsOption, MilliSecondsSinceUnixEpoch, OwnedRoomId, RoomId, }; use tracing::{instrument, trace, warn}; @@ -768,18 +768,20 @@ fn process_room_properties( room_info.mark_members_missing(); } - if let Some(recency_timestamp) = &room_data.timestamp { - if room_info.recency_timestamp.as_ref() != Some(recency_timestamp) { - room_info.update_recency_timestamp(*recency_timestamp); + if let Some(MilliSecondsSinceUnixEpoch(recency_stamp)) = &room_data.timestamp { + let recency_stamp: u64 = (*recency_stamp).into(); - // If it's not a new room, let's emit a `RECENCY_TIMESTAMP` update. + if room_info.recency_stamp != Some(recency_stamp) { + room_info.update_recency_stamp(recency_stamp); + + // If it's not a new room, let's emit a `RECENCY_STAMP` update. // For a new room, the room will appear as new, so we don't care about this // update. if !is_new_room { room_info_notable_updates .entry(room_id.to_owned()) .or_default() - .insert(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP); + .insert(RoomInfoNotableUpdateReasons::RECENCY_STAMP); } } } @@ -812,8 +814,7 @@ mod tests { }, mxc_uri, owned_mxc_uri, owned_user_id, room_alias_id, room_id, serde::Raw, - uint, user_id, JsOption, MilliSecondsSinceUnixEpoch, MxcUri, OwnedRoomId, OwnedUserId, - RoomAliasId, RoomId, UserId, + uint, user_id, JsOption, MxcUri, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, UserId, }; use serde_json::json; @@ -1790,59 +1791,53 @@ mod tests { } #[async_test] - async fn test_recency_timestamp_is_found_when_processing_sliding_sync_response() { + async fn test_recency_stamp_is_found_when_processing_sliding_sync_response() { // Given a logged-in client let client = logged_in_base_client(None).await; let room_id = room_id!("!r:e.uk"); - // When I send sliding sync response containing a room with a recency timestamp + // When I send sliding sync response containing a room with a recency stamp let room = assign!(v4::SlidingSyncRoom::new(), { timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); - // Then the room in the client has the recency timestamp + // Then the room in the client has the recency stamp let client_room = client.get_room(room_id).expect("No room found"); - assert_eq!(client_room.recency_timestamp().expect("No recency timestamp").0, 42u32.into()); + assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42); } #[async_test] - async fn test_recency_timestamp_can_be_overwritten_when_present_in_a_sliding_sync_response() { + async fn test_recency_stamp_can_be_overwritten_when_present_in_a_sliding_sync_response() { // Given a logged-in client let client = logged_in_base_client(None).await; let room_id = room_id!("!r:e.uk"); { - // When I send sliding sync response containing a room with a recency timestamp + // When I send sliding sync response containing a room with a recency stamp let room = assign!(v4::SlidingSyncRoom::new(), { timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); - // Then the room in the client has the recency timestamp + // Then the room in the client has the recency stamp let client_room = client.get_room(room_id).expect("No room found"); - assert_eq!( - client_room.recency_timestamp().expect("No recency timestamp").0, - 42u32.into() - ); + assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42); } { - // When I send sliding sync response containing a room with NO recency timestamp + // When I send sliding sync response containing a room with NO recency stamp let room = assign!(v4::SlidingSyncRoom::new(), { timestamp: None, }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); - // Then the room in the client has the previous recency timestamp + // Then the room in the client has the previous recency stamp let client_room = client.get_room(room_id).expect("No room found"); - assert_eq!( - client_room.recency_timestamp().expect("No recency timestamp").0, - 42u32.into() - ); + assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 42); } { @@ -1854,23 +1849,20 @@ mod tests { let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); - // Then the room in the client has the recency timestamp + // Then the room in the client has the recency stamp let client_room = client.get_room(room_id).expect("No room found"); - assert_eq!( - client_room.recency_timestamp().expect("No recency timestamp").0, - 153u32.into() - ); + assert_eq!(client_room.recency_stamp().expect("No recency stamp"), 153); } } #[async_test] - async fn test_recency_timestamp_can_trigger_a_notable_update_reason() { + async fn test_recency_stamp_can_trigger_a_notable_update_reason() { // Given a logged-in client let client = logged_in_base_client(None).await; let mut room_info_notable_update_stream = client.room_info_notable_update_receiver(); let room_id = room_id!("!r:e.uk"); - // When I send sliding sync response containing a room with a recency timestamp. + // When I send sliding sync response containing a room with a recency stamp. let room = assign!(v4::SlidingSyncRoom::new(), { timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), }); @@ -1883,11 +1875,11 @@ mod tests { room_info_notable_update_stream.recv().await, Ok(RoomInfoNotableUpdate { room_id: received_room_id, reasons: received_reasons }) => { assert_eq!(received_room_id, room_id); - assert!(!received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP)); + assert!(!received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_STAMP)); } ); - // When I send sliding sync response containing a room with a recency timestamp. + // When I send sliding sync response containing a room with a recency stamp. let room = assign!(v4::SlidingSyncRoom::new(), { timestamp: Some(MilliSecondsSinceUnixEpoch(43u32.into())), }); @@ -1899,7 +1891,7 @@ mod tests { room_info_notable_update_stream.recv().await, Ok(RoomInfoNotableUpdate { room_id: received_room_id, reasons: received_reasons }) => { assert_eq!(received_room_id, room_id); - assert!(received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_TIMESTAMP)); + assert!(received_reasons.contains(RoomInfoNotableUpdateReasons::RECENCY_STAMP)); } ); } diff --git a/crates/matrix-sdk-base/src/store/migration_helpers.rs b/crates/matrix-sdk-base/src/store/migration_helpers.rs index f4b611b40d1..fc2332fd7ca 100644 --- a/crates/matrix-sdk-base/src/store/migration_helpers.rs +++ b/crates/matrix-sdk-base/src/store/migration_helpers.rs @@ -126,7 +126,7 @@ impl RoomInfoV1 { warned_about_unknown_room_version: Arc::new(false.into()), cached_display_name: None, #[cfg(feature = "experimental-sliding-sync")] - recency_timestamp: None, + recency_stamp: None, } } } diff --git a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs index 75cb2fabbd0..f7228ce95dd 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room_list.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room_list.rs @@ -222,7 +222,7 @@ fn merge_stream_and_receiver( // We are interested by these _reasons_. if reasons.contains(NotableUpdate::LATEST_EVENT) || - reasons.contains(NotableUpdate::RECENCY_TIMESTAMP) || + reasons.contains(NotableUpdate::RECENCY_STAMP) || reasons.contains(NotableUpdate::READ_RECEIPT) || reasons.contains(NotableUpdate::UNREAD_MARKER) { // Emit a `VectorDiff::Set` for the specific rooms. diff --git a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs index 205c582e689..c70ebb3ce2a 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs @@ -14,20 +14,18 @@ use std::cmp::Ordering; -use ruma::MilliSecondsSinceUnixEpoch; - use super::{Room, Sorter}; struct RecencyMatcher where - F: Fn(&Room, &Room) -> (Option, Option), + F: Fn(&Room, &Room) -> (Option, Option), { - timestamps: F, + recency_stamps: F, } impl RecencyMatcher where - F: Fn(&Room, &Room) -> (Option, Option), + F: Fn(&Room, &Room) -> (Option, Option), { fn matches(&self, left: &Room, right: &Room) -> Ordering { if left.id() == right.id() { @@ -51,7 +49,7 @@ where return Ordering::Greater; } - match (self.timestamps)(left, right) { + match (self.recency_stamps)(left, right) { (Some(left_timestamp), Some(right_timestamp)) => { left_timestamp.cmp(&right_timestamp).reverse() } @@ -66,11 +64,11 @@ where } /// Create a new sorter that will sort two [`Room`] by recency, i.e. by -/// comparing their [`matrix_sdk_base::RoomInfo::recency_timestamp`] value. The -/// `Room` with the newest recency timestamp comes first, i.e. newest < oldest. +/// comparing their [`matrix_sdk_base::RoomInfo::recency_stamp`] value. The +/// `Room` with the newest recency stamp comes first, i.e. newest < oldest. pub fn new_sorter() -> impl Sorter { let matcher = RecencyMatcher { - timestamps: move |left, right| (left.recency_timestamp(), right.recency_timestamp()), + recency_stamps: move |left, right| (left.recency_stamp(), right.recency_stamp()), }; move |left, right| -> Ordering { matcher.matches(left, right) } @@ -79,85 +77,76 @@ pub fn new_sorter() -> impl Sorter { #[cfg(test)] mod tests { use matrix_sdk_test::async_test; - use ruma::{room_id, MilliSecondsSinceUnixEpoch, UInt}; + use ruma::room_id; use super::{ super::super::filters::{client_and_server_prelude, new_rooms}, *, }; - macro_rules! ms { - ($value:literal) => { - MilliSecondsSinceUnixEpoch(UInt::new_wrapping($value)) - }; - } - #[async_test] - async fn test_with_two_recency_timestamps() { + async fn test_with_two_recency_stamps() { let (client, server, sliding_sync) = client_and_server_prelude().await; let [room_a, room_b] = new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) .await; - // `room_a` has an older recency timestamp than `room_b`. + // `room_a` has an older recency stamp than `room_b`. { - let matcher = - RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), Some(ms!(2))) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), Some(2)) }; // `room_a` is greater than `room_b`, i.e. it must come after `room_b`. assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Greater); } - // `room_b` has an older recency timestamp than `room_a`. + // `room_b` has an older recency stamp than `room_a`. { - let matcher = - RecencyMatcher { timestamps: |_left, _right| (Some(ms!(2)), Some(ms!(1))) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(2), Some(1)) }; // `room_a` is less than `room_b`, i.e. it must come before `room_b`. assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Less); } - // `room_a` has an equally old recency timestamp than `room_b`. + // `room_a` has an equally old recency stamp than `room_b`. { - let matcher = - RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), Some(ms!(1))) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), Some(1)) }; assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Equal); } } #[async_test] - async fn test_with_one_recency_timestamp() { + async fn test_with_one_recency_stamp() { let (client, server, sliding_sync) = client_and_server_prelude().await; let [room_a, room_b] = new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) .await; - // `room_a` has a recency timestamp, `room_b` has no recency timestamp. + // `room_a` has a recency stamp, `room_b` has no recency stamp. { - let matcher = RecencyMatcher { timestamps: |_left, _right| (Some(ms!(1)), None) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (Some(1), None) }; assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Less); } - // `room_a` has no recency timestamp, `room_b` has a recency timestamp. + // `room_a` has no recency stamp, `room_b` has a recency stamp. { - let matcher = RecencyMatcher { timestamps: |_left, _right| (None, Some(ms!(1))) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (None, Some(1)) }; assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Greater); } } #[async_test] - async fn test_with_zero_recency_timestamp() { + async fn test_with_zero_recency_stamp() { let (client, server, sliding_sync) = client_and_server_prelude().await; let [room_a, room_b] = new_rooms([room_id!("!a:b.c"), room_id!("!d:e.f")], &client, &server, &sliding_sync) .await; - // `room_a` and `room_b` has no recency timestamp. + // `room_a` and `room_b` has no recency stamp. { - let matcher = RecencyMatcher { timestamps: |_left, _right| (None, None) }; + let matcher = RecencyMatcher { recency_stamps: |_left, _right| (None, None) }; assert_eq!(matcher.matches(&room_a, &room_b), Ordering::Equal); } From 8c36b7d9592bf11ee616ef9e30b8e5f50aafa943 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 15:11:01 +0200 Subject: [PATCH 07/11] feat(ui): Remove `is_tombstoned` filter from sliding sync. Simplified sliding sync no longer has the `is_tombstoned` filter. This patch removes it. --- crates/matrix-sdk-ui/src/notification_client.rs | 1 - crates/matrix-sdk-ui/src/room_list_service/mod.rs | 1 - crates/matrix-sdk-ui/tests/integration/notification_client.rs | 1 - crates/matrix-sdk-ui/tests/integration/room_list_service.rs | 1 - 4 files changed, 4 deletions(-) diff --git a/crates/matrix-sdk-ui/src/notification_client.rs b/crates/matrix-sdk-ui/src/notification_client.rs index 64f475106e4..bb27b4582a3 100644 --- a/crates/matrix-sdk-ui/src/notification_client.rs +++ b/crates/matrix-sdk-ui/src/notification_client.rs @@ -360,7 +360,6 @@ impl NotificationClient { .required_state(required_state.clone()) .filters(Some(assign!(SyncRequestListFilters::default(), { is_invite: Some(true), - is_tombstoned: Some(false), not_room_types: vec!["m.space".to_owned()], }))) .sort(vec!["by_recency".to_owned(), "by_name".to_owned()]); diff --git a/crates/matrix-sdk-ui/src/room_list_service/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/mod.rs index 1309fa63cbe..855c72d7bba 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/mod.rs @@ -163,7 +163,6 @@ impl RoomListService { // If unset, both invited and joined rooms are returned. If false, no invited rooms are // returned. If true, only invited rooms are returned. is_invite: None, - is_tombstoned: Some(false), not_room_types: vec!["m.space".to_owned()], }))) .bump_event_types(&[ diff --git a/crates/matrix-sdk-ui/tests/integration/notification_client.rs b/crates/matrix-sdk-ui/tests/integration/notification_client.rs index 2d423e4dfe4..794d9ac4133 100644 --- a/crates/matrix-sdk-ui/tests/integration/notification_client.rs +++ b/crates/matrix-sdk-ui/tests/integration/notification_client.rs @@ -264,7 +264,6 @@ async fn test_notification_client_sliding_sync() { ], "filters": { "is_invite": true, - "is_tombstoned": false, "not_room_types": ["m.space"], }, "sort": ["by_recency", "by_name"], diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index d5e28773b59..49549f3c40e 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -331,7 +331,6 @@ async fn test_sync_all_states() -> Result<(), Error> { ], "include_heroes": true, "filters": { - "is_tombstoned": false, "not_room_types": ["m.space"], }, "bump_event_types": [ From 3bc88bcee263352ead5c9008a7a713bfb32536bc Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 15:18:07 +0200 Subject: [PATCH 08/11] feat(sdk): Remove `sort` and `bump_event_types` from sliding sync. Simplified sliding sync no longer has `sort` or `bump_event_types` because they are static values on the implementation/server side. This patch removes them here. --- .../matrix-sdk-ui/src/notification_client.rs | 3 +- .../src/room_list_service/mod.rs | 8 +----- .../tests/integration/notification_client.rs | 1 - .../tests/integration/room_list_service.rs | 6 ---- .../src/sliding_sync/list/builder.rs | 28 ------------------- .../src/sliding_sync/list/sticky.rs | 12 +------- crates/matrix-sdk/src/sliding_sync/mod.rs | 2 -- 7 files changed, 3 insertions(+), 57 deletions(-) diff --git a/crates/matrix-sdk-ui/src/notification_client.rs b/crates/matrix-sdk-ui/src/notification_client.rs index bb27b4582a3..f95895ba5fd 100644 --- a/crates/matrix-sdk-ui/src/notification_client.rs +++ b/crates/matrix-sdk-ui/src/notification_client.rs @@ -361,8 +361,7 @@ impl NotificationClient { .filters(Some(assign!(SyncRequestListFilters::default(), { is_invite: Some(true), not_room_types: vec!["m.space".to_owned()], - }))) - .sort(vec!["by_recency".to_owned(), "by_name".to_owned()]); + }))); let sync = self .client diff --git a/crates/matrix-sdk-ui/src/room_list_service/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/mod.rs index 855c72d7bba..2ebbfa9fdc2 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/mod.rs @@ -156,7 +156,6 @@ impl RoomListService { (StateEventType::RoomName, "".to_owned()), (StateEventType::RoomPowerLevels, "".to_owned()), ]) - .sort(vec!["by_recency".to_owned(), "by_name".to_owned()]) .include_heroes(Some(true)) .filters(Some(assign!(SyncRequestListFilters::default(), { // As defined in the [SlidingSync MSC](https://github.com/matrix-org/matrix-spec-proposals/blob/9450ced7fb9cf5ea9077d029b3adf36aebfa8709/proposals/3575-sync.md?plain=1#L444) @@ -164,12 +163,7 @@ impl RoomListService { // returned. If true, only invited rooms are returned. is_invite: None, not_room_types: vec!["m.space".to_owned()], - }))) - .bump_event_types(&[ - TimelineEventType::RoomMessage, - TimelineEventType::RoomEncrypted, - TimelineEventType::Sticker, - ]), + }))), ) .await .map_err(Error::SlidingSync)? diff --git a/crates/matrix-sdk-ui/tests/integration/notification_client.rs b/crates/matrix-sdk-ui/tests/integration/notification_client.rs index 794d9ac4133..c47363b902a 100644 --- a/crates/matrix-sdk-ui/tests/integration/notification_client.rs +++ b/crates/matrix-sdk-ui/tests/integration/notification_client.rs @@ -266,7 +266,6 @@ async fn test_notification_client_sliding_sync() { "is_invite": true, "not_room_types": ["m.space"], }, - "sort": ["by_recency", "by_name"], "timeline_limit": 8, } }, diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index 49549f3c40e..93145c02ba2 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -333,12 +333,6 @@ async fn test_sync_all_states() -> Result<(), Error> { "filters": { "not_room_types": ["m.space"], }, - "bump_event_types": [ - "m.room.message", - "m.room.encrypted", - "m.sticker", - ], - "sort": ["by_recency", "by_name"], "timeline_limit": 1, }, }, diff --git a/crates/matrix-sdk/src/sliding_sync/list/builder.rs b/crates/matrix-sdk/src/sliding_sync/list/builder.rs index e76ddd21912..cfc9329492c 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/builder.rs @@ -36,7 +36,6 @@ struct SlidingSyncListCachedData { #[derive(Clone)] pub struct SlidingSyncListBuilder { sync_mode: SlidingSyncMode, - sort: Vec, required_state: Vec<(StateEventType, String)>, include_heroes: Option, filters: Option, @@ -51,8 +50,6 @@ pub struct SlidingSyncListBuilder { reloaded_cached_data: Option, once_built: Arc SlidingSyncList + Send + Sync>>, - - bump_event_types: Vec, } #[cfg(not(tarpaulin_include))] @@ -62,13 +59,11 @@ impl fmt::Debug for SlidingSyncListBuilder { formatter .debug_struct("SlidingSyncListBuilder") .field("sync_mode", &self.sync_mode) - .field("sort", &self.sort) .field("required_state", &self.required_state) .field("include_heroes", &self.include_heroes) .field("filters", &self.filters) .field("timeline_limit", &self.timeline_limit) .field("name", &self.name) - .field("bump_event_types", &self.bump_event_types) .finish_non_exhaustive() } } @@ -77,7 +72,6 @@ impl SlidingSyncListBuilder { pub(super) fn new(name: impl Into) -> Self { Self { sync_mode: SlidingSyncMode::default(), - sort: vec!["by_recency".to_owned(), "by_name".to_owned()], required_state: vec![ (StateEventType::RoomEncryption, "".to_owned()), (StateEventType::RoomTombstone, "".to_owned()), @@ -89,7 +83,6 @@ impl SlidingSyncListBuilder { reloaded_cached_data: None, cache_policy: SlidingSyncListCachePolicy::Disabled, once_built: Arc::new(Box::new(identity)), - bump_event_types: Vec::new(), } } @@ -112,12 +105,6 @@ impl SlidingSyncListBuilder { self } - /// Sort the room list by this. - pub fn sort(mut self, value: Vec) -> Self { - self.sort = value; - self - } - /// Required states to return per room. pub fn required_state(mut self, value: Vec<(StateEventType, String)>) -> Self { self.required_state = value; @@ -177,19 +164,6 @@ impl SlidingSyncListBuilder { } } - /// Allowlist of event types which should be considered recent activity - /// when sorting `by_recency`. - /// - /// By omitting event types, clients can ensure - /// that uninteresting events (e.g. a profile rename) do not cause a - /// room to jump to the top of its list(s). Empty or - /// omitted `bump_event_types` have no effect: all events in a room will - /// be considered recent activity. - pub fn bump_event_types(mut self, bump_event_types: &[TimelineEventType]) -> Self { - self.bump_event_types = bump_event_types.to_vec(); - self - } - /// Build the list. pub(in super::super) fn build( self, @@ -203,12 +177,10 @@ impl SlidingSyncListBuilder { // From the builder sticky: StdRwLock::new(SlidingSyncStickyManager::new( SlidingSyncListStickyParameters::new( - self.sort, self.required_state, self.include_heroes, self.filters, self.timeline_limit, - self.bump_event_types, ), )), name: self.name, diff --git a/crates/matrix-sdk/src/sliding_sync/list/sticky.rs b/crates/matrix-sdk/src/sliding_sync/list/sticky.rs index cd214f2f0a6..06c67f7b919 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/sticky.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/sticky.rs @@ -10,9 +10,6 @@ use crate::sliding_sync::sticky_parameters::StickyData; /// defined by the [Sliding Sync MSC](https://github.com/matrix-org/matrix-spec-proposals/blob/kegan/sync-v3/proposals/3575-sync.md). #[derive(Debug)] pub(super) struct SlidingSyncListStickyParameters { - /// Sort the room list by this. - sort: Vec, - /// Required states to return per room. required_state: Vec<(StateEventType, String)>, @@ -25,24 +22,18 @@ pub(super) struct SlidingSyncListStickyParameters { /// The maximum number of timeline events to query for. timeline_limit: Option, - - /// The `bump_event_types` field. See - /// [`SlidingSyncListBuilder::bump_event_types`] to learn more. - bump_event_types: Vec, } impl SlidingSyncListStickyParameters { pub fn new( - sort: Vec, required_state: Vec<(StateEventType, String)>, include_heroes: Option, filters: Option, timeline_limit: Option, - bump_event_types: Vec, ) -> Self { // Consider that each list will have at least one parameter set, so invalidate // it by default. - Self { sort, required_state, include_heroes, filters, timeline_limit, bump_event_types } + Self { required_state, include_heroes, filters, timeline_limit } } } @@ -65,6 +56,5 @@ impl StickyData for SlidingSyncListStickyParameters { request.room_details.timeline_limit = self.timeline_limit.map(Into::into); request.include_heroes = self.include_heroes; request.filters = self.filters.clone(); - request.bump_event_types = self.bump_event_types.clone(); } } diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index fb79852a354..ca69ef11701 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -2565,7 +2565,6 @@ mod tests { ["m.room.encryption", ""], ["m.room.tombstone", ""] ], - "sort": ["by_recency", "by_name"] }, "another-list": { "ranges": another_list_ranges, @@ -2573,7 +2572,6 @@ mod tests { ["m.room.encryption", ""], ["m.room.tombstone", ""] ], - "sort": ["by_recency", "by_name"] }, } }), From 9ccff87bb7928c7332324265b296d97de43b483e Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 15:21:56 +0200 Subject: [PATCH 09/11] feat(sdk) Remove `delta_token` from sliding sync. Simplified sliding sync doesn't have `delta_token`. This patch removes it. Note: even the current sliding sync proxy doesn't use it. --- crates/matrix-sdk/src/sliding_sync/builder.rs | 8 +++---- crates/matrix-sdk/src/sliding_sync/cache.rs | 20 ++-------------- crates/matrix-sdk/src/sliding_sync/mod.rs | 23 +++---------------- 3 files changed, 9 insertions(+), 42 deletions(-) diff --git a/crates/matrix-sdk/src/sliding_sync/builder.rs b/crates/matrix-sdk/src/sliding_sync/builder.rs index 83855bf4f26..328b9d848d9 100644 --- a/crates/matrix-sdk/src/sliding_sync/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/builder.rs @@ -252,15 +252,15 @@ impl SlidingSyncBuilder { let restored_fields = restore_sliding_sync_state(&client, &self.storage_key, &lists).await?; - let (delta_token, pos, rooms) = if let Some(fields) = restored_fields { + let (pos, rooms) = if let Some(fields) = restored_fields { #[cfg(feature = "e2e-encryption")] let pos = if self.share_pos { fields.pos } else { None }; #[cfg(not(feature = "e2e-encryption"))] let pos = None; - (fields.delta_token, pos, fields.rooms) + (pos, fields.rooms) } else { - (None, None, BTreeMap::new()) + (None, BTreeMap::new()) }; #[cfg(feature = "e2e-encryption")] @@ -286,7 +286,7 @@ impl SlidingSyncBuilder { lists, rooms, - position: Arc::new(AsyncMutex::new(SlidingSyncPositionMarkers { pos, delta_token })), + position: Arc::new(AsyncMutex::new(SlidingSyncPositionMarkers { pos })), // SAFETY: `unwrap` is safe because 20 is not zero. past_positions: StdRwLock::new(RingBuffer::new(NonZeroUsize::new(20).unwrap())), diff --git a/crates/matrix-sdk/src/sliding_sync/cache.rs b/crates/matrix-sdk/src/sliding_sync/cache.rs index e93e829eddc..97a03462100 100644 --- a/crates/matrix-sdk/src/sliding_sync/cache.rs +++ b/crates/matrix-sdk/src/sliding_sync/cache.rs @@ -88,10 +88,7 @@ pub(super) async fn store_sliding_sync_state( storage .set_custom_value( instance_storage_key.as_bytes(), - serde_json::to_vec(&FrozenSlidingSync::new( - position, - &*sliding_sync.inner.rooms.read().await, - ))?, + serde_json::to_vec(&FrozenSlidingSync::new(&*sliding_sync.inner.rooms.read().await))?, ) .await?; @@ -184,7 +181,6 @@ pub(super) async fn restore_sliding_sync_list( /// Fields restored during `restore_sliding_sync_state`. #[derive(Default)] pub(super) struct RestoredFields { - pub delta_token: Option, pub to_device_token: Option, pub pos: Option, pub rooms: BTreeMap, @@ -223,11 +219,7 @@ pub(super) async fn restore_sliding_sync_state( .map(|custom_value| serde_json::from_slice::(&custom_value)) { // `SlidingSync` has been found and successfully deserialized. - Some(Ok(FrozenSlidingSync { - to_device_since, - delta_token: frozen_delta_token, - rooms: frozen_rooms, - })) => { + Some(Ok(FrozenSlidingSync { to_device_since, rooms: frozen_rooms })) => { trace!("Successfully read the `SlidingSync` from the cache"); // Only update the to-device token if we failed to read it from the crypto store // above. @@ -235,8 +227,6 @@ pub(super) async fn restore_sliding_sync_state( restored_fields.to_device_token = to_device_since; } - restored_fields.delta_token = frozen_delta_token; - #[cfg(feature = "e2e-encryption")] { if let Some(olm_machine) = &*client.olm_machine().await { @@ -505,11 +495,9 @@ mod tests { assert!(state_store.get_custom_value(full_storage_key.as_bytes()).await?.is_none()); // Emulate some data to be cached. - let delta_token = "delta_token".to_owned(); let pos = "pos".to_owned(); { let mut position_guard = sliding_sync.inner.position.lock().await; - position_guard.delta_token = Some(delta_token.clone()); position_guard.pos = Some(pos.clone()); // Then, we can correctly cache the sliding sync instance. @@ -523,7 +511,6 @@ mod tests { state_store.get_custom_value(full_storage_key.as_bytes()).await?, Some(bytes) => { let deserialized: FrozenSlidingSync = serde_json::from_slice(&bytes)?; - assert_eq!(deserialized.delta_token, Some(delta_token.clone())); assert!(deserialized.to_device_since.is_none()); } ); @@ -536,7 +523,6 @@ mod tests { .expect("must have restored sliding sync fields"); // After restoring, the delta token and to-device token could be read. - assert_eq!(restored_fields.delta_token.unwrap(), delta_token); assert_eq!(restored_fields.pos.unwrap(), pos); // Test the "migration" path: assume a missing to-device token in crypto store, @@ -558,7 +544,6 @@ mod tests { full_storage_key.as_bytes(), serde_json::to_vec(&FrozenSlidingSync { to_device_since: Some(to_device_token.clone()), - delta_token: Some(delta_token.clone()), rooms: vec![FrozenSlidingSyncRoom { room_id: owned_room_id!("!r0:matrix.org"), prev_batch: Some("t0ken".to_owned()), @@ -574,7 +559,6 @@ mod tests { // After restoring, the delta token, the to-device since token, stream // position and rooms could be read from the state store. - assert_eq!(restored_fields.delta_token.unwrap(), delta_token); assert_eq!(restored_fields.to_device_token.unwrap(), to_device_token); assert_eq!(restored_fields.pos.unwrap(), pos); assert_eq!(restored_fields.rooms.len(), 1); diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index ca69ef11701..3a8d15265aa 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -424,7 +424,6 @@ impl SlidingSync { // // Save the new position markers. position.pos = pos; - position.delta_token = sliding_sync_response.delta_token.clone(); // Keep this position markers in memory, in case it pops from the server. let mut past_positions = self.inner.past_positions.write().unwrap(); @@ -448,7 +447,7 @@ impl SlidingSync { } } - // Collect the `pos` and `delta_token`. + // Collect the `pos`. // // Wait on the `position` mutex to be available. It means no request nor // response is running. The `position` mutex is released whether the response @@ -456,7 +455,6 @@ impl SlidingSync { // the response handling has failed, in this case the `pos` hasn't been updated // and the same `pos` will be used for this new request. let mut position_guard = self.inner.position.clone().lock_owned().await; - let delta_token = position_guard.delta_token.clone(); let to_device_enabled = self.inner.sticky.read().unwrap().data().extensions.to_device.enabled == Some(true); @@ -493,7 +491,6 @@ impl SlidingSync { let mut request = assign!(v4::Request::new(), { conn_id: Some(self.inner.id.clone()), - delta_token, pos, timeout: Some(self.inner.poll_timeout), lists: requests_lists, @@ -874,13 +871,6 @@ pub(super) struct SlidingSyncPositionMarkers { /// /// Should not be persisted. pos: Option, - - /// Server-provided opaque token that remembers what the last timeline and - /// state events stored by the client were. - /// - /// If `None`, the server will send the full information for all the lists - /// present in the request. - delta_token: Option, } /// Frozen bits of a Sliding Sync that are stored in the *state* store. @@ -889,20 +879,14 @@ struct FrozenSlidingSync { /// Deprecated: prefer storing in the crypto store. #[serde(skip_serializing_if = "Option::is_none")] to_device_since: Option, - #[serde(skip_serializing_if = "Option::is_none")] - delta_token: Option, #[serde(default, skip_serializing_if = "Vec::is_empty")] rooms: Vec, } impl FrozenSlidingSync { - fn new( - position: &SlidingSyncPositionMarkers, - rooms: &BTreeMap, - ) -> Self { + fn new(rooms: &BTreeMap) -> Self { // The to-device token must be saved in the `FrozenCryptoSlidingSync` now. Self { - delta_token: position.delta_token.clone(), to_device_since: None, rooms: rooms .iter() @@ -1200,8 +1184,7 @@ mod tests { // FrozenSlidingSync doesn't contain the to_device_token anymore, as it's saved // in the crypto store since PR #2323. - let position_guard = sliding_sync.inner.position.lock().await; - let frozen = FrozenSlidingSync::new(&position_guard, &Default::default()); + let frozen = FrozenSlidingSync::new(&*sliding_sync.inner.rooms.read().await); assert!(frozen.to_device_since.is_none()); Ok(()) From 7bbd4a8bea4e0360f90ad5461759eca1b7959a11 Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Wed, 17 Jul 2024 15:24:41 +0200 Subject: [PATCH 10/11] feat(ffi,base,ui,sdk): Migrate from sliding sync to simplified sliding sync. This patch migrates the entire SDK to sliding sync to simplified sliding sync. --- Cargo.lock | 1 + bindings/matrix-sdk-ffi/src/room_list.rs | 14 +- crates/matrix-sdk-base/src/lib.rs | 2 +- crates/matrix-sdk-base/src/rooms/normal.rs | 4 +- .../matrix-sdk-base/src/sliding_sync/http.rs | 1 + .../matrix-sdk-base/src/sliding_sync/mod.rs | 152 ++++++++--------- .../src/encryption_sync_service.rs | 7 +- .../matrix-sdk-ui/src/notification_client.rs | 10 +- .../src/room_list_service/mod.rs | 29 ++-- .../src/room_list_service/room.rs | 5 +- .../src/timeline/event_item/mod.rs | 13 +- .../tests/integration/notification_client.rs | 14 +- .../tests/integration/room_list_service.rs | 46 ++--- .../tests/integration/sliding_sync.rs | 2 +- .../integration/timeline/sliding_sync.rs | 2 +- crates/matrix-sdk/src/sliding_sync/README.md | 62 ++----- crates/matrix-sdk/src/sliding_sync/builder.rs | 36 ++-- crates/matrix-sdk/src/sliding_sync/client.rs | 13 +- .../src/sliding_sync/list/builder.rs | 10 +- .../matrix-sdk/src/sliding_sync/list/mod.rs | 15 +- .../src/sliding_sync/list/sticky.rs | 15 +- crates/matrix-sdk/src/sliding_sync/mod.rs | 157 +++++++++--------- crates/matrix-sdk/src/sliding_sync/room.rs | 21 +-- .../tests/integration/encryption/backups.rs | 2 +- .../matrix-sdk-integration-testing/Cargo.toml | 3 +- .../src/tests/sliding_sync/mod.rs | 4 +- .../src/tests/sliding_sync/room.rs | 16 +- 27 files changed, 313 insertions(+), 343 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 9fe47df6e4b..7a5e7b44327 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3465,6 +3465,7 @@ dependencies = [ "http 1.1.0", "json-structural-diff", "matrix-sdk", + "matrix-sdk-base", "matrix-sdk-test", "matrix-sdk-ui", "once_cell", diff --git a/bindings/matrix-sdk-ffi/src/room_list.rs b/bindings/matrix-sdk-ffi/src/room_list.rs index a325289f47e..f0e2f5ba607 100644 --- a/bindings/matrix-sdk-ffi/src/room_list.rs +++ b/bindings/matrix-sdk-ffi/src/room_list.rs @@ -2,12 +2,12 @@ use std::{fmt::Debug, mem::MaybeUninit, ptr::addr_of_mut, sync::Arc, time::Durat use eyeball_im::VectorDiff; use futures_util::{pin_mut, StreamExt, TryFutureExt}; -use matrix_sdk::ruma::{ - api::client::sync::sync_events::{ - v4::RoomSubscription as RumaRoomSubscription, - UnreadNotificationsCount as RumaUnreadNotificationsCount, +use matrix_sdk::{ + ruma::{ + api::client::sync::sync_events::UnreadNotificationsCount as RumaUnreadNotificationsCount, + assign, RoomId, }, - assign, RoomId, + sliding_sync::http, }; use matrix_sdk_ui::{ room_list_service::filters::{ @@ -671,9 +671,9 @@ pub struct RoomSubscription { pub include_heroes: Option, } -impl From for RumaRoomSubscription { +impl From for http::request::RoomSubscription { fn from(val: RoomSubscription) -> Self { - assign!(RumaRoomSubscription::default(), { + assign!(http::request::RoomSubscription::default(), { required_state: val.required_state.map(|r| r.into_iter().map(|s| (s.key.into(), s.value)).collect() ).unwrap_or_default(), diff --git a/crates/matrix-sdk-base/src/lib.rs b/crates/matrix-sdk-base/src/lib.rs index 997787a9085..1331c95177e 100644 --- a/crates/matrix-sdk-base/src/lib.rs +++ b/crates/matrix-sdk-base/src/lib.rs @@ -34,7 +34,7 @@ mod rooms; pub mod read_receipts; pub use read_receipts::PreviousEventsProvider; #[cfg(feature = "experimental-sliding-sync")] -mod sliding_sync; +pub mod sliding_sync; pub mod store; pub mod sync; diff --git a/crates/matrix-sdk-base/src/rooms/normal.rs b/crates/matrix-sdk-base/src/rooms/normal.rs index ddb50f06f9c..777be9ad83b 100644 --- a/crates/matrix-sdk-base/src/rooms/normal.rs +++ b/crates/matrix-sdk-base/src/rooms/normal.rs @@ -24,6 +24,8 @@ use bitflags::bitflags; use eyeball::{SharedObservable, Subscriber}; #[cfg(all(feature = "e2e-encryption", feature = "experimental-sliding-sync"))] use matrix_sdk_common::ring_buffer::RingBuffer; +#[cfg(feature = "experimental-sliding-sync")] +use ruma::events::AnySyncTimelineEvent; use ruma::{ api::client::sync::sync_events::v3::RoomSummary as RumaSummary, events::{ @@ -49,8 +51,6 @@ use ruma::{ EventId, MxcUri, OwnedEventId, OwnedMxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomVersionId, UserId, }; -#[cfg(feature = "experimental-sliding-sync")] -use ruma::{events::AnySyncTimelineEvent, MilliSecondsSinceUnixEpoch}; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast; use tracing::{debug, field::debug, info, instrument, warn}; diff --git a/crates/matrix-sdk-base/src/sliding_sync/http.rs b/crates/matrix-sdk-base/src/sliding_sync/http.rs index 0d4215fe2c2..ca2233a52db 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/http.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/http.rs @@ -42,6 +42,7 @@ pub mod msc3575 { } } +/// HTTP types from Simplified MSC3575. pub mod simplified_msc3575 { pub use ruma::api::client::sync::sync_events::v5::*; } diff --git a/crates/matrix-sdk-base/src/sliding_sync/mod.rs b/crates/matrix-sdk-base/src/sliding_sync/mod.rs index c20d270d76d..0b28e667a6b 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/mod.rs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! Extend `BaseClient` with capabilities to handle MSC3575. + pub mod http; use std::collections::BTreeMap; @@ -23,13 +25,10 @@ use matrix_sdk_common::deserialized_responses::SyncTimelineEvent; #[cfg(feature = "e2e-encryption")] use ruma::events::AnyToDeviceEvent; use ruma::{ - api::client::sync::sync_events::{ - v3::{self, InvitedRoom}, - v4, - }, + api::client::sync::sync_events::v3::{self, InvitedRoom}, events::{AnyRoomAccountDataEvent, AnySyncStateEvent, AnySyncTimelineEvent}, serde::Raw, - JsOption, MilliSecondsSinceUnixEpoch, OwnedRoomId, RoomId, + JsOption, OwnedRoomId, RoomId, }; use tracing::{instrument, trace, warn}; @@ -59,15 +58,16 @@ impl BaseClient { /// store. pub async fn process_sliding_sync_e2ee( &self, - extensions: &v4::Extensions, + extensions: &http::response::Extensions, ) -> Result>> { if extensions.is_empty() { return Ok(Default::default()); } - let v4::Extensions { to_device, e2ee, .. } = extensions; + let http::response::Extensions { to_device, e2ee, .. } = extensions; - let to_device_events = to_device.as_ref().map(|v4| v4.events.clone()).unwrap_or_default(); + let to_device_events = + to_device.as_ref().map(|to_device| to_device.events.clone()).unwrap_or_default(); trace!( to_device_events = to_device_events.len(), @@ -120,10 +120,10 @@ impl BaseClient { #[instrument(skip_all, level = "trace")] pub async fn process_sliding_sync( &self, - response: &v4::Response, + response: &http::Response, previous_events_provider: &PEP, ) -> Result { - let v4::Response { + let http::Response { // FIXME not yet supported by sliding sync. see // https://github.com/matrix-org/matrix-rust-sdk/issues/1014 // next_batch, @@ -339,7 +339,7 @@ impl BaseClient { async fn process_sliding_sync_room( &self, room_id: &RoomId, - room_data: &v4::SlidingSyncRoom, + room_data: &http::response::Room, rooms_account_data: &mut BTreeMap>>, store: &Store, changes: &mut StateChanges, @@ -493,7 +493,7 @@ impl BaseClient { /// otherwise. https://github.com/matrix-org/matrix-spec-proposals/blob/kegan/sync-v3/proposals/3575-sync.md#room-list-parameters fn process_sliding_sync_room_membership( &self, - room_data: &v4::SlidingSyncRoom, + room_data: &http::response::Room, state_events: &[AnySyncStateEvent], store: &Store, room_id: &RoomId, @@ -720,7 +720,7 @@ async fn cache_latest_events( fn process_room_properties( room_id: &RoomId, - room_data: &v4::SlidingSyncRoom, + room_data: &http::response::Room, room_info: &mut RoomInfo, is_new_room: bool, room_info_notable_updates: &mut BTreeMap, @@ -728,7 +728,7 @@ fn process_room_properties( // Handle the room's avatar. // // It can be updated via the state events, or via the - // [`v4::SlidingSyncRoom::avatar`] field. This part of the code handles the + // [`http::ResponseRoom::avatar`] field. This part of the code handles the // latter case. The former case is handled by [`BaseClient::handle_state`]. match &room_data.avatar { // A new avatar! @@ -741,7 +741,7 @@ fn process_room_properties( // Sliding sync doesn't have a room summary, nevertheless it contains the joined // and invited member counts, in addition to the heroes if it's been configured - // to return them (see the [`v4::RoomSubscription::include_heroes`]). + // to return them (see the [`http::RequestRoomSubscription::include_heroes`]). if let Some(count) = room_data.joined_count { room_info.update_joined_member_count(count.into()); } @@ -768,10 +768,10 @@ fn process_room_properties( room_info.mark_members_missing(); } - if let Some(MilliSecondsSinceUnixEpoch(recency_stamp)) = &room_data.timestamp { + if let Some(recency_stamp) = &room_data.bump_stamp { let recency_stamp: u64 = (*recency_stamp).into(); - if room_info.recency_stamp != Some(recency_stamp) { + if room_info.recency_stamp.as_ref() != Some(&recency_stamp) { room_info.update_recency_stamp(recency_stamp); // If it's not a new room, let's emit a `RECENCY_STAMP` update. @@ -798,7 +798,7 @@ mod tests { use matrix_sdk_common::{deserialized_responses::SyncTimelineEvent, ring_buffer::RingBuffer}; use matrix_sdk_test::async_test; use ruma::{ - api::client::sync::sync_events::{v4, UnreadNotificationsCount}, + api::client::sync::sync_events::UnreadNotificationsCount, assign, event_id, events::{ direct::DirectEventContent, @@ -818,7 +818,7 @@ mod tests { }; use serde_json::json; - use super::cache_latest_events; + use super::{cache_latest_events, http}; use crate::{ rooms::normal::{RoomHero, RoomInfoNotableUpdateReasons}, store::MemoryStore, @@ -830,7 +830,7 @@ mod tests { async fn test_notification_count_set() { let client = logged_in_base_client(None).await; - let mut response = v4::Response::new("42".to_owned()); + let mut response = http::Response::new("42".to_owned()); let room_id = room_id!("!room:example.org"); let count = assign!(UnreadNotificationsCount::default(), { highlight_count: Some(uint!(13)), @@ -839,7 +839,7 @@ mod tests { response.rooms.insert( room_id.to_owned(), - assign!(v4::SlidingSyncRoom::new(), { + assign!(http::response::Room::new(), { unread_notifications: count.clone() }), ); @@ -859,7 +859,7 @@ mod tests { #[async_test] async fn test_can_process_empty_sliding_sync_response() { let client = logged_in_base_client(None).await; - let empty_response = v4::Response::new("5".to_owned()); + let empty_response = http::Response::new("5".to_owned()); client.process_sliding_sync(&empty_response, &()).await.expect("Failed to process sync"); } @@ -871,7 +871,7 @@ mod tests { // When I send sliding sync response containing a room (with identifiable data // in joined_count) - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.joined_count = Some(uint!(41)); let response = response_with_room(room_id, room); let sync_resp = @@ -897,7 +897,7 @@ mod tests { // When I send sliding sync response containing a room with a name set in the // sliding sync response, - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.name = Some("little room".to_owned()); let response = response_with_room(room_id, room); let sync_resp = @@ -923,7 +923,7 @@ mod tests { // When I send sliding sync response containing a room with a name set in the // sliding sync response, and a m.room.name event, - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.name = Some("little room".to_owned()); set_room_name(&mut room, user_id!("@a:b.c"), "The Name".to_owned()); @@ -947,7 +947,7 @@ mod tests { // When I send sliding sync response containing a room with a name set in the // sliding sync response, - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_invited(&mut room, inviter, user_id); room.name = Some("name from sliding sync response".to_owned()); let response = response_with_room(room_id, room); @@ -979,7 +979,7 @@ mod tests { // When I send sliding sync response containing a room with a name set in the // sliding sync response, and a m.room.name event, - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_invited(&mut room, inviter, user_id); @@ -1003,14 +1003,14 @@ mod tests { let user_id = user_id!("@u:e.uk"); // When I join… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_joined(&mut room, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); assert_eq!(client.get_room(room_id).unwrap().state(), RoomState::Joined); // And then leave with a `required_state` state event… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_left(&mut room, user_id); let response = response_with_room(room_id, room); let sync_resp = @@ -1034,14 +1034,14 @@ mod tests { let client = logged_in_base_client(Some(user_a_id)).await; // When I join… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_joined(&mut room, user_a_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); assert_eq!(client.get_room(room_id).unwrap().state(), RoomState::Joined); // And then get kicked/banned with a `required_state` state event… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.required_state.push(make_state_event( user_b_id, user_a_id.as_str(), @@ -1070,14 +1070,14 @@ mod tests { let user_id = user_id!("@u:e.uk"); // When I join… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_joined(&mut room, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); assert_eq!(client.get_room(room_id).unwrap().state(), RoomState::Joined); // And then leave with a `timeline` state event… - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_left_as_timeline_event(&mut room, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1096,7 +1096,7 @@ mod tests { let user_id = user_id!("@u:e.uk"); // When I join... - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_joined(&mut room, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1104,7 +1104,7 @@ mod tests { assert_eq!(client.get_room(room_id).unwrap().state(), RoomState::Joined); // And then leave... - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_left(&mut room, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1112,7 +1112,7 @@ mod tests { assert_eq!(client.get_room(room_id).unwrap().state(), RoomState::Left); // And then get invited back - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_invited(&mut room, user_id, user_id); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1226,7 +1226,7 @@ mod tests { // When I send sliding sync response containing a room with an avatar let room = { - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.avatar = JsOption::from_option(Some(mxc_uri!("mxc://e.uk/med1").to_owned())); room @@ -1252,7 +1252,7 @@ mod tests { // When I send sliding sync response containing a room with an avatar let room = { - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.avatar = JsOption::from_option(Some(mxc_uri!("mxc://e.uk/med1").to_owned())); room @@ -1270,7 +1270,7 @@ mod tests { // No avatar. Still here. // When I send sliding sync response containing no avatar. - let room = v4::SlidingSyncRoom::new(); + let room = http::response::Room::new(); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1285,7 +1285,7 @@ mod tests { // When I send sliding sync response containing an avatar set to `null` (!). let room = { - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.avatar = JsOption::Null; room @@ -1326,7 +1326,7 @@ mod tests { let user_id = user_id!("@u:e.uk"); // When I send sliding sync response containing an invited room - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_invited(&mut room, user_id, user_id); let response = response_with_room(room_id, room); let sync_resp = @@ -1414,12 +1414,12 @@ mod tests { // When I send sliding sync response containing a room (with identifiable data // in `heroes`) - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.heroes = Some(vec![ - assign!(v4::SlidingSyncRoomHero::new(gordon), { + assign!(http::response::Hero::new(gordon), { name: Some("Gordon".to_owned()), }), - assign!(v4::SlidingSyncRoomHero::new(alice), { + assign!(http::response::Hero::new(alice), { name: Some("Alice".to_owned()), avatar: Some(owned_mxc_uri!("mxc://e.uk/med1")) }), @@ -1797,8 +1797,8 @@ mod tests { let room_id = room_id!("!r:e.uk"); // When I send sliding sync response containing a room with a recency stamp - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), + let room = assign!(http::response::Room::new(), { + bump_stamp: Some(42u32.into()), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1816,8 +1816,8 @@ mod tests { { // When I send sliding sync response containing a room with a recency stamp - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), + let room = assign!(http::response::Room::new(), { + bump_stamp: Some(42u32.into()), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1829,8 +1829,8 @@ mod tests { { // When I send sliding sync response containing a room with NO recency stamp - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: None, + let room = assign!(http::response::Room::new(), { + bump_stamp: None, }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1843,8 +1843,8 @@ mod tests { { // When I send sliding sync response containing a room with a NEW recency // timestamp - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: Some(MilliSecondsSinceUnixEpoch(153u32.into())), + let room = assign!(http::response::Room::new(), { + bump_stamp: Some(153u32.into()), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1863,8 +1863,8 @@ mod tests { let room_id = room_id!("!r:e.uk"); // When I send sliding sync response containing a room with a recency stamp. - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: Some(MilliSecondsSinceUnixEpoch(42u32.into())), + let room = assign!(http::response::Room::new(), { + bump_stamp: Some(42u32.into()), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1880,8 +1880,8 @@ mod tests { ); // When I send sliding sync response containing a room with a recency stamp. - let room = assign!(v4::SlidingSyncRoom::new(), { - timestamp: Some(MilliSecondsSinceUnixEpoch(43u32.into())), + let room = assign!(http::response::Room::new(), { + bump_stamp: Some(43u32.into()), }); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1904,7 +1904,7 @@ mod tests { // When I send sliding sync response containing a new room. let room_id = room_id!("!r:e.uk"); - let room = v4::SlidingSyncRoom::new(); + let room = http::response::Room::new(); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1925,7 +1925,7 @@ mod tests { make_raw_event("m.room.message", "$4"), make_raw_event("m.read", "$5"), ]; - let room = assign!(v4::SlidingSyncRoom::new(), { + let room = assign!(http::response::Room::new(), { timeline: events, }); let response = response_with_room(room_id, room); @@ -1949,7 +1949,7 @@ mod tests { // When I receive a sliding sync response containing a new room, let room_id = room_id!("!r:e.uk"); - let room = v4::SlidingSyncRoom::new(); + let room = http::response::Room::new(); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -1976,7 +1976,7 @@ mod tests { .to_string(), ) .unwrap()]; - let mut response = response_with_room(room_id, v4::SlidingSyncRoom::new()); + let mut response = response_with_room(room_id, http::response::Room::new()); response.extensions.account_data.rooms.insert(room_id.to_owned(), room_account_data_events); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); @@ -2125,7 +2125,7 @@ mod tests { their_id: &UserId, other_state: MembershipState, ) { - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); set_room_joined(&mut room, my_id); match other_state { @@ -2159,14 +2159,14 @@ mod tests { user_id: &UserId, new_state: MembershipState, ) { - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.required_state.push(make_membership_event(user_id, new_state)); let response = response_with_room(room_id, room); client.process_sliding_sync(&response, &()).await.expect("Failed to process sync"); } fn set_direct_with( - response: &mut v4::Response, + response: &mut http::Response, user_id: OwnedUserId, room_ids: Vec, ) { @@ -2179,14 +2179,14 @@ mod tests { .push(make_global_account_data_event(DirectEventContent(direct_content))); } - fn response_with_room(room_id: &RoomId, room: v4::SlidingSyncRoom) -> v4::Response { - let mut response = v4::Response::new("5".to_owned()); + fn response_with_room(room_id: &RoomId, room: http::response::Room) -> http::Response { + let mut response = http::Response::new("5".to_owned()); response.rooms.insert(room_id.to_owned(), room); response } - fn room_with_avatar(avatar_uri: &MxcUri, user_id: &UserId) -> v4::SlidingSyncRoom { - let mut room = v4::SlidingSyncRoom::new(); + fn room_with_avatar(avatar_uri: &MxcUri, user_id: &UserId) -> http::response::Room { + let mut room = http::response::Room::new(); let mut avatar_event_content = RoomAvatarEventContent::new(); avatar_event_content.url = Some(avatar_uri.to_owned()); @@ -2199,8 +2199,8 @@ mod tests { fn room_with_canonical_alias( room_alias_id: &RoomAliasId, user_id: &UserId, - ) -> v4::SlidingSyncRoom { - let mut room = v4::SlidingSyncRoom::new(); + ) -> http::response::Room { + let mut room = http::response::Room::new(); let mut canonical_alias_event_content = RoomCanonicalAliasEventContent::new(); canonical_alias_event_content.alias = Some(room_alias_id.to_owned()); @@ -2215,8 +2215,8 @@ mod tests { room } - fn room_with_timeline(events: &[serde_json::Value]) -> v4::SlidingSyncRoom { - let mut room = v4::SlidingSyncRoom::new(); + fn room_with_timeline(events: &[serde_json::Value]) -> http::response::Room { + let mut room = http::response::Room::new(); room.timeline.extend( events .iter() @@ -2226,7 +2226,7 @@ mod tests { room } - fn set_room_name(room: &mut v4::SlidingSyncRoom, sender: &UserId, name: String) { + fn set_room_name(room: &mut http::response::Room, sender: &UserId, name: String) { room.required_state.push(make_state_event( sender, "", @@ -2235,7 +2235,7 @@ mod tests { )); } - fn set_room_invited(room: &mut v4::SlidingSyncRoom, inviter: &UserId, invitee: &UserId) { + fn set_room_invited(room: &mut http::response::Room, inviter: &UserId, invitee: &UserId) { // MSC3575 shows an almost-empty event to indicate that we are invited to a // room. Just the type is supplied. @@ -2257,15 +2257,15 @@ mod tests { )); } - fn set_room_joined(room: &mut v4::SlidingSyncRoom, user_id: &UserId) { + fn set_room_joined(room: &mut http::response::Room, user_id: &UserId) { room.required_state.push(make_membership_event(user_id, MembershipState::Join)); } - fn set_room_left(room: &mut v4::SlidingSyncRoom, user_id: &UserId) { + fn set_room_left(room: &mut http::response::Room, user_id: &UserId) { room.required_state.push(make_membership_event(user_id, MembershipState::Leave)); } - fn set_room_left_as_timeline_event(room: &mut v4::SlidingSyncRoom, user_id: &UserId) { + fn set_room_left_as_timeline_event(room: &mut http::response::Room, user_id: &UserId) { room.timeline.push(make_membership_event(user_id, MembershipState::Leave)); } diff --git a/crates/matrix-sdk-ui/src/encryption_sync_service.rs b/crates/matrix-sdk-ui/src/encryption_sync_service.rs index c4ca039f04e..66da6e8903f 100644 --- a/crates/matrix-sdk-ui/src/encryption_sync_service.rs +++ b/crates/matrix-sdk-ui/src/encryption_sync_service.rs @@ -32,7 +32,8 @@ use async_stream::stream; use futures_core::stream::Stream; use futures_util::{pin_mut, StreamExt}; use matrix_sdk::{Client, SlidingSync, LEASE_DURATION_MS}; -use ruma::{api::client::sync::sync_events::v4, assign}; +use matrix_sdk_base::sliding_sync::http; +use ruma::assign; use tokio::sync::OwnedMutexGuard; use tracing::{debug, instrument, trace, Span}; @@ -104,9 +105,9 @@ impl EncryptionSyncService { .map_err(Error::SlidingSync)? //.share_pos() // TODO(bnjbvr) This is racy, needs cross-process lock :') .with_to_device_extension( - assign!(v4::ToDeviceConfig::default(), { enabled: Some(true)}), + assign!(http::request::ToDevice::default(), { enabled: Some(true)}), ) - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true)})); + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true)})); if let Some((poll_timeout, network_timeout)) = poll_and_network_timeouts { builder = builder.poll_timeout(poll_timeout).network_timeout(network_timeout); diff --git a/crates/matrix-sdk-ui/src/notification_client.rs b/crates/matrix-sdk-ui/src/notification_client.rs index f95895ba5fd..4b323f9f14c 100644 --- a/crates/matrix-sdk-ui/src/notification_client.rs +++ b/crates/matrix-sdk-ui/src/notification_client.rs @@ -22,12 +22,10 @@ use matrix_sdk::{room::Room, Client, ClientBuildError, SlidingSyncList, SlidingS use matrix_sdk_base::{ crypto::{vodozemac, MegolmError}, deserialized_responses::TimelineEvent, + sliding_sync::http, RoomState, StoreError, }; use ruma::{ - api::client::sync::sync_events::v4::{ - AccountDataConfig, RoomSubscription, SyncRequestListFilters, - }, assign, events::{ room::{member::StrippedRoomMemberEvent, message::SyncRoomMessageEvent}, @@ -358,7 +356,7 @@ impl NotificationClient { .sync_mode(SlidingSyncMode::new_selective().add_range(0..=16)) .timeline_limit(8) .required_state(required_state.clone()) - .filters(Some(assign!(SyncRequestListFilters::default(), { + .filters(Some(assign!(http::request::ListFilters::default(), { is_invite: Some(true), not_room_types: vec!["m.space".to_owned()], }))); @@ -369,7 +367,7 @@ impl NotificationClient { .poll_timeout(Duration::from_secs(1)) .network_timeout(Duration::from_secs(3)) .with_account_data_extension( - assign!(AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), ) .add_list(invites) .build() @@ -377,7 +375,7 @@ impl NotificationClient { sync.subscribe_to_room( room_id.to_owned(), - Some(assign!(RoomSubscription::default(), { + Some(assign!(http::request::RoomSubscription::default(), { required_state, timeline_limit: Some(uint!(16)) })), diff --git a/crates/matrix-sdk-ui/src/room_list_service/mod.rs b/crates/matrix-sdk-ui/src/room_list_service/mod.rs index 2ebbfa9fdc2..41f298a69fb 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/mod.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/mod.rs @@ -66,17 +66,10 @@ use matrix_sdk::{ event_cache::EventCacheError, Client, Error as SlidingSyncError, SlidingSync, SlidingSyncList, SlidingSyncMode, }; +use matrix_sdk_base::sliding_sync::http; pub use room::*; pub use room_list::*; -use ruma::{ - api::client::sync::sync_events::v4::{ - AccountDataConfig, E2EEConfig, ReceiptsConfig, RoomReceiptConfig, SyncRequestListFilters, - ToDeviceConfig, TypingConfig, - }, - assign, - events::{StateEventType, TimelineEventType}, - OwnedRoomId, RoomId, -}; +use ruma::{assign, events::StateEventType, OwnedRoomId, RoomId}; pub use state::*; use thiserror::Error; use tokio::time::timeout; @@ -123,21 +116,23 @@ impl RoomListService { .sliding_sync("room-list") .map_err(Error::SlidingSync)? .with_account_data_extension( - assign!(AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), ) - .with_receipt_extension(assign!(ReceiptsConfig::default(), { + .with_receipt_extension(assign!(http::request::Receipts::default(), { enabled: Some(true), - rooms: Some(vec![RoomReceiptConfig::AllSubscribed]) + rooms: Some(vec![http::request::ReceiptsRoom::AllSubscribed]) })) - .with_typing_extension(assign!(TypingConfig::default(), { + .with_typing_extension(assign!(http::request::Typing::default(), { enabled: Some(true), })); if with_encryption { builder = builder - .with_e2ee_extension(assign!(E2EEConfig::default(), { enabled: Some(true) })) + .with_e2ee_extension( + assign!(http::request::E2EE::default(), { enabled: Some(true) }), + ) .with_to_device_extension( - assign!(ToDeviceConfig::default(), { enabled: Some(true) }), + assign!(http::request::ToDevice::default(), { enabled: Some(true) }), ); } @@ -157,7 +152,7 @@ impl RoomListService { (StateEventType::RoomPowerLevels, "".to_owned()), ]) .include_heroes(Some(true)) - .filters(Some(assign!(SyncRequestListFilters::default(), { + .filters(Some(assign!(http::request::ListFilters::default(), { // As defined in the [SlidingSync MSC](https://github.com/matrix-org/matrix-spec-proposals/blob/9450ced7fb9cf5ea9077d029b3adf36aebfa8709/proposals/3575-sync.md?plain=1#L444) // If unset, both invited and joined rooms are returned. If false, no invited rooms are // returned. If true, only invited rooms are returned. @@ -474,7 +469,7 @@ mod tests { impl Match for SlidingSyncMatcher { fn matches(&self, request: &Request) -> bool { - request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync" + request.url.path() == "/_matrix/client/unstable/org.matrix.simplified_msc3575/sync" && request.method == Method::POST } } diff --git a/crates/matrix-sdk-ui/src/room_list_service/room.rs b/crates/matrix-sdk-ui/src/room_list_service/room.rs index bc28a8f1bc5..946a8c399ff 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/room.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/room.rs @@ -19,7 +19,8 @@ use std::{ops::Deref, sync::Arc}; use async_once_cell::OnceCell as AsyncOnceCell; use matrix_sdk::SlidingSync; -use ruma::{api::client::sync::sync_events::v4::RoomSubscription, events::StateEventType, RoomId}; +use matrix_sdk_base::sliding_sync::http; +use ruma::{events::StateEventType, RoomId}; use super::Error; use crate::{ @@ -91,7 +92,7 @@ impl Room { /// /// It means that all events from this room will be received every time, no /// matter how the `RoomList` is configured. - pub fn subscribe(&self, settings: Option) { + pub fn subscribe(&self, settings: Option) { let mut settings = settings.unwrap_or_default(); // Make sure to always include the room creation event in the required state 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 bdbf8c1a593..768edf6bbfa 100644 --- a/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs +++ b/crates/matrix-sdk-ui/src/timeline/event_item/mod.rs @@ -559,12 +559,11 @@ mod tests { use assert_matches2::assert_let; use matrix_sdk::test_utils::logged_in_client; use matrix_sdk_base::{ - deserialized_responses::SyncTimelineEvent, latest_event::LatestEvent, MinimalStateEvent, - OriginalMinimalStateEvent, + deserialized_responses::SyncTimelineEvent, latest_event::LatestEvent, sliding_sync::http, + MinimalStateEvent, OriginalMinimalStateEvent, }; use matrix_sdk_test::{async_test, sync_timeline_event}; use ruma::{ - api::client::sync::sync_events::v4, events::{ room::{ member::RoomMemberEventContent, @@ -620,7 +619,7 @@ mod tests { let user_id = user_id!("@t:o.uk"); let event = message_event(room_id, user_id, "**My M**", "My M", 122344); let client = logged_in_client(None).await; - let mut room = v4::SlidingSyncRoom::new(); + let mut room = http::response::Room::new(); room.timeline.push(member_event(room_id, user_id, "Alice Margatroid", "mxc://e.org/SEs")); // And the room is stored in the client so it can be extracted when needed @@ -663,7 +662,7 @@ mod tests { .unwrap(), ); - let room = v4::SlidingSyncRoom::new(); + let room = http::response::Room::new(); // Do not push the `member_event` inside the room. Let's say it's flying in the // `StateChanges`. @@ -718,8 +717,8 @@ mod tests { }) } - fn response_with_room(room_id: &RoomId, room: v4::SlidingSyncRoom) -> v4::Response { - let mut response = v4::Response::new("6".to_owned()); + fn response_with_room(room_id: &RoomId, room: http::response::Room) -> http::Response { + let mut response = http::Response::new("6".to_owned()); response.rooms.insert(room_id.to_owned(), room); response } diff --git a/crates/matrix-sdk-ui/tests/integration/notification_client.rs b/crates/matrix-sdk-ui/tests/integration/notification_client.rs index c47363b902a..06b15fadb83 100644 --- a/crates/matrix-sdk-ui/tests/integration/notification_client.rs +++ b/crates/matrix-sdk-ui/tests/integration/notification_client.rs @@ -189,7 +189,7 @@ async fn test_notification_client_sliding_sync() { }, // Power levels. - json!({ + { "content": { "ban": 50, "events": { @@ -198,7 +198,7 @@ async fn test_notification_client_sliding_sync() { "m.room.history_visibility": 100, "m.room.name": 50, "m.room.power_levels": 100, - "m.room.message": 25 + "m.room.message": 25, }, "events_default": 0, "invite": 0, @@ -207,9 +207,9 @@ async fn test_notification_client_sliding_sync() { "state_default": 50, "users": { "@example:localhost": 100, - sender: 0 + sender: 0, }, - "users_default": 0 + "users_default": 0, }, "event_id": "$15139375512JaHAW:localhost", "origin_server_ts": 151393755, @@ -217,9 +217,9 @@ async fn test_notification_client_sliding_sync() { "state_key": "", "type": "m.room.power_levels", "unsigned": { - "age": 703422 - } - }) + "age": 703422, + }, + }, ], "timeline": [ diff --git a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs index 93145c02ba2..c94dfad2935 100644 --- a/crates/matrix-sdk-ui/tests/integration/room_list_service.rs +++ b/crates/matrix-sdk-ui/tests/integration/room_list_service.rs @@ -7,7 +7,9 @@ use assert_matches::assert_matches; use eyeball_im::VectorDiff; use futures_util::{pin_mut, FutureExt, StreamExt}; use matrix_sdk::{test_utils::logged_in_client_with_server, Client}; -use matrix_sdk_base::sync::UnreadNotificationsCount; +use matrix_sdk_base::{ + sliding_sync::http::request::RoomSubscription, sync::UnreadNotificationsCount, +}; use matrix_sdk_test::async_test; use matrix_sdk_ui::{ room_list_service::{ @@ -18,7 +20,6 @@ use matrix_sdk_ui::{ RoomListService, }; use ruma::{ - api::client::sync::sync_events::v4::RoomSubscription, assign, event_id, events::{room::message::RoomMessageEventContent, StateEventType}, mxc_uri, room_id, uint, @@ -83,7 +84,6 @@ macro_rules! sync_then_assert_request_and_fake_response { respond with = $( ( code $code ) )? { $( $response_json )* }, $( after delay = $response_delay, )? }; - $( assert_matches!(state.next().now_or_never(), Some(Some($post_state)), "post state"); )? next @@ -1285,7 +1285,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { "rooms": { "!r0:bar.org": { "initial": true, - "timestamp": 1, + "bump_stamp": 1, "required_state": [ { "content": { @@ -1339,7 +1339,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { "rooms": { "!r1:bar.org": { "initial": true, - "timestamp": 2, + "bump_stamp": 2, "required_state": [ { "content": { @@ -1355,7 +1355,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { }, "!r2:bar.org": { "initial": true, - "timestamp": 3, + "bump_stamp": 3, "required_state": [ { "content": { @@ -1371,7 +1371,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { }, "!r3:bar.org": { "initial": true, - "timestamp": 4, + "bump_stamp": 4, "required_state": [ { "content": { @@ -1387,7 +1387,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { }, "!r4:bar.org": { "initial": true, - "timestamp": 5, + "bump_stamp": 5, "required_state": [ { "content": { @@ -1435,7 +1435,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { "rooms": { "!r5:bar.org": { "initial": true, - "timestamp": 6, + "bump_stamp": 6, "required_state": [ { "content": { @@ -1451,7 +1451,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { }, "!r6:bar.org": { "initial": true, - "timestamp": 7, + "bump_stamp": 7, "required_state": [ { "content": { @@ -1467,7 +1467,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { }, "!r7:bar.org": { "initial": true, - "timestamp": 8, + "bump_stamp": 8, "required_state": [ { "content": { @@ -1588,7 +1588,7 @@ async fn test_dynamic_entries_stream() -> Result<(), Error> { "rooms": { "!r0:bar.org": { "initial": true, - "timestamp": 9, + "bump_stamp": 9, "required_state": [], }, }, @@ -1658,7 +1658,7 @@ async fn test_room_sorting() -> Result<(), Error> { "rooms": { "!r0:bar.org": { "initial": true, - "timestamp": 3, + "bump_stamp": 3, "required_state": [ { "content": { @@ -1674,7 +1674,7 @@ async fn test_room_sorting() -> Result<(), Error> { }, "!r1:bar.org": { "initial": true, - "timestamp": 3, + "bump_stamp": 3, "required_state": [ { "content": { @@ -1690,15 +1690,15 @@ async fn test_room_sorting() -> Result<(), Error> { }, "!r2:bar.org": { "initial": true, - "timestamp": 1, + "bump_stamp": 1, }, "!r3:bar.org": { "initial": true, - "timestamp": 4, + "bump_stamp": 4, }, "!r4:bar.org": { "initial": true, - "timestamp": 5, + "bump_stamp": 5, }, }, }, @@ -1755,13 +1755,13 @@ async fn test_room_sorting() -> Result<(), Error> { }, "rooms": { "!r0:bar.org": { - "timestamp": 7, + "bump_stamp": 7, }, "!r1:bar.org": { - "timestamp": 6, + "bump_stamp": 6, }, "!r2:bar.org": { - "timestamp": 9, + "bump_stamp": 9, }, }, }, @@ -1841,10 +1841,10 @@ async fn test_room_sorting() -> Result<(), Error> { "rooms": { "!r6:bar.org": { "initial": true, - "timestamp": 8, + "bump_stamp": 8, }, "!r3:bar.org": { - "timestamp": 10, + "bump_stamp": 10, }, }, }, @@ -1906,7 +1906,7 @@ async fn test_room_sorting() -> Result<(), Error> { }, "rooms": { "!r3:bar.org": { - "timestamp": 11, + "bump_stamp": 11, }, }, }, diff --git a/crates/matrix-sdk-ui/tests/integration/sliding_sync.rs b/crates/matrix-sdk-ui/tests/integration/sliding_sync.rs index 65801279388..b267fa96bb7 100644 --- a/crates/matrix-sdk-ui/tests/integration/sliding_sync.rs +++ b/crates/matrix-sdk-ui/tests/integration/sliding_sync.rs @@ -47,7 +47,7 @@ pub(crate) struct PartialSlidingSyncRequest { impl Match for SlidingSyncMatcher { fn matches(&self, request: &Request) -> bool { - request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync" + request.url.path() == "/_matrix/client/unstable/org.matrix.simplified_msc3575/sync" && request.method == Method::POST } } diff --git a/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs b/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs index db56d215db2..ddde9c9b450 100644 --- a/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs +++ b/crates/matrix-sdk-ui/tests/integration/timeline/sliding_sync.rs @@ -298,7 +298,7 @@ struct SlidingSyncMatcher; impl Match for SlidingSyncMatcher { fn matches(&self, request: &Request) -> bool { - request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync" + request.url.path() == "/_matrix/client/unstable/org.matrix.simplified_msc3575/sync" && request.method == Method::POST } } diff --git a/crates/matrix-sdk/src/sliding_sync/README.md b/crates/matrix-sdk/src/sliding_sync/README.md index 95893b235bf..df3ec5a2cb1 100644 --- a/crates/matrix-sdk/src/sliding_sync/README.md +++ b/crates/matrix-sdk/src/sliding_sync/README.md @@ -58,7 +58,7 @@ After the general configuration, one typically wants to add a list via the ## Lists A list defines a subset of matching rooms one wants to filter for, and be -kept up about. The [`v4::SyncRequestListFilters`][] allows for a granular +kept up about. The [`http::request::ListFilters`] allows for a granular specification of the exact rooms one wants the server to select and the way one wants them to be ordered before receiving. Secondly each list has a set of `ranges`: the subset of indexes of the entire list one is interested in @@ -67,25 +67,25 @@ and a unique name to be identified with. For example, a user might be part of thousands of rooms, but if the client app always starts by showing the most recent direct message conversations, loading all rooms is an inefficient approach. Instead with Sliding Sync one -defines a list (e.g. named `"main_list"`) filtering for `is_dm`, ordered +defines a list (e.g. named `"main_list"`) filtering for `is_invite`, ordered by recency and select to list the top 10 via `ranges: [ [0,9] ]` (indexes are **inclusive**) like so: ```rust # use matrix_sdk::sliding_sync::{SlidingSyncList, SlidingSyncMode}; -use ruma::{assign, api::client::sync::sync_events::v4}; +use matrix_sdk_base::sliding_sync::http; +use ruma::assign; let list_builder = SlidingSyncList::builder("main_list") .sync_mode(SlidingSyncMode::new_selective().add_range(0..=9)) .filters(Some(assign!( - v4::SyncRequestListFilters::default(), { is_dm: Some(true)} - ))) - .sort(vec!["by_recency".to_owned()]); + http::request::ListFilters::default(), { is_invite: Some(true)} + ))); ``` Please refer to the [specification][MSC], the [Ruma types][ruma-types], specifically [`SyncRequestListFilter`](https://docs.rs/ruma/latest/ruma/api/client/sync/sync_events/v4/struct.SyncRequestListFilters.html) and the -[`SlidingSyncListBuilder`] for details on the filters, sort-order and +[`SlidingSyncListBuilder`] for details on the filters, and range-options and data one requests to be sent. Once the list is fully configured, `build()` it and add the list to the sliding sync session by supplying it to [`add_list`][`SlidingSyncBuilder::add_list`]. @@ -155,7 +155,7 @@ typing- and presence-information and account-data, but can be extended by any implementation as they please. Handling of the data of the e2ee, to-device and typing-extensions takes place transparently within the SDK. -By default [`SlidingSync`][] doesn't activate _any_ extensions to save on +By default [`SlidingSync`] doesn't activate _any_ extensions to save on bandwidth, but we generally recommend to use the `with_XXX_extensions` family of methods when building sliding sync to enable e2ee, to-device-messages and account-data-extensions. @@ -163,7 +163,7 @@ account-data-extensions. ## Timeline events Both the list configuration as well as the [room subscription -settings](`v4::RoomSubscription`) allow to specify a `timeline_limit` to +settings](`http::request::RoomSubscription`) allow to specify a `timeline_limit` to receive timeline events. If that is unset or set to 0, no events are sent by the server (which is the default), if multiple limits are found, the highest takes precedence. Any positive number indicates that on the first request a @@ -223,14 +223,8 @@ In full, this typically looks like this: ```rust,no_run # use futures_util::{pin_mut, StreamExt}; -# use matrix_sdk::{ -# sliding_sync::{SlidingSyncMode, SlidingSyncListBuilder}, -# Client, -# }; -# use ruma::{ -# api::client::sync::sync_events::v4, assign, -# }; -# use tracing::{debug, error, info, warn}; +# use matrix_sdk::Client; +# use tracing::{error, info}; # use url::Url; # async { # let homeserver = Url::parse("http://example.com")?; @@ -282,7 +276,7 @@ will return immediately — with a proper response though. One just needs to make sure to not call that stream any further. Additionally, as both requests are sent with the same positional argument, the server might respond with data, the client has already processed. This isn't a problem, -the [`SlidingSync`][] will only process new data and skip the processing +the [`SlidingSync`] will only process new data and skip the processing even across restarts. To support this, in practice, one can spawn a `Future` that runs @@ -335,32 +329,12 @@ be sent in their first request than if they were loaded from a cold cache. Only the latest 10 timeline items of each room are cached and they are reset whenever a new set of timeline items is received by the server. -## Bot mode - -_Note_: This is not yet exposed via the API. See [#1475](https://github.com/matrix-org/matrix-rust-sdk/issues/1475) - -Sliding Sync is modeled for faster and more efficient user-facing client -applications, but offers significant speed ups even for bot cases through -its filtering mechanism. The sort-order and specific subsets, however, are -usually not of interest for bots. For that use case the -[`v4::SyncRequestList`][] offers the -[`slow_get_all_rooms`](`v4::SyncRequestList::slow_get_all_rooms`) flag. - -Once switched on, this mode will not trigger any updates on "list -movements", ranges and sorting are ignored and all rooms matching the filter -will be returned with the given room details settings. Depending on the data -that is requested this will still be significantly faster as the response -only returns the matching rooms and states as per settings. - -Think about a bot that only interacts in `is_dm = true` and doesn't need -room topic, room avatar and all the other state. It will be a lot faster to -start up and retrieve only the data needed to actually run. - # Full example ```rust,no_run use matrix_sdk::{Client, sliding_sync::{SlidingSyncList, SlidingSyncMode}}; -use ruma::{assign, api::client::sync::sync_events::v4, events::StateEventType}; +use matrix_sdk_base::sliding_sync::http; +use ruma::{assign, events::StateEventType}; use tracing::{warn, error, info, debug}; use futures_util::{pin_mut, StreamExt}; use url::Url; @@ -374,23 +348,21 @@ let sliding_sync_builder = client .sliding_sync("main-sync")? .sliding_sync_proxy(Url::parse("http://sliding-sync.example.org")?) // our proxy server .with_account_data_extension( - assign!(v4::AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), ) // we enable the account-data extension - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true) })) // and the e2ee extension + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true) })) // and the e2ee extension .with_to_device_extension( - assign!(v4::ToDeviceConfig::default(), { enabled: Some(true) }), + assign!(http::request::ToDevice::default(), { enabled: Some(true) }), ); // and the to-device extension let full_sync_list = SlidingSyncList::builder(&full_sync_list_name) .sync_mode(SlidingSyncMode::Growing { batch_size: 50, maximum_number_of_rooms_to_fetch: Some(500) }) // sync up by growing the window - .sort(vec!["by_recency".to_owned()]) // ordered by most recent .required_state(vec![ (StateEventType::RoomEncryption, "".to_owned()) ]); // only want to know if the room is encrypted let active_list = SlidingSyncList::builder(&active_list_name) // the active window .sync_mode(SlidingSyncMode::new_selective().add_range(0..=9)) // sync up the specific range only, first 10 items - .sort(vec!["by_recency".to_owned()]) // last active .timeline_limit(5u32) // add the last 5 timeline items for room preview and faster timeline loading .required_state(vec![ // we want to know immediately: (StateEventType::RoomEncryption, "".to_owned()), // is it encrypted diff --git a/crates/matrix-sdk/src/sliding_sync/builder.rs b/crates/matrix-sdk/src/sliding_sync/builder.rs index 328b9d848d9..abff2b17cd5 100644 --- a/crates/matrix-sdk/src/sliding_sync/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/builder.rs @@ -6,14 +6,9 @@ use std::{ time::Duration, }; +use matrix_sdk_base::sliding_sync::http; use matrix_sdk_common::{ring_buffer::RingBuffer, timer}; -use ruma::{ - api::client::sync::sync_events::v4::{ - self, AccountDataConfig, E2EEConfig, ExtensionsConfig, ReceiptsConfig, ToDeviceConfig, - TypingConfig, - }, - OwnedRoomId, -}; +use ruma::OwnedRoomId; use tokio::sync::{broadcast::channel, Mutex as AsyncMutex, RwLock as AsyncRwLock}; use url::Url; @@ -35,8 +30,8 @@ pub struct SlidingSyncBuilder { sliding_sync_proxy: Option, client: Client, lists: Vec, - extensions: Option, - subscriptions: BTreeMap, + extensions: Option, + subscriptions: BTreeMap, poll_timeout: Duration, network_timeout: Duration, #[cfg(feature = "e2e-encryption")] @@ -133,31 +128,32 @@ impl SlidingSyncBuilder { } /// Set the E2EE extension configuration. - pub fn with_e2ee_extension(mut self, e2ee: E2EEConfig) -> Self { + pub fn with_e2ee_extension(mut self, e2ee: http::request::E2EE) -> Self { self.extensions.get_or_insert_with(Default::default).e2ee = e2ee; self } /// Unset the E2EE extension configuration. pub fn without_e2ee_extension(mut self) -> Self { - self.extensions.get_or_insert_with(Default::default).e2ee = E2EEConfig::default(); + self.extensions.get_or_insert_with(Default::default).e2ee = http::request::E2EE::default(); self } /// Set the ToDevice extension configuration. - pub fn with_to_device_extension(mut self, to_device: ToDeviceConfig) -> Self { + pub fn with_to_device_extension(mut self, to_device: http::request::ToDevice) -> Self { self.extensions.get_or_insert_with(Default::default).to_device = to_device; self } /// Unset the ToDevice extension configuration. pub fn without_to_device_extension(mut self) -> Self { - self.extensions.get_or_insert_with(Default::default).to_device = ToDeviceConfig::default(); + self.extensions.get_or_insert_with(Default::default).to_device = + http::request::ToDevice::default(); self } /// Set the account data extension configuration. - pub fn with_account_data_extension(mut self, account_data: AccountDataConfig) -> Self { + pub fn with_account_data_extension(mut self, account_data: http::request::AccountData) -> Self { self.extensions.get_or_insert_with(Default::default).account_data = account_data; self } @@ -165,31 +161,33 @@ impl SlidingSyncBuilder { /// Unset the account data extension configuration. pub fn without_account_data_extension(mut self) -> Self { self.extensions.get_or_insert_with(Default::default).account_data = - AccountDataConfig::default(); + http::request::AccountData::default(); self } /// Set the Typing extension configuration. - pub fn with_typing_extension(mut self, typing: TypingConfig) -> Self { + pub fn with_typing_extension(mut self, typing: http::request::Typing) -> Self { self.extensions.get_or_insert_with(Default::default).typing = typing; self } /// Unset the Typing extension configuration. pub fn without_typing_extension(mut self) -> Self { - self.extensions.get_or_insert_with(Default::default).typing = TypingConfig::default(); + self.extensions.get_or_insert_with(Default::default).typing = + http::request::Typing::default(); self } /// Set the Receipt extension configuration. - pub fn with_receipt_extension(mut self, receipt: ReceiptsConfig) -> Self { + pub fn with_receipt_extension(mut self, receipt: http::request::Receipts) -> Self { self.extensions.get_or_insert_with(Default::default).receipts = receipt; self } /// Unset the Receipt extension configuration. pub fn without_receipt_extension(mut self) -> Self { - self.extensions.get_or_insert_with(Default::default).receipts = ReceiptsConfig::default(); + self.extensions.get_or_insert_with(Default::default).receipts = + http::request::Receipts::default(); self } diff --git a/crates/matrix-sdk/src/sliding_sync/client.rs b/crates/matrix-sdk/src/sliding_sync/client.rs index 6c7831a5612..8093c8c5656 100644 --- a/crates/matrix-sdk/src/sliding_sync/client.rs +++ b/crates/matrix-sdk/src/sliding_sync/client.rs @@ -1,8 +1,8 @@ use std::collections::BTreeMap; use imbl::Vector; -use matrix_sdk_base::{sync::SyncResponse, PreviousEventsProvider}; -use ruma::{api::client::sync::sync_events::v4, events::AnyToDeviceEvent, serde::Raw, OwnedRoomId}; +use matrix_sdk_base::{sliding_sync::http, sync::SyncResponse, PreviousEventsProvider}; +use ruma::{events::AnyToDeviceEvent, serde::Raw, OwnedRoomId}; use super::{SlidingSync, SlidingSyncBuilder}; use crate::{Client, Result, SlidingSyncRoom}; @@ -25,7 +25,7 @@ impl Client { #[tracing::instrument(skip(self, response))] pub async fn process_sliding_sync_test_helper( &self, - response: &v4::Response, + response: &http::Response, ) -> Result { let response = self.base_client().process_sliding_sync(response, &()).await?; @@ -66,7 +66,10 @@ impl<'a> SlidingSyncResponseProcessor<'a> { } #[cfg(feature = "e2e-encryption")] - pub async fn handle_encryption(&mut self, extensions: &v4::Extensions) -> Result<()> { + pub async fn handle_encryption( + &mut self, + extensions: &http::response::Extensions, + ) -> Result<()> { // This is an internal API misuse if this is triggered (calling // handle_room_response before this function), so panic is fine. assert!(self.response.is_none()); @@ -80,7 +83,7 @@ impl<'a> SlidingSyncResponseProcessor<'a> { Ok(()) } - pub async fn handle_room_response(&mut self, response: &v4::Response) -> Result<()> { + pub async fn handle_room_response(&mut self, response: &http::Response) -> Result<()> { self.response = Some( self.client .base_client() diff --git a/crates/matrix-sdk/src/sliding_sync/list/builder.rs b/crates/matrix-sdk/src/sliding_sync/list/builder.rs index cfc9329492c..01673744d55 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/builder.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/builder.rs @@ -7,10 +7,8 @@ use std::{ }; use eyeball::{Observable, SharedObservable}; -use ruma::{ - api::client::sync::sync_events::v4, - events::{StateEventType, TimelineEventType}, -}; +use matrix_sdk_base::sliding_sync::http; +use ruma::events::StateEventType; use tokio::sync::broadcast::Sender; use super::{ @@ -38,7 +36,7 @@ pub struct SlidingSyncListBuilder { sync_mode: SlidingSyncMode, required_state: Vec<(StateEventType, String)>, include_heroes: Option, - filters: Option, + filters: Option, timeline_limit: Option, pub(crate) name: String, @@ -118,7 +116,7 @@ impl SlidingSyncListBuilder { } /// Any filters to apply to the query. - pub fn filters(mut self, value: Option) -> Self { + pub fn filters(mut self, value: Option) -> Self { self.filters = value; self } diff --git a/crates/matrix-sdk/src/sliding_sync/list/mod.rs b/crates/matrix-sdk/src/sliding_sync/list/mod.rs index 7733fc1d642..673bceb8480 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/mod.rs @@ -11,7 +11,8 @@ use std::{ use eyeball::{Observable, SharedObservable, Subscriber}; use futures_core::Stream; -use ruma::{api::client::sync::sync_events::v4, assign, TransactionId}; +use matrix_sdk_base::sliding_sync::http; +use ruma::{assign, TransactionId}; use serde::{Deserialize, Serialize}; use tokio::sync::broadcast::Sender; use tracing::{instrument, warn}; @@ -147,7 +148,7 @@ impl SlidingSyncList { pub(super) fn next_request( &self, txn_id: &mut LazyTransactionId, - ) -> Result { + ) -> Result { self.inner.next_request(txn_id) } @@ -274,7 +275,7 @@ impl SlidingSyncListInner { } /// Update the state to the next request, and return it. - fn next_request(&self, txn_id: &mut LazyTransactionId) -> Result { + fn next_request(&self, txn_id: &mut LazyTransactionId) -> Result { let ranges = { // Use a dedicated scope to ensure the lock is released before continuing. let mut request_generator = self.request_generator.write().unwrap(); @@ -285,16 +286,16 @@ impl SlidingSyncListInner { Ok(self.request(ranges, txn_id)) } - /// Build a [`SyncRequestList`][v4::SyncRequestList] based on the current - /// state of the request generator. + /// Build a [`http::request::List`] based on the current state of the + /// request generator. #[instrument(skip(self), fields(name = self.name))] - fn request(&self, ranges: Ranges, txn_id: &mut LazyTransactionId) -> v4::SyncRequestList { + fn request(&self, ranges: Ranges, txn_id: &mut LazyTransactionId) -> http::request::List { use ruma::UInt; let ranges = ranges.into_iter().map(|r| (UInt::from(*r.start()), UInt::from(*r.end()))).collect(); - let mut request = assign!(v4::SyncRequestList::default(), { ranges }); + let mut request = assign!(http::request::List::default(), { ranges }); { let mut sticky = self.sticky.write().unwrap(); sticky.maybe_apply(&mut request, txn_id); diff --git a/crates/matrix-sdk/src/sliding_sync/list/sticky.rs b/crates/matrix-sdk/src/sliding_sync/list/sticky.rs index 06c67f7b919..3770cc7a0b6 100644 --- a/crates/matrix-sdk/src/sliding_sync/list/sticky.rs +++ b/crates/matrix-sdk/src/sliding_sync/list/sticky.rs @@ -1,7 +1,5 @@ -use ruma::{ - api::client::sync::sync_events::v4, - events::{StateEventType, TimelineEventType}, -}; +use matrix_sdk_base::sliding_sync::http; +use ruma::events::StateEventType; use super::Bound; use crate::sliding_sync::sticky_parameters::StickyData; @@ -18,7 +16,7 @@ pub(super) struct SlidingSyncListStickyParameters { include_heroes: Option, /// Any filters to apply to the query. - filters: Option, + filters: Option, /// The maximum number of timeline events to query for. timeline_limit: Option, @@ -28,7 +26,7 @@ impl SlidingSyncListStickyParameters { pub fn new( required_state: Vec<(StateEventType, String)>, include_heroes: Option, - filters: Option, + filters: Option, timeline_limit: Option, ) -> Self { // Consider that each list will have at least one parameter set, so invalidate @@ -48,10 +46,9 @@ impl SlidingSyncListStickyParameters { } impl StickyData for SlidingSyncListStickyParameters { - type Request = v4::SyncRequestList; + type Request = http::request::List; - fn apply(&self, request: &mut v4::SyncRequestList) { - request.sort = self.sort.to_vec(); + fn apply(&self, request: &mut Self::Request) { request.room_details.required_state = self.required_state.to_vec(); request.room_details.timeline_limit = self.timeline_limit.map(Into::into); request.include_heroes = self.include_heroes; diff --git a/crates/matrix-sdk/src/sliding_sync/mod.rs b/crates/matrix-sdk/src/sliding_sync/mod.rs index 3a8d15265aa..c3748b1d408 100644 --- a/crates/matrix-sdk/src/sliding_sync/mod.rs +++ b/crates/matrix-sdk/src/sliding_sync/mod.rs @@ -34,13 +34,10 @@ use std::{ use async_stream::stream; use futures_core::stream::Stream; +pub use matrix_sdk_base::sliding_sync::http; use matrix_sdk_common::{ring_buffer::RingBuffer, timer}; use ruma::{ - api::client::{ - error::ErrorKind, - sync::sync_events::v4::{self, ExtensionsConfig}, - OutgoingRequest, - }, + api::{client::error::ErrorKind, OutgoingRequest}, assign, OwnedEventId, OwnedRoomId, RoomId, }; use serde::{Deserialize, Serialize}; @@ -150,7 +147,11 @@ impl SlidingSync { /// /// If the associated `Room` exists, it will be marked as /// members are missing, so that it ensures to re-fetch all members. - pub fn subscribe_to_room(&self, room_id: OwnedRoomId, settings: Option) { + pub fn subscribe_to_room( + &self, + room_id: OwnedRoomId, + settings: Option, + ) { if let Some(room) = self.inner.client.get_room(&room_id) { room.mark_members_missing(); } @@ -252,16 +253,13 @@ impl SlidingSync { #[instrument(skip_all)] async fn handle_response( &self, - mut sliding_sync_response: v4::Response, + mut sliding_sync_response: http::Response, position: &mut SlidingSyncPositionMarkers, ) -> Result { let pos = Some(sliding_sync_response.pos.clone()); { - debug!( - delta_token = ?sliding_sync_response.delta_token, - "Update position markers" - ); + debug!("Update position markers"); // Look up for this new `pos` in the past position markers. let past_positions = self.inner.past_positions.read().unwrap(); @@ -288,7 +286,7 @@ impl SlidingSync { // Transform a Sliding Sync Response to a `SyncResponse`. // // We may not need the `sync_response` in the future (once `SyncResponse` will - // move to Sliding Sync, i.e. to `v4::Response`), but processing the + // move to Sliding Sync, i.e. to `http::Response`), but processing the // `sliding_sync_response` is vital, so it must be done somewhere; for now it // happens here. @@ -435,7 +433,7 @@ impl SlidingSync { async fn generate_sync_request( &self, txn_id: &mut LazyTransactionId, - ) -> Result<(v4::Request, RequestConfig, OwnedMutexGuard)> { + ) -> Result<(http::Request, RequestConfig, OwnedMutexGuard)> { // Collect requests for lists. let mut requests_lists = BTreeMap::new(); @@ -489,7 +487,7 @@ impl SlidingSync { Span::current().record("pos", &pos); - let mut request = assign!(v4::Request::new(), { + let mut request = assign!(http::Request::new(), { conn_id: Some(self.inner.id.clone()), pos, timeout: Some(self.inner.poll_timeout), @@ -858,7 +856,7 @@ impl SlidingSync { /// Note: this is not the next content of the sticky parameters, but rightly /// the static configuration that was set during creation of this /// Sliding Sync. - pub fn extensions_config(&self) -> ExtensionsConfig { + pub fn extensions_config(&self) -> http::request::Extensions { let sticky = self.inner.sticky.read().unwrap(); sticky.data().extensions.clone() } @@ -918,25 +916,25 @@ pub struct UpdateSummary { pub(super) struct SlidingSyncStickyParameters { /// Room subscriptions, i.e. rooms that may be out-of-scope of all lists /// but one wants to receive updates. - room_subscriptions: BTreeMap, + room_subscriptions: BTreeMap, /// The intended state of the extensions being supplied to sliding /sync /// calls. - extensions: ExtensionsConfig, + extensions: http::request::Extensions, } impl SlidingSyncStickyParameters { /// Create a new set of sticky parameters. pub fn new( - room_subscriptions: BTreeMap, - extensions: ExtensionsConfig, + room_subscriptions: BTreeMap, + extensions: http::request::Extensions, ) -> Self { Self { room_subscriptions, extensions } } } impl StickyData for SlidingSyncStickyParameters { - type Request = v4::Request; + type Request = http::Request; fn apply(&self, request: &mut Self::Request) { request.room_subscriptions = self.room_subscriptions.clone(); @@ -951,7 +949,7 @@ impl StickyData for SlidingSyncStickyParameters { // NOTE: SS proxy workaround. fn compute_limited( local_rooms: &BTreeMap, - remote_rooms: &mut BTreeMap, + remote_rooms: &mut BTreeMap, ) { for (room_id, remote_room) in remote_rooms { // Only rooms marked as initially loaded are subject to the fixup. @@ -1037,13 +1035,8 @@ mod tests { use matrix_sdk_common::deserialized_responses::SyncTimelineEvent; use matrix_sdk_test::async_test; use ruma::{ - api::client::{ - error::ErrorKind, - sync::sync_events::v4::{self, ExtensionsConfig, ToDeviceConfig}, - }, - assign, owned_room_id, room_id, - serde::Raw, - uint, DeviceKeyAlgorithm, OwnedRoomId, TransactionId, + api::client::error::ErrorKind, assign, owned_room_id, room_id, serde::Raw, uint, + DeviceKeyAlgorithm, OwnedRoomId, TransactionId, }; use serde::Deserialize; use serde_json::json; @@ -1051,7 +1044,7 @@ mod tests { use wiremock::{http::Method, Match, Mock, MockServer, Request, ResponseTemplate}; use super::{ - compute_limited, + compute_limited, http, sticky_parameters::{LazyTransactionId, SlidingSyncStickyManager}, FrozenSlidingSync, SlidingSync, SlidingSyncList, SlidingSyncListBuilder, SlidingSyncMode, SlidingSyncRoom, SlidingSyncStickyParameters, @@ -1065,7 +1058,7 @@ mod tests { impl Match for SlidingSyncMatcher { fn matches(&self, request: &Request) -> bool { - request.url.path() == "/_matrix/client/unstable/org.matrix.msc3575/sync" + request.url.path() == "/_matrix/client/unstable/org.matrix.simplified_msc3575/sync" && request.method == Method::POST } } @@ -1233,7 +1226,7 @@ mod tests { // Then when we create a request, the sticky parameters are applied. let txn_id: &TransactionId = "tid123".into(); - let mut request = v4::Request::default(); + let mut request = http::Request::default(); request.txn_id = Some(txn_id.to_string()); sticky.maybe_apply(&mut request, &mut LazyTransactionId::from_owned(txn_id.to_owned())); @@ -1260,7 +1253,7 @@ mod tests { // Restarting a request will only remember the last generated transaction id. let txn_id1: &TransactionId = "tid456".into(); - let mut request1 = v4::Request::default(); + let mut request1 = http::Request::default(); request1.txn_id = Some(txn_id1.to_string()); sticky.maybe_apply(&mut request1, &mut LazyTransactionId::from_owned(txn_id1.to_owned())); @@ -1268,7 +1261,7 @@ mod tests { assert_eq!(request1.room_subscriptions.len(), 2); let txn_id2: &TransactionId = "tid789".into(); - let mut request2 = v4::Request::default(); + let mut request2 = http::Request::default(); request2.txn_id = Some(txn_id2.to_string()); sticky.maybe_apply(&mut request2, &mut LazyTransactionId::from_owned(txn_id2.to_owned())); @@ -1287,7 +1280,7 @@ mod tests { #[test] fn test_extensions_are_sticky() { - let mut extensions = ExtensionsConfig::default(); + let mut extensions = http::request::Extensions::default(); extensions.account_data.enabled = Some(true); // At first it's invalidated. @@ -1309,7 +1302,7 @@ mod tests { assert_eq!(extensions.account_data.enabled, Some(true),); let txn_id: &TransactionId = "tid123".into(); - let mut request = v4::Request::default(); + let mut request = http::Request::default(); request.txn_id = Some(txn_id.to_string()); sticky.maybe_apply(&mut request, &mut LazyTransactionId::from_owned(txn_id.to_owned())); assert!(sticky.is_invalidated()); @@ -1339,8 +1332,10 @@ mod tests { let sync = client .sliding_sync("test-slidingsync")? .add_list(SlidingSyncList::builder("new_list")) - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true)})) - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true)})) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true)}), + ) + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true)})) .build() .await?; @@ -1434,7 +1429,9 @@ mod tests { let sliding_sync = client .sliding_sync("test-slidingsync")? - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true) })) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true) }), + ) .build() .await?; @@ -1995,46 +1992,46 @@ mod tests { let mut remote_rooms = BTreeMap::from_iter([ ( not_initial.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { timeline: response_timeline }), + assign!(http::response::Room::default(), { timeline: response_timeline }), ), ( no_overlap.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), timeline: vec![event_c.event.clone(), event_d.event.clone()], }), ), ( partial_overlap.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), timeline: vec![event_c.event.clone(), event_d.event.clone()], }), ), ( complete_overlap.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), timeline: vec![event_c.event.clone(), event_d.event.clone()], }), ), ( no_remote_events.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), timeline: vec![], }), ), ( no_local_events.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), timeline: vec![event_c.event.clone(), event_d.event.clone()], }), ), ( already_limited.to_owned(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { initial: Some(true), limited: true, timeline: vec![event_c.event, event_d.event], @@ -2062,7 +2059,9 @@ mod tests { let sliding_sync = client .sliding_sync("test")? - .with_receipt_extension(assign!(v4::ReceiptsConfig::default(), { enabled: Some(true) })) + .with_receipt_extension( + assign!(http::request::Receipts::default(), { enabled: Some(true) }), + ) .add_list( SlidingSyncList::builder("all") .sync_mode(SlidingSyncMode::new_selective().add_range(0..=100)), @@ -2072,10 +2071,10 @@ mod tests { // Initial state. { - let server_response = assign!(v4::Response::new("0".to_owned()), { + let server_response = assign!(http::Response::new("0".to_owned()), { rooms: BTreeMap::from([( room.clone(), - v4::SlidingSyncRoom::default(), + http::response::Room::default(), )]) }); @@ -2085,9 +2084,9 @@ mod tests { }; } - let server_response = assign!(v4::Response::new("1".to_owned()), { - extensions: assign!(v4::Extensions::default(), { - receipts: assign!(v4::Receipts::default(), { + let server_response = assign!(http::Response::new("1".to_owned()), { + extensions: assign!(http::response::Extensions::default(), { + receipts: assign!(http::response::Receipts::default(), { rooms: BTreeMap::from([ ( room.clone(), @@ -2135,7 +2134,7 @@ mod tests { let sliding_sync = client .sliding_sync("test")? .with_account_data_extension( - assign!(v4::AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), ) .add_list( SlidingSyncList::builder("all") @@ -2146,10 +2145,10 @@ mod tests { // Initial state. { - let server_response = assign!(v4::Response::new("0".to_owned()), { + let server_response = assign!(http::Response::new("0".to_owned()), { rooms: BTreeMap::from([( room_id.clone(), - v4::SlidingSyncRoom::default(), + http::response::Room::default(), )]) }); @@ -2198,15 +2197,15 @@ mod tests { room_id: OwnedRoomId, unread: bool, add_rooms_section: bool, - ) -> v4::Response { + ) -> http::Response { let rooms = if add_rooms_section { - BTreeMap::from([(room_id.clone(), v4::SlidingSyncRoom::default())]) + BTreeMap::from([(room_id.clone(), http::response::Room::default())]) } else { BTreeMap::new() }; - let extensions = assign!(v4::Extensions::default(), { - account_data: assign!(v4::AccountData::default(), { + let extensions = assign!(http::response::Extensions::default(), { + account_data: assign!(http::response::AccountData::default(), { rooms: BTreeMap::from([ ( room_id, @@ -2226,7 +2225,7 @@ mod tests { }) }); - assign!(v4::Response::new(response_number.to_owned()), { rooms: rooms, extensions: extensions }) + assign!(http::Response::new(response_number.to_owned()), { rooms: rooms, extensions: extensions }) } #[async_test] @@ -2239,7 +2238,7 @@ mod tests { let sliding_sync = client .sliding_sync("test")? .with_account_data_extension( - assign!(v4::AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), ) .add_list( SlidingSyncList::builder("all") @@ -2250,10 +2249,10 @@ mod tests { // Initial state. { - let server_response = assign!(v4::Response::new("0".to_owned()), { + let server_response = assign!(http::Response::new("0".to_owned()), { rooms: BTreeMap::from([( room.clone(), - v4::SlidingSyncRoom::default(), + http::response::Room::default(), )]) }); @@ -2263,9 +2262,9 @@ mod tests { }; } - let server_response = assign!(v4::Response::new("1".to_owned()), { - extensions: assign!(v4::Extensions::default(), { - account_data: assign!(v4::AccountData::default(), { + let server_response = assign!(http::Response::new("1".to_owned()), { + extensions: assign!(http::response::Extensions::default(), { + account_data: assign!(http::response::AccountData::default(), { rooms: BTreeMap::from([ ( room.clone(), @@ -2307,20 +2306,20 @@ mod tests { let server = MockServer::start().await; let client = logged_in_client(Some(server.uri())).await; - let server_response = assign!(v4::Response::new("0".to_owned()), { + let server_response = assign!(http::Response::new("0".to_owned()), { rooms: BTreeMap::from([( room.clone(), - assign!(v4::SlidingSyncRoom::default(), { + assign!(http::response::Room::default(), { name: Some("Croissants lovers".to_owned()), timeline: Vec::new(), }), )]), - extensions: assign!(v4::Extensions::default(), { - e2ee: assign!(v4::E2EE::default(), { + extensions: assign!(http::response::Extensions::default(), { + e2ee: assign!(http::response::E2EE::default(), { device_one_time_keys_count: BTreeMap::from([(DeviceKeyAlgorithm::SignedCurve25519, uint!(42))]) }), - to_device: Some(assign!(v4::ToDevice::default(), { + to_device: Some(assign!(http::response::ToDevice::default(), { next_batch: "to-device-token".to_owned(), })), }) @@ -2331,8 +2330,10 @@ mod tests { let sliding_sync = client .sliding_sync("test")? - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true)})) - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true)})) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true)}), + ) + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true)})) .build() .await?; @@ -2394,8 +2395,10 @@ mod tests { let sliding_sync = client .sliding_sync("test")? .add_list(SlidingSyncList::builder("thelist")) - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true)})) - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true)})) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true)}), + ) + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true)})) .build() .await?; @@ -2444,8 +2447,10 @@ mod tests { let sliding_sync = client .sliding_sync("test")? - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true)})) - .with_e2ee_extension(assign!(v4::E2EEConfig::default(), { enabled: Some(true)})) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true)}), + ) + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true)})) .build() .await?; diff --git a/crates/matrix-sdk/src/sliding_sync/room.rs b/crates/matrix-sdk/src/sliding_sync/room.rs index 095b86ccb7a..93e0e4b17fb 100644 --- a/crates/matrix-sdk/src/sliding_sync/room.rs +++ b/crates/matrix-sdk/src/sliding_sync/room.rs @@ -4,8 +4,8 @@ use std::{ }; use eyeball_im::Vector; -use matrix_sdk_base::deserialized_responses::SyncTimelineEvent; -use ruma::{api::client::sync::sync_events::v4, OwnedRoomId, RoomId}; +use matrix_sdk_base::{deserialized_responses::SyncTimelineEvent, sliding_sync::http}; +use ruma::{OwnedRoomId, RoomId}; use serde::{Deserialize, Serialize}; use crate::Client; @@ -81,10 +81,10 @@ impl SlidingSyncRoom { pub(super) fn update( &mut self, - room_data: v4::SlidingSyncRoom, + room_data: http::response::Room, timeline_updates: Vec, ) { - let v4::SlidingSyncRoom { prev_batch, limited, .. } = room_data; + let http::response::Room { prev_batch, limited, .. } = room_data; { if let Some(prev_batch) = &prev_batch { @@ -230,14 +230,11 @@ mod tests { use matrix_sdk_base::deserialized_responses::TimelineEvent; use matrix_sdk_common::deserialized_responses::SyncTimelineEvent; use matrix_sdk_test::async_test; - use ruma::{ - api::client::sync::sync_events::v4, events::room::message::RoomMessageEventContent, - room_id, serde::Raw, RoomId, - }; + use ruma::{events::room::message::RoomMessageEventContent, room_id, serde::Raw, RoomId}; use serde_json::json; use wiremock::MockServer; - use super::NUMBER_OF_TIMELINE_EVENTS_TO_KEEP_FOR_THE_CACHE; + use super::{http, NUMBER_OF_TIMELINE_EVENTS_TO_KEEP_FOR_THE_CACHE}; use crate::{ sliding_sync::{FrozenSlidingSyncRoom, SlidingSyncRoom, SlidingSyncRoomState}, test_utils::logged_in_client, @@ -245,19 +242,19 @@ mod tests { macro_rules! room_response { ( $( $json:tt )+ ) => { - serde_json::from_value::( + serde_json::from_value::( json!( $( $json )+ ) ).unwrap() }; } - async fn new_room(room_id: &RoomId, inner: v4::SlidingSyncRoom) -> SlidingSyncRoom { + async fn new_room(room_id: &RoomId, inner: http::response::Room) -> SlidingSyncRoom { new_room_with_timeline(room_id, inner, vec![]).await } async fn new_room_with_timeline( room_id: &RoomId, - inner: v4::SlidingSyncRoom, + inner: http::response::Room, timeline: Vec, ) -> SlidingSyncRoom { let server = MockServer::start().await; diff --git a/crates/matrix-sdk/tests/integration/encryption/backups.rs b/crates/matrix-sdk/tests/integration/encryption/backups.rs index 8908ff14924..fe0ab56513f 100644 --- a/crates/matrix-sdk/tests/integration/encryption/backups.rs +++ b/crates/matrix-sdk/tests/integration/encryption/backups.rs @@ -763,7 +763,7 @@ async fn incremental_upload_of_keys_sliding_sync() -> Result<()> { }); Mock::given(method("POST")) - .and(path("_matrix/client/unstable/org.matrix.msc3575/sync")) + .and(path("_matrix/client/unstable/org.matrix.simplified_msc3575/sync")) .and(header("authorization", "Bearer 1234")) .respond_with(ResponseTemplate::new(200).set_body_json(json!({ "pos": "5", diff --git a/testing/matrix-sdk-integration-testing/Cargo.toml b/testing/matrix-sdk-integration-testing/Cargo.toml index c6b137acf41..83ec826ecd1 100644 --- a/testing/matrix-sdk-integration-testing/Cargo.toml +++ b/testing/matrix-sdk-integration-testing/Cargo.toml @@ -16,7 +16,8 @@ futures = { version = "0.3.29", features = ["executor"] } futures-core = { workspace = true } futures-util = { workspace = true } http = { workspace = true } -matrix-sdk = { workspace = true, default-features = true, features = ["testing", "qrcode"] } +matrix-sdk = {workspace = true, default-features = true, features = ["testing", "qrcode"] } +matrix-sdk-base = { workspace = true, default-features = true, features = ["testing", "qrcode"] } matrix-sdk-ui = { workspace = true, default-features = true } matrix-sdk-test = { workspace = true } once_cell = { workspace = true } diff --git a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/mod.rs b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/mod.rs index 98036d034ed..58419212825 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/mod.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/mod.rs @@ -1,2 +1,2 @@ -mod notification_client; -mod room; +// mod notification_client; +// mod room; diff --git a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs index 083b5ec2892..12f6006092a 100644 --- a/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs +++ b/testing/matrix-sdk-integration-testing/src/tests/sliding_sync/room.rs @@ -16,9 +16,6 @@ use matrix_sdk::{ api::client::{ receipt::create_receipt::v3::ReceiptType, room::create_room::v3::{Request as CreateRoomRequest, RoomPreset}, - sync::sync_events::v4::{ - AccountDataConfig, E2EEConfig, ReceiptsConfig, ToDeviceConfig, - }, }, assign, events::{ @@ -36,6 +33,7 @@ use matrix_sdk::{ }, Client, RoomInfo, RoomMemberships, RoomState, SlidingSyncList, SlidingSyncMode, }; +use matrix_sdk_base::sliding_sync::http; use matrix_sdk_ui::{ room_list_service::filters::new_filter_all, sync_service::SyncService, timeline::RoomExt, RoomListService, @@ -379,12 +377,16 @@ async fn test_room_notification_count() -> Result<()> { spawn({ let sync = alice .sliding_sync("main")? - .with_receipt_extension(assign!(ReceiptsConfig::default(), { enabled: Some(true) })) + .with_receipt_extension( + assign!(http::request::Receipts::default(), { enabled: Some(true) }), + ) .with_account_data_extension( - assign!(AccountDataConfig::default(), { enabled: Some(true) }), + assign!(http::request::AccountData::default(), { enabled: Some(true) }), + ) + .with_e2ee_extension(assign!(http::request::E2EE::default(), { enabled: Some(true) })) + .with_to_device_extension( + assign!(http::request::ToDevice::default(), { enabled: Some(true) }), ) - .with_e2ee_extension(assign!(E2EEConfig::default(), { enabled: Some(true) })) - .with_to_device_extension(assign!(ToDeviceConfig::default(), { enabled: Some(true) })) .add_list( SlidingSyncList::builder("all") .sync_mode(SlidingSyncMode::new_selective().add_range(0..=20)) From 07b20049f0ad8adea164915cc91ecc3e161cc55c Mon Sep 17 00:00:00 2001 From: Ivan Enderlin Date: Mon, 15 Jul 2024 14:32:01 +0200 Subject: [PATCH 11/11] doc(sdk): Fix some typos in the documentation. --- crates/matrix-sdk-base/src/sliding_sync/http.rs | 4 ++-- .../matrix-sdk-ui/src/room_list_service/sorters/recency.rs | 6 ++++-- crates/matrix-sdk/src/sliding_sync/cache.rs | 6 +++--- testing/matrix-sdk-integration-testing/src/helpers.rs | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/crates/matrix-sdk-base/src/sliding_sync/http.rs b/crates/matrix-sdk-base/src/sliding_sync/http.rs index ca2233a52db..82879253265 100644 --- a/crates/matrix-sdk-base/src/sliding_sync/http.rs +++ b/crates/matrix-sdk-base/src/sliding_sync/http.rs @@ -1,4 +1,4 @@ -// Copyright 2023 The Matrix.org Foundation C.I.C. +// Copyright 2024 The Matrix.org Foundation C.I.C. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -14,7 +14,7 @@ //! HTTP types for (Simplified) MSC3575. //! -//! This module provides a unified namings for types from MSC3575 and +//! This module provides unified namings for types from MSC3575 and //! Simplified MSC3575, in addition to provide conversion from one //! format to another. diff --git a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs index c70ebb3ce2a..7dde5db79d8 100644 --- a/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs +++ b/crates/matrix-sdk-ui/src/room_list_service/sorters/recency.rs @@ -64,8 +64,10 @@ where } /// Create a new sorter that will sort two [`Room`] by recency, i.e. by -/// comparing their [`matrix_sdk_base::RoomInfo::recency_stamp`] value. The -/// `Room` with the newest recency stamp comes first, i.e. newest < oldest. +/// comparing their [`RoomInfo::recency_stamp`] value. The `Room` with the +/// newest recency stamp comes first, i.e. newest < oldest. +/// +/// [`RoomInfo::recency_stamp`]: matrix_sdk_base::RoomInfo::recency_stamp pub fn new_sorter() -> impl Sorter { let matcher = RecencyMatcher { recency_stamps: move |left, right| (left.recency_stamp(), right.recency_stamp()), diff --git a/crates/matrix-sdk/src/sliding_sync/cache.rs b/crates/matrix-sdk/src/sliding_sync/cache.rs index 97a03462100..27b906b153b 100644 --- a/crates/matrix-sdk/src/sliding_sync/cache.rs +++ b/crates/matrix-sdk/src/sliding_sync/cache.rs @@ -522,7 +522,7 @@ mod tests { .await? .expect("must have restored sliding sync fields"); - // After restoring, the delta token and to-device token could be read. + // After restoring, to-device token could be read. assert_eq!(restored_fields.pos.unwrap(), pos); // Test the "migration" path: assume a missing to-device token in crypto store, @@ -557,8 +557,8 @@ mod tests { .await? .expect("must have restored fields"); - // After restoring, the delta token, the to-device since token, stream - // position and rooms could be read from the state store. + // After restoring, the to-device since token, stream position and rooms could + // be read from the state store. assert_eq!(restored_fields.to_device_token.unwrap(), to_device_token); assert_eq!(restored_fields.pos.unwrap(), pos); assert_eq!(restored_fields.rooms.len(), 1); diff --git a/testing/matrix-sdk-integration-testing/src/helpers.rs b/testing/matrix-sdk-integration-testing/src/helpers.rs index dc8a63de381..60a89d95d9a 100644 --- a/testing/matrix-sdk-integration-testing/src/helpers.rs +++ b/testing/matrix-sdk-integration-testing/src/helpers.rs @@ -88,8 +88,8 @@ impl TestClientBuilder { .user_agent("matrix-sdk-integration-tests") .homeserver_url(homeserver_url) .sliding_sync_proxy(sliding_sync_proxy_url) - // Disable Simplified MSC3575 for the integration tests as, at the time of writing, we - // use a Synapse version that doesn't support Simplified MSC3575. + // Disable Simplified MSC3575 for the integration tests as, at the time of writing + // (2024-07-15), we use a Synapse version that doesn't support Simplified MSC3575. .simplified_sliding_sync(false) .with_encryption_settings(self.encryption_settings) .request_config(RequestConfig::short_retry());