79 lines
2.0 KiB
TypeScript
79 lines
2.0 KiB
TypeScript
import type { FC } from '../../../lib/teact/teact';
|
|
import React, { memo, useMemo } from '../../../lib/teact/teact';
|
|
|
|
import type { ApiEmojiStatus, ApiReactionCustomEmoji } from '../../../api/types';
|
|
|
|
import { getStickerPreviewHash } from '../../../global/helpers';
|
|
import buildClassName from '../../../util/buildClassName';
|
|
import { IS_OFFSET_PATH_SUPPORTED } from '../../../util/windowEnvironment';
|
|
|
|
import useMedia from '../../../hooks/useMedia';
|
|
|
|
import CustomEmoji from '../CustomEmoji';
|
|
|
|
import styles from './CustomEmojiEffect.module.scss';
|
|
|
|
type OwnProps = {
|
|
reaction: ApiReactionCustomEmoji | ApiEmojiStatus;
|
|
className?: string;
|
|
isLottie?: boolean;
|
|
};
|
|
|
|
const EFFECT_AMOUNT = 7;
|
|
|
|
const CustomEmojiEffect: FC<OwnProps> = ({
|
|
reaction,
|
|
isLottie,
|
|
className,
|
|
}) => {
|
|
const stickerHash = getStickerPreviewHash(reaction.documentId);
|
|
|
|
const previewMediaData = useMedia(!isLottie ? stickerHash : undefined);
|
|
|
|
const paths: string[] = useMemo(() => {
|
|
if (!IS_OFFSET_PATH_SUPPORTED) return [];
|
|
return Array.from({ length: EFFECT_AMOUNT }).map(() => generateRandomDropPath());
|
|
}, []);
|
|
|
|
if (!previewMediaData && !isLottie) {
|
|
return undefined;
|
|
}
|
|
|
|
return (
|
|
<div className={buildClassName(styles.root, className)}>
|
|
{paths.map((path) => {
|
|
const style = `--offset-path: path('${path}');`;
|
|
if (isLottie) {
|
|
return (
|
|
<CustomEmoji
|
|
documentId={reaction.documentId}
|
|
className={styles.particle}
|
|
style={style}
|
|
withSharedAnimation
|
|
/>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<img
|
|
src={previewMediaData}
|
|
alt=""
|
|
className={styles.particle}
|
|
style={style}
|
|
draggable={false}
|
|
/>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default memo(CustomEmojiEffect);
|
|
|
|
function generateRandomDropPath() {
|
|
const x = (10 + Math.random() * 60) * (Math.random() > 0.5 ? 1 : -1);
|
|
const y = 20 + Math.random() * 80;
|
|
|
|
return `M 0 0 C 0 0 ${x} ${-y - 20} ${x} ${y}`;
|
|
}
|