mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
useSellablePetPalette(breed): per-breed TanStack query for pet picker
CatalogLayoutPetView previously read 'catalogOptions.petPalettes' (an
accumulating array of CatalogPetPalette objects keyed by breed) and,
on cache miss, dispatched GetSellablePetPalettesComposer(productData.type)
inline. useCatalog kept the matching SellablePetPalettesMessageEvent
listener that appended each new breed to the array (deduping by breed
identity).
Migrate the request/response pair to a TanStack query parameterized on
breed:
useSellablePetPalette(breed)
key: ['nitro', 'catalog', 'petPalette', breed]
request: () => new GetSellablePetPalettesComposer(breed)
parser: SellablePetPalettesMessageEvent
accept: event.getParser().productCode === breed
select: build a CatalogPetPalette from parser
enabled: !!breed (avoid spamming composers before currentOffer is set)
staleTime: Infinity
The view now derives breed from currentOffer.product.productData.type
and reads 'const { data: petPalette }'. The cache-miss-then-fetch
two-pass effect collapses into a single effect that runs once
petPalette resolves (or clears state when offer/petPalette aren't
ready).
Drops the matching listener from useCatalog, drops petPalettes from
ICatalogOptions, and removes the now-unused CatalogPetPalette /
SellablePetPalettesMessageEvent imports from useCatalog.
This commit is contained in:
@@ -1,9 +1,7 @@
|
||||
import { ClubGiftInfoParser, MarketplaceConfigurationMessageParser } from '@nitrots/nitro-renderer';
|
||||
import { CatalogPetPalette } from './CatalogPetPalette';
|
||||
|
||||
export interface ICatalogOptions
|
||||
{
|
||||
petPalettes?: CatalogPetPalette[];
|
||||
clubGifts?: ClubGiftInfoParser;
|
||||
marketplaceConfiguration?: MarketplaceConfigurationMessageParser;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { ApproveNameMessageComposer, ApproveNameMessageEvent, ColorConverter, GetSellablePetPalettesComposer, PurchaseFromCatalogComposer, SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { ApproveNameMessageComposer, ApproveNameMessageEvent, ColorConverter, PurchaseFromCatalogComposer, SellablePetPaletteData } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { FaCheck, FaEdit, FaFillDrip, FaPaw, FaPlus, FaTimes } from 'react-icons/fa';
|
||||
import { DispatchUiEvent, GetPetAvailableColors, GetPetIndexFromLocalization, LocalizeText, SanitizeHtml, SendMessageComposer } from '../../../../../../api';
|
||||
import { LayoutGridItem, LayoutPetImageView } from '../../../../../../common';
|
||||
import { CatalogPurchaseFailureEvent } from '../../../../../../events';
|
||||
import { useCatalog, useMessageEvent } from '../../../../../../hooks';
|
||||
import { useCatalog, useMessageEvent, useSellablePetPalette } from '../../../../../../hooks';
|
||||
import { useCatalogAdmin } from '../../../../CatalogAdminContext';
|
||||
import { CatalogAddOnBadgeWidgetView } from '../../widgets/CatalogAddOnBadgeWidgetView';
|
||||
import { CatalogTotalPriceWidget } from '../../widgets/CatalogTotalPriceWidget';
|
||||
@@ -23,10 +23,11 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
const [ petName, setPetName ] = useState('');
|
||||
const [ approvalPending, setApprovalPending ] = useState(true);
|
||||
const [ approvalResult, setApprovalResult ] = useState(-1);
|
||||
const { currentOffer = null, setCurrentOffer = null, setPurchaseOptions = null, catalogOptions = null, roomPreviewer = null } = useCatalog();
|
||||
const { currentOffer = null, setCurrentOffer = null, setPurchaseOptions = null, roomPreviewer = null } = useCatalog();
|
||||
const catalogAdmin = useCatalogAdmin();
|
||||
const adminMode = catalogAdmin?.adminMode ?? false;
|
||||
const { petPalettes = null } = catalogOptions;
|
||||
const breed: string = (currentOffer?.product?.productData?.type as unknown as string) ?? '';
|
||||
const { data: petPalette = null } = useSellablePetPalette(breed);
|
||||
|
||||
const getColor = useMemo(() =>
|
||||
{
|
||||
@@ -129,39 +130,25 @@ export const CatalogLayoutPetView: FC<CatalogLayoutProps> = props =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!currentOffer) return;
|
||||
|
||||
const productData = currentOffer.product.productData;
|
||||
|
||||
if(!productData) return;
|
||||
|
||||
if(petPalettes)
|
||||
if(!currentOffer || !petPalette)
|
||||
{
|
||||
for(const paletteData of petPalettes)
|
||||
{
|
||||
if(paletteData.breed !== productData.type) continue;
|
||||
|
||||
const palettes: SellablePetPaletteData[] = [];
|
||||
|
||||
for(const palette of paletteData.palettes)
|
||||
{
|
||||
if(!palette.sellable) continue;
|
||||
|
||||
palettes.push(palette);
|
||||
}
|
||||
|
||||
setSelectedPaletteIndex((palettes.length ? 0 : -1));
|
||||
setSellablePalettes(palettes);
|
||||
|
||||
return;
|
||||
}
|
||||
setSelectedPaletteIndex(-1);
|
||||
setSellablePalettes([]);
|
||||
return;
|
||||
}
|
||||
|
||||
setSelectedPaletteIndex(-1);
|
||||
setSellablePalettes([]);
|
||||
const palettes: SellablePetPaletteData[] = [];
|
||||
|
||||
SendMessageComposer(new GetSellablePetPalettesComposer(productData.type));
|
||||
}, [ currentOffer, petPalettes ]);
|
||||
for(const palette of petPalette.palettes)
|
||||
{
|
||||
if(!palette.sellable) continue;
|
||||
|
||||
palettes.push(palette);
|
||||
}
|
||||
|
||||
setSelectedPaletteIndex(palettes.length ? 0 : -1);
|
||||
setSellablePalettes(palettes);
|
||||
}, [ currentOffer, petPalette ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
|
||||
@@ -4,3 +4,4 @@ export * from './useCatalogPlaceMultipleItems';
|
||||
export * from './useCatalogSkipPurchaseConfirmation';
|
||||
export * from './useClubOffers';
|
||||
export * from './useGiftConfiguration';
|
||||
export * from './useSellablePetPalette';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, CreateLinkEvent, FrontPageItem, FurniturePlaceComposer, FurniturePlacePaintComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetRoomEngine, GetSessionDataManager, GetTickerTime, LegacyDataType, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, RoomPreviewer, SellablePetPalettesMessageEvent, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, CreateLinkEvent, FrontPageItem, FurniturePlaceComposer, FurniturePlacePaintComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetRoomEngine, GetSessionDataManager, GetTickerTime, LegacyDataType, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useBetween } from 'use-between';
|
||||
import { BuilderFurniPlaceableStatus, CatalogNode, CatalogPage, CatalogPetPalette, CatalogType, DispatchUiEvent, FurniCategory, GetFurnitureData, GetProductDataForLocalization, GetRoomSession, ICatalogNode, ICatalogOptions, ICatalogPage, IPageLocalization, IProduct, IPurchasableOffer, IPurchaseOptions, LocalizeText, NotificationAlertType, Offer, PageLocalization, PlacedObjectPurchaseData, PlaySound, Product, ProductTypeEnum, RequestedPage, SearchResult, SendMessageComposer, SoundNames } from '../../api';
|
||||
import { BuilderFurniPlaceableStatus, CatalogNode, CatalogPage, CatalogType, DispatchUiEvent, FurniCategory, GetFurnitureData, GetProductDataForLocalization, GetRoomSession, ICatalogNode, ICatalogOptions, ICatalogPage, IPageLocalization, IProduct, IPurchasableOffer, IPurchaseOptions, LocalizeText, NotificationAlertType, Offer, PageLocalization, PlacedObjectPurchaseData, PlaySound, Product, ProductTypeEnum, RequestedPage, SearchResult, SendMessageComposer, SoundNames } from '../../api';
|
||||
import { CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent, CatalogPurchasedEvent, InventoryFurniAddedEvent } from '../../events';
|
||||
import { useMessageEvent, useNitroEvent, useUiEvent } from '../events';
|
||||
import { useNotification } from '../notification';
|
||||
@@ -710,34 +710,6 @@ const useCatalogState = () =>
|
||||
// (this._isObjectMoverRequested) && (this._purchasableOffer)
|
||||
});
|
||||
|
||||
useMessageEvent<SellablePetPalettesMessageEvent>(SellablePetPalettesMessageEvent, event =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
const petPalette = new CatalogPetPalette(parser.productCode, parser.palettes.slice());
|
||||
|
||||
setCatalogOptions(prevValue =>
|
||||
{
|
||||
const petPalettes = [];
|
||||
|
||||
if(prevValue.petPalettes) petPalettes.push(...prevValue.petPalettes);
|
||||
|
||||
for(let i = 0; i < petPalettes.length; i++)
|
||||
{
|
||||
const palette = petPalettes[i];
|
||||
|
||||
if(palette.breed === petPalette.breed)
|
||||
{
|
||||
petPalettes.splice(i, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
petPalettes.push(petPalette);
|
||||
|
||||
return { ...prevValue, petPalettes };
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { GetSellablePetPalettesComposer, SellablePetPalettesMessageEvent } from '@nitrots/nitro-renderer';
|
||||
import { UseQueryResult } from '@tanstack/react-query';
|
||||
import { CatalogPetPalette } from '../../api';
|
||||
import { useNitroQuery } from '../../api/nitro-query';
|
||||
|
||||
/**
|
||||
* Sellable palettes for a given pet breed, as returned by
|
||||
* GetSellablePetPalettesComposer(breed) → SellablePetPalettesMessageEvent.
|
||||
* The renderer multiplexes one event type for every breed; accept()
|
||||
* keeps each query slot listening only for the matching productCode.
|
||||
*
|
||||
* Replaces the per-breed accumulator that previously lived in
|
||||
* useCatalog (writing to catalogOptions.petPalettes). The catalog pet
|
||||
* page now reads via `useSellablePetPalette(productData.type)`.
|
||||
*
|
||||
* The breed identifier is the localization product code string
|
||||
* (e.g. 'pet_egg', 'pet_dog', ...). Disabled while breed is empty so
|
||||
* we don't spam composers at mount before the offer is known.
|
||||
*/
|
||||
export const useSellablePetPalette = (
|
||||
breed: string,
|
||||
options: { enabled?: boolean } = {}
|
||||
): UseQueryResult<CatalogPetPalette> =>
|
||||
useNitroQuery<SellablePetPalettesMessageEvent, CatalogPetPalette>({
|
||||
key: [ 'nitro', 'catalog', 'petPalette', breed ],
|
||||
request: () => new GetSellablePetPalettesComposer(breed),
|
||||
parser: SellablePetPalettesMessageEvent,
|
||||
accept: event => (event.getParser().productCode === breed),
|
||||
select: event => new CatalogPetPalette(event.getParser().productCode, event.getParser().palettes.slice()),
|
||||
enabled: (options.enabled ?? true) && !!breed,
|
||||
staleTime: Infinity
|
||||
});
|
||||
Reference in New Issue
Block a user