Avatar: Animate online status

This commit is contained in:
Alexander Zinchuk 2023-04-17 22:57:07 +02:00
parent c722a3ba30
commit 8be0459193
2 changed files with 31 additions and 19 deletions

View File

@ -124,20 +124,27 @@
}
}
&.online {
&::after {
content: "";
display: block;
position: absolute;
bottom: 0.0625rem;
right: 0.0625rem;
width: 0.875rem;
height: 0.875rem;
border-radius: 50%;
border: 2px solid var(--color-background);
background-color: #0ac630;
flex-shrink: 0;
}
&.online::after {
content: "";
display: block;
position: absolute;
bottom: 0.0625rem;
right: 0.0625rem;
width: 0.875rem;
height: 0.875rem;
border-radius: 50%;
border: 2px solid var(--color-background);
background-color: #0ac630;
flex-shrink: 0;
opacity: 0.5;
transform: scale(0);
transition: opacity 200ms, transform 200ms;
}
&.online-open::after {
opacity: 1;
transform: scale(1);
}
&.interactive {

View File

@ -1,6 +1,6 @@
import type { MouseEvent as ReactMouseEvent } from 'react';
import React, {
memo, useCallback, useEffect, useRef,
memo, useCallback, useEffect, useMemo, useRef,
} from '../../lib/teact/teact';
import { getActions } from '../../global';
@ -29,7 +29,7 @@ import buildClassName, { createClassNameBuilder } from '../../util/buildClassNam
import renderText from './helpers/renderText';
import useMedia from '../../hooks/useMedia';
import useShowTransition from '../../hooks/useShowTransition';
import useMediaTransition from '../../hooks/useMediaTransition';
import useLang from '../../hooks/useLang';
import { useIsIntersecting } from '../../hooks/useIntersectionObserver';
@ -127,7 +127,13 @@ const Avatar: FC<OwnProps> = ({
// `videoBlobUrl` can be taken from memory cache, so we need to check `shouldLoadVideo` again
const shouldPlayVideo = Boolean(isIntersectingForVideo && videoBlobUrl && shouldLoadVideo);
const { transitionClassNames } = useShowTransition(hasBlobUrl, undefined, hasBlobUrl, 'slow');
const transitionClassNames = useMediaTransition(hasBlobUrl);
const isOnline = !isSavedMessages && user && userStatus && isUserOnline(user, userStatus);
const onlineTransitionClassNames = useMediaTransition(isOnline);
const onlineClassNamesPrefixed = useMemo(() => {
return onlineTransitionClassNames.split(' ').map((c) => (c === 'shown' ? 'online' : `online-${c}`)).join(' ');
}, [onlineTransitionClassNames]);
const handleVideoEnded = useCallback((e) => {
const video = e.currentTarget;
@ -193,7 +199,6 @@ const Avatar: FC<OwnProps> = ({
content = getFirstLetters(text, 2);
}
const isOnline = !isSavedMessages && user && userStatus && isUserOnline(user, userStatus);
const fullClassName = buildClassName(
`Avatar size-${size}`,
className,
@ -202,7 +207,7 @@ const Avatar: FC<OwnProps> = ({
isDeleted && 'deleted-account',
isReplies && 'replies-bot-account',
isForum && 'forum',
isOnline && 'online',
onlineClassNamesPrefixed,
onClick && 'interactive',
(!isSavedMessages && !imgBlobUrl) && 'no-photo',
);