From 7e53d0da57e9b73bc73e87168fcf3df287d1c257 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Tue, 25 Apr 2023 17:24:51 +0400 Subject: [PATCH] RLottie: Fix synchronous bundling (#3071) --- src/components/common/AnimatedSticker.tsx | 26 ++++--------------- .../composer/hooks/useInputCustomEmojis.ts | 20 +++++++------- src/lib/rlottie/RLottie.async.ts | 22 ++++++++++++++++ 3 files changed, 38 insertions(+), 30 deletions(-) create mode 100644 src/lib/rlottie/RLottie.async.ts diff --git a/src/components/common/AnimatedSticker.tsx b/src/components/common/AnimatedSticker.tsx index 564f7b8c0..e99d50b83 100644 --- a/src/components/common/AnimatedSticker.tsx +++ b/src/components/common/AnimatedSticker.tsx @@ -1,6 +1,8 @@ import type { RefObject } from 'react'; import type { FC } from '../../lib/teact/teact'; +import type RLottieInstance from '../../lib/rlottie/RLottie'; import { requestMeasure } from '../../lib/fasterdom/fasterdom'; +import { ensureRLottie, getRLottie } from '../../lib/rlottie/RLottie.async'; import React, { useEffect, useRef, memo, useCallback, useState, useMemo, @@ -41,27 +43,9 @@ export type OwnProps = { onLoop?: NoneToVoidFunction; }; -type RLottieClass = typeof import('../../lib/rlottie/RLottie').default; -type RLottieInstance = import('../../lib/rlottie/RLottie').default; -let lottiePromise: Promise; -let RLottie: RLottieClass; - -// Time for the main interface to completely load -const LOTTIE_LOAD_DELAY = 3000; const THROTTLE_MS = 150; const ID_STORE = {}; -async function ensureLottie() { - if (!lottiePromise) { - lottiePromise = import('../../lib/rlottie/RLottie') as unknown as Promise; - RLottie = (await lottiePromise as any).default; - } - - return lottiePromise; -} - -setTimeout(ensureLottie, LOTTIE_LOAD_DELAY); - const AnimatedSticker: FC = ({ ref, renderId, @@ -122,7 +106,7 @@ const AnimatedSticker: FC = ({ return; } - const newAnimation = RLottie.init( + const newAnimation = getRLottie().init( tgsUrl, container, renderId || generateIdFor(ID_STORE, true), @@ -152,10 +136,10 @@ const AnimatedSticker: FC = ({ ]); useEffect(() => { - if (RLottie) { + if (getRLottie()) { init(); } else { - ensureLottie().then(init); + ensureRLottie().then(init); } }, [init]); diff --git a/src/components/middle/composer/hooks/useInputCustomEmojis.ts b/src/components/middle/composer/hooks/useInputCustomEmojis.ts index 5cd2f6c34..0bb2f27db 100644 --- a/src/components/middle/composer/hooks/useInputCustomEmojis.ts +++ b/src/components/middle/composer/hooks/useInputCustomEmojis.ts @@ -1,7 +1,6 @@ import { useCallback, useEffect, useRef, } from '../../../../lib/teact/teact'; -import RLottie from '../../../../lib/rlottie/RLottie'; import { requestMeasure } from '../../../../lib/fasterdom/fasterdom'; import type { ApiSticker } from '../../../../api/types'; @@ -23,6 +22,7 @@ import useBackgroundMode from '../../../../hooks/useBackgroundMode'; import useThrottledCallback from '../../../../hooks/useThrottledCallback'; import useDynamicColorListener from '../../../../hooks/useDynamicColorListener'; import useEffectWithPrevDeps from '../../../../hooks/useEffectWithPrevDeps'; +import { ensureRLottie } from '../../../../lib/rlottie/RLottie.async'; const SIZE = 1.25 * REM; const THROTTLE_MS = 300; @@ -97,7 +97,7 @@ export default function useInputCustomEmojis( prefixId, documentId, textColor?.join(','), ].filter(Boolean).join('_'); - const animation = createPlayer({ + createPlayer({ customEmoji, sharedCanvasRef, sharedCanvasHqRef, @@ -108,12 +108,13 @@ export default function useInputCustomEmojis( isHq, position: { x, y }, textColor, - }); - if (canPlayAnimatedEmojis) { - animation.play(); - } + }).then((animation) => { + if (canPlayAnimatedEmojis) { + animation.play(); + } - playersById.current.set(playerId, animation); + playersById.current.set(playerId, animation); + }); }); clearPlayers(Array.from(playerIdsToClear)); @@ -182,7 +183,7 @@ export default function useInputCustomEmojis( useBackgroundMode(freezeAnimation, unfreezeAnimationOnRaf); } -function createPlayer({ +async function createPlayer({ customEmoji, sharedCanvasRef, sharedCanvasHqRef, @@ -204,8 +205,9 @@ function createPlayer({ position: { x: number; y: number }; isHq?: boolean; textColor?: [number, number, number]; -}): CustomEmojiPlayer { +}): Promise { if (customEmoji.isLottie) { + const RLottie = await ensureRLottie(); const lottie = RLottie.init( mediaUrl, isHq ? sharedCanvasHqRef.current! : sharedCanvasRef.current!, diff --git a/src/lib/rlottie/RLottie.async.ts b/src/lib/rlottie/RLottie.async.ts new file mode 100644 index 000000000..5d2289e25 --- /dev/null +++ b/src/lib/rlottie/RLottie.async.ts @@ -0,0 +1,22 @@ +type RLottieClass = typeof import('./RLottie').default; + +let promise: Promise; +let RLottie: RLottieClass; + +// Time for the main interface to completely load +const LOTTIE_LOAD_DELAY = 3000; + +export async function ensureRLottie() { + if (!promise) { + promise = import('./RLottie').then((module) => module.default); + RLottie = await promise; + } + + return promise; +} + +export function getRLottie() { + return RLottie; +} + +setTimeout(ensureRLottie, LOTTIE_LOAD_DELAY);