Replace `getQRCodeBytes` with `generateQRCode` (#11241)
* Replace `getQRCodeBytes` with `generateQRCode` * another test update * remove obsolete snapshotpull/28217/head
parent
9077592bec
commit
2cfbd73cd3
|
@ -22,7 +22,8 @@ import { _t } from "../../../languageHandler";
|
||||||
import Spinner from "./Spinner";
|
import Spinner from "./Spinner";
|
||||||
|
|
||||||
interface IProps extends QRCodeRenderersOptions {
|
interface IProps extends QRCodeRenderersOptions {
|
||||||
data: string | QRCodeSegment[];
|
/** The data for the QR code. If `null`, a spinner is shown. */
|
||||||
|
data: null | string | QRCodeSegment[];
|
||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -33,6 +34,10 @@ const defaultOptions: QRCodeToDataURLOptions = {
|
||||||
const QRCode: React.FC<IProps> = ({ data, className, ...options }) => {
|
const QRCode: React.FC<IProps> = ({ data, className, ...options }) => {
|
||||||
const [dataUri, setUri] = React.useState<string | null>(null);
|
const [dataUri, setUri] = React.useState<string | null>(null);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
|
if (data === null) {
|
||||||
|
setUri(null);
|
||||||
|
return;
|
||||||
|
}
|
||||||
let cancelled = false;
|
let cancelled = false;
|
||||||
toDataURL(data, { ...defaultOptions, ...options }).then((uri) => {
|
toDataURL(data, { ...defaultOptions, ...options }).then((uri) => {
|
||||||
if (cancelled) return;
|
if (cancelled) return;
|
||||||
|
|
|
@ -19,14 +19,15 @@ import React from "react";
|
||||||
import QRCode from "../QRCode";
|
import QRCode from "../QRCode";
|
||||||
|
|
||||||
interface IProps {
|
interface IProps {
|
||||||
qrCodeBytes: Buffer;
|
/** The data for the QR code. If `undefined`, a spinner is shown. */
|
||||||
|
qrCodeBytes: undefined | Buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default class VerificationQRCode extends React.PureComponent<IProps> {
|
export default class VerificationQRCode extends React.PureComponent<IProps> {
|
||||||
public render(): React.ReactNode {
|
public render(): React.ReactNode {
|
||||||
return (
|
return (
|
||||||
<QRCode
|
<QRCode
|
||||||
data={[{ data: this.props.qrCodeBytes, mode: "byte" }]}
|
data={this.props.qrCodeBytes === undefined ? null : [{ data: this.props.qrCodeBytes, mode: "byte" }]}
|
||||||
className="mx_VerificationQRCode"
|
className="mx_VerificationQRCode"
|
||||||
width={196}
|
width={196}
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -49,6 +49,14 @@ interface IProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface IState {
|
interface IState {
|
||||||
|
/**
|
||||||
|
* The data for the QR code to display.
|
||||||
|
*
|
||||||
|
* We attempt to calculate this once the verification request transitions into the "Ready" phase. If the other
|
||||||
|
* side cannot scan QR codes, it will remain `undefined`.
|
||||||
|
*/
|
||||||
|
qrCodeBytes: Buffer | undefined;
|
||||||
|
|
||||||
sasEvent: ShowSasCallbacks | null;
|
sasEvent: ShowSasCallbacks | null;
|
||||||
emojiButtonClicked?: boolean;
|
emojiButtonClicked?: boolean;
|
||||||
reciprocateButtonClicked?: boolean;
|
reciprocateButtonClicked?: boolean;
|
||||||
|
@ -68,9 +76,12 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
/** have we yet tried to check the other device's info */
|
/** have we yet tried to check the other device's info */
|
||||||
private haveCheckedDevice = false;
|
private haveCheckedDevice = false;
|
||||||
|
|
||||||
|
/** have we yet tried to get the QR code */
|
||||||
|
private haveFetchedQRCode = false;
|
||||||
|
|
||||||
public constructor(props: IProps) {
|
public constructor(props: IProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { sasEvent: null, reciprocateQREvent: null };
|
this.state = { qrCodeBytes: undefined, sasEvent: null, reciprocateQREvent: null };
|
||||||
this.hasVerifier = false;
|
this.hasVerifier = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -78,7 +89,6 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
const { member, request } = this.props;
|
const { member, request } = this.props;
|
||||||
const showSAS: boolean = request.otherPartySupportsMethod(verificationMethods.SAS);
|
const showSAS: boolean = request.otherPartySupportsMethod(verificationMethods.SAS);
|
||||||
const showQR: boolean = request.otherPartySupportsMethod(SCAN_QR_CODE_METHOD);
|
const showQR: boolean = request.otherPartySupportsMethod(SCAN_QR_CODE_METHOD);
|
||||||
const qrCodeBytes = showQR ? request.getQRCodeBytes() : null;
|
|
||||||
const brand = SdkConfig.get().brand;
|
const brand = SdkConfig.get().brand;
|
||||||
|
|
||||||
const noCommonMethodError: JSX.Element | null =
|
const noCommonMethodError: JSX.Element | null =
|
||||||
|
@ -97,11 +107,11 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
// HACK: This is a terrible idea.
|
// HACK: This is a terrible idea.
|
||||||
let qrBlockDialog: JSX.Element | undefined;
|
let qrBlockDialog: JSX.Element | undefined;
|
||||||
let sasBlockDialog: JSX.Element | undefined;
|
let sasBlockDialog: JSX.Element | undefined;
|
||||||
if (!!qrCodeBytes) {
|
if (showQR) {
|
||||||
qrBlockDialog = (
|
qrBlockDialog = (
|
||||||
<div className="mx_VerificationPanel_QRPhase_startOption">
|
<div className="mx_VerificationPanel_QRPhase_startOption">
|
||||||
<p>{_t("Scan this unique code")}</p>
|
<p>{_t("Scan this unique code")}</p>
|
||||||
<VerificationQRCode qrCodeBytes={qrCodeBytes} />
|
<VerificationQRCode qrCodeBytes={this.state.qrCodeBytes} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -145,7 +155,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
}
|
}
|
||||||
|
|
||||||
let qrBlock: JSX.Element | undefined;
|
let qrBlock: JSX.Element | undefined;
|
||||||
if (!!qrCodeBytes) {
|
if (showQR) {
|
||||||
qrBlock = (
|
qrBlock = (
|
||||||
<div className="mx_UserInfo_container">
|
<div className="mx_UserInfo_container">
|
||||||
<h3>{_t("Verify by scanning")}</h3>
|
<h3>{_t("Verify by scanning")}</h3>
|
||||||
|
@ -156,7 +166,7 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div className="mx_VerificationPanel_qrCode">
|
<div className="mx_VerificationPanel_qrCode">
|
||||||
<VerificationQRCode qrCodeBytes={qrCodeBytes} />
|
<VerificationQRCode qrCodeBytes={this.state.qrCodeBytes} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -426,6 +436,20 @@ export default class VerificationPanel extends React.PureComponent<IProps, IStat
|
||||||
// if we have a device ID and did not have one before, fetch the device's details
|
// if we have a device ID and did not have one before, fetch the device's details
|
||||||
this.maybeGetOtherDevice();
|
this.maybeGetOtherDevice();
|
||||||
|
|
||||||
|
// if we have had a reply from the other side (ie, the phase is "ready") and we have not
|
||||||
|
// yet done so, fetch the QR code
|
||||||
|
if (request.phase === Phase.Ready && !this.haveFetchedQRCode) {
|
||||||
|
this.haveFetchedQRCode = true;
|
||||||
|
request.generateQRCode().then(
|
||||||
|
(buf) => {
|
||||||
|
this.setState({ qrCodeBytes: buf });
|
||||||
|
},
|
||||||
|
(error) => {
|
||||||
|
console.error("Error generating QR code:", error);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const hadVerifier = this.hasVerifier;
|
const hadVerifier = this.hasVerifier;
|
||||||
this.hasVerifier = !!request.verifier;
|
this.hasVerifier = !!request.verifier;
|
||||||
if (!hadVerifier && this.hasVerifier) {
|
if (!hadVerifier && this.hasVerifier) {
|
||||||
|
|
|
@ -22,6 +22,11 @@ describe("<QRCode />", () => {
|
||||||
cleanup();
|
cleanup();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("shows a spinner when data is null", async () => {
|
||||||
|
const { container } = render(<QRCode data={null} />);
|
||||||
|
expect(container.querySelector(".mx_Spinner")).toBeDefined();
|
||||||
|
});
|
||||||
|
|
||||||
it("renders a QR with defaults", async () => {
|
it("renders a QR with defaults", async () => {
|
||||||
const { container, getAllByAltText } = render(<QRCode data="asd" />);
|
const { container, getAllByAltText } = render(<QRCode data="asd" />);
|
||||||
await waitFor(() => getAllByAltText("QR Code").length === 1);
|
await waitFor(() => getAllByAltText("QR Code").length === 1);
|
||||||
|
|
|
@ -179,6 +179,7 @@ describe("<UserInfo />", () => {
|
||||||
Object.assign(this, {
|
Object.assign(this, {
|
||||||
channel: { transactionId: 1 },
|
channel: { transactionId: 1 },
|
||||||
otherPartySupportsMethod: jest.fn(),
|
otherPartySupportsMethod: jest.fn(),
|
||||||
|
generateQRCode: jest.fn().mockReturnValue(new Promise(() => {})),
|
||||||
...opts,
|
...opts,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,7 @@ describe("<VerificationPanel />", () => {
|
||||||
const request = makeMockVerificationRequest({
|
const request = makeMockVerificationRequest({
|
||||||
phase: Phase.Ready,
|
phase: Phase.Ready,
|
||||||
});
|
});
|
||||||
request.getQRCodeBytes.mockReturnValue(Buffer.from("test", "utf-8"));
|
request.generateQRCode.mockResolvedValue(Buffer.from("test", "utf-8"));
|
||||||
const container = renderComponent({
|
const container = renderComponent({
|
||||||
request: request,
|
request: request,
|
||||||
layout: "dialog",
|
layout: "dialog",
|
||||||
|
@ -81,7 +81,7 @@ describe("<VerificationPanel />", () => {
|
||||||
const request = makeMockVerificationRequest({
|
const request = makeMockVerificationRequest({
|
||||||
phase: Phase.Ready,
|
phase: Phase.Ready,
|
||||||
});
|
});
|
||||||
request.getQRCodeBytes.mockReturnValue(Buffer.from("test", "utf-8"));
|
request.generateQRCode.mockResolvedValue(Buffer.from("test", "utf-8"));
|
||||||
const container = renderComponent({
|
const container = renderComponent({
|
||||||
request: request,
|
request: request,
|
||||||
member: new User("@other:user"),
|
member: new User("@other:user"),
|
||||||
|
@ -198,7 +198,7 @@ function makeMockVerificationRequest(props: Partial<VerificationRequest> = {}):
|
||||||
Object.assign(request, {
|
Object.assign(request, {
|
||||||
cancel: jest.fn(),
|
cancel: jest.fn(),
|
||||||
otherPartySupportsMethod: jest.fn().mockReturnValue(true),
|
otherPartySupportsMethod: jest.fn().mockReturnValue(true),
|
||||||
getQRCodeBytes: jest.fn(),
|
generateQRCode: jest.fn().mockResolvedValue(undefined),
|
||||||
...props,
|
...props,
|
||||||
});
|
});
|
||||||
return request as unknown as Mocked<VerificationRequest>;
|
return request as unknown as Mocked<VerificationRequest>;
|
||||||
|
|
Loading…
Reference in New Issue