Skip to content

Commit 140ab9a

Browse files
committed
refactor(timeline): apply aggregation to TimelineItemContent [CONSIDER SQUASHING]
1 parent 69715a9 commit 140ab9a

File tree

2 files changed

+59
-41
lines changed

2 files changed

+59
-41
lines changed

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

Lines changed: 29 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use std::collections::HashMap;
1616

1717
use ruma::{EventId, MilliSecondsSinceUnixEpoch, OwnedEventId, OwnedUserId};
1818

19-
use crate::timeline::PollState;
19+
use crate::timeline::{PollState, TimelineItemContent};
2020

2121
#[derive(Clone, Debug)]
2222
pub(crate) enum Aggregation {
@@ -31,13 +31,30 @@ pub(crate) enum Aggregation {
3131
},
3232
}
3333

34+
fn poll_state_from_item(
35+
content: &mut TimelineItemContent,
36+
) -> Result<&mut PollState, AggregationError> {
37+
match content {
38+
TimelineItemContent::Poll(state) => Ok(state),
39+
c => Err(AggregationError::InvalidType {
40+
expected: "a poll".to_owned(),
41+
actual: c.debug_string().to_owned(),
42+
}),
43+
}
44+
}
45+
3446
impl Aggregation {
35-
pub fn apply_poll(&self, poll_state: &mut PollState) -> Result<(), AggregationError> {
47+
pub fn apply(&self, content: &mut TimelineItemContent) -> Result<(), AggregationError> {
3648
match self {
3749
Aggregation::PollResponse { sender, timestamp, answers } => {
38-
poll_state.add_response(sender.clone(), *timestamp, answers.clone());
50+
poll_state_from_item(content)?.add_response(
51+
sender.clone(),
52+
*timestamp,
53+
answers.clone(),
54+
);
3955
}
4056
Aggregation::PollEnd { end_date } => {
57+
let poll_state = poll_state_from_item(content)?;
4158
if !poll_state.end(*end_date) {
4259
return Err(AggregationError::PollAlreadyEnded);
4360
}
@@ -61,23 +78,26 @@ impl Aggregations {
6178
self.stashed.entry(event_id).or_default().push(aggregation);
6279
}
6380

64-
pub fn apply_poll(
81+
pub fn apply(
6582
&self,
6683
event_id: &EventId,
67-
poll_state: &mut PollState,
68-
) -> Result<(), AggregationError> {
84+
content: &mut TimelineItemContent,
85+
) -> Result<bool, AggregationError> {
6986
let Some(aggregations) = self.stashed.get(event_id) else {
70-
return Ok(());
87+
return Ok(false);
7188
};
7289
for a in aggregations {
73-
a.apply_poll(poll_state)?;
90+
a.apply(content)?;
7491
}
75-
Ok(())
92+
Ok(true)
7693
}
7794
}
7895

7996
#[derive(Debug, thiserror::Error)]
8097
pub(crate) enum AggregationError {
8198
#[error("trying to end a poll twice")]
8299
PollAlreadyEnded,
100+
101+
#[error("trying to apply an aggregation of one type to an invalid target: expected {expected}, actual {actual}")]
102+
InvalidType { expected: String, actual: String },
83103
}

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

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -865,49 +865,53 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
865865
.or(pending_edit)
866866
.unzip();
867867

868-
let mut poll_state = PollState::new(c, edit_content);
868+
let poll_state = PollState::new(c, edit_content);
869+
let mut content = TimelineItemContent::Poll(poll_state);
869870

870871
if let Some(event_id) = self.ctx.flow.event_id() {
871872
// Applying the cache to remote events only because local echoes
872873
// don't have an event ID that could be referenced by responses yet.
873-
if let Err(err) = self.meta.aggregations.apply_poll(event_id, &mut poll_state) {
874+
if let Err(err) = self.meta.aggregations.apply(event_id, &mut content) {
874875
warn!("discarding poll aggregations: {err}");
875876
}
876877
}
877878

878879
let edit_json = edit_json.flatten();
879880

880-
self.add_item(TimelineItemContent::Poll(poll_state), edit_json);
881+
self.add_item(content, edit_json);
881882
}
882883

883884
fn handle_poll_response(&mut self, c: UnstablePollResponseEventContent) {
884885
let start_event_id = c.relates_to.event_id;
885886

886-
self.meta.aggregations.add(
887-
start_event_id.clone(),
888-
Aggregation::PollResponse {
889-
sender: self.ctx.sender.clone(),
890-
timestamp: self.ctx.timestamp,
891-
answers: c.poll_response.answers.clone(),
892-
},
893-
);
894-
895-
let Some((item_pos, item)) = rfind_event_by_id(self.items, &start_event_id) else {
896-
return;
887+
let aggregation = Aggregation::PollResponse {
888+
sender: self.ctx.sender.clone(),
889+
timestamp: self.ctx.timestamp,
890+
answers: c.poll_response.answers,
897891
};
892+
self.meta.aggregations.add(start_event_id.clone(), aggregation.clone());
898893

899-
let TimelineItemContent::Poll(poll_state) = item.content() else {
894+
let Some((item_pos, item)) = rfind_event_by_id(self.items, &start_event_id) else {
900895
return;
901896
};
902897

903-
let mut new_poll = poll_state.clone();
904-
new_poll.add_response(self.ctx.sender.clone(), self.ctx.timestamp, c.poll_response.answers);
905-
906-
let new_item = item.with_content(TimelineItemContent::Poll(new_poll), None);
907-
908-
trace!("Adding poll response.");
909-
self.items.replace(item_pos, TimelineItem::new(new_item, item.internal_id.to_owned()));
910-
self.result.items_updated += 1;
898+
let mut new_content = item.content().clone();
899+
match aggregation.apply(&mut new_content) {
900+
Ok(()) => {
901+
trace!("adding poll response.");
902+
self.items.replace(
903+
item_pos,
904+
TimelineItem::new(
905+
item.with_content(new_content, None),
906+
item.internal_id.clone(),
907+
),
908+
);
909+
self.result.items_updated += 1;
910+
}
911+
Err(err) => {
912+
warn!("discarding poll response: {err}");
913+
}
914+
}
911915
}
912916

913917
fn handle_poll_end(&mut self, c: UnstablePollEndEventContent) {
@@ -920,21 +924,15 @@ impl<'a, 'o> TimelineEventHandler<'a, 'o> {
920924
return;
921925
};
922926

923-
let TimelineItemContent::Poll(poll_state) = item.content() else {
924-
return;
925-
};
926-
927-
let mut poll_state = poll_state.clone();
928-
929-
match aggregation.apply_poll(&mut poll_state) {
927+
let mut new_content = item.content().clone();
928+
match aggregation.apply(&mut new_content) {
930929
Ok(()) => {
931930
trace!("Ending poll.");
932-
let new_item = item.with_content(TimelineItemContent::Poll(poll_state), None);
931+
let new_item = item.with_content(new_content, None);
933932
self.items
934933
.replace(item_pos, TimelineItem::new(new_item, item.internal_id.to_owned()));
935934
self.result.items_updated += 1;
936935
}
937-
938936
Err(err) => {
939937
warn!("discarding poll end: {err}");
940938
}

0 commit comments

Comments
 (0)