From 916470641e9dd6c7a5210146110db62009b63f67 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Mon, 10 Jul 2023 13:01:48 +0100 Subject: [PATCH 1/3] Replace `getQRCodeBytes` with `generateQRCode` --- src/components/views/elements/QRCode.tsx | 7 +++- .../elements/crypto/VerificationQRCode.tsx | 5 +-- .../views/right_panel/VerificationPanel.tsx | 36 +++++++++++++++---- .../components/views/elements/QRCode-test.tsx | 5 +++ .../__snapshots__/QRCode-test.tsx.snap | 20 +++++++++++ .../right_panel/VerificationPanel-test.tsx | 6 ++-- 6 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/components/views/elements/QRCode.tsx b/src/components/views/elements/QRCode.tsx index 4ba8af22503..c58f9a0449b 100644 --- a/src/components/views/elements/QRCode.tsx +++ b/src/components/views/elements/QRCode.tsx @@ -22,7 +22,8 @@ import { _t } from "../../../languageHandler"; import Spinner from "./Spinner"; 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; } @@ -33,6 +34,10 @@ const defaultOptions: QRCodeToDataURLOptions = { const QRCode: React.FC = ({ data, className, ...options }) => { const [dataUri, setUri] = React.useState(null); React.useEffect(() => { + if (data === null) { + setUri(null); + return; + } let cancelled = false; toDataURL(data, { ...defaultOptions, ...options }).then((uri) => { if (cancelled) return; diff --git a/src/components/views/elements/crypto/VerificationQRCode.tsx b/src/components/views/elements/crypto/VerificationQRCode.tsx index 193134cd93d..1f25472341d 100644 --- a/src/components/views/elements/crypto/VerificationQRCode.tsx +++ b/src/components/views/elements/crypto/VerificationQRCode.tsx @@ -19,14 +19,15 @@ import React from "react"; import QRCode from "../QRCode"; 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 { public render(): React.ReactNode { return ( diff --git a/src/components/views/right_panel/VerificationPanel.tsx b/src/components/views/right_panel/VerificationPanel.tsx index f82c974ec2d..f07569e6848 100644 --- a/src/components/views/right_panel/VerificationPanel.tsx +++ b/src/components/views/right_panel/VerificationPanel.tsx @@ -49,6 +49,14 @@ interface IProps { } 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; emojiButtonClicked?: boolean; reciprocateButtonClicked?: boolean; @@ -68,9 +76,12 @@ export default class VerificationPanel extends React.PureComponent

{_t("Scan this unique code")}

- + ); } @@ -145,7 +155,7 @@ export default class VerificationPanel extends React.PureComponent

{_t("Verify by scanning")}

@@ -156,7 +166,7 @@ export default class VerificationPanel extends React.PureComponent
- +
); @@ -426,6 +436,20 @@ export default class VerificationPanel extends React.PureComponent { + this.setState({ qrCodeBytes: buf }); + }, + (error) => { + console.error("Error generating QR code:", error); + }, + ); + } + const hadVerifier = this.hasVerifier; this.hasVerifier = !!request.verifier; if (!hadVerifier && this.hasVerifier) { diff --git a/test/components/views/elements/QRCode-test.tsx b/test/components/views/elements/QRCode-test.tsx index 4148366063b..8c27604182a 100644 --- a/test/components/views/elements/QRCode-test.tsx +++ b/test/components/views/elements/QRCode-test.tsx @@ -22,6 +22,11 @@ describe("", () => { cleanup(); }); + it("shows a spinner when data is null", async () => { + const { container } = render(); + expect(container.querySelector(".mx_Spinner")).toBeDefined(); + }); + it("renders a QR with defaults", async () => { const { container, getAllByAltText } = render(); await waitFor(() => getAllByAltText("QR Code").length === 1); diff --git a/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap b/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap index eb82ed1b0d5..9940a2ffdc8 100644 --- a/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap +++ b/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap @@ -27,3 +27,23 @@ exports[` renders a QR with high error correction level 1`] = ` `; + +exports[` shows a spinner when data is null 1`] = ` +
+
+
+
+
+
+
+`; diff --git a/test/components/views/right_panel/VerificationPanel-test.tsx b/test/components/views/right_panel/VerificationPanel-test.tsx index 73f927afcb9..1dc252c3047 100644 --- a/test/components/views/right_panel/VerificationPanel-test.tsx +++ b/test/components/views/right_panel/VerificationPanel-test.tsx @@ -56,7 +56,7 @@ describe("", () => { const request = makeMockVerificationRequest({ phase: Phase.Ready, }); - request.getQRCodeBytes.mockReturnValue(Buffer.from("test", "utf-8")); + request.generateQRCode.mockResolvedValue(Buffer.from("test", "utf-8")); const container = renderComponent({ request: request, layout: "dialog", @@ -81,7 +81,7 @@ describe("", () => { const request = makeMockVerificationRequest({ phase: Phase.Ready, }); - request.getQRCodeBytes.mockReturnValue(Buffer.from("test", "utf-8")); + request.generateQRCode.mockResolvedValue(Buffer.from("test", "utf-8")); const container = renderComponent({ request: request, member: new User("@other:user"), @@ -198,7 +198,7 @@ function makeMockVerificationRequest(props: Partial = {}): Object.assign(request, { cancel: jest.fn(), otherPartySupportsMethod: jest.fn().mockReturnValue(true), - getQRCodeBytes: jest.fn(), + generateQRCode: jest.fn().mockResolvedValue(undefined), ...props, }); return request as unknown as Mocked; From 5f758ad4c55e414d9f7de9e2c56875c54f72be1c Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 12 Jul 2023 17:13:49 +0100 Subject: [PATCH 2/3] another test update --- test/components/views/right_panel/UserInfo-test.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/test/components/views/right_panel/UserInfo-test.tsx b/test/components/views/right_panel/UserInfo-test.tsx index 28b072a5d87..2875f7691cb 100644 --- a/test/components/views/right_panel/UserInfo-test.tsx +++ b/test/components/views/right_panel/UserInfo-test.tsx @@ -179,6 +179,7 @@ describe("", () => { Object.assign(this, { channel: { transactionId: 1 }, otherPartySupportsMethod: jest.fn(), + generateQRCode: jest.fn().mockReturnValue(new Promise(() => {})), ...opts, }); } From 1d73a06466c36145a5a6a1c7d4d246157a575760 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff Date: Wed, 12 Jul 2023 18:19:54 +0100 Subject: [PATCH 3/3] remove obsolete snapshot --- .../__snapshots__/QRCode-test.tsx.snap | 20 ------------------- 1 file changed, 20 deletions(-) diff --git a/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap b/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap index 9940a2ffdc8..eb82ed1b0d5 100644 --- a/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap +++ b/test/components/views/elements/__snapshots__/QRCode-test.tsx.snap @@ -27,23 +27,3 @@ exports[` renders a QR with high error correction level 1`] = `
`; - -exports[` shows a spinner when data is null 1`] = ` -
-
-
-
-
-
-
-`;