From 3e962620385c1213b12f6d2cd80a5822b26c767e Mon Sep 17 00:00:00 2001 From: Alexander Zinchuk Date: Thu, 28 Dec 2023 14:38:10 +0100 Subject: [PATCH] PremiumMainModal: Render all subscription options (#4129) --- src/api/gramjs/apiBuilders/payments.ts | 2 +- src/api/types/payments.ts | 2 +- .../main/premium/GiftPremiumModal.tsx | 4 +- .../main/premium/PremiumMainModal.module.scss | 8 +++ .../main/premium/PremiumMainModal.tsx | 68 +++++++++++++++---- ... => PremiumSubscriptionOption.module.scss} | 0 ...tion.tsx => PremiumSubscriptionOption.tsx} | 26 ++++--- src/global/actions/api/payments.ts | 2 +- 8 files changed, 87 insertions(+), 25 deletions(-) rename src/components/main/premium/{GiftOption.module.scss => PremiumSubscriptionOption.module.scss} (100%) rename src/components/main/premium/{GiftOption.tsx => PremiumSubscriptionOption.tsx} (77%) diff --git a/src/api/gramjs/apiBuilders/payments.ts b/src/api/gramjs/apiBuilders/payments.ts index e6d8956b2..7fa293b74 100644 --- a/src/api/gramjs/apiBuilders/payments.ts +++ b/src/api/gramjs/apiBuilders/payments.ts @@ -194,7 +194,7 @@ function buildApiPremiumSubscriptionOption(option: GramJs.PremiumSubscriptionOpt isCurrent: current, canPurchaseUpgrade, currency, - amount: amount.toString(), + amount: amount.toJSNumber(), botUrl, months, }; diff --git a/src/api/types/payments.ts b/src/api/types/payments.ts index f43b6171e..46debc51d 100644 --- a/src/api/types/payments.ts +++ b/src/api/types/payments.ts @@ -75,7 +75,7 @@ export interface ApiPremiumSubscriptionOption { canPurchaseUpgrade?: boolean; months: number; currency: string; - amount: string; + amount: number; botUrl: string; } diff --git a/src/components/main/premium/GiftPremiumModal.tsx b/src/components/main/premium/GiftPremiumModal.tsx index c02fd1e2b..f0042faba 100644 --- a/src/components/main/premium/GiftPremiumModal.tsx +++ b/src/components/main/premium/GiftPremiumModal.tsx @@ -22,7 +22,7 @@ import Avatar from '../../common/Avatar'; import Button from '../../ui/Button'; import Link from '../../ui/Link'; import Modal from '../../ui/Modal'; -import GiftOption from './GiftOption'; +import PremiumSubscriptionOption from './PremiumSubscriptionOption'; import styles from './GiftPremiumModal.module.scss'; @@ -141,7 +141,7 @@ const GiftPremiumModal: FC = ({
{renderedGifts?.map((gift) => ( - = ({ const lang = useLang(); const [isHeaderHidden, setHeaderHidden] = useState(true); const [currentSection, setCurrentSection] = useState(initialSection); + const [selectedSubscriptionOption, setSubscriptionOption] = useState(); const handleOpen = useCallback((section: string | undefined) => { return () => { @@ -146,7 +148,7 @@ const PremiumMainModal: FC = ({ setHeaderHidden(scrollTop <= 150); } - function handleClickWithStartParam(startParam?: string) { + const handleClickWithStartParam = useLastCallback((startParam?: string) => { const dialog = dialogRef.current; if (!dialog) return; @@ -160,12 +162,21 @@ const PremiumMainModal: FC = ({ }); closePremiumModal(); } - } - - const handleClick = useLastCallback(() => { - handleClickWithStartParam(); }); + const handleClick = useCallback(() => { + if (selectedSubscriptionOption) { + handleClickWithStartParam(String(selectedSubscriptionOption.months)); + } else { + handleClickWithStartParam(); + } + }, [selectedSubscriptionOption, handleClickWithStartParam]); + + const handleChangeSubscriptionOption = useCallback((months: number) => { + const foundOption = promo?.options.find((option) => option.months === months); + setSubscriptionOption(foundOption); + }, [promo]); + const showConfetti = useCallback(() => { const dialog = dialogRef.current; if (!dialog) return; @@ -206,6 +217,11 @@ const PremiumMainModal: FC = ({ }); }, [loadStickers, fromUserStatusEmoji, fromUserStatusSet]); + useEffect(() => { + const [defaultOption] = promo?.options ?? []; + setSubscriptionOption(defaultOption); + }, [promo]); + const handleOpenStatusSet = useLastCallback(() => { if (!fromUserStatusSet) return; @@ -231,10 +247,15 @@ const PremiumMainModal: FC = ({ return [renderText(first), link, renderText(second)]; }, [fromUser, fromUserStatusSet, lang]); - if (!promo || (fromUserStatusEmoji && !fromUserStatusSet)) return undefined; + const fullMonthlyAmount = useMemo(() => { + const monthOption = promo?.options.find((option) => option.months === 1); + if (!monthOption) { + return undefined; + } + return Number(monthOption.amount); + }, [promo]); - // TODO Support all subscription options - const month = promo.options.find((option) => option.months === 1)!; + if (!promo || (fromUserStatusEmoji && !fromUserStatusSet)) return undefined; function getHeaderText() { if (isGift) { @@ -279,6 +300,24 @@ const PremiumMainModal: FC = ({ ); } + function renderSubscriptionOptions() { + return ( +
+ {promo?.options + .map((option) => ( + + ))} +
+ ); + } + return ( = ({
{renderText(getHeaderDescription(), ['simple_markdown', 'emoji'])}
+ {!isPremium && renderSubscriptionOptions()}

{lang('TelegramPremium')}

-
{filteredSections.map((section, index) => { return ( @@ -355,10 +394,15 @@ const PremiumMainModal: FC = ({
{renderFooterText()}
- {!isPremium && ( + {!isPremium && selectedSubscriptionOption && (
)} diff --git a/src/components/main/premium/GiftOption.module.scss b/src/components/main/premium/PremiumSubscriptionOption.module.scss similarity index 100% rename from src/components/main/premium/GiftOption.module.scss rename to src/components/main/premium/PremiumSubscriptionOption.module.scss diff --git a/src/components/main/premium/GiftOption.tsx b/src/components/main/premium/PremiumSubscriptionOption.tsx similarity index 77% rename from src/components/main/premium/GiftOption.tsx rename to src/components/main/premium/PremiumSubscriptionOption.tsx index d07912dc4..7f510e11b 100644 --- a/src/components/main/premium/GiftOption.tsx +++ b/src/components/main/premium/PremiumSubscriptionOption.tsx @@ -2,24 +2,27 @@ import type { ChangeEvent } from 'react'; import type { FC } from '../../../lib/teact/teact'; import React, { memo, useCallback, useMemo } from '../../../lib/teact/teact'; -import type { ApiPremiumGiftOption } from '../../../api/types'; - import buildClassName from '../../../util/buildClassName'; import { formatCurrency } from '../../../util/formatCurrency'; import useLang from '../../../hooks/useLang'; -import styles from './GiftOption.module.scss'; +import styles from './PremiumSubscriptionOption.module.scss'; type OwnProps = { - option: ApiPremiumGiftOption; + option: { + months: number; + currency: string; + amount: number; + }; checked?: boolean; fullMonthlyAmount?: number; + className?: string; onChange: (month: number) => void; }; -const GiftOption: FC = ({ - option, checked, fullMonthlyAmount, onChange, +const PremiumSubscriptionOption: FC = ({ + option, checked, fullMonthlyAmount, onChange, className, }) => { const lang = useLang(); @@ -39,7 +42,14 @@ const GiftOption: FC = ({ }, [months, onChange]); return ( -