diff --git a/src/components/common/AnimatedEmoji.tsx b/src/components/common/AnimatedEmoji.tsx index a57369386..14e9997dc 100644 --- a/src/components/common/AnimatedEmoji.tsx +++ b/src/components/common/AnimatedEmoji.tsx @@ -7,7 +7,7 @@ import { ApiMediaFormat, ApiSticker } from '../../api/types'; import { LIKE_STICKER_ID } from './helpers/mediaDimensions'; import { ObserveFn, useIsIntersecting } from '../../hooks/useIntersectionObserver'; import useMedia from '../../hooks/useMedia'; -import useTransitionForMedia from '../../hooks/useTransitionForMedia'; +import useMediaTransition from '../../hooks/useMediaTransition'; import useFlag from '../../hooks/useFlag'; import AnimatedSticker from './AnimatedSticker'; @@ -51,7 +51,7 @@ const AnimatedEmoji: FC = ({ ApiMediaFormat.BlobUrl, lastSyncTime, ); - const { transitionClassNames } = useTransitionForMedia(previewBlobUrl, 'slow'); + const transitionClassNames = useMediaTransition(previewBlobUrl); const mediaData = useMedia(localMediaHash, !isIntersecting, ApiMediaFormat.Lottie, lastSyncTime); const isMediaLoaded = Boolean(mediaData); diff --git a/src/components/common/Avatar.tsx b/src/components/common/Avatar.tsx index 7e8261902..e88bc210c 100644 --- a/src/components/common/Avatar.tsx +++ b/src/components/common/Avatar.tsx @@ -18,7 +18,7 @@ import { getFirstLetters } from '../../util/textFormat'; import buildClassName from '../../util/buildClassName'; import renderText from './helpers/renderText'; import useMedia from '../../hooks/useMedia'; -import useTransitionForMedia from '../../hooks/useTransitionForMedia'; +import useShowTransition from '../../hooks/useShowTransition'; import useLang from '../../hooks/useLang'; import './Avatar.scss'; @@ -59,7 +59,8 @@ const Avatar: FC = ({ } const blobUrl = useMedia(imageHash, false, ApiMediaFormat.BlobUrl, lastSyncTime); - const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(blobUrl, 'slow'); + const hasBlobUrl = Boolean(blobUrl); + const { transitionClassNames } = useShowTransition(hasBlobUrl, undefined, hasBlobUrl, 'slow'); const lang = useLang(); @@ -71,8 +72,10 @@ const Avatar: FC = ({ content = ; } else if (isReplies) { content = ; - } else if (shouldRenderFullMedia) { - content = ; + } else if (blobUrl) { + content = ( + + ); } else if (user) { const userFullName = getUserFullName(user); content = userFullName ? getFirstLetters(userFullName, 2) : undefined; @@ -93,14 +96,15 @@ const Avatar: FC = ({ isReplies && 'replies-bot-account', withOnlineStatus && isOnline && 'online', onClick && 'interactive', - (!isSavedMessages && !shouldRenderFullMedia) && 'no-photo', + (!isSavedMessages && !blobUrl) && 'no-photo', ); + const hasImage = Boolean(isSavedMessages || blobUrl); const handleClick = useCallback((e: ReactMouseEvent) => { if (onClick) { - onClick(e, isSavedMessages || shouldRenderFullMedia); + onClick(e, hasImage); } - }, [onClick, isSavedMessages, shouldRenderFullMedia]); + }, [onClick, hasImage]); const senderId = (user || chat) && (user || chat)!.id; diff --git a/src/components/common/File.tsx b/src/components/common/File.tsx index df5808954..9cbf9972a 100644 --- a/src/components/common/File.tsx +++ b/src/components/common/File.tsx @@ -2,7 +2,7 @@ import { RefObject } from 'react'; import React, { FC, memo, useRef } from '../../lib/teact/teact'; import useShowTransition from '../../hooks/useShowTransition'; -import useTransitionForMedia from '../../hooks/useTransitionForMedia'; +import useMediaTransition from '../../hooks/useMediaTransition'; import buildClassName from '../../util/buildClassName'; import { formatMediaDateTime, formatPastTimeShort } from '../../util/dateFormat'; import { getColorFromExtension, getFileSizeString } from './helpers/documentInfo'; @@ -63,16 +63,15 @@ const File: FC = ({ elementRef = ref; } + const transitionClassNames = useMediaTransition(previewData); const { shouldRender: shouldSpinnerRender, transitionClassNames: spinnerClassNames, } = useShowTransition(isTransferring, undefined, true); + const color = getColorFromExtension(extension); const sizeString = getFileSizeString(size); - const { - shouldRenderThumb, shouldRenderFullMedia, transitionClassNames, - } = useTransitionForMedia(previewData, 'slow'); const { width, height } = getDocumentThumbnailDimensions(smaller); const fullClassName = buildClassName( @@ -93,24 +92,20 @@ const File: FC = ({
{thumbnailDataUri || previewData ? (
- {shouldRenderThumb && ( - - )} - {shouldRenderFullMedia && ( - - )} + +
) : (
diff --git a/src/components/common/Media.tsx b/src/components/common/Media.tsx index 94857cb4b..74d25aa33 100644 --- a/src/components/common/Media.tsx +++ b/src/components/common/Media.tsx @@ -8,8 +8,9 @@ import { getMessageMediaThumbDataUri, getMessageVideo, } from '../../modules/helpers'; +import buildClassName from '../../util/buildClassName'; import useMedia from '../../hooks/useMedia'; -import useTransitionForMedia from '../../hooks/useTransitionForMedia'; +import useMediaTransition from '../../hooks/useMediaTransition'; import './Media.scss'; @@ -26,20 +27,14 @@ const Media: FC = ({ message, idPrefix = 'shared-media', onClick }) => const thumbDataUri = getMessageMediaThumbDataUri(message); const mediaBlobUrl = useMedia(getMessageMediaHash(message, 'pictogram')); - const { - shouldRenderThumb, shouldRenderFullMedia, transitionClassNames, - } = useTransitionForMedia(mediaBlobUrl, 'slow'); + const transitionClassNames = useMediaTransition(mediaBlobUrl); const video = getMessageVideo(message); return (
- {shouldRenderThumb && ( - - )} - {shouldRenderFullMedia && ( - - )} + + {video && {video.isGif ? 'GIF' : formatMediaDuration(video.duration)}}
); diff --git a/src/components/common/StickerButton.tsx b/src/components/common/StickerButton.tsx index 7d505aabf..40313dcad 100644 --- a/src/components/common/StickerButton.tsx +++ b/src/components/common/StickerButton.tsx @@ -7,7 +7,7 @@ import { ApiMediaFormat, ApiSticker } from '../../api/types'; import { useIsIntersecting, ObserveFn } from '../../hooks/useIntersectionObserver'; import useMedia from '../../hooks/useMedia'; -import useTransitionForMedia from '../../hooks/useTransitionForMedia'; +import useShowTransition from '../../hooks/useShowTransition'; import useFlag from '../../hooks/useFlag'; import buildClassName from '../../util/buildClassName'; import { preventMessageInputBlurWithBubbling } from '../middle/helpers/preventMessageInputBlur'; @@ -48,11 +48,12 @@ const StickerButton: FC = ({ const [isAnimationLoaded, markLoaded, unmarkLoaded] = useFlag(Boolean(lottieData)); const canAnimatedPlay = isAnimationLoaded && shouldPlay; - const { - shouldRenderThumb, - shouldRenderFullMedia: shouldRenderPreview, - transitionClassNames: previewTransitionClassNames, - } = useTransitionForMedia(previewBlobUrl || canAnimatedPlay, 'slow'); + const { transitionClassNames: previewTransitionClassNames } = useShowTransition( + Boolean(previewBlobUrl || canAnimatedPlay), + undefined, + undefined, + 'slow', + ); // To avoid flickering useEffect(() => { @@ -82,7 +83,7 @@ const StickerButton: FC = ({ className, ); - const style = shouldRenderThumb && thumbDataUri ? `background-image: url('${thumbDataUri}');` : ''; + const style = thumbDataUri ? `background-image: url('${thumbDataUri}');` : ''; return (
= ({ onMouseDown={preventMessageInputBlurWithBubbling} onClick={handleClick} > - {shouldRenderPreview && !canAnimatedPlay && ( + {!canAnimatedPlay && ( // eslint-disable-next-line jsx-a11y/alt-text )} diff --git a/src/components/left/settings/WallpaperTile.tsx b/src/components/left/settings/WallpaperTile.tsx index 434ec0d17..3b8deaee6 100644 --- a/src/components/left/settings/WallpaperTile.tsx +++ b/src/components/left/settings/WallpaperTile.tsx @@ -7,7 +7,6 @@ import { ThemeKey, UPLOADING_WALLPAPER_SLUG } from '../../../types'; import { CUSTOM_BG_CACHE_NAME } from '../../../config'; import * as cacheApi from '../../../util/cacheApi'; import { fetchBlob } from '../../../util/files'; -import useTransitionForMedia from '../../../hooks/useTransitionForMedia'; import buildClassName from '../../../util/buildClassName'; import useMedia from '../../../hooks/useMedia'; import useMediaWithLoadProgress from '../../../hooks/useMediaWithLoadProgress'; @@ -37,9 +36,12 @@ const WallpaperTile: FC = ({ const localBlobUrl = document.previewBlobUrl; const previewBlobUrl = useMedia(`${localMediaHash}?size=m`); const thumbRef = useCanvasBlur(document.thumbnail?.dataUri, Boolean(previewBlobUrl), true); - const { - shouldRenderThumb, shouldRenderFullMedia, transitionClassNames, - } = useTransitionForMedia(previewBlobUrl || localBlobUrl, 'slow'); + const { transitionClassNames } = useShowTransition( + Boolean(previewBlobUrl || localBlobUrl), + undefined, + undefined, + 'slow', + ); const [isLoadAllowed, setIsLoadAllowed] = useState(false); const { mediaData: fullMedia, loadProgress, @@ -85,19 +87,15 @@ const WallpaperTile: FC = ({ return (
- {shouldRenderThumb && ( - - )} - {shouldRenderFullMedia && ( - - )} + + {shouldRenderSpinner && (
diff --git a/src/components/middle/composer/EmojiCategory.tsx b/src/components/middle/composer/EmojiCategory.tsx index ad91b46f7..cde3847c3 100644 --- a/src/components/middle/composer/EmojiCategory.tsx +++ b/src/components/middle/composer/EmojiCategory.tsx @@ -4,7 +4,7 @@ import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment'; import buildClassName from '../../../util/buildClassName'; import windowSize from '../../../util/windowSize'; import { ObserveFn, useOnIntersect } from '../../../hooks/useIntersectionObserver'; -import useShowTransition from '../../../hooks/useShowTransition'; +import useMediaTransition from '../../../hooks/useMediaTransition'; import useLang from '../../../hooks/useLang'; import EmojiButton from './EmojiButton'; @@ -31,7 +31,7 @@ const EmojiCategory: FC = ({ useOnIntersect(ref, observeIntersection); - const { transitionClassNames } = useShowTransition(shouldRender, undefined, undefined, 'slow'); + const transitionClassNames = useMediaTransition(shouldRender); const lang = useLang(); diff --git a/src/components/middle/composer/StickerSet.tsx b/src/components/middle/composer/StickerSet.tsx index 239c147f8..921aeeefd 100644 --- a/src/components/middle/composer/StickerSet.tsx +++ b/src/components/middle/composer/StickerSet.tsx @@ -8,7 +8,7 @@ import { STICKER_SIZE_PICKER } from '../../../config'; import { IS_SINGLE_COLUMN_LAYOUT } from '../../../util/environment'; import windowSize from '../../../util/windowSize'; import StickerButton from '../../common/StickerButton'; -import useShowTransition from '../../../hooks/useShowTransition'; +import useMediaTransition from '../../../hooks/useMediaTransition'; import buildClassName from '../../../util/buildClassName'; type OwnProps = { @@ -39,7 +39,7 @@ const StickerSet: FC = ({ useOnIntersect(ref, observeIntersection); - const { transitionClassNames } = useShowTransition(shouldRender, undefined, undefined, 'slow'); + const transitionClassNames = useMediaTransition(shouldRender); const stickersPerRow = IS_SINGLE_COLUMN_LAYOUT ? Math.floor((windowSize.get().width - MOBILE_CONTAINER_PADDING) / (STICKER_SIZE_PICKER + STICKER_MARGIN)) diff --git a/src/components/middle/composer/StickerSetCover.tsx b/src/components/middle/composer/StickerSetCover.tsx index 85187fa87..b3294a1ed 100644 --- a/src/components/middle/composer/StickerSetCover.tsx +++ b/src/components/middle/composer/StickerSetCover.tsx @@ -1,11 +1,13 @@ -import React, { FC, memo, useRef } from '../../../lib/teact/teact'; +import React, { + FC, memo, useMemo, useRef, +} from '../../../lib/teact/teact'; import { ApiStickerSet } from '../../../api/types'; +import { getFirstLetters } from '../../../util/textFormat'; import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import useMedia from '../../../hooks/useMedia'; -import useTransitionForMedia from '../../../hooks/useTransitionForMedia'; -import { getFirstLetters } from '../../../util/textFormat'; +import useMediaTransition from '../../../hooks/useMediaTransition'; type OwnProps = { stickerSet: ApiStickerSet; @@ -19,14 +21,18 @@ const StickerSetCover: FC = ({ stickerSet, observeIntersection }) => { const isIntersecting = useIsIntersecting(ref, observeIntersection); const mediaData = useMedia(stickerSet.hasThumbnail && `stickerSet${stickerSet.id}`, !isIntersecting); - const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(mediaData, 'slow'); + const transitionClassNames = useMediaTransition(mediaData); + + const firstLetters = useMemo(() => { + if (mediaData) return undefined; + + return getFirstLetters(stickerSet.title, 2); + }, [mediaData, stickerSet.title]); return (
- {!shouldRenderFullMedia && getFirstLetters(stickerSet.title, 2)} - {shouldRenderFullMedia && ( - - )} + {firstLetters} +
); }; diff --git a/src/components/middle/composer/StickerSetCoverAnimated.tsx b/src/components/middle/composer/StickerSetCoverAnimated.tsx index f794d4813..c01854be3 100644 --- a/src/components/middle/composer/StickerSetCoverAnimated.tsx +++ b/src/components/middle/composer/StickerSetCoverAnimated.tsx @@ -1,11 +1,13 @@ -import React, { FC, memo, useRef } from '../../../lib/teact/teact'; +import React, { + FC, memo, useMemo, useRef, +} from '../../../lib/teact/teact'; import { ApiMediaFormat, ApiStickerSet } from '../../../api/types'; import { STICKER_SIZE_PICKER_HEADER } from '../../../config'; import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import useMedia from '../../../hooks/useMedia'; -import useTransitionForMedia from '../../../hooks/useTransitionForMedia'; +import useMediaTransition from '../../../hooks/useMediaTransition'; import { getFirstLetters } from '../../../util/textFormat'; import AnimatedSticker from '../../common/AnimatedSticker'; @@ -28,12 +30,18 @@ const StickerSetCoverAnimated: FC = ({ const mediaHash = `stickerSet${stickerSet.id}`; const lottieData = useMedia(mediaHash, !isIntersecting, ApiMediaFormat.Lottie); - const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(lottieData, 'slow'); + const transitionClassNames = useMediaTransition(lottieData); + + const firstLetters = useMemo(() => { + if (lottieData) return undefined; + + return getFirstLetters(stickerSet.title, 2); + }, [lottieData, stickerSet.title]); return (
- {!shouldRenderFullMedia && getFirstLetters(stickerSet.title, 2)} - {shouldRenderFullMedia && lottieData && ( + {firstLetters} + {lottieData && ( = ({ const thumbnailDataUrl = useMedia(webThumbnail ? `webDocument:${webThumbnail.url}` : undefined); const mediaBlobUrl = useMedia(photo && `photo${photo.id}?size=m`); - const { - shouldRenderThumb, shouldRenderFullMedia, transitionClassNames, - } = useTransitionForMedia(mediaBlobUrl, 'slow'); + const transitionClassNames = useMediaTransition(mediaBlobUrl); const handleClick = useCallback(() => { onClick(inlineResult); @@ -49,12 +48,8 @@ const MediaResult: FC = ({ if (isForGallery) { return (
- {shouldRenderThumb && ( - - )} - {shouldRenderFullMedia && ( - - )} + +
); } @@ -64,8 +59,8 @@ const MediaResult: FC = ({ return ( = ({ shouldLoad && !fullMediaData, ); const wasLoadDisabled = usePrevious(isLoadAllowed) === false; + + const transitionClassNames = useMediaTransition(fullMediaData); const { shouldRender: shouldRenderSpinner, transitionClassNames: spinnerClassNames, } = useShowTransition(isTransferring, undefined, wasLoadDisabled, 'slow'); - const { - shouldRenderThumb, shouldRenderFullMedia, transitionClassNames, - } = useTransitionForMedia(fullMediaData, 'slow'); const handleClick = useCallback(() => { if (isUploading) { @@ -152,23 +151,19 @@ const Photo: FC = ({ style={style} onClick={isUploading ? undefined : handleClick} > - {shouldRenderThumb && ( - - )} - {shouldRenderFullMedia && ( - - )} + + {shouldRenderSpinner && (
diff --git a/src/components/middle/message/RoundVideo.tsx b/src/components/middle/message/RoundVideo.tsx index f11168422..7ec801a36 100644 --- a/src/components/middle/message/RoundVideo.tsx +++ b/src/components/middle/message/RoundVideo.tsx @@ -10,22 +10,22 @@ import { getDispatch } from '../../../lib/teact/teactn'; import { ApiMediaFormat, ApiMessage } from '../../../api/types'; import { ROUND_VIDEO_DIMENSIONS_PX } from '../../common/helpers/mediaDimensions'; -import { formatMediaDuration } from '../../../util/dateFormat'; import { getMessageMediaFormat, getMessageMediaHash } from '../../../modules/helpers'; +import { formatMediaDuration } from '../../../util/dateFormat'; +import buildClassName from '../../../util/buildClassName'; +import { stopCurrentAudio } from '../../../util/audioPlayer'; +import safePlay from '../../../util/safePlay'; +import { fastRaf } from '../../../util/schedulers'; import { ObserveFn, useIsIntersecting } from '../../../hooks/useIntersectionObserver'; import useMediaWithLoadProgress from '../../../hooks/useMediaWithLoadProgress'; import useShowTransition from '../../../hooks/useShowTransition'; -import useTransitionForMedia from '../../../hooks/useTransitionForMedia'; +import useMediaTransition from '../../../hooks/useMediaTransition'; import usePrevious from '../../../hooks/usePrevious'; import useBuffering from '../../../hooks/useBuffering'; -import buildClassName from '../../../util/buildClassName'; -import { stopCurrentAudio } from '../../../util/audioPlayer'; import useHeavyAnimationCheckForVideo from '../../../hooks/useHeavyAnimationCheckForVideo'; import useVideoCleanup from '../../../hooks/useVideoCleanup'; import usePauseOnInactive from './hooks/usePauseOnInactive'; import useBlurredMediaThumbRef from './hooks/useBlurredMediaThumbRef'; -import safePlay from '../../../util/safePlay'; -import { fastRaf } from '../../../util/schedulers'; import ProgressSpinner from '../../ui/ProgressSpinner'; @@ -91,11 +91,12 @@ const RoundVideo: FC = ({ const { isBuffered, bufferingHandlers } = useBuffering(); const isTransferring = (isLoadAllowed && !isBuffered) || isDownloading; const wasLoadDisabled = usePrevious(isLoadAllowed) === false; + + const transitionClassNames = useMediaTransition(mediaData); const { shouldRender: shouldSpinnerRender, transitionClassNames: spinnerClassNames, } = useShowTransition(isTransferring || !isBuffered, undefined, wasLoadDisabled); - const { shouldRenderThumb, transitionClassNames } = useTransitionForMedia(mediaData, 'slow'); const [isActivated, setIsActivated] = useState(false); const [progress, setProgress] = useState(0); @@ -206,16 +207,14 @@ const RoundVideo: FC = ({ className="RoundVideo media-inner" onClick={handleClick} > - {(shouldRenderThumb || mediaData) && ( -
- -
- )} +
+ +
{mediaData && (
{/* eslint-disable-next-line jsx-a11y/media-has-caption */} diff --git a/src/components/middle/message/Sticker.tsx b/src/components/middle/message/Sticker.tsx index 5173939dc..bb35a3648 100644 --- a/src/components/middle/message/Sticker.tsx +++ b/src/components/middle/message/Sticker.tsx @@ -5,10 +5,10 @@ import { ApiMessage } from '../../../api/types'; import { MEMOJI_STICKER_ID } from '../../../config'; import { getStickerDimensions } from '../../common/helpers/mediaDimensions'; import { getMessageMediaFormat, getMessageMediaHash } from '../../../modules/helpers'; -import useMedia from '../../../hooks/useMedia'; -import useTransitionForMedia from '../../../hooks/useTransitionForMedia'; 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'; @@ -52,7 +52,7 @@ const Sticker: FC = ({ const isMediaLoaded = Boolean(mediaData); const [isAnimationLoaded, markAnimationLoaded] = useFlag(isMediaLoaded); const isMediaReady = isAnimated ? isAnimationLoaded : isMediaLoaded; - const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(isMediaReady, 'slow'); + const transitionClassNames = useMediaTransition(isMediaReady); const { width, height } = getStickerDimensions(sticker); const thumbClassName = buildClassName('thumbnail', !thumbDataUri && 'empty'); @@ -74,7 +74,7 @@ const Sticker: FC = ({ className={thumbClassName} /> )} - {!isAnimated && shouldRenderFullMedia && ( + {!isAnimated && ( = ({ getMessageMediaFormat(message, 'pictogram'), lastSyncTime, ); - const { - shouldRenderThumb, - shouldRenderFullMedia: shouldRenderPreview, - transitionClassNames: previewClassNames, - } = useTransitionForMedia(previewBlobUrl, 'slow'); + const { transitionClassNames: previewClassNames } = useShowTransition( + Boolean(previewBlobUrl), + undefined, + undefined, + 'slow', + ); const { mediaData, loadProgress } = useMediaWithLoadProgress( getMessageMediaHash(message, 'inline'), @@ -163,23 +163,19 @@ const Video: FC = ({ style={style} onClick={isUploading ? undefined : handleClick} > - {shouldRenderThumb && ( - - )} - {shouldRenderPreview && ( - - )} + + {isInline && (