diff --git a/src/common/layout/LayoutAvatarImageView.tsx b/src/common/layout/LayoutAvatarImageView.tsx index 2b3b156..89779bb 100644 --- a/src/common/layout/LayoutAvatarImageView.tsx +++ b/src/common/layout/LayoutAvatarImageView.tsx @@ -1,6 +1,7 @@ -import { AvatarScaleType, AvatarSetType, GetAvatarRenderManager } from '@nitrots/nitro-renderer'; +import { AvatarScaleType, AvatarSetType, GetAvatarRenderManager, NitroEventType } from '@nitrots/nitro-renderer'; import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react'; import { Base, BaseProps } from '../Base'; +import { useNitroEvent } from '../../hooks/events'; const AVATAR_IMAGE_CACHE: Map = new Map(); @@ -18,7 +19,14 @@ export const LayoutAvatarImageView: FC = props => const { figure = '', gender = '', headOnly = false, direction = 0, scale = 1, classNames = [], style = {}, ...rest } = props; const [ avatarUrl, setAvatarUrl ] = useState(null); const [ isReady, setIsReady ] = useState(false); + const [ updateId, setUpdateId ] = useState(0); const isDisposed = useRef(false); + const isPlaceholderRef = useRef(false); + + useNitroEvent(NitroEventType.AVATAR_ASSET_LOADED, () => + { + if(isPlaceholderRef.current) setUpdateId(prev => prev + 1); + }); const getClassNames = useMemo(() => { @@ -55,37 +63,49 @@ export const LayoutAvatarImageView: FC = props => if(AVATAR_IMAGE_CACHE.has(figureKey)) { + isPlaceholderRef.current = false; setAvatarUrl(AVATAR_IMAGE_CACHE.get(figureKey)); } else { - const resetFigure = (_figure: string) => - { - if(isDisposed.current) return; - - const avatarImage = GetAvatarRenderManager().createAvatarImage(_figure, AvatarScaleType.LARGE, gender, { resetFigure: (figure: string) => resetFigure(figure), dispose: null, disposed: false }); - - let setType = AvatarSetType.FULL; - - if(headOnly) setType = AvatarSetType.HEAD; - - avatarImage.setDirection(setType, direction); - - const imageUrl = avatarImage.processAsImageUrl(setType); - - if(imageUrl && !isDisposed.current) + const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, { + resetFigure: (figure: string) => { - if(!avatarImage.isPlaceholder()) AVATAR_IMAGE_CACHE.set(figureKey, imageUrl); + if(isDisposed.current) return; - setAvatarUrl(imageUrl); + isPlaceholderRef.current = false; + setUpdateId(prev => prev + 1); + }, + dispose: null, + disposed: false + }); + + let setType = AvatarSetType.FULL; + + if(headOnly) setType = AvatarSetType.HEAD; + + avatarImage.setDirection(setType, direction); + + const imageUrl = avatarImage.processAsImageUrl(setType); + + if(imageUrl && !isDisposed.current) + { + if(!avatarImage.isPlaceholder()) + { + AVATAR_IMAGE_CACHE.set(figureKey, imageUrl); + isPlaceholderRef.current = false; + } + else + { + isPlaceholderRef.current = true; } - avatarImage.dispose(); - }; + setAvatarUrl(imageUrl); + } - resetFigure(figure); + avatarImage.dispose(); } - }, [ figure, gender, direction, headOnly, isReady ]); + }, [ figure, gender, direction, headOnly, isReady, updateId ]); useEffect(() => {