diff --git a/src/api/catalog/ICatalogOptions.ts b/src/api/catalog/ICatalogOptions.ts index e8676e5..9aeec55 100644 --- a/src/api/catalog/ICatalogOptions.ts +++ b/src/api/catalog/ICatalogOptions.ts @@ -1,6 +1,5 @@ import { ClubGiftInfoParser, ClubOfferData, HabboGroupEntryData, MarketplaceConfigurationMessageParser } from '@nitrots/nitro-renderer'; import { CatalogPetPalette } from './CatalogPetPalette'; -import { GiftWrappingConfiguration } from './GiftWrappingConfiguration'; export interface ICatalogOptions { @@ -9,6 +8,5 @@ export interface ICatalogOptions clubOffers?: ClubOfferData[]; clubOffersByWindowId?: Record; clubGifts?: ClubGiftInfoParser; - giftConfiguration?: GiftWrappingConfiguration; marketplaceConfiguration?: MarketplaceConfigurationMessageParser; } diff --git a/src/components/catalog/views/gift/CatalogGiftView.tsx b/src/components/catalog/views/gift/CatalogGiftView.tsx index a6ab7bb..34d94a4 100644 --- a/src/components/catalog/views/gift/CatalogGiftView.tsx +++ b/src/components/catalog/views/gift/CatalogGiftView.tsx @@ -4,7 +4,7 @@ import { FaChevronLeft, FaChevronRight } from 'react-icons/fa'; import { ColorUtils, LocalizeText, MessengerFriend, ProductTypeEnum, SendMessageComposer } from '../../../../api'; import { Button, Column, Flex, FormGroup, LayoutCurrencyIcon, LayoutFurniImageView, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { CatalogEvent, CatalogInitGiftEvent, CatalogPurchasedEvent } from '../../../../events'; -import { useCatalog, useFriends, useMessageEvent, useUiEvent } from '../../../../hooks'; +import { useFriends, useGiftConfiguration, useMessageEvent, useUiEvent } from '../../../../hooks'; import { classNames } from '../../../../layout'; let isBuyingGift = false; @@ -25,9 +25,8 @@ export const CatalogGiftView: FC<{}> = props => const [ maxBoxIndex, setMaxBoxIndex ] = useState(0); const [ maxRibbonIndex, setMaxRibbonIndex ] = useState(0); const [ receiverNotFound, setReceiverNotFound ] = useState(false); - const { catalogOptions = null } = useCatalog(); const { friends } = useFriends(); - const { giftConfiguration = null } = catalogOptions; + const { data: giftConfiguration = null } = useGiftConfiguration(); const [ boxTypes, setBoxTypes ] = useState([]); const [ suggestions, setSuggestions ] = useState([]); const [ isAutocompleteVisible, setIsAutocompleteVisible ] = useState(true); diff --git a/src/hooks/catalog/index.ts b/src/hooks/catalog/index.ts index e12e2da..da4144f 100644 --- a/src/hooks/catalog/index.ts +++ b/src/hooks/catalog/index.ts @@ -2,3 +2,4 @@ export * from './useCatalog'; export * from './useCatalogFavorites'; export * from './useCatalogPlaceMultipleItems'; export * from './useCatalogSkipPurchaseConfirmation'; +export * from './useGiftConfiguration'; diff --git a/src/hooks/catalog/useCatalog.ts b/src/hooks/catalog/useCatalog.ts index 09820ad..1eecbb1 100644 --- a/src/hooks/catalog/useCatalog.ts +++ b/src/hooks/catalog/useCatalog.ts @@ -1,7 +1,7 @@ -import { BuildersClubFurniCountMessageEvent, BuildersClubPlaceRoomItemMessageComposer, BuildersClubPlaceWallItemMessageComposer, BuildersClubQueryFurniCountMessageComposer, BuildersClubSubscriptionStatusMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, ClubGiftInfoEvent, CreateLinkEvent, FrontPageItem, FurniturePlaceComposer, FurniturePlacePaintComposer, GetCatalogIndexComposer, GetCatalogPageComposer, GetClubGiftInfo, GetGiftWrappingConfigurationComposer, GetRoomEngine, GetSessionDataManager, GetTickerTime, GiftWrappingConfigurationEvent, GuildMembershipsMessageEvent, HabboClubOffersMessageEvent, 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, GuildMembershipsMessageEvent, HabboClubOffersMessageEvent, LegacyDataType, LimitedEditionSoldOutEvent, MarketplaceMakeOfferResult, NodeData, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseFromCatalogComposer, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, RoomControllerLevel, RoomEngineObjectPlacedEvent, RoomObjectCategory, RoomObjectPlacementSource, RoomObjectType, RoomObjectVariable, RoomPreviewer, SellablePetPalettesMessageEvent, 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, GiftWrappingConfiguration, 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, 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 { CatalogPurchaseFailureEvent, CatalogPurchaseNotAllowedEvent, CatalogPurchaseSoldOutEvent, CatalogPurchasedEvent, InventoryFurniAddedEvent } from '../../events'; import { useMessageEvent, useNitroEvent, useUiEvent } from '../events'; import { useNotification } from '../notification'; @@ -768,18 +768,6 @@ const useCatalogState = () => }); }); - useMessageEvent(GiftWrappingConfigurationEvent, event => - { - const parser = event.getParser(); - - setCatalogOptions(prevValue => - { - const giftConfiguration = new GiftWrappingConfiguration(parser); - - return { ...prevValue, giftConfiguration }; - }); - }); - useMessageEvent(MarketplaceMakeOfferResult, event => { const parser = event.getParser(); @@ -1108,7 +1096,6 @@ const useCatalogState = () => { if(!isVisible || rootNode) return; - SendMessageComposer(new GetGiftWrappingConfigurationComposer()); SendMessageComposer(new GetClubGiftInfo()); SendMessageComposer(new GetCatalogIndexComposer(currentType)); SendMessageComposer(new BuildersClubQueryFurniCountMessageComposer()); diff --git a/src/hooks/catalog/useGiftConfiguration.ts b/src/hooks/catalog/useGiftConfiguration.ts new file mode 100644 index 0000000..0462d40 --- /dev/null +++ b/src/hooks/catalog/useGiftConfiguration.ts @@ -0,0 +1,29 @@ +import { GetGiftWrappingConfigurationComposer, GiftWrappingConfigurationEvent } from '@nitrots/nitro-renderer'; +import { UseQueryResult } from '@tanstack/react-query'; +import { GiftWrappingConfiguration } from '../../api'; +import { useNitroQuery } from '../../api/nitro-query'; + +/** + * Wraps the GetGiftWrappingConfigurationComposer / GiftWrappingConfigurationEvent + * request-response pair as a TanStack query. The configuration is + * session-stable (box types, ribbon types, colour palette) so the data + * is cached with `staleTime: Infinity` — the server is asked at most + * once per session. + * + * Replaces the previous pattern in useCatalog where the composer was + * dispatched eagerly inside an `isVisible` effect and the result was + * stored in `catalogOptions.giftConfiguration`. Consumers now read the + * query directly and benefit from the standard TanStack loading/error + * states. + */ +export const useGiftConfiguration = ( + options: { enabled?: boolean } = {} +): UseQueryResult => + useNitroQuery({ + key: [ 'nitro', 'catalog', 'giftConfiguration' ], + request: () => new GetGiftWrappingConfigurationComposer(), + parser: GiftWrappingConfigurationEvent, + select: event => new GiftWrappingConfiguration(event.getParser()), + enabled: options.enabled, + staleTime: Infinity + });