From 76629db59f20bf1c5190c80a99b41759e4c8bdb0 Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Mon, 4 Dec 2023 14:39:22 +0100 Subject: [PATCH] Premium modal: Various fixes (#4045) --- .../main/premium/PremiumFeatureModal.tsx | 25 +++++++++----- .../main/premium/PremiumMainModal.tsx | 1 + .../PremiumFeaturePreviewStickers.tsx | 34 +++++++++++-------- .../PremiumFeaturePreviewStories.module.scss | 3 +- .../mediaArea/MediaAreaSuggestedReaction.tsx | 20 ++++++----- 5 files changed, 50 insertions(+), 33 deletions(-) diff --git a/src/components/main/premium/PremiumFeatureModal.tsx b/src/components/main/premium/PremiumFeatureModal.tsx index dcdf8d9d2..f9feae319 100644 --- a/src/components/main/premium/PremiumFeatureModal.tsx +++ b/src/components/main/premium/PremiumFeatureModal.tsx @@ -1,6 +1,6 @@ import type { FC } from '../../../lib/teact/teact'; import React, { - memo, useCallback, useEffect, useRef, useState, + memo, useCallback, useEffect, useMemo, useRef, useState, } from '../../../lib/teact/teact'; import type { ApiPremiumPromo } from '../../../api/types'; @@ -127,21 +127,23 @@ const LIMITS_DESCRIPTIONS: Record = { const BORDER_THRESHOLD = 20; type OwnProps = { - onBack: VoidFunction; initialSection: string; promo: ApiPremiumPromo; - onClickSubscribe: (startParam?: string) => void; isPremium?: boolean; limits?: NonNullable['limits']; + premiumPromoOrder?: string[]; + onBack: VoidFunction; + onClickSubscribe: (startParam?: string) => void; }; const PremiumFeatureModal: FC = ({ promo, initialSection, - onBack, - onClickSubscribe, isPremium, limits, + premiumPromoOrder, + onBack, + onClickSubscribe, }) => { const lang = useLang(); // eslint-disable-next-line no-null/no-null @@ -155,6 +157,11 @@ const PremiumFeatureModal: FC = ({ const prevInitialSection = usePrevious(initialSection); + const filteredSections = useMemo(() => { + if (!premiumPromoOrder) return PREMIUM_FEATURE_SECTIONS; + return premiumPromoOrder.filter((section) => PREMIUM_FEATURE_SECTIONS.includes(section)); + }, [premiumPromoOrder]); + function handleClick() { onClickSubscribe(initialSection); } @@ -192,12 +199,12 @@ const PremiumFeatureModal: FC = ({ const scrollContainer = scrollContainerRef.current; if (!scrollContainer || (prevInitialSection === initialSection)) return; - const index = PREMIUM_FEATURE_SECTIONS.indexOf(initialSection); + const index = filteredSections.indexOf(initialSection); setCurrentSlideIndex(index); startScrolling(); animateHorizontalScroll(scrollContainer, scrollContainer.clientWidth * index, 0) .then(stopScrolling); - }, [currentSlideIndex, initialSection, prevInitialSection, startScrolling, stopScrolling]); + }, [currentSlideIndex, filteredSections, initialSection, prevInitialSection]); const handleSelectSlide = useCallback(async (index: number) => { const scrollContainer = scrollContainerRef.current; @@ -208,7 +215,7 @@ const PremiumFeatureModal: FC = ({ startScrolling(); await animateHorizontalScroll(scrollContainer, scrollContainer.clientWidth * index, 800); stopScrolling(); - }, [startScrolling, stopScrolling]); + }, []); // TODO Support all subscription options const month = promo.options.find((option) => option.months === 1)!; @@ -230,7 +237,7 @@ const PremiumFeatureModal: FC = ({
- {PREMIUM_FEATURE_SECTIONS.map((section, index) => { + {filteredSections.map((section, index) => { if (section === 'double_limits') { return (
diff --git a/src/components/main/premium/PremiumMainModal.tsx b/src/components/main/premium/PremiumMainModal.tsx index 09b2beecd..50c537bf4 100644 --- a/src/components/main/premium/PremiumMainModal.tsx +++ b/src/components/main/premium/PremiumMainModal.tsx @@ -372,6 +372,7 @@ const PremiumMainModal: FC = ({ onClickSubscribe={handleClickWithStartParam} isPremium={isPremium} limits={limits} + premiumPromoOrder={premiumPromoOrder} /> )} diff --git a/src/components/main/premium/previews/PremiumFeaturePreviewStickers.tsx b/src/components/main/premium/previews/PremiumFeaturePreviewStickers.tsx index 04fafaf31..28f128aa0 100644 --- a/src/components/main/premium/previews/PremiumFeaturePreviewStickers.tsx +++ b/src/components/main/premium/previews/PremiumFeaturePreviewStickers.tsx @@ -1,6 +1,6 @@ import type { FC } from '../../../../lib/teact/teact'; import React, { - memo, useCallback, useEffect, useRef, useState, + memo, useEffect, useRef, useState, } from '../../../../lib/teact/teact'; import { withGlobal } from '../../../../global'; @@ -10,6 +10,7 @@ import type { GlobalState } from '../../../../global/types'; import cycleRestrict from '../../../../util/cycleRestrict'; import useFlag from '../../../../hooks/useFlag'; +import useLastCallback from '../../../../hooks/useLastCallback'; import useMedia from '../../../../hooks/useMedia'; import AnimatedSticker from '../../../common/AnimatedSticker'; @@ -36,7 +37,7 @@ const AnimatedCircleSticker: FC<{ index: number; maxLength: number; onClick: (index: number) => void; - onEnded: NoneToVoidFunction; + onEnded: (index: number) => void; canPlay: boolean; }> = ({ size, realIndex, canPlay, @@ -60,14 +61,14 @@ const AnimatedCircleSticker: FC<{ const x = Math.cos(angle) * width - circleSize * 2.8; const y = Math.sin(angle) * height; - const handleClick = useCallback(() => { + const handleClick = useLastCallback(() => { onClick(realIndex); - }, [onClick, realIndex]); + }); - const handleEnded = useCallback(() => { + const handleEnded = useLastCallback(() => { inanimate(); - onEnded(); - }, [inanimate, onEnded]); + onEnded(realIndex); + }); useEffect(() => { if (isActivated) { @@ -112,15 +113,20 @@ const PremiumFeaturePreviewStickers: FC = ({ const renderedStickers = stickers?.slice(0, MAX_EMOJIS); - const handleClick = useCallback((i: number) => { + const handleClick = useLastCallback((i: number) => { setOffset(-i); - }, []); + }); + + const handleEnded = useLastCallback((i: number) => { + const displayIndex = cycleRestrict(renderedStickers.length, i + offset); + if (displayIndex !== 0) return; - const handleEnded = useCallback(() => { setTimeout(() => { - setOffset((current) => cycleRestrict(renderedStickers.length, current + 1)); + setOffset((current) => { + return cycleRestrict(renderedStickers.length, current + 1); + }); }, ENDED_DELAY); - }, [renderedStickers.length]); + }); useEffect(() => { const container = containerRef.current; @@ -134,11 +140,11 @@ const PremiumFeaturePreviewStickers: FC = ({ className={styles.root} ref={containerRef} > - {Boolean(size) && renderedStickers?.map((l, i) => { + {Boolean(size) && renderedStickers?.map((sticker, i) => { return ( - + {Boolean(customEmojiSize) && ( + + )} {shouldDisplayCount && ( {reactionCount} )}