Update some stuff to use async

This commit is contained in:
Bill 2023-07-11 22:07:45 -04:00
parent f0049d6aa5
commit 3b4c443ea6
20 changed files with 237 additions and 167 deletions

View File

@ -189,7 +189,7 @@ export class AvatarEditorGridPartItem implements IAvatarImageListener
return container;
}
private updateThumbVisualization(): void
private async updateThumbVisualization(): Promise<void>
{
if(!this._isInitalized) return;
@ -212,7 +212,7 @@ export class AvatarEditorGridPartItem implements IAvatarImageListener
if(this._isDisabled) this.setAlpha(container, 0.2);
this._imageUrl = TextureUtils.generateImageUrl(container);
this._imageUrl = await TextureUtils.generateImageUrl(container);
if(this.notify) this.notify();
}

View File

@ -9,7 +9,6 @@ export class AvatarInfoFurni implements IAvatarInfo
public category: number = 0;
public name: string = '';
public description: string = '';
public image: HTMLImageElement = null;
public isWallItem: boolean = false;
public isStickie: boolean = false;
public isRoomOwner: boolean = false;

View File

@ -1,4 +1,4 @@
import { GetTickerTime, IFurnitureData, IRoomModerationSettings, IRoomPetData, IRoomUserData, ObjectDataFactory, PetFigureData, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomTradingLevelEnum, RoomWidgetEnumItemExtradataParameter, Vector3d } from '@nitrots/nitro-renderer';
import { GetTickerTime, IFurnitureData, IRoomModerationSettings, IRoomPetData, IRoomUserData, ObjectDataFactory, PetFigureData, PetType, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomTradingLevelEnum, RoomWidgetEnumItemExtradataParameter } from '@nitrots/nitro-renderer';
import { GetRoomEngine, GetRoomSession, GetSessionDataManager, IsOwnerOfFurniture } from '../../nitro';
import { LocalizeText } from '../../utils';
import { AvatarInfoFurni } from './AvatarInfoFurni';
@ -72,24 +72,20 @@ export class AvatarInfoUtilities
public static getFurniInfo(objectId: number, category: number): AvatarInfoFurni
{
const roomSession = GetRoomSession();
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, objectId, category);
if(!roomObject) return null;
const furniInfo = new AvatarInfoFurni(AvatarInfoFurni.FURNI);
furniInfo.id = objectId;
furniInfo.category = category;
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, objectId, category);
if(!roomObject) return;
const model = roomObject.model;
if(model.getValue<string>(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM))
{
furniInfo.extraParam = model.getValue<string>(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM);
}
if(model.getValue<string>(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM)) furniInfo.extraParam = model.getValue<string>(RoomWidgetEnumItemExtradataParameter.INFOSTAND_EXTRA_PARAM);
const dataFormat = model.getValue<number>(RoomObjectVariable.FURNITURE_DATA_FORMAT);
const objectData = ObjectDataFactory.getData(dataFormat);
const objectData = ObjectDataFactory.getData(model.getValue<number>(RoomObjectVariable.FURNITURE_DATA_FORMAT));
objectData.initializeFromRoomObjectModel(model);
@ -141,14 +137,14 @@ export class AvatarInfoUtilities
furniInfo.expiration = ((expiryTime < 0) ? expiryTime : Math.max(0, (expiryTime - ((GetTickerTime() - expiryTimestamp) / 1000))));
let roomObjectImage = GetRoomEngine().getRoomObjectImage(roomSession.roomId, objectId, category, new Vector3d(180), 64, null);
/* let roomObjectImage = GetRoomEngine().getRoomObjectImage(roomSession.roomId, objectId, category, new Vector3d(180), 64, null);
if(!roomObjectImage.data || (roomObjectImage.data.width > 140) || (roomObjectImage.data.height > 200))
{
roomObjectImage = GetRoomEngine().getRoomObjectImage(roomSession.roomId, objectId, category, new Vector3d(180), 1, null);
}
furniInfo.image = roomObjectImage.getImage();
furniInfo.image = roomObjectImage.getImage(); */
furniInfo.isWallItem = (category === RoomObjectCategory.WALL);
furniInfo.isRoomOwner = roomSession.isRoomOwner;
furniInfo.roomControllerLevel = roomSession.controllerLevel;
@ -159,11 +155,7 @@ export class AvatarInfoUtilities
const guildId = model.getValue<number>(RoomObjectVariable.FURNITURE_GUILD_CUSTOMIZED_GUILD_ID);
if(guildId !== 0)
{
furniInfo.groupId = guildId;
//this.container.connection.send(new GroupInformationComposer(guildId, false));
}
if(guildId !== 0) furniInfo.groupId = guildId;
if(IsOwnerOfFurniture(roomObject)) furniInfo.isOwner = true;
@ -174,11 +166,7 @@ export class AvatarInfoUtilities
{
const roomSession = GetRoomSession();
let userInfoType = AvatarInfoUser.OWN_USER;
if(userData.webID !== GetSessionDataManager().userId) userInfoType = AvatarInfoUser.PEER;
const userInfo = new AvatarInfoUser(userInfoType);
const userInfo = new AvatarInfoUser((userData.webID === GetSessionDataManager().userId) ? AvatarInfoUser.OWN_USER : AvatarInfoUser.PEER);
userInfo.isSpectatorMode = roomSession.isSpectator;
userInfo.name = userData.name;
@ -192,7 +180,7 @@ export class AvatarInfoUtilities
if(roomObject) userInfo.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0);
if(userInfoType === AvatarInfoUser.OWN_USER) userInfo.allowNameChange = GetSessionDataManager().canChangeName;
if(userInfo.type === AvatarInfoUser.OWN_USER) userInfo.allowNameChange = GetSessionDataManager().canChangeName;
userInfo.amIOwner = roomSession.isRoomOwner;
userInfo.isGuildRoom = roomSession.isGuildRoom;
@ -200,14 +188,11 @@ export class AvatarInfoUtilities
userInfo.amIAnyRoomController = GetSessionDataManager().isModerator;
userInfo.isAmbassador = GetSessionDataManager().isAmbassador;
if(userInfoType === AvatarInfoUser.PEER)
if(userInfo.type === AvatarInfoUser.PEER)
{
if(roomObject)
{
const flatControl = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_FLAT_CONTROL);
if(flatControl !== null) userInfo.targetRoomControllerLevel = flatControl;
userInfo.targetRoomControllerLevel = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_FLAT_CONTROL);
userInfo.canBeMuted = this.canBeMuted(userInfo);
userInfo.canBeKicked = this.canBeKicked(userInfo);
userInfo.canBeBanned = this.canBeBanned(userInfo);
@ -234,7 +219,7 @@ export class AvatarInfoUtilities
userInfo.canTrade = (roomController || targetController);
break;
}
case RoomTradingLevelEnum.NO_TRADING:
case RoomTradingLevelEnum.FREE_TRADING:
userInfo.canTrade = true;
break;
default:

