nitro-react/src/views/shared/avatar-image/AvatarImageView.tsx

101 lines
2.8 KiB
TypeScript
Raw Normal View History

import { AvatarScaleType, AvatarSetType } from '@nitrots/nitro-renderer';
2021-12-29 17:42:29 +01:00
import { CSSProperties, FC, useEffect, useMemo, useRef, useState } from 'react';
2021-06-23 05:59:02 +02:00
import { GetAvatarRenderManager } from '../../../api';
2021-12-29 17:42:29 +01:00
import { Base, BaseProps } from '../../../common/Base';
export interface AvatarImageViewProps extends BaseProps<HTMLDivElement>
{
figure: string;
gender?: string;
headOnly?: boolean;
direction?: number;
scale?: number;
}
2021-04-14 23:47:12 +02:00
2021-04-29 00:45:38 +02:00
export const AvatarImageView: FC<AvatarImageViewProps> = props =>
2021-04-14 23:47:12 +02:00
{
2021-12-29 17:42:29 +01:00
const { figure = '', gender = 'M', headOnly = false, direction = 0, scale = 1, classNames = [], style = {}, ...rest } = props;
2021-04-29 00:45:38 +02:00
const [ avatarUrl, setAvatarUrl ] = useState<string>(null);
2021-06-29 21:20:12 +02:00
const [ randomValue, setRandomValue ] = useState(-1);
2021-08-15 08:24:10 +02:00
const isDisposed = useRef(false);
2021-04-14 23:47:12 +02:00
2021-12-29 17:42:29 +01:00
const getClassNames = useMemo(() =>
2021-09-22 03:48:00 +02:00
{
2021-12-29 17:42:29 +01:00
const newClassNames: string[] = [ 'avatar-image' ];
switch(scale)
{
case .5:
newClassNames.push('scale-0-5');
break;
case .75:
newClassNames.push('scale-0-75');
break;
case 1.25:
newClassNames.push('scale-1-25');
break;
case 1.50:
newClassNames.push('scale-1-50');
break;
default:
newClassNames.push(`scale-${ scale }`);
break;
}
if(classNames.length) newClassNames.push(...classNames);
2021-09-22 03:48:00 +02:00
2021-12-29 17:42:29 +01:00
return newClassNames;
}, [ scale, classNames ]);
2021-09-22 21:01:56 +02:00
2021-12-29 17:42:29 +01:00
const getStyle = useMemo(() =>
{
let newStyle: CSSProperties = {};
2021-09-22 21:01:56 +02:00
2021-12-29 17:42:29 +01:00
if(avatarUrl && avatarUrl.length) newStyle.backgroundImage = `url('${ avatarUrl }')`;
2021-09-22 21:01:56 +02:00
2021-12-29 17:42:29 +01:00
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
return newStyle;
}, [ avatarUrl, style ]);
2021-09-22 03:48:00 +02:00
2021-06-29 21:20:12 +02:00
useEffect(() =>
2021-04-14 23:47:12 +02:00
{
2021-04-29 00:45:38 +02:00
const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, gender, {
2021-08-16 08:00:31 +02:00
resetFigure: figure =>
2021-08-16 08:39:56 +02:00
{
2021-08-15 08:24:10 +02:00
if(isDisposed.current) return;
setRandomValue(Math.random());
},
2021-04-29 00:45:38 +02:00
dispose: () => {},
disposed: false
}, null);
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
if(!avatarImage) return;
let setType = AvatarSetType.FULL;
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
if(headOnly) setType = AvatarSetType.HEAD;
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
avatarImage.setDirection(setType, direction);
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
const image = avatarImage.getCroppedImage(setType);
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
if(image) setAvatarUrl(image.src);
2021-04-14 23:47:12 +02:00
2021-06-29 21:20:12 +02:00
avatarImage.dispose();
}, [ figure, gender, direction, headOnly, randomValue ]);
2021-04-14 23:47:12 +02:00
2021-08-15 08:24:10 +02:00
useEffect(() =>
{
isDisposed.current = false;
return () =>
{
isDisposed.current = true;
}
}, []);
2021-04-14 23:47:12 +02:00
2021-12-29 17:42:29 +01:00
return <Base classNames={ getClassNames } style={ getStyle } { ...rest } />;
2021-04-14 23:47:12 +02:00
}