Merge pull request #70 from duckietm/Dev

Dev
This commit is contained in:
DuckieTM
2026-04-01 17:12:28 +02:00
committed by GitHub
7 changed files with 52 additions and 44 deletions
+19 -24
View File
@@ -150,39 +150,34 @@ export class AvatarEditorThumbnailsHelper
if(cached) return cached; if(cached) return cached;
const avatarImage = GetAvatarRenderManager().createAvatarImage(figureString, AvatarScaleType.LARGE, null, null); return new Promise(async (resolve, reject) =>
if(avatarImage.isPlaceholder())
{ {
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) if(isDisabled) sprite.filters = [ AvatarEditorThumbnailsHelper.ALPHA_FILTER ];
{
avatarImage.dispose();
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({ resolve(imageUrl);
target: sprite, };
frame: new NitroRectangle(0, 0, texture.width, texture.height)
resetFigure(figureString);
}); });
sprite.destroy();
avatarImage.dispose();
if(imageUrl) AvatarEditorThumbnailsHelper.THUMBNAIL_CACHE.set(thumbnailKey, imageUrl);
return imageUrl;
} }
private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number private static sortByDrawOrder(a: IFigurePart, b: IFigurePart): number
+5 -1
View File
@@ -13,6 +13,8 @@ export const GetSubscriptionProductIcon = (id: number) =>
export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) => export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId: number) =>
{ {
if(!offerNodes) return [];
const nodes = offerNodes.get(offerId); const nodes = offerNodes.get(offerId);
const allowedNodes: ICatalogNode[] = []; const allowedNodes: ICatalogNode[] = [];
@@ -20,7 +22,7 @@ export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId:
{ {
for(const node of nodes) for(const node of nodes)
{ {
if(!node.isVisible) continue; if(!node || !node.isVisible) continue;
allowedNodes.push(node); allowedNodes.push(node);
} }
@@ -31,6 +33,8 @@ export const GetOfferNodes = (offerNodes: Map<number, ICatalogNode[]>, offerId:
export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) => export const FilterCatalogNode = (search: string, furniLines: string[], node: ICatalogNode, nodes: ICatalogNode[]) =>
{ {
if(!node) return;
if(node.isVisible && (node.pageId > 0)) if(node.isVisible && (node.pageId > 0))
{ {
let nodeAdded = false; let nodeAdded = false;
+2 -2
View File
@@ -105,12 +105,12 @@ export class FurnitureOffer implements IPurchasableOffer
public get localizationName(): string public get localizationName(): string
{ {
return this._furniData.name; return this._furniData?.name ?? '';
} }
public get localizationDescription(): string public get localizationDescription(): string
{ {
return this._furniData.description; return this._furniData?.description ?? '';
} }
public get isLazy(): boolean public get isLazy(): boolean
+10 -13
View File
@@ -21,11 +21,15 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
const [ isReady, setIsReady ] = useState<boolean>(false); const [ isReady, setIsReady ] = useState<boolean>(false);
const [ updateId, setUpdateId ] = useState<number>(0); const [ updateId, setUpdateId ] = useState<number>(0);
const isDisposed = useRef(false); const isDisposed = useRef(false);
const isPlaceholderRef = useRef(false); const figureKeyRef = useRef<string>(null);
useNitroEvent(NitroEventType.AVATAR_ASSET_LOADED, () => useNitroEvent(NitroEventType.AVATAR_ASSET_LOADED, () =>
{ {
if(isPlaceholderRef.current) setUpdateId(prev => prev + 1); if(figureKeyRef.current)
{
AVATAR_IMAGE_CACHE.delete(figureKeyRef.current);
setUpdateId(prev => prev + 1);
}
}); });
const getClassNames = useMemo(() => const getClassNames = useMemo(() =>
@@ -61,9 +65,10 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
const figureKey = [ figure, gender, direction, headOnly ].join('-'); const figureKey = [ figure, gender, direction, headOnly ].join('-');
figureKeyRef.current = figureKey;
if(AVATAR_IMAGE_CACHE.has(figureKey)) if(AVATAR_IMAGE_CACHE.has(figureKey))
{ {
isPlaceholderRef.current = false;
setAvatarUrl(AVATAR_IMAGE_CACHE.get(figureKey)); setAvatarUrl(AVATAR_IMAGE_CACHE.get(figureKey));
} }
else else
@@ -73,7 +78,7 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
{ {
if(isDisposed.current) return; if(isDisposed.current) return;
isPlaceholderRef.current = false; AVATAR_IMAGE_CACHE.delete(figureKey);
setUpdateId(prev => prev + 1); setUpdateId(prev => prev + 1);
}, },
dispose: null, dispose: null,
@@ -90,15 +95,7 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
if(imageUrl && !isDisposed.current) if(imageUrl && !isDisposed.current)
{ {
if(!avatarImage.isPlaceholder()) if(!avatarImage.isPlaceholder()) AVATAR_IMAGE_CACHE.set(figureKey, imageUrl);
{
AVATAR_IMAGE_CACHE.set(figureKey, imageUrl);
isPlaceholderRef.current = false;
}
else
{
isPlaceholderRef.current = true;
}
setAvatarUrl(imageUrl); setAvatarUrl(imageUrl);
} }
@@ -26,7 +26,11 @@ export const AvatarEditorFigureSetItemView: FC<{
useNitroEvent(NitroEventType.AVATAR_ASSET_LOADED, () => useNitroEvent(NitroEventType.AVATAR_ASSET_LOADED, () =>
{ {
if(!assetUrl || !assetUrl.length) setRetryId(prev => prev + 1); if(!assetUrl || !assetUrl.length)
{
AvatarEditorThumbnailsHelper.clearCache();
setRetryId(prev => prev + 1);
}
}); });
useEffect(() => useEffect(() =>
@@ -18,16 +18,18 @@ export const CatalogGridOfferView: FC<CatalogGridOfferViewProps> = props =>
const { requestOfferToMover = null } = useCatalog(); const { requestOfferToMover = null } = useCatalog();
const { isVisible = false } = useInventoryFurni(); const { isVisible = false } = useInventoryFurni();
const { isFavoriteOffer, toggleFavoriteOffer } = useCatalogFavorites(); const { isFavoriteOffer, toggleFavoriteOffer } = useCatalogFavorites();
const isFav = isFavoriteOffer(offer.offerId); const isFav = offer ? isFavoriteOffer(offer.offerId) : false;
const iconUrl = useMemo(() => const iconUrl = useMemo(() =>
{ {
if(!offer) return null;
if(offer.pricingModel === Offer.PRICING_MODEL_BUNDLE) if(offer.pricingModel === Offer.PRICING_MODEL_BUNDLE)
{ {
return null; return null;
} }
return offer.product.getIconUrl(offer); return offer.product?.getIconUrl(offer) ?? null;
}, [ offer ]); }, [ offer ]);
const onMouseEvent = (event: MouseEvent) => const onMouseEvent = (event: MouseEvent) =>
@@ -49,6 +51,8 @@ export const CatalogGridOfferView: FC<CatalogGridOfferViewProps> = props =>
} }
}; };
if(!offer) return null;
const product = offer.product; const product = offer.product;
if(!product) return null; if(!product) return null;
@@ -22,6 +22,8 @@ export const CatalogSearchView: FC<{}> = () =>
const timeout = setTimeout(() => const timeout = setTimeout(() =>
{ {
if(!offersToNodes || !rootNode) return;
const furnitureDatas = GetSessionDataManager().getAllFurnitureData(); const furnitureDatas = GetSessionDataManager().getAllFurnitureData();
if(!furnitureDatas || !furnitureDatas.length) return; if(!furnitureDatas || !furnitureDatas.length) return;
@@ -31,11 +33,13 @@ export const CatalogSearchView: FC<{}> = () =>
for(const furniture of furnitureDatas) for(const furniture of furnitureDatas)
{ {
if(!furniture) continue;
if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue; if((currentType === CatalogType.BUILDER) && !furniture.availableForBuildersClub) continue;
if((currentType === CatalogType.NORMAL) && furniture.excludeDynamic) 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)) if((currentType === CatalogType.BUILDER) && (furniture.purchaseOfferId === -1) && (furniture.rentOfferId === -1))
{ {