View File

@ -0,0 +1,70 @@
import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, PetFigureData, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
import { GetAvatarRenderManager, GetRoomEngine } from '../../nitro';
export class ChatBubbleUtilities
{
public static AVATAR_COLOR_CACHE: Map<string, number> = new Map();
public static AVATAR_IMAGE_CACHE: Map<string, string> = new Map();
public static PET_IMAGE_CACHE: Map<string, string> = new Map();
private static placeHolderImageUrl: string = '';
public static async setFigureImage(figure: string): Promise<string>
{
const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, {
resetFigure: figure => this.setFigureImage(figure),
dispose: () =>
{},
disposed: false
});
if(!avatarImage) return null;
const isPlaceholder = avatarImage.isPlaceholder();
if(isPlaceholder && this.placeHolderImageUrl?.length) return this.placeHolderImageUrl;
figure = avatarImage.getFigure().getFigureString();
const image = await avatarImage.getCroppedImage(AvatarSetType.HEAD);
const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST);
if(isPlaceholder) this.placeHolderImageUrl = image.src;
this.AVATAR_COLOR_CACHE.set(figure, ((color && color.rgb) || 16777215));
this.AVATAR_IMAGE_CACHE.set(figure, image.src);
avatarImage.dispose();
return image.src;
}
public static async getUserImage(figure: string): Promise<string>
{
let existing = this.AVATAR_IMAGE_CACHE.get(figure);
if(!existing) existing = await this.setFigureImage(figure);
return existing;
}
public static async getPetImage(figure: string, direction: number, _arg_3: boolean, scale: number = 64, posture: string = null)
{
let existing = this.PET_IMAGE_CACHE.get((figure + posture));
if(existing) return existing;
const figureData = new PetFigureData(figure);
const typeId = figureData.typeId;
const image = GetRoomEngine().getRoomObjectPetImage(typeId, figureData.paletteId, figureData.color, new Vector3d((direction * 45)), scale, null, false, 0, figureData.customParts, posture);
if(image)
{
existing = await TextureUtils.generateImageUrl(image.data);
this.PET_IMAGE_CACHE.set((figure + posture), existing);
}
return existing;
}
}

