Skip to content

Commit 095a5ed

Browse files
committed
refactor(timeline): apply aggregation in a single place
1 parent 6da988e commit 095a5ed

File tree

3 files changed

+57
-93
lines changed

3 files changed

+57
-93
lines changed

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

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@
4040
use std::collections::HashMap;
4141

4242
use ruma::{MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedTransactionId, OwnedUserId};
43-
use tracing::warn;
43+
use tracing::{trace, warn};
4444

45+
use super::{rfind_event_by_item_id, ObservableItemsTransaction};
4546
use crate::timeline::{
46-
PollState, ReactionInfo, ReactionStatus, TimelineEventItemId, TimelineItemContent,
47+
PollState, ReactionInfo, ReactionStatus, TimelineEventItemId, TimelineItem, TimelineItemContent,
4748
};
4849

4950
/// Which kind of aggregation (related event) is this?
@@ -369,6 +370,41 @@ impl Aggregations {
369370
}
370371
}
371372

373+
/// Find an item identified by the target identifier, and apply the aggregation
374+
/// onto it.
375+
///
376+
/// Returns whether the aggregation has been applied or not (so as to increment
377+
/// a number of updated result, for instance).
378+
pub(crate) fn find_item_and_apply_aggregation(
379+
items: &mut ObservableItemsTransaction<'_>,
380+
target: &TimelineEventItemId,
381+
aggregation: Aggregation,
382+
) -> bool {
383+
let Some((idx, event_item)) = rfind_event_by_item_id(items, &target) else {
384+
warn!("couldn't find aggregation's target {target:?}");
385+
return false;
386+
};
387+
388+
let mut new_content = event_item.content().clone();
389+
390+
match aggregation.apply(&mut new_content) {
391+
Ok(true) => {
392+
trace!("applied aggregation");
393+
let new_item = event_item.with_content(new_content);
394+
items.replace(idx, TimelineItem::new(new_item, event_item.internal_id.to_owned()));
395+
true
396+
}
397+
Ok(false) => {
398+
trace!("applying the aggregation had no effect");
399+
false
400+
}
401+
Err(err) => {
402+
warn!("error when applying aggregation: {err}");
403+
false
404+
}
405+
}
406+
}
407+
372408
/// The result of marking an aggregation as sent.
373409
pub(crate) enum MarkAggregationSentResult {
374410
/// The aggregation has been found, and marked as sent.

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

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1357,6 +1357,7 @@ impl<P: RoomDataProvider> TimelineController<P> {
13571357
applies_to: OwnedTransactionId,
13581358
) {
13591359
let mut state = self.state.write().await;
1360+
let mut tr = state.transaction();
13601361

13611362
let target = TimelineEventItemId::TransactionId(applies_to);
13621363

@@ -1372,26 +1373,10 @@ impl<P: RoomDataProvider> TimelineController<P> {
13721373
},
13731374
);
13741375

1375-
state.meta.aggregations.add(target.clone(), aggregation.clone());
1376+
tr.meta.aggregations.add(target.clone(), aggregation.clone());
1377+
find_item_and_apply_aggregation(&mut tr.items, &target, aggregation);
13761378

1377-
let Some((item_pos, item)) = rfind_event_by_item_id(&state.items, &target) else {
1378-
warn!("Local item not found anymore.");
1379-
return;
1380-
};
1381-
1382-
let mut content = item.content().clone();
1383-
match aggregation.apply(&mut content) {
1384-
Ok(true) => {
1385-
trace!("added local reaction to local echo");
1386-
let internal_id = item.internal_id.clone();
1387-
let new_item = item.with_content(content);
1388-
state.items.replace(item_pos, TimelineItem::new(new_item, internal_id));
1389-
}
1390-
Ok(false) => {}
1391-
Err(err) => {
1392-
warn!("when applying local reaction to local echo: {err}");
1393-
}
1394-
}
1379+
tr.commit();
13951380
}
13961381

13971382
/// Handle a single room send queue update.

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

