From 6ad9a0c7b95905c4ac72d902fef3296fcf8ee3fd Mon Sep 17 00:00:00 2001 From: duckietm Date: Wed, 1 Apr 2026 17:12:09 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=86=99=20Fix=20the=20catalog=20search=20i?= =?UTF-8?q?n=20some=20cases=20it=20will=20give=20a=20black=20screen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../avatar/AvatarEditorThumbnailsHelper.ts | 43 ++++++++----------- src/api/catalog/CatalogUtilities.ts | 6 ++- src/api/catalog/FurnitureOffer.ts | 4 +- .../page/common/CatalogGridOfferView.tsx | 8 +++- .../views/page/common/CatalogSearchView.tsx | 6 ++- 5 files changed, 37 insertions(+), 30 deletions(-) diff --git a/src/api/avatar/AvatarEditorThumbnailsHelper.ts b/src/api/avatar/AvatarEditorThumbnailsHelper.ts index f40483d..bffc418 100644 --- a/src/api/avatar/AvatarEditorThumbnailsHelper.ts +++ b/src/api/avatar/AvatarEditorThumbnailsHelper.ts @@ -150,39 +150,34 @@ export class AvatarEditorThumbnailsHelper if(cached) return cached; - const avatarImage = GetAvatarRenderManager().createAvatarImage(figureString, AvatarScaleType.LARGE, null, null); - - if(avatarImage.isPlaceholder()) + return new Promise(async (resolve, reject) => { - avatarImage.dispose(); + const resetFigure = async (figure: string) => + { + const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, { resetFigure, dispose: null, disposed: false }); - return null; - } + if(avatarImage.isPlaceholder()) return; - const texture = avatarImage.processAsTexture(AvatarSetType.HEAD, false); + const texture = avatarImage.processAsTexture(AvatarSetType.HEAD, false); + const sprite = new NitroSprite(texture); - if(!texture) - { - avatarImage.dispose(); + if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ]; - return null; - } + const imageUrl = await TextureUtils.generateImageUrl({ + target: sprite, + frame: new NitroRectangle(0, 0, texture.width, texture.height) + }); - const sprite = new NitroSprite(texture); + sprite.destroy(); + avatarImage.dispose(); - if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ]; + AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl); - const imageUrl = await TextureUtils.generateImageUrl({ - target: sprite, - frame: new NitroRectangle(0, 0, texture.width, texture.height) + resolve(imageUrl); + }; + + resetFigure(figureString); }); - - sprite.destroy(); - avatarImage.dispose(); - - if(imageUrl) AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl); - - return imageUrl; } private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number diff --git a/src/api/catalog/CatalogUtilities.ts b/src/api/catalog/CatalogUtilities.ts index c2e1d5e..9cb8866 100644 --- a/src/api/catalog/CatalogUtilities.ts +++ b/src/api/catalog/CatalogUtilities.ts @@ -13,6 +13,8 @@ export const GetSubscriptionProductIcon = (id: number) => export const GetOfferNodes = (offerNodes: Map, offerId: number) => { + if(!offerNodes) return []; + const nodes = offerNodes.get(offerId); const allowedNodes: ICatalogNode[] = []; @@ -20,7 +22,7 @@ export const GetOfferNodes = (offerNodes: Map, offerId: { for(const node of nodes) { - if(!node.isVisible) continue; + if(!node || !node.isVisible) continue; allowedNodes.push(node); } @@ -31,6 +33,8 @@ export const GetOfferNodes = (offerNodes: Map, offerId: export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) => { + if(!node) return; + if(node.isVisible && (node.pageId > 0)) { let nodeAdded = false; diff --git a/src/api/catalog/FurnitureOffer.ts b/src/api/catalog/FurnitureOffer.ts index 367f247..5b68c11 100644 --- a/src/api/catalog/FurnitureOffer.ts +++ b/src/api/catalog/FurnitureOffer.ts @@ -105,12 +105,12 @@ export class FurnitureOffer implements IPurchasableOffer public get localizationName(): string { - return this._furniData.name; + return this._furniData?.name ?? ''; } public get localizationDescription(): string { - return this._furniData.description; + return this._furniData?.description ?? ''; } public get isLazy(): boolean diff --git a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx b/src/components/catalog/views/page/common/CatalogGridOfferView.tsx index a3fcedd..fd7bba4 100644 --- a/src/components/catalog/views/page/common/CatalogGridOfferView.tsx +++ b/src/components/catalog/views/page/common/CatalogGridOfferView.tsx @@ -18,16 +18,18 @@ export const CatalogGridOfferView: FC = props => const { requestOfferToMover = null } = useCatalog(); const { isVisible = false } = useInventoryFurni(); const { isFavoriteOffer, toggleFavoriteOffer } = useCatalogFavorites(); - const isFav = isFavoriteOffer(offer.offerId); + const isFav = offer ? isFavoriteOffer(offer.offerId) : false; const iconUrl = useMemo(() => { + if(!offer) return null; + if(offer.pricingModel === Offer.PRICING_MODEL_BUNDLE) { return null; } - return offer.product.getIconUrl(offer); + return offer.product?.getIconUrl(offer) ?? null; }, [ offer ]); const onMouseEvent = (event: MouseEvent) => @@ -49,6 +51,8 @@ export const CatalogGridOfferView: FC = props => } }; + if(!offer) return null; + const product = offer.product; if(!product) return null; diff --git a/src/components/catalog/views/page/common/CatalogSearchView.tsx b/src/components/catalog/views/page/common/CatalogSearchView.tsx index 7cc30c7..295abe3 100644 --- a/src/components/catalog/views/page/common/CatalogSearchView.tsx +++ b/src/components/catalog/views/page/common/CatalogSearchView.tsx @@ -22,6 +22,8 @@ export const CatalogSearchView: FC<{}> = () => const timeout = setTimeout(() => { + if(!offersToNodes || !rootNode) return; + const furnitureDatas = GetSessionDataManager().getAllFurnitureData(); if(!furnitureDatas || !furnitureDatas.length) return; @@ -31,11 +33,13 @@ export const CatalogSearchView: FC<{}> = () => for(const furniture of furnitureDatas) { + if(!furniture) continue; + if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue; if((currentType === CatalogType.NORMAL) && furniture.excludeDynamic) continue; - const searchValues = [ furniture.className, furniture.name, furniture.description ].join(' ').replace(/ /gi, '').toLowerCase(); + const searchValues = [ furniture.className || '', furniture.name || '', furniture.description || '' ].join(' ').replace(/ /gi, '').toLowerCase(); if((currentType === CatalogType.BUILDER) && (furniture.purchaseOfferId === -1) && (furniture.rentOfferId === -1)) {