diff --git a/src/components/auth/AuthQrCode.tsx b/src/components/auth/AuthQrCode.tsx index a4d7ebce6..c54a34d84 100644 --- a/src/components/auth/AuthQrCode.tsx +++ b/src/components/auth/AuthQrCode.tsx @@ -1,10 +1,9 @@ -import QrCodeStyling from 'qr-code-styling'; -import type { FC } from '../../lib/teact/teact'; import React, { useEffect, useRef, memo, useCallback, } from '../../lib/teact/teact'; import { getActions, withGlobal } from '../../global'; +import type { FC } from '../../lib/teact/teact'; import type { GlobalState } from '../../global/types'; import type { LangCode } from '../../types'; @@ -19,12 +18,14 @@ import useLangString from '../../hooks/useLangString'; import useFlag from '../../hooks/useFlag'; import useLang from '../../hooks/useLang'; import useMediaTransition from '../../hooks/useMediaTransition'; +import useAsync from '../../hooks/useAsync'; import Loading from '../ui/Loading'; import Button from '../ui/Button'; -import blankUrl from '../../assets/blank.png'; import AnimatedIcon from '../common/AnimatedIcon'; +import blankUrl from '../../assets/blank.png'; + type StateProps = Pick & { language?: LangCode }; @@ -33,26 +34,14 @@ const DATA_PREFIX = 'tg://login?token='; const QR_SIZE = 280; const QR_PLANE_SIZE = 54; -const QR_CODE = new QrCodeStyling({ - width: QR_SIZE, - height: QR_SIZE, - image: blankUrl, - margin: 10, - type: 'svg', - dotsOptions: { - type: 'rounded', - }, - cornersSquareOptions: { - type: 'extra-rounded', - }, - imageOptions: { - imageSize: 0.4, - margin: 8, - }, - qrOptions: { - errorCorrectionLevel: 'M', - }, -}); +let qrCodeStylingPromise: Promise; + +function ensureQrCodeStyling() { + if (!qrCodeStylingPromise) { + qrCodeStylingPromise = import('qr-code-styling'); + } + return qrCodeStylingPromise; +} const AuthCode: FC = ({ connectionState, @@ -73,10 +62,34 @@ const AuthCode: FC = ({ const [isLoading, markIsLoading, unmarkIsLoading] = useFlag(); const [isQrMounted, markQrMounted, unmarkQrMounted] = useFlag(); + const { result: qrCode } = useAsync(async () => { + const QrCodeStyling = (await ensureQrCodeStyling()).default; + return new QrCodeStyling({ + width: QR_SIZE, + height: QR_SIZE, + image: blankUrl, + margin: 10, + type: 'svg', + dotsOptions: { + type: 'rounded', + }, + cornersSquareOptions: { + type: 'extra-rounded', + }, + imageOptions: { + imageSize: 0.4, + margin: 8, + }, + qrOptions: { + errorCorrectionLevel: 'M', + }, + }); + }, []); + const transitionClassNames = useMediaTransition(isQrMounted); useEffect(() => { - if (!authQrCode) { + if (!authQrCode || !qrCode) { return () => { unmarkQrMounted(); }; @@ -89,16 +102,16 @@ const AuthCode: FC = ({ const container = qrCodeRef.current!; const data = `${DATA_PREFIX}${authQrCode.token}`; - QR_CODE.update({ + qrCode.update({ data, }); if (!isQrMounted) { - QR_CODE.append(container); + qrCode.append(container); markQrMounted(); } return undefined; - }, [connectionState, authQrCode, isQrMounted, markQrMounted, unmarkQrMounted]); + }, [connectionState, authQrCode, isQrMounted, markQrMounted, unmarkQrMounted, qrCode]); useEffect(() => { if (connectionState === 'connectionStateReady') {