Change the title of VerificationRequestDialog when a request is cancelled (#30879)

* Test that VerificationRequestDialog updates when phase changes

* Change the title of VerificationRequestDialog when a request is cancelled

Part of implementing
https://github.com/element-hq/element-meta/issues/2898 but split out as
a separate change because it involves making VerificationRequestDialog
listen for changes to the verificationRequest so it can update based on
changes to phase.
This commit is contained in:
Andy Balaam
2025-09-26 09:59:40 +01:00
committed by GitHub
parent e225c23fba
commit 88d4f369eb
5 changed files with 197 additions and 33 deletions

View File

@@ -7,7 +7,7 @@ Please see LICENSE files in the repository root for full details.
*/
import React from "react";
import { type VerificationRequest } from "matrix-js-sdk/src/crypto-api";
import { VerificationPhase, VerificationRequestEvent, type VerificationRequest } from "matrix-js-sdk/src/crypto-api";
import { type User } from "matrix-js-sdk/src/matrix";
import { MatrixClientPeg } from "../../../MatrixClientPeg";
@@ -23,7 +23,17 @@ interface IProps {
}
interface IState {
// The VerificationRequest that is ongoing. This can be replaced if a
// promise was supplied in the props and it completes.
verificationRequest?: VerificationRequest;
// What phase the VerificationRequest is at. This is part of
// verificationRequest but we have it as independent state because we need
// to update when it changes.
//
// We listen to the `Change` event on verificationRequest and update phase
// when that fires.
phase?: VerificationPhase;
}
export default class VerificationRequestDialog extends React.Component<IProps, IState> {
@@ -31,22 +41,51 @@ export default class VerificationRequestDialog extends React.Component<IProps, I
super(props);
this.state = {
verificationRequest: this.props.verificationRequest,
phase: this.props.verificationRequest?.phase,
};
}
public componentDidMount(): void {
// Listen to when the verificationRequest changes, so we can keep our
// phase up-to-date.
this.state.verificationRequest?.on(VerificationRequestEvent.Change, this.onRequestChange);
this.props.verificationRequestPromise?.then((r) => {
this.setState({ verificationRequest: r });
// The request promise completed, so we have a new request
// Stop listening to the old request (if we have one, which normally we won't)
this.state.verificationRequest?.off(VerificationRequestEvent.Change, this.onRequestChange);
// And start listening to the new one
r.on(VerificationRequestEvent.Change, this.onRequestChange);
this.setState({ verificationRequest: r, phase: r.phase });
});
}
public componentWillUnmount(): void {
// Stop listening for changes to the request when we close
this.state.verificationRequest?.off(VerificationRequestEvent.Change, this.onRequestChange);
}
/**
* The verificationRequest changed, so we need to make sure we update our
* state to have the correct phase.
*
* Note: this is called when verificationRequest changes in some way, not
* when we replace verificationRequest with some new request.
*/
private readonly onRequestChange = (): void => {
this.setState((prevState) => ({
phase: prevState.verificationRequest?.phase,
}));
};
public render(): React.ReactNode {
const request = this.state.verificationRequest;
const otherUserId = request?.otherUserId;
const member = this.props.member || (otherUserId ? MatrixClientPeg.safeGet().getUser(otherUserId) : null);
const title = request?.isSelfVerification
? _t("encryption|verification|verification_dialog_title_device")
: _t("encryption|verification|verification_dialog_title_user");
const title = this.dialogTitle(request);
if (!member) return null;
@@ -69,4 +108,16 @@ export default class VerificationRequestDialog extends React.Component<IProps, I
</BaseDialog>
);
}
private dialogTitle(request?: VerificationRequest): string {
if (request?.isSelfVerification) {
if (request.phase === VerificationPhase.Cancelled) {
return _t("encryption|verification|verification_dialog_title_failed");
} else {
return _t("encryption|verification|verification_dialog_title_device");
}
} else {
return _t("encryption|verification|verification_dialog_title_user");
}
}
}

View File

@@ -1068,6 +1068,7 @@
"use_another_device": "Use another device",
"use_recovery_key": "Use recovery key",
"verification_dialog_title_device": "Verify other device",
"verification_dialog_title_failed": "Verification failed",
"verification_dialog_title_user": "Verification Request",
"verification_skip_warning": "Without verifying, you won't have access to all your messages and may appear as untrusted to others.",
"verification_success_with_backup": "Your new device is now verified. It has access to your encrypted messages, and other users will see it as trusted.",