View File

@ -6,6 +6,7 @@ export * from './AvatarInfoUser';
export * from './AvatarInfoUtilities';
export * from './BotSkillsEnum';
export * from './ChatBubbleMessage';
export * from './ChatBubbleUtilities';
export * from './ChatMessageTypeEnum';
export * from './DimmerFurnitureWidgetPresetItem';
export * from './DoChatsOverlap';

View File

@ -280,7 +280,8 @@
}
}
.furni-image {
.furni-image,
.room-object-image {
position: relative;
width: 100%;
height: 100%;

View File

@ -68,11 +68,14 @@ export const LayoutAvatarImageView: FC<LayoutAvatarImageViewProps> = props =>
avatarImage.setDirection(setType, direction);
const image = avatarImage.getCroppedImage(setType);
(async () =>
{
const image = await avatarImage.getCroppedImage(setType);
if(image) setAvatarUrl(image.src);
if(image) setAvatarUrl(image.src);
avatarImage.dispose();
avatarImage.dispose();
})();
}, [ figure, gender, direction, headOnly, randomValue ]);
useEffect(() =>

View File

@ -37,7 +37,7 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
if(imageElement)
{
newStyle.backgroundImage = `url(${ (isGroup) ? imageElement.src : GetConfiguration<string>('badge.asset.url').replace('%badgename%', badgeCode.toString())})`;
newStyle.backgroundImage = `url(${ (isGroup) ? imageElement.src : GetConfiguration<string>('badge.asset.url').replace('%badgename%', badgeCode.toString()) })`;
newStyle.width = imageElement.width;
newStyle.height = imageElement.height;
@ -55,7 +55,7 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
return newStyle;
}, [ imageElement, scale, style ]);
}, [ badgeCode, isGroup, imageElement, scale, style ]);
useEffect(() =>
{
@ -63,11 +63,11 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
let didSetBadge = false;
const onBadgeImageReadyEvent = (event: BadgeImageReadyEvent) =>
const onBadgeImageReadyEvent = async (event: BadgeImageReadyEvent) =>
{
if(event.badgeId !== badgeCode) return;
const element = TextureUtils.generateImage(new NitroSprite(event.image));
const element = await TextureUtils.generateImage(new NitroSprite(event.image));
element.onload = () => setImageElement(element);
@ -82,9 +82,12 @@ export const LayoutBadgeImageView: FC<LayoutBadgeImageViewProps> = props =>
if(texture && !didSetBadge)
{
const element = TextureUtils.generateImage(new NitroSprite(texture));
(async () =>
{
const element = await TextureUtils.generateImage(new NitroSprite(texture));
element.onload = () => setImageElement(element);
element.onload = () => setImageElement(element);
})();
}
return () => GetSessionDataManager().events.removeEventListener(BadgeImageReadyEvent.IMAGE_READY, onBadgeImageReadyEvent);

View File

@ -46,15 +46,7 @@ export const LayoutFurniImageView: FC<LayoutFurniImageViewProps> = props =>
let imageResult: ImageResult = null;
const listener: IGetImageListener = {
imageReady: (id, texture, image) =>
{
if(!image && texture)
{
image = TextureUtils.generateImage(texture);
}
image.onload = () => setImageElement(image);
},
imageReady: async (id, texture, image) => setImageElement(await TextureUtils.generateImage(texture)),
imageFailed: null
};
@ -68,12 +60,9 @@ export const LayoutFurniImageView: FC<LayoutFurniImageViewProps> = props =>
break;
}
if(imageResult)
{
const image = imageResult.getImage();
if(!imageResult) return;
image.onload = () => setImageElement(image);
}
(async () => setImageElement(await TextureUtils.generateImage(imageResult.data)))();
}, [ productType, productClassId, direction, extraData ]);
if(!imageElement) return null;

View File

