import React, { FC, useEffect, useRef } from '../../../lib/teact/teact'; import { ApiMessage } from '../../../api/types'; import { NO_STICKER_SET_ID } from '../../../config'; import { getStickerDimensions } from '../../common/helpers/mediaDimensions'; import { getMessageMediaFormat, getMessageMediaHash } from '../../../modules/helpers'; import buildClassName from '../../../util/buildClassName'; import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import useMedia from '../../../hooks/useMedia'; import useMediaTransition from '../../../hooks/useMediaTransition'; import useFlag from '../../../hooks/useFlag'; import useWebpThumbnail from '../../../hooks/useWebpThumbnail'; import safePlay from '../../../util/safePlay'; import { IS_WEBM_SUPPORTED } from '../../../util/environment'; import AnimatedSticker from '../../common/AnimatedSticker'; import StickerSetModal from '../../common/StickerSetModal.async'; import './Sticker.scss'; type OwnProps = { message: ApiMessage; observeIntersection: ObserveFn; observeIntersectionForPlaying: ObserveFn; shouldLoop?: boolean; lastSyncTime?: number; }; const Sticker: FC = ({ message, observeIntersection, observeIntersectionForPlaying, shouldLoop, lastSyncTime, }) => { // eslint-disable-next-line no-null/no-null const ref = useRef(null); const [isModalOpen, openModal, closeModal] = useFlag(); const sticker = message.content.sticker!; const { isLottie, stickerSetId, isGif } = sticker; const canDisplayGif = IS_WEBM_SUPPORTED; const isMemojiSticker = stickerSetId === NO_STICKER_SET_ID; const shouldLoad = useIsIntersecting(ref, observeIntersection); const shouldPlay = useIsIntersecting(ref, observeIntersectionForPlaying); const mediaHash = sticker.isPreloadedGlobally ? `sticker${sticker.id}` : getMessageMediaHash(message, 'inline')!; const previewMediaHash = isGif && !canDisplayGif && ( sticker.isPreloadedGlobally ? `sticker${sticker.id}?size=m` : getMessageMediaHash(message, 'pictogram')); const previewBlobUrl = useMedia(previewMediaHash); const thumbDataUri = useWebpThumbnail(message); const previewUrl = previewBlobUrl || thumbDataUri; const mediaData = useMedia( mediaHash, !shouldLoad, getMessageMediaFormat(message, 'inline'), lastSyncTime, ); const isMediaLoaded = Boolean(mediaData); const [isLottieLoaded, markLottieLoaded] = useFlag(isMediaLoaded); const isMediaReady = isLottie ? isLottieLoaded : isMediaLoaded; const transitionClassNames = useMediaTransition(isMediaReady); const { width, height } = getStickerDimensions(sticker); const thumbClassName = buildClassName('thumbnail', !thumbDataUri && 'empty'); const stickerClassName = buildClassName( 'Sticker media-inner', isMemojiSticker && 'inactive', ); useEffect(() => { if (!isGif || !ref.current) return; const video = ref.current.querySelector('video'); if (!video) return; if (shouldPlay) { safePlay(video); } else { video.pause(); } }, [isGif, shouldPlay]); return (
{(!isMediaReady || (isGif && !canDisplayGif)) && ( )} {!isLottie && !isGif && ( )} {isGif && canDisplayGif && isMediaReady && (
); }; export default Sticker;