Skip to content

refactor(timeline): Make RoomDataProvider provide Decryptor to simplify redecryption #5517

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 16 additions & 30 deletions crates/matrix-sdk-ui/src/timeline/controller/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,17 @@ use eyeball_im_util::vector::{FilterMap, VectorObserverExt};
use futures_core::Stream;
use imbl::Vector;
#[cfg(test)]
use matrix_sdk::crypto::OlmMachine;
use matrix_sdk::Result;
use matrix_sdk::{
Result, Room,
deserialized_responses::TimelineEvent,
event_cache::{RoomEventCache, RoomPaginationStatus},
paginators::{PaginationResult, Paginator},
send_queue::{
LocalEcho, LocalEchoContent, RoomSendQueueUpdate, SendHandle, SendReactionHandle,
},
};
#[cfg(test)]
use ruma::events::receipt::ReceiptEventContent;
use ruma::{
EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, TransactionId, UserId,
api::client::receipt::create_receipt::v3::ReceiptType as SendReceiptType,
Expand All @@ -46,8 +47,6 @@ use ruma::{
room_version_rules::RoomVersionRules,
serde::Raw,
};
#[cfg(test)]
use ruma::{OwnedRoomId, RoomId, events::receipt::ReceiptEventContent};
use tokio::sync::{RwLock, RwLockWriteGuard};
use tracing::{debug, error, field::debug, info, instrument, trace, warn};

Expand All @@ -68,11 +67,11 @@ use super::{
event_item::{ReactionStatus, RemoteEventOrigin},
item::TimelineUniqueId,
subscriber::TimelineSubscriber,
traits::{Decryptor, RoomDataProvider},
traits::RoomDataProvider,
};
use crate::{
timeline::{
MsgLikeContent, MsgLikeKind, TimelineEventFilterFn,
MsgLikeContent, MsgLikeKind, Room, TimelineEventFilterFn,
algorithms::rfind_event_by_item_id,
date_dividers::DateDividerAdjuster,
event_item::TimelineItemHandle,
Expand Down Expand Up @@ -152,7 +151,7 @@ impl<P: RoomDataProvider> TimelineFocusKind<P> {
}

#[derive(Clone, Debug)]
pub(super) struct TimelineController<P: RoomDataProvider = Room, D: Decryptor = Room> {
pub(super) struct TimelineController<P: RoomDataProvider = Room> {
/// Inner mutable state.
state: Arc<RwLock<TimelineState<P>>>,

Expand All @@ -161,15 +160,16 @@ pub(super) struct TimelineController<P: RoomDataProvider = Room, D: Decryptor =

/// A [`RoomDataProvider`] implementation, providing data.
///
/// Useful for testing only; in the real world, it's just a [`Room`].
/// The type is a `RoomDataProvider` to allow testing. In the real world,
/// this would normally be a [`Room`].
pub(crate) room_data_provider: P,

/// Settings applied to this timeline.
pub(super) settings: TimelineSettings,

/// Long-running task used to retry decryption of timeline items without
/// blocking main processing.
decryption_retry_task: DecryptionRetryTask<P, D>,
decryption_retry_task: DecryptionRetryTask<P, P>,
}

#[derive(Clone)]
Expand Down Expand Up @@ -290,7 +290,7 @@ pub fn default_event_filter(event: &AnySyncTimelineEvent, rules: &RoomVersionRul
}
}

impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
impl<P: RoomDataProvider> TimelineController<P> {
pub(super) fn new(
room_data_provider: P,
focus: TimelineFocus,
Expand Down Expand Up @@ -1103,12 +1103,10 @@ impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
true
}

async fn retry_event_decryption_inner(
&self,
decryptor: D,
session_ids: Option<BTreeSet<String>>,
) {
self.decryption_retry_task.decrypt(decryptor, session_ids, self.settings.clone()).await;
pub(crate) async fn retry_event_decryption_inner(&self, session_ids: Option<BTreeSet<String>>) {
self.decryption_retry_task
.decrypt(self.room_data_provider.clone(), session_ids, self.settings.clone())
.await;
}

pub(super) async fn set_sender_profiles_pending(&self) {
Expand Down Expand Up @@ -1250,7 +1248,7 @@ impl<P: RoomDataProvider, D: Decryptor> TimelineController<P, D> {
/// Subscribe to changes in the read receipts of our own user.
pub async fn subscribe_own_user_read_receipts_changed(
&self,
) -> impl Stream<Item = ()> + use<P, D> {
) -> impl Stream<Item = ()> + use<P> {
self.state.read().await.meta.read_receipts.subscribe_own_user_read_receipts_changed()
}

Expand Down Expand Up @@ -1604,7 +1602,7 @@ impl TimelineController {

#[instrument(skip(self), fields(room_id = ?self.room().room_id()))]
pub(super) async fn retry_event_decryption(&self, session_ids: Option<BTreeSet<String>>) {
self.retry_event_decryption_inner(self.room().clone(), session_ids).await
self.retry_event_decryption_inner(session_ids).await
}

/// Combine the global (event cache) pagination status with the local state
Expand Down Expand Up @@ -1638,18 +1636,6 @@ impl TimelineController {
}
}

#[cfg(test)]
impl<P: RoomDataProvider> TimelineController<P, (OlmMachine, OwnedRoomId)> {
pub(super) async fn retry_event_decryption_test(
&self,
room_id: &RoomId,
olm_machine: OlmMachine,
session_ids: Option<BTreeSet<String>>,
) {
self.retry_event_decryption_inner((olm_machine, room_id.to_owned()), session_ids).await
}
}

#[allow(clippy::too_many_arguments)]
async fn fetch_replied_to_event<P: RoomDataProvider>(
mut state_guard: RwLockWriteGuard<'_, TimelineState<P>>,
Expand Down
Loading
Loading