diff --git a/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts b/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts new file mode 100644 index 00000000..39310a6a --- /dev/null +++ b/src/events/catalog/SetRoomPreviewerStuffDataEvent.ts @@ -0,0 +1,27 @@ +import { CatalogPageMessageOfferData, IObjectData, NitroEvent } from '@nitrots/nitro-renderer'; + +export class SetRoomPreviewerStuffDataEvent extends NitroEvent +{ + public static UPDATE_STUFF_DATA: string = 'SRPSA_UPDATE_STUFF_DATA'; + + private _offer: CatalogPageMessageOfferData; + private _stuffData: IObjectData; + + constructor(offer: CatalogPageMessageOfferData, stuffData: IObjectData) + { + super(SetRoomPreviewerStuffDataEvent.UPDATE_STUFF_DATA); + + this._offer = offer; + this._stuffData = stuffData; + } + + public get offer(): CatalogPageMessageOfferData + { + return this._offer; + } + + public get stuffData(): IObjectData + { + return this._stuffData; + } +} diff --git a/src/events/catalog/index.ts b/src/events/catalog/index.ts index 5986db42..98c4c45a 100644 --- a/src/events/catalog/index.ts +++ b/src/events/catalog/index.ts @@ -3,3 +3,4 @@ export * from './CatalogNameResultEvent'; export * from './CatalogPurchasedEvent'; export * from './CatalogPurchaseFailureEvent'; export * from './CatalogPurchaseSoldOutEvent'; +export * from './SetRoomPreviewerStuffDataEvent'; diff --git a/src/hooks/events/event-dispatcher.base.tsx b/src/hooks/events/event-dispatcher.base.tsx index 61bcc7fd..ed4702d8 100644 --- a/src/hooks/events/event-dispatcher.base.tsx +++ b/src/hooks/events/event-dispatcher.base.tsx @@ -1,9 +1,9 @@ import { IEventDispatcher, NitroEvent } from '@nitrots/nitro-renderer'; import { useEffect } from 'react'; -export function CreateEventDispatcherHook(type: string, eventDispatcher: IEventDispatcher, handler: (event: NitroEvent) => void): void +export const CreateEventDispatcherHook = (type: string, eventDispatcher: IEventDispatcher, handler: (event: NitroEvent) => void) => { - useEffect(() => + return useEffect(() => { eventDispatcher.addEventListener(type, handler); @@ -14,7 +14,7 @@ export function CreateEventDispatcherHook(type: string, eventDispatcher: IEventD }, [ type, eventDispatcher, handler ]); } -export function DispatchEventHook(eventDispatcher: IEventDispatcher, event: NitroEvent): void +export const DispatchEventHook = (eventDispatcher: IEventDispatcher, event: NitroEvent) => { eventDispatcher.dispatchEvent(event); } diff --git a/src/hooks/events/ui/ui-event.tsx b/src/hooks/events/ui/ui-event.tsx index 0d9385ff..99a546e6 100644 --- a/src/hooks/events/ui/ui-event.tsx +++ b/src/hooks/events/ui/ui-event.tsx @@ -3,9 +3,9 @@ import { CreateEventDispatcherHook, DispatchEventHook } from '../event-dispatche const uiEventDispatcher: IEventDispatcher = new EventDispatcher(); -export function useUiEvent(type: string, handler: (event: NitroEvent) => void): void +export const useUiEvent = (type: string, handler: (event: NitroEvent) => void) => { - CreateEventDispatcherHook(type, uiEventDispatcher, handler); + return CreateEventDispatcherHook(type, uiEventDispatcher, handler); } export function dispatchUiEvent(event: NitroEvent): void diff --git a/src/views/catalog/views/page/CatalogPageView.tsx b/src/views/catalog/views/page/CatalogPageView.tsx index 6d95c293..fe1e45fe 100644 --- a/src/views/catalog/views/page/CatalogPageView.tsx +++ b/src/views/catalog/views/page/CatalogPageView.tsx @@ -1,6 +1,8 @@ -import { Vector3d } from '@nitrots/nitro-renderer'; -import { FC, useEffect } from 'react'; +import { CatalogPageMessageOfferData, IObjectData, Vector3d } from '@nitrots/nitro-renderer'; +import { FC, useCallback, useEffect, useState } from 'react'; import { GetAvatarRenderManager, GetFurnitureDataForProductOffer, GetSessionDataManager } from '../../../../api'; +import { SetRoomPreviewerStuffDataEvent } from '../../../../events'; +import { useUiEvent } from '../../../../hooks'; import { FurniCategory } from '../../common/FurniCategory'; import { ProductTypeEnum } from '../../common/ProductTypeEnum'; import { useCatalogContext } from '../../context/CatalogContext'; @@ -11,90 +13,99 @@ import { CatalogLayoutSearchResultView } from './search-result/CatalogLayoutSear export const CatalogPageView: FC = props => { const { roomPreviewer = null } = props; + const [ lastOffer, setLastOffer ] = useState(null); const { catalogState = null } = useCatalogContext(); const { pageParser = null, activeOffer = null, searchResult = null } = catalogState; - useEffect(() => + const updatePreviewerForOffer = useCallback((offer: CatalogPageMessageOfferData, stuffData: IObjectData = null) => { - if(!roomPreviewer) return; + if(!offer || !roomPreviewer) return; - roomPreviewer && roomPreviewer.reset(false); + const product = offer.products[0]; + const furniData = GetFurnitureDataForProductOffer(product); - if(activeOffer && activeOffer.products.length) + if(!furniData && (product.productType !== ProductTypeEnum.ROBOT)) return; + + switch(product.productType) { - const product = activeOffer.products[0]; + case ProductTypeEnum.ROBOT: { + roomPreviewer.updateObjectRoom('default', 'default', 'default'); + const figure = GetAvatarRenderManager().getFigureStringWithFigureIds(product.extraParam, 'm', []); - if(!product) return; - - const furniData = GetFurnitureDataForProductOffer(product); + roomPreviewer.addAvatarIntoRoom(figure, 0); - if(!furniData && (product.productType !== ProductTypeEnum.ROBOT)) return; + return; + } + case ProductTypeEnum.FLOOR: { + roomPreviewer.updateObjectRoom('default', 'default', 'default'); - switch(product.productType) - { - case ProductTypeEnum.ROBOT: { - roomPreviewer.updateObjectRoom('default', 'default', 'default'); - const figure = GetAvatarRenderManager().getFigureStringWithFigureIds(product.extraParam, 'm', []); + if(furniData.specialType === FurniCategory.FIGURE_PURCHASABLE_SET) + { + const setIds: number[] = []; + const sets = furniData.customParams.split(','); + + for(const set of sets) + { + const setId = parseInt(set); + + if(GetAvatarRenderManager().isValidFigureSetForGender(setId, GetSessionDataManager().gender)) setIds.push(setId); + } + + const figure = GetAvatarRenderManager().getFigureStringWithFigureIds(GetSessionDataManager().figure, GetSessionDataManager().gender, setIds); roomPreviewer.addAvatarIntoRoom(figure, 0); - - return; } - case ProductTypeEnum.FLOOR: { - roomPreviewer.updateObjectRoom('default', 'default', 'default'); - - if(furniData.specialType === FurniCategory.FIGURE_PURCHASABLE_SET) - { - const setIds: number[] = []; - const sets = furniData.customParams.split(','); - - for(const set of sets) - { - const setId = parseInt(set); - - if(GetAvatarRenderManager().isValidFigureSetForGender(setId, GetSessionDataManager().gender)) setIds.push(setId); - } - - const figure = GetAvatarRenderManager().getFigureStringWithFigureIds(GetSessionDataManager().figure, GetSessionDataManager().gender, setIds); - - roomPreviewer.addAvatarIntoRoom(figure, 0); - } - else - { - roomPreviewer.addFurnitureIntoRoom(product.furniClassId, new Vector3d(90)); - } - return; + else + { + roomPreviewer.addFurnitureIntoRoom(product.furniClassId, new Vector3d(90), stuffData); + } + return; + } + case ProductTypeEnum.WALL: { + switch(furniData.className) + { + case 'floor': + roomPreviewer.reset(false); + roomPreviewer.updateObjectRoom(product.extraParam); + break; + case 'wallpaper': + roomPreviewer.reset(false); + roomPreviewer.updateObjectRoom(null, product.extraParam); + break; + case 'landscape': + roomPreviewer.reset(false); + roomPreviewer.updateObjectRoom(null, null, product.extraParam); + break; + default: + roomPreviewer.updateObjectRoom('default', 'default', 'default'); + roomPreviewer.addWallItemIntoRoom(product.furniClassId, new Vector3d(90), product.extraParam); + return; } - case ProductTypeEnum.WALL: - switch(furniData.className) - { - case 'floor': - roomPreviewer.reset(false); - roomPreviewer.updateObjectRoom(product.extraParam); - break; - case 'wallpaper': - roomPreviewer.reset(false); - roomPreviewer.updateObjectRoom(null, product.extraParam); - break; - case 'landscape': - roomPreviewer.reset(false); - roomPreviewer.updateObjectRoom(null, null, product.extraParam); - break; - default: - roomPreviewer.updateObjectRoom('default', 'default', 'default'); - roomPreviewer.addWallItemIntoRoom(product.furniClassId, new Vector3d(90), product.extraParam); - return; - } + const windowData = GetSessionDataManager().getWallItemDataByName('noob_window_double'); - const windowData = GetSessionDataManager().getWallItemDataByName('noob_window_double'); + if(windowData) roomPreviewer.addWallItemIntoRoom(windowData.id, new Vector3d(90, 0, 0), windowData.customParams); - if(windowData) roomPreviewer.addWallItemIntoRoom(windowData.id, new Vector3d(90, 0, 0), windowData.customParams); - - return; + return; } } - }, [ roomPreviewer, activeOffer ]); + }, [ roomPreviewer ]); + + const onSetRoomPreviewerStuffDataEvent = useCallback((event: SetRoomPreviewerStuffDataEvent) => + { + if(roomPreviewer) roomPreviewer.reset(false); + + updatePreviewerForOffer(event.offer, event.stuffData); + }, [ roomPreviewer, updatePreviewerForOffer ]); + + useUiEvent(SetRoomPreviewerStuffDataEvent.UPDATE_STUFF_DATA, onSetRoomPreviewerStuffDataEvent); + + useEffect(() => + { + if(!activeOffer) return; + + updatePreviewerForOffer(activeOffer); + }, [ activeOffer, updatePreviewerForOffer ]); if(searchResult && searchResult.furniture) { diff --git a/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx b/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx index 5fe3149b..b36ce01b 100644 --- a/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx +++ b/src/views/catalog/views/page/layout/badge-display/CatalogLayoutBadgeDisplayView.tsx @@ -1,7 +1,7 @@ import { StringDataType } from '@nitrots/nitro-renderer'; import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { LocalizeText } from '../../../../../../api'; -import { InventoryBadgesUpdatedEvent } from '../../../../../../events'; +import { InventoryBadgesUpdatedEvent, SetRoomPreviewerStuffDataEvent } from '../../../../../../events'; import { InventoryBadgesRequestEvent } from '../../../../../../events/inventory/InventoryBadgesRequestEvent'; import { dispatchUiEvent, useUiEvent } from '../../../../../../hooks'; import { NitroCardGridItemView } from '../../../../../../layout/card/grid/item/NitroCardGridItemView'; @@ -53,11 +53,19 @@ export const CatalogLayoutBadgeDisplayView: FC = props => { const { roomPreviewer = null, pageParser = null } = props; - + const [ selectedGroupIndex, setSelectedGroupIndex ] = useState(0); const { catalogState = null } = useCatalogContext(); const { activeOffer = null, groups = null } = catalogState; - const product = ((activeOffer && activeOffer.products[0]) || null); - - const [ selectedGroupIndex, setSelectedGroupIndex ] = useState(0); - useEffect(() => { SendMessageHook(new CatalogGroupsComposer()); @@ -28,7 +26,7 @@ export const CatalogLayouGuildCustomFurniView: FC { - if(!groups[selectedGroupIndex]) return; + if(!activeOffer || !groups[selectedGroupIndex]) return; const productData = []; productData.push('0'); @@ -40,10 +38,12 @@ export const CatalogLayouGuildCustomFurniView: FC