Lines changed: 15 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,9 @@ use tracing::{debug, error, field::debug, info, instrument, trace, warn};
5353
use super::{
5454
algorithms::{rfind_event_by_id, rfind_event_by_item_id},
5555
controller::{
56-
Aggregation, AggregationKind, ObservableItemsTransaction, ObservableItemsTransactionEntry,
57-
PendingEdit, PendingEditKind, TimelineMetadata, TimelineStateTransaction,
56+
find_item_and_apply_aggregation, Aggregation, AggregationKind, ObservableItemsTransaction,
57+
ObservableItemsTransactionEntry, PendingEdit, PendingEditKind, TimelineMetadata,
58+
TimelineStateTransaction,
5859
},
5960
date_dividers::DateDividerAdjuster,
6061
event_item::{
@@ -717,7 +718,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
717718
/// [`crate::timeline::TimelineController::handle_local_echo`].
718719
#[instrument(skip_all, fields(relates_to_event_id = ?c.relates_to.event_id))]
719720
fn handle_reaction(&mut self, c: ReactionEventContent) {
720-
let reacted_to_event_id = &c.relates_to.event_id;
721+
let target = TimelineEventItemId::EventId(c.relates_to.event_id);
721722

722723
// Add the aggregation to the manager.
723724
let reaction_status = match &self.ctx.flow {
@@ -739,28 +740,10 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
739740
reaction_status,
740741
},
741742
);
742-
self.meta
743-
.aggregations
744-
.add(TimelineEventItemId::EventId(reacted_to_event_id.clone()), aggregation.clone());
745743

746-
let Some((idx, event_item)) = rfind_event_by_id(self.items, reacted_to_event_id) else {
747-
warn!("couldn't find reaction's target {reacted_to_event_id:?}");
748-
return;
749-
};
750-
751-
let mut new_content = event_item.content().clone();
752-
match aggregation.apply(&mut new_content) {
753-
Ok(true) => {
754-
trace!("added reaction");
755-
let new_item = event_item.with_content(new_content);
756-
self.items
757-
.replace(idx, TimelineItem::new(new_item, event_item.internal_id.to_owned()));
758-
self.result.items_updated += 1;
759-
}
760-
Ok(false) => {}
761-
Err(err) => {
762-
warn!("error when applying reaction aggregation: {err}");
763-
}
744+
self.meta.aggregations.add(target.clone(), aggregation.clone());
745+
if find_item_and_apply_aggregation(&mut *self.items, &target, aggregation) {
746+
self.result.items_updated += 1;
764747
}
765748
}
766749

@@ -864,8 +847,7 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
864847
}
865848

866849
fn handle_poll_response(&mut self, c: UnstablePollResponseEventContent) {
867-
let start_event_id = c.relates_to.event_id;
868-
850+
let target = TimelineEventItemId::EventId(c.relates_to.event_id);
869851
let aggregation = Aggregation::new(
870852
self.ctx.flow.timeline_item_id(),
871853
AggregationKind::PollResponse {
@@ -874,60 +856,21 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
874856
answers: c.poll_response.answers,
875857
},
876858
);
877-
878-
self.meta
879-
.aggregations
880-
.add(TimelineEventItemId::EventId(start_event_id.clone()), aggregation.clone());
881-
882-
let Some((item_pos, item)) = rfind_event_by_id(self.items, &start_event_id) else {
883-
return;
884-
};
885-
886-
let mut new_content = item.content().clone();
887-
match aggregation.apply(&mut new_content) {
888-
Ok(true) => {
889-
trace!("adding poll response.");
890-
self.items.replace(
891-
item_pos,
892-
TimelineItem::new(item.with_content(new_content), item.internal_id.clone()),
893-
);
894-
self.result.items_updated += 1;
895-
}
896-
Ok(false) => {}
897-
Err(err) => {
898-
warn!("discarding poll response: {err}");
899-
}
859+
self.meta.aggregations.add(target.clone(), aggregation.clone());
860+
if find_item_and_apply_aggregation(self.items, &target, aggregation) {
861+
self.result.items_updated += 1;
900862
}
901863
}
902864

903865
fn handle_poll_end(&mut self, c: UnstablePollEndEventContent) {
904-
let start_event_id = c.relates_to.event_id;
905-
866+
let target = TimelineEventItemId::EventId(c.relates_to.event_id);
906867
let aggregation = Aggregation::new(
907868
self.ctx.flow.timeline_item_id(),
908869
AggregationKind::PollEnd { end_date: self.ctx.timestamp },
909870
);
910-
self.meta
911-
.aggregations
912-
.add(TimelineEventItemId::EventId(start_event_id.clone()), aggregation.clone());
913-
914-
let Some((item_pos, item)) = rfind_event_by_id(self.items, &start_event_id) else {
915-
return;
916-
};
917-
918-
let mut new_content = item.content().clone();
919-
match aggregation.apply(&mut new_content) {
920-
Ok(true) => {
921-
trace!("Ending poll.");
922-
let new_item = item.with_content(new_content);
923-
self.items
924-
.replace(item_pos, TimelineItem::new(new_item, item.internal_id.to_owned()));
925-
self.result.items_updated += 1;
926-
}
927-
Ok(false) => {}
928-
Err(err) => {
929-
warn!("discarding poll end: {err}");
930-
}
871+
self.meta.aggregations.add(target.clone(), aggregation.clone());
872+
if find_item_and_apply_aggregation(self.items, &target, aggregation) {
873+
self.result.items_updated += 1;
931874
}
932875
}
933876

0 commit comments

Comments
 (0)