Gift Modal: Fix build market collectible gifts (#6441)

This commit is contained in:
Alexander Zinchuk 2025-11-06 11:36:51 +01:00
parent 5fa084c78d
commit f426014dbc
7 changed files with 51 additions and 47 deletions

View File

@ -217,7 +217,7 @@ const Main = ({
loadPremiumGifts, loadPremiumGifts,
loadTonGifts, loadTonGifts,
loadStarGifts, loadStarGifts,
loadMyCollectibleGifts, loadMyUniqueGifts,
loadDefaultTopicIcons, loadDefaultTopicIcons,
loadAddedStickers, loadAddedStickers,
loadFavoriteStickers, loadFavoriteStickers,
@ -333,7 +333,7 @@ const Main = ({
loadPremiumGifts(); loadPremiumGifts();
loadTonGifts(); loadTonGifts();
loadStarGifts(); loadStarGifts();
loadMyCollectibleGifts(); loadMyUniqueGifts();
loadAvailableEffects(); loadAvailableEffects();
loadBirthdayNumbersStickers(); loadBirthdayNumbersStickers();
loadRestrictedEmojiStickers(); loadRestrictedEmojiStickers();

View File

@ -58,8 +58,8 @@ type StateProps = {
boostPerSentGift?: number; boostPerSentGift?: number;
starGiftsById?: Record<string, ApiStarGiftRegular>; starGiftsById?: Record<string, ApiStarGiftRegular>;
starGiftIdsByCategory?: Record<StarGiftCategory, string[]>; starGiftIdsByCategory?: Record<StarGiftCategory, string[]>;
myCollectibleGiftsById?: Record<string, ApiSavedStarGift>; myUniqueGiftsById?: Record<string, ApiSavedStarGift>;
myCollectibleGiftIds?: string[]; myUniqueGiftIds?: string[];
starBalance?: ApiStarsAmount; starBalance?: ApiStarsAmount;
peer?: ApiPeer; peer?: ApiPeer;
isSelf?: boolean; isSelf?: boolean;
@ -81,8 +81,8 @@ const GiftModal: FC<OwnProps & StateProps> = ({
modal, modal,
starGiftsById, starGiftsById,
starGiftIdsByCategory, starGiftIdsByCategory,
myCollectibleGiftsById, myUniqueGiftsById,
myCollectibleGiftIds, myUniqueGiftIds,
starBalance, starBalance,
peer, peer,
isSelf, isSelf,
@ -99,7 +99,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
loadResaleGifts, loadResaleGifts,
openGiftInMarket, openGiftInMarket,
closeResaleGiftsMarket, closeResaleGiftsMarket,
loadMyCollectibleGifts, loadMyUniqueGifts,
openGiftTransferConfirmModal, openGiftTransferConfirmModal,
} = getActions(); } = getActions();
const dialogRef = useRef<HTMLDivElement>(); const dialogRef = useRef<HTMLDivElement>();
@ -235,7 +235,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
}); });
} }
if (selectedCategory === 'resale') { if (selectedCategory === 'collectible') {
return lang('StarGiftDescriptionCollectibles'); return lang('StarGiftDescriptionCollectibles');
} }
@ -293,8 +293,8 @@ const GiftModal: FC<OwnProps & StateProps> = ({
}); });
const handleMyGiftClick = useLastCallback((gift: ApiStarGift) => { const handleMyGiftClick = useLastCallback((gift: ApiStarGift) => {
if (gift.type === 'starGift' || !myCollectibleGiftsById || !peer?.id) return; if (gift.type === 'starGift' || !myUniqueGiftsById || !peer?.id) return;
const savedGift = myCollectibleGiftsById[gift.id]; const savedGift = myUniqueGiftsById[gift.id];
openGiftTransferConfirmModal({ openGiftTransferConfirmModal({
gift: savedGift, gift: savedGift,
@ -303,23 +303,23 @@ const GiftModal: FC<OwnProps & StateProps> = ({
}); });
const handleLoadMore = useLastCallback(() => { const handleLoadMore = useLastCallback(() => {
if (selectedCategory === 'myCollectibles') { if (selectedCategory === 'myUnique') {
loadMyCollectibleGifts(); loadMyUniqueGifts();
} }
}); });
function renderStarGifts() { function renderStarGifts() {
if (selectedCategory === 'myCollectibles') { if (selectedCategory === 'myUnique') {
return ( return (
<InfiniteScroll <InfiniteScroll
className={styles.starGiftsContainer} className={styles.starGiftsContainer}
items={myCollectibleGiftIds} items={myUniqueGiftIds}
onLoadMore={handleLoadMore} onLoadMore={handleLoadMore}
scrollContainerClosest={`.${styles.main}`} scrollContainerClosest={`.${styles.main}`}
itemSelector=".starGiftItem" itemSelector=".starGiftItem"
> >
{myCollectibleGiftsById && myCollectibleGiftIds?.map((giftId) => { {myUniqueGiftsById && myUniqueGiftIds?.map((giftId) => {
const savedGift = myCollectibleGiftsById[giftId]; const savedGift = myUniqueGiftsById[giftId];
if (!savedGift) return undefined; if (!savedGift) return undefined;
return ( return (
@ -356,8 +356,7 @@ const GiftModal: FC<OwnProps & StateProps> = ({
{starGiftsById && filteredGiftIds?.flatMap((giftId) => { {starGiftsById && filteredGiftIds?.flatMap((giftId) => {
const gift = starGiftsById[giftId]; const gift = starGiftsById[giftId];
const shouldShowResale = Boolean(gift.availabilityResale) && !areUniqueStarGiftsDisallowed; const shouldShowResale = Boolean(gift.availabilityResale) && !areUniqueStarGiftsDisallowed;
const shouldDuplicateAsResale = selectedCategory !== 'resale' const shouldDuplicateAsResale = shouldShowResale && !gift.isSoldOut && !areLimitedStarGiftsDisallowed;
&& shouldShowResale && !gift.isSoldOut && !areLimitedStarGiftsDisallowed;
const elements = [ const elements = [
<GiftItemStar <GiftItemStar
@ -464,9 +463,10 @@ const GiftModal: FC<OwnProps & StateProps> = ({
{renderStarGiftsHeader()} {renderStarGiftsHeader()}
{renderStarGiftsDescription()} {renderStarGiftsDescription()}
<StarGiftCategoryList <StarGiftCategoryList
areCollectibleStarGiftsDisallowed={areUniqueStarGiftsDisallowed} areUniqueStarGiftsDisallowed={areUniqueStarGiftsDisallowed}
areLimitedStarGiftsDisallowed={areLimitedStarGiftsDisallowed}
isSelf={isSelf} isSelf={isSelf}
hasCollectible={Boolean(myCollectibleGiftIds?.length)} hasMyUnique={Boolean(myUniqueGiftIds?.length)}
onCategoryChanged={onCategoryChanged} onCategoryChanged={onCategoryChanged}
/> />
<Transition <Transition
@ -602,8 +602,8 @@ export default memo(withGlobal<OwnProps>((global, { modal }): Complete<StateProp
boostPerSentGift: global.appConfig.boostsPerSentGift, boostPerSentGift: global.appConfig.boostsPerSentGift,
starGiftsById: starGifts?.byId, starGiftsById: starGifts?.byId,
starGiftIdsByCategory: starGifts?.idsByCategory, starGiftIdsByCategory: starGifts?.idsByCategory,
myCollectibleGiftsById: global.myCollectibleGifts?.byId, myUniqueGiftsById: global.myUniqueGifts?.byId,
myCollectibleGiftIds: global.myCollectibleGifts?.ids, myUniqueGiftIds: global.myUniqueGifts?.ids,
starBalance: stars?.balance, starBalance: stars?.balance,
peer, peer,
isSelf, isSelf,
@ -617,6 +617,6 @@ export default memo(withGlobal<OwnProps>((global, { modal }): Complete<StateProp
function getCategoryKey(category: StarGiftCategory) { function getCategoryKey(category: StarGiftCategory) {
if (category === 'all') return 0; if (category === 'all') return 0;
if (category === 'myCollectibles') return 1; if (category === 'myUnique') return 1;
return 2; return 2;
} }

View File

@ -13,9 +13,10 @@ import useLang from '../../../hooks/useLang';
import styles from './StarGiftCategoryList.module.scss'; import styles from './StarGiftCategoryList.module.scss';
type OwnProps = { type OwnProps = {
areCollectibleStarGiftsDisallowed?: boolean; areUniqueStarGiftsDisallowed?: boolean;
areLimitedStarGiftsDisallowed?: boolean;
isSelf?: boolean; isSelf?: boolean;
hasCollectible?: boolean; hasMyUnique?: boolean;
onCategoryChanged: (category: StarGiftCategory) => void; onCategoryChanged: (category: StarGiftCategory) => void;
}; };
@ -26,15 +27,16 @@ type StateProps = {
const StarGiftCategoryList = ({ const StarGiftCategoryList = ({
idsByCategory, idsByCategory,
onCategoryChanged, onCategoryChanged,
areCollectibleStarGiftsDisallowed, areUniqueStarGiftsDisallowed,
areLimitedStarGiftsDisallowed,
isSelf, isSelf,
hasCollectible, hasMyUnique,
}: StateProps & OwnProps) => { }: StateProps & OwnProps) => {
const ref = useRef<HTMLDivElement>(); const ref = useRef<HTMLDivElement>();
const lang = useLang(); const lang = useLang();
const hasResale = idsByCategory && idsByCategory['resale'].length > 0; const hasCollectible = Boolean(idsByCategory?.collectible?.length);
const [selectedCategory, setSelectedCategory] = useState<StarGiftCategory>('all'); const [selectedCategory, setSelectedCategory] = useState<StarGiftCategory>('all');
@ -47,8 +49,8 @@ const StarGiftCategoryList = ({
function renderCategoryName(category: StarGiftCategory) { function renderCategoryName(category: StarGiftCategory) {
if (category === 'all') return lang('AllGiftsCategory'); if (category === 'all') return lang('AllGiftsCategory');
if (category === 'myCollectibles') return lang('GiftCategoryMyGifts'); if (category === 'myUnique') return lang('GiftCategoryMyGifts');
if (category === 'resale') return lang('GiftCategoryCollectibles'); if (category === 'collectible') return lang('GiftCategoryCollectibles');
return category; return category;
} }
@ -71,13 +73,14 @@ const StarGiftCategoryList = ({
return ( return (
<div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}> <div ref={ref} className={buildClassName(styles.list, 'no-scrollbar')}>
{renderCategoryItem('all')} {renderCategoryItem('all')}
{!areCollectibleStarGiftsDisallowed && !isSelf && hasCollectible && renderCategoryItem('myCollectibles')} {!areUniqueStarGiftsDisallowed && !isSelf && hasMyUnique && renderCategoryItem('myUnique')}
{!areCollectibleStarGiftsDisallowed && hasResale && renderCategoryItem('resale')} {(!areUniqueStarGiftsDisallowed || !areLimitedStarGiftsDisallowed)
&& hasCollectible && renderCategoryItem('collectible')}
</div> </div>
); );
}; };
export default memo(withGlobal( export default memo(withGlobal<OwnProps>(
(global): Complete<StateProps> => { (global): Complete<StateProps> => {
const { starGifts } = global; const { starGifts } = global;

View File

@ -138,7 +138,8 @@ addActionHandler('loadStarGifts', async (global): Promise<void> => {
const allStarGiftIds = Object.keys(byId); const allStarGiftIds = Object.keys(byId);
const allStarGifts = Object.values(byId); const allStarGifts = Object.values(byId);
const resaleStarGiftIds = allStarGifts.map((gift) => (gift.availabilityResale ? gift.id : undefined)) const collectibleStarGiftIds = allStarGifts.map((gift) => (
(gift.availabilityResale || (gift.isLimited && !gift.isSoldOut)) ? gift.id : undefined))
.filter(Boolean); .filter(Boolean);
global = { global = {
@ -147,23 +148,23 @@ addActionHandler('loadStarGifts', async (global): Promise<void> => {
byId, byId,
idsByCategory: { idsByCategory: {
all: allStarGiftIds, all: allStarGiftIds,
resale: resaleStarGiftIds, collectible: collectibleStarGiftIds,
myCollectibles: [], myUnique: [],
}, },
}, },
}; };
setGlobal(global); setGlobal(global);
}); });
addActionHandler('loadMyCollectibleGifts', async (global, actions, payload): Promise<void> => { addActionHandler('loadMyUniqueGifts', async (global, actions, payload): Promise<void> => {
const { shouldRefresh } = payload || {}; const { shouldRefresh } = payload || {};
const currentUserId = global.currentUserId; const currentUserId = global.currentUserId;
if (!currentUserId) return; if (!currentUserId) return;
const currentMyCollectibleGifts = global.myCollectibleGifts; const currentMyUniqueGifts = global.myUniqueGifts;
const localNextOffset = currentMyCollectibleGifts?.nextOffset; const localNextOffset = currentMyUniqueGifts?.nextOffset;
if (currentMyCollectibleGifts && !localNextOffset && !shouldRefresh) return; if (currentMyUniqueGifts && !localNextOffset && !shouldRefresh) return;
const peer = selectPeer(global, currentUserId); const peer = selectPeer(global, currentUserId);
if (!peer) return; if (!peer) return;
@ -196,13 +197,13 @@ addActionHandler('loadMyCollectibleGifts', async (global, actions, payload): Pro
global = { global = {
...global, ...global,
myCollectibleGifts: { myUniqueGifts: {
byId: { byId: {
...!shouldRefresh && (global.myCollectibleGifts?.byId || {}), ...!shouldRefresh && (global.myUniqueGifts?.byId || {}),
...byId, ...byId,
}, },
ids: [ ids: [
...!shouldRefresh ? (global.myCollectibleGifts?.ids || []) : [], ...!shouldRefresh ? (global.myUniqueGifts?.ids || []) : [],
...ids, ...ids,
], ],
nextOffset: result.nextOffset, nextOffset: result.nextOffset,
@ -372,7 +373,7 @@ addActionHandler('reloadPeerSavedGifts', (global, actions, payload): ActionRetur
} }
}); });
if (peerId === global.currentUserId) { if (peerId === global.currentUserId) {
actions.loadMyCollectibleGifts({ shouldRefresh: true }); actions.loadMyUniqueGifts({ shouldRefresh: true });
} }
}); });

View File

@ -2556,7 +2556,7 @@ export interface ActionPayloads {
loadPremiumGifts: undefined; loadPremiumGifts: undefined;
loadTonGifts: undefined; loadTonGifts: undefined;
loadStarGifts: undefined; loadStarGifts: undefined;
loadMyCollectibleGifts: { loadMyUniqueGifts: {
shouldRefresh?: true; shouldRefresh?: true;
} | undefined; } | undefined;
updateResaleGiftsFilter: { updateResaleGiftsFilter: {

View File

@ -312,7 +312,7 @@ export type GlobalState = {
byId: Record<string, ApiStarGiftRegular>; byId: Record<string, ApiStarGiftRegular>;
idsByCategory: Record<StarGiftCategory, string[]>; idsByCategory: Record<StarGiftCategory, string[]>;
}; };
myCollectibleGifts?: { myUniqueGifts?: {
byId: Record<string, ApiSavedStarGift>; byId: Record<string, ApiSavedStarGift>;
ids: string[]; ids: string[];
nextOffset?: string; nextOffset?: string;

View File

@ -670,7 +670,7 @@ export type WebPageMediaSize = 'large' | 'small';
export type AttachmentCompression = 'compress' | 'original'; export type AttachmentCompression = 'compress' | 'original';
export type StarGiftCategory = 'all' | 'myCollectibles' | 'resale'; export type StarGiftCategory = 'all' | 'myUnique' | 'collectible';
export type CallSound = ( export type CallSound = (
'join' | 'allowTalk' | 'leave' | 'connecting' | 'incoming' | 'end' | 'connect' | 'busy' | 'ringing' 'join' | 'allowTalk' | 'leave' | 'connecting' | 'incoming' | 'end' | 'connect' | 'busy' | 'ringing'