import type { ChangeEvent } from 'react'; import type { FC } from '../../../lib/teact/teact'; import type React from '../../../lib/teact/teact'; import { memo, useEffect, useMemo, useRef, useState, } from '../../../lib/teact/teact'; import { getActions, getGlobal, withGlobal } from '../../../global'; import type { ApiCountry, ApiPremiumGiftCodeOption, ApiPrepaidGiveaway, ApiPrepaidStarsGiveaway, ApiStarGiveawayOption, ApiTypePrepaidGiveaway, } from '../../../api/types'; import { GIVEAWAY_BOOST_PER_PREMIUM, GIVEAWAY_MAX_ADDITIONAL_CHANNELS, GIVEAWAY_MAX_ADDITIONAL_COUNTRIES, GIVEAWAY_MAX_ADDITIONAL_USERS, STARS_CURRENCY_CODE, } from '../../../config'; import { getUserFullName, isChatChannel } from '../../../global/helpers'; import { selectChat, selectTabState, } from '../../../global/selectors'; import buildClassName from '../../../util/buildClassName'; import { formatDateTimeToString } from '../../../util/dates/dateFormat'; import { unique } from '../../../util/iteratees'; import renderText from '../../common/helpers/renderText'; import useFlag from '../../../hooks/useFlag'; import useLastCallback from '../../../hooks/useLastCallback'; import useOldLang from '../../../hooks/useOldLang'; import CalendarModal from '../../common/CalendarModal'; import CountryPickerModal from '../../common/CountryPickerModal.async'; import GroupChatInfo from '../../common/GroupChatInfo'; import Icon from '../../common/icons/Icon'; import StarTopupOptionList from '../../modals/stars/StarTopupOptionList'; import Button from '../../ui/Button'; import ConfirmDialog from '../../ui/ConfirmDialog'; import InputText from '../../ui/InputText'; import Link from '../../ui/Link'; import ListItem from '../../ui/ListItem'; import Modal from '../../ui/Modal'; import RadioGroup from '../../ui/RadioGroup'; import RangeSliderWithMarks from '../../ui/RangeSliderWithMarks'; import Switcher from '../../ui/Switcher'; import GiveawayChannelPickerModal from './GiveawayChannelPickerModal'; import GiveawayTypeOption from './GiveawayTypeOption'; import GiveawayUserPickerModal from './GiveawayUserPickerModal'; import PremiumSubscriptionOption from './PremiumSubscriptionOption'; import styles from './GiveawayModal.module.scss'; import GiftBlueRound from '../../../assets/premium/GiftBlueRound.svg'; import GiftGreenRound from '../../../assets/premium/GiftGreenRound.svg'; import GiftRedRound from '../../../assets/premium/GiftRedRound.svg'; import GiftStar from '../../../assets/premium/GiftStar.svg'; import PremiumLogo from '../../../assets/premium/PremiumStar.svg'; export type OwnProps = { isOpen?: boolean; userIds?: string[]; }; type StateProps = { chatId?: string; gifts?: ApiPremiumGiftCodeOption[]; selectedMemberList?: string[] | undefined; selectedChannelList?: string[] | undefined; giveawayBoostPerPremiumLimit?: number; userSelectionLimit?: number; countryList: ApiCountry[]; prepaidGiveaway?: ApiTypePrepaidGiveaway; countrySelectionLimit: number | undefined; isChannel?: boolean; isStarsGiftEnabled?: boolean; starsGiftOptions?: ApiStarGiveawayOption[] | undefined; }; type GiveawayAction = 'createPremiumGiveaway' | 'createStarsGiveaway'; type ApiGiveawayType = 'premium_giveaway' | 'stars_giveaway'; type SubscribersType = 'all' | 'new'; interface TypeOption { name: string; text: string; value: ApiGiveawayType; img: string; actions?: GiveawayAction; isLink: boolean; onClickAction?: () => void; } const DEFAULT_CUSTOM_EXPIRE_DATE = 86400 * 3 * 1000; // 3 days const MAX_ADDITIONAL_CHANNELS = 9; const DEFAULT_BOOST_COUNT = 5; const GIVEAWAY_IMG_LIST: Partial> = { 3: GiftGreenRound, 6: GiftBlueRound, 12: GiftRedRound, }; const GiveawayModal: FC = ({ chatId, gifts, isOpen, isChannel, selectedMemberList, selectedChannelList, giveawayBoostPerPremiumLimit = GIVEAWAY_BOOST_PER_PREMIUM, countryList, prepaidGiveaway, countrySelectionLimit = GIVEAWAY_MAX_ADDITIONAL_COUNTRIES, userSelectionLimit = GIVEAWAY_MAX_ADDITIONAL_USERS, isStarsGiftEnabled, starsGiftOptions, }) => { const dialogRef = useRef(); const { closeGiveawayModal, openInvoice, openPremiumModal, launchPrepaidGiveaway, launchPrepaidStarsGiveaway, } = getActions(); const lang = useOldLang(); const [isCalendarOpened, openCalendar, closeCalendar] = useFlag(); const [isCountryPickerModalOpen, openCountryPickerModal, closeCountryPickerModal] = useFlag(); const [isConfirmModalOpen, openConfirmModal, closeConfirmModal] = useFlag(); const [isUserPickerModalOpen, openUserPickerModal, closeUserPickerModal] = useFlag(); const [isChannelPickerModalOpen, openChannelPickerModal, closeChannelPickerModal] = useFlag(); const TYPE_OPTIONS: TypeOption[] = [{ name: 'Premium.Title', text: 'BoostingWinnersRandomly', value: 'premium_giveaway', img: GiftBlueRound, actions: 'createPremiumGiveaway', isLink: true, onClickAction: () => { openUserPickerModal(); }, }]; if (isStarsGiftEnabled) { TYPE_OPTIONS.push({ name: 'TelegramStars', text: 'BoostingWinnersRandomly', value: 'stars_giveaway', img: GiftStar, actions: 'createStarsGiveaway', isLink: false, }); } const [customExpireDate, setCustomExpireDate] = useState(() => Date.now() + DEFAULT_CUSTOM_EXPIRE_DATE); const [isHeaderHidden, setHeaderHidden] = useState(true); const [selectedRandomUserCount, setSelectedRandomUserCount] = useState(DEFAULT_BOOST_COUNT); const [selectedGiveawayOption, setGiveawayOption] = useState(TYPE_OPTIONS[0].value); const [selectedStarOption, setSelectedStarOption] = useState(); const [selectedSubscriberOption, setSelectedSubscriberOption] = useState('all'); const [selectedMonthOption, setSelectedMonthOption] = useState(); const [selectedUserIds, setSelectedUserIds] = useState([]); const [selectedChannelIds, setSelectedChannelIds] = useState([]); const [selectedCountryIds, setSelectedCountryIds] = useState([]); const [shouldShowWinners, setShouldShowWinners] = useState(false); const [shouldShowPrizes, setShouldShowPrizes] = useState(false); const [prizeDescription, setPrizeDescription] = useState(undefined); const [dataPrepaidGiveaway, setDataPrepaidGiveaway] = useState(undefined); const [ dataStarsPrepaidGiveaway, setDataStarsPrepaidGiveaway, ] = useState(undefined); const isPremiumGiveaway = selectedGiveawayOption === 'premium_giveaway'; const isStarsGiveaway = selectedGiveawayOption === 'stars_giveaway'; const selectedUserCount = isPremiumGiveaway && !selectedUserIds.length ? selectedRandomUserCount : selectedUserIds.length; const boostQuantity = selectedUserCount * giveawayBoostPerPremiumLimit; const boostStarsQuantity = selectedStarOption?.yearlyBoosts; const SUBSCRIBER_OPTIONS = useMemo(() => [ { value: 'all', label: lang(isChannel ? 'BoostingAllSubscribers' : 'BoostingAllMembers'), subLabel: selectedCountryIds && selectedCountryIds.length > 0 ? lang('Giveaway.ReceiverType.Countries', selectedCountryIds.length) : lang('BoostingFromAllCountries'), }, { value: 'new', label: lang(isChannel ? 'BoostingNewSubscribers' : 'BoostingNewMembers'), subLabel: selectedCountryIds && selectedCountryIds.length > 0 ? lang('Giveaway.ReceiverType.Countries', selectedCountryIds.length) : lang('BoostingFromAllCountries'), }, ], [isChannel, lang, selectedCountryIds]); const monthQuantity = lang('Months', selectedMonthOption); const isStarsPrepaidGiveaway = prepaidGiveaway?.type === 'starsGiveaway'; const isPremiumPrepaidGiveaway = prepaidGiveaway?.type === 'giveaway'; const selectedGift = useMemo(() => { return gifts?.find((gift) => gift.months === selectedMonthOption && gift.users === selectedUserCount); }, [gifts, selectedMonthOption, selectedUserCount]); const selectedStarsGift = useMemo(() => { return starsGiftOptions?.find((gift) => { return isStarsPrepaidGiveaway && gift.stars === (dataStarsPrepaidGiveaway?.stars); }); }, [dataStarsPrepaidGiveaway, starsGiftOptions, isStarsPrepaidGiveaway]); const filteredGifts = useMemo(() => { return gifts?.filter((gift) => gift.users === selectedUserCount && gift.currency !== STARS_CURRENCY_CODE); }, [gifts, selectedUserCount]); const fullMonthlyAmount = useMemo(() => { const basicGift = filteredGifts?.reduce((acc, gift) => { return gift.amount < acc.amount ? gift : acc; }, filteredGifts[0]); return basicGift && Math.floor(basicGift.amount / basicGift.months); }, [filteredGifts]); const userCountOptions = useMemo(() => { return unique((gifts?.filter((gift) => gift.currency !== STARS_CURRENCY_CODE) ?.map((winner) => winner.users) || [])).sort((a, b) => a - b); }, [gifts]); const winnerCountOptions = useMemo(() => { return unique((selectedStarOption?.winners?.map((winner) => winner.users) || [])).sort((a, b) => a - b); }, [selectedStarOption]); useEffect(() => { if (isOpen && gifts?.length && !isStarsPrepaidGiveaway) { setSelectedMonthOption(gifts?.[0].months); } }, [isOpen, gifts, isStarsPrepaidGiveaway]); useEffect(() => { if (isOpen && starsGiftOptions?.length && !isPremiumPrepaidGiveaway) { setSelectedStarOption(starsGiftOptions?.[0]); } }, [isOpen, starsGiftOptions, isPremiumPrepaidGiveaway]); useEffect(() => { if (isOpen && isStarsPrepaidGiveaway) { setSelectedRandomUserCount(prepaidGiveaway.quantity); setDataStarsPrepaidGiveaway(prepaidGiveaway); } }, [isOpen, isStarsPrepaidGiveaway, prepaidGiveaway]); useEffect(() => { if (isOpen && isPremiumPrepaidGiveaway) { setSelectedRandomUserCount(prepaidGiveaway.quantity); setDataPrepaidGiveaway(prepaidGiveaway); setSelectedMonthOption(prepaidGiveaway.months); } }, [isOpen, isPremiumPrepaidGiveaway, prepaidGiveaway]); useEffect(() => { if (selectedMemberList) { setSelectedUserIds(selectedMemberList); } }, [selectedMemberList]); useEffect(() => { if (selectedChannelList) { setSelectedChannelIds(selectedChannelList); } }, [selectedChannelList]); const handlePremiumClick = useLastCallback(() => { openPremiumModal(); }); const handleClose = useLastCallback(() => { setDataStarsPrepaidGiveaway(undefined); setDataPrepaidGiveaway(undefined); setSelectedStarOption(undefined); setSelectedMonthOption(undefined); setSelectedRandomUserCount(DEFAULT_BOOST_COUNT); closeGiveawayModal(); }); const handleClick = useLastCallback(() => { if (isPremiumGiveaway) { if (selectedUserIds?.length) { openInvoice({ type: 'giftcode', boostChannelId: chatId!, userIds: selectedUserIds, currency: selectedGift!.currency, amount: selectedGift!.amount, option: selectedGift!, }); } else { openInvoice({ type: 'giveaway', chatId: chatId!, additionalChannelIds: selectedChannelIds, isOnlyForNewSubscribers: selectedSubscriberOption === 'new', countries: selectedCountryIds, areWinnersVisible: shouldShowWinners, prizeDescription, untilDate: customExpireDate / 1000, currency: selectedGift!.currency, amount: selectedGift!.amount, option: selectedGift!, }); } } else { openInvoice({ type: 'starsgiveaway', chatId: chatId!, additionalChannelIds: selectedChannelIds, isOnlyForNewSubscribers: selectedSubscriberOption === 'new', countries: selectedCountryIds, areWinnersVisible: shouldShowWinners, prizeDescription, untilDate: customExpireDate / 1000, currency: selectedStarOption!.currency, amount: selectedStarOption!.amount, stars: selectedStarOption!.stars, users: selectedRandomUserCount, }); } handleClose(); }); const confirmLaunchPrepaidGiveaway = useLastCallback(() => { if (isStarsPrepaidGiveaway) { launchPrepaidStarsGiveaway({ chatId: chatId!, giveawayId: dataStarsPrepaidGiveaway!.id, paymentPurpose: { additionalChannelIds: selectedChannelIds, countries: selectedCountryIds, prizeDescription, areWinnersVisible: shouldShowWinners, untilDate: customExpireDate / 1000, stars: dataStarsPrepaidGiveaway!.stars, currency: selectedStarsGift!.currency, amount: selectedStarsGift!.amount, users: dataStarsPrepaidGiveaway!.quantity, }, }); } else { launchPrepaidGiveaway({ chatId: chatId!, giveawayId: dataPrepaidGiveaway!.id, paymentPurpose: { additionalChannelIds: selectedChannelIds, countries: selectedCountryIds, prizeDescription, areWinnersVisible: shouldShowWinners, untilDate: customExpireDate / 1000, currency: selectedGift!.currency, amount: selectedGift!.amount, }, }); } closeConfirmModal(); handleClose(); }); const handleRandomUserCountChange = useLastCallback((newValue) => { setSelectedRandomUserCount(newValue); }); const handleWinnerCountChange = useLastCallback((newValue) => { setSelectedRandomUserCount(newValue); }); const handlePrizeDescriptionChange = useLastCallback((e: ChangeEvent) => { setPrizeDescription(e.target.value); }); const userNames = useMemo(() => { const usersById = getGlobal().users.byId; return selectedUserIds?.map((userId) => getUserFullName(usersById[userId])).join(', '); }, [selectedUserIds]); function handleScroll(e: React.UIEvent) { const { scrollTop } = e.currentTarget; setHeaderHidden(scrollTop <= 150); } const handleChangeSubscriberOption = useLastCallback((value) => { setSelectedSubscriberOption(value); }); const handleChangeTypeOption = useLastCallback((value: ApiGiveawayType) => { setGiveawayOption(value); setSelectedUserIds([]); setSelectedRandomUserCount(DEFAULT_BOOST_COUNT); }); const handleExpireDateChange = useLastCallback((date: Date) => { setCustomExpireDate(date.getTime()); closeCalendar(); }); const handleSetCountriesListChange = useLastCallback((value: string[]) => { setSelectedCountryIds(value); }); const handleSelectedUserIdsChange = useLastCallback((newSelectedIds: string[]) => { setSelectedUserIds(newSelectedIds); if (!newSelectedIds.length) { setGiveawayOption('premium_giveaway'); } }); const handleSelectedChannelIdsChange = useLastCallback((newSelectedIds: string[]) => { setSelectedChannelIds(newSelectedIds); }); const handleShouldShowWinnersChange = useLastCallback((e: ChangeEvent) => { setShouldShowWinners(e.target.checked); }); const handleShouldShowPrizesChange = useLastCallback((e: ChangeEvent) => { setShouldShowPrizes(e.target.checked); }); const onClickActionHandler = useLastCallback(() => { openCountryPickerModal(); }); const handleStarClick = useLastCallback((option) => { setSelectedStarOption(option); }); function renderTypeOptions() { return (
{TYPE_OPTIONS.map((option) => { return ( ); })}
); } function renderSubscribersOptions() { return (
); } function renderSubscriptionOptions() { return (
{filteredGifts?.map((gift) => ( ))}
); } function renderPremiumFeaturesLink() { const info = lang('GiftPremiumListFeaturesAndTerms'); const parts = info.match(/([^*]*)\*([^*]+)\*(.*)/); if (!parts || parts.length < 4) { return undefined; } return (

{parts[1]} {parts[2]} {parts[3]}

); } function deleteParticipantsHandler(id: string) { const filteredChannelIds = selectedChannelIds.filter((channelId) => channelId !== id); setSelectedChannelIds(filteredChannelIds); } function renderStarOptionList() { return ( ); } function renderGiveawayOptionList() { return ( <>

{lang('BoostingChannelsGroupsIncludedGiveaway')}

{selectedChannelIds?.map((channelId) => { return ( deleteParticipantsHandler(channelId)} rightElement={()} > ); })} {selectedChannelIds.length < MAX_ADDITIONAL_CHANNELS && ( {lang('BoostingAddChannelOrGroup')} )}

{lang('BoostingEligibleUsers')}

{renderSubscribersOptions()}
{renderText(lang(isChannel ? 'BoostGift.LimitSubscribersInfo' : 'lng_giveaway_users_about_group'))}

{lang('BoostingGiveawayAdditionalPrizes')}

{shouldShowPrizes && (

{selectedRandomUserCount}

)}
{shouldShowPrizes ? ( !isStarsGiveaway && !isStarsPrepaidGiveaway ? (
{prizeDescription?.length ? renderText(lang('BoostingGiveawayAdditionPrizeCountNameHint', dataPrepaidGiveaway ? [dataPrepaidGiveaway.quantity, prizeDescription, monthQuantity] : [selectedUserCount, prizeDescription, monthQuantity], undefined, selectedMonthOption), ['simple_markdown']) : renderText(lang('BoostingGiveawayAdditionPrizeCountHint', dataPrepaidGiveaway ? [dataPrepaidGiveaway.quantity, monthQuantity] : [selectedUserCount, monthQuantity], undefined, selectedMonthOption), ['simple_markdown'])}
) : undefined ) : (
{renderText(lang('BoostingGiveawayAdditionPrizeHint'))}
)}

{lang('BoostingGiveawayShowWinners')}

{renderText(lang('BoostingGiveawayShowWinnersHint'))}

{lang('BoostingDateWhenGiveawayEnds')}

); } return (

{renderText(lang('BoostingBoostsViaGifts'))}

{renderText(lang(isChannel ? 'BoostingGetMoreBoost' : 'BoostingGetMoreBoostsGroup'))}

{lang('BoostingBoostsViaGifts')}

{(dataPrepaidGiveaway || dataStarsPrepaidGiveaway) ? (
{dataStarsPrepaidGiveaway ? ( ) : ( )}

{dataStarsPrepaidGiveaway ? lang('Giveaway.Stars.Prepaid.Title', dataStarsPrepaidGiveaway?.stars) : lang('BoostingTelegramPremiumCountPlural', dataPrepaidGiveaway!.quantity)}

{dataStarsPrepaidGiveaway ? lang('Giveaway.Stars.Prepaid.Desc', dataStarsPrepaidGiveaway?.quantity) : lang('PrepaidGiveawayMonths', dataPrepaidGiveaway?.months)}

{dataStarsPrepaidGiveaway ? dataStarsPrepaidGiveaway?.boosts : dataPrepaidGiveaway!.quantity * (giveawayBoostPerPremiumLimit ?? GIVEAWAY_BOOST_PER_PREMIUM)}
) : (
{renderTypeOptions()}
)} {isPremiumGiveaway && !selectedUserIds?.length && ( <> {!dataPrepaidGiveaway && !dataStarsPrepaidGiveaway && ( <>

{lang('BoostingQuantityPrizes')}

{boostQuantity}
{renderText(lang('BoostingChooseHowMany'))}
)} {renderGiveawayOptionList()} )} {isStarsGiveaway && ( <> {!dataStarsPrepaidGiveaway && !dataPrepaidGiveaway && ( <>

{lang('BoostingStarsOptions')}

{boostStarsQuantity}
{renderStarOptionList()}
{renderText(lang('BoostGift.Stars.Info'))}

{lang('BoostingStarsQuantityPrizes')}

{renderText(lang('BoostingStarsQuantityPrizesInfo'))}
)} {renderGiveawayOptionList()} )} {!dataPrepaidGiveaway && !dataStarsPrepaidGiveaway && isPremiumGiveaway && ( <>

{lang('BoostingDurationOfPremium')}

{renderSubscriptionOptions()}
{renderPremiumFeaturesLink()}
)} {selectedGiveawayOption && (
)}
); }; export default memo(withGlobal((global): Complete => { const { giveawayModal, } = selectTabState(global); const chatId = giveawayModal?.chatId; const chat = chatId ? selectChat(global, chatId) : undefined; const isChannel = chat && isChatChannel(chat); return { chatId, gifts: giveawayModal?.gifts, selectedMemberList: giveawayModal?.selectedMemberIds, selectedChannelList: giveawayModal?.selectedChannelIds, giveawayBoostPerPremiumLimit: global.appConfig.giveawayBoostsPerPremium, isStarsGiftEnabled: global.appConfig.isStarsGiftEnabled, userSelectionLimit: global.appConfig.giveawayAddPeersMax, countrySelectionLimit: global.appConfig.giveawayCountriesMax, countryList: global.countryList.general, prepaidGiveaway: giveawayModal?.prepaidGiveaway, isChannel, starsGiftOptions: giveawayModal?.starOptions, }; })(GiveawayModal));