TelegramPWA/src/components/middle/message/ReactionButton.tsx
2022-03-19 21:19:11 +01:00

80 lines
2.2 KiB
TypeScript

import React, {
FC, memo, useCallback, useMemo,
} from '../../../lib/teact/teact';
import { getActions, getGlobal } from '../../../global';
import {
ApiAvailableReaction, ApiMessage, ApiReactionCount, ApiUser,
} from '../../../api/types';
import { ActiveReaction } from '../../../global/types';
import buildClassName from '../../../util/buildClassName';
import { formatIntegerCompact } from '../../../util/textFormat';
import Button from '../../ui/Button';
import Avatar from '../../common/Avatar';
import ReactionAnimatedEmoji from './ReactionAnimatedEmoji';
import './Reactions.scss';
const MAX_REACTORS_AVATARS = 3;
const ReactionButton: FC<{
reaction: ApiReactionCount;
message: ApiMessage;
activeReaction?: ActiveReaction;
availableReactions?: ApiAvailableReaction[];
}> = ({
reaction,
message,
activeReaction,
availableReactions,
}) => {
const { sendReaction } = getActions();
const { recentReactions } = message.reactions!;
const recentReactors = useMemo(() => {
if (!recentReactions || reaction.count > MAX_REACTORS_AVATARS) {
return undefined;
}
// No need for expensive global updates on users, so we avoid them
const usersById = getGlobal().users.byId;
return recentReactions
.filter((recentReaction) => recentReaction.reaction === reaction.reaction)
.map((recentReaction) => usersById[recentReaction.userId])
.filter(Boolean) as ApiUser[];
}, [reaction, recentReactions]);
const handleClick = useCallback(() => {
sendReaction({
reaction: reaction.isChosen ? undefined : reaction.reaction,
chatId: message.chatId,
messageId: message.id,
});
}, [message, reaction, sendReaction]);
return (
<Button
className={buildClassName(reaction.isChosen && 'chosen')}
size="tiny"
onClick={handleClick}
>
<ReactionAnimatedEmoji
activeReaction={activeReaction}
reaction={reaction.reaction}
availableReactions={availableReactions}
/>
{recentReactors?.length ? (
<div className="avatars">
{recentReactors.map((user) => <Avatar user={user} size="micro" />)}
</div>
) : formatIntegerCompact(reaction.count)}
</Button>
);
};
export default memo(ReactionButton);