[Perf] Avatar: Do not render video when not intersecting
This commit is contained in:
parent
3ef3a8bdfe
commit
4e5c951372
@ -30,9 +30,10 @@ import useMedia from '../../hooks/useMedia';
|
|||||||
import useShowTransition from '../../hooks/useShowTransition';
|
import useShowTransition from '../../hooks/useShowTransition';
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
|
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
|
||||||
|
import useVideoAutoPause from '../middle/message/hooks/useVideoAutoPause';
|
||||||
|
import useVideoCleanup from '../../hooks/useVideoCleanup';
|
||||||
|
|
||||||
import './Avatar.scss';
|
import './Avatar.scss';
|
||||||
import useVideoAutoPause from '../middle/message/hooks/useVideoAutoPause';
|
|
||||||
|
|
||||||
const cn = createClassNameBuilder('Avatar');
|
const cn = createClassNameBuilder('Avatar');
|
||||||
cn.media = cn('media');
|
cn.media = cn('media');
|
||||||
@ -80,16 +81,12 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
let imageHash: string | undefined;
|
let imageHash: string | undefined;
|
||||||
let videoHash: string | undefined;
|
let videoHash: string | undefined;
|
||||||
|
|
||||||
const hasVideoAvatar = (user || chat)?.hasVideoAvatar;
|
const withVideo = isIntersecting && !noVideo && user?.isPremium && user?.hasVideoAvatar;
|
||||||
const profilePhoto = (user?.fullInfo?.profilePhoto || chat?.fullInfo?.profilePhoto);
|
const profilePhoto = user?.fullInfo?.profilePhoto;
|
||||||
const shouldShowVideo = !noVideo && Boolean(user?.isPremium && profilePhoto?.isVideo);
|
const shouldLoadVideo = withVideo && profilePhoto?.isVideo;
|
||||||
const shouldPlayVideo = isIntersecting && shouldShowVideo;
|
|
||||||
|
|
||||||
const shouldFetchBig = size === 'jumbo';
|
const shouldFetchBig = size === 'jumbo';
|
||||||
if (!isSavedMessages && !isDeleted) {
|
if (!isSavedMessages && !isDeleted) {
|
||||||
if (shouldShowVideo) {
|
|
||||||
videoHash = getChatAvatarHash(user!, undefined, 'video');
|
|
||||||
}
|
|
||||||
if (user) {
|
if (user) {
|
||||||
imageHash = getChatAvatarHash(user, shouldFetchBig ? 'big' : undefined);
|
imageHash = getChatAvatarHash(user, shouldFetchBig ? 'big' : undefined);
|
||||||
} else if (chat) {
|
} else if (chat) {
|
||||||
@ -97,9 +94,21 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
} else if (photo) {
|
} else if (photo) {
|
||||||
imageHash = `photo${photo.id}?size=m`;
|
imageHash = `photo${photo.id}?size=m`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (shouldLoadVideo) {
|
||||||
|
videoHash = getChatAvatarHash(user!, undefined, 'video');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const imgBlobUrl = useMedia(imageHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);
|
||||||
|
const videoBlobUrl = useMedia(videoHash, !shouldLoadVideo, ApiMediaFormat.BlobUrl, lastSyncTime);
|
||||||
|
const hasBlobUrl = Boolean(imgBlobUrl || videoBlobUrl);
|
||||||
|
const shouldPlayVideo = Boolean(isIntersecting && videoBlobUrl);
|
||||||
|
|
||||||
|
const { transitionClassNames } = useShowTransition(hasBlobUrl, undefined, hasBlobUrl, 'slow');
|
||||||
|
|
||||||
useVideoAutoPause(videoRef, shouldPlayVideo);
|
useVideoAutoPause(videoRef, shouldPlayVideo);
|
||||||
|
useVideoCleanup(videoRef, [shouldPlayVideo]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const video = videoRef.current;
|
const video = videoRef.current;
|
||||||
@ -113,16 +122,12 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
return () => video.removeEventListener('ended', returnToStart);
|
return () => video.removeEventListener('ended', returnToStart);
|
||||||
}, [noLoop]);
|
}, [noLoop]);
|
||||||
|
|
||||||
|
const userId = user?.id;
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (isIntersecting && !noVideo && user && hasVideoAvatar && !profilePhoto) {
|
if (withVideo && !profilePhoto) {
|
||||||
loadFullUser({ userId: user.id });
|
loadFullUser({ userId });
|
||||||
}
|
}
|
||||||
}, [hasVideoAvatar, profilePhoto, loadFullUser, user, noVideo, isIntersecting]);
|
}, [loadFullUser, profilePhoto, userId, withVideo]);
|
||||||
|
|
||||||
const imgBlobUrl = useMedia(imageHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);
|
|
||||||
const videoBlobUrl = useMedia(videoHash, false, ApiMediaFormat.BlobUrl, lastSyncTime);
|
|
||||||
const hasBlobUrl = Boolean(imgBlobUrl || videoBlobUrl);
|
|
||||||
const { transitionClassNames } = useShowTransition(hasBlobUrl, undefined, hasBlobUrl, 'slow');
|
|
||||||
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
@ -144,11 +149,11 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
alt={author}
|
alt={author}
|
||||||
decoding="async"
|
decoding="async"
|
||||||
/>
|
/>
|
||||||
{videoBlobUrl && (
|
{shouldPlayVideo && (
|
||||||
<video
|
<video
|
||||||
ref={videoRef}
|
ref={videoRef}
|
||||||
src={videoBlobUrl}
|
src={videoBlobUrl}
|
||||||
className={buildClassName(cn.media, 'avatar-media', transitionClassNames)}
|
className={buildClassName(cn.media, 'avatar-media')}
|
||||||
muted
|
muted
|
||||||
autoPlay
|
autoPlay
|
||||||
disablePictureInPicture
|
disablePictureInPicture
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user