@@ -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,8 +242,15 @@ impl Aggregation {
237242 }
238243 }
239244
240- AggregationKind :: Redaction => {
241- if event. content ( ) . is_redacted ( ) {
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+ }
253+ } else if event. content ( ) . is_redacted ( ) {
242254 ApplyAggregationResult :: LeftItemIntact
243255 } else {
244256 let new_item = event. redact ( & rules. redaction ) ;
@@ -352,9 +364,18 @@ impl Aggregation {
352364 ApplyAggregationResult :: Error ( AggregationError :: CantUndoPollEnd )
353365 }
354366
355- AggregationKind :: Redaction => {
356- // Redactions are not reversible.
357- ApplyAggregationResult :: Error ( AggregationError :: CantUndoRedaction )
367+ AggregationKind :: Redaction { is_local } => {
368+ if * is_local {
369+ if event. is_being_redacted {
370+ * event = Cow :: Owned ( event. with_is_being_redacted ( false ) ) ;
371+ ApplyAggregationResult :: UpdatedItem
372+ } else {
373+ ApplyAggregationResult :: LeftItemIntact
374+ }
375+ } else {
376+ // Remote redactions are not reversible.
377+ ApplyAggregationResult :: Error ( AggregationError :: CantUndoRedaction )
378+ }
358379 }
359380
360381 AggregationKind :: Reaction { key, sender, .. } => {
@@ -477,7 +498,7 @@ impl Aggregations {
477498 pub fn add ( & mut self , related_to : TimelineEventItemId , aggregation : Aggregation ) {
478499 // If the aggregation is a redaction, it invalidates all the other aggregations;
479500 // remove them.
480- if matches ! ( aggregation. kind, AggregationKind :: Redaction ) {
501+ if matches ! ( aggregation. kind, AggregationKind :: Redaction { .. } ) {
481502 for agg in self . related_events . remove ( & related_to) . unwrap_or_default ( ) {
482503 self . inverted_map . remove ( & agg. own_id ) ;
483504 }
@@ -488,7 +509,7 @@ impl Aggregations {
488509 if let Some ( previous_aggregations) = self . related_events . get ( & related_to)
489510 && previous_aggregations
490511 . iter ( )
491- . any ( |agg| matches ! ( agg. kind, AggregationKind :: Redaction ) )
512+ . any ( |agg| matches ! ( agg. kind, AggregationKind :: Redaction { .. } ) )
492513 {
493514 return ;
494515 }
@@ -698,7 +719,7 @@ impl Aggregations {
698719 AggregationKind :: PollResponse { .. }
699720 | AggregationKind :: PollEnd { .. }
700721 | AggregationKind :: Edit ( ..)
701- | AggregationKind :: Redaction
722+ | AggregationKind :: Redaction { .. }
702723 | AggregationKind :: BeaconUpdate { .. }
703724 | AggregationKind :: BeaconStop { .. } => {
704725 // Nothing particular to do.
0 commit comments