@ -6,7 +6,7 @@ import { DraggableWindow } from '../draggable-window';
interface LayoutMiniCameraViewProps
{
roomId: number;
textureReceiver: (texture: NitroRenderTexture) => void;
textureReceiver: (texture: NitroRenderTexture) => Promise<void>;
onClose: () => void;
}

View File

@ -68,7 +68,7 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
if(petTypeId === 16) petHeadOnly = false;
const imageResult = GetRoomEngine().getRoomObjectPetImage(petTypeId, petPaletteId, petColor1, new Vector3d((direction * 45)), 64, {
imageReady: (id, texture, image) =>
imageReady: async (id, texture, image) =>
{
if(isDisposed.current) return;
@ -81,7 +81,7 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
else if(texture)
{
setPetUrl(TextureUtils.generateImageUrl(texture));
setPetUrl(await TextureUtils.generateImageUrl(texture));
setWidth(texture.width);
setHeight(texture.height);
}
@ -94,14 +94,17 @@ export const LayoutPetImageView: FC<LayoutPetImageViewProps> = props =>
if(imageResult)
{
const image = imageResult.getImage();
if(image)
(async () =>
{
setPetUrl(image.src);
setWidth(image.width);
setHeight(image.height);
}
const image = await imageResult.getImage();
if(image)
{
setPetUrl(image.src);
setWidth(image.width);
setHeight(image.height);
}
})();
}
}, [ figure, typeId, paletteId, petColor, customParts, posture, headOnly, direction ]);

View File

