@@ -126,7 +126,12 @@ pub(crate) enum AggregationKind {
126126 } ,
127127
128128 /// An event has been redacted.
129- Redaction ,
129+ Redaction {
130+ /// Whether this aggregation results from the local echo of a redaction.
131+ /// Local echoes of redactions are applied reversibly whereas remote
132+ /// echoes of redactions are applied irreversibly.
133+ is_local : bool ,
134+ } ,
130135
131136 /// An event has been edited.
132137 ///
@@ -237,13 +242,22 @@ impl Aggregation {
237242 }
238243 }
239244
240- AggregationKind :: Redaction => {
241- if event. content ( ) . is_redacted ( ) {
242- ApplyAggregationResult :: LeftItemIntact
245+ AggregationKind :: Redaction { is_local } => {
246+ if * is_local {
247+ if event. is_being_redacted {
248+ ApplyAggregationResult :: LeftItemIntact
249+ } else {
250+ * event = Cow :: Owned ( event. with_is_being_redacted ( true ) ) ;
251+ ApplyAggregationResult :: UpdatedItem
252+ }
243253 } else {
244- let new_item = event. redact ( & rules. redaction ) ;
245- * event = Cow :: Owned ( new_item) ;
246- ApplyAggregationResult :: UpdatedItem
254+ if event. content ( ) . is_redacted ( ) {
255+ ApplyAggregationResult :: LeftItemIntact
256+ } else {
257+ let new_item = event. redact ( & rules. redaction ) ;
258+ * event = Cow :: Owned ( new_item) ;
259+ ApplyAggregationResult :: UpdatedItem
260+ }
247261 }
248262 }
249263
@@ -352,9 +366,18 @@ impl Aggregation {
352366 ApplyAggregationResult :: Error ( AggregationError :: CantUndoPollEnd )
353367 }
354368
355- AggregationKind :: Redaction => {
356- // Redactions are not reversible.
357- ApplyAggregationResult :: Error ( AggregationError :: CantUndoRedaction )
369+ AggregationKind :: Redaction { is_local } => {
370+ if * is_local {
371+ if event. is_being_redacted {
372+ * event = Cow :: Owned ( event. with_is_being_redacted ( false ) ) ;
373+ ApplyAggregationResult :: UpdatedItem
374+ } else {
375+ ApplyAggregationResult :: LeftItemIntact
376+ }
377+ } else {
378+ // Remote redactions are not reversible.
379+ ApplyAggregationResult :: Error ( AggregationError :: CantUndoRedaction )
380+ }
358381 }
359382
360383 AggregationKind :: Reaction { key, sender, .. } => {
@@ -477,7 +500,7 @@ impl Aggregations {
477500 pub fn add ( & mut self , related_to : TimelineEventItemId , aggregation : Aggregation ) {
478501 // If the aggregation is a redaction, it invalidates all the other aggregations;
479502 // remove them.
480- if matches ! ( aggregation. kind, AggregationKind :: Redaction ) {
503+ if matches ! ( aggregation. kind, AggregationKind :: Redaction { .. } ) {
481504 for agg in self . related_events . remove ( & related_to) . unwrap_or_default ( ) {
482505 self . inverted_map . remove ( & agg. own_id ) ;
483506 }
@@ -488,7 +511,7 @@ impl Aggregations {
488511 if let Some ( previous_aggregations) = self . related_events . get ( & related_to)
489512 && previous_aggregations
490513 . iter ( )
491- . any ( |agg| matches ! ( agg. kind, AggregationKind :: Redaction ) )
514+ . any ( |agg| matches ! ( agg. kind, AggregationKind :: Redaction { .. } ) )
492515 {
493516 return ;
494517 }
@@ -698,7 +721,7 @@ impl Aggregations {
698721 AggregationKind :: PollResponse { .. }
699722 | AggregationKind :: PollEnd { .. }
700723 | AggregationKind :: Edit ( ..)
701- | AggregationKind :: Redaction
724+ | AggregationKind :: Redaction { .. }
702725 | AggregationKind :: BeaconUpdate { .. }
703726 | AggregationKind :: BeaconStop { .. } => {
704727 // Nothing particular to do.
0 commit comments