import type { FC } from '../../../../lib/teact/teact'; import React, { memo, useMemo } from '../../../../lib/teact/teact'; import { getActions, withGlobal } from '../../../../global'; import type { ApiPeer, ApiStarsTransactionPeer, ApiSticker, ApiUser, } from '../../../../api/types'; import type { TabState } from '../../../../global/types'; import { MediaViewerOrigin } from '../../../../types'; import { getMessageLink, getUserFullName } from '../../../../global/helpers'; import { buildStarsTransactionCustomPeer, formatStarsTransactionAmount } from '../../../../global/helpers/payments'; import { selectCanPlayAnimatedEmojis, selectGiftStickerForStars, selectPeer, selectUser, } from '../../../../global/selectors'; import buildClassName from '../../../../util/buildClassName'; import { copyTextToClipboard } from '../../../../util/clipboard'; import { formatDateTimeToString } from '../../../../util/dates/dateFormat'; import renderText from '../../../common/helpers/renderText'; import useLang from '../../../../hooks/useLang'; import useLastCallback from '../../../../hooks/useLastCallback'; import useOldLang from '../../../../hooks/useOldLang'; import usePrevious from '../../../../hooks/usePrevious'; import AnimatedIconFromSticker from '../../../common/AnimatedIconFromSticker'; import Avatar from '../../../common/Avatar'; import Icon from '../../../common/icons/Icon'; import StarIcon from '../../../common/icons/StarIcon'; import SafeLink from '../../../common/SafeLink'; import TableInfoModal, { type TableData } from '../../common/TableInfoModal'; import PaidMediaThumb from './PaidMediaThumb'; import styles from './StarsTransactionModal.module.scss'; import StarsBackground from '../../../../assets/stars-bg.png'; export type OwnProps = { modal: TabState['starsTransactionModal']; }; type StateProps = { peer?: ApiPeer; user?: ApiUser; canPlayAnimatedEmojis?: boolean; starGiftSticker?: ApiSticker; }; const StarsTransactionModal: FC = ({ modal, peer, user, canPlayAnimatedEmojis, starGiftSticker, }) => { const { showNotification, openMediaViewer, closeStarsTransactionModal } = getActions(); const oldLang = useOldLang(); const lang = useLang(); const { transaction } = modal || {}; const handleOpenMedia = useLastCallback(() => { const media = transaction?.extendedMedia; if (!media) return; openMediaViewer({ origin: MediaViewerOrigin.StarsTransaction, standaloneMedia: media.flatMap((item) => Object.values(item)), }); }); const giftEntryAboutText = useMemo(() => { const subtitleText = oldLang('lng_credits_box_history_entry_gift_in_about'); const subtitleTextParts = subtitleText.split('{link}'); return ( <> {subtitleTextParts[0]} {renderText(oldLang('GiftStarsSubtitleLinkName'), ['simple_markdown'])} {subtitleTextParts[1]} ); }, [oldLang]); const giftOutAboutText = useMemo(() => { return lang( 'CreditsBoxHistoryEntryGiftOutAbout', { user: {user ? getUserFullName(user) : ''}, link: ( {renderText(oldLang('GiftStarsSubtitleLinkName'), ['simple_markdown'])} ), }, { withNodes: true, }, ); }, [lang, user, oldLang]); const starModalData = useMemo(() => { if (!transaction) { return undefined; } const { isGift, isPrizeStars, photo } = transaction; const customPeer = (transaction.peer && transaction.peer.type !== 'peer' && buildStarsTransactionCustomPeer(transaction.peer)) || undefined; const peerId = transaction.peer?.type === 'peer' ? transaction.peer.id : undefined; const toName = transaction.peer && oldLang(getStarsPeerTitleKey(transaction.peer)); const title = (() => { if (transaction.extendedMedia) return oldLang('StarMediaPurchase'); if (transaction.subscriptionPeriod) return oldLang('StarSubscriptionPurchase'); if (transaction.isReaction) return oldLang('StarsReactionsSent'); if (customPeer) return customPeer.title || oldLang(customPeer.titleKey!); return transaction.title; })(); const messageLink = peer && transaction.messageId ? getMessageLink(peer, undefined, transaction.messageId) : undefined; const media = transaction.extendedMedia; const mediaAmount = media?.length || 0; const areAllPhotos = media?.every((m) => !m.video); const areAllVideos = media?.every((m) => !m.photo); const mediaText = areAllPhotos ? oldLang('Stars.Transfer.Photos', mediaAmount) : areAllVideos ? oldLang('Stars.Transfer.Videos', mediaAmount) : oldLang('Media', mediaAmount); const description = transaction.description || (media ? mediaText : undefined); const shouldDisplayAvatar = !media && !isGift && !isPrizeStars; const avatarPeer = !photo ? (peer || customPeer) : undefined; const header = (
{media && ( )} {(isGift || isPrizeStars) && starGiftSticker && ( )} {shouldDisplayAvatar && ( )} {title &&

{title}

} {(isGift || isPrizeStars) && (

{isPrizeStars ? oldLang('StarsGiveawayPrizeReceived') : transaction?.isMyGift ? oldLang('StarsGiftSent') : oldLang('StarsGiftReceived')}

)}

{description}

{formatStarsTransactionAmount(transaction.stars)}

{isGift && ( {transaction?.isMyGift ? giftOutAboutText : giftEntryAboutText} )}
); const tableData: TableData = []; tableData.push([ oldLang(transaction.stars < 0 || transaction.isMyGift ? 'Stars.Transaction.To' : peerId ? 'Star.Transaction.From' : 'Stars.Transaction.Via'), peerId ? { chatId: peerId } : toName || '', ]); if (messageLink) { tableData.push([oldLang('Stars.Transaction.Reaction.Post'), ]); } if (isPrizeStars) { tableData.push( [oldLang('BoostReason'), oldLang('Giveaway')], [oldLang('Gift'), oldLang('Stars', transaction.stars, 'i')], ); } if (transaction.id && !isPrizeStars) { tableData.push([ oldLang('Stars.Transaction.Id'), ( <>
{ copyTextToClipboard(transaction.id!); showNotification({ message: oldLang('StarsTransactionIDCopied'), }); }} > {transaction.id}
), ]); } tableData.push([ oldLang('Stars.Transaction.Date'), formatDateTimeToString(transaction.date * 1000, oldLang.code, true), ]); const footerText = oldLang('lng_credits_box_out_about'); const footerTextParts = footerText.split('{link}'); const footer = ( {footerTextParts[0]} {footerTextParts[1]} ); return { header, tableData, footer, }; }, [ transaction, oldLang, peer, giftOutAboutText, giftEntryAboutText, canPlayAnimatedEmojis, starGiftSticker, ]); const prevModalData = usePrevious(starModalData); const renderingModalData = prevModalData || starModalData; return ( ); }; export default memo(withGlobal( (global, { modal }): StateProps => { const peerId = modal?.transaction?.peer?.type === 'peer' && modal.transaction.peer.id; const peer = peerId ? selectPeer(global, peerId) : undefined; const user = peerId ? selectUser(global, peerId) : undefined; const starCount = modal?.transaction.stars; const starGiftSticker = selectGiftStickerForStars(global, starCount); return { peer, user, canPlayAnimatedEmojis: selectCanPlayAnimatedEmojis(global), starGiftSticker, }; }, )(StarsTransactionModal)); function getStarsPeerTitleKey(peer: ApiStarsTransactionPeer) { switch (peer.type) { case 'appStore': return 'AppStore'; case 'playMarket': return 'PlayMarket'; case 'fragment': return 'Fragment'; case 'premiumBot': return 'StarsTransactionBot'; case 'ads': return 'StarsTransactionAds'; default: return 'Stars.Transaction.Unsupported.Title'; } }