@ -0,0 +1,61 @@
import { TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
import { CSSProperties, FC, useEffect, useMemo, useState } from 'react';
import { BaseProps } from '..';
import { GetRoomEngine } from '../../api';
import { Base } from '../Base';
interface LayoutRoomObjectImageViewProps extends BaseProps<HTMLDivElement>
{
roomId: number;
objectId: number;
category: number;
direction?: number;
scale?: number;
}
export const LayoutRoomObjectImageView: FC<LayoutRoomObjectImageViewProps> = props =>
{
const { roomId = -1, objectId = 1, category = -1, direction = 2, scale = 1, style = {}, ...rest } = props;
const [ imageElement, setImageElement ] = useState<HTMLImageElement>(null);
const getStyle = useMemo(() =>
{
let newStyle: CSSProperties = {};
if(imageElement?.src?.length)
{
newStyle.backgroundImage = `url('${ imageElement.src }')`;
newStyle.width = imageElement.width;
newStyle.height = imageElement.height;
}
if(scale !== 1)
{
newStyle.transform = `scale(${ scale })`;
if(!(scale % 1)) newStyle.imageRendering = 'pixelated';
}
if(Object.keys(style).length) newStyle = { ...newStyle, ...style };
return newStyle;
}, [ imageElement, scale, style ]);
useEffect(() =>
{
const imageResult = GetRoomEngine().getRoomObjectImage(roomId, objectId, category, new Vector3d(direction * 45), 64, {
imageReady: async (id, texture, image) => setImageElement(await TextureUtils.generateImage(texture)),
imageFailed: null
});
// needs (roomObjectImage.data.width > 140) || (roomObjectImage.data.height > 200) scale 1
if(!imageResult) return;
(async () => setImageElement(await TextureUtils.generateImage(imageResult.data)))();
}, [ roomId, objectId, category, direction, scale ]);
if(!imageElement) return null;
return <Base classNames={ [ 'furni-image' ] } style={ getStyle } { ...rest } />;
}

View File

@ -26,7 +26,7 @@ export const LayoutRoomPreviewerView: FC<LayoutRoomPreviewerViewProps> = props =
{
if(!roomPreviewer) return;
const update = (time: number) =>
const update = async (time: number) =>
{
if(!roomPreviewer || !renderingCanvas || !elementRef.current) return;
@ -34,7 +34,7 @@ export const LayoutRoomPreviewerView: FC<LayoutRoomPreviewerViewProps> = props =
if(!renderingCanvas.canvasUpdated) return;
elementRef.current.style.backgroundImage = `url(${ TextureUtils.generateImageUrl(renderingCanvas.master) })`;
elementRef.current.style.backgroundImage = `url(${ await TextureUtils.generateImageUrl(renderingCanvas.master) })`;
}
if(!renderingCanvas)

View File

@ -16,8 +16,9 @@ export * from './LayoutNotificationBubbleView';
export * from './LayoutPetImageView';
export * from './LayoutProgressBar';
export * from './LayoutRarityLevelView';
export * from './LayoutRoomObjectImageView';
export * from './LayoutRoomPreviewerView';
export * from './LayoutRoomThumbnailView';
export * from './LayoutTrophyView';
export * from './limited-edition';
export * from './UserProfileIconView';
export * from './limited-edition';

View File

@ -32,7 +32,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
return new NitroRectangle(Math.floor(frameBounds.x), Math.floor(frameBounds.y), Math.floor(frameBounds.width), Math.floor(frameBounds.height));
}
const takePicture = () =>
const takePicture = async () =>
{
if(selectedPictureIndex > -1)
{
@ -52,7 +52,7 @@ export const CameraWidgetCaptureView: FC<CameraWidgetCaptureViewProps> = props =
}
PlaySound(SoundNames.CAMERA_SHUTTER);
clone.push(new CameraPicture(texture, TextureUtils.generateImageUrl(texture)));
clone.push(new CameraPicture(texture, await TextureUtils.generateImageUrl(texture)));
setCameraRoll(clone);
}

View File

@ -26,6 +26,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
const [ selectedEffects, setSelectedEffects ] = useState<IRoomCameraWidgetSelectedEffect[]>([]);
const [ effectsThumbnails, setEffectsThumbnails ] = useState<CameraPictureThumbnail[]>([]);
const [ isZoomed, setIsZoomed ] = useState(false);
const [ currentPictureUrl, setCurrentPictureUrl ] = useState<string>('');
const getColorMatrixEffects = useMemo(() =>
{
@ -83,11 +84,6 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
});
}, [ getCurrentEffectIndex, setSelectedEffects ]);
const getCurrentPictureUrl = useMemo(() =>
{
return GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed).src;
}, [ picture, selectedEffects, isZoomed ]);
const processAction = useCallback((type: string, effectName: string = null) =>
{
switch(type)
@ -99,7 +95,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
onCancel();
return;
case 'checkout':
onCheckout(getCurrentPictureUrl);
onCheckout(currentPictureUrl);
return;
case 'change_tab':
setCurrentTab(String(effectName));
@ -143,32 +139,50 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
setSelectedEffects([]);
return;
case 'download': {
const image = new Image();
(async () =>
{
const image = new Image();
image.src = getCurrentPictureUrl
const newWindow = window.open('');
newWindow.document.write(image.outerHTML);
image.src = currentPictureUrl
const newWindow = window.open('');
newWindow.document.write(image.outerHTML);
})();
return;
}
case 'zoom':
setIsZoomed(!isZoomed);
return;
}
}, [ isZoomed, availableEffects, selectedEffectName, getCurrentPictureUrl, getSelectedEffectIndex, onCancel, onCheckout, onClose, setIsZoomed, setSelectedEffects ]);
}, [ isZoomed, availableEffects, selectedEffectName, currentPictureUrl, getSelectedEffectIndex, onCancel, onCheckout, onClose, setIsZoomed, setSelectedEffects ]);
useEffect(() =>
{
const thumbnails: CameraPictureThumbnail[] = [];
for(const effect of availableEffects)
(async () =>
{
thumbnails.push(new CameraPictureThumbnail(effect.name, GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false).src));
}
const thumbnails: CameraPictureThumbnail[] = [];
for await (const effect of availableEffects)
{
const image = await GetRoomCameraWidgetManager().applyEffects(picture.texture, [ new RoomCameraWidgetSelectedEffect(effect, 1) ], false);
setEffectsThumbnails(thumbnails);
thumbnails.push(new CameraPictureThumbnail(effect.name, image.src));
}
setEffectsThumbnails(thumbnails);
})();
}, [ picture, availableEffects ]);
useEffect(() =>
{
(async () =>
{
const imageUrl = await GetRoomCameraWidgetManager().applyEffects(picture.texture, selectedEffects, isZoomed);
setCurrentPictureUrl(imageUrl.src);
})();
}, [ picture, selectedEffects, isZoomed ]);
return (
<NitroCardView className="nitro-camera-editor">
<NitroCardHeaderView headerText={ LocalizeText('camera.editor.button.text') } onCloseClick={ event => processAction('close') } />
@ -185,7 +199,7 @@ export const CameraWidgetEditorView: FC<CameraWidgetEditorViewProps> = props =>
</Column>
<Column size={ 7 } justifyContent="between" overflow="hidden">
<Column center>
<LayoutImage imageUrl={ getCurrentPictureUrl } className="picture-preview" />
<LayoutImage imageUrl={ currentPictureUrl } className="picture-preview" />
{ selectedEffectName &&
<Column center fullWidth gap={ 1 }>
<Text>{ LocalizeText('camera.effect.name.' + selectedEffectName) }</Text>

View File

@ -2,7 +2,7 @@ import { CrackableDataType, GroupInformationComposer, GroupInformationEvent, Now
import { FC, useCallback, useEffect, useState } from 'react';
import { FaTimes } from 'react-icons/fa';
import { AvatarInfoFurni, CreateLinkEvent, GetGroupInformation, GetNitroInstance, GetRoomEngine, LocalizeText, SendMessageComposer } from '../../../../../api';
import { Base, Button, Column, Flex, LayoutBadgeImageView, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, Text, UserProfileIconView } from '../../../../../common';
import { Base, Button, Column, Flex, LayoutBadgeImageView, LayoutLimitedEditionCompactPlateView, LayoutRarityLevelView, LayoutRoomObjectImageView, Text, UserProfileIconView } from '../../../../../common';
import { useMessageEvent, useRoom, useSoundEvent } from '../../../../../hooks';
interface InfoStandWidgetFurniViewProps
@ -347,8 +347,9 @@ export const InfoStandWidgetFurniView: FC<InfoStandWidgetFurniViewProps> = props
<div className="position-absolute end-0">
<LayoutRarityLevelView level={ avatarInfo.stuffData.rarityLevel } />
</div> }
{ avatarInfo.image && avatarInfo.image.src.length &&
<img className="d-block mx-auto" src={ avatarInfo.image.src } alt="" /> }
<Flex fullWidth center>
<LayoutRoomObjectImageView roomId={ roomSession.roomId } objectId={ avatarInfo.id } category={ avatarInfo.category } />
</Flex>
</Flex>
<hr className="m-0" />
</Column>

View File

@ -29,9 +29,9 @@ export const RoomThumbnailWidgetView: FC<{}> = props =>
}
});
const receiveTexture = (texture: NitroRenderTexture) =>
const receiveTexture = async (texture: NitroRenderTexture) =>
{
GetRoomEngine().saveTextureAsScreenshot(texture, true);
await GetRoomEngine().saveTextureAsScreenshot(texture, true);
setIsVisible(false);
}

