mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
Merge branch 'dev' into feature/mod-tools
This commit is contained in:
commit
20af2633dd
@ -35,6 +35,15 @@ $navigator-height: 420px;
|
||||
$chat-input-style-selector-widget-width: 200px;
|
||||
$chat-input-style-selector-widget-height: 200px;
|
||||
|
||||
$user-profile-width: 560px;
|
||||
$user-profile-height: 500px;
|
||||
|
||||
$nitro-widget-custom-stack-height-width: 275px;
|
||||
$nitro-widget-custom-stack-height-height: 220px;
|
||||
|
||||
$nitro-widget-exchange-credit-width: 375px;
|
||||
$nitro-widget-exchange-credit-height: 150px;
|
||||
|
||||
.nitro-app {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -0,0 +1,41 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateMannequinEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static MANNEQUIN_UPDATE: string = 'RWUME_MANNEQUIN_UPDATE';
|
||||
|
||||
private _objectId: number;
|
||||
private _figure: string;
|
||||
private _gender: string;
|
||||
private _name: string;
|
||||
|
||||
constructor(type: string, objectId: number, figure: string, gender: string, name: string)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._objectId = objectId;
|
||||
this._figure = figure;
|
||||
this._gender = gender;
|
||||
this._name = name;
|
||||
}
|
||||
|
||||
public get objectId(): number
|
||||
{
|
||||
return this._objectId;
|
||||
}
|
||||
|
||||
public get figure(): string
|
||||
{
|
||||
return this._figure;
|
||||
}
|
||||
|
||||
public get gender(): string
|
||||
{
|
||||
return this._gender;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
}
|
@ -1,9 +1,9 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetRoomEngineUpdateEvent extends RoomWidgetUpdateEvent
|
||||
export class RoomWidgetUpdateRoomEngineEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static GAME_MODE: string = 'RWREUE_GAME_MODE';
|
||||
public static NORMAL_MODE: string = 'RWREUE_NORMAL_MODE';
|
||||
public static GAME_MODE: string = 'RWUREE_GAME_MODE';
|
||||
public static NORMAL_MODE: string = 'RWUREE_NORMAL_MODE';
|
||||
|
||||
private _roomId: number = 0;
|
||||
|
@ -1,16 +1,16 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetRoomObjectUpdateEvent extends RoomWidgetUpdateEvent
|
||||
export class RoomWidgetUpdateRoomObjectEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static OBJECT_SELECTED: string = 'RWROUE_OBJECT_SELECTED';
|
||||
public static OBJECT_DESELECTED: string = 'RWROUE_OBJECT_DESELECTED';
|
||||
public static USER_REMOVED: string = 'RWROUE_USER_REMOVED';
|
||||
public static FURNI_REMOVED: string = 'RWROUE_FURNI_REMOVED';
|
||||
public static FURNI_ADDED: string = 'RWROUE_FURNI_ADDED';
|
||||
public static USER_ADDED: string = 'RWROUE_USER_ADDED';
|
||||
public static OBJECT_ROLL_OVER: string = 'RWROUE_OBJECT_ROLL_OVER';
|
||||
public static OBJECT_ROLL_OUT: string = 'RWROUE_OBJECT_ROLL_OUT';
|
||||
public static OBJECT_REQUEST_MANIPULATION: string = 'RWROUE_OBJECT_REQUEST_MANIPULATION';
|
||||
public static OBJECT_SELECTED: string = 'RWUROE_OBJECT_SELECTED';
|
||||
public static OBJECT_DESELECTED: string = 'RWUROE_OBJECT_DESELECTED';
|
||||
public static USER_REMOVED: string = 'RWUROE_USER_REMOVED';
|
||||
public static FURNI_REMOVED: string = 'RWUROE_FURNI_REMOVED';
|
||||
public static FURNI_ADDED: string = 'RWUROE_FURNI_ADDED';
|
||||
public static USER_ADDED: string = 'RWUROE_USER_ADDED';
|
||||
public static OBJECT_ROLL_OVER: string = 'RWUROE_OBJECT_ROLL_OVER';
|
||||
public static OBJECT_ROLL_OUT: string = 'RWUROE_OBJECT_ROLL_OUT';
|
||||
public static OBJECT_REQUEST_MANIPULATION: string = 'RWUROE_OBJECT_REQUEST_MANIPULATION';
|
||||
|
||||
private _id: number;
|
||||
private _category: number;
|
@ -0,0 +1,48 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateTrophyEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static TROPHY_UPDATE: string = 'RWUTE_TROPHY_UPDATE';
|
||||
|
||||
private _color: number;
|
||||
private _name: string;
|
||||
private _date: string;
|
||||
private _message: string;
|
||||
private _extra: number;
|
||||
|
||||
constructor(type: string, color: number, name: string, date: string, message: string, extra: number)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._color = color;
|
||||
this._name = name;
|
||||
this._date = date;
|
||||
this._message = message;
|
||||
this._extra = extra;
|
||||
}
|
||||
|
||||
public get color(): number
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public get name(): string
|
||||
{
|
||||
return this._name;
|
||||
}
|
||||
|
||||
public get date(): string
|
||||
{
|
||||
return this._date;
|
||||
}
|
||||
|
||||
public get message(): string
|
||||
{
|
||||
return this._message;
|
||||
}
|
||||
|
||||
public get extra(): number
|
||||
{
|
||||
return this._extra;
|
||||
}
|
||||
}
|
@ -6,8 +6,6 @@ export * from './RoomWidgetChooserContentEvent';
|
||||
export * from './RoomWidgetDoorbellEvent';
|
||||
export * from './RoomWidgetFloodControlEvent';
|
||||
export * from './RoomWidgetObjectNameEvent';
|
||||
export * from './RoomWidgetRoomEngineUpdateEvent';
|
||||
export * from './RoomWidgetRoomObjectUpdateEvent';
|
||||
export * from './RoomWidgetUpdateBackgroundColorPreviewEvent';
|
||||
export * from './RoomWidgetUpdateChatEvent';
|
||||
export * from './RoomWidgetUpdateChatInputContentEvent';
|
||||
@ -24,10 +22,14 @@ export * from './RoomWidgetUpdateInfostandFurniEvent';
|
||||
export * from './RoomWidgetUpdateInfostandPetEvent';
|
||||
export * from './RoomWidgetUpdateInfostandRentableBotEvent';
|
||||
export * from './RoomWidgetUpdateInfostandUserEvent';
|
||||
export * from './RoomWidgetUpdateMannequinEvent';
|
||||
export * from './RoomWidgetUpdatePresentDataEvent';
|
||||
export * from './RoomWidgetUpdateRentableBotChatEvent';
|
||||
export * from './RoomWidgetUpdateRoomEngineEvent';
|
||||
export * from './RoomWidgetUpdateRoomObjectEvent';
|
||||
export * from './RoomWidgetUpdateRoomViewEvent';
|
||||
export * from './RoomWidgetUpdateSongEvent';
|
||||
export * from './RoomWidgetUpdateTrophyEvent';
|
||||
export * from './RoomWidgetUpdateUserDataEvent';
|
||||
export * from './RoomWidgetUseProductBubbleEvent';
|
||||
export * from './UseProductItem';
|
||||
|
@ -0,0 +1,54 @@
|
||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable, RoomWidgetEnum } from '@nitrots/nitro-renderer';
|
||||
import { RoomWidgetUpdateMannequinEvent } from '..';
|
||||
import { GetRoomEngine } from '../../GetRoomEngine';
|
||||
import { RoomWidgetUpdateEvent } from '../events/RoomWidgetUpdateEvent';
|
||||
import { RoomWidgetMessage } from '../messages/RoomWidgetMessage';
|
||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||
|
||||
export class FurnitureMannequinWidgetHandler extends RoomWidgetHandler
|
||||
{
|
||||
public processEvent(event: NitroEvent): void
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN: {
|
||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
||||
|
||||
if(!roomObject) return;
|
||||
|
||||
const model = roomObject.model;
|
||||
const figure = model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE);
|
||||
const gender = model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER);
|
||||
const name = model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME);
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateMannequinEvent(RoomWidgetUpdateMannequinEvent.MANNEQUIN_UPDATE, roomObject.id, figure, gender, name));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
switch(message.type)
|
||||
{
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return RoomWidgetEnum.MANNEQUIN;
|
||||
}
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [ RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN ];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [];
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@ export * from './FurnitureCreditWidgetHandler';
|
||||
export * from './FurnitureCustomStackHeightWidgetHandler';
|
||||
export * from './FurnitureDimmerWidgetHandler';
|
||||
export * from './FurnitureExternalImageWidgetHandler';
|
||||
export * from './FurnitureMannequinWidgetHandler';
|
||||
export * from './FurniturePresentWidgetHandler';
|
||||
export * from './IRoomWidgetHandler';
|
||||
export * from './IRoomWidgetHandlerManager';
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 9.3 KiB |
@ -13,6 +13,7 @@ $nitro-card-tabs-height: 33px;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
pointer-events: none;
|
||||
overflow: hidden;
|
||||
|
||||
.theme-primary {
|
||||
border: $border-width solid $border-color;
|
||||
@ -25,7 +26,7 @@ $nitro-card-tabs-height: 33px;
|
||||
left: 0 !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
transform: none !important;
|
||||
//transform: none !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -39,6 +40,29 @@ $nitro-card-tabs-height: 33px;
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@include media-breakpoint-down(sm) {
|
||||
|
||||
.draggable-window {
|
||||
top: 0 !important;
|
||||
left: 0 !important;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
//transform: none !important;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.nitro-card {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
max-height: calc(100% - #{$toolbar-height});
|
||||
margin: 0;
|
||||
|
||||
&.rounded {
|
||||
border-radius: 0 !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './accordion/NitroCardAccordionView';
|
||||
|
@ -1 +1 @@
|
||||
export type NitroLayoutSpacing = 1 | 2 | 3 | 4 | 5;
|
||||
export type NitroLayoutSpacing = 0 | 1 | 2 | 3 | 4 | 5;
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MouseEventType } from '@nitrots/nitro-renderer';
|
||||
import { FC, Key, MouseEvent as ReactMouseEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { MouseEventType, TouchEventType } from '@nitrots/nitro-renderer';
|
||||
import { FC, Key, MouseEvent as ReactMouseEvent, TouchEvent as ReactTouchEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { DraggableWindowPosition, DraggableWindowProps } from './DraggableWindow.types';
|
||||
|
||||
const CURRENT_WINDOWS: HTMLElement[] = [];
|
||||
@ -29,7 +29,7 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
}
|
||||
}, []);
|
||||
|
||||
const onMouseDown = useCallback((event: ReactMouseEvent) =>
|
||||
const moveCurrentWindow = useCallback(() =>
|
||||
{
|
||||
const index = CURRENT_WINDOWS.indexOf(elementRef.current);
|
||||
|
||||
@ -50,18 +50,47 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
bringToTop();
|
||||
}, [ bringToTop ]);
|
||||
|
||||
const onDragMouseDown = useCallback((event: MouseEvent) =>
|
||||
const onMouseDown = useCallback((event: ReactMouseEvent<HTMLDivElement>) =>
|
||||
{
|
||||
setStart({ x: event.clientX, y: event.clientY });
|
||||
moveCurrentWindow();
|
||||
}, [ moveCurrentWindow ]);
|
||||
|
||||
const onTouchStart = useCallback((event: ReactTouchEvent<HTMLDivElement>) =>
|
||||
{
|
||||
moveCurrentWindow();
|
||||
}, [ moveCurrentWindow ]);
|
||||
|
||||
const startDragging = useCallback((startX: number, startY: number) =>
|
||||
{
|
||||
setStart({ x: startX, y: startY });
|
||||
setIsDragging(true);
|
||||
}, []);
|
||||
|
||||
const onDragMouseDown = useCallback((event: MouseEvent) =>
|
||||
{
|
||||
startDragging(event.clientX, event.clientY);
|
||||
}, [ startDragging ]);
|
||||
|
||||
const onTouchDown = useCallback((event: TouchEvent) =>
|
||||
{
|
||||
const touch = event.touches[0];
|
||||
|
||||
startDragging(touch.clientX, touch.clientY);
|
||||
}, [ startDragging ]);
|
||||
|
||||
const onDragMouseMove = useCallback((event: MouseEvent) =>
|
||||
{
|
||||
setDelta({ x: (event.clientX - start.x), y: (event.clientY - start.y) });
|
||||
}, [ start ]);
|
||||
|
||||
const onDragMouseUp = useCallback((event: MouseEvent) =>
|
||||
const onDragTouchMove = useCallback((event: TouchEvent) =>
|
||||
{
|
||||
const touch = event.touches[0];
|
||||
|
||||
setDelta({ x: (touch.clientX - start.x), y: (touch.clientY - start.y) });
|
||||
}, [ start ]);
|
||||
|
||||
const completeDrag = useCallback(() =>
|
||||
{
|
||||
if(!elementRef.current || !dragHandler) return;
|
||||
|
||||
@ -98,6 +127,16 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
if(uniqueKey !== null) POS_MEMORY.set(uniqueKey, { x: offsetX, y: offsetY });
|
||||
}, [ dragHandler, delta, offset, uniqueKey ]);
|
||||
|
||||
const onDragMouseUp = useCallback((event: MouseEvent) =>
|
||||
{
|
||||
completeDrag();
|
||||
}, [ completeDrag ]);
|
||||
|
||||
const onDragTouchUp = useCallback((event: TouchEvent) =>
|
||||
{
|
||||
completeDrag();
|
||||
}, [ completeDrag ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const element = (elementRef.current as HTMLElement);
|
||||
@ -169,29 +208,35 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
if(!dragHandler) return;
|
||||
|
||||
dragHandler.addEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown);
|
||||
dragHandler.addEventListener(TouchEventType.TOUCH_START, onTouchDown);
|
||||
|
||||
return () =>
|
||||
{
|
||||
dragHandler.removeEventListener(MouseEventType.MOUSE_DOWN, onDragMouseDown);
|
||||
dragHandler.removeEventListener(TouchEventType.TOUCH_START, onTouchDown);
|
||||
}
|
||||
}, [ dragHandler, onDragMouseDown ]);
|
||||
}, [ dragHandler, onDragMouseDown, onTouchDown ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isDragging) return;
|
||||
|
||||
document.addEventListener(MouseEventType.MOUSE_UP, onDragMouseUp);
|
||||
document.addEventListener(TouchEventType.TOUCH_END, onDragTouchUp);
|
||||
document.addEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove);
|
||||
document.addEventListener(TouchEventType.TOUCH_MOVE, onDragTouchMove);
|
||||
|
||||
return () =>
|
||||
{
|
||||
document.removeEventListener(MouseEventType.MOUSE_UP, onDragMouseUp);
|
||||
document.removeEventListener(TouchEventType.TOUCH_END, onDragTouchUp);
|
||||
document.removeEventListener(MouseEventType.MOUSE_MOVE, onDragMouseMove);
|
||||
document.removeEventListener(TouchEventType.TOUCH_MOVE, onDragTouchMove);
|
||||
}
|
||||
}, [ isDragging, onDragMouseUp, onDragMouseMove ]);
|
||||
}, [ isDragging, onDragMouseUp, onDragMouseMove, onDragTouchUp, onDragTouchMove ]);
|
||||
|
||||
return (
|
||||
<div ref={ elementRef } className="position-absolute draggable-window" onMouseDownCapture={ onMouseDown }>
|
||||
<div ref={ elementRef } className="position-absolute draggable-window" onMouseDownCapture={ onMouseDown } onTouchStartCapture={ onTouchStart }>
|
||||
{ children }
|
||||
</div>
|
||||
);
|
||||
|
@ -1,28 +1,46 @@
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { FC, useEffect, useMemo, useState } from 'react';
|
||||
import { NitroLayoutBase } from '../base';
|
||||
import { TransitionAnimation, TransitionAnimationTypes } from '../transitions';
|
||||
import { NotificationBubbleViewProps } from './NotificationBubbleView.types';
|
||||
|
||||
export const NotificationBubbleView: FC<NotificationBubbleViewProps> = props =>
|
||||
{
|
||||
const { fadesOut = false, close = null, className = '', children = null, ...rest } = props;
|
||||
const [ isFading, setIsFading ] = useState(false);
|
||||
const { fadesOut = true, timeoutMs = 8000, close = null, className = '', ...rest } = props;
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
|
||||
const getClassName = useMemo(() =>
|
||||
{
|
||||
let newClassName = 'nitro-notification-bubble rounded';
|
||||
|
||||
if(className && className.length) newClassName += ` ${ className }`;
|
||||
|
||||
return newClassName;
|
||||
}, [ className ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
|
||||
return () => setIsVisible(false);
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!fadesOut) return;
|
||||
|
||||
const timeout = setTimeout(() =>
|
||||
{
|
||||
setIsFading(true);
|
||||
{
|
||||
setIsVisible(false);
|
||||
|
||||
setTimeout(() => close());
|
||||
}, 8000);
|
||||
setTimeout(() => close(), 300);
|
||||
}, timeoutMs);
|
||||
|
||||
return () => clearTimeout(timeout);
|
||||
}, [ fadesOut, close ]);
|
||||
}, [ fadesOut, timeoutMs, close ]);
|
||||
|
||||
return (
|
||||
<div className={ ('nitro-notification-bubble rounded ' + (className || '')) } { ...rest } onClick={ close }>
|
||||
{ children }
|
||||
</div>
|
||||
)
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isVisible } timeout={ 300 }>
|
||||
<NitroLayoutBase className={ getClassName } onClick={ close } { ...rest } />
|
||||
</TransitionAnimation>
|
||||
);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { DetailsHTMLAttributes } from 'react';
|
||||
import { NitroLayoutBaseProps } from '../base';
|
||||
|
||||
export interface NotificationBubbleViewProps extends DetailsHTMLAttributes<HTMLDivElement>
|
||||
export interface NotificationBubbleViewProps extends NitroLayoutBaseProps
|
||||
{
|
||||
fadesOut?: boolean;
|
||||
timeoutMs?: number;
|
||||
close: () => void;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
width: 340px;
|
||||
height: 173px;
|
||||
color: black;
|
||||
pointer-events: all;
|
||||
|
||||
background-position: 0px 0px;
|
||||
background-image: url('../../assets/images/room-widgets/trophy-widget/trophy-spritesheet.png');
|
||||
|
@ -158,6 +158,11 @@ export const AchievementsView: FC<AchievementsViewProps> = props =>
|
||||
return progress;
|
||||
}, [ achievementCategories ]);
|
||||
|
||||
const scaledProgressPercent = useMemo(() =>
|
||||
{
|
||||
return ~~((((getProgress - 0) * (100 - 0)) / (getMaxProgress - 0)) + 0);
|
||||
}, [ getProgress, getMaxProgress ]);
|
||||
|
||||
const getSelectedCategory = useMemo(() =>
|
||||
{
|
||||
if(!achievementCategories || !achievementCategories.length) return null;
|
||||
@ -220,8 +225,10 @@ export const AchievementsView: FC<AchievementsViewProps> = props =>
|
||||
<>
|
||||
<AchievementsCategoryListView categories={ achievementCategories } selectedCategoryCode={ selectedCategoryCode } setSelectedCategoryCode={ setSelectedCategoryCode } />
|
||||
<NitroLayoutFlexColumn className="flex-grow-1 justify-content-end" gap={ 2 }>
|
||||
<NitroLayoutBase className="bg-muted text-black text-center rounded">
|
||||
{ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) }
|
||||
<NitroLayoutBase className="progress">
|
||||
<NitroLayoutBase className="progress-bar" style={ { width: (scaledProgressPercent + '%') }}>
|
||||
{ LocalizeText('achievements.categories.totalprogress', [ 'progress', 'limit' ], [ getProgress.toString(), getMaxProgress.toString() ]) }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutBase className="bg-muted text-black text-center rounded">
|
||||
{ LocalizeText('achievements.categories.score', [ 'score' ], [ achievementScore.toString() ]) }
|
||||
|
8
src/views/achievements/common/GetAchievementLevel.ts
Normal file
8
src/views/achievements/common/GetAchievementLevel.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const GetAchievementLevel = (achievement: AchievementData) =>
|
||||
{
|
||||
if(achievement.finalLevel) return achievement.level;
|
||||
|
||||
return (achievement.level - 1);
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
import { AchievementData } from '@nitrots/nitro-renderer';
|
||||
|
||||
export const GetScaledProgressPercent = (achievement: AchievementData) =>
|
||||
{
|
||||
if(!achievement) return 0;
|
||||
|
||||
return ~~(((((achievement.currentPoints + achievement.scoreAtStartOfLevel) - 0) * (100 - 0)) / ((achievement.scoreLimit + achievement.scoreAtStartOfLevel) - 0)) + 0);
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { FC } from 'react';
|
||||
import { LocalizeBadgeDescription, LocalizeBadgeName, LocalizeText } from '../../../../api';
|
||||
import { NitroLayoutFlex, NitroLayoutFlexColumn } from '../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../layout/base';
|
||||
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||
import { AchievementUtilities } from '../../common/AchievementUtilities';
|
||||
import { GetAchievementLevel } from '../../common/GetAchievementLevel';
|
||||
import { GetScaledProgressPercent } from '../../common/GetScaledProgressPercent';
|
||||
import { AchievementBadgeView } from '../achievement-badge/AchievementBadgeView';
|
||||
import { AchievementDetailsViewProps } from './AchievementDetailsView.types';
|
||||
|
||||
@ -11,25 +13,17 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
|
||||
{
|
||||
const { achievement = null } = props;
|
||||
|
||||
const getAchievementLevel = useMemo(() =>
|
||||
{
|
||||
if(achievement.finalLevel) return achievement.level;
|
||||
|
||||
return (achievement.level - 1);
|
||||
}, [ achievement ]);
|
||||
|
||||
if(!achievement) return null;
|
||||
|
||||
const currentAmount = achievement.currentPoints;
|
||||
const maxAmount = achievement.scoreLimit;
|
||||
const scoreAtStartOfLevel = achievement.scoreAtStartOfLevel;
|
||||
const achievementLevel = GetAchievementLevel(achievement);
|
||||
const scaledProgressPercent = GetScaledProgressPercent(achievement);
|
||||
|
||||
return (
|
||||
<NitroLayoutFlex className="bg-muted rounded p-2 text-black flex-shrink-0" gap={ 2 } overflow="hidden">
|
||||
<NitroLayoutFlexColumn className="justify-content-center align-items-center">
|
||||
<AchievementBadgeView className="nitro-achievements-badge-image" achievement={ achievement } scale={ 2 } />
|
||||
<NitroLayoutBase className="fw-bold">
|
||||
{ LocalizeText('achievements.details.level', [ 'level', 'limit' ], [ getAchievementLevel.toString(), achievement.levelCount.toString() ]) }
|
||||
{ LocalizeText('achievements.details.level', [ 'level', 'limit' ], [ achievementLevel.toString(), achievement.levelCount.toString() ]) }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlexColumn>
|
||||
<NitroLayoutFlexColumn className="justify-content-center w-100" overflow="hidden" gap={ 2 }>
|
||||
@ -41,20 +35,24 @@ export const AchievementDetailsView: FC<AchievementDetailsViewProps> = props =>
|
||||
{ LocalizeBadgeDescription(AchievementUtilities.getBadgeCode(achievement)) }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlexColumn>
|
||||
{ ((achievement.levelRewardPoints > 0) || (maxAmount > 0)) &&
|
||||
{ ((achievement.levelRewardPoints > 0) || (achievement.scoreLimit > 0)) &&
|
||||
<NitroLayoutFlexColumn gap={ 1 }>
|
||||
{ (achievement.levelRewardPoints > 0) &&
|
||||
<NitroLayoutFlex gap={ 1 }>
|
||||
<NitroLayoutBase className="text-truncate">
|
||||
<NitroLayoutBase className="text-truncate small">
|
||||
{ LocalizeText('achievements.details.reward') }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutFlex className="fw-bold align-items-center justify-content-center" gap={ 1 }>
|
||||
<NitroLayoutFlex className="fw-bold align-items-center justify-content-center small" gap={ 1 }>
|
||||
{ achievement.levelRewardPoints }
|
||||
<CurrencyIcon type={ achievement.levelRewardPointType } />
|
||||
</NitroLayoutFlex>
|
||||
</NitroLayoutFlex> }
|
||||
{ (maxAmount > 0) &&
|
||||
LocalizeText('achievements.details.progress', [ 'progress', 'limit' ], [ (currentAmount + scoreAtStartOfLevel).toString(), (maxAmount + scoreAtStartOfLevel).toString() ]) }
|
||||
{ (achievement.scoreLimit > 0) &&
|
||||
<NitroLayoutBase className="progress">
|
||||
<NitroLayoutBase className="progress-bar" style={ { width: (scaledProgressPercent + '%') }}>
|
||||
{ LocalizeText('achievements.details.progress', [ 'progress', 'limit' ], [ (achievement.currentPoints + achievement.scoreAtStartOfLevel).toString(), (achievement.scoreLimit + achievement.scoreAtStartOfLevel).toString() ]) }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutBase> }
|
||||
</NitroLayoutFlexColumn> }
|
||||
</NitroLayoutFlexColumn>
|
||||
</NitroLayoutFlex>
|
||||
|
@ -9,9 +9,9 @@ export const AchievementListView: FC<AchievementListViewProps> = props =>
|
||||
|
||||
return (
|
||||
<NitroCardGridView { ...rest }>
|
||||
{ achievements && (achievements.length > 0) && achievements.map(achievement =>
|
||||
{ achievements && (achievements.length > 0) && achievements.map((achievement, index) =>
|
||||
{
|
||||
return <AchievementListItemView key={ achievement.achievementId } achievement={ achievement } itemActive={ (selectedAchievementId === achievement.achievementId) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } />;
|
||||
return <AchievementListItemView key={ index } achievement={ achievement } itemActive={ (selectedAchievementId === achievement.achievementId) } onClick={ event => setSelectedAchievementId(achievement.achievementId) } />;
|
||||
}) }
|
||||
</NitroCardGridView>
|
||||
);
|
||||
|
@ -54,8 +54,11 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${giftData.colors[0].toString(16)}` });
|
||||
}
|
||||
|
||||
setSelectedColorId(newColors[0].id);
|
||||
setColors(newColors);
|
||||
if(newColors.length)
|
||||
{
|
||||
setSelectedColorId(newColors[0].id);
|
||||
setColors(newColors);
|
||||
}
|
||||
}, [ giftConfiguration ]);
|
||||
|
||||
const close = useCallback(() =>
|
||||
@ -68,7 +71,8 @@ export const CatalogGiftView: FC<{}> = props =>
|
||||
setMessage('');
|
||||
setSelectedBoxIndex(0);
|
||||
setSelectedRibbonIndex(0);
|
||||
setSelectedColorId(colors[0].id);
|
||||
|
||||
if(colors.length) setSelectedColorId(colors[0].id);
|
||||
}, [ colors ]);
|
||||
|
||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||
|
@ -85,7 +85,7 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
|
||||
</NitroLayoutGridColumn>
|
||||
<NitroLayoutGridColumn className="justify-content-between" size={ 5 } overflow="auto">
|
||||
<NitroLayoutFlexColumn overflow="hidden" gap={ 2 }>
|
||||
<NitroLayoutBase className="text-black text-truncate">{ LocalizeText('inventory.badges.activebadges') }</NitroLayoutBase>
|
||||
<NitroLayoutBase className="text-black text-truncate flex-shrink-0">{ LocalizeText('inventory.badges.activebadges') }</NitroLayoutBase>
|
||||
<InventoryActiveBadgeResultsView badges={ activeBadges } />
|
||||
</NitroLayoutFlexColumn>
|
||||
{ badge && (badge.length > 0) &&
|
||||
|
@ -10,7 +10,7 @@ export const NotificationClubGiftBubbleView: FC<NotificationBubbleLayoutViewProp
|
||||
const { item = null, close = null, ...rest } = props;
|
||||
|
||||
return (
|
||||
<NotificationBubbleView className="flex-column club-gift" close={ close } { ...rest }>
|
||||
<NotificationBubbleView fadesOut={ false } className="flex-column club-gift" close={ close } { ...rest }>
|
||||
<div className="d-flex align-items-center gap-2 mb-2">
|
||||
<CurrencyIcon type="hc" className="flex-shrink-0" />
|
||||
<span className="ms-1">{ LocalizeText('notifications.text.club_gift') }</span>
|
||||
|
@ -7,7 +7,7 @@ export const NotificationDefaultBubbleView: FC<NotificationDefaultBubbleViewProp
|
||||
const { item = null, close = null, ...rest } = props;
|
||||
|
||||
return (
|
||||
<NotificationBubbleView className="d-flex" fadesOut={ false } close={ close } { ...rest }>
|
||||
<NotificationBubbleView className="d-flex" close={ close } { ...rest }>
|
||||
{ (item.iconUrl && item.iconUrl.length) && <img className="bubble-image no-select" src={ item.iconUrl } alt="" /> }
|
||||
<span>{ item.message }</span>
|
||||
</NotificationBubbleView>
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { EventDispatcher, NitroRectangle, RoomGeometry, RoomVariableEnum, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { FC, useEffect, useRef, useState } from 'react';
|
||||
import { DispatchMouseEvent, DispatchTouchEvent, DoorbellWidgetHandler, FurniChooserWidgetHandler, FurnitureContextMenuWidgetHandler, FurnitureCreditWidgetHandler, FurnitureCustomStackHeightWidgetHandler, FurnitureDimmerWidgetHandler, FurnitureExternalImageWidgetHandler, FurniturePresentWidgetHandler, GetNitroInstance, GetRoomEngine, InitializeRoomInstanceRenderingCanvas, IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler, RoomWidgetRoomToolsHandler, RoomWidgetUpdateRoomViewEvent, UserChooserWidgetHandler } from '../../api';
|
||||
import { DispatchMouseEvent, DispatchTouchEvent, DoorbellWidgetHandler, FurniChooserWidgetHandler, FurnitureContextMenuWidgetHandler, FurnitureCreditWidgetHandler, FurnitureCustomStackHeightWidgetHandler, FurnitureDimmerWidgetHandler, FurnitureExternalImageWidgetHandler, FurnitureMannequinWidgetHandler, FurniturePresentWidgetHandler, GetNitroInstance, GetRoomEngine, InitializeRoomInstanceRenderingCanvas, IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler, RoomWidgetRoomToolsHandler, RoomWidgetUpdateRoomViewEvent, UserChooserWidgetHandler } from '../../api';
|
||||
import { RoomContextProvider } from './context/RoomContext';
|
||||
import { RoomColorView } from './RoomColorView';
|
||||
import { RoomViewProps } from './RoomView.types';
|
||||
@ -44,6 +44,7 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
widgetHandlerManager.registerHandler(new FurnitureExternalImageWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurniturePresentWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureDimmerWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureMannequinWidgetHandler());
|
||||
|
||||
setWidgetHandler(widgetHandlerManager);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RoomEngineEvent, RoomEngineObjectEvent, RoomEngineRoomAdEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomObjectVariable, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomZoomEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from '../../../api';
|
||||
import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../api';
|
||||
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
|
||||
import { NotificationAlertType } from '../../notification-center/common/NotificationAlertType';
|
||||
import { NotificationUtilities } from '../../notification-center/common/NotificationUtilities';
|
||||
@ -27,10 +27,10 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomEngineEvent.NORMAL_MODE:
|
||||
eventDispatcher.dispatchEvent(new RoomWidgetRoomEngineUpdateEvent(RoomWidgetRoomEngineUpdateEvent.NORMAL_MODE, event.roomId));
|
||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateRoomEngineEvent(RoomWidgetUpdateRoomEngineEvent.NORMAL_MODE, event.roomId));
|
||||
return;
|
||||
case RoomEngineEvent.GAME_MODE:
|
||||
eventDispatcher.dispatchEvent(new RoomWidgetRoomEngineUpdateEvent(RoomWidgetRoomEngineUpdateEvent.GAME_MODE, event.roomId));
|
||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateRoomEngineEvent(RoomWidgetUpdateRoomEngineEvent.GAME_MODE, event.roomId));
|
||||
return;
|
||||
case RoomZoomEvent.ROOM_ZOOM: {
|
||||
const zoomEvent = (event as RoomZoomEvent);
|
||||
@ -67,15 +67,15 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
const objectId = event.objectId;
|
||||
const category = event.category;
|
||||
|
||||
let updateEvent: RoomWidgetRoomObjectUpdateEvent = null;
|
||||
let updateEvent: RoomWidgetUpdateRoomObjectEvent = null;
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomEngineObjectEvent.SELECTED:
|
||||
if(!IsFurnitureSelectionDisabled(event)) updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, objectId, category, event.roomId);
|
||||
if(!IsFurnitureSelectionDisabled(event)) updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED, objectId, category, event.roomId);
|
||||
break;
|
||||
case RoomEngineObjectEvent.DESELECTED:
|
||||
updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, objectId, category, event.roomId);
|
||||
updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, objectId, category, event.roomId);
|
||||
break;
|
||||
case RoomEngineObjectEvent.ADDED: {
|
||||
let addedEventType: string = null;
|
||||
@ -84,14 +84,14 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
case RoomObjectCategory.WALL:
|
||||
addedEventType = RoomWidgetRoomObjectUpdateEvent.FURNI_ADDED;
|
||||
addedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED;
|
||||
break;
|
||||
case RoomObjectCategory.UNIT:
|
||||
addedEventType = RoomWidgetRoomObjectUpdateEvent.USER_ADDED;
|
||||
addedEventType = RoomWidgetUpdateRoomObjectEvent.USER_ADDED;
|
||||
break;
|
||||
}
|
||||
|
||||
if(addedEventType) updateEvent = new RoomWidgetRoomObjectUpdateEvent(addedEventType, objectId, category, event.roomId);
|
||||
if(addedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(addedEventType, objectId, category, event.roomId);
|
||||
break;
|
||||
}
|
||||
case RoomEngineObjectEvent.REMOVED: {
|
||||
@ -101,14 +101,14 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
case RoomObjectCategory.WALL:
|
||||
removedEventType = RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED;
|
||||
removedEventType = RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED;
|
||||
break;
|
||||
case RoomObjectCategory.UNIT:
|
||||
removedEventType = RoomWidgetRoomObjectUpdateEvent.USER_REMOVED;
|
||||
removedEventType = RoomWidgetUpdateRoomObjectEvent.USER_REMOVED;
|
||||
break;
|
||||
}
|
||||
|
||||
if(removedEventType) updateEvent = new RoomWidgetRoomObjectUpdateEvent(removedEventType, objectId, category, event.roomId);
|
||||
if(removedEventType) updateEvent = new RoomWidgetUpdateRoomObjectEvent(removedEventType, objectId, category, event.roomId);
|
||||
break;
|
||||
}
|
||||
case RoomEngineObjectEvent.REQUEST_MOVE:
|
||||
@ -118,13 +118,13 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
if(CanManipulateFurniture(roomSession, objectId, category)) ProcessRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
||||
break;
|
||||
case RoomEngineObjectEvent.REQUEST_MANIPULATION:
|
||||
if(CanManipulateFurniture(roomSession, objectId, category)) updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION, objectId, category, event.roomId);
|
||||
if(CanManipulateFurniture(roomSession, objectId, category)) updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION, objectId, category, event.roomId);
|
||||
break;
|
||||
case RoomEngineObjectEvent.MOUSE_ENTER:
|
||||
updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OVER, objectId, category, event.roomId);
|
||||
updateEvent = new RoomWidgetUpdateRoomObjectEvent(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER, objectId, category, event.roomId);
|
||||
break;
|
||||
case RoomEngineObjectEvent.MOUSE_LEAVE:
|
||||
updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT, objectId, category, event.roomId);
|
||||
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));
|
||||
@ -202,7 +202,7 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
{
|
||||
let dispatchEvent = true;
|
||||
|
||||
if(updateEvent instanceof RoomWidgetRoomObjectUpdateEvent) dispatchEvent = (!RoomId.isRoomPreviewerId(updateEvent.roomId));
|
||||
if(updateEvent instanceof RoomWidgetUpdateRoomObjectEvent) dispatchEvent = (!RoomId.isRoomPreviewerId(updateEvent.roomId));
|
||||
|
||||
if(dispatchEvent) widgetHandler.eventDispatcher.dispatchEvent(updateEvent);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RoomEnterEffect, RoomObjectCategory } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { GetRoomSession, GetSessionDataManager, RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectMessage, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../../../../api';
|
||||
import { GetRoomSession, GetSessionDataManager, RoomWidgetObjectNameEvent, RoomWidgetRoomObjectMessage, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent, RoomWidgetUpdateRoomEngineEvent, RoomWidgetUpdateRoomObjectEvent, RoomWidgetUseProductBubbleEvent, UseProductItem } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView';
|
||||
@ -73,25 +73,25 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
setProductBubbles([]);
|
||||
}, []);
|
||||
|
||||
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
|
||||
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetUpdateRoomEngineEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomEngineUpdateEvent.NORMAL_MODE: {
|
||||
case RoomWidgetUpdateRoomEngineEvent.NORMAL_MODE: {
|
||||
if(isGameMode) setGameMode(false);
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomEngineUpdateEvent.GAME_MODE: {
|
||||
case RoomWidgetUpdateRoomEngineEvent.GAME_MODE: {
|
||||
if(!isGameMode) setGameMode(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [ isGameMode ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomEngineUpdateEvent.NORMAL_MODE, eventDispatcher, onRoomWidgetRoomEngineUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomEngineUpdateEvent.GAME_MODE, eventDispatcher, onRoomWidgetRoomEngineUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomEngineEvent.NORMAL_MODE, eventDispatcher, onRoomWidgetRoomEngineUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomEngineEvent.GAME_MODE, eventDispatcher, onRoomWidgetRoomEngineUpdateEvent);
|
||||
|
||||
const onRoomObjectRemoved = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomObjectRemoved = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
if(name)
|
||||
{
|
||||
@ -152,15 +152,15 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
}
|
||||
}, [ name, infoStandEvent, nameBubbles, productBubbles, removeNameBubble, clearInfoStandEvent ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||
|
||||
const onObjectRolled = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onObjectRolled = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OVER: {
|
||||
const roomObjectEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER: {
|
||||
const roomObjectEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
if(infoStandEvent) return;
|
||||
|
||||
@ -168,8 +168,8 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT: {
|
||||
const roomObjectEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OUT: {
|
||||
const roomObjectEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
if(!name || (name.roomIndex !== roomObjectEvent.id)) return;
|
||||
|
||||
@ -180,16 +180,16 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
}
|
||||
}, [ infoStandEvent, name, widgetHandler ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OVER, eventDispatcher, onObjectRolled);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT, eventDispatcher, onObjectRolled);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OVER, eventDispatcher, onObjectRolled);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_ROLL_OUT, eventDispatcher, onObjectRolled);
|
||||
|
||||
const onObjectDeselected = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onObjectDeselected = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
if(infoStandEvent) clearInfoStandEvent();
|
||||
if(productBubbles.length) setProductBubbles([]);
|
||||
}, [ infoStandEvent, productBubbles, clearInfoStandEvent ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onObjectDeselected);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, eventDispatcher, onObjectDeselected);
|
||||
|
||||
const onRoomWidgetObjectNameEvent = useCallback((event: RoomWidgetObjectNameEvent) =>
|
||||
{
|
||||
|
@ -71,7 +71,7 @@
|
||||
max-height: $chat-input-style-selector-widget-height;
|
||||
|
||||
.content-area {
|
||||
max-height: $chat-input-style-selector-widget-height;
|
||||
max-height: $chat-input-style-selector-widget-height !important;
|
||||
}
|
||||
|
||||
.grid-item {
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { HabboClubLevelEnum, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent } from '../../../../api';
|
||||
import { GetConfiguration, GetSessionDataManager, LocalizeText, RoomWidgetChatMessage, RoomWidgetChatTypingMessage, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks/events';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { ChatInputStyleSelectorView } from './style-selector/ChatInputStyleSelectorView';
|
||||
@ -177,12 +177,12 @@ export const ChatInputView: FC<{}> = props =>
|
||||
|
||||
}, [ inputRef, chatModeIdWhisper, anotherInputHasFocus, setInputFocus, checkSpecialKeywordForInput, sendChatValue ]);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
setSelectedUsername('');
|
||||
}, []);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const onRoomWidgetUpdateInfostandUserEvent = useCallback((event: RoomWidgetUpdateInfostandUserEvent) =>
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetRoomObjectUpdateEvent } from '../../../../api';
|
||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||
@ -31,21 +31,21 @@ export const FurniChooserWidgetView: FC<{}> = props =>
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.FURNI_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_ADDED:
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED:
|
||||
refreshChooser();
|
||||
return;
|
||||
}
|
||||
}, [ isVisible, refreshChooser ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetRoomObjectUpdateEvent } from '../../../../api';
|
||||
import { LocalizeText, RoomObjectItem, RoomWidgetChooserContentEvent, RoomWidgetRequestWidgetMessage, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { ChooserWidgetView } from './ChooserWidgetView';
|
||||
@ -31,21 +31,21 @@ export const UserChooserWidgetView: FC<{}> = props =>
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetChooserContentEvent.USER_CHOOSER_CONTENT, eventDispatcher, onRoomWidgetChooserContentEvent);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.USER_ADDED:
|
||||
case RoomWidgetRoomObjectUpdateEvent.USER_REMOVED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.USER_ADDED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.USER_REMOVED:
|
||||
refreshChooser();
|
||||
return;
|
||||
}
|
||||
}, [ isVisible, refreshChooser ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
|
@ -7,6 +7,7 @@
|
||||
border-radius: $border-radius;
|
||||
font-size: $font-size-sm;
|
||||
z-index: $context-menu-zindex;
|
||||
pointer-events: all;
|
||||
|
||||
&.name-only {
|
||||
background-color: rgba($black, 0.5);
|
||||
@ -34,8 +35,7 @@
|
||||
.menu-header {
|
||||
background-color: $william;
|
||||
color: $white;
|
||||
width: 117px;
|
||||
max-width: 117px;
|
||||
min-width: 117px;
|
||||
height: 25px;
|
||||
max-height: 25px;
|
||||
font-size: 16px;
|
||||
|
@ -1,3 +1,9 @@
|
||||
.nitro-room-widgets {
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
@import './custom-stack-height/FurnitureCustomStackHeightView';
|
||||
|
||||
@import './dimmer/FurnitureDimmerView';
|
||||
@import './exchange-credit/FurnitureExchangeCreditView';
|
||||
@import './external-image/FurnitureExternalImageView';
|
||||
|
@ -17,7 +17,7 @@ import { FurnitureTrophyView } from './trophy/FurnitureTrophyView';
|
||||
export const FurnitureWidgetsView: FC<{}> = props =>
|
||||
{
|
||||
return (
|
||||
<div className="position-absolute nitro-room-widgets top-0 start-0">
|
||||
<div className="position-absolute nitro-room-widgets top-0 start-0 w-100 h-100">
|
||||
<FurnitureBackgroundColorView />
|
||||
<FurnitureContextMenuView />
|
||||
<FurnitureCustomStackHeightView />
|
||||
|
@ -1,7 +1,7 @@
|
||||
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, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateBackgroundColorPreviewEvent } from '../../../../../api';
|
||||
import { GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { SendMessageHook } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||
@ -48,7 +48,7 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
||||
if(objectId !== event.objectId) return;
|
||||
|
||||
close();
|
||||
@ -58,7 +58,7 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
||||
}, [ objectId, canOpenBackgroundToner, close ]);
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomEngineObjectEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomEngineObjectEvent);
|
||||
|
||||
const processAction = useCallback((name: string) =>
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, StringDataType } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomEngine, LocalizeBadgeDescription, LocalizeBadgeName, RoomWidgetRoomObjectUpdateEvent } from '../../../../../api';
|
||||
import { GetRoomEngine, LocalizeBadgeDescription, LocalizeBadgeName, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event';
|
||||
import { NitroLayoutTrophyView } from '../../../../../layout';
|
||||
@ -36,8 +36,8 @@ export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
||||
setTrophyData(new FurnitureTrophyData(widgetEvent.objectId, widgetEvent.category, '1', senderName, date, badgeDesc, badgeName));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
setTrophyData(prevState =>
|
||||
{
|
||||
@ -52,7 +52,7 @@ export const FurnitureBadgeDisplayView: FC<{}> = props =>
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING, onNitroEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, widgetHandler.eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, widgetHandler.eventDispatcher, onNitroEvent);
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
{
|
||||
|
@ -0,0 +1,4 @@
|
||||
.nitro-widget-custom-stack-height {
|
||||
width: $nitro-widget-custom-stack-height-width;
|
||||
height: $nitro-widget-custom-stack-height-height;
|
||||
}
|
@ -2,9 +2,10 @@ import { FurnitureStackHeightComposer, FurnitureStackHeightEvent } from '@nitrot
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import ReactSlider from 'react-slider';
|
||||
import { LocalizeText, RoomWidgetUpdateCustomStackHeightEvent } from '../../../../../api';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../../../../hooks';
|
||||
import { BatchUpdates, CreateMessageHook, SendMessageHook } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
|
||||
const MAX_HEIGHT: number = 40;
|
||||
@ -14,13 +15,15 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||
const [ objectId, setObjectId ] = useState(-1);
|
||||
const [ height, setHeight ] = useState(0);
|
||||
const [ pendingHeight, setPendingHeight ] = useState(-1);
|
||||
|
||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
||||
const { eventDispatcher = null } = useRoomContext();
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setHeight(0);
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setHeight(0);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const updateHeight = useCallback((height: number, fromServer: boolean = false) =>
|
||||
@ -31,9 +34,12 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||
|
||||
if(!fromServer) ((height > MAX_HEIGHT) && (height = MAX_HEIGHT));
|
||||
|
||||
setHeight(parseFloat(height.toFixed(2)));
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setHeight(parseFloat(height.toFixed(2)));
|
||||
|
||||
if(!fromServer) setPendingHeight(height * 100);
|
||||
if(!fromServer) setPendingHeight(height * 100);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const onRoomWidgetUpdateCustomStackHeightEvent = useCallback((event: RoomWidgetUpdateCustomStackHeightEvent) =>
|
||||
@ -65,16 +71,6 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||
SendMessageHook(new FurnitureStackHeightComposer(objectId, ~~(height)));
|
||||
}, [ objectId ]);
|
||||
|
||||
const placeAboveStack = useCallback(() =>
|
||||
{
|
||||
sendUpdate(-100);
|
||||
}, [ sendUpdate ]);
|
||||
|
||||
const placeAtFloor = useCallback(() =>
|
||||
{
|
||||
sendUpdate(0);
|
||||
}, [ sendUpdate ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if((objectId === -1) || (pendingHeight === -1)) return;
|
||||
@ -87,27 +83,35 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||
if(objectId === -1) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView>
|
||||
<NitroCardView className="nitro-widget-custom-stack-height" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('widget.custom.stack.height.title') } onCloseClick={ close } />
|
||||
<NitroCardContentView>
|
||||
<div className="form-group">
|
||||
<label className="fw-bold text-black">{ LocalizeText('widget.custom.stack.height.text') }</label>
|
||||
<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> } />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<input type="number" min={ 0 } max={ MAX_HEIGHT } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
|
||||
</div>
|
||||
<div className="form-group">
|
||||
<button type="button" className="btn btn-primary" onClick={ placeAboveStack }>{ LocalizeText('furniture.above.stack') }</button>
|
||||
<button type="button" className="btn btn-primary" onClick={ placeAtFloor }>{ LocalizeText('furniture.floor.level') }</button>
|
||||
</div>
|
||||
<NitroLayoutGrid>
|
||||
<NitroLayoutGridColumn className="justify-content-between" size={ 12 }>
|
||||
<NitroLayoutBase className="text-black" overflow="auto">
|
||||
{ LocalizeText('widget.custom.stack.height.text') }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutFlexColumn gap={ 2 }>
|
||||
<NitroLayoutFlex 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)) } />
|
||||
</NitroLayoutFlex>
|
||||
<NitroLayoutButton variant="primary" onClick={ event => sendUpdate(-100) }>
|
||||
{ LocalizeText('furniture.above.stack') }
|
||||
</NitroLayoutButton>
|
||||
<NitroLayoutButton variant="primary" onClick={ event => sendUpdate(0) }>
|
||||
{ LocalizeText('furniture.floor.level') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlexColumn>
|
||||
</NitroLayoutGridColumn>
|
||||
</NitroLayoutGrid>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,3 +1,10 @@
|
||||
.nitro-exchange-credit {
|
||||
width: 290px;
|
||||
.nitro-widget-exchange-credit {
|
||||
width: $nitro-widget-exchange-credit-width;
|
||||
height: $nitro-widget-exchange-credit-height;
|
||||
|
||||
.exchange-image {
|
||||
background-image: url('../../../../../assets/images/room-widgets/exchange-credit/exchange-credit-image.png');
|
||||
width: 103px;
|
||||
height: 103px;
|
||||
}
|
||||
}
|
||||
|
@ -2,7 +2,8 @@ import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
|
||||
import { BatchUpdates } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
|
||||
export const FurnitureExchangeCreditView: FC<{}> = props =>
|
||||
@ -19,35 +20,46 @@ export const FurnitureExchangeCreditView: FC<{}> = props =>
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
switch(type)
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
case 'close':
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setValue(0);
|
||||
});
|
||||
return;
|
||||
case 'redeem':
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
||||
setObjectId(-1);
|
||||
setValue(0);
|
||||
});
|
||||
}, []);
|
||||
|
||||
processAction('close');
|
||||
return;
|
||||
}
|
||||
}, [ widgetHandler, objectId ]);
|
||||
const redeem = useCallback(() =>
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
||||
|
||||
close();
|
||||
}, [ widgetHandler, objectId, close ]);
|
||||
|
||||
if(objectId === -1) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-exchange-credit" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ event => processAction('close') } />
|
||||
<NitroCardView className="nitro-widget-exchange-credit" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ close } />
|
||||
<NitroCardContentView>
|
||||
<div className="text-black mb-2">
|
||||
{ LocalizeText('widgets.furniture.credit.redeem.value', [ 'value' ], [ value.toString() ]) }
|
||||
</div>
|
||||
<button className="btn btn-success w-100" onClick={ event => processAction('redeem') }>{ LocalizeText('catalog.redeem.dialog.button.exchange') }</button>
|
||||
<NitroLayoutGrid>
|
||||
<NitroLayoutGridColumn className="justify-content-center align-items-center" overflow="hidden" size={ 4 }>
|
||||
<NitroLayoutBase className="exchange-image" />
|
||||
</NitroLayoutGridColumn>
|
||||
<NitroLayoutGridColumn className="justify-content-between" overflow="hidden" size={ 8 }>
|
||||
<NitroLayoutFlexColumn gap={ 1 } overflow="auto">
|
||||
<NitroLayoutBase className="text-black fw-bold">
|
||||
{ LocalizeText('creditfurni.description', [ 'credits' ], [ value.toString() ]) }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText('creditfurni.prompt') }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlexColumn>
|
||||
<NitroLayoutButton variant="success" onClick={ redeem }>
|
||||
{ LocalizeText('catalog.redeem.dialog.button.exchange') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutGridColumn>
|
||||
</NitroLayoutGrid>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { FriendFurniConfirmLockMessageComposer, LoveLockFurniFinishedEvent, LoveLockFurniFriendConfirmedEvent, LoveLockFurniStartEvent, NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomEngine, GetRoomSession, LocalizeText, RoomWidgetRoomObjectUpdateEvent } from '../../../../../api';
|
||||
import { GetRoomEngine, GetRoomSession, LocalizeText, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event';
|
||||
import { CreateMessageHook } from '../../../../../hooks/messages/message-event';
|
||||
@ -37,8 +37,8 @@ export const FurnitureFriendFurniView: FC<{}> = props =>
|
||||
}
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
setEngravingLockData(prevState =>
|
||||
{
|
||||
@ -52,7 +52,7 @@ export const FurnitureFriendFurniView: FC<{}> = props =>
|
||||
};
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
|
||||
const onLoveLockFurniStartEvent = useCallback((event: LoveLockFurniStartEvent) =>
|
||||
{
|
||||
|
@ -1,8 +1,10 @@
|
||||
import { RoomObjectCategory, RoomObjectOperationType } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { CreateLinkEvent, GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetPresentOpenMessage, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdatePresentDataEvent } from '../../../../../api';
|
||||
import { CreateLinkEvent, GetRoomEngine, GetSessionDataManager, LocalizeText, RoomWidgetPresentOpenMessage, RoomWidgetUpdatePresentDataEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { BatchUpdates } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGiftCardView } from '../../../../../layout';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGiftCardView, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
||||
import { ProductTypeEnum } from '../../../../catalog/common/ProductTypeEnum';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
|
||||
@ -10,6 +12,11 @@ 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);
|
||||
@ -44,57 +51,67 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
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);
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
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: {
|
||||
setObjectId(event.objectId);
|
||||
setClassId(event.classId);
|
||||
setItemType(event.itemType);
|
||||
setText(event.giftMessage);
|
||||
setIsOwnerOfFurniture(event.isController);
|
||||
setPlacedItemId(event.placedItemId);
|
||||
setPlacedItemType(event.placedItemType);
|
||||
setPlacedInRoom(event.placedInRoom);
|
||||
|
||||
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';
|
||||
|
||||
setImageUrl(getGiftImageUrl(imageType));
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
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'));
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
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);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setObjectId(event.objectId);
|
||||
setClassId(event.classId);
|
||||
setItemType(event.itemType);
|
||||
setText(event.giftMessage);
|
||||
setIsOwnerOfFurniture(event.isController);
|
||||
setPlacedItemId(event.placedItemId);
|
||||
setPlacedItemType(event.placedItemType);
|
||||
setPlacedInRoom(event.placedInRoom);
|
||||
});
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE: {
|
||||
@ -113,7 +130,7 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
if(event.id === objectId) clearGift();
|
||||
|
||||
@ -123,17 +140,20 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
}
|
||||
}, [ objectId, placedItemId, placedInRoom, clearGift ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setOpenRequested(false);
|
||||
setPlacedItemId(-1);
|
||||
setPlacedInRoom(false);
|
||||
setText(null);
|
||||
setIsOwnerOfFurniture(false);
|
||||
}, [ clearGift ]);
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setOpenRequested(false);
|
||||
setPlacedItemId(-1);
|
||||
setPlacedInRoom(false);
|
||||
setText(null);
|
||||
setIsOwnerOfFurniture(false);
|
||||
});
|
||||
}, []);
|
||||
|
||||
const isSpaces = useMemo(() =>
|
||||
{
|
||||
@ -152,26 +172,25 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
{
|
||||
if(objectId === -1) return '';
|
||||
|
||||
if(isSpaces)
|
||||
return 'widget.furni.present.spaces.message_opened';
|
||||
if(isSpaces) return 'widget.furni.present.spaces.message_opened';
|
||||
|
||||
return 'widget.furni.present.message_opened';
|
||||
}, [ objectId, isSpaces ]);
|
||||
|
||||
const handleAction = useCallback((action: string) =>
|
||||
const handleAction = useCallback((action: number) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'give_gift':
|
||||
case ACTION_GIVE_GIFT:
|
||||
CreateLinkEvent('catalog/open');
|
||||
return;
|
||||
case 'open':
|
||||
case ACTION_OPEN:
|
||||
setOpenRequested(true);
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetPresentOpenMessage(RoomWidgetPresentOpenMessage.OPEN_PRESENT, objectId));
|
||||
return;
|
||||
case 'room':
|
||||
case ACTION_PLACE:
|
||||
return;
|
||||
case 'inventory':
|
||||
case ACTION_INVENTORY:
|
||||
if((placedItemId > 0) && placedInRoom)
|
||||
{
|
||||
if(placedItemType === ProductTypeEnum.PET)
|
||||
@ -195,32 +214,48 @@ export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-gift-opening" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText(senderName ? 'widget.furni.present.window.title_from' : 'widget.furni.present.window.title', ['name'], [senderName]) } onCloseClick={ close } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText(senderName ? 'widget.furni.present.window.title_from' : 'widget.furni.present.window.title', [ 'name' ], [ senderName ]) } onCloseClick={ close } />
|
||||
<NitroCardContentView>
|
||||
{ placedItemId === -1 && <>
|
||||
<NitroLayoutGiftCardView userName={ senderName } figure={ senderFigure } message={ text } />
|
||||
{ isOwnerOfFurniture && <div className="d-flex gap-2 mt-2">
|
||||
{ senderName && <button className="btn btn-primary w-100 text-nowrap" onClick={ () => handleAction('give_gift') }>{ LocalizeText('widget.furni.present.give_gift', ['name'], [senderName]) }</button> }
|
||||
<button className="btn btn-success w-100 text-nowrap" onClick={ () => handleAction('open') }>{ LocalizeText('widget.furni.present.open_gift') }</button>
|
||||
</div> }
|
||||
</> }
|
||||
{ placedItemId !== -1 && <>
|
||||
<div className="d-flex gap-2 align-items-center">
|
||||
<div>
|
||||
<img src={ imageUrl } alt="" />
|
||||
</div>
|
||||
<div className="bg-muted rounded p-2 text-center text-black">
|
||||
{ LocalizeText(productName, ['product'], [text]) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex gap-2 mt-3">
|
||||
<button className="btn btn-primary w-100 text-nowrap" onClick={ () => handleAction('inventory') }>{ LocalizeText('widget.furni.present.put_in_inventory') }</button>
|
||||
<button className="btn btn-success w-100 text-nowrap" onClick={ () => handleAction('room') }>{ LocalizeText(placedInRoom ? 'widget.furni.present.keep_in_room' : 'widget.furni.present.place_in_room') }</button>
|
||||
</div>
|
||||
{ senderName && <>
|
||||
<button className="btn btn-primary w-100 text-nowrap mt-2" onClick={ () => handleAction('give_gift') }>{ LocalizeText('widget.furni.present.give_gift', ['name'], [senderName]) }</button>
|
||||
</> }
|
||||
</> }
|
||||
<NitroLayoutGrid>
|
||||
{ (placedItemId === -1) &&
|
||||
<NitroLayoutGridColumn size={ 12 }>
|
||||
<NitroLayoutFlex className="justify-content-center align-items-center" overflow="auto">
|
||||
<NitroLayoutGiftCardView userName={ senderName } figure={ senderFigure } message={ text } />
|
||||
</NitroLayoutFlex>
|
||||
<NitroLayoutFlex gap={ 2 }>
|
||||
{ senderName &&
|
||||
<NitroLayoutButton className="text-nowrap w-100" variant="primary" onClick={ event => handleAction(ACTION_GIVE_GIFT) }>
|
||||
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
||||
</NitroLayoutButton> }
|
||||
<NitroLayoutButton className="text-nowrap w-100" variant="success" onClick={ event => handleAction(ACTION_OPEN) }>
|
||||
{ LocalizeText('widget.furni.present.open_gift') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlex>
|
||||
</NitroLayoutGridColumn> }
|
||||
{ (placedItemId > -1) &&
|
||||
<NitroLayoutGridColumn size={ 12 }>
|
||||
<NitroLayoutFlex className="justify-content-center align-items-center" overflow="auto" gap={ 2 }>
|
||||
<img src={ imageUrl } alt="" />
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText(productName, [ 'product' ], [ text ]) }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlex>
|
||||
<NitroLayoutFlexColumn gap={ 2 }>
|
||||
<NitroLayoutFlex gap={ 2 }>
|
||||
<NitroLayoutButton className="w-100" variant="primary" onClick={ event => handleAction(ACTION_INVENTORY) }>
|
||||
{ LocalizeText('widget.furni.present.put_in_inventory') }
|
||||
</NitroLayoutButton>
|
||||
<NitroLayoutButton className="w-100" variant="success" onClick={ event => handleAction(ACTION_PLACE) }>
|
||||
{ LocalizeText(placedInRoom ? 'widget.furni.present.keep_in_room' : 'widget.furni.present.place_in_room') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlex>
|
||||
{ (senderName && senderName.length) &&
|
||||
<NitroLayoutButton className="w-100" variant="primary" onClick={ event => handleAction(ACTION_GIVE_GIFT) }>
|
||||
{ LocalizeText('widget.furni.present.give_gift', [ 'name' ], [ senderName ]) }
|
||||
</NitroLayoutButton> }
|
||||
</NitroLayoutFlexColumn>
|
||||
</NitroLayoutGridColumn> }
|
||||
</NitroLayoutGrid>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,5 +1,6 @@
|
||||
.highscore-widget
|
||||
.nitro-widget-high-score
|
||||
{
|
||||
width: 150px;
|
||||
max-width: 150px;
|
||||
width: 250px;
|
||||
max-width: 250px;
|
||||
height: 200px;
|
||||
}
|
||||
|
@ -2,13 +2,15 @@ import { HighScoreDataType, ObjectDataFactory, RoomEngineTriggerWidgetEvent, Roo
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomEngine, LocalizeText } from '../../../../../api';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks';
|
||||
import { NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
import { ContextMenuView } from '../../context-menu/ContextMenuView';
|
||||
import { ContextMenuHeaderView } from '../../context-menu/views/header/ContextMenuHeaderView';
|
||||
import { ContextMenuListView } from '../../context-menu/views/list/ContextMenuListView';
|
||||
|
||||
const SCORE_TYPES = ['perteam', 'mostwins', 'classic'];
|
||||
const CLEAR_TYPES = ['alltime', 'daily', 'weekly', 'monthly'];
|
||||
const SCORE_TYPES = [ 'perteam', 'mostwins', 'classic' ];
|
||||
const CLEAR_TYPES = [ 'alltime', 'daily', 'weekly', 'monthly' ];
|
||||
|
||||
export const FurnitureHighScoreView: FC<{}> = props =>
|
||||
{
|
||||
@ -55,33 +57,48 @@ export const FurnitureHighScoreView: FC<{}> = props =>
|
||||
if((objectId === -1) || !stuffData) return null;
|
||||
|
||||
return (
|
||||
<ContextMenuView objectId={ objectId } category={ RoomObjectCategory.FLOOR } close={ close } fades={ false } className="highscore-widget">
|
||||
<ContextMenuView objectId={ objectId } category={ RoomObjectCategory.FLOOR } close={ close } fades={ false } className="nitro-widget-high-score">
|
||||
<ContextMenuHeaderView>
|
||||
{ LocalizeText('high.score.display.caption', [ 'scoretype', 'cleartype' ], [LocalizeText(`high.score.display.scoretype.${ SCORE_TYPES[stuffData.scoreType] }`), LocalizeText(`high.score.display.cleartype.${ CLEAR_TYPES[stuffData.clearType] }`) ]) }
|
||||
</ContextMenuHeaderView>
|
||||
<ContextMenuListView>
|
||||
<div className="row">
|
||||
<div className="col-6">{ LocalizeText('high.score.display.users.header') }</div>
|
||||
<div className="col-6">{ LocalizeText('high.score.display.score.header') }</div>
|
||||
</div>
|
||||
<div className="row">
|
||||
<div className="col-6">
|
||||
<div className="container h-100">
|
||||
{ stuffData.entries.map((entry, index) =>
|
||||
{
|
||||
return <div key={ index }>{entry.users.join()}</div>
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-6">
|
||||
<NitroLayoutGrid>
|
||||
<NitroLayoutGridColumn size={ 6 }>
|
||||
<NitroLayoutBase className="text-center fw-bold">
|
||||
{ LocalizeText('high.score.display.users.header') }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutGridColumn>
|
||||
<NitroLayoutGridColumn size={ 6 }>
|
||||
<NitroLayoutBase className="text-center fw-bold">
|
||||
{ LocalizeText('high.score.display.score.header') }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutGridColumn>
|
||||
</NitroLayoutGrid>
|
||||
<hr className="m-0 my-1" />
|
||||
<NitroLayoutGrid overflow="hidden">
|
||||
<NitroLayoutGridColumn size={ 6 }>
|
||||
{ stuffData.entries.map((entry, index) =>
|
||||
{
|
||||
return <div key={ index }>{entry.score}</div>
|
||||
return (
|
||||
<NitroLayoutBase key={ index } className="text-center">
|
||||
{ entry.users.join(', ') }
|
||||
</NitroLayoutBase>
|
||||
);
|
||||
})
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</NitroLayoutGridColumn>
|
||||
<NitroLayoutGridColumn size={ 6 }>
|
||||
{ stuffData.entries.map((entry, index) =>
|
||||
{
|
||||
return (
|
||||
<NitroLayoutBase key={ index } className="text-center">
|
||||
{ entry.score }
|
||||
</NitroLayoutBase>
|
||||
);
|
||||
})
|
||||
}
|
||||
</NitroLayoutGridColumn>
|
||||
</NitroLayoutGrid>
|
||||
</ContextMenuListView>
|
||||
</ContextMenuView>
|
||||
);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RoomObjectOperationType } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { ProcessRoomObjectOperation, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDecorateModeEvent } from '../../../../../api';
|
||||
import { ProcessRoomObjectOperation, RoomWidgetUpdateDecorateModeEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { BatchUpdates } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
@ -28,11 +28,11 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
|
||||
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_PICKUP);
|
||||
}, [ objectId, objectType ]);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetUpdateRoomObjectEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION: {
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION: {
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(true);
|
||||
@ -41,7 +41,7 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
|
||||
});
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
||||
if(event.id === objectId)
|
||||
{
|
||||
BatchUpdates(() =>
|
||||
@ -53,7 +53,7 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
|
||||
}
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED: {
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED: {
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
@ -65,8 +65,8 @@ export const FurnitureManipulationMenuView: FC<{}> = props =>
|
||||
}
|
||||
}, [ objectId ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_REQUEST_MANIPULATION, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const onRoomWidgetUpdateDecorateModeEvent = useCallback((event: RoomWidgetUpdateDecorateModeEvent) =>
|
||||
{
|
||||
|
@ -1,15 +1,26 @@
|
||||
import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, IAvatarFigureContainer, NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { AvatarFigurePartType, FurnitureMannequinSaveLookComposer, FurnitureMannequinSaveNameComposer, FurnitureMultiStateComposer, HabboClubLevelEnum, IAvatarFigureContainer, RoomControllerLevel } from '@nitrots/nitro-renderer';
|
||||
import { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react';
|
||||
import { GetAvatarRenderManager, GetNitroInstance, GetRoomEngine, GetRoomSession, GetSessionDataManager, LocalizeText, RoomWidgetRoomObjectUpdateEvent } from '../../../../../api';
|
||||
import { GetAvatarRenderManager, GetSessionDataManager, LocalizeText, RoomWidgetUpdateMannequinEvent } from '../../../../../api';
|
||||
import { BatchUpdates, SendMessageHook } from '../../../../../hooks';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||
import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn, NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../../layout';
|
||||
import { NitroLayoutBase } from '../../../../../layout/base';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
import { MannequinViewMode } from './common/MannequinViewMode';
|
||||
import { FurnitureMannequinData } from './FurnitureMannequinData';
|
||||
import { FurnitureMannequinPreviewView } from './views/preview/FurnitureMannequinPreviewView';
|
||||
|
||||
const parts = [
|
||||
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,
|
||||
@ -17,197 +28,209 @@ const parts = [
|
||||
AvatarFigurePartType.SHOES,
|
||||
AvatarFigurePartType.WAIST_ACCESSORY
|
||||
];
|
||||
const baseAvatar = ['hd', 99999, 99998];
|
||||
|
||||
export const FurnitureMannequinView: FC<{}> = props =>
|
||||
{
|
||||
const { eventDispatcher = null } = useRoomContext();
|
||||
|
||||
const [ mannequinData, setMannequinData ] = useState<FurnitureMannequinData>(null);
|
||||
const [ viewMode, setViewMode ] = useState('');
|
||||
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 loadMannequinFigure = useCallback((figureContainer: IAvatarFigureContainer) =>
|
||||
{
|
||||
for(const item of figureContainer.getPartTypeIds())
|
||||
{
|
||||
if(parts.indexOf(item) === -1)
|
||||
{
|
||||
figureContainer.removePart(item);
|
||||
}
|
||||
}
|
||||
|
||||
figureContainer.updatePart(baseAvatar[0].toString(), Number(baseAvatar[1]), [ Number(baseAvatar[2]) ]);
|
||||
|
||||
setMannequinData(mannequinData => new FurnitureMannequinData(mannequinData.objectId, mannequinData.category, mannequinData.name, mannequinData.figure, mannequinData.gender, mannequinData.clubLevel, figureContainer.getFigureString()));
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
const onRoomWidgetUpdateMannequinEvent = useCallback((event: RoomWidgetUpdateMannequinEvent) =>
|
||||
{
|
||||
if(mannequinData && !mannequinData.renderedFigure)
|
||||
{
|
||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(mannequinData.figure);
|
||||
loadMannequinFigure(figureContainer);
|
||||
}
|
||||
}, [loadMannequinFigure, mannequinData]);
|
||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(event.figure);
|
||||
const figureClubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, event.gender, MANNEQUIN_CLOTHING_PART_TYPES);
|
||||
|
||||
const loadViewMode = useCallback((mannequinData: FurnitureMannequinData) =>
|
||||
{
|
||||
if(!mannequinData) return;
|
||||
|
||||
const userCanEdit = (GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator);
|
||||
const userGender = GetNitroInstance().sessionDataManager.gender;
|
||||
const userClubLevel = GetNitroInstance().sessionDataManager.clubLevel;
|
||||
|
||||
if(userCanEdit)
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setViewMode(MannequinViewMode.EDIT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!mannequinData.figure || mannequinData.figure.length <= 1) return;
|
||||
setObjectId(event.objectId);
|
||||
setFigure(event.figure);
|
||||
setGender(event.gender);
|
||||
setName(event.name);
|
||||
setClubLevel(figureClubLevel);
|
||||
|
||||
if(userGender.toUpperCase() !== mannequinData.gender.toUpperCase())
|
||||
if(roomSession.isRoomOwner || (roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator)
|
||||
{
|
||||
setViewMode(MannequinViewMode.INCOMPATIBLE_GENDER);
|
||||
setMode(MODE_CONTROLLER);
|
||||
}
|
||||
else if(userClubLevel < mannequinData.clubLevel)
|
||||
|
||||
else if(GetSessionDataManager().gender.toLowerCase() !== event.gender.toLowerCase())
|
||||
{
|
||||
setViewMode(MannequinViewMode.CLUB);
|
||||
setMode(MODE_WRONG_GENDER);
|
||||
}
|
||||
|
||||
else if(GetSessionDataManager().clubLevel < figureClubLevel)
|
||||
{
|
||||
setMode(MODE_NO_CLUB);
|
||||
}
|
||||
else
|
||||
{
|
||||
setViewMode(MannequinViewMode.DEFAULT);
|
||||
setMode(MODE_PEER);
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
});
|
||||
}, [ roomSession ]);
|
||||
|
||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateMannequinEvent.MANNEQUIN_UPDATE, eventDispatcher, onRoomWidgetUpdateMannequinEvent);
|
||||
|
||||
const getMergedFigureContainer = (figure: string, targetFigure: string) =>
|
||||
{
|
||||
switch(event.type)
|
||||
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())
|
||||
{
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN: {
|
||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
||||
|
||||
if(!roomObject) return;
|
||||
|
||||
const figure = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_FIGURE);
|
||||
const gender = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_GENDER);
|
||||
const name = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_MANNEQUIN_NAME);
|
||||
|
||||
const figureContainer = GetAvatarRenderManager().createFigureContainer(figure);
|
||||
const clubLevel = GetAvatarRenderManager().getFigureClubLevel(figureContainer, gender, parts);
|
||||
|
||||
const mannequinData = new FurnitureMannequinData(widgetEvent.objectId, widgetEvent.category, name, figure, gender, clubLevel);
|
||||
|
||||
setMannequinData(mannequinData);
|
||||
loadViewMode(mannequinData);
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
setMannequinData(prevState =>
|
||||
{
|
||||
if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
||||
|
||||
return null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
figureContainer.updatePart(part, targetFigureContainer.getPartSetId(part), targetFigureContainer.getPartColorIds(part));
|
||||
}
|
||||
}, [loadViewMode]);
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
return figureContainer;
|
||||
}
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
const transformAsMannequinFigure = (figureContainer: IAvatarFigureContainer) =>
|
||||
{
|
||||
switch(type)
|
||||
for(const part of figureContainer.getPartTypeIds())
|
||||
{
|
||||
case 'close':
|
||||
setMannequinData(null);
|
||||
return;
|
||||
case 'set_name':
|
||||
setMannequinData(mannequinData => new FurnitureMannequinData(mannequinData.objectId, mannequinData.category, value, mannequinData.figure, mannequinData.gender, mannequinData.clubLevel, mannequinData.renderedFigure));
|
||||
return;
|
||||
case 'load_figure':
|
||||
loadMannequinFigure(GetAvatarRenderManager().createFigureContainer(GetNitroInstance().sessionDataManager.figure));
|
||||
setViewMode(MannequinViewMode.SAVE);
|
||||
return;
|
||||
case 'back':
|
||||
loadMannequinFigure(GetAvatarRenderManager().createFigureContainer(mannequinData.figure));
|
||||
setViewMode(MannequinViewMode.EDIT);
|
||||
return;
|
||||
case 'save_name':
|
||||
GetRoomSession().connection.send(new FurnitureMannequinSaveNameComposer(mannequinData.objectId, mannequinData.name));
|
||||
return;
|
||||
case 'save_figure':
|
||||
GetRoomSession().connection.send(new FurnitureMannequinSaveLookComposer(mannequinData.objectId));
|
||||
processAction('save_name');
|
||||
processAction('close');
|
||||
return;
|
||||
case 'wear':
|
||||
GetRoomSession().connection.send(new FurnitureMultiStateComposer(mannequinData.objectId));
|
||||
processAction('close');
|
||||
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:
|
||||
SendMessageHook(new FurnitureMannequinSaveLookComposer(objectId));
|
||||
break;
|
||||
case ACTION_WEAR:
|
||||
SendMessageHook(new FurnitureMultiStateComposer(objectId));
|
||||
break;
|
||||
case ACTION_SET_NAME:
|
||||
SendMessageHook(new FurnitureMannequinSaveNameComposer(objectId, name));
|
||||
return;
|
||||
}
|
||||
}, [ loadMannequinFigure, mannequinData ]);
|
||||
|
||||
setMode(MODE_NONE);
|
||||
}, [ objectId, name ]);
|
||||
|
||||
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
|
||||
{
|
||||
if(event.key !== 'Enter') return;
|
||||
|
||||
processAction('save_name');
|
||||
processAction(ACTION_SET_NAME);
|
||||
};
|
||||
|
||||
if(!mannequinData) return null;
|
||||
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" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ event => processAction('close') } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText('mannequin.widget.title') } onCloseClick={ event => setMode(MODE_NONE) } />
|
||||
<NitroCardContentView>
|
||||
<div className="row">
|
||||
<div className="col-4">
|
||||
<div className="mannequin-preview">
|
||||
<AvatarImageView figure={ mannequinData.renderedFigure } direction={ 2 } />
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex flex-column justify-content-between col">
|
||||
{ viewMode === MannequinViewMode.DEFAULT &&
|
||||
<NitroLayoutGrid>
|
||||
<NitroLayoutGridColumn className="justify-content-center align-items-center" overflow="hidden" size={ 4 }>
|
||||
<FurnitureMannequinPreviewView figure={ renderedFigure } clubLevel={ renderedClubLevel } />
|
||||
</NitroLayoutGridColumn>
|
||||
<NitroLayoutGridColumn className="justify-content-between" overflow="hidden" size={ 8 }>
|
||||
{ (mode === MODE_CONTROLLER) &&
|
||||
<>
|
||||
<div className="h-100">
|
||||
<div className="mb-1 text-black fw-bold">{ mannequinData.name }</div>
|
||||
<div className="text-black">{ LocalizeText('mannequin.widget.weartext') }</div>
|
||||
</div>
|
||||
<div className="btn btn-success float-end" onClick={ event => processAction('wear') }>{ LocalizeText('mannequin.widget.wear') }</div>
|
||||
</> }
|
||||
{ viewMode === MannequinViewMode.EDIT &&
|
||||
<>
|
||||
<input type="text" className="form-control mb-2" value={ mannequinData.name } onChange={ event => processAction('set_name', event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
|
||||
<div className="d-flex flex-column w-100">
|
||||
<div className="btn btn-success mb-2 w-100" onClick={ event => processAction('load_figure') }>{ LocalizeText('mannequin.widget.style') }</div>
|
||||
<div className="btn btn-success w-100" onClick={ event => processAction('wear') }>{ LocalizeText('mannequin.widget.wear') }</div>
|
||||
</div>
|
||||
<NitroLayoutFlexColumn gap={ 1 } overflow="auto">
|
||||
<input type="text" className="form-control" value={ name } onChange={ event => setName(event.target.value) } onKeyDown={ event => handleKeyDown(event) } />
|
||||
</NitroLayoutFlexColumn>
|
||||
<NitroLayoutFlexColumn gap={ 1 }>
|
||||
<NitroLayoutButton variant="success" onClick={ event => setMode(MODE_UPDATE) }>
|
||||
{ LocalizeText('mannequin.widget.style') }
|
||||
</NitroLayoutButton>
|
||||
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_WEAR) }>
|
||||
{ LocalizeText('mannequin.widget.wear') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlexColumn>
|
||||
</> }
|
||||
{ viewMode === MannequinViewMode.SAVE &&
|
||||
{ (mode === MODE_UPDATE) &&
|
||||
<>
|
||||
<div className="h-100">
|
||||
<div className="mb-1 text-black fw-bold">{ mannequinData.name }</div>
|
||||
<div className="text-black">{ LocalizeText('mannequin.widget.savetext') }</div>
|
||||
</div>
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<div className="text-black text-decoration-underline cursor-pointer" onClick={ event => processAction('back') }>{ LocalizeText('mannequin.widget.back') }</div>
|
||||
<div className="btn btn-success" onClick={ event => processAction('save_figure') }>{ LocalizeText('mannequin.widget.save') }</div>
|
||||
</div>
|
||||
<NitroLayoutFlexColumn gap={ 1 } overflow="auto">
|
||||
<NitroLayoutBase className="text-black fw-bold">
|
||||
{ name }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText('mannequin.widget.savetext') }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlexColumn>
|
||||
<NitroLayoutFlex className="justify-content-between align-items-center">
|
||||
<NitroLayoutBase className="text-black text-decoration-underline cursor-pointer" onClick={ event => setMode(MODE_CONTROLLER) }>
|
||||
{ LocalizeText('mannequin.widget.back') }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_SAVE) }>
|
||||
{ LocalizeText('mannequin.widget.save') }
|
||||
</NitroLayoutButton>
|
||||
</NitroLayoutFlex>
|
||||
</> }
|
||||
{ viewMode === MannequinViewMode.CLUB &&
|
||||
<div className="text-black">{ LocalizeText('mannequin.widget.clubnotification') }</div> }
|
||||
{ viewMode === MannequinViewMode.INCOMPATIBLE_GENDER &&
|
||||
<div className="text-black">{ LocalizeText('mannequin.widget.wronggender') }</div> }
|
||||
</div>
|
||||
</div>
|
||||
{ (mode === MODE_PEER) &&
|
||||
<>
|
||||
<NitroLayoutFlexColumn gap={ 1 } overflow="auto">
|
||||
<NitroLayoutBase className="text-black fw-bold">
|
||||
{ name }
|
||||
</NitroLayoutBase>
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText('mannequin.widget.weartext') }
|
||||
</NitroLayoutBase>
|
||||
</NitroLayoutFlexColumn>
|
||||
<NitroLayoutButton variant="success" onClick={ event => processAction(ACTION_WEAR) }>
|
||||
{ LocalizeText('mannequin.widget.wear') }
|
||||
</NitroLayoutButton>
|
||||
</> }
|
||||
{ (mode === MODE_NO_CLUB) &&
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText('mannequin.widget.clubnotification') }
|
||||
</NitroLayoutBase> }
|
||||
{ (mode === MODE_WRONG_GENDER) &&
|
||||
<NitroLayoutBase className="text-black">
|
||||
{ LocalizeText('mannequin.widget.wronggender') }
|
||||
</NitroLayoutBase> }
|
||||
</NitroLayoutGridColumn>
|
||||
</NitroLayoutGrid>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,8 +0,0 @@
|
||||
export class MannequinViewMode
|
||||
{
|
||||
public static readonly EDIT: string = 'edit';
|
||||
public static readonly SAVE: string = 'save';
|
||||
public static readonly CLUB: string = 'club';
|
||||
public static readonly DEFAULT: string = 'default';
|
||||
public static readonly INCOMPATIBLE_GENDER: string = 'incompatible_gender';
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
import { FC } from 'react';
|
||||
import { NitroLayoutBase } from '../../../../../../../layout/base';
|
||||
import { AvatarImageView } from '../../../../../../shared/avatar-image/AvatarImageView';
|
||||
import { CurrencyIcon } from '../../../../../../shared/currency-icon/CurrencyIcon';
|
||||
import { FurnitureMannequinPreviewViewProps } from './FurnitureMannequinPreviewView.types';
|
||||
|
||||
export const FurnitureMannequinPreviewView: FC<FurnitureMannequinPreviewViewProps> = props =>
|
||||
{
|
||||
const { figure = null, clubLevel = 0 } = props;
|
||||
|
||||
return (
|
||||
<NitroLayoutBase className="mannequin-preview" position="relative">
|
||||
<AvatarImageView figure={ figure } direction={ 2 } />
|
||||
{ (clubLevel > 0) && <CurrencyIcon className="position-absolute end-2 bottom-2" type="hc" /> }
|
||||
</NitroLayoutBase>
|
||||
);
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
export interface FurnitureMannequinPreviewViewProps
|
||||
{
|
||||
figure: string;
|
||||
clubLevel: number;
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
top: 25px;
|
||||
left: 25px;
|
||||
padding: 1px;
|
||||
pointer-events: all;
|
||||
|
||||
.stickie-header {
|
||||
width: 183px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { ColorUtils, GetRoomEngine, GetRoomSession, GetSessionDataManager, RoomWidgetRoomObjectUpdateEvent } from '../../../../../api';
|
||||
import { ColorUtils, GetRoomEngine, GetRoomSession, GetSessionDataManager, RoomWidgetUpdateRoomObjectEvent } from '../../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event';
|
||||
import { DraggableWindowPosition } from '../../../../../layout';
|
||||
@ -45,8 +45,8 @@ export const FurnitureStickieView: FC<{}> = props =>
|
||||
setStickieData(new FurnitureStickieData(widgetEvent.objectId, widgetEvent.category, color, text, (GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator), false));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
setStickieData(prevState =>
|
||||
{
|
||||
@ -60,7 +60,7 @@ export const FurnitureStickieView: FC<{}> = props =>
|
||||
}, []);
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
{
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { RoomWidgetRoomObjectMessage, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../../../../api';
|
||||
import { RoomWidgetRoomObjectMessage, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRoomObjectEvent } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { InfoStandWidgetBotView } from './views/bot/InfoStandWidgetBotView';
|
||||
@ -22,33 +22,33 @@ export const InfoStandWidgetView: FC<{}> = props =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED: {
|
||||
const roomObjectEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED: {
|
||||
const roomObjectEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetRoomObjectMessage(RoomWidgetRoomObjectMessage.GET_OBJECT_INFO, roomObjectEvent.id, roomObjectEvent.category));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED: {
|
||||
const roomObjectEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED: {
|
||||
const roomObjectEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
closeInfostand();
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED:
|
||||
case RoomWidgetRoomObjectUpdateEvent.USER_REMOVED: {
|
||||
const roomObjectEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.USER_REMOVED: {
|
||||
const roomObjectEvent = (event as RoomWidgetUpdateRoomObjectEvent);
|
||||
|
||||
setInfoStandEvent(prevValue =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED:
|
||||
if(prevValue instanceof RoomWidgetUpdateInfostandFurniEvent)
|
||||
{
|
||||
if(prevValue.id === roomObjectEvent.id) return null;
|
||||
}
|
||||
break;
|
||||
case RoomWidgetRoomObjectUpdateEvent.USER_REMOVED:
|
||||
case RoomWidgetUpdateRoomObjectEvent.USER_REMOVED:
|
||||
if(prevValue instanceof RoomWidgetUpdateInfostandUserEvent || prevValue instanceof RoomWidgetUpdateInfostandRentableBotEvent)
|
||||
{
|
||||
if(prevValue.roomIndex === roomObjectEvent.id) return null;
|
||||
@ -80,10 +80,10 @@ export const InfoStandWidgetView: FC<{}> = props =>
|
||||
}
|
||||
}, [ widgetHandler, closeInfostand ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.USER_REMOVED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomObjectEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateInfostandFurniEvent.FURNI, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateInfostandUserEvent.OWN_USER, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateInfostandUserEvent.PEER, eventDispatcher, onRoomWidgetUpdateEvent);
|
||||
|
Loading…
Reference in New Issue
Block a user