mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-18 21:36:27 +01:00
Update widgets
This commit is contained in:
parent
61022c16ef
commit
e564cac2fc
@ -15,7 +15,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scale-1-50 {
|
.scale-1-50 {
|
||||||
transform: scale(1.50) translateZ(0);
|
transform: scale(1.5) translateZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
.scale-2 {
|
.scale-2 {
|
||||||
@ -35,7 +35,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
ul {
|
ul {
|
||||||
|
|
||||||
&.columns-3 {
|
&.columns-3 {
|
||||||
display: block;
|
display: block;
|
||||||
columns: 3;
|
columns: 3;
|
||||||
@ -92,7 +91,6 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.striped-children {
|
.striped-children {
|
||||||
|
|
||||||
> :nth-child(1) {
|
> :nth-child(1) {
|
||||||
background-color: $table-striped-bg;
|
background-color: $table-striped-bg;
|
||||||
}
|
}
|
||||||
@ -101,14 +99,14 @@ ul {
|
|||||||
@keyframes bounceIn {
|
@keyframes bounceIn {
|
||||||
0% {
|
0% {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transform: scale(.3);
|
transform: scale(0.3);
|
||||||
}
|
}
|
||||||
50% {
|
50% {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transform: scale(1.1);
|
transform: scale(1.1);
|
||||||
}
|
}
|
||||||
70% {
|
70% {
|
||||||
transform: scale(.9);
|
transform: scale(0.9);
|
||||||
}
|
}
|
||||||
100% {
|
100% {
|
||||||
transform: scale(1);
|
transform: scale(1);
|
||||||
@ -118,3 +116,7 @@ ul {
|
|||||||
.btn {
|
.btn {
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.no-resize {
|
||||||
|
resize: none !important;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,7 @@ export interface BaseProps<T = HTMLElement> extends DetailedHTMLProps<HTMLAttrib
|
|||||||
innerRef?: MutableRefObject<T>;
|
innerRef?: MutableRefObject<T>;
|
||||||
display?: DisplayType;
|
display?: DisplayType;
|
||||||
fit?: boolean;
|
fit?: boolean;
|
||||||
|
fitV?: boolean;
|
||||||
grow?: boolean;
|
grow?: boolean;
|
||||||
shrink?: boolean;
|
shrink?: boolean;
|
||||||
fullWidth?: boolean;
|
fullWidth?: boolean;
|
||||||
@ -21,7 +22,7 @@ export interface BaseProps<T = HTMLElement> extends DetailedHTMLProps<HTMLAttrib
|
|||||||
|
|
||||||
export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
||||||
{
|
{
|
||||||
const { ref = null, innerRef = null, display = null, fit = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, visible = null, textColor = null, classNames = [], className = '', style = {}, ...rest } = props;
|
const { ref = null, innerRef = null, display = null, fit = false, fitV = false, grow = false, shrink = false, fullWidth = false, fullHeight = false, overflow = null, position = null, float = null, pointer = false, visible = null, textColor = null, classNames = [], className = '', style = {}, ...rest } = props;
|
||||||
|
|
||||||
const getClassNames = useMemo(() =>
|
const getClassNames = useMemo(() =>
|
||||||
{
|
{
|
||||||
@ -33,6 +34,8 @@ export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
|||||||
|
|
||||||
if(fit || fullHeight) newClassNames.push('h-100');
|
if(fit || fullHeight) newClassNames.push('h-100');
|
||||||
|
|
||||||
|
if(fitV) newClassNames.push('vw-100', 'vh-100');
|
||||||
|
|
||||||
if(grow) newClassNames.push('flex-grow-1');
|
if(grow) newClassNames.push('flex-grow-1');
|
||||||
|
|
||||||
if(shrink) newClassNames.push('flex-shrink-0');
|
if(shrink) newClassNames.push('flex-shrink-0');
|
||||||
@ -52,7 +55,7 @@ export const Base: FC<BaseProps<HTMLDivElement>> = props =>
|
|||||||
if(classNames.length) newClassNames.push(...classNames);
|
if(classNames.length) newClassNames.push(...classNames);
|
||||||
|
|
||||||
return newClassNames;
|
return newClassNames;
|
||||||
}, [ display, fit, grow, shrink, fullWidth, fullHeight, overflow, position, float, pointer, visible, textColor, classNames ]);
|
}, [ display, fit, fitV, grow, shrink, fullWidth, fullHeight, overflow, position, float, pointer, visible, textColor, classNames ]);
|
||||||
|
|
||||||
const getClassName = useMemo(() =>
|
const getClassName = useMemo(() =>
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@ export interface LayoutImageProps extends DetailedHTMLProps<HTMLAttributes<HTMLI
|
|||||||
|
|
||||||
export const LayoutImage: FC<LayoutImageProps> = props =>
|
export const LayoutImage: FC<LayoutImageProps> = props =>
|
||||||
{
|
{
|
||||||
const { imageUrl = null, ...rest } = props;
|
const { imageUrl = null, className = '', ...rest } = props;
|
||||||
|
|
||||||
return <img src={ imageUrl } alt="" { ...rest } />;
|
return <img src={ imageUrl } className={ 'no-select ' + className } alt="" { ...rest } />;
|
||||||
}
|
}
|
||||||
|
@ -1,150 +1,16 @@
|
|||||||
import { EventDispatcher, IRoomSession, RoomEngineEvent, RoomGeometry, RoomId, RoomSessionEvent, RoomVariableEnum, Vector3d } from '@nitrots/nitro-renderer';
|
import { FC, useEffect, useRef } from 'react';
|
||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { DispatchMouseEvent, DispatchTouchEvent, GetNitroInstance } from '../../api';
|
||||||
import { DispatchMouseEvent, DispatchTouchEvent, FurniChooserWidgetHandler, FurnitureContextMenuWidgetHandler, FurnitureCreditWidgetHandler, FurnitureCustomStackHeightWidgetHandler, FurnitureDimmerWidgetHandler, FurnitureExternalImageWidgetHandler, FurnitureInternalLinkHandler, FurnitureMannequinWidgetHandler, FurniturePresentWidgetHandler, FurnitureRoomLinkHandler, FurnitureYoutubeDisplayWidgetHandler, GetNitroInstance, GetRoomEngine, GetRoomSession, InitializeRoomInstanceRenderingCanvas, IRoomWidgetHandlerManager, PollWidgetHandler, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler, SetActiveRoomId, StartRoomSession, UserChooserWidgetHandler, WordQuizWidgetHandler } from '../../api';
|
|
||||||
import { Base } from '../../common';
|
import { Base } from '../../common';
|
||||||
import { UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../hooks';
|
import { useRoom } from '../../hooks';
|
||||||
import { RoomColorView } from './RoomColorView';
|
import { RoomColorView } from './RoomColorView';
|
||||||
import { RoomContextProvider } from './RoomContext';
|
import { RoomContextProvider } from './RoomContext';
|
||||||
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
||||||
|
|
||||||
export const RoomView: FC<{}> = props =>
|
export const RoomView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
const { roomSession = null, widgetHandler = null, resize = null } = useRoom();
|
||||||
const [ widgetHandler, setWidgetHandler ] = useState<IRoomWidgetHandlerManager>(null);
|
|
||||||
const elementRef = useRef<HTMLDivElement>();
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
|
||||||
{
|
|
||||||
if(RoomId.isRoomPreviewerId(event.roomId)) return;
|
|
||||||
|
|
||||||
const session = GetRoomSession();
|
|
||||||
|
|
||||||
if(!session) return;
|
|
||||||
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomEngineEvent.INITIALIZED:
|
|
||||||
SetActiveRoomId(event.roomId);
|
|
||||||
setRoomSession(session);
|
|
||||||
return;
|
|
||||||
case RoomEngineEvent.DISPOSED:
|
|
||||||
setRoomSession(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineEvent.INITIALIZED, onRoomEngineEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineEvent.DISPOSED, onRoomEngineEvent);
|
|
||||||
|
|
||||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomSessionEvent.CREATED:
|
|
||||||
StartRoomSession(event.session);
|
|
||||||
return;
|
|
||||||
case RoomSessionEvent.ENDED:
|
|
||||||
setRoomSession(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
|
||||||
|
|
||||||
const resize = useCallback((event: UIEvent = null) =>
|
|
||||||
{
|
|
||||||
const canvas = GetNitroInstance().renderer.view;
|
|
||||||
|
|
||||||
if(!canvas) return;
|
|
||||||
|
|
||||||
canvas.style.width = `${ Math.floor(window.innerWidth) }px`;
|
|
||||||
canvas.style.height = `${ Math.floor(window.innerHeight) }px`;
|
|
||||||
|
|
||||||
const nitroInstance = GetNitroInstance();
|
|
||||||
|
|
||||||
nitroInstance.renderer.resolution = window.devicePixelRatio;
|
|
||||||
nitroInstance.renderer.resize(window.innerWidth, window.innerHeight);
|
|
||||||
|
|
||||||
InitializeRoomInstanceRenderingCanvas(window.innerWidth, window.innerHeight, 1);
|
|
||||||
|
|
||||||
nitroInstance.render();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!roomSession)
|
|
||||||
{
|
|
||||||
setWidgetHandler(null);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const widgetHandlerManager = new RoomWidgetHandlerManager(roomSession, new EventDispatcher());
|
|
||||||
|
|
||||||
widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new RoomWidgetChatHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new UserChooserWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new WordQuizWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new PollWidgetHandler());
|
|
||||||
|
|
||||||
widgetHandlerManager.registerHandler(new FurniChooserWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureCreditWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureCustomStackHeightWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureExternalImageWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurniturePresentWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureDimmerWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureYoutubeDisplayWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureMannequinWidgetHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureInternalLinkHandler());
|
|
||||||
widgetHandlerManager.registerHandler(new FurnitureRoomLinkHandler());
|
|
||||||
|
|
||||||
setWidgetHandler(widgetHandlerManager);
|
|
||||||
|
|
||||||
const roomEngine = GetRoomEngine();
|
|
||||||
const roomId = roomSession.roomId;
|
|
||||||
const canvasId = 1;
|
|
||||||
|
|
||||||
resize();
|
|
||||||
|
|
||||||
const displayObject = roomEngine.getRoomInstanceDisplay(roomId, canvasId, window.innerWidth, window.innerHeight, RoomGeometry.SCALE_ZOOMED_IN);
|
|
||||||
|
|
||||||
if(!displayObject) return;
|
|
||||||
|
|
||||||
const geometry = (roomEngine.getRoomInstanceGeometry(roomId, canvasId) as RoomGeometry);
|
|
||||||
|
|
||||||
if(geometry)
|
|
||||||
{
|
|
||||||
const minX = (roomEngine.getRoomInstanceVariable<number>(roomId, RoomVariableEnum.ROOM_MIN_X) || 0);
|
|
||||||
const maxX = (roomEngine.getRoomInstanceVariable<number>(roomId, RoomVariableEnum.ROOM_MAX_X) || 0);
|
|
||||||
const minY = (roomEngine.getRoomInstanceVariable<number>(roomId, RoomVariableEnum.ROOM_MIN_Y) || 0);
|
|
||||||
const maxY = (roomEngine.getRoomInstanceVariable<number>(roomId, RoomVariableEnum.ROOM_MAX_Y) || 0);
|
|
||||||
|
|
||||||
let x = ((minX + maxX) / 2);
|
|
||||||
let y = ((minY + maxY) / 2);
|
|
||||||
|
|
||||||
const offset = 20;
|
|
||||||
|
|
||||||
x = (x + (offset - 1));
|
|
||||||
y = (y + (offset - 1));
|
|
||||||
|
|
||||||
const z = (Math.sqrt(((offset * offset) + (offset * offset))) * Math.tan(((30 / 180) * Math.PI)));
|
|
||||||
|
|
||||||
geometry.location = new Vector3d(x, y, z);
|
|
||||||
}
|
|
||||||
|
|
||||||
const stage = GetNitroInstance().stage;
|
|
||||||
|
|
||||||
if(!stage) return;
|
|
||||||
|
|
||||||
stage.addChild(displayObject);
|
|
||||||
|
|
||||||
SetActiveRoomId(roomSession.roomId);
|
|
||||||
}, [ roomSession, resize ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
const canvas = GetNitroInstance().renderer.view;
|
const canvas = GetNitroInstance().renderer.view;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPetStatusUpdateEvent, RoomSessionPollEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomSessionWordQuizEvent, RoomZoomEvent } from '@nitrots/nitro-renderer';
|
import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFavoriteGroupUpdateEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPetStatusUpdateEvent, RoomSessionPollEvent, RoomSessionUserBadgesEvent, RoomSessionUserFigureUpdateEvent, RoomSessionWordQuizEvent, RoomZoomEvent } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, NotificationAlertType, NotificationUtilities, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../api';
|
import { GetRoomEngine, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, RoomWidgetFurniToWidgetMessage, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../api';
|
||||||
import { UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../../hooks';
|
import { DispatchUiEvent, UseRoomEngineEvent, UseRoomSessionManagerEvent } from '../../../hooks';
|
||||||
import { useRoomContext } from '../RoomContext';
|
import { useRoomContext } from '../RoomContext';
|
||||||
import { AvatarInfoWidgetView } from './avatar-info/AvatarInfoWidgetView';
|
import { AvatarInfoWidgetView } from './avatar-info/AvatarInfoWidgetView';
|
||||||
import { ChatInputView } from './chat-input/ChatInputView';
|
import { ChatInputView } from './chat-input/ChatInputView';
|
||||||
@ -67,73 +67,6 @@ export const RoomWidgetsView: FC<{}> = props =>
|
|||||||
|
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case RoomEngineObjectEvent.SELECTED:
|
|
||||||
if(!IsFurnitureSelectionDisabled(event)) updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.DESELECTED:
|
|
||||||
updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.ADDED: {
|
|
||||||
let addedEventType: string = null;
|
|
||||||
|
|
||||||
switch(category)
|
|
||||||
{
|
|
||||||
case RoomObjectCategory.FLOOR:
|
|
||||||
case RoomObjectCategory.WALL:
|
|
||||||
addedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED;
|
|
||||||
break;
|
|
||||||
case RoomObjectCategory.UNIT:
|
|
||||||
addedEventType = RoomWidgetUpdateRoomObjectEvent.USER_ADDED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(addedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(addedEventType, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RoomEngineObjectEvent.REMOVED: {
|
|
||||||
let removedEventType: string = null;
|
|
||||||
|
|
||||||
switch(category)
|
|
||||||
{
|
|
||||||
case RoomObjectCategory.FLOOR:
|
|
||||||
case RoomObjectCategory.WALL:
|
|
||||||
removedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED;
|
|
||||||
break;
|
|
||||||
case RoomObjectCategory.UNIT:
|
|
||||||
removedEventType = RoomWidgetUpdateRoomObjectEvent.USER_REMOVED;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(removedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(removedEventType, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case RoomEngineObjectEvent.REQUEST_MOVE:
|
|
||||||
if(CanManipulateFurniture(roomSession, objectId, category)) ProcessRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_MOVE);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.REQUEST_ROTATE:
|
|
||||||
if(CanManipulateFurniture(roomSession, objectId, category)) ProcessRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.REQUEST_MANIPULATION:
|
|
||||||
if(CanManipulateFurniture(roomSession, objectId, category)) updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.MOUSE_ENTER:
|
|
||||||
updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
case RoomEngineObjectEvent.MOUSE_LEAVE:
|
|
||||||
updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OUT, objectId, category, event.roomId);
|
|
||||||
break;
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI:
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_CREDITFURNI, objectId, category, event.roomId));
|
|
||||||
break;
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_STICKIE:
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_STICKIE, objectId, category, event.roomId));
|
|
||||||
break;
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_PRESENT:
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_PRESENT, objectId, category, event.roomId));
|
|
||||||
break;
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_TROPHY:
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_TROPHY, objectId, category, event.roomId));
|
|
||||||
break;
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_TEASER:
|
case RoomEngineTriggerWidgetEvent.REQUEST_TEASER:
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_TEASER, objectId, category, event.roomId));
|
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_TEASER, objectId, category, event.roomId));
|
||||||
break;
|
break;
|
||||||
@ -173,7 +106,6 @@ export const RoomWidgetsView: FC<{}> = props =>
|
|||||||
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
|
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
|
||||||
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
|
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
|
||||||
case RoomEngineTriggerWidgetEvent.REMOVE_DIMMER:
|
case RoomEngineTriggerWidgetEvent.REMOVE_DIMMER:
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN:
|
|
||||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
||||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR:
|
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR:
|
||||||
@ -200,24 +132,15 @@ export const RoomWidgetsView: FC<{}> = props =>
|
|||||||
|
|
||||||
if(updateEvent instanceof RoomWidgetUpdateRoomObjectEvent) dispatchEvent = (!RoomId.isRoomPreviewerId(updateEvent.roomId));
|
if(updateEvent instanceof RoomWidgetUpdateRoomObjectEvent) dispatchEvent = (!RoomId.isRoomPreviewerId(updateEvent.roomId));
|
||||||
|
|
||||||
if(dispatchEvent) widgetHandler.eventDispatcher.dispatchEvent(updateEvent);
|
if(dispatchEvent)
|
||||||
|
{
|
||||||
|
widgetHandler.eventDispatcher.dispatchEvent(updateEvent);
|
||||||
|
|
||||||
|
DispatchUiEvent(updateEvent);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, [ roomSession, widgetHandler, handleRoomAdClick, handleRoomAdTooltip ]);
|
}, [ roomSession, widgetHandler, handleRoomAdClick, handleRoomAdTooltip ]);
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.SELECTED, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.DESELECTED, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.ADDED, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.REMOVED, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.PLACED, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MOVE, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.REQUEST_ROTATE, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MANIPULATION, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.MOUSE_ENTER, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TEASER, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TEASER, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ECOTRONBOX, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ECOTRONBOX, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, onRoomEngineObjectEvent);
|
||||||
@ -232,7 +155,6 @@ export const RoomWidgetsView: FC<{}> = props =>
|
|||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REMOVE_DIMMER, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REMOVE_DIMMER, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, onRoomEngineObjectEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
||||||
@ -260,11 +182,7 @@ export const RoomWidgetsView: FC<{}> = props =>
|
|||||||
UseRoomSessionManagerEvent(RoomSessionUserFigureUpdateEvent.USER_FIGURE, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionUserFigureUpdateEvent.USER_FIGURE, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionFavoriteGroupUpdateEvent.FAVOURITE_GROUP_UPDATE, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionPetStatusUpdateEvent.PET_STATUS_UPDATE, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionDoorbellEvent.DOORBELL, onRoomSessionEvent);
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_REJECTED, onRoomSessionEvent);
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionDoorbellEvent.RSDE_ACCEPTED, onRoomSessionEvent);
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionPresentEvent.RSPE_PRESENT_OPENED, onRoomSessionEvent);
|
|
||||||
UseRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionPetInfoUpdateEvent.PET_INFO, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionWordQuizEvent.ANSWERED, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionWordQuizEvent.ANSWERED, onRoomSessionEvent);
|
||||||
UseRoomSessionManagerEvent(RoomSessionWordQuizEvent.FINISHED, onRoomSessionEvent);
|
UseRoomSessionManagerEvent(RoomSessionWordQuizEvent.FINISHED, onRoomSessionEvent);
|
||||||
|
@ -1,57 +1,52 @@
|
|||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
import { FC, useEffect, useMemo, useState } from 'react';
|
||||||
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
|
import { AutoSizer, List, ListRowProps, ListRowRenderer } from 'react-virtualized';
|
||||||
import { RoomObjectItem, RoomWidgetRoomObjectMessage } from '../../../../api';
|
import { GetSessionDataManager, RoomObjectItem } from '../../../../api';
|
||||||
import { LocalizeText } from '../../../../api/utils';
|
import { LocalizeText } from '../../../../api/utils';
|
||||||
import { Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
import { Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
import { useRoomContext } from '../../RoomContext';
|
|
||||||
|
|
||||||
interface ChooserWidgetViewProps
|
interface ChooserWidgetViewProps
|
||||||
{
|
{
|
||||||
title: string;
|
title: string;
|
||||||
items: RoomObjectItem[];
|
items: RoomObjectItem[];
|
||||||
displayItemId: boolean;
|
selectItem: (item: RoomObjectItem) => void;
|
||||||
onCloseClick: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
export const ChooserWidgetView: FC<ChooserWidgetViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { title = null, items = null, displayItemId = false, onCloseClick = null } = props;
|
const { title = null, items = [], selectItem = null, close = null } = props;
|
||||||
const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null);
|
const [ selectedItem, setSelectedItem ] = useState<RoomObjectItem>(null);
|
||||||
const [ searchValue, setSearchValue ] = useState('');
|
const [ searchValue, setSearchValue ] = useState('');
|
||||||
const { widgetHandler = null } = useRoomContext();
|
const canSeeId = GetSessionDataManager().isModerator;
|
||||||
|
|
||||||
const filteredItems = useMemo(() =>
|
const filteredItems = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(!items) return [];
|
|
||||||
|
|
||||||
if(!searchValue || !searchValue.length) return items;
|
|
||||||
|
|
||||||
const value = searchValue.toLocaleLowerCase();
|
const value = searchValue.toLocaleLowerCase();
|
||||||
|
|
||||||
return items.filter(item => item.name.toLocaleLowerCase().includes(value));
|
return items.filter(item => item.name.toLocaleLowerCase().includes(value));
|
||||||
}, [ items, searchValue ]);
|
}, [ items, searchValue ]);
|
||||||
|
|
||||||
const onItemClick = useCallback((item: RoomObjectItem) =>
|
|
||||||
{
|
|
||||||
setSelectedItem(item);
|
|
||||||
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.SELECT_OBJECT, item.id, item.category));
|
|
||||||
}, [ widgetHandler, setSelectedItem ]);
|
|
||||||
|
|
||||||
const rowRenderer: ListRowRenderer = (props: ListRowProps) =>
|
const rowRenderer: ListRowRenderer = (props: ListRowProps) =>
|
||||||
{
|
{
|
||||||
const item = filteredItems[props.index];
|
const item = filteredItems[props.index];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Flex key={ props.key } alignItems="center" position="absolute" className={ 'rounded px-1' + ((selectedItem === item) ? ' bg-muted' : '') } pointer style={ props.style } onClick={ event => onItemClick(item) }>
|
<Flex key={ props.key } alignItems="center" position="absolute" className={ 'rounded px-1' + ((selectedItem === item) ? ' bg-muted' : '') } pointer style={ props.style } onClick={ event => setSelectedItem(item) }>
|
||||||
<Text truncate>{ item.name } { displayItemId && (' - ' + item.id) }</Text>
|
<Text truncate>{ item.name } { canSeeId && (' - ' + item.id) }</Text>
|
||||||
</Flex>
|
</Flex>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!selectedItem) return;
|
||||||
|
|
||||||
|
selectItem(selectedItem);
|
||||||
|
}, [ selectedItem, selectItem ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView className="nitro-chooser-widget" theme="primary-slim">
|
<NitroCardView className="nitro-chooser-widget" theme="primary-slim">
|
||||||
<NitroCardHeaderView headerText={ title } onCloseClick={ onCloseClick } />
|
<NitroCardHeaderView headerText={ title } onCloseClick={ close } />
|
||||||
<NitroCardContentView overflow="hidden">
|
<NitroCardContentView overflow="hidden">
|
||||||
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
||||||
<Column fullHeight overflow="auto">
|
<Column fullHeight overflow="auto">
|
||||||
|
@ -1,60 +1,31 @@
|
|||||||
import { SecurityLevel } from '@nitrots/nitro-renderer';
|
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
import { GetSessionDataManager, LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
||||||
import { UseEventDispatcherHook } from '../../../../hooks';
|
import { useFurniChooserWidget } from '../../../../hooks';
|
||||||
import { useRoomContext } from '../../RoomContext';
|
|
||||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
export const FurniChooserWidgetView: FC<{}> = props =>
|
export const FurniChooserWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const { items = null, close = null, selectItem = null, populateChooser = null } = useFurniChooserWidget();
|
||||||
const [ items, setItems ] = useState<RoomObjectItem[]>(null);
|
|
||||||
const [ refreshTimeout, setRefreshTimeout ] = useState<ReturnType<typeof setTimeout>>(null);
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const refreshChooser = useCallback(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!isVisible) return;
|
const linkTracker: ILinkEventTracker = {
|
||||||
|
linkReceived: (url: string) =>
|
||||||
setRefreshTimeout(prevValue =>
|
|
||||||
{
|
{
|
||||||
if(prevValue) clearTimeout(prevValue);
|
const parts = url.split('/');
|
||||||
|
|
||||||
return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER)), 100);
|
populateChooser();
|
||||||
});
|
},
|
||||||
}, [ isVisible, widgetHandler ]);
|
eventUrlPrefix: 'furni-chooser/'
|
||||||
|
};
|
||||||
|
|
||||||
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
AddEventLinkTracker(linkTracker);
|
||||||
{
|
|
||||||
setItems(event.items);
|
|
||||||
setIsVisible(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
return () => RemoveLinkEventTracker(linkTracker);
|
||||||
|
}, [ populateChooser ]);
|
||||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
|
||||||
{
|
|
||||||
if(!isVisible) return;
|
|
||||||
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED:
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED:
|
|
||||||
refreshChooser();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, [ isVisible, refreshChooser ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
|
|
||||||
const close = useCallback(() =>
|
|
||||||
{
|
|
||||||
setIsVisible(false);
|
|
||||||
setItems(null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(!items) return null;
|
if(!items) return null;
|
||||||
|
|
||||||
return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } displayItemId={ GetSessionDataManager().hasSecurity(SecurityLevel.MODERATOR) } items={ items } onCloseClick={ close } />;
|
return <ChooserWidgetView title={ LocalizeText('widget.chooser.furni.title') } items={ items } selectItem={ selectItem } close={ close } />;
|
||||||
}
|
}
|
||||||
|
@ -1,59 +1,31 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { ILinkEventTracker } from '@nitrots/nitro-renderer';
|
||||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
import { FC, useEffect } from 'react';
|
||||||
import { UseEventDispatcherHook } from '../../../../hooks';
|
import { AddEventLinkTracker, LocalizeText, RemoveLinkEventTracker } from '../../../../api';
|
||||||
import { useRoomContext } from '../../RoomContext';
|
import { useUserChooserWidget } from '../../../../hooks';
|
||||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||||
|
|
||||||
export const UserChooserWidgetView: FC<{}> = props =>
|
export const UserChooserWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const { items = null, close = null, selectItem = null, populateChooser = null } = useUserChooserWidget();
|
||||||
const [ items, setItems ] = useState<RoomObjectItem[]>(null);
|
|
||||||
const [ refreshTimeout, setRefreshTimeout ] = useState<ReturnType<typeof setTimeout>>(null);
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const refreshChooser = useCallback(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
if(!isVisible) return;
|
const linkTracker: ILinkEventTracker = {
|
||||||
|
linkReceived: (url: string) =>
|
||||||
setRefreshTimeout(prevValue =>
|
|
||||||
{
|
{
|
||||||
if(prevValue) clearTimeout(prevValue);
|
const parts = url.split('/');
|
||||||
|
|
||||||
return setTimeout(() => widgetHandler.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.USER_CHOOSER)), 100);
|
populateChooser();
|
||||||
})
|
},
|
||||||
}, [ isVisible, widgetHandler ]);
|
eventUrlPrefix: 'user-chooser/'
|
||||||
|
};
|
||||||
|
|
||||||
const onRoomWidgetChooserContentEvent = useCallback((event: RoomWidgetChooserContentEvent) =>
|
AddEventLinkTracker(linkTracker);
|
||||||
{
|
|
||||||
setItems(event.items);
|
|
||||||
setIsVisible(true);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
return () => RemoveLinkEventTracker(linkTracker);
|
||||||
|
}, [ populateChooser ]);
|
||||||
|
|
||||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
if(!items) return null;
|
||||||
{
|
|
||||||
if(!isVisible) return;
|
|
||||||
|
|
||||||
switch(event.type)
|
return <ChooserWidgetView title={ LocalizeText('widget.chooser.user.title') } items={ items } selectItem={ selectItem } close={ close } />;
|
||||||
{
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.USER_ADDED:
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.USER_REMOVED:
|
|
||||||
refreshChooser();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, [ isVisible, refreshChooser ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
|
|
||||||
const close = useCallback(() =>
|
|
||||||
{
|
|
||||||
setIsVisible(false);
|
|
||||||
setItems(null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(!isVisible) return null;
|
|
||||||
|
|
||||||
return <ChooserWidgetView title={ LocalizeText('widget.chooser.user.title') } displayItemId={ false } items={ items } onCloseClick={ close } />;
|
|
||||||
}
|
}
|
||||||
|
@ -3,13 +3,11 @@ import { RoomObjectCategory } from '@nitrots/nitro-renderer';
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeText, MessengerRequest } from '../../../../api';
|
import { LocalizeText, MessengerRequest } from '../../../../api';
|
||||||
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
import { Base, Button, Column, Flex, Text } from '../../../../common';
|
||||||
import { useFriends } from '../../../../hooks';
|
|
||||||
import { ObjectLocationView } from '../object-location/ObjectLocationView';
|
import { ObjectLocationView } from '../object-location/ObjectLocationView';
|
||||||
|
|
||||||
export const FriendRequestDialogView: FC<{ roomIndex: number, request: MessengerRequest, hideFriendRequest: (userId: number) => void }> = props =>
|
export const FriendRequestDialogView: FC<{ roomIndex: number, request: MessengerRequest, hideFriendRequest: (userId: number) => void, requestResponse: (requestId: number, flag: boolean) => void }> = props =>
|
||||||
{
|
{
|
||||||
const { roomIndex = -1, request = null, hideFriendRequest = null } = props;
|
const { roomIndex = -1, request = null, hideFriendRequest = null, requestResponse = null } = props;
|
||||||
const { requestResponse = null } = useFriends();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ObjectLocationView objectId={ roomIndex } category={ RoomObjectCategory.UNIT }>
|
<ObjectLocationView objectId={ roomIndex } category={ RoomObjectCategory.UNIT }>
|
||||||
|
@ -1,100 +1,17 @@
|
|||||||
import { RoomObjectCategory, RoomObjectUserType } from '@nitrots/nitro-renderer';
|
import { FC } from 'react';
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { useFriendRequestWidget, useFriends } from '../../../../hooks';
|
||||||
import { MessengerRequest, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
|
||||||
import { UseEventDispatcherHook, useFriends } from '../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../RoomContext';
|
|
||||||
import { FriendRequestDialogView } from './FriendRequestDialogView';
|
import { FriendRequestDialogView } from './FriendRequestDialogView';
|
||||||
|
|
||||||
export const FriendRequestWidgetView: FC<{}> = props =>
|
export const FriendRequestWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ displayedRequests, setDisplayedRequests ] = useState<{ roomIndex: number, request: MessengerRequest }[]>([]);
|
const { displayedRequests = [], hideFriendRequest = null } = useFriendRequestWidget();
|
||||||
const [ dismissedRequestIds, setDismissedRequestIds ] = useState<number[]>([]);
|
const { requestResponse = null } = useFriends();
|
||||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
|
||||||
const { requests = [] } = useFriends();
|
|
||||||
|
|
||||||
const hideFriendRequest = (userId: number) =>
|
if(!displayedRequests.length) return null;
|
||||||
{
|
|
||||||
setDismissedRequestIds(prevValue =>
|
|
||||||
{
|
|
||||||
if(prevValue.indexOf(userId) >= 0) return prevValue;
|
|
||||||
|
|
||||||
const newValue = [ ...prevValue ];
|
|
||||||
|
|
||||||
newValue.push(userId);
|
|
||||||
|
|
||||||
return newValue;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateRoomObjectEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
|
||||||
{
|
|
||||||
if(event.category !== RoomObjectCategory.UNIT) return;
|
|
||||||
|
|
||||||
const userData = roomSession.userDataManager.getUserDataByIndex(event.id);
|
|
||||||
|
|
||||||
if(userData && (userData.type === RoomObjectUserType.getTypeNumber(RoomObjectUserType.USER)))
|
|
||||||
{
|
|
||||||
if(event.type === RoomWidgetUpdateRoomObjectEvent.USER_ADDED)
|
|
||||||
{
|
|
||||||
const request = requests.find(request => (request.requesterUserId === userData.webID));
|
|
||||||
|
|
||||||
if(!request || displayedRequests.find(request => (request.request.requesterUserId === userData.webID))) return;
|
|
||||||
|
|
||||||
const newValue = [ ...displayedRequests ];
|
|
||||||
|
|
||||||
newValue.push({ roomIndex: userData.roomIndex, request });
|
|
||||||
|
|
||||||
setDisplayedRequests(newValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(event.type === RoomWidgetUpdateRoomObjectEvent.USER_REMOVED)
|
|
||||||
{
|
|
||||||
const index = displayedRequests.findIndex(request => (request.roomIndex === event.id));
|
|
||||||
|
|
||||||
if(index === -1) return;
|
|
||||||
|
|
||||||
const newValue = [ ...displayedRequests ];
|
|
||||||
|
|
||||||
newValue.splice(index, 1);
|
|
||||||
|
|
||||||
setDisplayedRequests(newValue);
|
|
||||||
}
|
|
||||||
}, [ roomSession, requests, displayedRequests ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_ADDED, eventDispatcher, onRoomWidgetUpdateRoomObjectEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetUpdateRoomObjectEvent);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!requests || !requests.length) return;
|
|
||||||
|
|
||||||
const newDisplayedRequests: { roomIndex: number, request: MessengerRequest }[] = [];
|
|
||||||
|
|
||||||
for(const request of requests)
|
|
||||||
{
|
|
||||||
const userData = roomSession.userDataManager.getUserData(request.requesterUserId);
|
|
||||||
|
|
||||||
if(!userData) continue;
|
|
||||||
|
|
||||||
newDisplayedRequests.push({ roomIndex: userData.roomIndex, request });
|
|
||||||
}
|
|
||||||
|
|
||||||
setDisplayedRequests(newDisplayedRequests);
|
|
||||||
}, [ roomSession, requests ]);
|
|
||||||
|
|
||||||
if(!requests.length) return null;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ displayedRequests.map((request, index) =>
|
{ displayedRequests.map((request, index) => <FriendRequestDialogView key={ index } roomIndex={ request.roomIndex } request={ request.request } hideFriendRequest={ hideFriendRequest } requestResponse={ requestResponse } />) }
|
||||||
{
|
|
||||||
if(dismissedRequestIds.indexOf(request.request.requesterUserId) >= 0) return null;
|
|
||||||
|
|
||||||
return <FriendRequestDialogView key={ index } roomIndex={ request.roomIndex } request={ request.request } hideFriendRequest={ hideFriendRequest } />;
|
|
||||||
}) }
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,63 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import ReactSlider from 'react-slider';
|
||||||
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
|
import { useFurnitureBackgroundColorWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureBackgroundColorView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, hue = 0, setHue = null, saturation = 0, setSaturation = null, lightness = 0, setLightness = null, applyToner = null, toggleToner = null, close = null } = useFurnitureBackgroundColorWidget();
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView theme="primary-slim" className="nitro-room-widget-toner">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView overflow="hidden" justifyContent="between">
|
||||||
|
<Column overflow="auto" gap={ 1 }>
|
||||||
|
<Column>
|
||||||
|
<Text bold>{ LocalizeText('widget.backgroundcolor.hue') }</Text>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 360 }
|
||||||
|
value={ hue }
|
||||||
|
onChange={ event => setHue(event) }
|
||||||
|
thumbClassName={ 'thumb degree' }
|
||||||
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
|
</Column>
|
||||||
|
<Column>
|
||||||
|
<Text bold>{ LocalizeText('widget.backgroundcolor.saturation') }</Text>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 100 }
|
||||||
|
value={ saturation }
|
||||||
|
onChange={ event => setSaturation(event) }
|
||||||
|
thumbClassName={ 'thumb percent' }
|
||||||
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
|
</Column>
|
||||||
|
<Column>
|
||||||
|
<Text bold>{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 100 }
|
||||||
|
value={ lightness }
|
||||||
|
onChange={ event => setLightness(event) }
|
||||||
|
thumbClassName={ 'thumb percent' }
|
||||||
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
|
</Column>
|
||||||
|
</Column>
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Button fullWidth variant="primary" onClick={ toggleToner }>
|
||||||
|
{ LocalizeText('widget.backgroundcolor.button.on') }
|
||||||
|
</Button>
|
||||||
|
<Button fullWidth variant="primary" onClick={ applyToner }>
|
||||||
|
{ LocalizeText('widget.backgroundcolor.button.apply') }
|
||||||
|
</Button>
|
||||||
|
</Column>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LayoutTrophyView } from '../../../../common';
|
||||||
|
import { useFurnitureBadgeDisplayWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, color = '1', badgeName = '', badgeDesc = '', date = '', senderName = '', close = null } = useFurnitureBadgeDisplayWidget();
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return <LayoutTrophyView color={ color } message={ badgeDesc } date={ date } senderName={ senderName } customTitle={ badgeName } onCloseClick={ close } />;
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import ReactSlider from 'react-slider';
|
||||||
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
|
import { useFurnitureStackHeightWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, height = 0, maxHeight = 40, close = null, updateHeight = null, sendUpdate = null } = useFurnitureStackHeightWidget();
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-widget-custom-stack-height" theme="primary-slim">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('widget.custom.stack.height.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView justifyContent="between">
|
||||||
|
<Text>{ LocalizeText('widget.custom.stack.height.text') }</Text>
|
||||||
|
<Flex gap={ 2 }>
|
||||||
|
<ReactSlider
|
||||||
|
className="nitro-slider"
|
||||||
|
min={ 0 }
|
||||||
|
max={ maxHeight }
|
||||||
|
step={ 0.01 }
|
||||||
|
value={ height }
|
||||||
|
onChange={ event => updateHeight(event) }
|
||||||
|
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
||||||
|
<input type="number" min={ 0 } max={ maxHeight } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
|
||||||
|
</Flex>
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Button onClick={ event => sendUpdate(-100) }>
|
||||||
|
{ LocalizeText('furniture.above.stack') }
|
||||||
|
</Button>
|
||||||
|
<Button onClick={ event => sendUpdate(0) }>
|
||||||
|
{ LocalizeText('furniture.floor.level') }
|
||||||
|
</Button>
|
||||||
|
</Column>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -1,35 +1,11 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC } from 'react';
|
||||||
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
|
import { LocalizeText } from '../../../../api';
|
||||||
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
import { Base, Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
import { UseEventDispatcherHook } from '../../../../../hooks';
|
import { useFurnitureExchangeWidget } from '../../../../hooks';
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
export const FurnitureExchangeCreditView: FC<{}> = props =>
|
export const FurnitureExchangeCreditView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
const { objectId = -1, value = 0, close = null, redeem = null } = useFurnitureExchangeWidget();
|
||||||
const [ value, setValue ] = useState(0);
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateCreditFurniEvent = useCallback((event: RoomWidgetUpdateCreditFurniEvent) =>
|
|
||||||
{
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setValue(event.value);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
|
|
||||||
|
|
||||||
const close = () =>
|
|
||||||
{
|
|
||||||
setObjectId(-1);
|
|
||||||
setValue(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const redeem = () =>
|
|
||||||
{
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
|
||||||
|
|
||||||
close();
|
|
||||||
}
|
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
if(objectId === -1) return null;
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../api';
|
||||||
|
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
|
import { useFurnitureExternalImageWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureExternalImageView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, photoData = null, close = null } = useFurnitureExternalImageWidget();
|
||||||
|
|
||||||
|
if((objectId === -1) || !photoData) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-external-image-widget" theme="primary-slim">
|
||||||
|
<NitroCardHeaderView headerText="" onCloseClick={ close } />
|
||||||
|
<NitroCardContentView>
|
||||||
|
<Flex center className="picture-preview border border-black" style={ photoData.w ? { backgroundImage: 'url(' + photoData.w + ')' } : {} }>
|
||||||
|
{ !photoData.w &&
|
||||||
|
<Text bold>{ LocalizeText('camera.loading') }</Text> }
|
||||||
|
</Flex>
|
||||||
|
{ photoData.m && photoData.m.length &&
|
||||||
|
<Text center>{ photoData.m }</Text> }
|
||||||
|
<Flex alignItems="center" justifyContent="between">
|
||||||
|
<Text>{ (photoData.n || '') }</Text>
|
||||||
|
<Text>{ new Date(photoData.t * 1000).toLocaleDateString() }</Text>
|
||||||
|
</Flex>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { CreateLinkEvent, LocalizeText } from '../../../../api';
|
||||||
|
import { Button, Column, Flex, LayoutGiftTagView, LayoutImage, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
|
import { useFurniturePresentWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, classId = -1, itemType = null, text = null, isOwnerOfFurniture = false, senderName = null, senderFigure = null, placedItemId = -1, placedItemType = null, placedInRoom = false, imageUrl = null, openPresent = null, close = null } = useFurniturePresentWidget();
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-gift-opening" theme="primary-slim">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText(senderName ? 'widget.furni.present.window.title_from' : 'widget.furni.present.window.title', [ 'name' ], [ senderName ]) } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView>
|
||||||
|
{ (placedItemId === -1) &&
|
||||||
|
<Column overflow="hidden">
|
||||||
|
<Flex center overflow="auto">
|
||||||
|
<LayoutGiftTagView userName={ senderName } figure={ senderFigure } message={ text } />
|
||||||
|
</Flex>
|
||||||
|
{ isOwnerOfFurniture &&
|
||||||
|
<Flex gap={ 1 }>
|
||||||
|
{ senderName &&
|
||||||
|
<Button fullWidth onClick={ event => CreateLinkEvent('catalog/open') }>
|
||||||
|
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
||||||
|
</Button> }
|
||||||
|
<Button fullWidth variant="success" onClick={ openPresent }>
|
||||||
|
{ LocalizeText('widget.furni.present.open_gift') }
|
||||||
|
</Button>
|
||||||
|
</Flex> }
|
||||||
|
</Column> }
|
||||||
|
{ (placedItemId > -1) &&
|
||||||
|
<Flex gap={ 2 } overflow="hidden">
|
||||||
|
<Column center className="p-2">
|
||||||
|
<LayoutImage imageUrl={ imageUrl } />
|
||||||
|
</Column>
|
||||||
|
<Column grow>
|
||||||
|
<Column center gap={ 1 }>
|
||||||
|
<Text wrap small>{ LocalizeText('widget.furni.present.message_opened') }</Text>
|
||||||
|
<Text bold fontSize={ 5 }>{ text }</Text>
|
||||||
|
</Column>
|
||||||
|
<Column grow gap={ 1 }>
|
||||||
|
<Flex gap={ 1 }>
|
||||||
|
{ placedInRoom &&
|
||||||
|
<Button fullWidth onClick={ null }>
|
||||||
|
{ LocalizeText('widget.furni.present.put_in_inventory') }
|
||||||
|
</Button> }
|
||||||
|
<Button fullWidth variant="success" onClick={ null }>
|
||||||
|
{ LocalizeText(placedInRoom ? 'widget.furni.present.keep_in_room' : 'widget.furni.present.place_in_room') }
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
{ (senderName && senderName.length) &&
|
||||||
|
<Button fullWidth onClick={ event => CreateLinkEvent('catalog/open') }>
|
||||||
|
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
||||||
|
</Button> }
|
||||||
|
</Column>
|
||||||
|
</Column>
|
||||||
|
</Flex> }
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
|
import { RoomObjectOperationType } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC } from 'react';
|
||||||
|
import { ProcessRoomObjectOperation } from '../../../../api';
|
||||||
|
import { Button, ButtonGroup } from '../../../../common';
|
||||||
|
import { useFurnitureManipulationWidget } from '../../../../hooks';
|
||||||
|
import { ObjectLocationView } from '../object-location/ObjectLocationView';
|
||||||
|
|
||||||
|
export const FurnitureManipulationMenuView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { manipulatingId = -1, manipulatingCategory = -1 } = useFurnitureManipulationWidget();
|
||||||
|
|
||||||
|
// const onRoomWidgetUpdateDecorateModeEvent = useCallback((event: RoomWidgetUpdateDecorateModeEvent) =>
|
||||||
|
// {
|
||||||
|
// if(event.isDecorating) return;
|
||||||
|
|
||||||
|
// moveFurniture();
|
||||||
|
|
||||||
|
// setIsVisible(false);
|
||||||
|
// setObjectId(-1);
|
||||||
|
// setCategory(-1);
|
||||||
|
// }, [ moveFurniture ]);
|
||||||
|
|
||||||
|
// UseEventDispatcherHook(RoomWidgetUpdateDecorateModeEvent.UPDATE_DECORATE, eventDispatcher, onRoomWidgetUpdateDecorateModeEvent);
|
||||||
|
|
||||||
|
// useEffect(() =>
|
||||||
|
// {
|
||||||
|
// if(!isVisible)
|
||||||
|
// {
|
||||||
|
// eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(false));
|
||||||
|
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(true));
|
||||||
|
|
||||||
|
// moveFurniture();
|
||||||
|
// }, [ eventDispatcher, isVisible, moveFurniture ]);
|
||||||
|
|
||||||
|
if((manipulatingId === -1) || (manipulatingCategory === -1)) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ObjectLocationView objectId={ manipulatingId } category={ manipulatingCategory }>
|
||||||
|
<ButtonGroup>
|
||||||
|
<Button onClick={ event => ProcessRoomObjectOperation(manipulatingId, manipulatingCategory, RoomObjectOperationType.OBJECT_PICKUP) }>
|
||||||
|
<FontAwesomeIcon icon="times" />
|
||||||
|
</Button>
|
||||||
|
<Button onClick={ event => ProcessRoomObjectOperation(manipulatingId, manipulatingCategory, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE) }>
|
||||||
|
<FontAwesomeIcon icon="undo" />
|
||||||
|
</Button>
|
||||||
|
</ButtonGroup>
|
||||||
|
</ObjectLocationView>
|
||||||
|
);
|
||||||
|
}
|
144
src/components/room/widgets/furniture/FurnitureMannequinView.tsx
Normal file
144
src/components/room/widgets/furniture/FurnitureMannequinView.tsx
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import { HabboClubLevelEnum, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
||||||
|
import { FC, useEffect, useState } from 'react';
|
||||||
|
import { GetAvatarRenderManager, GetClubMemberLevel, GetMergedMannequinFigureContainer, GetRoomSession, GetSessionDataManager, LocalizeText, TransformAsMannequinFigure } from '../../../../api';
|
||||||
|
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
|
||||||
|
import { useFurnitureMannequinWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
const MODE_NONE: number = -1;
|
||||||
|
const MODE_CONTROLLER: number = 0;
|
||||||
|
const MODE_UPDATE: number = 1;
|
||||||
|
const MODE_PEER: number = 2;
|
||||||
|
const MODE_NO_CLUB: number = 3;
|
||||||
|
const MODE_WRONG_GENDER: number = 4;
|
||||||
|
|
||||||
|
export const FurnitureMannequinView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const [ renderedFigure, setRenderedFigure ] = useState<string>(null);
|
||||||
|
const [ mode, setMode ] = useState(MODE_NONE);
|
||||||
|
const { objectId = -1, figure = null, gender = null, clubLevel = HabboClubLevelEnum.NO_CLUB, name = null, setName = null, saveFigure = null, wearFigure = null, saveName = null, close = null } = useFurnitureMannequinWidget();
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(objectId === -1) return;
|
||||||
|
|
||||||
|
const roomSession = GetRoomSession();
|
||||||
|
|
||||||
|
if(roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator)
|
||||||
|
{
|
||||||
|
setMode(MODE_CONTROLLER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetSessionDataManager().gender.toLowerCase() !== gender.toLowerCase())
|
||||||
|
{
|
||||||
|
setMode(MODE_WRONG_GENDER);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(GetClubMemberLevel() < clubLevel)
|
||||||
|
{
|
||||||
|
setMode(MODE_NO_CLUB);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMode(MODE_PEER);
|
||||||
|
}, [ objectId, gender, clubLevel ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
switch(mode)
|
||||||
|
{
|
||||||
|
case MODE_CONTROLLER:
|
||||||
|
case MODE_WRONG_GENDER: {
|
||||||
|
const figureContainer = GetAvatarRenderManager().createFigureContainer(figure);
|
||||||
|
|
||||||
|
TransformAsMannequinFigure(figureContainer);
|
||||||
|
|
||||||
|
setRenderedFigure(figureContainer.getFigureString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MODE_UPDATE: {
|
||||||
|
const figureContainer = GetAvatarRenderManager().createFigureContainer(GetSessionDataManager().figure);
|
||||||
|
|
||||||
|
TransformAsMannequinFigure(figureContainer);
|
||||||
|
|
||||||
|
setRenderedFigure(figureContainer.getFigureString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MODE_PEER:
|
||||||
|
case MODE_NO_CLUB: {
|
||||||
|
const figureContainer = GetMergedMannequinFigureContainer(GetSessionDataManager().figure, figure);
|
||||||
|
|
||||||
|
setRenderedFigure(figureContainer.getFigureString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ mode, figure, clubLevel ]);
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView className="nitro-mannequin no-resize" theme="primary-slim">
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView center>
|
||||||
|
<Flex fullWidth gap={ 2 } overflow="hidden">
|
||||||
|
<Column>
|
||||||
|
<Base position="relative" className="mannequin-preview">
|
||||||
|
<LayoutAvatarImageView position="absolute" figure={ renderedFigure } direction={ 2 } />
|
||||||
|
{ (clubLevel > 0) &&
|
||||||
|
<LayoutCurrencyIcon className="position-absolute end-2 bottom-2" type="hc" /> }
|
||||||
|
</Base>
|
||||||
|
</Column>
|
||||||
|
<Column grow justifyContent="between" overflow="auto">
|
||||||
|
{ (mode === MODE_CONTROLLER) &&
|
||||||
|
<>
|
||||||
|
<input type="text" className="form-control form-control-sm" value={ name } onChange={ event => setName(event.target.value) } onBlur={ saveName } />
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Button variant="success" onClick={ event => setMode(MODE_UPDATE) }>
|
||||||
|
{ LocalizeText('mannequin.widget.style') }
|
||||||
|
</Button>
|
||||||
|
<Button variant="success" onClick={ wearFigure }>
|
||||||
|
{ LocalizeText('mannequin.widget.wear') }
|
||||||
|
</Button>
|
||||||
|
</Column>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_UPDATE) &&
|
||||||
|
<>
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Text bold>{ name }</Text>
|
||||||
|
<Text wrap>{ LocalizeText('mannequin.widget.savetext') }</Text>
|
||||||
|
</Column>
|
||||||
|
<Flex alignItems="center" justifyContent="between">
|
||||||
|
<Text underline pointer onClick={ event => setMode(MODE_CONTROLLER) }>
|
||||||
|
{ LocalizeText('mannequin.widget.back') }
|
||||||
|
</Text>
|
||||||
|
<Button variant="success" onClick={ saveFigure }>
|
||||||
|
{ LocalizeText('mannequin.widget.save') }
|
||||||
|
</Button>
|
||||||
|
</Flex>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_PEER) &&
|
||||||
|
<>
|
||||||
|
<Column gap={ 1 }>
|
||||||
|
<Text bold>{ name }</Text>
|
||||||
|
<Text>{ LocalizeText('mannequin.widget.weartext') }</Text>
|
||||||
|
</Column>
|
||||||
|
<Button variant="success" onClick={ wearFigure }>
|
||||||
|
{ LocalizeText('mannequin.widget.wear') }
|
||||||
|
</Button>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_NO_CLUB) &&
|
||||||
|
<Flex center grow>
|
||||||
|
<Text>{ LocalizeText('mannequin.widget.clubnotification') }</Text>
|
||||||
|
</Flex> }
|
||||||
|
{ (mode === MODE_WRONG_GENDER) &&
|
||||||
|
<Text>{ LocalizeText('mannequin.widget.wronggender') }</Text> }
|
||||||
|
</Column>
|
||||||
|
</Flex>
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,52 @@
|
|||||||
|
import { FC, useEffect, useState } from 'react';
|
||||||
|
import { ColorUtils } from '../../../../api';
|
||||||
|
import { DraggableWindow, DraggableWindowPosition } from '../../../../common';
|
||||||
|
import { useFurnitureStickieWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
const STICKIE_COLORS = [ '9CCEFF','FF9CFF', '9CFF9C','FFFF33' ];
|
||||||
|
const STICKIE_COLOR_NAMES = [ 'blue', 'pink', 'green', 'yellow' ];
|
||||||
|
|
||||||
|
const getStickieColorName = (color: string) =>
|
||||||
|
{
|
||||||
|
let index = STICKIE_COLORS.indexOf(color);
|
||||||
|
|
||||||
|
if(index === -1) index = 0;
|
||||||
|
|
||||||
|
return STICKIE_COLOR_NAMES[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FurnitureStickieView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, color = '0', text = '', canModify = false, updateColor = null, updateText = null, trash = null, close = null } = useFurnitureStickieWidget();
|
||||||
|
const [ isEditing, setIsEditing ] = useState(false);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
setIsEditing(false);
|
||||||
|
}, [ objectId, color, text ]);
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<DraggableWindow handleSelector=".drag-handler" windowPosition={ DraggableWindowPosition.NOTHING }>
|
||||||
|
<div className={ 'nitro-stickie nitro-stickie-image stickie-' + getStickieColorName(color) }>
|
||||||
|
<div className="d-flex align-items-center stickie-header drag-handler">
|
||||||
|
<div className="d-flex align-items-center flex-grow-1 h-100">
|
||||||
|
{ canModify &&
|
||||||
|
<>
|
||||||
|
<div className="nitro-stickie-image stickie-trash header-trash" onClick={ trash }></div>
|
||||||
|
{ STICKIE_COLORS.map(color =>
|
||||||
|
{
|
||||||
|
return <div key={ color } className="stickie-color ms-1" onClick={ event => updateColor(color) } style={ { backgroundColor: ColorUtils.makeColorHex(color) } } />
|
||||||
|
}) }
|
||||||
|
</> }
|
||||||
|
</div>
|
||||||
|
<div className="d-flex align-items-center nitro-stickie-image stickie-close header-close" onClick={ close }></div>
|
||||||
|
</div>
|
||||||
|
<div className="stickie-context">
|
||||||
|
{ !isEditing ? <div className="context-text" onClick={ event => setIsEditing(true) }>{ text }</div> : <textarea className="context-text" defaultValue={ text } tabIndex={ 0 } onBlur={ event => updateText(event.target.value) } autoFocus></textarea> }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</DraggableWindow>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LayoutTrophyView } from '../../../../common';
|
||||||
|
import { useFurnitureTrophyWidget } from '../../../../hooks';
|
||||||
|
|
||||||
|
export const FurnitureTrophyView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, color = '1', senderName = '', date = '', message = '' } = useFurnitureTrophyWidget();
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return <LayoutTrophyView color={ color } message={ message } date={ date } senderName={ senderName } onCloseClick={ close } />;
|
||||||
|
}
|
@ -17,13 +17,14 @@
|
|||||||
.dimmer-banner {
|
.dimmer-banner {
|
||||||
width: 56px;
|
width: 56px;
|
||||||
height: 79px;
|
height: 79px;
|
||||||
background: url('../../../../assets/images/room-widgets/dimmer-widget/dimmer_banner.png') center no-repeat;
|
background: url("../../../../assets/images/room-widgets/dimmer-widget/dimmer_banner.png")
|
||||||
|
center no-repeat;
|
||||||
}
|
}
|
||||||
|
|
||||||
.color-swatch {
|
.color-swatch {
|
||||||
height: 30px;
|
height: 30px;
|
||||||
border: 2px solid $white;
|
border: 2px solid $white;
|
||||||
box-shadow: inset 3px 3px rgba(0, 0, 0, .2);
|
box-shadow: inset 3px 3px rgba(0, 0, 0, 0.2);
|
||||||
|
|
||||||
&.active {
|
&.active {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
@ -36,14 +37,13 @@
|
|||||||
height: $nitro-widget-exchange-credit-height;
|
height: $nitro-widget-exchange-credit-height;
|
||||||
|
|
||||||
.exchange-image {
|
.exchange-image {
|
||||||
background-image: url('../../../../assets/images/room-widgets/exchange-credit/exchange-credit-image.png');
|
background-image: url("../../../../assets/images/room-widgets/exchange-credit/exchange-credit-image.png");
|
||||||
width: 103px;
|
width: 103px;
|
||||||
height: 103px;
|
height: 103px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.nitro-external-image-widget {
|
.nitro-external-image-widget {
|
||||||
|
|
||||||
.picture-preview {
|
.picture-preview {
|
||||||
width: 320px;
|
width: 320px;
|
||||||
height: 320px;
|
height: 320px;
|
||||||
@ -51,24 +51,129 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.nitro-gift-opening {
|
.nitro-gift-opening {
|
||||||
|
width: 340px;
|
||||||
|
resize: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nitro-mannequin {
|
.nitro-mannequin {
|
||||||
}
|
width: 300px;
|
||||||
|
|
||||||
.mannequin-preview {
|
.mannequin-preview {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
width: 83px;
|
width: 83px;
|
||||||
height: 130px;
|
height: 130px;
|
||||||
background-image: url('../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png');
|
background-image: url("../../../../assets/images/room-widgets/mannequin-widget/mannequin-spritesheet.png");
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
|
.avatar-image {
|
||||||
|
background-position: unset;
|
||||||
|
top: -8px;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './friend-furni/FurnitureFriendFurniView';
|
.nitro-stickie {
|
||||||
@import './manipulation-menu/FurnitureManipulationMenuView';
|
position: relative;
|
||||||
@import './stickie/FurnitureStickieView';
|
width: 185px;
|
||||||
@import './high-score/FurnitureHighScoreView';
|
height: 178px;
|
||||||
@import './youtube-tv/FurnitureYoutubeDisplayView';
|
top: 25px;
|
||||||
|
left: 25px;
|
||||||
|
padding: 1px;
|
||||||
|
pointer-events: all;
|
||||||
|
|
||||||
|
.stickie-header {
|
||||||
|
width: 183px;
|
||||||
|
height: 18px;
|
||||||
|
padding: 0 7px;
|
||||||
|
|
||||||
|
.header-trash,
|
||||||
|
.header-close {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.stickie-color {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.stickie-context {
|
||||||
|
width: 183px;
|
||||||
|
height: 145px;
|
||||||
|
padding: 2px 7px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: $black;
|
||||||
|
|
||||||
|
.context-text {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
padding: 0;
|
||||||
|
overflow-wrap: break-word;
|
||||||
|
white-space: break-spaces;
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
textarea {
|
||||||
|
background: transparent;
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
resize: none;
|
||||||
|
font-style: italic;
|
||||||
|
|
||||||
|
&:active {
|
||||||
|
border: 0;
|
||||||
|
outline: none;
|
||||||
|
box-shadow: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.nitro-stickie-image {
|
||||||
|
background-image: url("../../../../assets/images/room-widgets/stickie-widget/stickie-spritesheet.png");
|
||||||
|
|
||||||
|
&.stickie-blue,
|
||||||
|
&.stickie-yellow,
|
||||||
|
&.stickie-green,
|
||||||
|
&.stickie-pink {
|
||||||
|
width: 185px;
|
||||||
|
height: 178px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-blue {
|
||||||
|
background-position: -2px -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-yellow {
|
||||||
|
background-image: url("../../../../assets/images/room-widgets/stickie-widget/stickie-yellow.png");
|
||||||
|
//background-position: -191px -184px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-green {
|
||||||
|
background-position: -191px -2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-pink {
|
||||||
|
background-position: -2px -184px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-close {
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
background-position: -2px -366px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.stickie-trash {
|
||||||
|
width: 9px;
|
||||||
|
height: 10px;
|
||||||
|
background-position: -16px -366px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@import "./friend-furni/FurnitureFriendFurniView";
|
||||||
|
@import "./high-score/FurnitureHighScoreView";
|
||||||
|
@import "./youtube-tv/FurnitureYoutubeDisplayView";
|
||||||
|
@ -1,24 +1,25 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { FurnitureBackgroundColorView } from './background-color/FurnitureBackgroundColorView';
|
import { Base } from '../../../../common';
|
||||||
import { FurnitureBadgeDisplayView } from './badge-display/FurnitureBadgeDisplayView';
|
|
||||||
import { FurnitureContextMenuView } from './context-menu/FurnitureContextMenuView';
|
import { FurnitureContextMenuView } from './context-menu/FurnitureContextMenuView';
|
||||||
import { FurnitureCustomStackHeightView } from './custom-stack-height/FurnitureCustomStackHeightView';
|
|
||||||
import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView';
|
import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView';
|
||||||
import { FurnitureExchangeCreditView } from './exchange-credit/FurnitureExchangeCreditView';
|
|
||||||
import { FurnitureExternalImageView } from './external-image/FurnitureExternalImageView';
|
|
||||||
import { FurnitureFriendFurniView } from './friend-furni/FurnitureFriendFurniView';
|
import { FurnitureFriendFurniView } from './friend-furni/FurnitureFriendFurniView';
|
||||||
import { FurnitureGiftOpeningView } from './gift-opening/FurnitureGiftOpeningView';
|
import { FurnitureBackgroundColorView } from './FurnitureBackgroundColorView';
|
||||||
|
import { FurnitureBadgeDisplayView } from './FurnitureBadgeDisplayView';
|
||||||
|
import { FurnitureCustomStackHeightView } from './FurnitureCustomStackHeightView';
|
||||||
|
import { FurnitureExchangeCreditView } from './FurnitureExchangeCreditView';
|
||||||
|
import { FurnitureExternalImageView } from './FurnitureExternalImageView';
|
||||||
|
import { FurnitureGiftOpeningView } from './FurnitureGiftOpeningView';
|
||||||
|
import { FurnitureManipulationMenuView } from './FurnitureManipulationMenuView';
|
||||||
|
import { FurnitureMannequinView } from './FurnitureMannequinView';
|
||||||
|
import { FurnitureStickieView } from './FurnitureStickieView';
|
||||||
|
import { FurnitureTrophyView } from './FurnitureTrophyView';
|
||||||
import { FurnitureHighScoreView } from './high-score/FurnitureHighScoreView';
|
import { FurnitureHighScoreView } from './high-score/FurnitureHighScoreView';
|
||||||
import { FurnitureManipulationMenuView } from './manipulation-menu/FurnitureManipulationMenuView';
|
|
||||||
import { FurnitureMannequinView } from './mannequin/FurnitureMannequinView';
|
|
||||||
import { FurnitureStickieView } from './stickie/FurnitureStickieView';
|
|
||||||
import { FurnitureTrophyView } from './trophy/FurnitureTrophyView';
|
|
||||||
import { FurnitureYoutubeDisplayView } from './youtube-tv/FurnitureYoutubeDisplayView';
|
import { FurnitureYoutubeDisplayView } from './youtube-tv/FurnitureYoutubeDisplayView';
|
||||||
|
|
||||||
export const FurnitureWidgetsView: FC<{}> = props =>
|
export const FurnitureWidgetsView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
return (
|
return (
|
||||||
<div className="position-absolute nitro-room-widgets top-0 start-0 w-100 h-100">
|
<Base fit position="absolute" className="nitro-room-widgets top-0 start-0">
|
||||||
<FurnitureBackgroundColorView />
|
<FurnitureBackgroundColorView />
|
||||||
<FurnitureContextMenuView />
|
<FurnitureContextMenuView />
|
||||||
<FurnitureCustomStackHeightView />
|
<FurnitureCustomStackHeightView />
|
||||||
@ -34,6 +35,6 @@ export const FurnitureWidgetsView: FC<{}> = props =>
|
|||||||
<FurnitureBadgeDisplayView />
|
<FurnitureBadgeDisplayView />
|
||||||
<FurnitureExternalImageView />
|
<FurnitureExternalImageView />
|
||||||
<FurnitureYoutubeDisplayView />
|
<FurnitureYoutubeDisplayView />
|
||||||
</div>
|
</Base>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,130 +0,0 @@
|
|||||||
import { ApplyTonerComposer, RoomControllerLevel, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
|
||||||
import ReactSlider from 'react-slider';
|
|
||||||
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent, SendMessageComposer } from '../../../../../api';
|
|
||||||
import { Button, Column, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ hue, setHue ] = useState(0);
|
|
||||||
const [ saturation, setSaturation ] = useState(0);
|
|
||||||
const [ lightness, setLightness ] = useState(0);
|
|
||||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
|
||||||
|
|
||||||
const close = useCallback(() =>
|
|
||||||
{
|
|
||||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW));
|
|
||||||
|
|
||||||
setObjectId(-1);
|
|
||||||
}, [ eventDispatcher ]);
|
|
||||||
|
|
||||||
const canOpenBackgroundToner = useCallback(() =>
|
|
||||||
{
|
|
||||||
return (roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator);
|
|
||||||
}, [ roomSession ]);
|
|
||||||
|
|
||||||
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR: {
|
|
||||||
if(!canOpenBackgroundToner()) return;
|
|
||||||
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
|
||||||
const model = roomObject.model;
|
|
||||||
|
|
||||||
setObjectId(roomObject.id);
|
|
||||||
setHue(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
|
|
||||||
setSaturation(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
|
|
||||||
setLightness(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
|
||||||
if(objectId !== event.objectId) return;
|
|
||||||
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ objectId, canOpenBackgroundToner, close ]);
|
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomEngineObjectEvent);
|
|
||||||
|
|
||||||
const processAction = useCallback((name: string) =>
|
|
||||||
{
|
|
||||||
switch(name)
|
|
||||||
{
|
|
||||||
case 'apply':
|
|
||||||
SendMessageComposer(new ApplyTonerComposer(objectId, hue, saturation, lightness));
|
|
||||||
break;
|
|
||||||
case 'toggle':
|
|
||||||
roomSession.useMultistateItem(objectId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}, [ roomSession, objectId, hue, saturation, lightness ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(objectId === -1) return;
|
|
||||||
|
|
||||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, hue, saturation, lightness));
|
|
||||||
}, [ eventDispatcher, objectId, hue, saturation, lightness ]);
|
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView theme="primary-slim" className="nitro-room-widget-toner">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
|
||||||
<NitroCardContentView overflow="hidden" justifyContent="between">
|
|
||||||
<Column overflow="auto" gap={ 1 }>
|
|
||||||
<Column>
|
|
||||||
<Text bold>{ LocalizeText('widget.backgroundcolor.hue') }</Text>
|
|
||||||
<ReactSlider
|
|
||||||
className={ 'nitro-slider' }
|
|
||||||
min={ 0 }
|
|
||||||
max={ 360 }
|
|
||||||
value={ hue }
|
|
||||||
onChange={ event => setHue(event) }
|
|
||||||
thumbClassName={ 'thumb degree' }
|
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
|
||||||
</Column>
|
|
||||||
<Column>
|
|
||||||
<Text bold>{ LocalizeText('widget.backgroundcolor.saturation') }</Text>
|
|
||||||
<ReactSlider
|
|
||||||
className={ 'nitro-slider' }
|
|
||||||
min={ 0 }
|
|
||||||
max={ 100 }
|
|
||||||
value={ saturation }
|
|
||||||
onChange={ event => setSaturation(event) }
|
|
||||||
thumbClassName={ 'thumb percent' }
|
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
|
||||||
</Column>
|
|
||||||
<Column>
|
|
||||||
<Text bold>{ LocalizeText('widget.backgroundcolor.lightness') }</Text>
|
|
||||||
<ReactSlider
|
|
||||||
className={ 'nitro-slider' }
|
|
||||||
min={ 0 }
|
|
||||||
max={ 100 }
|
|
||||||
value={ lightness }
|
|
||||||
onChange={ event => setLightness(event) }
|
|
||||||
thumbClassName={ 'thumb percent' }
|
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
|
||||||
</Column>
|
|
||||||
</Column>
|
|
||||||
<Column gap={ 1 }>
|
|
||||||
<Button fullWidth variant="primary" onClick={ event => processAction('toggle') }>
|
|
||||||
{ LocalizeText('widget.backgroundcolor.button.on') }
|
|
||||||
</Button>
|
|
||||||
<Button fullWidth variant="primary" onClick={ event => processAction('apply') }>
|
|
||||||
{ LocalizeText('widget.backgroundcolor.button.apply') }
|
|
||||||
</Button>
|
|
||||||
</Column>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,69 +0,0 @@
|
|||||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, StringDataType } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useState } from 'react';
|
|
||||||
import { GetRoomEngine, LocalizeBadgeDescription, LocalizeBadgeName, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
|
||||||
import { LayoutTrophyView } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
import { FurnitureTrophyData } from '../trophy/FurnitureTrophyData';
|
|
||||||
|
|
||||||
export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ trophyData, setTrophyData ] = useState<FurnitureTrophyData>(null);
|
|
||||||
const { widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING:
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING: {
|
|
||||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
|
||||||
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
|
||||||
|
|
||||||
if(!roomObject) return;
|
|
||||||
|
|
||||||
const stringStuff = new StringDataType();
|
|
||||||
|
|
||||||
stringStuff.initializeFromRoomObjectModel(roomObject.model);
|
|
||||||
|
|
||||||
const badgeName = LocalizeBadgeName(stringStuff.getValue(1));
|
|
||||||
const badgeDesc = LocalizeBadgeDescription(stringStuff.getValue(1));
|
|
||||||
const date = stringStuff.getValue(2);
|
|
||||||
const senderName = stringStuff.getValue(3);
|
|
||||||
|
|
||||||
setTrophyData(new FurnitureTrophyData(widgetEvent.objectId, widgetEvent.category, '1', senderName, date, badgeDesc, badgeName));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
|
||||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
|
||||||
|
|
||||||
setTrophyData(prevState =>
|
|
||||||
{
|
|
||||||
if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING, onNitroEvent);
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING, onNitroEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, widgetHandler.eventDispatcher, onNitroEvent);
|
|
||||||
|
|
||||||
const processAction = useCallback((type: string, value: string = null) =>
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case 'close':
|
|
||||||
setTrophyData(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(!trophyData) return null;
|
|
||||||
|
|
||||||
return <LayoutTrophyView color={ trophyData.color } message={ trophyData.message } date={ trophyData.date } senderName={ trophyData.ownerName } customTitle={ trophyData.customTitle } onCloseClick={ () => processAction('close') } />;
|
|
||||||
}
|
|
@ -1,104 +0,0 @@
|
|||||||
import { FurnitureStackHeightComposer, FurnitureStackHeightEvent } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
|
||||||
import ReactSlider from 'react-slider';
|
|
||||||
import { LocalizeText, RoomWidgetUpdateCustomStackHeightEvent, SendMessageComposer } from '../../../../../api';
|
|
||||||
import { Button, Column, Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook, UseMessageEventHook } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
const MAX_HEIGHT: number = 40;
|
|
||||||
|
|
||||||
export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ height, setHeight ] = useState(0);
|
|
||||||
const [ pendingHeight, setPendingHeight ] = useState(-1);
|
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
|
||||||
|
|
||||||
const close = () =>
|
|
||||||
{
|
|
||||||
setObjectId(-1);
|
|
||||||
setHeight(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
const updateHeight = useCallback((height: number, fromServer: boolean = false) =>
|
|
||||||
{
|
|
||||||
if(!height) height = 0;
|
|
||||||
|
|
||||||
height = Math.abs(height);
|
|
||||||
|
|
||||||
if(!fromServer) ((height > MAX_HEIGHT) && (height = MAX_HEIGHT));
|
|
||||||
|
|
||||||
setHeight(parseFloat(height.toFixed(2)));
|
|
||||||
|
|
||||||
if(!fromServer) setPendingHeight(height * 100);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateCustomStackHeightEvent = useCallback((event: RoomWidgetUpdateCustomStackHeightEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetUpdateCustomStackHeightEvent.UPDATE_CUSTOM_STACK_HEIGHT: {
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
updateHeight(event.height, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ updateHeight ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateCustomStackHeightEvent.UPDATE_CUSTOM_STACK_HEIGHT, eventDispatcher, onRoomWidgetUpdateCustomStackHeightEvent);
|
|
||||||
|
|
||||||
const onFurnitureStackHeightEvent = useCallback((event: FurnitureStackHeightEvent) =>
|
|
||||||
{
|
|
||||||
const parser = event.getParser();
|
|
||||||
|
|
||||||
if(objectId !== parser.furniId) return;
|
|
||||||
|
|
||||||
updateHeight(parser.height, true);
|
|
||||||
}, [ objectId, updateHeight ]);
|
|
||||||
|
|
||||||
UseMessageEventHook(FurnitureStackHeightEvent, onFurnitureStackHeightEvent);
|
|
||||||
|
|
||||||
const sendUpdate = useCallback((height: number) =>
|
|
||||||
{
|
|
||||||
SendMessageComposer(new FurnitureStackHeightComposer(objectId, ~~(height)));
|
|
||||||
}, [ objectId ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if((objectId === -1) || (pendingHeight === -1)) return;
|
|
||||||
|
|
||||||
const timeout = setTimeout(() => sendUpdate(~~(pendingHeight)), 10);
|
|
||||||
|
|
||||||
return () => clearTimeout(timeout);
|
|
||||||
}, [ objectId, pendingHeight, sendUpdate ]);
|
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-widget-custom-stack-height" theme="primary-slim">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.custom.stack.height.title') } onCloseClick={ close } />
|
|
||||||
<NitroCardContentView justifyContent="between">
|
|
||||||
<Text>{ LocalizeText('widget.custom.stack.height.text') }</Text>
|
|
||||||
<Flex gap={ 2 }>
|
|
||||||
<ReactSlider
|
|
||||||
className="nitro-slider"
|
|
||||||
min={ 0 }
|
|
||||||
max={ MAX_HEIGHT }
|
|
||||||
step={ 0.01 }
|
|
||||||
value={ height }
|
|
||||||
onChange={ event => updateHeight(event) }
|
|
||||||
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
|
|
||||||
<input type="number" min={ 0 } max={ MAX_HEIGHT } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
|
|
||||||
</Flex>
|
|
||||||
<Column gap={ 1 }>
|
|
||||||
<Button onClick={ event => sendUpdate(-100) }>
|
|
||||||
{ LocalizeText('furniture.above.stack') }
|
|
||||||
</Button>
|
|
||||||
<Button onClick={ event => sendUpdate(0) }>
|
|
||||||
{ LocalizeText('furniture.floor.level') }
|
|
||||||
</Button>
|
|
||||||
</Column>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import { FC, useCallback, useState } from 'react';
|
|
||||||
import { IPhotoData, LocalizeText, RoomWidgetUpdateExternalImageEvent } from '../../../../../api';
|
|
||||||
import { Flex, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
export const FurnitureExternalImageView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ photoData, setPhotoData ] = useState<IPhotoData>(null);
|
|
||||||
const { eventDispatcher = null } = useRoomContext();
|
|
||||||
|
|
||||||
const close = () =>
|
|
||||||
{
|
|
||||||
setObjectId(-1);
|
|
||||||
setPhotoData(null)
|
|
||||||
}
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateExternalImageEvent = useCallback((event: RoomWidgetUpdateExternalImageEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE:
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setPhotoData(event.photoData);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateExternalImageEvent.UPDATE_EXTERNAL_IMAGE, eventDispatcher, onRoomWidgetUpdateExternalImageEvent);
|
|
||||||
|
|
||||||
if((objectId === -1) || !photoData) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-external-image-widget" theme="primary-slim">
|
|
||||||
<NitroCardHeaderView headerText={ '' } onCloseClick={ close } />
|
|
||||||
<NitroCardContentView>
|
|
||||||
<Flex center className="picture-preview border border-black" style={ photoData.w ? { backgroundImage: 'url(' + photoData.w + ')' } : {} }>
|
|
||||||
{ !photoData.w &&
|
|
||||||
<Text bold>{ LocalizeText('camera.loading') }</Text> }
|
|
||||||
</Flex>
|
|
||||||
{ photoData.m && photoData.m.length &&
|
|
||||||
<Text center>{ photoData.m }</Text> }
|
|
||||||
<Flex alignItems="center" justifyContent="between">
|
|
||||||
<Text>{ (photoData.n || '') }</Text>
|
|
||||||
<Text>{ new Date(photoData.t * 1000).toLocaleDateString() }</Text>
|
|
||||||
</Flex>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,241 +0,0 @@
|
|||||||
import { RoomObjectCategory, RoomObjectOperationType } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
|
||||||
import { CreateLinkEvent, GetRoomEngine, GetSessionDataManager, LocalizeText, ProductTypeEnum, RoomWidgetPresentOpenMessage, RoomWidgetUpdatePresentDataEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
|
||||||
import { Button, Column, Flex, LayoutGiftTagView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook } from '../../../../../hooks/events/UseEventDispatcherHook';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
const FLOOR: string = 'floor';
|
|
||||||
const WALLPAPER: string = 'wallpaper';
|
|
||||||
const LANDSCAPE: string = 'landscape';
|
|
||||||
|
|
||||||
const ACTION_GIVE_GIFT = 0;
|
|
||||||
const ACTION_OPEN = 1;
|
|
||||||
const ACTION_PLACE = 2;
|
|
||||||
const ACTION_INVENTORY = 3;
|
|
||||||
|
|
||||||
export const FurnitureGiftOpeningView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ classId, setClassId ] = useState(-1);
|
|
||||||
const [ itemType, setItemType ] = useState<string>(null);
|
|
||||||
const [ text, setText ] = useState<string>(null);
|
|
||||||
const [ isOwnerOfFurniture, setIsOwnerOfFurniture ] = useState(false);
|
|
||||||
const [ senderName, setSenderName ] = useState<string>(null);
|
|
||||||
const [ senderFigure, setSenderFigure ] = useState<string>(null);
|
|
||||||
const [ placedItemId, setPlacedItemId ] = useState(-1);
|
|
||||||
const [ placedItemType, setPlacedItemType ] = useState<string>(null);
|
|
||||||
const [ placedInRoom, setPlacedInRoom ] = useState(false);
|
|
||||||
const [ imageUrl, setImageUrl ] = useState<string>(null);
|
|
||||||
const [ openRequested, setOpenRequested ] = useState(false);
|
|
||||||
const { roomSession = null, eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const clearGift = useCallback(() =>
|
|
||||||
{
|
|
||||||
if(!openRequested) setObjectId(-1);
|
|
||||||
|
|
||||||
setText(null);
|
|
||||||
setIsOwnerOfFurniture(false);
|
|
||||||
}, [ openRequested ]);
|
|
||||||
|
|
||||||
const getGiftImageUrl = useCallback((name: string) =>
|
|
||||||
{
|
|
||||||
return '';
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const onRoomWidgetUpdatePresentDataEvent = useCallback((event: RoomWidgetUpdatePresentDataEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.PACKAGEINFO: {
|
|
||||||
setOpenRequested(false);
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setText(event.giftMessage);
|
|
||||||
setIsOwnerOfFurniture(event.isController);
|
|
||||||
setSenderName(event.purchaserName);
|
|
||||||
setSenderFigure(event.purchaserFigure);
|
|
||||||
setImageUrl(event.imageUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR:
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE:
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER: {
|
|
||||||
let imageType: string = null;
|
|
||||||
|
|
||||||
if(event.type === RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR) imageType = 'packagecard_icon_floor';
|
|
||||||
else if(event.type === RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE) imageType = 'packagecard_icon_landscape';
|
|
||||||
else if(event.type === RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER) imageType = 'packagecard_icon_wallpaper';
|
|
||||||
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setClassId(event.classId);
|
|
||||||
setItemType(event.itemType);
|
|
||||||
setText(event.giftMessage);
|
|
||||||
setIsOwnerOfFurniture(event.isController);
|
|
||||||
setPlacedItemId(event.placedItemId);
|
|
||||||
setPlacedItemType(event.placedItemType);
|
|
||||||
setPlacedInRoom(event.placedInRoom);
|
|
||||||
setImageUrl(getGiftImageUrl(imageType));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB: {
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setClassId(event.classId);
|
|
||||||
setItemType(event.itemType);
|
|
||||||
setText(event.giftMessage);
|
|
||||||
setIsOwnerOfFurniture(event.isController);
|
|
||||||
setImageUrl(getGiftImageUrl('packagecard_icon_hc'));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS: {
|
|
||||||
if(!openRequested) return;
|
|
||||||
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setClassId(event.classId);
|
|
||||||
setItemType(event.itemType);
|
|
||||||
setText(event.giftMessage);
|
|
||||||
setIsOwnerOfFurniture(event.isController);
|
|
||||||
setPlacedItemId(event.placedItemId);
|
|
||||||
setPlacedItemType(event.placedItemType);
|
|
||||||
setPlacedInRoom(event.placedInRoom);
|
|
||||||
setImageUrl(event.imageUrl);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE: {
|
|
||||||
if(!openRequested) return;
|
|
||||||
|
|
||||||
setImageUrl(event.imageUrl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ openRequested, getGiftImageUrl ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.PACKAGEINFO, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
|
||||||
|
|
||||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
|
||||||
{
|
|
||||||
if(event.id === objectId) clearGift();
|
|
||||||
|
|
||||||
if(event.id === placedItemId)
|
|
||||||
{
|
|
||||||
if(placedInRoom) setPlacedInRoom(false);
|
|
||||||
}
|
|
||||||
}, [ objectId, placedItemId, placedInRoom, clearGift ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
|
|
||||||
const close = useCallback(() =>
|
|
||||||
{
|
|
||||||
setObjectId(-1);
|
|
||||||
setOpenRequested(false);
|
|
||||||
setPlacedItemId(-1);
|
|
||||||
setPlacedInRoom(false);
|
|
||||||
setText(null);
|
|
||||||
setIsOwnerOfFurniture(false);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const isSpaces = useMemo(() =>
|
|
||||||
{
|
|
||||||
if(itemType !== ProductTypeEnum.WALL) return false;
|
|
||||||
|
|
||||||
const furniData = GetSessionDataManager().getWallItemData(classId);
|
|
||||||
|
|
||||||
if(!furniData) return false;
|
|
||||||
|
|
||||||
const className = furniData.className;
|
|
||||||
|
|
||||||
return (className === FLOOR || className === LANDSCAPE || className === WALLPAPER);
|
|
||||||
}, [ classId, itemType ]);
|
|
||||||
|
|
||||||
const productName = useMemo(() =>
|
|
||||||
{
|
|
||||||
if(objectId === -1) return '';
|
|
||||||
|
|
||||||
if(isSpaces) return 'widget.furni.present.spaces.message_opened';
|
|
||||||
|
|
||||||
return 'widget.furni.present.message_opened';
|
|
||||||
}, [ objectId, isSpaces ]);
|
|
||||||
|
|
||||||
const handleAction = useCallback((action: number) =>
|
|
||||||
{
|
|
||||||
switch(action)
|
|
||||||
{
|
|
||||||
case ACTION_GIVE_GIFT:
|
|
||||||
CreateLinkEvent('catalog/open');
|
|
||||||
return;
|
|
||||||
case ACTION_OPEN:
|
|
||||||
setOpenRequested(true);
|
|
||||||
widgetHandler.processWidgetMessage(new RoomWidgetPresentOpenMessage(RoomWidgetPresentOpenMessage.OPEN_PRESENT, objectId));
|
|
||||||
return;
|
|
||||||
case ACTION_PLACE:
|
|
||||||
return;
|
|
||||||
case ACTION_INVENTORY:
|
|
||||||
if((placedItemId > 0) && placedInRoom)
|
|
||||||
{
|
|
||||||
if(placedItemType === ProductTypeEnum.PET)
|
|
||||||
{
|
|
||||||
roomSession.pickupPet(placedItemId);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, placedItemId, RoomObjectCategory.FLOOR);
|
|
||||||
|
|
||||||
if(roomObject) GetRoomEngine().processRoomObjectOperation(roomObject.id, RoomObjectCategory.FLOOR, RoomObjectOperationType.OBJECT_PICKUP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, [ roomSession, widgetHandler, objectId, placedInRoom, placedItemId, placedItemType, close ]);
|
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-gift-opening" theme="primary-slim">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText(senderName ? 'widget.furni.present.window.title_from' : 'widget.furni.present.window.title', [ 'name' ], [ senderName ]) } onCloseClick={ close } />
|
|
||||||
<NitroCardContentView center>
|
|
||||||
{ (placedItemId === -1) &&
|
|
||||||
<Column overflow="hidden">
|
|
||||||
<Flex center overflow="auto">
|
|
||||||
<LayoutGiftTagView userName={ senderName } figure={ senderFigure } message={ text } />
|
|
||||||
</Flex>
|
|
||||||
<Flex gap={ 1 }>
|
|
||||||
{ senderName &&
|
|
||||||
<Button fullWidth onClick={ event => handleAction(ACTION_GIVE_GIFT) }>
|
|
||||||
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
|
||||||
</Button> }
|
|
||||||
<Button fullWidth variant="success" onClick={ event => handleAction(ACTION_OPEN) }>
|
|
||||||
{ LocalizeText('widget.furni.present.open_gift') }
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</Column> }
|
|
||||||
{ (placedItemId > -1) &&
|
|
||||||
<Column overflow="hidden">
|
|
||||||
<Flex center overflow="auto" gap={ 2 }>
|
|
||||||
<img src={ imageUrl } className="no-select" alt="" />
|
|
||||||
<Text wrap>{ LocalizeText(productName, [ 'product' ], [ text ]) }</Text>
|
|
||||||
</Flex>
|
|
||||||
<Column grow gap={ 1 }>
|
|
||||||
<Flex gap={ 1 }>
|
|
||||||
<Button fullWidth onClick={ event => handleAction(ACTION_INVENTORY) }>
|
|
||||||
{ LocalizeText('widget.furni.present.put_in_inventory') }
|
|
||||||
</Button>
|
|
||||||
<Button fullWidth variant="success" onClick={ event => handleAction(ACTION_PLACE) }>
|
|
||||||
{ LocalizeText(placedInRoom ? 'widget.furni.present.keep_in_room' : 'widget.furni.present.place_in_room') }
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
{ (senderName && senderName.length) &&
|
|
||||||
<Button fullWidth onClick={ event => handleAction(ACTION_GIVE_GIFT) }>
|
|
||||||
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
|
||||||
</Button> }
|
|
||||||
</Column>
|
|
||||||
</Column> }
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,103 +0,0 @@
|
|||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
|
||||||
import { RoomObjectOperationType } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
|
||||||
import { ProcessRoomObjectOperation, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
|
||||||
import { UseEventDispatcherHook } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
import { ObjectLocationView } from '../../object-location/ObjectLocationView';
|
|
||||||
|
|
||||||
export const FurnitureManipulationMenuView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ objectType, setObjectType ] = useState(-1);
|
|
||||||
const { roomSession = null, eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
|
|
||||||
const rotateFurniture = useCallback(() =>
|
|
||||||
{
|
|
||||||
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
|
||||||
}, [ objectId, objectType ]);
|
|
||||||
|
|
||||||
const moveFurniture = useCallback(() =>
|
|
||||||
{
|
|
||||||
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_MOVE);
|
|
||||||
}, [ objectId, objectType ]);
|
|
||||||
|
|
||||||
const pickupFurniture = useCallback(() =>
|
|
||||||
{
|
|
||||||
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_PICKUP);
|
|
||||||
}, [ objectId, objectType ]);
|
|
||||||
|
|
||||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION: {
|
|
||||||
setIsVisible(true);
|
|
||||||
setObjectId(event.id);
|
|
||||||
setObjectType(event.category);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
|
||||||
if(event.id === objectId)
|
|
||||||
{
|
|
||||||
setIsVisible(false);
|
|
||||||
setObjectId(-1);
|
|
||||||
setObjectType(-1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED: {
|
|
||||||
setIsVisible(false);
|
|
||||||
setObjectId(-1);
|
|
||||||
setObjectType(-1);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ objectId ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateDecorateModeEvent = useCallback((event: RoomWidgetUpdateDecorateModeEvent) =>
|
|
||||||
{
|
|
||||||
if(event.isDecorating) return;
|
|
||||||
|
|
||||||
moveFurniture();
|
|
||||||
|
|
||||||
setIsVisible(false);
|
|
||||||
setObjectId(-1);
|
|
||||||
setObjectType(-1);
|
|
||||||
}, [ moveFurniture ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateDecorateModeEvent.UPDATE_DECORATE, eventDispatcher, onRoomWidgetUpdateDecorateModeEvent);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
if(!isVisible)
|
|
||||||
{
|
|
||||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(false));
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateDecorateModeEvent(true));
|
|
||||||
|
|
||||||
moveFurniture();
|
|
||||||
}, [ eventDispatcher, isVisible, moveFurniture ]);
|
|
||||||
|
|
||||||
if(!isVisible) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ObjectLocationView objectId={ objectId } category={ objectType }>
|
|
||||||
<div className="btn-group">
|
|
||||||
<button type="button" className="btn btn-primary btn-sm" onClick={ pickupFurniture }>
|
|
||||||
<FontAwesomeIcon icon="times" />
|
|
||||||
</button>
|
|
||||||
<button type="button" className="btn btn-primary btn-sm" onClick={ rotateFurniture }>
|
|
||||||
<FontAwesomeIcon icon="undo" />
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</ObjectLocationView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export class FurnitureMannequinData
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
public objectId: number,
|
|
||||||
public category: number,
|
|
||||||
public name: string,
|
|
||||||
public figure: string,
|
|
||||||
public gender: string,
|
|
||||||
public clubLevel: number,
|
|
||||||
public renderedFigure: string = null)
|
|
||||||
{}
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
import { FC } from 'react';
|
|
||||||
import { Base, LayoutAvatarImageView, LayoutCurrencyIcon } from '../../../../../common';
|
|
||||||
|
|
||||||
interface FurnitureMannequinPreviewViewProps
|
|
||||||
{
|
|
||||||
figure: string;
|
|
||||||
clubLevel: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const FurnitureMannequinPreviewView: FC<FurnitureMannequinPreviewViewProps> = props =>
|
|
||||||
{
|
|
||||||
const { figure = null, clubLevel = 0 } = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Base position="relative" className="mannequin-preview">
|
|
||||||
<LayoutAvatarImageView figure={ figure } direction={ 2 } />
|
|
||||||
{ (clubLevel > 0) &&
|
|
||||||
<LayoutCurrencyIcon className="position-absolute end-2 bottom-2" type="hc" /> }
|
|
||||||
</Base>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,221 +0,0 @@
|
|||||||
import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, HabboClubLevelEnum, IAvatarFigureContainer, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react';
|
|
||||||
import { GetAvatarRenderManager, GetClubMemberLevel, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent, SendMessageComposer } from '../../../../../api';
|
|
||||||
import { Base, Button, Column, Flex, LayoutAvatarImageView, LayoutCurrencyIcon, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
|
|
||||||
const MODE_NONE: number = -1;
|
|
||||||
const MODE_CONTROLLER: number = 0;
|
|
||||||
const MODE_UPDATE: number = 1;
|
|
||||||
const MODE_PEER: number = 2;
|
|
||||||
const MODE_NO_CLUB: number = 3;
|
|
||||||
const MODE_WRONG_GENDER: number = 4;
|
|
||||||
|
|
||||||
const ACTION_SET_NAME: number = 1;
|
|
||||||
const ACTION_WEAR: number = 2;
|
|
||||||
const ACTION_SAVE: number = 3;
|
|
||||||
|
|
||||||
const MANNEQUIN_FIGURE = [ 'hd', 99999, [ 99998 ] ];
|
|
||||||
const MANNEQUIN_CLOTHING_PART_TYPES = [
|
|
||||||
AvatarFigurePartType.CHEST_ACCESSORY,
|
|
||||||
AvatarFigurePartType.COAT_CHEST,
|
|
||||||
AvatarFigurePartType.CHEST,
|
|
||||||
AvatarFigurePartType.LEGS,
|
|
||||||
AvatarFigurePartType.SHOES,
|
|
||||||
AvatarFigurePartType.WAIST_ACCESSORY
|
|
||||||
];
|
|
||||||
|
|
||||||
export const FurnitureMannequinView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
|
||||||
const [ figure, setFigure ] = useState<string>(null);
|
|
||||||
const [ gender, setGender ] = useState<string>(null);
|
|
||||||
const [ name, setName ] = useState<string>(null);
|
|
||||||
const [ clubLevel, setClubLevel ] = useState(HabboClubLevelEnum.NO_CLUB);
|
|
||||||
const [ renderedFigure, setRenderedFigure ] = useState<string>(null);
|
|
||||||
const [ renderedClubLevel, setRenderedClubLevel ] = useState(HabboClubLevelEnum.NO_CLUB);
|
|
||||||
const [ mode, setMode ] = useState(MODE_NONE);
|
|
||||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateMannequinEvent = useCallback((event: RoomWidgetUpdateMannequinEvent) =>
|
|
||||||
{
|
|
||||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(event.figure);
|
|
||||||
const figureClubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, event.gender, MANNEQUIN_CLOTHING_PART_TYPES);
|
|
||||||
|
|
||||||
setObjectId(event.objectId);
|
|
||||||
setFigure(event.figure);
|
|
||||||
setGender(event.gender);
|
|
||||||
setName(event.name);
|
|
||||||
setClubLevel(figureClubLevel);
|
|
||||||
|
|
||||||
if(roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator)
|
|
||||||
{
|
|
||||||
setMode(MODE_CONTROLLER);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(GetSessionDataManager().gender.toLowerCase() !== event.gender.toLowerCase())
|
|
||||||
{
|
|
||||||
setMode(MODE_WRONG_GENDER);
|
|
||||||
}
|
|
||||||
|
|
||||||
else if(GetClubMemberLevel() < figureClubLevel)
|
|
||||||
{
|
|
||||||
setMode(MODE_NO_CLUB);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
setMode(MODE_PEER);
|
|
||||||
}
|
|
||||||
}, [ roomSession ]);
|
|
||||||
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateMannequinEvent.MANNEQUIN_UPDATE, eventDispatcher, onRoomWidgetUpdateMannequinEvent);
|
|
||||||
|
|
||||||
const getMergedFigureContainer = (figure: string, targetFigure: string) =>
|
|
||||||
{
|
|
||||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(figure);
|
|
||||||
const targetFigureContainer = GetAvatarRenderManager().createFigureContainer(targetFigure);
|
|
||||||
|
|
||||||
for(const part of MANNEQUIN_CLOTHING_PART_TYPES) figureContainer.removePart(part);
|
|
||||||
|
|
||||||
for(const part of targetFigureContainer.getPartTypeIds())
|
|
||||||
{
|
|
||||||
figureContainer.updatePart(part, targetFigureContainer.getPartSetId(part), targetFigureContainer.getPartColorIds(part));
|
|
||||||
}
|
|
||||||
|
|
||||||
return figureContainer;
|
|
||||||
}
|
|
||||||
|
|
||||||
const transformAsMannequinFigure = (figureContainer: IAvatarFigureContainer) =>
|
|
||||||
{
|
|
||||||
for(const part of figureContainer.getPartTypeIds())
|
|
||||||
{
|
|
||||||
if(MANNEQUIN_CLOTHING_PART_TYPES.indexOf(part) >= 0) continue;
|
|
||||||
|
|
||||||
figureContainer.removePart(part);
|
|
||||||
}
|
|
||||||
|
|
||||||
figureContainer.updatePart((MANNEQUIN_FIGURE[0] as string), (MANNEQUIN_FIGURE[1] as number), (MANNEQUIN_FIGURE[2] as number[]));
|
|
||||||
};
|
|
||||||
|
|
||||||
const processAction = useCallback((action: number, value: string = null) =>
|
|
||||||
{
|
|
||||||
switch(action)
|
|
||||||
{
|
|
||||||
case ACTION_SAVE:
|
|
||||||
SendMessageComposer(new FurnitureMannequinSaveLookComposer(objectId));
|
|
||||||
break;
|
|
||||||
case ACTION_WEAR:
|
|
||||||
SendMessageComposer(new FurnitureMultiStateComposer(objectId));
|
|
||||||
break;
|
|
||||||
case ACTION_SET_NAME:
|
|
||||||
SendMessageComposer(new FurnitureMannequinSaveNameComposer(objectId, name));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setMode(MODE_NONE);
|
|
||||||
}, [ objectId, name ]);
|
|
||||||
|
|
||||||
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
|
||||||
{
|
|
||||||
if(event.key !== 'Enter') return;
|
|
||||||
|
|
||||||
processAction(ACTION_SET_NAME);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
switch(mode)
|
|
||||||
{
|
|
||||||
case MODE_CONTROLLER:
|
|
||||||
case MODE_WRONG_GENDER: {
|
|
||||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(figure);
|
|
||||||
|
|
||||||
transformAsMannequinFigure(figureContainer);
|
|
||||||
|
|
||||||
setRenderedFigure(figureContainer.getFigureString());
|
|
||||||
setRenderedClubLevel(clubLevel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MODE_UPDATE: {
|
|
||||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(GetSessionDataManager().figure);
|
|
||||||
|
|
||||||
transformAsMannequinFigure(figureContainer);
|
|
||||||
|
|
||||||
setRenderedFigure(figureContainer.getFigureString());
|
|
||||||
setRenderedClubLevel(GetAvatarRenderManager().getFigureClubLevel(figureContainer, GetSessionDataManager().gender, MANNEQUIN_CLOTHING_PART_TYPES));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case MODE_PEER:
|
|
||||||
case MODE_NO_CLUB: {
|
|
||||||
const figureContainer = getMergedFigureContainer(GetSessionDataManager().figure, figure);
|
|
||||||
|
|
||||||
setRenderedFigure(figureContainer.getFigureString());
|
|
||||||
setRenderedClubLevel(clubLevel);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [ mode, figure, clubLevel ]);
|
|
||||||
|
|
||||||
if(mode === MODE_NONE) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<NitroCardView className="nitro-mannequin" theme="primary-slim">
|
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ event => setMode(MODE_NONE) } />
|
|
||||||
<NitroCardContentView center>
|
|
||||||
<Flex gap={ 2 } overflow="hidden">
|
|
||||||
<Column>
|
|
||||||
<Base position="relative" className="mannequin-preview">
|
|
||||||
<LayoutAvatarImageView figure={ renderedFigure } direction={ 2 } />
|
|
||||||
{ (clubLevel > 0) &&
|
|
||||||
<LayoutCurrencyIcon className="position-absolute end-2 bottom-2" type="hc" /> }
|
|
||||||
</Base>
|
|
||||||
</Column>
|
|
||||||
<Column justifyContent="between" overflow="auto">
|
|
||||||
{ (mode === MODE_CONTROLLER) &&
|
|
||||||
<>
|
|
||||||
<input type="text" className="form-control" value={ name } onChange={ event => setName(event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
|
|
||||||
<Column gap={ 1 }>
|
|
||||||
<Button variant="success" onClick={ event => setMode(MODE_UPDATE) }>
|
|
||||||
{ LocalizeText('mannequin.widget.style') }
|
|
||||||
</Button>
|
|
||||||
<Button variant="success" onClick={ event => processAction(ACTION_WEAR) }>
|
|
||||||
{ LocalizeText('mannequin.widget.wear') }
|
|
||||||
</Button>
|
|
||||||
</Column>
|
|
||||||
</> }
|
|
||||||
{ (mode === MODE_UPDATE) &&
|
|
||||||
<>
|
|
||||||
<Column gap={ 1 }>
|
|
||||||
<Text bold>{ name }</Text>
|
|
||||||
<Text wrap>{ LocalizeText('mannequin.widget.savetext') }</Text>
|
|
||||||
</Column>
|
|
||||||
<Flex alignItems="center" justifyContent="between">
|
|
||||||
<Text underline pointer onClick={ event => setMode(MODE_CONTROLLER) }>
|
|
||||||
{ LocalizeText('mannequin.widget.back') }
|
|
||||||
</Text>
|
|
||||||
<Button variant="success" onClick={ event => processAction(ACTION_SAVE) }>
|
|
||||||
{ LocalizeText('mannequin.widget.save') }
|
|
||||||
</Button>
|
|
||||||
</Flex>
|
|
||||||
</> }
|
|
||||||
{ (mode === MODE_PEER) &&
|
|
||||||
<>
|
|
||||||
<Column gap={ 1 }>
|
|
||||||
<Text bold>{ name }</Text>
|
|
||||||
<Text>{ LocalizeText('mannequin.widget.weartext') }</Text>
|
|
||||||
</Column>
|
|
||||||
<Button variant="success" onClick={ event => processAction(ACTION_WEAR) }>
|
|
||||||
{ LocalizeText('mannequin.widget.wear') }
|
|
||||||
</Button>
|
|
||||||
</> }
|
|
||||||
{ (mode === MODE_NO_CLUB) &&
|
|
||||||
<Text>{ LocalizeText('mannequin.widget.clubnotification') }</Text> }
|
|
||||||
{ (mode === MODE_WRONG_GENDER) &&
|
|
||||||
<Text>{ LocalizeText('mannequin.widget.wronggender') }</Text> }
|
|
||||||
</Column>
|
|
||||||
</Flex>
|
|
||||||
</NitroCardContentView>
|
|
||||||
</NitroCardView>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export class FurnitureStickieData
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
public objectId: number,
|
|
||||||
public category: number,
|
|
||||||
public color: string,
|
|
||||||
public text: string,
|
|
||||||
public canModify: boolean = false,
|
|
||||||
public isEditing: boolean = false)
|
|
||||||
{}
|
|
||||||
}
|
|
@ -1,11 +0,0 @@
|
|||||||
export const STICKIE_COLORS = [ '9CCEFF','FF9CFF', '9CFF9C','FFFF33' ];
|
|
||||||
export const STICKIE_COLOR_NAMES = [ 'blue', 'pink', 'green', 'yellow' ];
|
|
||||||
|
|
||||||
export function getStickieColorName(color: string): string
|
|
||||||
{
|
|
||||||
let index = STICKIE_COLORS.indexOf(color);
|
|
||||||
|
|
||||||
if(index === -1) index = 0;
|
|
||||||
|
|
||||||
return STICKIE_COLOR_NAMES[index];
|
|
||||||
}
|
|
@ -1,99 +0,0 @@
|
|||||||
.nitro-stickie {
|
|
||||||
position: relative;
|
|
||||||
width: 185px;
|
|
||||||
height: 178px;
|
|
||||||
top: 25px;
|
|
||||||
left: 25px;
|
|
||||||
padding: 1px;
|
|
||||||
pointer-events: all;
|
|
||||||
|
|
||||||
.stickie-header {
|
|
||||||
width: 183px;
|
|
||||||
height: 18px;
|
|
||||||
padding: 0 7px;
|
|
||||||
|
|
||||||
.header-trash,
|
|
||||||
.header-close {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stickie-color {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.stickie-context {
|
|
||||||
width: 183px;
|
|
||||||
height: 145px;
|
|
||||||
padding: 2px 7px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: $black;
|
|
||||||
|
|
||||||
.context-text {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
padding: 0;
|
|
||||||
overflow-wrap: break-word;
|
|
||||||
white-space: break-spaces;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
textarea {
|
|
||||||
background: transparent;
|
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
resize: none;
|
|
||||||
font-style: italic;
|
|
||||||
|
|
||||||
&:active {
|
|
||||||
border: 0;
|
|
||||||
outline: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.nitro-stickie-image {
|
|
||||||
background-image: url('../../../../../assets/images/room-widgets/stickie-widget/stickie-spritesheet.png');
|
|
||||||
|
|
||||||
&.stickie-blue,
|
|
||||||
&.stickie-yellow,
|
|
||||||
&.stickie-green,
|
|
||||||
&.stickie-pink {
|
|
||||||
width: 185px;
|
|
||||||
height: 178px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-blue {
|
|
||||||
background-position: -2px -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-yellow {
|
|
||||||
background-image: url('../../../../../assets/images/room-widgets/stickie-widget/stickie-yellow.png');
|
|
||||||
//background-position: -191px -184px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-green {
|
|
||||||
background-position: -191px -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-pink {
|
|
||||||
background-position: -2px -184px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-close {
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
background-position: -2px -366px;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.stickie-trash {
|
|
||||||
width: 9px;
|
|
||||||
height: 10px;
|
|
||||||
background-position: -16px -366px;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useState } from 'react';
|
|
||||||
import { ColorUtils, GetRoomEngine, GetRoomSession, GetSessionDataManager, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
|
||||||
import { DraggableWindow, DraggableWindowPosition } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
import { FurnitureStickieData } from './FurnitureStickieData';
|
|
||||||
import { getStickieColorName, STICKIE_COLORS } from './FurnitureStickieUtils';
|
|
||||||
|
|
||||||
export const FurnitureStickieView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
const [ stickieData, setStickieData ] = useState<FurnitureStickieData>(null);
|
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_STICKIE: {
|
|
||||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
|
||||||
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
|
||||||
|
|
||||||
if(!roomObject) return;
|
|
||||||
|
|
||||||
const data = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_ITEMDATA);
|
|
||||||
|
|
||||||
if(data.length < 6) return;
|
|
||||||
|
|
||||||
let color: string = null;
|
|
||||||
let text: string = null;
|
|
||||||
|
|
||||||
if(data.indexOf(' ') > 0)
|
|
||||||
{
|
|
||||||
color = data.slice(0, data.indexOf(' '));
|
|
||||||
text = data.slice((data.indexOf(' ') + 1), data.length);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
color = data;
|
|
||||||
}
|
|
||||||
|
|
||||||
setStickieData(new FurnitureStickieData(widgetEvent.objectId, widgetEvent.category, color, text, (GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator), false));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
|
||||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
|
||||||
|
|
||||||
setStickieData(prevState =>
|
|
||||||
{
|
|
||||||
if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, onNitroEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
|
||||||
|
|
||||||
const processAction = useCallback((type: string, value: string = null) =>
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case 'close':
|
|
||||||
setStickieData(null);
|
|
||||||
return;
|
|
||||||
case 'trash':
|
|
||||||
setStickieData(prevState =>
|
|
||||||
{
|
|
||||||
if(!prevState) return null;
|
|
||||||
|
|
||||||
GetRoomEngine().deleteRoomObject(prevState.objectId, prevState.category);
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case 'changeColor':
|
|
||||||
setStickieData(prevState =>
|
|
||||||
{
|
|
||||||
const newStickieData = new FurnitureStickieData(prevState.objectId, prevState.category, value, prevState.text, prevState.canModify);
|
|
||||||
|
|
||||||
GetRoomEngine().modifyRoomObjectData(newStickieData.objectId, newStickieData.category, newStickieData.color, newStickieData.text);
|
|
||||||
|
|
||||||
return newStickieData;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case 'changeText':
|
|
||||||
setStickieData(prevState =>
|
|
||||||
{
|
|
||||||
const newStickieData = new FurnitureStickieData(prevState.objectId, prevState.category, prevState.color, value, prevState.canModify);
|
|
||||||
|
|
||||||
GetRoomEngine().modifyRoomObjectData(newStickieData.objectId, newStickieData.category, newStickieData.color, newStickieData.text);
|
|
||||||
|
|
||||||
return newStickieData;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
case 'editMode':
|
|
||||||
setStickieData(prevValue =>
|
|
||||||
{
|
|
||||||
if(!prevValue.canModify) return prevValue;
|
|
||||||
|
|
||||||
return new FurnitureStickieData(prevValue.objectId, prevValue.category, prevValue.color, prevValue.text, prevValue.canModify, true);
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(!stickieData) return null;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<DraggableWindow handleSelector=".drag-handler" windowPosition={ DraggableWindowPosition.NOTHING }>
|
|
||||||
<div className={ 'nitro-stickie nitro-stickie-image stickie-' + getStickieColorName(stickieData.color) }>
|
|
||||||
<div className="d-flex align-items-center stickie-header drag-handler">
|
|
||||||
<div className="d-flex align-items-center flex-grow-1 h-100">
|
|
||||||
{ stickieData.canModify &&
|
|
||||||
<>
|
|
||||||
<div className="nitro-stickie-image stickie-trash header-trash" onClick={ event => processAction('trash') }></div>
|
|
||||||
{ STICKIE_COLORS.map(color =>
|
|
||||||
{
|
|
||||||
return <div key={ color } className="stickie-color ms-1" onClick={ event => processAction('changeColor', color) } style={ { backgroundColor: ColorUtils.makeColorHex(color) } } />
|
|
||||||
}) }
|
|
||||||
</> }
|
|
||||||
</div>
|
|
||||||
<div className="d-flex align-items-center nitro-stickie-image stickie-close header-close" onClick={ event => processAction('close') }></div>
|
|
||||||
</div>
|
|
||||||
<div className="stickie-context">
|
|
||||||
{ !stickieData.isEditing ? <div className="context-text" onClick={ event => processAction('editMode') }>{ stickieData.text }</div> : <textarea className="context-text" defaultValue={ stickieData.text || '' } tabIndex={ 0 } onBlur={ event => processAction('changeText', event.target.value) } autoFocus></textarea> }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</DraggableWindow>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,12 +0,0 @@
|
|||||||
export class FurnitureTrophyData
|
|
||||||
{
|
|
||||||
constructor(
|
|
||||||
public objectId: number,
|
|
||||||
public category: number,
|
|
||||||
public color: string,
|
|
||||||
public ownerName: string,
|
|
||||||
public date: string,
|
|
||||||
public message: string,
|
|
||||||
public customTitle?: string)
|
|
||||||
{}
|
|
||||||
}
|
|
@ -1,72 +0,0 @@
|
|||||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
|
||||||
import { FC, useCallback, useState } from 'react';
|
|
||||||
import { GetRoomEngine, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
|
||||||
import { LayoutTrophyView } from '../../../../../common';
|
|
||||||
import { UseEventDispatcherHook, UseRoomEngineEvent } from '../../../../../hooks';
|
|
||||||
import { useRoomContext } from '../../../RoomContext';
|
|
||||||
import { FurnitureTrophyData } from './FurnitureTrophyData';
|
|
||||||
|
|
||||||
export const FurnitureTrophyView: FC<{}> = props =>
|
|
||||||
{
|
|
||||||
|
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
|
||||||
const [ trophyData, setTrophyData ] = useState<FurnitureTrophyData>(null);
|
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_TROPHY: {
|
|
||||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
|
||||||
|
|
||||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
|
||||||
|
|
||||||
if(!roomObject) return;
|
|
||||||
|
|
||||||
let data = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA);
|
|
||||||
let extra = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_EXTRAS);
|
|
||||||
|
|
||||||
if(!extra) extra = '0';
|
|
||||||
|
|
||||||
const color = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_COLOR);
|
|
||||||
const ownerName = data.substring(0, data.indexOf('\t'));
|
|
||||||
|
|
||||||
data = data.substring((ownerName.length + 1), data.length);
|
|
||||||
|
|
||||||
const trophyDate = data.substring(0, data.indexOf('\t'));
|
|
||||||
const trophyText = data.substr((trophyDate.length + 1), data.length);
|
|
||||||
|
|
||||||
setTrophyData(new FurnitureTrophyData(widgetEvent.objectId, widgetEvent.category, color, ownerName, trophyDate, trophyText));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
|
||||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
|
||||||
|
|
||||||
setTrophyData(prevState =>
|
|
||||||
{
|
|
||||||
if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
|
||||||
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, onNitroEvent);
|
|
||||||
UseEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, widgetHandler.eventDispatcher, onNitroEvent);
|
|
||||||
|
|
||||||
const processAction = useCallback((type: string, value: string = null) =>
|
|
||||||
{
|
|
||||||
switch(type)
|
|
||||||
{
|
|
||||||
case 'close':
|
|
||||||
setTrophyData(null);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if(!trophyData) return null;
|
|
||||||
|
|
||||||
return <LayoutTrophyView color={ trophyData.color } message={ trophyData.message } date={ trophyData.date } senderName={ trophyData.ownerName } onCloseClick={ () => processAction('close') } />;
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user