View File

@ -258,7 +258,7 @@ const useNotificationState = () =>
simpleAlert( LocalizeText(('opening.hours.' + (parser.userThrowOutAtClose ? 'disconnected' : 'closed')), [ 'h', 'm' ], [ getTimeZeroPadded(parser.openHour), getTimeZeroPadded(parser.openMinute) ]), NotificationAlertType.DEFAULT, null, null, LocalizeText('opening.hours.title'));
});
useMessageEvent<PetReceivedMessageEvent>(PetReceivedMessageEvent, event =>
useMessageEvent<PetReceivedMessageEvent>(PetReceivedMessageEvent, async event =>
{
const parser = event.getParser();
@ -268,7 +268,7 @@ const useNotificationState = () =>
const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.pet.typeId, parser.pet.paletteId, parseInt(parser.pet.color, 16), new Vector3d(45 * 3), 64, null, true);
if(imageResult) imageUrl = imageResult.getImage().src;
if(imageResult) imageUrl = (await imageResult.getImage())?.src;
showSingleBubble(text, NotificationBubbleType.PETLEVEL, imageUrl);
});
@ -284,7 +284,7 @@ const useNotificationState = () =>
setAlerts(prevValue => [ alertItem, ...prevValue ]);
});
useMessageEvent<PetLevelNotificationEvent>(PetLevelNotificationEvent, event =>
useMessageEvent<PetLevelNotificationEvent>(PetLevelNotificationEvent, async event =>
{
const parser = event.getParser();
@ -292,7 +292,7 @@ const useNotificationState = () =>
const imageResult = GetRoomEngine().getRoomObjectPetImage(parser.figureData.typeId, parser.figureData.paletteId, parseInt(parser.figureData.color, 16), new Vector3d(45 * 3), 64, null, true);
if(imageResult) imageUrl = imageResult.getImage().src;
if(imageResult) imageUrl = (await imageResult.getImage())?.src;
showSingleBubble(LocalizeText('notifications.text.petlevel', [ 'pet_name', 'level' ], [ parser.petName, parser.level.toString() ]), NotificationBubbleType.PETLEVEL, imageUrl);
});

View File

@ -1,14 +1,10 @@
import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, GetGuestRoomResultEvent, NitroPoint, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
import { GetGuestRoomResultEvent, NitroPoint, PetFigureData, RoomChatSettings, RoomChatSettingsEvent, RoomDragEvent, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, RoomUserData, SystemChatStyleEnum } from '@nitrots/nitro-renderer';
import { useEffect, useMemo, useRef, useState } from 'react';
import { ChatBubbleMessage, ChatEntryType, ChatHistoryCurrentDate, GetAvatarRenderManager, GetConfiguration, GetRoomEngine, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api';
import { ChatBubbleMessage, ChatBubbleUtilities, ChatEntryType, ChatHistoryCurrentDate, GetConfiguration, GetRoomEngine, GetRoomObjectScreenLocation, IRoomChatSettings, LocalizeText, PlaySound, RoomChatFormatter } from '../../../api';
import { useMessageEvent, useRoomEngineEvent, useRoomSessionManagerEvent } from '../../events';
import { useRoom } from '../useRoom';
import { useChatHistory } from './../../chat-history';
const avatarColorCache: Map<string, number> = new Map();
const avatarImageCache: Map<string, string> = new Map();
const petImageCache: Map<string, string> = new Map();
const useChatWidgetState = () =>
{
const [ chatMessages, setChatMessages ] = useState<ChatBubbleMessage[]>([]);
@ -38,64 +34,7 @@ const useChatWidgetState = () =>
}
}, [ chatSettings ]);
const setFigureImage = (figure: string) =>
{
const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, {
resetFigure: figure =>
{
if(isDisposed.current) return;
setFigureImage(figure);
},
dispose: () =>
{},
disposed: false
});
if(!avatarImage) return;
const image = avatarImage.getCroppedImage(AvatarSetType.HEAD);
const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST);
avatarColorCache.set(figure, ((color && color.rgb) || 16777215));
avatarImage.dispose();
avatarImageCache.set(figure, image.src);
return image.src;
}
const getUserImage = (figure: string) =>
{
let existing = avatarImageCache.get(figure);
if(!existing) existing = setFigureImage(figure);
return existing;
}
const getPetImage = (figure: string, direction: number, _arg_3: boolean, scale: number = 64, posture: string = null) =>
{
let existing = petImageCache.get((figure + posture));
if(existing) return existing;
const figureData = new PetFigureData(figure);
const typeId = figureData.typeId;
const image = GetRoomEngine().getRoomObjectPetImage(typeId, figureData.paletteId, figureData.color, new Vector3d((direction * 45)), scale, null, false, 0, figureData.customParts, posture);
if(image)
{
existing = TextureUtils.generateImageUrl(image.data);
petImageCache.set((figure + posture), existing);
}
return existing;
}
useRoomSessionManagerEvent<RoomSessionChatEvent>(RoomSessionChatEvent.CHAT_EVENT, event =>
useRoomSessionManagerEvent<RoomSessionChatEvent>(RoomSessionChatEvent.CHAT_EVENT, async event =>
{
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, RoomObjectCategory.UNIT);
const bubbleLocation = roomObject ? GetRoomObjectScreenLocation(roomSession.roomId, roomObject?.id, RoomObjectCategory.UNIT) : new NitroPoint();
@ -119,11 +58,11 @@ const useChatWidgetState = () =>
switch(userType)
{
case RoomObjectType.PET:
imageUrl = getPetImage(figure, 2, true, 64, roomObject.model.getValue<string>(RoomObjectVariable.FIGURE_POSTURE));
imageUrl = await ChatBubbleUtilities.getPetImage(figure, 2, true, 64, roomObject.model.getValue<string>(RoomObjectVariable.FIGURE_POSTURE));
petType = new PetFigureData(figure).typeId;
break;
case RoomObjectType.USER:
imageUrl = getUserImage(figure);
imageUrl = await ChatBubbleUtilities.getUserImage(figure);
break;
case RoomObjectType.RENTABLE_BOT:
case RoomObjectType.BOT:
@ -131,7 +70,7 @@ const useChatWidgetState = () =>
break;
}
avatarColor = avatarColorCache.get(figure);
avatarColor = ChatBubbleUtilities.AVATAR_COLOR_CACHE.get(figure);
username = userData.name;
}