Gift Preview Modal: Fix animation (#6734)

This commit is contained in:
Alexander Zinchuk 2026-02-27 19:51:25 +01:00
parent 64c5b740d3
commit ca7d6eef8a
2 changed files with 16 additions and 5 deletions

View File

@ -44,6 +44,8 @@ type OwnProps = {
resellPrice?: ApiTypeCurrencyAmount;
showManageButtons?: boolean;
savedGift?: ApiSavedStarGift;
noLoop?: boolean;
onStickerAnimationEnded?: (modelName: string) => void;
children?: React.ReactNode;
};
@ -61,6 +63,8 @@ const UniqueGiftHeader = ({
resellPrice,
showManageButtons,
savedGift,
noLoop,
onStickerAnimationEnded,
children,
}: OwnProps) => {
const {
@ -74,6 +78,10 @@ const UniqueGiftHeader = ({
const activeKey = useTransitionActiveKey([modelAttribute, backdropAttribute, patternAttribute]);
const subtitleColor = backdropAttribute?.textColor;
const handleStickerEnded = () => {
onStickerAnimationEnded?.(modelAttribute.name);
};
const radialPatternBackdrop = useMemo(() => {
const backdropColors = [backdropAttribute.centerColor, backdropAttribute.edgeColor];
@ -112,7 +120,8 @@ const UniqueGiftHeader = ({
className={styles.sticker}
sticker={modelAttribute.sticker}
size={STICKER_SIZE}
noLoop={!isGiftHover}
noLoop={noLoop ?? !isGiftHover}
onEnded={handleStickerEnded}
onMouseEnter={!IS_TOUCH_ENV ? markGiftHover : undefined}
onMouseLeave={!IS_TOUCH_ENV ? unmarkGiftHover : undefined}
/>

View File

@ -15,7 +15,6 @@ import { getNextArrowReplacement } from '../../../../util/localization/format';
import { resolveTransitionName } from '../../../../util/resolveTransitionName';
import { getGiftAttributes, getRandomGiftPreviewAttributes } from '../../../common/helpers/gifts';
import useInterval from '../../../../hooks/schedulers/useInterval';
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
import useFlag from '../../../../hooks/useFlag';
import { useIntersectionObserver } from '../../../../hooks/useIntersectionObserver';
@ -45,7 +44,6 @@ type StateProps = {
const MODEL_STICKER_SIZE = 80;
const PATTERN_STICKER_SIZE = 60;
const INTERSECTION_THROTTLE = 200;
const PLAYBACK_INTERVAL = 5000;
enum AttributeTab {
Model,
@ -125,7 +123,9 @@ const GiftPreviewModal = ({ modal, animationLevel }: OwnProps & StateProps) => {
if (newModel && newModel.rarity.type !== 'regular') showCraftableModels();
}, [initialAttributes, firstModel, firstPattern, firstBackdrop]);
useInterval(() => {
const handleStickerAnimationEnded = useLastCallback((modelName: string) => {
if (modelName !== selectedModel?.name || !isPlayingRandomPreviews) return;
if (!originGift || !selectedModel || !selectedPattern || !selectedBackdrop) return;
const newAttributes = getRandomGiftPreviewAttributes(renderingModal?.attributes, {
model: selectedModel,
@ -135,7 +135,7 @@ const GiftPreviewModal = ({ modal, animationLevel }: OwnProps & StateProps) => {
setSelectedModel(newAttributes.model);
setSelectedPattern(newAttributes.pattern);
setSelectedBackdrop(newAttributes.backdrop);
}, isPlayingRandomPreviews ? PLAYBACK_INTERVAL : undefined, true);
});
const {
observe: observeModelsIntersection,
@ -273,6 +273,8 @@ const GiftPreviewModal = ({ modal, animationLevel }: OwnProps & StateProps) => {
patternAttribute={selectedPattern}
title={originGift?.title}
subtitle={lang('GiftPreviewSelectedTraits')}
noLoop={isPlayingRandomPreviews}
onStickerAnimationEnded={handleStickerAnimationEnded}
>
<div
className={styles.traitButtons}