Skip to content

Commit d90576b

Browse files
committed
fix(timeline): when loading initial receipts for main|unthreaded, load both kinds
This is a fix, because some other code elsewhere will use both kinds of receipts whenever they're received over sync. The code that's modified in this patch is called for the initial load of receipts, that happens whenever we see a new event. Since the two code paths were not doing the same thing, this would affect the displayed receipts, depending on whether we received them during sync, or after loading the timeline for the first time.
1 parent bbeb2d2 commit d90576b

File tree

1 file changed

+42
-16
lines changed

1 file changed

+42
-16
lines changed

crates/matrix-sdk-ui/src/timeline/traits.rs

Lines changed: 42 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -232,34 +232,60 @@ impl RoomDataProvider for Room {
232232
event_id: &'a EventId,
233233
receipt_thread: ReceiptThread,
234234
) -> IndexMap<OwnedUserId, Receipt> {
235-
let mut result = match self
236-
.load_event_receipts(ReceiptType::Read, receipt_thread.clone(), event_id)
237-
.await
238-
{
239-
Ok(receipts) => receipts.into_iter().collect(),
240-
Err(e) => {
241-
error!(?event_id, ?receipt_thread, "Failed to get read receipts for event: {e}");
242-
IndexMap::new()
243-
}
244-
};
235+
if matches!(receipt_thread, ReceiptThread::Unthreaded | ReceiptThread::Main) {
236+
// If the requested receipt thread is unthreaded or main, we maintain maximal
237+
// compatibility with clients using either unthreaded or main-thread read
238+
// receipts by allowing both here.
245239

246-
if receipt_thread == ReceiptThread::Unthreaded {
247-
// Include the main thread receipts as well, to be maximally compatible with
248-
// clients using either the unthreaded or main thread receipt type.
249-
let main_thread_receipts = match self
240+
// First, load the main receipts.
241+
let mut result = match self
250242
.load_event_receipts(ReceiptType::Read, ReceiptThread::Main, event_id)
251243
.await
244+
{
245+
Ok(receipts) => receipts.into_iter().collect(),
246+
Err(e) => {
247+
error!(?event_id, "Failed to get main thread read receipts for event: {e}");
248+
IndexMap::new()
249+
}
250+
};
251+
252+
// Then, load the unthreaded receipts.
253+
let unthreaded_receipts = match self
254+
.load_event_receipts(ReceiptType::Read, ReceiptThread::Unthreaded, event_id)
255+
.await
252256
{
253257
Ok(receipts) => receipts,
254258
Err(e) => {
255259
error!(?event_id, "Failed to get main thread read receipts for event: {e}");
256260
Vec::new()
257261
}
258262
};
259-
result.extend(main_thread_receipts);
263+
264+
// Only insert unthreaded receipts that are more recent. Ideally we'd compare
265+
// the receipted event position, but we don't have access to that
266+
// here.
267+
for (user_id, unthreaded_receipt) in unthreaded_receipts {
268+
if let Some(main_receipt) = result.get(&user_id) {
269+
if unthreaded_receipt.ts > main_receipt.ts {
270+
result.insert(user_id, unthreaded_receipt);
271+
}
272+
} else {
273+
result.insert(user_id, unthreaded_receipt);
274+
}
275+
}
276+
277+
return result;
260278
}
261279

262-
result
280+
// In all other cases, return what's requested, and only that (threaded
281+
// receipts).
282+
match self.load_event_receipts(ReceiptType::Read, receipt_thread.clone(), event_id).await {
283+
Ok(receipts) => receipts.into_iter().collect(),
284+
Err(e) => {
285+
error!(?event_id, ?receipt_thread, "Failed to get read receipts for event: {e}");
286+
IndexMap::new()
287+
}
288+
}
263289
}
264290

265291
async fn push_context(&self) -> Option<PushContext> {

0 commit comments

Comments
 (0)