Skip to content

Commit 8d0f9ff

Browse files
committed
fix(timeline): Allow focused timelines to replace UTDs with decrypted events
1 parent 7235585 commit 8d0f9ff

File tree

2 files changed

+82
-23
lines changed

2 files changed

+82
-23
lines changed

crates/matrix-sdk-ui/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ All notable changes to this project will be documented in this file.
1919
to network mode after a cache miss.
2020
([#5930](https://github.com/matrix-org/matrix-rust-sdk/pull/5930))
2121

22+
### Bug Fixes
23+
24+
- Fix the redecryption of events in timelines built using the
25+
`TimelineFocus` of `PinnedEvents`, `Thread`, `Event`.
26+
([#5955](https://github.com/matrix-org/matrix-rust-sdk/pull/5955))
27+
2228
## [0.16.0] - 2025-12-04
2329

2430
### Features

crates/matrix-sdk-ui/src/timeline/controller/state_transaction.rs

Lines changed: 76 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -210,7 +210,7 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> {
210210
let event_id = deserialized.event_id().to_owned();
211211
let txn_id = deserialized.transaction_id().map(ToOwned::to_owned);
212212

213-
if let Some(action @ TimelineAction::HandleAggregation { .. }) = TimelineAction::from_event(
213+
let timeline_action = TimelineAction::from_event(
214214
deserialized,
215215
raw_event,
216216
room_data_provider,
@@ -219,31 +219,50 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> {
219219
None,
220220
None,
221221
)
222-
.await
223-
{
224-
let encryption_info = event.kind.encryption_info().cloned();
222+
.await;
225223

226-
let sender_profile = room_data_provider.profile_from_user_id(&sender).await;
224+
match timeline_action {
225+
Some(action @ TimelineAction::AddItem { .. })
226+
| Some(action @ TimelineAction::HandleAggregation { .. }) => {
227+
let encryption_info = event.kind.encryption_info().cloned();
228+
let sender_profile = room_data_provider.profile_from_user_id(&sender).await;
229+
let mut ctx = TimelineEventContext {
230+
sender,
231+
sender_profile,
232+
timestamp,
233+
// These are not used when handling an aggregation.
234+
read_receipts: Default::default(),
235+
is_highlighted: false,
236+
flow: Flow::Remote {
237+
event_id: event_id.clone(),
238+
raw_event: event.raw().clone(),
239+
encryption_info,
240+
txn_id,
241+
position,
242+
},
243+
// This field is not used when handling an aggregation.
244+
should_add_new_items: false,
245+
};
227246

228-
let ctx = TimelineEventContext {
229-
sender,
230-
sender_profile,
231-
timestamp,
232-
// These are not used when handling an aggregation.
233-
read_receipts: Default::default(),
234-
is_highlighted: false,
235-
flow: Flow::Remote {
236-
event_id: event_id.clone(),
237-
raw_event: event.raw().clone(),
238-
encryption_info,
239-
txn_id,
240-
position,
241-
},
242-
// This field is not used when handling an aggregation.
243-
should_add_new_items: false,
244-
};
247+
// FIXME: Continuation of the hackjob to get UTDs for focused timelines
248+
// working from `handle_remote_aggregations()`.
249+
if let TimelineAction::AddItem { .. } = action
250+
&& let TimelineItemPosition::UpdateAt { timeline_item_index } = position
251+
&& let Some(event) = self.items.get(timeline_item_index)
252+
&& event
253+
.as_event()
254+
.map(|e| e.content().is_unable_to_decrypt())
255+
.unwrap_or_default()
256+
{
257+
// Except when this is an UTD transitioning into a decrypted event.
258+
ctx.should_add_new_items = true;
259+
}
245260

246-
TimelineEventHandler::new(self, ctx).handle_event(date_divider_adjuster, action).await;
261+
TimelineEventHandler::new(self, ctx)
262+
.handle_event(date_divider_adjuster, action)
263+
.await;
264+
}
265+
None => {}
247266
}
248267
}
249268

@@ -321,6 +340,40 @@ impl<'a, P: RoomDataProvider> TimelineStateTransaction<'a, P> {
321340
&mut date_divider_adjuster,
322341
)
323342
.await;
343+
} else if let Some(event_id) = event.event_id()
344+
&& let Some(meta) =
345+
self.items.all_remote_events().get_by_event_id(&event_id)
346+
&& let Some(timeline_item_index) = meta.timeline_item_index
347+
{
348+
// FIXME: This branch is a complete hackjob.
349+
//
350+
// The reason being is that this branch is here to handle UTD -> Decrypted
351+
// event remplacements for focused timelines. But this transition should
352+
// naturally happen the same way it happens for unfocused timelines.
353+
//
354+
// Why it doesn't work here? Because the event cache fires out a
355+
// VectorDiff::Set with an index that matches to the cache's view of the
356+
// timeline, which is unfiltered, while the focused timeline will only show
357+
// i.e. pinned events.
358+
//
359+
// The `test_pinned_events_are_decrypted_after_recovering` integration test
360+
// showcases this. The event cache fires out the `Set` with an index of 7,
361+
// but the timeline with the PinnedEvents focus has only 4 items.
362+
//
363+
// This hackjob continues in the `handle_remote_aggregation()` method as we
364+
// can't just handle any `TimelineAction::AddItem` due to:
365+
// https://github.com/matrix-org/matrix-rust-sdk/pull/4645
366+
//
367+
// Doing so breaks the `test_new_pinned_events_are_not_added_on_sync` test.
368+
//
369+
// Relevant issue: https://github.com/matrix-org/matrix-rust-sdk/issues/5954.
370+
self.handle_remote_aggregation(
371+
event,
372+
TimelineItemPosition::UpdateAt { timeline_item_index },
373+
room_data_provider,
374+
&mut date_divider_adjuster,
375+
)
376+
.await;
324377
} else {
325378
warn!(
326379
event_index,

0 commit comments

Comments
 (0)