Messages: Add appearance order to avatar list (#5731)

This commit is contained in:
Alexander Zinchuk 2025-03-27 19:03:15 +01:00
parent 839f630466
commit da69dea394
3 changed files with 32 additions and 4 deletions

View File

@ -264,6 +264,7 @@ const MessageListContent: FC<OwnProps> = ({
const lastMessageOrAlbum = senderGroup[senderGroup.length - 1]; const lastMessageOrAlbum = senderGroup[senderGroup.length - 1];
const lastMessage = isAlbum(lastMessageOrAlbum) ? lastMessageOrAlbum.mainMessage : lastMessageOrAlbum; const lastMessage = isAlbum(lastMessageOrAlbum) ? lastMessageOrAlbum.mainMessage : lastMessageOrAlbum;
const lastMessageId = getMessageOriginalId(lastMessage); const lastMessageId = getMessageOriginalId(lastMessage);
const lastAppearanceOrder = messageCountToAnimate - appearanceIndex;
const isTopicTopMessage = lastMessage.id === threadId; const isTopicTopMessage = lastMessage.id === threadId;
const isOwn = isOwnMessage(lastMessage); const isOwn = isOwnMessage(lastMessage);
@ -283,6 +284,7 @@ const MessageListContent: FC<OwnProps> = ({
id={id} id={id}
message={lastMessage} message={lastMessage}
withAvatar={withAvatar} withAvatar={withAvatar}
appearanceOrder={lastAppearanceOrder}
> >
{senderGroupElements} {senderGroupElements}
</SenderGroupContainer> </SenderGroupContainer>

View File

@ -10,8 +10,10 @@
bottom: 0; bottom: 0;
z-index: 2; z-index: 2;
transform: translateX(0); transform: translateX(0) scale(1);
transition: transform var(--select-transition); opacity: 1;
transition: opacity 0.2s, transform var(--select-transition);
:global(.select-mode-active) & { :global(.select-mode-active) & {
transform: translateX(2.5rem); transform: translateX(2.5rem);

View File

@ -1,6 +1,7 @@
import type { FC } from '../../../lib/teact/teact'; import type { FC } from '../../../lib/teact/teact';
import React, { import React, {
memo, memo,
useEffect,
} from '../../../lib/teact/teact'; } from '../../../lib/teact/teact';
import { getActions, withGlobal } from '../../../global'; import { getActions, withGlobal } from '../../../global';
@ -9,6 +10,7 @@ import type {
ApiPeer, ApiPeer,
} from '../../../api/types'; } from '../../../api/types';
import { MESSAGE_APPEARANCE_DELAY } from '../../../config';
import { import {
isAnonymousForwardsChat, isAnonymousForwardsChat,
isAnonymousOwnMessage, isAnonymousOwnMessage,
@ -21,7 +23,9 @@ import {
} from '../../../global/selectors'; } from '../../../global/selectors';
import buildClassName from '../../../util/buildClassName'; import buildClassName from '../../../util/buildClassName';
import useFlag from '../../../hooks/useFlag';
import useLastCallback from '../../../hooks/useLastCallback'; import useLastCallback from '../../../hooks/useLastCallback';
import useShowTransition from '../../../hooks/useShowTransition';
import Avatar from '../../common/Avatar'; import Avatar from '../../common/Avatar';
@ -33,6 +37,7 @@ type OwnProps =
withAvatar?: boolean; withAvatar?: boolean;
children: React.ReactNode; children: React.ReactNode;
id: string; id: string;
appearanceOrder: number;
}; };
type StateProps = { type StateProps = {
@ -49,6 +54,7 @@ const SenderGroupContainer: FC<OwnProps & StateProps> = ({
withAvatar, withAvatar,
children, children,
id, id,
appearanceOrder,
sender, sender,
canShowSender, canShowSender,
originSender, originSender,
@ -62,6 +68,16 @@ const SenderGroupContainer: FC<OwnProps & StateProps> = ({
const messageSender = canShowSender ? sender : undefined; const messageSender = canShowSender ? sender : undefined;
const noAppearanceAnimation = appearanceOrder <= 0;
const [isShown, markShown] = useFlag(noAppearanceAnimation);
useEffect(() => {
if (noAppearanceAnimation) {
return;
}
setTimeout(markShown, appearanceOrder * MESSAGE_APPEARANCE_DELAY);
}, [appearanceOrder, markShown, noAppearanceAnimation]);
const shouldPreferOriginSender = forwardInfo const shouldPreferOriginSender = forwardInfo
&& (isChatWithSelf || isRepliesChat || isAnonymousForwards || !messageSender); && (isChatWithSelf || isRepliesChat || isAnonymousForwards || !messageSender);
const avatarPeer = shouldPreferOriginSender ? originSender : messageSender; const avatarPeer = shouldPreferOriginSender ? originSender : messageSender;
@ -74,6 +90,14 @@ const SenderGroupContainer: FC<OwnProps & StateProps> = ({
openChat({ id: avatarPeer.id }); openChat({ id: avatarPeer.id });
}); });
const {
ref: avatarRef,
shouldRender,
} = useShowTransition({
isOpen: withAvatar && isShown,
withShouldRender: true,
});
function renderAvatar() { function renderAvatar() {
const hiddenName = (!avatarPeer && forwardInfo) ? forwardInfo.hiddenUserName : undefined; const hiddenName = (!avatarPeer && forwardInfo) ? forwardInfo.hiddenUserName : undefined;
@ -95,8 +119,8 @@ const SenderGroupContainer: FC<OwnProps & StateProps> = ({
return ( return (
<div id={id} className={className}> <div id={id} className={className}>
{withAvatar && ( {shouldRender && (
<div className={styles.avatarContainer}> <div ref={avatarRef} className={styles.avatarContainer}>
{renderAvatar()} {renderAvatar()}
</div> </div>
)} )}