@@ -232,7 +232,7 @@ interface IState {
232232 // Whether the action bar is focused.
233233 actionBarFocused : boolean ;
234234 // Whether the event's sender has been verified.
235- verified : string ;
235+ verified : string | null ;
236236 // The Relations model from the JS SDK for reactions to `mxEvent`
237237 reactions ?: Relations | null | undefined ;
238238
@@ -278,7 +278,8 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
278278 this . state = {
279279 // Whether the action bar is focused.
280280 actionBarFocused : false ,
281- // Whether the event's sender has been verified.
281+ // Whether the event's sender has been verified. `null` if no attempt has yet been made to verify
282+ // (including if the event is not encrypted).
282283 verified : null ,
283284 // The Relations model from the JS SDK for reactions to `mxEvent`
284285 reactions : this . getReactions ( ) ,
@@ -371,6 +372,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
371372 client . on ( CryptoEvent . DeviceVerificationChanged , this . onDeviceVerificationChanged ) ;
372373 client . on ( CryptoEvent . UserTrustStatusChanged , this . onUserVerificationChanged ) ;
373374 this . props . mxEvent . on ( MatrixEventEvent . Decrypted , this . onDecrypted ) ;
375+ this . props . mxEvent . on ( MatrixEventEvent . Replaced , this . onReplaced ) ;
374376 DecryptionFailureTracker . instance . addVisibleEvent ( this . props . mxEvent ) ;
375377 if ( this . props . showReactions ) {
376378 this . props . mxEvent . on ( MatrixEventEvent . RelationsCreated , this . onReactionsCreated ) ;
@@ -395,7 +397,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
395397 const room = client . getRoom ( this . props . mxEvent . getRoomId ( ) ) ;
396398 room ?. on ( ThreadEvent . New , this . onNewThread ) ;
397399
398- this . verifyEvent ( this . props . mxEvent ) ;
400+ this . verifyEvent ( ) ;
399401 }
400402
401403 private get supportsThreadNotifications ( ) : boolean {
@@ -461,6 +463,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
461463 }
462464 this . isListeningForReceipts = false ;
463465 this . props . mxEvent . removeListener ( MatrixEventEvent . Decrypted , this . onDecrypted ) ;
466+ this . props . mxEvent . removeListener ( MatrixEventEvent . Replaced , this . onReplaced ) ;
464467 if ( this . props . showReactions ) {
465468 this . props . mxEvent . removeListener ( MatrixEventEvent . RelationsCreated , this . onReactionsCreated ) ;
466469 }
@@ -470,15 +473,19 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
470473 this . threadState ?. off ( NotificationStateEvents . Update , this . onThreadStateUpdate ) ;
471474 }
472475
473- public componentDidUpdate ( prevProps : Readonly < EventTileProps > ) {
476+ public componentDidUpdate ( prevProps : Readonly < EventTileProps > , prevState : Readonly < IState > ) {
477+ // If the verification state changed, the height might have changed
478+ if ( prevState . verified !== this . state . verified && this . props . onHeightChanged ) {
479+ this . props . onHeightChanged ( ) ;
480+ }
474481 // If we're not listening for receipts and expect to be, register a listener.
475482 if ( ! this . isListeningForReceipts && ( this . shouldShowSentReceipt || this . shouldShowSendingReceipt ) ) {
476483 MatrixClientPeg . get ( ) . on ( RoomEvent . Receipt , this . onRoomReceipt ) ;
477484 this . isListeningForReceipts = true ;
478485 }
479486 // re-check the sender verification as outgoing events progress through the send process.
480487 if ( prevProps . eventSendStatus !== this . props . eventSendStatus ) {
481- this . verifyEvent ( this . props . mxEvent ) ;
488+ this . verifyEvent ( ) ;
482489 }
483490 }
484491
@@ -586,26 +593,36 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
586593 */
587594 private onDecrypted = ( ) => {
588595 // we need to re-verify the sending device.
589- // (we call onHeightChanged in verifyEvent to handle the case where decryption
590- // has caused a change in size of the event tile)
591- this . verifyEvent ( this . props . mxEvent ) ;
592- this . forceUpdate ( ) ;
596+ this . verifyEvent ( ) ;
597+ // decryption might, of course, trigger a height change, so call onHeightChanged after the re-render
598+ this . forceUpdate ( this . props . onHeightChanged ) ;
593599 } ;
594600
595601 private onDeviceVerificationChanged = ( userId : string , device : string ) : void => {
596602 if ( userId === this . props . mxEvent . getSender ( ) ) {
597- this . verifyEvent ( this . props . mxEvent ) ;
603+ this . verifyEvent ( ) ;
598604 }
599605 } ;
600606
601607 private onUserVerificationChanged = ( userId : string , _trustStatus : UserTrustLevel ) : void => {
602608 if ( userId === this . props . mxEvent . getSender ( ) ) {
603- this . verifyEvent ( this . props . mxEvent ) ;
609+ this . verifyEvent ( ) ;
604610 }
605611 } ;
606612
607- private async verifyEvent ( mxEvent : MatrixEvent ) : Promise < void > {
613+ /** called when the event is edited after we show it. */
614+ private onReplaced = ( ) => {
615+ // re-verify the event if it is replaced (the edit may not be verified)
616+ this . verifyEvent ( ) ;
617+ } ;
618+
619+ private verifyEvent ( ) : void {
620+ // if the event was edited, show the verification info for the edit, not
621+ // the original
622+ const mxEvent = this . props . mxEvent . replacingEvent ( ) ?? this . props . mxEvent ;
623+
608624 if ( ! mxEvent . isEncrypted ( ) || mxEvent . isRedacted ( ) ) {
625+ this . setState ( { verified : null } ) ;
609626 return ;
610627 }
611628
@@ -615,66 +632,36 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
615632
616633 if ( encryptionInfo . mismatchedSender ) {
617634 // something definitely wrong is going on here
618- this . setState (
619- {
620- verified : E2EState . Warning ,
621- } ,
622- this . props . onHeightChanged ,
623- ) ; // Decryption may have caused a change in size
635+ this . setState ( { verified : E2EState . Warning } ) ;
624636 return ;
625637 }
626638
627639 if ( ! userTrust . isCrossSigningVerified ( ) ) {
628640 // If the message is unauthenticated, then display a grey
629641 // shield, otherwise if the user isn't cross-signed then
630642 // nothing's needed
631- this . setState (
632- {
633- verified : encryptionInfo . authenticated ? E2EState . Normal : E2EState . Unauthenticated ,
634- } ,
635- this . props . onHeightChanged ,
636- ) ; // Decryption may have caused a change in size
643+ this . setState ( { verified : encryptionInfo . authenticated ? E2EState . Normal : E2EState . Unauthenticated } ) ;
637644 return ;
638645 }
639646
640647 const eventSenderTrust =
641648 encryptionInfo . sender && MatrixClientPeg . get ( ) . checkDeviceTrust ( senderId , encryptionInfo . sender . deviceId ) ;
642649 if ( ! eventSenderTrust ) {
643- this . setState (
644- {
645- verified : E2EState . Unknown ,
646- } ,
647- this . props . onHeightChanged ,
648- ) ; // Decryption may have caused a change in size
650+ this . setState ( { verified : E2EState . Unknown } ) ;
649651 return ;
650652 }
651653
652654 if ( ! eventSenderTrust . isVerified ( ) ) {
653- this . setState (
654- {
655- verified : E2EState . Warning ,
656- } ,
657- this . props . onHeightChanged ,
658- ) ; // Decryption may have caused a change in size
655+ this . setState ( { verified : E2EState . Warning } ) ;
659656 return ;
660657 }
661658
662659 if ( ! encryptionInfo . authenticated ) {
663- this . setState (
664- {
665- verified : E2EState . Unauthenticated ,
666- } ,
667- this . props . onHeightChanged ,
668- ) ; // Decryption may have caused a change in size
660+ this . setState ( { verified : E2EState . Unauthenticated } ) ;
669661 return ;
670662 }
671663
672- this . setState (
673- {
674- verified : E2EState . Verified ,
675- } ,
676- this . props . onHeightChanged ,
677- ) ; // Decryption may have caused a change in size
664+ this . setState ( { verified : E2EState . Verified } ) ;
678665 }
679666
680667 private propsEqual ( objA : EventTileProps , objB : EventTileProps ) : boolean {
@@ -768,7 +755,9 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
768755 } ;
769756
770757 private renderE2EPadlock ( ) {
771- const ev = this . props . mxEvent ;
758+ // if the event was edited, show the verification info for the edit, not
759+ // the original
760+ const ev = this . props . mxEvent . replacingEvent ( ) ?? this . props . mxEvent ;
772761
773762 // no icon for local rooms
774763 if ( isLocalRoom ( ev . getRoomId ( ) ! ) ) return ;
0 commit comments