Chat Badge: Fix animation (#6905)
This commit is contained in:
parent
57bcad5215
commit
caa1cc8621
@ -20,6 +20,8 @@
|
||||
}
|
||||
|
||||
.transition {
|
||||
transform-origin: center;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
@ -28,7 +30,7 @@
|
||||
|
||||
opacity: 1;
|
||||
|
||||
transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1);
|
||||
transition: transform 0.15s ease-out, opacity 0.15s ease-out;
|
||||
|
||||
&:not(:global(.open)) {
|
||||
transform: scale(0);
|
||||
@ -38,12 +40,6 @@
|
||||
&:not(:global(.shown)) {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&:global(.closing) {
|
||||
transition:
|
||||
transform 0.2s ease-out,
|
||||
opacity 0.2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
.wrapper {
|
||||
|
||||
@ -18,6 +18,7 @@ import useSelector, { useShallowSelector } from '../../../hooks/data/useSelector
|
||||
import useDerivedState from '../../../hooks/useDerivedState';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
import useLastCallback from '../../../hooks/useLastCallback';
|
||||
import useShowTransitionSwap from '../../../hooks/useShowTransitionSwap';
|
||||
|
||||
import AnimatedCounter from '../../common/AnimatedCounter';
|
||||
import Icon from '../../common/icons/Icon';
|
||||
@ -153,6 +154,12 @@ const ChatBadge = ({
|
||||
|| isTopicUnopened || hasMiniApp,
|
||||
);
|
||||
|
||||
const contentCategory = (isUnread || unreadMentionsCount || unreadReactionsCount
|
||||
|| unreadPollVotesCount || isTopicUnopened)
|
||||
? 'active'
|
||||
: (hasMiniApp ? 'miniapp' : (isPinned ? 'pinned' : 'none'));
|
||||
const effectiveIsOpen = useShowTransitionSwap(isShown, contentCategory);
|
||||
|
||||
const handleOpenApp = useLastCallback((e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
|
||||
e.stopPropagation();
|
||||
|
||||
@ -263,7 +270,7 @@ const ChatBadge = ({
|
||||
isOnAvatar && styles.onAvatar,
|
||||
transitionClassName,
|
||||
)}
|
||||
isOpen={isShown}
|
||||
isOpen={effectiveIsOpen}
|
||||
>
|
||||
{renderContent()}
|
||||
</ShowTransition>
|
||||
|
||||
31
src/hooks/useShowTransitionSwap.ts
Normal file
31
src/hooks/useShowTransitionSwap.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { useRef } from '../lib/teact/teact';
|
||||
|
||||
import useForceUpdate from './useForceUpdate';
|
||||
import usePreviousDeprecated from './usePreviousDeprecated';
|
||||
import useSyncEffect from './useSyncEffect';
|
||||
|
||||
const SWAP_CLOSE_DURATION = 150;
|
||||
|
||||
export default function useShowTransitionSwap(isOpen: boolean, contentKey?: string): boolean {
|
||||
const prevIsOpen = usePreviousDeprecated(isOpen);
|
||||
const prevContentKey = usePreviousDeprecated(contentKey);
|
||||
const isSwappingRef = useRef(false);
|
||||
const forceUpdate = useForceUpdate();
|
||||
|
||||
if (isOpen && prevIsOpen
|
||||
&& contentKey !== undefined && prevContentKey !== undefined
|
||||
&& prevContentKey !== contentKey && !isSwappingRef.current) {
|
||||
isSwappingRef.current = true;
|
||||
}
|
||||
|
||||
useSyncEffect(() => {
|
||||
if (!isSwappingRef.current) return undefined;
|
||||
const timer = window.setTimeout(() => {
|
||||
isSwappingRef.current = false;
|
||||
forceUpdate();
|
||||
}, SWAP_CLOSE_DURATION);
|
||||
return () => clearTimeout(timer);
|
||||
}, [contentKey]);
|
||||
|
||||
return isOpen && !isSwappingRef.current;
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user