Fix memory leak with avatar image

This commit is contained in:
billsonnn 2024-03-26 19:49:08 -04:00
parent 98b3bcc9d4
commit 0322c169ac
2 changed files with 31 additions and 30 deletions

View File

@ -25,17 +25,17 @@ export class ChatBubbleUtilities
figure = avatarImage.getFigure().getFigureString(); figure = avatarImage.getFigure().getFigureString();
const image = await avatarImage.getCroppedImage(AvatarSetType.HEAD); const imageUrl = await avatarImage.getCroppedImageUrl(AvatarSetType.HEAD);
const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST); const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST);
if(isPlaceholder) this.placeHolderImageUrl = image.src; if(isPlaceholder) this.placeHolderImageUrl = imageUrl;
this.AVATAR_COLOR_CACHE.set(figure, ((color && color.rgb) || 16777215)); this.AVATAR_COLOR_CACHE.set(figure, ((color && color.rgb) || 16777215));
this.AVATAR_IMAGE_CACHE.set(figure, image.src); this.AVATAR_IMAGE_CACHE.set(figure, imageUrl);
avatarImage.dispose(); avatarImage.dispose();
return image.src; return imageUrl;
} }
public static async getUserImage(figure: string): Promise<string> public static async getUserImage(figure: string): Promise<string>

View File

@ -15,7 +15,7 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
{ {
const { figure = '', gender = 'M', headOnly = false, direction = 0, scale = 1, classNames = [], style = {}, ...rest } = props; const { figure = '', gender = 'M', headOnly = false, direction = 0, scale = 1, classNames = [], style = {}, ...rest } = props;
const [ avatarUrl, setAvatarUrl ] = useState<string>(null); const [ avatarUrl, setAvatarUrl ] = useState<string>(null);
const [ randomValue, setRandomValue ] = useState(-1); const [ isReady, setIsReady ] = useState<boolean>(false);
const isDisposed = useRef(false); const isDisposed = useRef(false);
const getClassNames = useMemo(() => const getClassNames = useMemo(() =>
@ -47,19 +47,13 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
useEffect(() => useEffect(() =>
{ {
const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, { if(!isReady) return;
resetFigure: figure =>
const resetFigure = (_figure: string) =>
{ {
if(isDisposed.current) return; if(isDisposed.current) return;
setRandomValue(Math.random()); const avatarImage = GetAvatarRenderManager().createAvatarImage(_figure, AvatarScaleType.LARGE, gender, { resetFigure: (figure: string) => resetFigure(figure), dispose: null, disposed: false });
},
dispose: () =>
{},
disposed: false
}, null);
if(!avatarImage) return;
let setType = AvatarSetType.FULL; let setType = AvatarSetType.FULL;
@ -67,20 +61,27 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
avatarImage.setDirection(setType, direction); avatarImage.setDirection(setType, direction);
(async () => const loadImage = async () =>
{ {
const image = await avatarImage.getCroppedImage(setType); const imageUrl = await avatarImage.getCroppedImageUrl(setType);
if(image) setAvatarUrl(image.src); if(imageUrl && !isDisposed.current) setAvatarUrl(imageUrl);
avatarImage.dispose(); avatarImage.dispose();
})(); }
}, [ figure, gender, direction, headOnly, randomValue ]);
loadImage();
}
resetFigure(figure);
}, [ figure, gender, direction, headOnly, isReady ]);
useEffect(() => useEffect(() =>
{ {
isDisposed.current = false; isDisposed.current = false;
setIsReady(true);
return () => return () =>
{ {
isDisposed.current = true; isDisposed.current = true;