Gift Modal: Support My gifts category (#6316)
This commit is contained in:
parent
104fbb1d54
commit
aacd4a8429
@ -1452,6 +1452,7 @@
|
||||
"StarsGiftHeader" = "Send a Gift";
|
||||
"StarsGiftHeaderSelf" = "Buy a Gift";
|
||||
"StarGiftDescription" = "Give {user} gifts that can be kept on the profile or converted to Stars.";
|
||||
"StarGiftDescriptionCollectibles" = "Collectible gifts are unique digital items you exchange or sell.";
|
||||
"StarGiftDescriptionSelf" = "Buy yourself a gift to add to your profile or reserve for later.\n\nLimited-edition gifts upgraded to collectibles can be gifted to others.";
|
||||
"StarGiftDescriptionChannel" = "Select gift to show appreciation to **{peer}**.";
|
||||
"GiftLimited" = "limited";
|
||||
@ -1583,8 +1584,6 @@
|
||||
"StarsAmountText_one" = "{amount} Star";
|
||||
"StarsAmountText_other" = "{amount} Stars";
|
||||
"AllGiftsCategory" = "All gifts";
|
||||
"LimitedGiftsCategory" = "Limited";
|
||||
"StockGiftsCategory" = "In Stock";
|
||||
"PremiumGiftDescription" = "Premium";
|
||||
"SendPaidReaction" = "Send ⭐️{amount}";
|
||||
"StarsPay" = "Confirm and Pay {amount}";
|
||||
@ -2070,7 +2069,8 @@
|
||||
"ComposerTitleForwardFrom" = "From: **{users}**";
|
||||
"ContextMenuItemMention" = "Mention";
|
||||
"GiftRibbonResale" = "resale";
|
||||
"GiftCategoryResale" = "Resale";
|
||||
"GiftCategoryCollectibles" = "Collectibles";
|
||||
"GiftCategoryMyGifts" = "My Gifts";
|
||||
"HeaderDescriptionResaleGifts_one" = "{count} for resale";
|
||||
"HeaderDescriptionResaleGifts_other" = "{count} for resale";
|
||||
"GiftSortByPrice" = "Sort by Price";
|
||||
@ -2285,6 +2285,7 @@
|
||||
"GiftValueForSaleOnFragment" = "for sale on Fragment";
|
||||
"GiftValueForSaleOnTelegram" = "for sale on Telegram";
|
||||
"EmbeddedMessageNoCaption" = "Caption removed";
|
||||
"ConfirmBuyGiftForTonDescription" = "The seller only accepts TON as payment.";
|
||||
"TitleGiftLocked" = "Gift Locked";
|
||||
"GiftLockedMessage" = "This gift is currently only available to earlier Telegram users. It will unlock for your account in about **{relativeDate}**.";
|
||||
"QuickPreview" = "Quick Preview";
|
||||
|
||||
@ -15,5 +15,6 @@ export { default as GiftUpgradeModal } from '../components/modals/gift/upgrade/G
|
||||
export { default as GiftStatusInfoModal } from '../components/modals/gift/status/GiftStatusInfoModal';
|
||||
export { default as GiftWithdrawModal } from '../components/modals/gift/withdraw/GiftWithdrawModal';
|
||||
export { default as GiftTransferModal } from '../components/modals/gift/transfer/GiftTransferModal';
|
||||
export { default as GiftTransferConfirmModal } from '../components/modals/gift/transfer/GiftTransferConfirmModal';
|
||||
export { default as ChatRefundModal } from '../components/modals/stars/chatRefund/ChatRefundModal';
|
||||
export { default as PriceConfirmModal } from '../components/modals/priceConfirm/PriceConfirmModal';
|
||||
|
||||
@ -217,6 +217,7 @@ const Main = ({
|
||||
loadPremiumGifts,
|
||||
loadTonGifts,
|
||||
loadStarGifts,
|
||||
loadMyCollectibleGifts,
|
||||
loadDefaultTopicIcons,
|
||||
loadAddedStickers,
|
||||
loadFavoriteStickers,
|
||||
@ -332,6 +333,7 @@ const Main = ({
|
||||
loadPremiumGifts();
|
||||
loadTonGifts();
|
||||
loadStarGifts();
|
||||
loadMyCollectibleGifts();
|
||||
loadAvailableEffects();
|
||||
loadBirthdayNumbersStickers();
|
||||
loadRestrictedEmojiStickers();
|
||||
|
||||
@ -25,6 +25,7 @@ import GiftLockedModal from './gift/locked/GiftLockedModal.async';
|
||||
import GiftRecipientPicker from './gift/recipient/GiftRecipientPicker.async';
|
||||
import GiftResalePriceComposerModal from './gift/resale/GiftResalePriceComposerModal.async';
|
||||
import GiftStatusInfoModal from './gift/status/GiftStatusInfoModal.async';
|
||||
import GiftTransferConfirmModal from './gift/transfer/GiftTransferConfirmModal.async';
|
||||
import GiftTransferModal from './gift/transfer/GiftTransferModal.async';
|
||||
import GiftUpgradeModal from './gift/upgrade/GiftUpgradeModal.async';
|
||||
import GiftInfoValueModal from './gift/value/GiftInfoValueModal.async';
|
||||
@ -95,6 +96,7 @@ type ModalKey = keyof Pick<TabState,
|
||||
'sharePreparedMessageModal' |
|
||||
'giftStatusInfoModal' |
|
||||
'giftTransferModal' |
|
||||
'giftTransferConfirmModal' |
|
||||
'chatRefundModal' |
|
||||
'priceConfirmModal' |
|
||||
'isFrozenAccountModalOpen' |
|
||||
@ -156,6 +158,7 @@ const MODALS: ModalRegistry = {
|
||||
preparedMessageModal: PreparedMessageModal,
|
||||
sharePreparedMessageModal: SharePreparedMessageModal,
|
||||
giftTransferModal: GiftTransferModal,
|
||||
giftTransferConfirmModal: GiftTransferConfirmModal,
|
||||
chatRefundModal: ChatRefundModal,
|
||||
priceConfirmModal: PriceConfirmModal,
|
||||
isFrozenAccountModalOpen: FrozenAccountModal,
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
justify-content: center;
|
||||
|
||||
min-width: 0;
|
||||
margin-inline: 0.125rem;
|
||||
padding: 0.625rem;
|
||||
padding-top: 0;
|
||||
border-radius: 0.625rem;
|
||||
@ -69,6 +70,10 @@
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
.transferBadge {
|
||||
font-size: 0.8125rem !important;
|
||||
}
|
||||
|
||||
.star {
|
||||
margin-inline-start: 0 !important;
|
||||
margin-inline-end: 0.125rem;
|
||||
|
||||
@ -29,6 +29,7 @@ export type OwnProps = {
|
||||
observeIntersection?: ObserveFn;
|
||||
onClick: (gift: ApiStarGift, target: 'original' | 'resell') => void;
|
||||
isResale?: boolean;
|
||||
withTransferBadge?: boolean;
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
@ -38,7 +39,7 @@ type StateProps = {
|
||||
const GIFT_STICKER_SIZE = 90;
|
||||
|
||||
function GiftItemStar({
|
||||
gift, observeIntersection, onClick, isResale, isCurrentUserPremium,
|
||||
gift, observeIntersection, onClick, isResale, isCurrentUserPremium, withTransferBadge,
|
||||
}: OwnProps & StateProps) {
|
||||
const { openGiftInfoModal, openPremiumModal, showNotification, checkCanSendGift } = getActions();
|
||||
|
||||
@ -72,7 +73,7 @@ function GiftItemStar({
|
||||
: getPriceAmount(uniqueGift?.resellPrice);
|
||||
const priceCurrency = priceInfo?.currency || STARS_CURRENCY_CODE;
|
||||
const resellMinStars = regularGift?.resellMinStars;
|
||||
const priceInStarsAsString = !isGiftUnique && isResale && resellMinStars
|
||||
const formattedPrice = !isGiftUnique && isResale && resellMinStars
|
||||
? lang.number(resellMinStars) + '+' : priceInfo?.amount || 0;
|
||||
const isLimited = !isGiftUnique && Boolean(regularGift?.isLimited);
|
||||
const isSoldOut = !isGiftUnique && Boolean(regularGift?.isSoldOut);
|
||||
@ -175,6 +176,24 @@ function GiftItemStar({
|
||||
setIsVisible(visible);
|
||||
});
|
||||
|
||||
const badgeContent = useMemo(() => {
|
||||
if (withTransferBadge) {
|
||||
return lang('GiftTransferTitle');
|
||||
}
|
||||
|
||||
if (priceCurrency === TON_CURRENCY_CODE) {
|
||||
return formatTonAsIcon(lang, formattedPrice || 0, {
|
||||
shouldConvertFromNanos: true,
|
||||
className: styles.star,
|
||||
});
|
||||
}
|
||||
|
||||
return formatStarsAsIcon(lang, formattedPrice || 0, {
|
||||
asFont: true,
|
||||
className: styles.star,
|
||||
});
|
||||
}, [withTransferBadge, priceCurrency, formattedPrice, lang]);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
@ -212,17 +231,18 @@ function GiftItemStar({
|
||||
|
||||
</div>
|
||||
<Button
|
||||
className={styles.buy}
|
||||
className={buildClassName(
|
||||
styles.buy,
|
||||
withTransferBadge && styles.transferBadge,
|
||||
)}
|
||||
nonInteractive
|
||||
size="tiny"
|
||||
color={isGiftUnique ? 'bluredStarsBadge' : 'stars'}
|
||||
withSparkleEffect={isVisible}
|
||||
withSparkleEffect={isVisible && !withTransferBadge}
|
||||
pill
|
||||
fluid
|
||||
>
|
||||
{priceCurrency === TON_CURRENCY_CODE
|
||||
? formatTonAsIcon(lang, priceInStarsAsString || 0, { shouldConvertFromNanos: true, className: styles.star })
|
||||
: formatStarsAsIcon(lang, priceInStarsAsString || 0, { asFont: true, className: styles.star })}
|
||||
{badgeContent}
|
||||
</Button>
|
||||
{giftRibbon}
|
||||
{isLocked && <Icon name="lock-badge" className={styles.lockIcon} />}
|
||||
|
||||
@ -81,7 +81,7 @@
|
||||
.starGiftsContainer,
|
||||
.premiumGiftsGallery {
|
||||
display: flex;
|
||||
gap: 0.625rem;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
|
||||
@ -9,6 +9,7 @@ import type {
|
||||
ApiDisallowedGifts,
|
||||
ApiPeer,
|
||||
ApiPremiumGiftCodeOption,
|
||||
ApiSavedStarGift,
|
||||
ApiStarGift,
|
||||
ApiStarGiftRegular,
|
||||
ApiStarsAmount,
|
||||
@ -34,6 +35,7 @@ import Avatar from '../../common/Avatar';
|
||||
import InteractiveSparkles from '../../common/InteractiveSparkles';
|
||||
import SafeLink from '../../common/SafeLink';
|
||||
import Button from '../../ui/Button';
|
||||
import InfiniteScroll from '../../ui/InfiniteScroll';
|
||||
import Modal from '../../ui/Modal';
|
||||
import Transition from '../../ui/Transition';
|
||||
import BalanceBlock from '../stars/BalanceBlock';
|
||||
@ -56,6 +58,8 @@ type StateProps = {
|
||||
boostPerSentGift?: number;
|
||||
starGiftsById?: Record<string, ApiStarGiftRegular>;
|
||||
starGiftIdsByCategory?: Record<StarGiftCategory, string[]>;
|
||||
myCollectibleGiftsById?: Record<string, ApiSavedStarGift>;
|
||||
myCollectibleGiftIds?: string[];
|
||||
starBalance?: ApiStarsAmount;
|
||||
peer?: ApiPeer;
|
||||
isSelf?: boolean;
|
||||
@ -77,6 +81,8 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
modal,
|
||||
starGiftsById,
|
||||
starGiftIdsByCategory,
|
||||
myCollectibleGiftsById,
|
||||
myCollectibleGiftIds,
|
||||
starBalance,
|
||||
peer,
|
||||
isSelf,
|
||||
@ -87,7 +93,14 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
tabId,
|
||||
}) => {
|
||||
const {
|
||||
closeGiftModal, openGiftInfoModal, resetResaleGifts, loadResaleGifts, openGiftInMarket, closeResaleGiftsMarket,
|
||||
closeGiftModal,
|
||||
openGiftInfoModal,
|
||||
resetResaleGifts,
|
||||
loadResaleGifts,
|
||||
openGiftInMarket,
|
||||
closeResaleGiftsMarket,
|
||||
loadMyCollectibleGifts,
|
||||
openGiftTransferConfirmModal,
|
||||
} = getActions();
|
||||
const dialogRef = useRef<HTMLDivElement>();
|
||||
const transitionRef = useRef<HTMLDivElement>();
|
||||
@ -122,6 +135,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const areUnlimitedStarGiftsDisallowed = !isSelf && disallowedGifts?.shouldDisallowUnlimitedStarGifts;
|
||||
const areLimitedStarGiftsDisallowed = !isSelf && disallowedGifts?.shouldDisallowLimitedStarGifts;
|
||||
const areUniqueStarGiftsDisallowed = !isSelf && disallowedGifts?.shouldDisallowUniqueStarGifts;
|
||||
|
||||
const oldLang = useOldLang();
|
||||
const lang = useLang();
|
||||
@ -206,19 +220,29 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
),
|
||||
}, { withNodes: true });
|
||||
|
||||
const starGiftDescription = chat
|
||||
? lang('StarGiftDescriptionChannel', { peer: getPeerTitle(lang, chat) }, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
})
|
||||
: isSelf
|
||||
? lang('StarGiftDescriptionSelf', undefined, {
|
||||
const starGiftDescription = useMemo(() => {
|
||||
if (chat) {
|
||||
return lang('StarGiftDescriptionChannel', { peer: getPeerTitle(lang, chat) }, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
});
|
||||
}
|
||||
|
||||
if (isSelf) {
|
||||
return lang('StarGiftDescriptionSelf', undefined, {
|
||||
withNodes: true,
|
||||
renderTextFilters: ['br'],
|
||||
})
|
||||
: lang('StarGiftDescription', {
|
||||
user: getUserFullName(user)!,
|
||||
}, { withNodes: true, withMarkdown: true });
|
||||
});
|
||||
}
|
||||
|
||||
if (selectedCategory === 'resale') {
|
||||
return lang('StarGiftDescriptionCollectibles');
|
||||
}
|
||||
|
||||
return lang('StarGiftDescription', {
|
||||
user: getUserFullName(user)!,
|
||||
}, { withNodes: true, withMarkdown: true });
|
||||
}, [chat, isSelf, selectedCategory, user, lang]);
|
||||
|
||||
function renderGiftPremiumHeader() {
|
||||
return (
|
||||
@ -268,22 +292,62 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
setIsGiftScreenHeaderForStarGifts('id' in gift);
|
||||
});
|
||||
|
||||
const handleMyGiftClick = useLastCallback((gift: ApiStarGift) => {
|
||||
if (gift.type === 'starGift' || !myCollectibleGiftsById || !peer?.id) return;
|
||||
const savedGift = myCollectibleGiftsById[gift.id];
|
||||
|
||||
openGiftTransferConfirmModal({
|
||||
gift: savedGift,
|
||||
recipientId: peer.id,
|
||||
});
|
||||
});
|
||||
|
||||
const handleLoadMore = useLastCallback(() => {
|
||||
if (selectedCategory === 'myCollectibles') {
|
||||
loadMyCollectibleGifts();
|
||||
}
|
||||
});
|
||||
|
||||
function renderStarGifts() {
|
||||
if (selectedCategory === 'myCollectibles') {
|
||||
return (
|
||||
<InfiniteScroll
|
||||
className={styles.starGiftsContainer}
|
||||
items={myCollectibleGiftIds}
|
||||
onLoadMore={handleLoadMore}
|
||||
scrollContainerClosest={`.${styles.main}`}
|
||||
itemSelector=".starGiftItem"
|
||||
>
|
||||
{myCollectibleGiftsById && myCollectibleGiftIds?.map((giftId) => {
|
||||
const savedGift = myCollectibleGiftsById[giftId];
|
||||
if (!savedGift) return undefined;
|
||||
|
||||
return (
|
||||
<GiftItemStar
|
||||
key={giftId}
|
||||
gift={savedGift.gift}
|
||||
observeIntersection={observeIntersection}
|
||||
onClick={handleMyGiftClick}
|
||||
withTransferBadge
|
||||
/>
|
||||
);
|
||||
})}
|
||||
</InfiniteScroll>
|
||||
);
|
||||
}
|
||||
|
||||
const filteredGiftIds = starGiftIdsByCategory?.[selectedCategory]?.filter((giftId) => {
|
||||
const gift = starGiftsById?.[giftId];
|
||||
if (!gift) return false;
|
||||
|
||||
const { isLimited, isSoldOut, upgradeStars } = gift;
|
||||
if (areUnlimitedStarGiftsDisallowed && !areLimitedStarGiftsDisallowed) {
|
||||
return isLimited;
|
||||
}
|
||||
if (areLimitedStarGiftsDisallowed && !areUnlimitedStarGiftsDisallowed) {
|
||||
return !isLimited && !isSoldOut;
|
||||
}
|
||||
if (areUnlimitedStarGiftsDisallowed && areLimitedStarGiftsDisallowed) {
|
||||
return Boolean(isLimited && Boolean(upgradeStars));
|
||||
const { isLimited, availabilityResale } = gift;
|
||||
|
||||
if (areLimitedStarGiftsDisallowed && isLimited) {
|
||||
return !areUniqueStarGiftsDisallowed ? availabilityResale : false;
|
||||
}
|
||||
|
||||
if (areUnlimitedStarGiftsDisallowed && !isLimited) return false;
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
@ -291,8 +355,9 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
<div className={styles.starGiftsContainer}>
|
||||
{starGiftsById && filteredGiftIds?.flatMap((giftId) => {
|
||||
const gift = starGiftsById[giftId];
|
||||
const shouldShowResale = selectedCategory !== 'stock' && Boolean(gift.availabilityResale);
|
||||
const shouldDuplicateAsResale = selectedCategory !== 'resale' && shouldShowResale && !gift.isSoldOut;
|
||||
const shouldShowResale = Boolean(gift.availabilityResale) && !areUniqueStarGiftsDisallowed;
|
||||
const shouldDuplicateAsResale = selectedCategory !== 'resale'
|
||||
&& shouldShowResale && !gift.isSoldOut && !areLimitedStarGiftsDisallowed;
|
||||
|
||||
const elements = [
|
||||
<GiftItemStar
|
||||
@ -399,7 +464,9 @@ const GiftModal: FC<OwnProps & StateProps> = ({
|
||||
{renderStarGiftsHeader()}
|
||||
{renderStarGiftsDescription()}
|
||||
<StarGiftCategoryList
|
||||
areLimitedStarGiftsDisallowed={areLimitedStarGiftsDisallowed}
|
||||
areCollectibleStarGiftsDisallowed={areUniqueStarGiftsDisallowed}
|
||||
isSelf={isSelf}
|
||||
hasCollectible={Boolean(myCollectibleGiftIds?.length)}
|
||||
onCategoryChanged={onCategoryChanged}
|
||||
/>
|
||||
<Transition
|
||||
@ -535,6 +602,8 @@ export default memo(withGlobal<OwnProps>((global, { modal }): Complete<StateProp
|
||||
boostPerSentGift: global.appConfig.boostsPerSentGift,
|
||||
starGiftsById: starGifts?.byId,
|
||||
starGiftIdsByCategory: starGifts?.idsByCategory,
|
||||
myCollectibleGiftsById: global.myCollectibleGifts?.byId,
|
||||
myCollectibleGiftIds: global.myCollectibleGifts?.ids,
|
||||
starBalance: stars?.balance,
|
||||
peer,
|
||||
isSelf,
|
||||
@ -548,8 +617,6 @@ export default memo(withGlobal<OwnProps>((global, { modal }): Complete<StateProp
|
||||
|
||||
function getCategoryKey(category: StarGiftCategory) {
|
||||
if (category === 'all') return 0;
|
||||
if (category === 'limited') return 1;
|
||||
if (category === 'resale') return 2;
|
||||
if (category === 'stock') return 3;
|
||||
return category + 3;
|
||||
if (category === 'myCollectibles') return 1;
|
||||
return 2;
|
||||
}
|
||||
|
||||
@ -10,7 +10,7 @@
|
||||
flex-wrap: nowrap;
|
||||
gap: 0.0625rem;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
justify-content: center;
|
||||
|
||||
// Prevent first item from being always partially obscured
|
||||
margin-left: -0.5rem;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import {
|
||||
memo, useMemo, useRef, useState,
|
||||
memo, useRef, useState,
|
||||
} from '../../../lib/teact/teact';
|
||||
import { withGlobal } from '../../../global';
|
||||
|
||||
@ -10,12 +10,12 @@ import buildClassName from '../../../util/buildClassName';
|
||||
import useHorizontalScroll from '../../../hooks/useHorizontalScroll';
|
||||
import useLang from '../../../hooks/useLang';
|
||||
|
||||
import StarIcon from '../../common/icons/StarIcon';
|
||||
|
||||
import styles from './StarGiftCategoryList.module.scss';
|
||||
|
||||
type OwnProps = {
|
||||
areLimitedStarGiftsDisallowed?: boolean;
|
||||
areCollectibleStarGiftsDisallowed?: boolean;
|
||||
isSelf?: boolean;
|
||||
hasCollectible?: boolean;
|
||||
onCategoryChanged: (category: StarGiftCategory) => void;
|
||||
};
|
||||
|
||||
@ -26,16 +26,13 @@ type StateProps = {
|
||||
const StarGiftCategoryList = ({
|
||||
idsByCategory,
|
||||
onCategoryChanged,
|
||||
areLimitedStarGiftsDisallowed,
|
||||
areCollectibleStarGiftsDisallowed,
|
||||
isSelf,
|
||||
hasCollectible,
|
||||
}: StateProps & OwnProps) => {
|
||||
const ref = useRef<HTMLDivElement>();
|
||||
|
||||
const lang = useLang();
|
||||
const starCategories: number[] | undefined = useMemo(() => idsByCategory && Object.keys(idsByCategory)
|
||||
.filter((category) => category !== 'all' && category !== 'limited')
|
||||
.map(Number)
|
||||
.sort((a, b) => a - b),
|
||||
[idsByCategory]);
|
||||
|
||||
const hasResale = idsByCategory && idsByCategory['resale'].length > 0;
|
||||
|
||||
@ -50,9 +47,8 @@ const StarGiftCategoryList = ({
|
||||
|
||||
function renderCategoryName(category: StarGiftCategory) {
|
||||
if (category === 'all') return lang('AllGiftsCategory');
|
||||
if (category === 'stock') return lang('StockGiftsCategory');
|
||||
if (category === 'limited') return lang('LimitedGiftsCategory');
|
||||
if (category === 'resale') return lang('GiftCategoryResale');
|
||||
if (category === 'myCollectibles') return lang('GiftCategoryMyGifts');
|
||||
if (category === 'resale') return lang('GiftCategoryCollectibles');
|
||||
return category;
|
||||
}
|
||||
|
||||
@ -65,13 +61,6 @@ const StarGiftCategoryList = ({
|
||||
)}
|
||||
onClick={() => handleItemClick(category)}
|
||||
>
|
||||
{Number.isInteger(category) && (
|
||||
<StarIcon
|
||||
className={styles.star}
|
||||
type="gold"
|
||||
size="middle"
|
||||
/>
|
||||
)}
|
||||
{renderCategoryName(category)}
|
||||
</div>
|
||||
);
|
||||
@ -82,10 +71,8 @@ const StarGiftCategoryList = ({
|
||||
return (
|
||||
<div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}>
|
||||
{renderCategoryItem('all')}
|
||||
{!areLimitedStarGiftsDisallowed && renderCategoryItem('limited')}
|
||||
{!areLimitedStarGiftsDisallowed && hasResale && renderCategoryItem('resale')}
|
||||
{renderCategoryItem('stock')}
|
||||
{starCategories?.map(renderCategoryItem)}
|
||||
{!areCollectibleStarGiftsDisallowed && !isSelf && hasCollectible && renderCategoryItem('myCollectibles')}
|
||||
{!areCollectibleStarGiftsDisallowed && hasResale && renderCategoryItem('resale')}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -19,6 +19,17 @@
|
||||
font-size: 1.25rem;
|
||||
}
|
||||
|
||||
.descriptionConfirm {
|
||||
padding-bottom: 0.75rem;
|
||||
color: var(--color-text-secondary);
|
||||
}
|
||||
|
||||
.titleConfirm {
|
||||
margin-bottom: 0.75rem;
|
||||
font-size: 1.25rem;
|
||||
font-weight: var(--font-weight-medium);
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@ -938,10 +938,19 @@ const GiftInfoModal = ({
|
||||
confirmHandler={handleConfirmBuyGift}
|
||||
>
|
||||
|
||||
{uniqueGift.resaleTonOnly
|
||||
&& (
|
||||
<div className={styles.descriptionConfirm}>
|
||||
{lang('ConfirmBuyGiftForTonDescription')}
|
||||
</div>
|
||||
)}
|
||||
<GiftTransferPreview
|
||||
peer={recipientPeer || currentUser}
|
||||
gift={uniqueGift}
|
||||
/>
|
||||
<div className={styles.titleConfirm}>
|
||||
{lang('TitleConfirmPayment')}
|
||||
</div>
|
||||
{!recipientPeer
|
||||
&& (
|
||||
<p>
|
||||
|
||||
@ -0,0 +1,20 @@
|
||||
import type { FC } from '../../../../lib/teact/teact';
|
||||
|
||||
import type { OwnProps } from './GiftTransferConfirmModal';
|
||||
|
||||
import { Bundles } from '../../../../util/moduleLoader';
|
||||
|
||||
import useModuleLoader from '../../../../hooks/useModuleLoader';
|
||||
|
||||
const GiftTransferConfirmModalAsync: FC<OwnProps> = (props) => {
|
||||
const { modal } = props;
|
||||
const GiftTransferConfirmModal = useModuleLoader(
|
||||
Bundles.Stars,
|
||||
'GiftTransferConfirmModal',
|
||||
!modal,
|
||||
);
|
||||
|
||||
return GiftTransferConfirmModal ? <GiftTransferConfirmModal {...props} /> : undefined;
|
||||
};
|
||||
|
||||
export default GiftTransferConfirmModalAsync;
|
||||
108
src/components/modals/gift/transfer/GiftTransferConfirmModal.tsx
Normal file
108
src/components/modals/gift/transfer/GiftTransferConfirmModal.tsx
Normal file
@ -0,0 +1,108 @@
|
||||
import { memo } from '../../../../lib/teact/teact';
|
||||
import { getActions, withGlobal } from '../../../../global';
|
||||
|
||||
import type { ApiPeer } from '../../../../api/types';
|
||||
import type { TabState } from '../../../../global/types';
|
||||
|
||||
import { getPeerTitle } from '../../../../global/helpers/peers';
|
||||
import { selectPeer } from '../../../../global/selectors';
|
||||
import { formatStarsAsIcon, formatStarsAsText } from '../../../../util/localization/format';
|
||||
|
||||
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
|
||||
import useLang from '../../../../hooks/useLang';
|
||||
import useLastCallback from '../../../../hooks/useLastCallback';
|
||||
|
||||
import GiftTransferPreview from '../../../common/gift/GiftTransferPreview';
|
||||
import ConfirmDialog from '../../../ui/ConfirmDialog';
|
||||
|
||||
export type OwnProps = {
|
||||
modal: TabState['giftTransferConfirmModal'];
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
selectedPeer?: ApiPeer;
|
||||
};
|
||||
|
||||
const GiftTransferConfirmModal = ({ modal, selectedPeer }: OwnProps & StateProps) => {
|
||||
const {
|
||||
closeGiftTransferConfirmModal, transferGift, openChat, closeGiftModal, closeGiftTransferModal,
|
||||
} = getActions();
|
||||
const lang = useLang();
|
||||
|
||||
const isOpen = Boolean(modal);
|
||||
const renderingModal = useCurrentOrPrev(modal);
|
||||
const renderingSelectedPeer = useCurrentOrPrev(selectedPeer);
|
||||
|
||||
const handleConfirm = useLastCallback(() => {
|
||||
if (!renderingModal?.gift.inputGift || !renderingModal.recipientId) return;
|
||||
|
||||
transferGift({
|
||||
gift: renderingModal.gift.inputGift,
|
||||
recipientId: renderingModal.recipientId,
|
||||
transferStars: renderingModal.gift.transferStars,
|
||||
});
|
||||
|
||||
closeGiftTransferConfirmModal();
|
||||
openChat({ id: renderingModal.recipientId });
|
||||
|
||||
closeGiftModal();
|
||||
closeGiftTransferModal();
|
||||
});
|
||||
|
||||
if (!renderingModal) return undefined;
|
||||
|
||||
const { gift } = renderingModal;
|
||||
const uniqueGift = gift.gift.type === 'starGiftUnique' ? gift.gift : undefined;
|
||||
|
||||
if (!uniqueGift) return undefined;
|
||||
|
||||
return (
|
||||
<ConfirmDialog
|
||||
isOpen={isOpen}
|
||||
noDefaultTitle
|
||||
onClose={closeGiftTransferConfirmModal}
|
||||
confirmLabel={gift.transferStars
|
||||
? lang(
|
||||
'GiftTransferConfirmButton',
|
||||
{ amount: formatStarsAsIcon(lang, gift.transferStars, { asFont: true }) },
|
||||
{ withNodes: true },
|
||||
) : lang('GiftTransferConfirmButtonFree')}
|
||||
confirmHandler={handleConfirm}
|
||||
>
|
||||
{renderingSelectedPeer && (
|
||||
<GiftTransferPreview
|
||||
peer={renderingSelectedPeer}
|
||||
gift={uniqueGift}
|
||||
/>
|
||||
)}
|
||||
<p>
|
||||
{gift.transferStars
|
||||
? lang('GiftTransferConfirmDescription', {
|
||||
gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }),
|
||||
amount: formatStarsAsText(lang, gift.transferStars),
|
||||
peer: getPeerTitle(lang, renderingSelectedPeer!),
|
||||
}, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
})
|
||||
: lang('GiftTransferConfirmDescriptionFree', {
|
||||
gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }),
|
||||
peer: getPeerTitle(lang, renderingSelectedPeer!),
|
||||
}, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
})}
|
||||
</p>
|
||||
</ConfirmDialog>
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(
|
||||
withGlobal<OwnProps>((global, { modal }): Complete<StateProps> => {
|
||||
const selectedPeer = modal?.recipientId ? selectPeer(global, modal.recipientId) : undefined;
|
||||
|
||||
return {
|
||||
selectedPeer,
|
||||
};
|
||||
})(GiftTransferConfirmModal),
|
||||
);
|
||||
@ -1,19 +1,15 @@
|
||||
import {
|
||||
memo, useEffect, useMemo, useState,
|
||||
memo, useMemo, useState,
|
||||
} from '../../../../lib/teact/teact';
|
||||
import { getActions, getGlobal, withGlobal } from '../../../../global';
|
||||
|
||||
import type { ApiStarGiftUnique } from '../../../../api/types';
|
||||
import type { TabState } from '../../../../global/types';
|
||||
import type { UniqueCustomPeer } from '../../../../types';
|
||||
|
||||
import { ALL_FOLDER_ID } from '../../../../config';
|
||||
import { getPeerTitle } from '../../../../global/helpers/peers';
|
||||
import { selectCanGift, selectPeer } from '../../../../global/selectors';
|
||||
import { selectCanGift } from '../../../../global/selectors';
|
||||
import { unique } from '../../../../util/iteratees';
|
||||
import { formatStarsAsIcon, formatStarsAsText } from '../../../../util/localization/format';
|
||||
import { MEMO_EMPTY_ARRAY } from '../../../../util/memo';
|
||||
import { getGiftAttributes } from '../../../common/helpers/gifts';
|
||||
import sortChatIds from '../../../common/helpers/sortChatIds';
|
||||
|
||||
import useCurrentOrPrev from '../../../../hooks/useCurrentOrPrev';
|
||||
@ -22,10 +18,8 @@ import useLang from '../../../../hooks/useLang';
|
||||
import useLastCallback from '../../../../hooks/useLastCallback';
|
||||
import usePeerSearch from '../../../../hooks/usePeerSearch';
|
||||
|
||||
import GiftTransferPreview from '../../../common/gift/GiftTransferPreview';
|
||||
import PeerPicker from '../../../common/pickers/PeerPicker';
|
||||
import PickerModal from '../../../common/pickers/PickerModal';
|
||||
import ConfirmDialog from '../../../ui/ConfirmDialog';
|
||||
|
||||
export type OwnProps = {
|
||||
modal: TabState['giftTransferModal'];
|
||||
@ -41,7 +35,11 @@ type Categories = 'withdraw';
|
||||
const GiftTransferModal = ({
|
||||
modal, contactIds, currentUserId,
|
||||
}: OwnProps & StateProps) => {
|
||||
const { closeGiftTransferModal, openGiftWithdrawModal, transferGift } = getActions();
|
||||
const {
|
||||
closeGiftTransferModal,
|
||||
openGiftWithdrawModal,
|
||||
openGiftTransferConfirmModal,
|
||||
} = getActions();
|
||||
const isOpen = Boolean(modal);
|
||||
|
||||
const lang = useLang();
|
||||
@ -49,16 +47,6 @@ const GiftTransferModal = ({
|
||||
const [searchQuery, setSearchQuery] = useState<string>('');
|
||||
|
||||
const renderingModal = useCurrentOrPrev(modal);
|
||||
const uniqueGift = renderingModal?.gift?.gift as ApiStarGiftUnique;
|
||||
const giftAttributes = uniqueGift && getGiftAttributes(uniqueGift);
|
||||
|
||||
const [selectedId, setSelectedId] = useState<string | undefined>();
|
||||
|
||||
const renderingSelectedPeerId = useCurrentOrPrev(selectedId);
|
||||
const renderingSelectedPeer = useMemo(() => {
|
||||
const global = getGlobal();
|
||||
return renderingSelectedPeerId ? selectPeer(global, renderingSelectedPeerId) : undefined;
|
||||
}, [renderingSelectedPeerId]);
|
||||
|
||||
const orderedChatIds = useFolderManagerForOrderedIds(ALL_FOLDER_ID);
|
||||
|
||||
@ -107,26 +95,13 @@ const GiftTransferModal = ({
|
||||
false);
|
||||
}, [isLoading, foundIds, currentUserId]);
|
||||
|
||||
const closeConfirmModal = useLastCallback(() => {
|
||||
setSelectedId(undefined);
|
||||
});
|
||||
const handlePeerSelect = useLastCallback((peerId: string) => {
|
||||
if (!renderingModal?.gift) return;
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen) {
|
||||
setSelectedId(undefined);
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
const handleTransfer = useLastCallback(() => {
|
||||
if (!renderingModal?.gift.inputGift) return;
|
||||
transferGift({
|
||||
gift: renderingModal.gift.inputGift,
|
||||
recipientId: renderingSelectedPeerId!,
|
||||
transferStars: renderingModal.gift.transferStars,
|
||||
openGiftTransferConfirmModal({
|
||||
gift: renderingModal.gift,
|
||||
recipientId: peerId,
|
||||
});
|
||||
|
||||
closeConfirmModal();
|
||||
closeGiftTransferModal();
|
||||
});
|
||||
|
||||
return (
|
||||
@ -151,47 +126,8 @@ const GiftTransferModal = ({
|
||||
filterValue={searchQuery}
|
||||
filterPlaceholder={lang('Search')}
|
||||
onFilterChange={setSearchQuery}
|
||||
onSelectedIdChange={setSelectedId}
|
||||
onSelectedIdChange={handlePeerSelect}
|
||||
/>
|
||||
{giftAttributes && (
|
||||
<ConfirmDialog
|
||||
isOpen={Boolean(selectedId)}
|
||||
noDefaultTitle
|
||||
onClose={closeConfirmModal}
|
||||
confirmLabel={renderingModal?.gift.transferStars
|
||||
? lang(
|
||||
'GiftTransferConfirmButton',
|
||||
{ amount: formatStarsAsIcon(lang, renderingModal.gift.transferStars, { asFont: true }) },
|
||||
{ withNodes: true },
|
||||
) : lang('GiftTransferConfirmButtonFree')}
|
||||
confirmHandler={handleTransfer}
|
||||
>
|
||||
{renderingSelectedPeer && (
|
||||
<GiftTransferPreview
|
||||
peer={renderingSelectedPeer}
|
||||
gift={uniqueGift}
|
||||
/>
|
||||
)}
|
||||
<p>
|
||||
{renderingModal?.gift.transferStars
|
||||
? lang('GiftTransferConfirmDescription', {
|
||||
gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }),
|
||||
amount: formatStarsAsText(lang, renderingModal.gift.transferStars),
|
||||
peer: getPeerTitle(lang, renderingSelectedPeer!),
|
||||
}, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
})
|
||||
: lang('GiftTransferConfirmDescriptionFree', {
|
||||
gift: lang('GiftUnique', { title: uniqueGift.title, number: uniqueGift.number }),
|
||||
peer: getPeerTitle(lang, renderingSelectedPeer!),
|
||||
}, {
|
||||
withNodes: true,
|
||||
withMarkdown: true,
|
||||
})}
|
||||
</p>
|
||||
</ConfirmDialog>
|
||||
)}
|
||||
</PickerModal>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
import type { ApiSavedStarGift, ApiStarGiftUnique } from '../../../api/types';
|
||||
import type { StarGiftCategory } from '../../../types';
|
||||
import type { ActionReturnType } from '../../types';
|
||||
|
||||
import {
|
||||
@ -8,7 +7,7 @@ import {
|
||||
TON_CURRENCY_CODE,
|
||||
} from '../../../config';
|
||||
import { getCurrentTabId } from '../../../util/establishMultitabRole';
|
||||
import { buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { buildCollectionByCallback, buildCollectionByKey } from '../../../util/iteratees';
|
||||
import { callApi } from '../../../api/gramjs';
|
||||
import { RESALE_GIFTS_LIMIT } from '../../../limits';
|
||||
import { areInputSavedGiftsEqual, getRequestInputSavedStarGift } from '../../helpers/payments';
|
||||
@ -136,49 +135,83 @@ addActionHandler('loadStarGifts', async (global): Promise<void> => {
|
||||
|
||||
const byId = buildCollectionByKey(result.gifts, 'id');
|
||||
|
||||
const idsByCategoryName: Record<StarGiftCategory, string[]> = {
|
||||
all: [],
|
||||
stock: [],
|
||||
limited: [],
|
||||
resale: [],
|
||||
};
|
||||
|
||||
const allStarGiftIds = Object.keys(byId);
|
||||
const allStarGifts = Object.values(byId);
|
||||
|
||||
const limitedStarGiftIds = allStarGifts.map((gift) => (gift.isLimited ? gift.id : undefined))
|
||||
.filter(Boolean);
|
||||
|
||||
const stockedStarGiftIds = allStarGifts.map((gift) => (
|
||||
gift.availabilityRemains || !gift.availabilityTotal ? gift.id : undefined
|
||||
)).filter(Boolean);
|
||||
|
||||
const resaleStarGiftIds = allStarGifts.map((gift) => (gift.availabilityResale ? gift.id : undefined))
|
||||
.filter(Boolean);
|
||||
|
||||
idsByCategoryName.all = allStarGiftIds;
|
||||
idsByCategoryName.limited = limitedStarGiftIds;
|
||||
idsByCategoryName.stock = stockedStarGiftIds;
|
||||
idsByCategoryName.resale = resaleStarGiftIds;
|
||||
|
||||
allStarGifts.forEach((gift) => {
|
||||
const starsCategory = gift.stars;
|
||||
if (!idsByCategoryName[starsCategory]) {
|
||||
idsByCategoryName[starsCategory] = [];
|
||||
}
|
||||
idsByCategoryName[starsCategory].push(gift.id);
|
||||
});
|
||||
|
||||
global = {
|
||||
...global,
|
||||
starGifts: {
|
||||
byId,
|
||||
idsByCategory: idsByCategoryName,
|
||||
idsByCategory: {
|
||||
all: allStarGiftIds,
|
||||
resale: resaleStarGiftIds,
|
||||
myCollectibles: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('loadMyCollectibleGifts', async (global, actions, payload): Promise<void> => {
|
||||
const { shouldRefresh } = payload || {};
|
||||
const currentUserId = global.currentUserId;
|
||||
if (!currentUserId) return;
|
||||
|
||||
const currentMyCollectibleGifts = global.myCollectibleGifts;
|
||||
const localNextOffset = currentMyCollectibleGifts?.nextOffset;
|
||||
|
||||
if (currentMyCollectibleGifts && !localNextOffset && !shouldRefresh) return;
|
||||
|
||||
const peer = selectPeer(global, currentUserId);
|
||||
if (!peer) return;
|
||||
|
||||
const result = await callApi('fetchSavedStarGifts', {
|
||||
peer,
|
||||
offset: !shouldRefresh ? localNextOffset : undefined,
|
||||
filter: {
|
||||
sortType: 'byDate',
|
||||
shouldIncludeUnique: true,
|
||||
shouldIncludeUnlimited: false,
|
||||
shouldIncludeUpgradable: false,
|
||||
shouldIncludeLimited: false,
|
||||
shouldIncludeDisplayed: true,
|
||||
shouldIncludeHidden: true,
|
||||
},
|
||||
});
|
||||
|
||||
if (!result) return;
|
||||
|
||||
global = getGlobal();
|
||||
|
||||
const gifts = result.gifts;
|
||||
|
||||
const byId = buildCollectionByCallback(gifts, (savedGift) => (
|
||||
[savedGift.gift.id, savedGift]
|
||||
));
|
||||
|
||||
const ids = gifts.map((gift) => gift.gift.id);
|
||||
|
||||
global = {
|
||||
...global,
|
||||
myCollectibleGifts: {
|
||||
byId: {
|
||||
...!shouldRefresh && (global.myCollectibleGifts?.byId || {}),
|
||||
...byId,
|
||||
},
|
||||
ids: [
|
||||
...!shouldRefresh ? (global.myCollectibleGifts?.ids || []) : [],
|
||||
...ids,
|
||||
],
|
||||
nextOffset: result.nextOffset,
|
||||
},
|
||||
};
|
||||
|
||||
setGlobal(global);
|
||||
});
|
||||
|
||||
addActionHandler('updateResaleGiftsFilter', (global, actions, payload): ActionReturnType => {
|
||||
const {
|
||||
filter, tabId = getCurrentTabId(),
|
||||
@ -338,6 +371,9 @@ addActionHandler('reloadPeerSavedGifts', (global, actions, payload): ActionRetur
|
||||
actions.loadPeerSavedGifts({ peerId, shouldRefresh: true, tabId: tabState.id });
|
||||
}
|
||||
});
|
||||
if (peerId === global.currentUserId) {
|
||||
actions.loadMyCollectibleGifts({ shouldRefresh: true });
|
||||
}
|
||||
});
|
||||
|
||||
addActionHandler('loadStarsSubscriptions', async (global): Promise<void> => {
|
||||
|
||||
@ -298,6 +298,8 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
global = updateTabState(global, {
|
||||
isWaitingForStarGiftTransfer: undefined,
|
||||
}, tabId);
|
||||
|
||||
actions.reloadPeerSavedGifts({ peerId: global.currentUserId! });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@ -146,6 +146,7 @@ addActionHandler('apiUpdate', (global, actions, update): ActionReturnType => {
|
||||
},
|
||||
tabId,
|
||||
});
|
||||
actions.reloadPeerSavedGifts({ peerId: starGiftModalState.forPeerId });
|
||||
actions.requestConfetti({ withStars: true, tabId });
|
||||
actions.closeGiftModal({ tabId });
|
||||
}
|
||||
|
||||
@ -434,6 +434,21 @@ addActionHandler('openGiftTransferModal', (global, actions, payload): ActionRetu
|
||||
|
||||
addTabStateResetterAction('closeGiftTransferModal', 'giftTransferModal');
|
||||
|
||||
addActionHandler('openGiftTransferConfirmModal', (global, actions, payload): ActionReturnType => {
|
||||
const {
|
||||
gift, recipientId, tabId = getCurrentTabId(),
|
||||
} = payload;
|
||||
|
||||
return updateTabState(global, {
|
||||
giftTransferConfirmModal: {
|
||||
gift,
|
||||
recipientId,
|
||||
},
|
||||
}, tabId);
|
||||
});
|
||||
|
||||
addTabStateResetterAction('closeGiftTransferConfirmModal', 'giftTransferConfirmModal');
|
||||
|
||||
addActionHandler('updateSelectedGiftCollection', (global, actions, payload): ActionReturnType => {
|
||||
const { peerId, collectionId, tabId = getCurrentTabId() } = payload;
|
||||
const tabState = selectTabState(global, tabId);
|
||||
|
||||
@ -2544,6 +2544,9 @@ export interface ActionPayloads {
|
||||
loadPremiumGifts: undefined;
|
||||
loadTonGifts: undefined;
|
||||
loadStarGifts: undefined;
|
||||
loadMyCollectibleGifts: {
|
||||
shouldRefresh?: true;
|
||||
} | undefined;
|
||||
updateResaleGiftsFilter: {
|
||||
filter: ResaleGiftsFilterOptions;
|
||||
} & WithTabId;
|
||||
@ -2643,6 +2646,11 @@ export interface ActionPayloads {
|
||||
recipientId: string;
|
||||
} & WithTabId;
|
||||
closeGiftTransferModal: WithTabId | undefined;
|
||||
openGiftTransferConfirmModal: {
|
||||
gift: ApiSavedStarGift;
|
||||
recipientId: string;
|
||||
} & WithTabId;
|
||||
closeGiftTransferConfirmModal: WithTabId | undefined;
|
||||
updateSelectedGiftCollection: {
|
||||
peerId: string;
|
||||
collectionId: number;
|
||||
|
||||
@ -28,6 +28,7 @@ import type {
|
||||
ApiReaction,
|
||||
ApiReactionKey,
|
||||
ApiSavedReactionTag,
|
||||
ApiSavedStarGift,
|
||||
ApiSession,
|
||||
ApiSponsoredMessage,
|
||||
ApiStarGiftCollection,
|
||||
@ -311,6 +312,11 @@ export type GlobalState = {
|
||||
byId: Record<string, ApiStarGiftRegular>;
|
||||
idsByCategory: Record<StarGiftCategory, string[]>;
|
||||
};
|
||||
myCollectibleGifts?: {
|
||||
byId: Record<string, ApiSavedStarGift>;
|
||||
ids: string[];
|
||||
nextOffset?: string;
|
||||
};
|
||||
starGiftCollections?: {
|
||||
byPeerId: Record<string, ApiStarGiftCollection[]>;
|
||||
};
|
||||
|
||||
@ -849,6 +849,11 @@ export type TabState = {
|
||||
gift: ApiSavedStarGift;
|
||||
};
|
||||
|
||||
giftTransferConfirmModal?: {
|
||||
gift: ApiSavedStarGift;
|
||||
recipientId: string;
|
||||
};
|
||||
|
||||
giftUpgradeModal?: {
|
||||
sampleAttributes: ApiStarGiftAttribute[];
|
||||
recipientId?: string;
|
||||
|
||||
@ -669,7 +669,7 @@ export type WebPageMediaSize = 'large' | 'small';
|
||||
|
||||
export type AttachmentCompression = 'compress' | 'original';
|
||||
|
||||
export type StarGiftCategory = number | 'all' | 'limited' | 'stock' | 'resale';
|
||||
export type StarGiftCategory = 'all' | 'myCollectibles' | 'resale';
|
||||
|
||||
export type CallSound = (
|
||||
'join' | 'allowTalk' | 'leave' | 'connecting' | 'incoming' | 'end' | 'connect' | 'busy' | 'ringing'
|
||||
|
||||
7
src/types/language.d.ts
vendored
7
src/types/language.d.ts
vendored
@ -1232,6 +1232,7 @@ export interface LangPair {
|
||||
'GiftPremiumDescriptionLink': undefined;
|
||||
'StarsGiftHeader': undefined;
|
||||
'StarsGiftHeaderSelf': undefined;
|
||||
'StarGiftDescriptionCollectibles': undefined;
|
||||
'StarGiftDescriptionSelf': undefined;
|
||||
'GiftLimited': undefined;
|
||||
'GiftSoldOut': undefined;
|
||||
@ -1304,8 +1305,6 @@ export interface LangPair {
|
||||
'GiftWithdrawTitle': undefined;
|
||||
'GiftWithdrawSubmit': undefined;
|
||||
'AllGiftsCategory': undefined;
|
||||
'LimitedGiftsCategory': undefined;
|
||||
'StockGiftsCategory': undefined;
|
||||
'PremiumGiftDescription': undefined;
|
||||
'StarsReactionLinkText': undefined;
|
||||
'StarsReactionLink': undefined;
|
||||
@ -1578,7 +1577,8 @@ export interface LangPair {
|
||||
'StarGiftPurchaseTransaction': undefined;
|
||||
'ContextMenuItemMention': undefined;
|
||||
'GiftRibbonResale': undefined;
|
||||
'GiftCategoryResale': undefined;
|
||||
'GiftCategoryCollectibles': undefined;
|
||||
'GiftCategoryMyGifts': undefined;
|
||||
'GiftSortByPrice': undefined;
|
||||
'GiftSortByNumber': undefined;
|
||||
'ContextMenuItemSelectAll': undefined;
|
||||
@ -1709,6 +1709,7 @@ export interface LangPair {
|
||||
'GiftValueForSaleOnFragment': undefined;
|
||||
'GiftValueForSaleOnTelegram': undefined;
|
||||
'EmbeddedMessageNoCaption': undefined;
|
||||
'ConfirmBuyGiftForTonDescription': undefined;
|
||||
'TitleGiftLocked': undefined;
|
||||
'QuickPreview': undefined;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user