mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-22 22:30:52 +01:00
Merge branch 'dev' of https://github.com/billsonnn/nitro-react into dev
This commit is contained in:
commit
714e11fb5b
@ -33,6 +33,7 @@
|
||||
"system.packet.log": false,
|
||||
"system.pong.manually": true,
|
||||
"system.pong.interval.ms": 20000,
|
||||
"room.color.skip.transition": true,
|
||||
"avatar.mandatory.libraries": [
|
||||
"bd:1",
|
||||
"li:0"
|
||||
|
@ -5,24 +5,7 @@
|
||||
"thumbnails.url": "https://nitro.nitrots.co/camera/thumbnail/%thumbnail%.png",
|
||||
"url.prefix": "http://localhost:3000",
|
||||
"chat.viewer.height.percentage": 0.40,
|
||||
"navigator.slider.enabled": true,
|
||||
"navigator.slider.content": [
|
||||
{
|
||||
"title": "Games Hub",
|
||||
"image": "https://i.imgur.com/TFoivxi.png",
|
||||
"roomId": 2240
|
||||
},
|
||||
{
|
||||
"title": "Help Desk",
|
||||
"image": "https://i.imgur.com/GO981GC.png",
|
||||
"roomId": 2351
|
||||
},
|
||||
{
|
||||
"title": "The Lido",
|
||||
"image": "https://i.imgur.com/NVH38bV.png",
|
||||
"roomId": 2346
|
||||
}
|
||||
],
|
||||
"widget.dimmer.colorwheel": false,
|
||||
"hotelview": {
|
||||
"widgets": {
|
||||
"slot.1.widget": "promoarticle",
|
||||
|
@ -5,6 +5,7 @@ import { useConfigurationEvent } from './hooks/events/core/configuration/configu
|
||||
import { useLocalizationEvent } from './hooks/events/nitro/localization/localization-event';
|
||||
import { dispatchMainEvent, useMainEvent } from './hooks/events/nitro/main-event';
|
||||
import { useRoomEngineEvent } from './hooks/events/nitro/room/room-engine-event';
|
||||
import { TransitionAnimation, TransitionAnimationTypes } from './layout';
|
||||
import { LoadingView } from './views/loading/LoadingView';
|
||||
import { MainView } from './views/main/MainView';
|
||||
|
||||
@ -126,7 +127,9 @@ export const App: FC<{}> = props =>
|
||||
return (
|
||||
<div className="nitro-app">
|
||||
{ (!isReady || isError) && <LoadingView isError={ isError } message={ message } /> }
|
||||
{ (isReady && !isError) && <MainView /> }
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ (isReady && !isError) } timeout={ 300 }>
|
||||
<MainView />
|
||||
</TransitionAnimation>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
35
src/api/nitro/room/widgets/events/RoomDimmerPreset.ts
Normal file
35
src/api/nitro/room/widgets/events/RoomDimmerPreset.ts
Normal file
@ -0,0 +1,35 @@
|
||||
export class RoomDimmerPreset
|
||||
{
|
||||
private _id: number;
|
||||
private _type: number;
|
||||
private _color: number;
|
||||
private _brightness: number;
|
||||
|
||||
constructor(id: number, type: number, color: number, brightness: number)
|
||||
{
|
||||
this._id = id;
|
||||
this._type = type;
|
||||
this._color = color;
|
||||
this._brightness = brightness;
|
||||
}
|
||||
|
||||
public get id(): number
|
||||
{
|
||||
return this._id;
|
||||
}
|
||||
|
||||
public get type(): number
|
||||
{
|
||||
return this._type;
|
||||
}
|
||||
|
||||
public get color(): number
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public get brightness(): number
|
||||
{
|
||||
return this._brightness;
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateCreditFurniEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static CREDIT_FURNI_UPDATE: string = 'RWUCFE_CREDIT_FURNI_UPDATE';
|
||||
|
||||
private _objectId: number;
|
||||
private _value: number;
|
||||
private _furniType: string;
|
||||
|
||||
constructor(type: string, objectId: number, value: number, furniType: string)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._objectId = objectId;
|
||||
this._value = value;
|
||||
this._furniType = furniType;
|
||||
}
|
||||
|
||||
public get objectId(): number
|
||||
{
|
||||
return this._objectId;
|
||||
}
|
||||
|
||||
public get value(): number
|
||||
{
|
||||
return this._value;
|
||||
}
|
||||
|
||||
public get furniType(): string
|
||||
{
|
||||
return this._furniType;
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
import { RoomDimmerPreset } from './RoomDimmerPreset';
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateDimmerEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static PRESETS: string = 'RWUDE_PRESETS';
|
||||
public static HIDE: string = 'RWUDE_HIDE';
|
||||
|
||||
private _selectedPresetId: number = 0;
|
||||
private _presets: RoomDimmerPreset[];
|
||||
|
||||
constructor(type: string)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._presets = [];
|
||||
}
|
||||
|
||||
public get presetCount(): number
|
||||
{
|
||||
return this._presets.length;
|
||||
}
|
||||
|
||||
public get presets(): RoomDimmerPreset[]
|
||||
{
|
||||
return this._presets;
|
||||
}
|
||||
|
||||
public get selectedPresetId(): number
|
||||
{
|
||||
return this._selectedPresetId;
|
||||
}
|
||||
|
||||
public set selectedPresetId(k: number)
|
||||
{
|
||||
this._selectedPresetId = k;
|
||||
}
|
||||
|
||||
public setPresetValues(id: number, type: number, color: number, brightness: number):void
|
||||
{
|
||||
const preset = new RoomDimmerPreset(id, type, color, brightness);
|
||||
|
||||
this._presets[(id - 1)] = preset;
|
||||
}
|
||||
|
||||
public getPresetNumber(id: number): RoomDimmerPreset
|
||||
{
|
||||
return this._presets[id];
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateDimmerStateEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static DIMMER_STATE: string = 'RWUDSE_DIMMER_STATE';
|
||||
|
||||
private _state: number;
|
||||
private _presetId: number;
|
||||
private _effectId: number;
|
||||
private _color: number;
|
||||
private _brightness: number;
|
||||
|
||||
constructor(state: number, presetId: number, effectId: number, color: number, brightness: number)
|
||||
{
|
||||
super(RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE);
|
||||
|
||||
this._state = state;
|
||||
this._presetId = presetId;
|
||||
this._effectId = effectId;
|
||||
this._color = color;
|
||||
this._brightness = brightness;
|
||||
}
|
||||
|
||||
public get state(): number
|
||||
{
|
||||
return this._state;
|
||||
}
|
||||
|
||||
public get presetId(): number
|
||||
{
|
||||
return this._presetId;
|
||||
}
|
||||
|
||||
public get effectId(): number
|
||||
{
|
||||
return this._effectId;
|
||||
}
|
||||
|
||||
public get color(): number
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public get brightness(): number
|
||||
{
|
||||
return this._brightness;
|
||||
}
|
||||
}
|
@ -0,0 +1,116 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdatePresentDataEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
public static PACKAGEINFO: string = 'RWUPDE_PACKAGEINFO';
|
||||
public static CONTENTS: string = 'RWUPDE_CONTENTS';
|
||||
public static CONTENTS_CLUB: string = 'RWUPDE_CONTENTS_CLUB';
|
||||
public static CONTENTS_FLOOR: string = 'RWUPDE_CONTENTS_FLOOR';
|
||||
public static CONTENTS_LANDSCAPE: string = 'RWUPDE_CONTENTS_LANDSCAPE';
|
||||
public static CONTENTS_WALLPAPER: string = 'RWUPDE_CONTENTS_WALLPAPER';
|
||||
public static CONTENTS_IMAGE: string = 'RWUPDE_CONTENTS_IMAGE';
|
||||
|
||||
private _objectId: number = -1;
|
||||
private _classId: number = 0;
|
||||
private _itemType: string = '';
|
||||
private _giftMessage: string = '';
|
||||
private _imageUrl: string = null;
|
||||
private _isController: boolean;
|
||||
private _purchaserName: string;
|
||||
private _purchaserFigure: string;
|
||||
private _placedItemId: number = -1;
|
||||
private _placedItemType: string = '';
|
||||
private _placedInRoom: boolean;
|
||||
|
||||
constructor(type: string, objectId: number, giftMessage: string, isOwnerOfFurniture: boolean = false, imageUrl: string = null, purchaserName: string = null, purchaserFigure: string = null)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._objectId = objectId;
|
||||
this._giftMessage = giftMessage;
|
||||
this._imageUrl = imageUrl;
|
||||
this._isController = isOwnerOfFurniture;
|
||||
this._purchaserName = purchaserName;
|
||||
this._purchaserFigure = purchaserFigure;
|
||||
}
|
||||
|
||||
public get objectId(): number
|
||||
{
|
||||
return this._objectId;
|
||||
}
|
||||
|
||||
public get classId(): number
|
||||
{
|
||||
return this._classId;
|
||||
}
|
||||
|
||||
public set classId(classId: number)
|
||||
{
|
||||
this._classId = classId;
|
||||
}
|
||||
|
||||
public get itemType(): string
|
||||
{
|
||||
return this._itemType;
|
||||
}
|
||||
|
||||
public set itemType(type: string)
|
||||
{
|
||||
this._itemType = type;
|
||||
}
|
||||
|
||||
public get giftMessage(): string
|
||||
{
|
||||
return this._giftMessage;
|
||||
}
|
||||
|
||||
public get imageUrl(): string
|
||||
{
|
||||
return this._imageUrl;
|
||||
}
|
||||
|
||||
public get isController(): boolean
|
||||
{
|
||||
return this._isController;
|
||||
}
|
||||
|
||||
public get purchaserName(): string
|
||||
{
|
||||
return this._purchaserName;
|
||||
}
|
||||
|
||||
public get purchaserFigure(): string
|
||||
{
|
||||
return this._purchaserFigure;
|
||||
}
|
||||
|
||||
public get placedItemId(): number
|
||||
{
|
||||
return this._placedItemId;
|
||||
}
|
||||
|
||||
public set placedItemId(itemId: number)
|
||||
{
|
||||
this._placedItemId = itemId;
|
||||
}
|
||||
|
||||
public get placedInRoom(): boolean
|
||||
{
|
||||
return this._placedInRoom;
|
||||
}
|
||||
|
||||
public set placedInRoom(flag: boolean)
|
||||
{
|
||||
this._placedInRoom = flag;
|
||||
}
|
||||
|
||||
public get placedItemType(): string
|
||||
{
|
||||
return this._placedItemType;
|
||||
}
|
||||
|
||||
public set placedItemType(type: string)
|
||||
{
|
||||
this._placedItemType = type;
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
export * from './IPhotoData';
|
||||
export * from './RoomDimmerPreset';
|
||||
export * from './RoomObjectItem';
|
||||
export * from './RoomWidgetAvatarInfoEvent';
|
||||
export * from './RoomWidgetChooserContentEvent';
|
||||
@ -10,8 +11,11 @@ export * from './RoomWidgetRoomObjectUpdateEvent';
|
||||
export * from './RoomWidgetUpdateBackgroundColorPreviewEvent';
|
||||
export * from './RoomWidgetUpdateChatEvent';
|
||||
export * from './RoomWidgetUpdateChatInputContentEvent';
|
||||
export * from './RoomWidgetUpdateCreditFurniEvent';
|
||||
export * from './RoomWidgetUpdateCustomStackHeightEvent';
|
||||
export * from './RoomWidgetUpdateDanceStatusEvent';
|
||||
export * from './RoomWidgetUpdateDimmerEvent';
|
||||
export * from './RoomWidgetUpdateDimmerStateEvent';
|
||||
export * from './RoomWidgetUpdateEvent';
|
||||
export * from './RoomWidgetUpdateExternalImageEvent';
|
||||
export * from './RoomWidgetUpdateInfostandEvent';
|
||||
@ -19,6 +23,7 @@ export * from './RoomWidgetUpdateInfostandFurniEvent';
|
||||
export * from './RoomWidgetUpdateInfostandPetEvent';
|
||||
export * from './RoomWidgetUpdateInfostandRentableBotEvent';
|
||||
export * from './RoomWidgetUpdateInfostandUserEvent';
|
||||
export * from './RoomWidgetUpdatePresentDataEvent';
|
||||
export * from './RoomWidgetUpdateRentableBotChatEvent';
|
||||
export * from './RoomWidgetUpdateRoomViewEvent';
|
||||
export * from './RoomWidgetUpdateSongEvent';
|
||||
|
@ -0,0 +1,59 @@
|
||||
import { FurnitureExchangeComposer, NitroEvent, RoomObjectVariable, RoomWidgetEnum } from '@nitrots/nitro-renderer';
|
||||
import { RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent, RoomWidgetUpdateEvent } from '..';
|
||||
import { GetRoomEngine } from '../..';
|
||||
import { IsOwnerOfFurniture } from '../../..';
|
||||
import { RoomWidgetFurniToWidgetMessage, RoomWidgetMessage } from '../messages';
|
||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||
|
||||
export class FurnitureCreditWidgetHandler extends RoomWidgetHandler
|
||||
{
|
||||
public processEvent(event: NitroEvent): void
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
switch(message.type)
|
||||
{
|
||||
case RoomWidgetFurniToWidgetMessage.REQUEST_CREDITFURNI: {
|
||||
const creditMessage = (message as RoomWidgetFurniToWidgetMessage);
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(creditMessage.roomId, creditMessage.objectId, creditMessage.category);
|
||||
|
||||
if(!roomObject || !IsOwnerOfFurniture(roomObject)) return;
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateCreditFurniEvent(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, creditMessage.objectId, roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_CREDIT_VALUE), (roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_TYPE_ID) + '_' + creditMessage.type + '_' + creditMessage.objectId)));
|
||||
|
||||
break;
|
||||
}
|
||||
case RoomWidgetCreditFurniRedeemMessage.REDEEM: {
|
||||
const redeemMessage = (message as RoomWidgetCreditFurniRedeemMessage);
|
||||
|
||||
this.container.roomSession.connection.send(new FurnitureExchangeComposer(redeemMessage.objectId));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return RoomWidgetEnum.FURNI_CREDIT_WIDGET;
|
||||
}
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomWidgetFurniToWidgetMessage.REQUEST_CREDITFURNI,
|
||||
RoomWidgetCreditFurniRedeemMessage.REDEEM
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,114 @@
|
||||
import { NitroEvent, RoomControllerLevel, RoomEngineDimmerStateEvent, RoomEngineTriggerWidgetEvent, RoomSessionDimmerPresetsEvent, RoomWidgetEnum } from '@nitrots/nitro-renderer';
|
||||
import { GetRoomEngine } from '../..';
|
||||
import { GetSessionDataManager } from '../../..';
|
||||
import { RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateEvent } from '../events';
|
||||
import { RoomWidgetUpdateDimmerStateEvent } from '../events/RoomWidgetUpdateDimmerStateEvent';
|
||||
import { RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetFurniToWidgetMessage, RoomWidgetMessage } from '../messages';
|
||||
import { RoomWidgetDimmerSavePresetMessage } from '../messages/RoomWidgetDimmerSavePresetMessage';
|
||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||
|
||||
export class FurnitureDimmerWidgetHandler extends RoomWidgetHandler
|
||||
{
|
||||
public processEvent(event: NitroEvent): void
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS: {
|
||||
const presetsEvent = (event as RoomSessionDimmerPresetsEvent);
|
||||
const updateEvent = new RoomWidgetUpdateDimmerEvent(RoomWidgetUpdateDimmerEvent.PRESETS);
|
||||
|
||||
updateEvent.selectedPresetId = presetsEvent.selectedPresetId;
|
||||
|
||||
let i = 0;
|
||||
|
||||
while(i < presetsEvent.presetCount)
|
||||
{
|
||||
const preset = presetsEvent.getPreset(i);
|
||||
|
||||
if(preset) updateEvent.setPresetValues(preset.id, preset.type, preset.color, preset.brightness);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(updateEvent);
|
||||
return;
|
||||
}
|
||||
case RoomEngineDimmerStateEvent.ROOM_COLOR: {
|
||||
const stateEvent = (event as RoomEngineDimmerStateEvent);
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDimmerStateEvent(stateEvent.state, stateEvent.presetId, stateEvent.effectId, stateEvent.color, stateEvent.brightness));
|
||||
return;
|
||||
}
|
||||
case RoomEngineTriggerWidgetEvent.REMOVE_DIMMER: {
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDimmerEvent(RoomWidgetUpdateDimmerEvent.HIDE));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
switch(message.type)
|
||||
{
|
||||
case RoomWidgetFurniToWidgetMessage.REQUEST_DIMMER: {
|
||||
if(this.canOpenWidget()) this.container.roomSession.requestMoodlightSettings();
|
||||
|
||||
break;
|
||||
}
|
||||
case RoomWidgetDimmerSavePresetMessage.SAVE_PRESET: {
|
||||
if(this.canOpenWidget())
|
||||
{
|
||||
const savePresetMessage = (message as RoomWidgetDimmerSavePresetMessage);
|
||||
|
||||
this.container.roomSession.updateMoodlightData(savePresetMessage.presetNumber, savePresetMessage.effectTypeId, savePresetMessage.color, savePresetMessage.brightness, savePresetMessage.apply);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case RoomWidgetDimmerChangeStateMessage.CHANGE_STATE: {
|
||||
if(this.canOpenWidget()) this.container.roomSession.toggleMoodlightState();
|
||||
|
||||
break;
|
||||
}
|
||||
case RoomWidgetDimmerPreviewMessage.PREVIEW_DIMMER_PRESET: {
|
||||
const roomId = this.container.roomSession.roomId;
|
||||
const previewMessage = (message as RoomWidgetDimmerPreviewMessage);
|
||||
|
||||
GetRoomEngine().updateObjectRoomColor(roomId, previewMessage.color, previewMessage.brightness, previewMessage.bgOnly);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private canOpenWidget(): boolean
|
||||
{
|
||||
return (this.container.roomSession.isRoomOwner || (this.container.roomSession.controllerLevel >= RoomControllerLevel.GUEST) || GetSessionDataManager().isModerator);
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return RoomWidgetEnum.ROOM_DIMMER;
|
||||
}
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomSessionDimmerPresetsEvent.ROOM_DIMMER_PRESETS,
|
||||
RoomEngineDimmerStateEvent.ROOM_COLOR,
|
||||
RoomEngineTriggerWidgetEvent.REMOVE_DIMMER
|
||||
];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomWidgetFurniToWidgetMessage.REQUEST_DIMMER,
|
||||
RoomWidgetDimmerSavePresetMessage.SAVE_PRESET,
|
||||
RoomWidgetDimmerChangeStateMessage.CHANGE_STATE,
|
||||
RoomWidgetDimmerPreviewMessage.PREVIEW_DIMMER_PRESET
|
||||
];
|
||||
}
|
||||
}
|
@ -0,0 +1,223 @@
|
||||
import { IFurnitureData, IGetImageListener, NitroEvent, NitroRenderTexture, PetFigureData, RoomObjectCategory, RoomObjectVariable, RoomSessionPresentEvent, RoomWidgetEnum, TextureUtils, Vector3d } from '@nitrots/nitro-renderer';
|
||||
import { GetSessionDataManager, IsOwnerOfFurniture } from '../../..';
|
||||
import { GetRoomEngine, LocalizeText } from '../../../..';
|
||||
import { ProductTypeEnum } from '../../../../../views/catalog/common/ProductTypeEnum';
|
||||
import { RoomWidgetUpdateEvent, RoomWidgetUpdatePresentDataEvent } from '../events';
|
||||
import { RoomWidgetFurniToWidgetMessage, RoomWidgetPresentOpenMessage } from '../messages';
|
||||
import { RoomWidgetMessage } from '../messages/RoomWidgetMessage';
|
||||
import { RoomWidgetHandler } from './RoomWidgetHandler';
|
||||
|
||||
export class FurniturePresentWidgetHandler extends RoomWidgetHandler implements IGetImageListener
|
||||
{
|
||||
private static FLOOR: string = 'floor';
|
||||
private static WALLPAPER: string = 'wallpaper';
|
||||
private static LANDSCAPE: string = 'landscape';
|
||||
private static POSTER: string = 'poster';
|
||||
|
||||
private _lastFurniId: number = -1;
|
||||
private _name: string = null;
|
||||
|
||||
public processEvent(event: NitroEvent): void
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomSessionPresentEvent.RSPE_PRESENT_OPENED: {
|
||||
const presentEvent = (event as RoomSessionPresentEvent);
|
||||
|
||||
let furniData: IFurnitureData = null;
|
||||
|
||||
if(presentEvent.itemType === ProductTypeEnum.FLOOR)
|
||||
{
|
||||
furniData = GetSessionDataManager().getFloorItemData(presentEvent.classId);
|
||||
}
|
||||
else if(presentEvent.itemType === ProductTypeEnum.WALL)
|
||||
{
|
||||
furniData = GetSessionDataManager().getWallItemData(presentEvent.classId);
|
||||
}
|
||||
|
||||
let isOwnerOfFurni = false;
|
||||
|
||||
if(presentEvent.placedInRoom)
|
||||
{
|
||||
const roomObject = GetRoomEngine().getRoomObject(this.container.roomSession.roomId, presentEvent.placedItemId, RoomObjectCategory.FLOOR);
|
||||
|
||||
if(roomObject) isOwnerOfFurni = IsOwnerOfFurniture(roomObject);
|
||||
}
|
||||
|
||||
let giftImage: string = null;
|
||||
let dataUpdateEvent: RoomWidgetUpdatePresentDataEvent = null;
|
||||
|
||||
switch(presentEvent.itemType)
|
||||
{
|
||||
case ProductTypeEnum.WALL: {
|
||||
if(furniData)
|
||||
{
|
||||
switch(furniData.className)
|
||||
{
|
||||
case FurniturePresentWidgetHandler.FLOOR:
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR, 0, LocalizeText('inventory.furni.item.floor.name'), isOwnerOfFurni);
|
||||
break;
|
||||
case FurniturePresentWidgetHandler.LANDSCAPE:
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE, 0, LocalizeText('inventory.furni.item.landscape.name'), isOwnerOfFurni);
|
||||
break;
|
||||
case FurniturePresentWidgetHandler.WALLPAPER:
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER, 0, LocalizeText('inventory.furni.item.wallpaper.name'), isOwnerOfFurni);
|
||||
break;
|
||||
case FurniturePresentWidgetHandler.POSTER: {
|
||||
const productCode = presentEvent.productCode;
|
||||
|
||||
let extras: string = null;
|
||||
|
||||
if(productCode.indexOf('poster') === 0) extras = productCode.replace('poster', '');
|
||||
|
||||
giftImage = GetRoomEngine().getFurnitureWallIconUrl(presentEvent.classId, extras);
|
||||
|
||||
const productData = GetSessionDataManager().getProductData(productCode);
|
||||
|
||||
if(productData) this._name = productData.name;
|
||||
else if(furniData) this._name = furniData.name;
|
||||
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS, 0, this._name, isOwnerOfFurni, giftImage);
|
||||
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
giftImage = GetRoomEngine().getFurnitureWallIconUrl(presentEvent.classId);
|
||||
|
||||
if(furniData) this._name = furniData.name;
|
||||
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS, 0, this._name, isOwnerOfFurni, giftImage);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case ProductTypeEnum.HABBO_CLUB:
|
||||
dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB, 0, LocalizeText('widget.furni.present.hc'), false);
|
||||
break;
|
||||
default: {
|
||||
if(presentEvent.placedItemType === ProductTypeEnum.PET)
|
||||
{
|
||||
const petfigureString = presentEvent.petFigureString;
|
||||
|
||||
if(petfigureString && petfigureString.length)
|
||||
{
|
||||
const petFigureData = new PetFigureData(petfigureString);
|
||||
|
||||
const petImage = GetRoomEngine().getRoomObjectPetImage(petFigureData.typeId, petFigureData.paletteId, petFigureData.color, new Vector3d(90), 64, this, true, 0, petFigureData.customParts);
|
||||
|
||||
if(petImage) giftImage = petImage.getImage().src;
|
||||
}
|
||||
}
|
||||
|
||||
if(!giftImage)
|
||||
{
|
||||
const furniImage = GetRoomEngine().getFurnitureFloorImage(presentEvent.classId, new Vector3d(90), 64, this);
|
||||
|
||||
if(furniImage) giftImage = furniImage.getImage().src;
|
||||
}
|
||||
|
||||
const productData = GetSessionDataManager().getProductData(presentEvent.productCode);
|
||||
|
||||
if(productData) this._name = productData.name;
|
||||
else this._name = furniData.name;
|
||||
|
||||
if(giftImage) dataUpdateEvent = new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS, 0, this._name, isOwnerOfFurni, giftImage);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(dataUpdateEvent)
|
||||
{
|
||||
dataUpdateEvent.classId = presentEvent.classId;
|
||||
dataUpdateEvent.itemType = presentEvent.itemType;
|
||||
dataUpdateEvent.placedItemId = presentEvent.placedItemId;
|
||||
dataUpdateEvent.placedInRoom = presentEvent.placedInRoom;
|
||||
dataUpdateEvent.placedItemType = presentEvent.placedItemType;
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(dataUpdateEvent);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
switch(message.type)
|
||||
{
|
||||
case RoomWidgetFurniToWidgetMessage.REQUEST_PRESENT: {
|
||||
const widgetMessage = (message as RoomWidgetFurniToWidgetMessage);
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(widgetMessage.roomId, widgetMessage.objectId, widgetMessage.category);
|
||||
|
||||
if(!roomObject) return null;
|
||||
|
||||
this._lastFurniId = widgetMessage.objectId;
|
||||
|
||||
const giftMessage = (roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_DATA) || '');
|
||||
const purchaserName = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_PURCHASER_NAME);
|
||||
const purchaserFigure = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_PURCHASER_FIGURE);
|
||||
const typeId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_TYPE_ID);
|
||||
const extras = roomObject.model.getValue<string>(RoomObjectVariable.FURNITURE_EXTRAS);
|
||||
const giftImage = GetRoomEngine().getFurnitureFloorImage(typeId, new Vector3d(180), 64, null, 0, extras);
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.PACKAGEINFO, widgetMessage.objectId, giftMessage, IsOwnerOfFurniture(roomObject), giftImage.getImage().src, purchaserName, purchaserFigure));
|
||||
|
||||
break;
|
||||
}
|
||||
case RoomWidgetPresentOpenMessage.OPEN_PRESENT: {
|
||||
const openMessage = (message as RoomWidgetPresentOpenMessage);
|
||||
|
||||
if(openMessage.objectId !== this._lastFurniId) return null;
|
||||
|
||||
this.container.roomSession.openGift(openMessage.objectId);
|
||||
|
||||
GetRoomEngine().changeObjectModelData(GetRoomEngine().activeRoomId, openMessage.objectId, RoomObjectCategory.FLOOR, RoomObjectVariable.FURNITURE_DISABLE_PICKING_ANIMATION, 1);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public imageReady(id: number, texture: NitroRenderTexture, image: HTMLImageElement = null): void
|
||||
{
|
||||
let imageUrl: string = null;
|
||||
|
||||
if(image) imageUrl = image.src;
|
||||
else if(texture) imageUrl = TextureUtils.generateImageUrl(texture);
|
||||
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdatePresentDataEvent(RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE, 0, this._name, false, imageUrl));
|
||||
}
|
||||
|
||||
public imageFailed(id: number): void
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public get type(): string
|
||||
{
|
||||
return RoomWidgetEnum.FURNI_PRESENT_WIDGET;
|
||||
}
|
||||
|
||||
public get eventTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomSessionPresentEvent.RSPE_PRESENT_OPENED
|
||||
];
|
||||
}
|
||||
|
||||
public get messageTypes(): string[]
|
||||
{
|
||||
return [
|
||||
RoomWidgetFurniToWidgetMessage.REQUEST_PRESENT,
|
||||
RoomWidgetPresentOpenMessage.OPEN_PRESENT
|
||||
];
|
||||
}
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomWidgetEnum, RoomZoomEvent, TextureUtils } from '@nitrots/nitro-renderer';
|
||||
import { GetConfiguration, GetNitroInstance } from '../../..';
|
||||
import { GetRoomEngine, GetSessionDataManager } from '../../../..';
|
||||
import { SendMessageHook } from '../../../../../hooks/messages';
|
||||
import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events';
|
||||
@ -146,6 +147,12 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler
|
||||
}
|
||||
|
||||
return null;
|
||||
case ':togglefps': {
|
||||
if(GetNitroInstance().ticker.maxFPS > 0) GetNitroInstance().ticker.maxFPS = 0;
|
||||
else GetNitroInstance().ticker.maxFPS = GetConfiguration('system.animation.fps');
|
||||
|
||||
return null;
|
||||
}
|
||||
case ':client':
|
||||
case ':nitro':
|
||||
case ':billsonnn':
|
||||
|
@ -1,8 +1,11 @@
|
||||
export * from './DoorbellWidgetHandler';
|
||||
export * from './FurniChooserWidgetHandler';
|
||||
export * from './FurnitureContextMenuWidgetHandler';
|
||||
export * from './FurnitureCreditWidgetHandler';
|
||||
export * from './FurnitureCustomStackHeightWidgetHandler';
|
||||
export * from './FurnitureDimmerWidgetHandler';
|
||||
export * from './FurnitureExternalImageWidgetHandler';
|
||||
export * from './FurniturePresentWidgetHandler';
|
||||
export * from './IRoomWidgetHandler';
|
||||
export * from './IRoomWidgetHandlerManager';
|
||||
export * from './RoomWidgetAvatarInfoHandler';
|
||||
|
@ -0,0 +1,20 @@
|
||||
import { RoomWidgetMessage } from './RoomWidgetMessage';
|
||||
|
||||
export class RoomWidgetCreditFurniRedeemMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static REDEEM: string = 'RWCFRM_REDEEM';
|
||||
|
||||
private _objectId: number;
|
||||
|
||||
constructor(type: string, objectId: number)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._objectId = objectId;
|
||||
}
|
||||
|
||||
public get objectId(): number
|
||||
{
|
||||
return this._objectId;
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
import { RoomWidgetMessage } from './RoomWidgetMessage';
|
||||
|
||||
export class RoomWidgetDimmerChangeStateMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static CHANGE_STATE: string = 'RWCDSM_CHANGE_STATE';
|
||||
|
||||
constructor()
|
||||
{
|
||||
super(RoomWidgetDimmerChangeStateMessage.CHANGE_STATE);
|
||||
}
|
||||
}
|
@ -0,0 +1,34 @@
|
||||
import { RoomWidgetMessage } from './RoomWidgetMessage';
|
||||
|
||||
export class RoomWidgetDimmerPreviewMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static PREVIEW_DIMMER_PRESET: string = 'RWDPM_PREVIEW_DIMMER_PRESET';
|
||||
|
||||
private _color: number;
|
||||
private _brightness: number;
|
||||
private _bgOnly: boolean;
|
||||
|
||||
constructor(color: number, brightness: number, bgOnly: boolean)
|
||||
{
|
||||
super(RoomWidgetDimmerPreviewMessage.PREVIEW_DIMMER_PRESET);
|
||||
|
||||
this._color = color;
|
||||
this._brightness = brightness;
|
||||
this._bgOnly = bgOnly;
|
||||
}
|
||||
|
||||
public get color(): number
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public get brightness(): number
|
||||
{
|
||||
return this._brightness;
|
||||
}
|
||||
|
||||
public get bgOnly(): boolean
|
||||
{
|
||||
return this._bgOnly;
|
||||
}
|
||||
}
|
@ -0,0 +1,48 @@
|
||||
import { RoomWidgetMessage } from './RoomWidgetMessage';
|
||||
|
||||
export class RoomWidgetDimmerSavePresetMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static SAVE_PRESET: string = 'RWSDPM_SAVE_PRESET';
|
||||
|
||||
private _presetNumber: number;
|
||||
private _effectTypeId: number;
|
||||
private _color: number;
|
||||
private _brightness: number;
|
||||
private _apply: boolean;
|
||||
|
||||
constructor(presetNumber: number, effectTypeId: number, color: number, brightness: number, apply: boolean)
|
||||
{
|
||||
super(RoomWidgetDimmerSavePresetMessage.SAVE_PRESET);
|
||||
|
||||
this._presetNumber = presetNumber;
|
||||
this._effectTypeId = effectTypeId;
|
||||
this._color = color;
|
||||
this._brightness = brightness;
|
||||
this._apply = apply;
|
||||
}
|
||||
|
||||
public get presetNumber(): number
|
||||
{
|
||||
return this._presetNumber;
|
||||
}
|
||||
|
||||
public get effectTypeId(): number
|
||||
{
|
||||
return this._effectTypeId;
|
||||
}
|
||||
|
||||
public get color(): number
|
||||
{
|
||||
return this._color;
|
||||
}
|
||||
|
||||
public get brightness(): number
|
||||
{
|
||||
return this._brightness;
|
||||
}
|
||||
|
||||
public get apply(): boolean
|
||||
{
|
||||
return this._apply;
|
||||
}
|
||||
}
|
@ -0,0 +1,20 @@
|
||||
import { RoomWidgetMessage } from './RoomWidgetMessage';
|
||||
|
||||
export class RoomWidgetPresentOpenMessage extends RoomWidgetMessage
|
||||
{
|
||||
public static OPEN_PRESENT: string = 'RWPOM_OPEN_PRESENT';
|
||||
|
||||
private _objectId: number;
|
||||
|
||||
constructor(type: string, objectId: number)
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._objectId = objectId;
|
||||
}
|
||||
|
||||
public get objectId(): number
|
||||
{
|
||||
return this._objectId;
|
||||
}
|
||||
}
|
@ -4,11 +4,16 @@ export * from './RoomWidgetChangePostureMessage';
|
||||
export * from './RoomWidgetChatMessage';
|
||||
export * from './RoomWidgetChatSelectAvatarMessage';
|
||||
export * from './RoomWidgetChatTypingMessage';
|
||||
export * from './RoomWidgetCreditFurniRedeemMessage';
|
||||
export * from './RoomWidgetDanceMessage';
|
||||
export * from './RoomWidgetDimmerChangeStateMessage';
|
||||
export * from './RoomWidgetDimmerPreviewMessage';
|
||||
export * from './RoomWidgetDimmerSavePresetMessage';
|
||||
export * from './RoomWidgetFurniActionMessage';
|
||||
export * from './RoomWidgetFurniToWidgetMessage';
|
||||
export * from './RoomWidgetLetUserInMessage';
|
||||
export * from './RoomWidgetMessage';
|
||||
export * from './RoomWidgetPresentOpenMessage';
|
||||
export * from './RoomWidgetRequestWidgetMessage';
|
||||
export * from './RoomWidgetRoomObjectMessage';
|
||||
export * from './RoomWidgetUseProductMessage';
|
||||
|
@ -4,4 +4,14 @@ export class ColorUtils
|
||||
{
|
||||
return ('#' + color);
|
||||
}
|
||||
|
||||
public static makeColorNumberHex(color: number): string
|
||||
{
|
||||
return ( '#' + color.toString(16));
|
||||
}
|
||||
|
||||
public static convertFromHex(color: string): number
|
||||
{
|
||||
return parseInt(color.replace('#', ''), 16);
|
||||
}
|
||||
}
|
||||
|
BIN
src/assets/images/catalog/hc_banner_big.png
Normal file
BIN
src/assets/images/catalog/hc_banner_big.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.5 KiB |
BIN
src/assets/images/gift/gift_tag.png
Normal file
BIN
src/assets/images/gift/gift_tag.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 795 B |
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 1.0 KiB |
BIN
src/assets/images/room-widgets/dimmer-widget/dimmer_banner.png
Normal file
BIN
src/assets/images/room-widgets/dimmer-widget/dimmer_banner.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -9,6 +9,8 @@ export class CatalogEvent extends NitroEvent
|
||||
public static PURCHASE_FAILED: string = 'CE_PURCHASE_FAILED';
|
||||
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
||||
public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT';
|
||||
public static GIFT_RECEIVER_NOT_FOUND: string = 'CE_GIFT_RECEIVER_NOT_FOUND';
|
||||
public static PURCHASE_APPROVED: string = 'CE_PURCHASE_APPROVED';
|
||||
public static INIT_GIFT: string = 'CE_INIT_GIFT';
|
||||
public static CATALOG_RESET: string = 'CE_RESET';
|
||||
}
|
||||
|
9
src/events/catalog/CatalogGiftReceiverNotFoundEvent.ts
Normal file
9
src/events/catalog/CatalogGiftReceiverNotFoundEvent.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { CatalogEvent } from './CatalogEvent';
|
||||
|
||||
export class CatalogGiftReceiverNotFoundEvent extends CatalogEvent
|
||||
{
|
||||
constructor()
|
||||
{
|
||||
super(CatalogEvent.GIFT_RECEIVER_NOT_FOUND);
|
||||
}
|
||||
}
|
32
src/events/catalog/CatalogInitGiftEvent.ts
Normal file
32
src/events/catalog/CatalogInitGiftEvent.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { CatalogEvent } from './CatalogEvent';
|
||||
|
||||
export class CatalogInitGiftEvent extends CatalogEvent
|
||||
{
|
||||
private _pageId: number;
|
||||
private _offerId: number;
|
||||
private _extraData: string;
|
||||
|
||||
constructor(pageId: number, offerId: number, extraData: string)
|
||||
{
|
||||
super(CatalogEvent.INIT_GIFT);
|
||||
|
||||
this._pageId = pageId;
|
||||
this._offerId = offerId;
|
||||
this._extraData = extraData;
|
||||
}
|
||||
|
||||
public get pageId(): number
|
||||
{
|
||||
return this._pageId;
|
||||
}
|
||||
|
||||
public get offerId(): number
|
||||
{
|
||||
return this._offerId;
|
||||
}
|
||||
|
||||
public get extraData(): string
|
||||
{
|
||||
return this._extraData;
|
||||
}
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
import { MessengerFriend } from '../../views/friend-list/common/MessengerFriend';
|
||||
import { MessengerFriend } from '../../views/friends/common/MessengerFriend';
|
||||
import { FriendListEvent } from './FriendListEvent';
|
||||
|
||||
export class FriendListContentEvent extends FriendListEvent
|
||||
|
6
src/hooks/BatchUpdates.ts
Normal file
6
src/hooks/BatchUpdates.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { unstable_batchedUpdates } from 'react-dom';
|
||||
|
||||
export const BatchUpdates = (callback: () => any) =>
|
||||
{
|
||||
return unstable_batchedUpdates(callback);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
export * from './BatchUpdates';
|
||||
export * from './events';
|
||||
export * from './events/core';
|
||||
export * from './events/nitro';
|
||||
|
@ -29,3 +29,4 @@
|
||||
@import './mini-camera/NitroLayoutMiniCameraView';
|
||||
@import './notification-bubble/NotificationBubbleView';
|
||||
@import './trophy/NitroLayoutTrophyView';
|
||||
@import './gift-card/NitroLayoutGiftCardView';
|
||||
|
@ -1,12 +1,17 @@
|
||||
import { FC, useState } from 'react';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { NitroCardAccordionItemViewProps } from './NitroCardAccordionItemView.types';
|
||||
|
||||
export const NitroCardAccordionItemView: FC<NitroCardAccordionItemViewProps> = props =>
|
||||
{
|
||||
const { className = '', headerClassName = '', contentClassName = '', headerText = '' } = props;
|
||||
const { className = '', headerClassName = '', contentClassName = '', headerText = '', defaultState = false } = props;
|
||||
|
||||
const [ isExpanded, setIsExpanded ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setIsExpanded(defaultState);
|
||||
}, [ defaultState ]);
|
||||
|
||||
return (
|
||||
<div className={ 'nitro-card-accordion-item ' + className + (isExpanded ? ' active' : '') }>
|
||||
<div className={ 'nitro-card-accordion-item-header px-2 py-1 d-flex ' + headerClassName } onClick={ () => setIsExpanded((value) => !value) }>
|
||||
|
@ -4,4 +4,5 @@ export interface NitroCardAccordionItemViewProps
|
||||
headerClassName?: string;
|
||||
contentClassName?: string;
|
||||
headerText: string;
|
||||
defaultState?: boolean;
|
||||
}
|
||||
|
41
src/layout/gift-card/NitroLayoutGiftCardView.scss
Normal file
41
src/layout/gift-card/NitroLayoutGiftCardView.scss
Normal file
@ -0,0 +1,41 @@
|
||||
.nitro-gift-card {
|
||||
width: 306px;
|
||||
height: 159px;
|
||||
background: url(../../assets/images/gift/gift_tag.png) center no-repeat;
|
||||
|
||||
.gift-face {
|
||||
width: 65px;
|
||||
|
||||
.gift-incognito {
|
||||
width: 37px;
|
||||
height: 48px;
|
||||
background: url(../../assets/images/gift/incognito.png) center no-repeat;
|
||||
}
|
||||
|
||||
.gift-avatar {
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
width: 40px;
|
||||
height: 50px;
|
||||
|
||||
.avatar-image {
|
||||
position: absolute;
|
||||
left: -25px;
|
||||
top: -20px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gift-message {
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
height: 90px;
|
||||
min-height: 90px;
|
||||
max-height: 90px;
|
||||
border: none;
|
||||
resize: none;
|
||||
outline: none;
|
||||
line-height: 17px;
|
||||
}
|
||||
}
|
25
src/layout/gift-card/NitroLayoutGiftCardView.tsx
Normal file
25
src/layout/gift-card/NitroLayoutGiftCardView.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeText } from '../../api';
|
||||
import { AvatarImageView } from '../../views/shared/avatar-image/AvatarImageView';
|
||||
import { NitroLayoutGiftCardViewProps } from './NitroLayoutGiftCardView.types';
|
||||
|
||||
export const NitroLayoutGiftCardView: FC<NitroLayoutGiftCardViewProps> = props =>
|
||||
{
|
||||
const { figure = null, userName = null, message = null, editable = false, onChange = null } = props;
|
||||
|
||||
return (
|
||||
<div className="nitro-gift-card d-flex text-black">
|
||||
<div className="d-flex align-items-center justify-content-center gift-face flex-shrink-0">
|
||||
{ !userName && <div className="gift-incognito"></div> }
|
||||
{ figure && <div className="gift-avatar">
|
||||
<AvatarImageView figure={ figure } direction={ 2 } headOnly={ true } />
|
||||
</div> }
|
||||
</div>
|
||||
<div className="d-flex flex-column w-100 pt-4 pb-4 pe-4 ps-3">
|
||||
{ !editable && <div className="gift-message">{ message }</div> }
|
||||
{ editable && onChange && <textarea className="gift-message" maxLength={ 140 } value={ message } onChange={ (e) => onChange(e.target.value) } placeholder={ LocalizeText('catalog.gift_wrapping_new.message_hint') }></textarea> }
|
||||
{ userName && <div className="mt-auto text-end fst-italic">{ LocalizeText('catalog.gift_wrapping_new.message_from', ['name'], [userName]) }</div> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
8
src/layout/gift-card/NitroLayoutGiftCardView.types.ts
Normal file
8
src/layout/gift-card/NitroLayoutGiftCardView.types.ts
Normal file
@ -0,0 +1,8 @@
|
||||
export interface NitroLayoutGiftCardViewProps
|
||||
{
|
||||
figure?:string;
|
||||
userName?: string;
|
||||
message?: string;
|
||||
editable?: boolean;
|
||||
onChange?: (value: string) => void;
|
||||
}
|
2
src/layout/gift-card/index.ts
Normal file
2
src/layout/gift-card/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './NitroLayoutGiftCardView';
|
||||
export * from './NitroLayoutGiftCardView.types';
|
@ -1,5 +1,6 @@
|
||||
export * from './card';
|
||||
export * from './draggable-window';
|
||||
export * from './gift-card';
|
||||
export * from './loading-spinner';
|
||||
export * from './mini-camera';
|
||||
export * from './notification-bubble';
|
||||
|
@ -2,7 +2,7 @@
|
||||
@import './avatar-editor/AvatarEditorView';
|
||||
@import './camera/CameraWidgetView';
|
||||
@import './catalog/CatalogView';
|
||||
@import './friend-list/FriendListView';
|
||||
@import './friends/FriendsView';
|
||||
@import './groups/GroupView';
|
||||
@import './hotel-view/HotelView';
|
||||
@import './inventory/InventoryView';
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { ApproveNameMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, GiftWrappingConfigurationEvent, HabboClubOffersMessageEvent, LimitedEditionSoldOutEvent, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, SellablePetPalettesMessageEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer';
|
||||
import { ApproveNameMessageEvent, CatalogPageMessageEvent, CatalogPagesListEvent, CatalogPublishedMessageEvent, GiftReceiverNotFoundEvent, GiftWrappingConfigurationEvent, HabboClubOffersMessageEvent, LimitedEditionSoldOutEvent, ProductOfferEvent, PurchaseErrorMessageEvent, PurchaseNotAllowedMessageEvent, PurchaseOKMessageEvent, SellablePetPalettesMessageEvent, UserSubscriptionEvent } from '@nitrots/nitro-renderer';
|
||||
import { GuildMembershipsMessageEvent } from '@nitrots/nitro-renderer/src/nitro/communication/messages/incoming/user/GuildMembershipsMessageEvent';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent } from '../../events';
|
||||
import { CatalogGiftReceiverNotFoundEvent } from '../../events/catalog/CatalogGiftReceiverNotFoundEvent';
|
||||
import { CatalogPurchasedEvent } from '../../events/catalog/CatalogPurchasedEvent';
|
||||
import { CatalogPurchaseSoldOutEvent } from '../../events/catalog/CatalogPurchaseSoldOutEvent';
|
||||
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
@ -96,6 +97,11 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||
dispatchUiEvent(new CatalogNameResultEvent(parser.result, parser.validationInfo));
|
||||
}, []);
|
||||
|
||||
const onGiftReceiverNotFoundEvent = useCallback(() =>
|
||||
{
|
||||
dispatchUiEvent(new CatalogGiftReceiverNotFoundEvent());
|
||||
}, []);
|
||||
|
||||
const onHabboClubOffersMessageEvent = useCallback((event: HabboClubOffersMessageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -168,6 +174,7 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||
CreateMessageHook(GuildMembershipsMessageEvent, onGuildMembershipsMessageEvent);
|
||||
CreateMessageHook(SellablePetPalettesMessageEvent, onSellablePetPalettesMessageEvent);
|
||||
CreateMessageHook(ApproveNameMessageEvent, onApproveNameMessageEvent);
|
||||
CreateMessageHook(GiftReceiverNotFoundEvent, onGiftReceiverNotFoundEvent);
|
||||
CreateMessageHook(HabboClubOffersMessageEvent, onHabboClubOffersMessageEvent);
|
||||
CreateMessageHook(UserSubscriptionEvent, onUserSubscriptionEvent);
|
||||
CreateMessageHook(CatalogPublishedMessageEvent, onCatalogPublishedMessageEvent);
|
||||
|
@ -10,6 +10,7 @@ import { CatalogMode, CatalogViewProps } from './CatalogView.types';
|
||||
import { BuildCatalogPageTree } from './common/CatalogUtilities';
|
||||
import { CatalogContextProvider } from './context/CatalogContext';
|
||||
import { CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
||||
import { CatalogPageGiftView } from './views/gift/CatalogPageGiftView';
|
||||
import { ACTIVE_PAGES, CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
||||
import { CatalogPageView } from './views/page/CatalogPageView';
|
||||
|
||||
@ -213,6 +214,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView> }
|
||||
<CatalogPageGiftView />
|
||||
</CatalogContextProvider>
|
||||
);
|
||||
}
|
||||
|
@ -2,3 +2,4 @@
|
||||
@import './navigation/CatalogNavigationView';
|
||||
@import './page/CatalogPageView';
|
||||
@import './search/CatalogSearchView';
|
||||
@import './gift/CatalogPageGiftView';
|
||||
|
14
src/views/catalog/views/gift/CatalogPageGiftView.scss
Normal file
14
src/views/catalog/views/gift/CatalogPageGiftView.scss
Normal file
@ -0,0 +1,14 @@
|
||||
.nitro-catalog-gift {
|
||||
|
||||
.gift-preview {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.gift-color {
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
border-radius: $border-radius;
|
||||
}
|
||||
}
|
235
src/views/catalog/views/gift/CatalogPageGiftView.tsx
Normal file
235
src/views/catalog/views/gift/CatalogPageGiftView.tsx
Normal file
@ -0,0 +1,235 @@
|
||||
import { PurchaseFromCatalogAsGiftComposer } from '@nitrots/nitro-renderer';
|
||||
import classNames from 'classnames';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetSessionDataManager, LocalizeText } from '../../../../api';
|
||||
import { CatalogEvent } from '../../../../events';
|
||||
import { CatalogInitGiftEvent } from '../../../../events/catalog/CatalogInitGiftEvent';
|
||||
import { SendMessageHook, useUiEvent } from '../../../../hooks';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGiftCardView } from '../../../../layout';
|
||||
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||
import { FurniImageView } from '../../../shared/furni-image/FurniImageView';
|
||||
import { useCatalogContext } from '../../context/CatalogContext';
|
||||
|
||||
export const CatalogPageGiftView: FC<{}> = props =>
|
||||
{
|
||||
const { catalogState = null } = useCatalogContext();
|
||||
const { giftConfiguration = null } = catalogState;
|
||||
|
||||
const [ isVisible, setIsVisible ] = useState<boolean>(false);
|
||||
const [ pageId, setPageId ] = useState<number>(0);
|
||||
const [ offerId, setOfferId ] = useState<number>(0);
|
||||
|
||||
const [ receiverName, setReceiverName ] = useState<string>('');
|
||||
const [ showMyFace, setShowMyFace ] = useState<boolean>(true);
|
||||
const [ message, setMessage ] = useState<string>('');
|
||||
const [ colors, setColors ] = useState<{ id: number, color: string }[]>([]);
|
||||
const [ selectedBoxIndex, setSelectedBoxIndex ] = useState<number>(0);
|
||||
const [ selectedRibbonIndex, setSelectedRibbonIndex ] = useState<number>(0);
|
||||
const [ selectedColorId, setSelectedColorId ] = useState<number>(0);
|
||||
const [ maxBoxIndex, setMaxBoxIndex ] = useState<number>(0);
|
||||
const [ maxRibbonIndex, setMaxRibbonIndex ] = useState<number>(0);
|
||||
|
||||
const [ receiverNotFound, setReceiverNotFound ] = useState<boolean>(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setReceiverNotFound(false);
|
||||
}, [ receiverName ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!giftConfiguration) return;
|
||||
|
||||
setMaxBoxIndex(giftConfiguration.boxTypes.length - 1);
|
||||
setMaxRibbonIndex(giftConfiguration.ribbonTypes.length - 1);
|
||||
|
||||
const newColors: { id: number, color: string }[] = [];
|
||||
|
||||
for(const colorId of giftConfiguration.stuffTypes)
|
||||
{
|
||||
const giftData = GetSessionDataManager().getFloorItemData(colorId);
|
||||
|
||||
if(!giftData) continue;
|
||||
|
||||
if(giftData.colors && giftData.colors.length > 0) newColors.push({ id: colorId, color: `#${giftData.colors[0].toString(16)}` });
|
||||
}
|
||||
|
||||
setSelectedColorId(newColors[0].id);
|
||||
setColors(newColors);
|
||||
}, [ giftConfiguration ]);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
setPageId(0);
|
||||
setOfferId(0);
|
||||
setReceiverName('');
|
||||
setShowMyFace(true);
|
||||
setMessage('');
|
||||
setSelectedBoxIndex(0);
|
||||
setSelectedRibbonIndex(0);
|
||||
setSelectedColorId(colors[0].id);
|
||||
}, [ colors ]);
|
||||
|
||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case CatalogEvent.PURCHASE_SUCCESS:
|
||||
close();
|
||||
return;
|
||||
case CatalogEvent.INIT_GIFT:
|
||||
const castedEvent = (event as CatalogInitGiftEvent);
|
||||
close();
|
||||
|
||||
setPageId(castedEvent.pageId);
|
||||
setOfferId(castedEvent.offerId);
|
||||
setIsVisible(true);
|
||||
return;
|
||||
case CatalogEvent.GIFT_RECEIVER_NOT_FOUND:
|
||||
setReceiverNotFound(true);
|
||||
return;
|
||||
}
|
||||
}, [ close ]);
|
||||
|
||||
useUiEvent(CatalogEvent.PURCHASE_SUCCESS, onCatalogEvent);
|
||||
useUiEvent(CatalogEvent.INIT_GIFT, onCatalogEvent);
|
||||
useUiEvent(CatalogEvent.GIFT_RECEIVER_NOT_FOUND, onCatalogEvent);
|
||||
|
||||
const isBoxDefault = useMemo(() =>
|
||||
{
|
||||
return giftConfiguration ? giftConfiguration.defaultStuffTypes.findIndex(s => s === giftConfiguration.boxTypes[selectedBoxIndex]) > -1 : true;
|
||||
}, [ giftConfiguration, selectedBoxIndex ]);
|
||||
|
||||
const boxName = useMemo(() =>
|
||||
{
|
||||
return isBoxDefault ? 'catalog.gift_wrapping_new.box.default' : `catalog.gift_wrapping_new.box.${selectedBoxIndex}`;
|
||||
}, [ isBoxDefault, selectedBoxIndex ]);
|
||||
|
||||
const ribbonName = useMemo(() =>
|
||||
{
|
||||
return `catalog.gift_wrapping_new.ribbon.${selectedRibbonIndex}`;
|
||||
}, [ selectedRibbonIndex ]);
|
||||
|
||||
const priceText = useMemo(() =>
|
||||
{
|
||||
return isBoxDefault ? 'catalog.gift_wrapping_new.freeprice' : 'catalog.gift_wrapping_new.price';
|
||||
}, [ isBoxDefault ]);
|
||||
|
||||
const extraData = useMemo(() =>
|
||||
{
|
||||
if(!giftConfiguration) return '';
|
||||
|
||||
return ((giftConfiguration.boxTypes[selectedBoxIndex] * 1000) + giftConfiguration.ribbonTypes[selectedRibbonIndex]).toString();
|
||||
}, [ giftConfiguration, selectedBoxIndex, selectedRibbonIndex ]);
|
||||
|
||||
const isColorable = useMemo(() =>
|
||||
{
|
||||
if(!giftConfiguration) return false;
|
||||
|
||||
const boxType = giftConfiguration.boxTypes[selectedBoxIndex];
|
||||
|
||||
return (boxType === 8 || (boxType >= 3 && boxType <= 6)) ? false : true;
|
||||
}, [ giftConfiguration, selectedBoxIndex ]);
|
||||
|
||||
const handleAction = useCallback((action: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'prev_box':
|
||||
setSelectedBoxIndex(value =>
|
||||
{
|
||||
return (value === 0 ? maxBoxIndex : value - 1);
|
||||
});
|
||||
return;
|
||||
case 'next_box':
|
||||
setSelectedBoxIndex(value =>
|
||||
{
|
||||
return (value === maxBoxIndex ? 0 : value + 1);
|
||||
});
|
||||
return;
|
||||
case 'prev_ribbon':
|
||||
setSelectedRibbonIndex(value =>
|
||||
{
|
||||
return (value === 0 ? maxRibbonIndex : value - 1);
|
||||
});
|
||||
return;
|
||||
case 'next_ribbon':
|
||||
setSelectedRibbonIndex(value =>
|
||||
{
|
||||
return (value === maxRibbonIndex ? 0 : value + 1);
|
||||
});
|
||||
return;
|
||||
case 'buy':
|
||||
if(!receiverName || receiverName.length === 0)
|
||||
{
|
||||
setReceiverNotFound(true);
|
||||
return;
|
||||
}
|
||||
|
||||
SendMessageHook(new PurchaseFromCatalogAsGiftComposer(pageId, offerId, extraData, receiverName, message, selectedColorId, selectedBoxIndex, selectedRibbonIndex, showMyFace));
|
||||
return;
|
||||
}
|
||||
}, [ extraData, maxBoxIndex, maxRibbonIndex, message, offerId, pageId, receiverName, selectedBoxIndex, selectedColorId, selectedRibbonIndex, showMyFace ]);
|
||||
|
||||
if(!giftConfiguration || !giftConfiguration.isEnabled || !isVisible) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView uniqueKey="catalog-gift" className="nitro-catalog-gift" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.gift_wrapping.title') } onCloseClick={ close } />
|
||||
<NitroCardContentView className="text-black">
|
||||
<div className="form-group">
|
||||
<label>{ LocalizeText('catalog.gift_wrapping.receiver') }</label>
|
||||
<input type="text" className={ 'form-control form-control-sm' + classNames({ ' is-invalid': receiverNotFound }) } value={ receiverName } onChange={ (e) => setReceiverName(e.target.value) } />
|
||||
{ receiverNotFound && <div className="invalid-feedback">{ LocalizeText('catalog.gift_wrapping.receiver_not_found.title') }</div> }
|
||||
</div>
|
||||
<div className="mt-2">
|
||||
<NitroLayoutGiftCardView figure={ GetSessionDataManager().figure } userName={ GetSessionDataManager().userName } message={ message } editable={ true } onChange={ (value) => setMessage(value) } />
|
||||
</div>
|
||||
<div className="form-check mt-1">
|
||||
<input className="form-check-input" type="checkbox" name="showMyFace" checked={ showMyFace } onChange={ (e) => setShowMyFace(value => !value) } />
|
||||
<label className="form-check-label">{ LocalizeText('catalog.gift_wrapping.show_face.title') }</label>
|
||||
</div>
|
||||
<div className="d-flex gap-2 mt-1 align-items-center">
|
||||
<div className="gift-preview">
|
||||
{ selectedColorId && <FurniImageView spriteId={ selectedColorId } type="s" extras={ extraData } /> }
|
||||
</div>
|
||||
<div className="d-flex flex-column gap-2">
|
||||
<div className="d-flex gap-2">
|
||||
<div className="btn-group">
|
||||
<button className="btn btn-primary" onClick={ () => handleAction('prev_box') }><i className="fas fa-chevron-left" /></button>
|
||||
<button className="btn btn-primary" onClick={ () => handleAction('next_box') }><i className="fas fa-chevron-right" /></button>
|
||||
</div>
|
||||
<div>
|
||||
<div className="fw-bold">{ LocalizeText(boxName) }</div>
|
||||
<div className="d-flex align-items-center gap-1">{ LocalizeText(priceText, ['price'], [giftConfiguration.price.toString()]) }<CurrencyIcon type={ -1 } /></div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex gap-2 align-items-center">
|
||||
<div className="btn-group">
|
||||
<button className="btn btn-primary" onClick={ () => handleAction('prev_ribbon') }><i className="fas fa-chevron-left" /></button>
|
||||
<button className="btn btn-primary" onClick={ () => handleAction('next_ribbon') }><i className="fas fa-chevron-right" /></button>
|
||||
</div>
|
||||
<div>
|
||||
<div className="fw-bold">{ LocalizeText(ribbonName) }</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-1">
|
||||
<div className="fw-bold">{ LocalizeText('catalog.gift_wrapping.pick_color') }</div>
|
||||
<div className="btn-group w-100">
|
||||
{ colors.map(color =>
|
||||
{
|
||||
return <button key={ color.id } className={ 'btn btn-dark btn-sm' + classNames({ ' active': color.id === selectedColorId }) } disabled={ !isColorable } style={{ backgroundColor: color.color }} onClick={ () => setSelectedColorId(color.id) }></button>
|
||||
}) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="d-flex justify-content-between align-items-center mt-2">
|
||||
<div className="text-decoration-underline cursor-pointer" onClick={ close }>{ LocalizeText('cancel') }</div>
|
||||
<button className="btn btn-success" onClick={ () => handleAction('buy') }>{ LocalizeText('catalog.gift_wrapping.give_gift') }</button>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
@ -6,5 +6,11 @@
|
||||
height: 80px !important;
|
||||
max-height: 80px !important;
|
||||
}
|
||||
|
||||
.hc-banner {
|
||||
width: 68px;
|
||||
height: 40px;
|
||||
background: url(../../../../../../assets/images/catalog/hc_big.png) center no-repeat;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,22 +1,43 @@
|
||||
import { ClubOfferData, GetClubOffersMessageComposer, PurchaseFromCatalogComposer } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { CatalogEvent } from '../../../../../../events/catalog/CatalogEvent';
|
||||
import { useUiEvent } from '../../../../../../hooks';
|
||||
import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
|
||||
import { NitroCardGridItemView } from '../../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||
import { NitroCardGridView } from '../../../../../../layout/card/grid/NitroCardGridView';
|
||||
import { LoadingSpinnerView } from '../../../../../../layout/loading-spinner/LoadingSpinnerView';
|
||||
import { GetCurrencyAmount } from '../../../../../purse/common/CurrencyHelper';
|
||||
import { GLOBAL_PURSE } from '../../../../../purse/PurseView';
|
||||
import { CurrencyIcon } from '../../../../../shared/currency-icon/CurrencyIcon';
|
||||
import { GetCatalogPageImage } from '../../../../common/CatalogUtilities';
|
||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||
import { CatalogPurchaseState } from '../../purchase/purchase-button/CatalogPurchaseButtonView.types';
|
||||
import { CatalogLayoutVipBuyViewProps } from './CatalogLayoutVipBuyView.types';
|
||||
|
||||
export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =>
|
||||
{
|
||||
const { catalogState = null } = useCatalogContext();
|
||||
const { pageParser = null, clubOffers = null, subscriptionInfo = null } = catalogState;
|
||||
|
||||
const [ pendingOffer, setPendingOffer ] = useState<ClubOfferData>(null);
|
||||
const [ purchaseState, setPurchaseState ] = useState(CatalogPurchaseState.NONE);
|
||||
|
||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case CatalogEvent.PURCHASE_SUCCESS:
|
||||
setPurchaseState(CatalogPurchaseState.NONE);
|
||||
return;
|
||||
case CatalogEvent.PURCHASE_FAILED:
|
||||
setPurchaseState(CatalogPurchaseState.FAILED);
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useUiEvent(CatalogEvent.PURCHASE_SUCCESS, onCatalogEvent);
|
||||
useUiEvent(CatalogEvent.PURCHASE_FAILED, onCatalogEvent);
|
||||
|
||||
const getOfferText = useCallback((offer: ClubOfferData) =>
|
||||
{
|
||||
@ -77,130 +98,105 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
||||
{
|
||||
if(!pendingOffer) return;
|
||||
|
||||
setPurchaseState(CatalogPurchaseState.PURCHASE);
|
||||
SendMessageHook(new PurchaseFromCatalogComposer(pageParser.pageId, pendingOffer.offerId, null, 1));
|
||||
}, [ pendingOffer, pageParser ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(clubOffers === null)
|
||||
{
|
||||
SendMessageHook(new GetClubOffersMessageComposer(1));
|
||||
|
||||
return;
|
||||
}
|
||||
if(clubOffers === null) SendMessageHook(new GetClubOffersMessageComposer(1));
|
||||
}, [ clubOffers ]);
|
||||
|
||||
const getPurchaseButton = (offer: ClubOfferData) =>
|
||||
const setOffer = useCallback((offer: ClubOfferData) =>
|
||||
{
|
||||
if(!offer) return null;
|
||||
setPurchaseState(CatalogPurchaseState.NONE);
|
||||
setPendingOffer(offer);
|
||||
}, []);
|
||||
|
||||
if(offer.priceCredits > GetCurrencyAmount(-1))
|
||||
const getPurchaseButton = useCallback(() =>
|
||||
{
|
||||
if(!pendingOffer) return null;
|
||||
|
||||
if(pendingOffer.priceCredits > GetCurrencyAmount(-1))
|
||||
{
|
||||
return <Button variant="danger" size="sm">{ LocalizeText('catalog.alert.notenough.title') }</Button>;
|
||||
return <button className="btn btn-danger btn-sm w-100">{ LocalizeText('catalog.alert.notenough.title') }</button>;
|
||||
}
|
||||
|
||||
if(offer.priceActivityPoints > GetCurrencyAmount(offer.priceActivityPointsType))
|
||||
if(pendingOffer.priceActivityPoints > GetCurrencyAmount(pendingOffer.priceActivityPointsType))
|
||||
{
|
||||
return <Button variant="danger" size="sm">{ LocalizeText('catalog.alert.notenough.activitypoints.title.' + offer.priceActivityPointsType) }</Button>;
|
||||
return <button className="btn btn-danger btn-sm w-100">{ LocalizeText('catalog.alert.notenough.activitypoints.title.' + pendingOffer.priceActivityPointsType) }</button>;
|
||||
}
|
||||
|
||||
return <Button variant="primary" size="sm" onClick={ event => setPendingOffer(offer) }>{ LocalizeText('buy') }</Button>;
|
||||
}
|
||||
|
||||
console.log(pendingOffer)
|
||||
switch(purchaseState)
|
||||
{
|
||||
case CatalogPurchaseState.CONFIRM:
|
||||
return <button type="button" className="btn btn-warning w-100" onClick={ purchaseSubscription }>{ LocalizeText('catalog.marketplace.confirm_title') }</button>;
|
||||
case CatalogPurchaseState.PURCHASE:
|
||||
return <button type="button" className="btn btn-primary w-100" disabled><LoadingSpinnerView /></button>;
|
||||
case CatalogPurchaseState.FAILED:
|
||||
return <button type="button" className="btn btn-danger w-100" disabled>{ LocalizeText('generic.failed') }</button>;
|
||||
case CatalogPurchaseState.NONE:
|
||||
default:
|
||||
return <button type="button" className="btn btn-success w-100" onClick={ () => setPurchaseState(CatalogPurchaseState.CONFIRM) }>{ LocalizeText('buy') }</button>;
|
||||
}
|
||||
}, [ pendingOffer, purchaseState, purchaseSubscription ]);
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="row h-100 nitro-catalog-layout-vip-buy">
|
||||
<div className="col-7 h-100">
|
||||
<div className="col-6 h-100">
|
||||
<NitroCardGridView columns={ 1 } className="vip-buy-grid">
|
||||
{ clubOffers && (clubOffers.length > 0) && clubOffers.map((offer, index) =>
|
||||
{
|
||||
return (
|
||||
<NitroCardGridItemView key={ index } className="justify-content-between p-1">
|
||||
{ (pendingOffer === offer) &&
|
||||
<>
|
||||
<div className="d-flex flex-column text-black text-small m-1">
|
||||
<div className="d-flex align-items-center">
|
||||
<i className="icon icon-catalogue-hc_small me-1"></i>
|
||||
{ getPurchaseHeader() }
|
||||
</div>
|
||||
<div className="text-black text-small">{ getPurchaseValidUntil() }</div>
|
||||
<div className="d-flex">
|
||||
{ (offer.priceCredits > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black">{ offer.priceCredits }</span>
|
||||
<CurrencyIcon type={ -1 } />
|
||||
</div> }
|
||||
{ (offer.priceActivityPoints > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black">{ offer.priceActivityPoints }</span>
|
||||
<CurrencyIcon type={ offer.priceActivityPointsType } />
|
||||
</div> }
|
||||
</div>
|
||||
<NitroCardGridItemView key={ index } className="justify-content-between py-1 px-2 text-black" itemActive={ pendingOffer === offer } onClick={ () => setOffer(offer) }>
|
||||
<div className="hc-banner"></div>
|
||||
<div className="fw-bold">
|
||||
<div className="text-end">{ getOfferText(offer) }</div>
|
||||
<div className="d-flex gap-2 justify-content-end">
|
||||
{ (offer.priceCredits > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end gap-1">
|
||||
<span className="text-black">{ offer.priceCredits }</span>
|
||||
<CurrencyIcon type={ -1 } />
|
||||
</div> }
|
||||
{ (offer.priceActivityPoints > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end gap-1">
|
||||
<span className="text-black">{ offer.priceActivityPoints }</span>
|
||||
<CurrencyIcon type={ offer.priceActivityPointsType } />
|
||||
</div> }
|
||||
</div>
|
||||
<Button variant="primary" size="sm" onClick={ purchaseSubscription }>{ LocalizeText('catalog.marketplace.confirm_title') }</Button>
|
||||
</> }
|
||||
{ (pendingOffer !== offer) &&
|
||||
<>
|
||||
<div className="d-flex flex-column text-black text-small m-1">
|
||||
<div className="d-flex align-items-center">
|
||||
<i className="icon icon-catalogue-hc_small me-1"></i>
|
||||
{ getOfferText(offer) }
|
||||
</div>
|
||||
<div className="d-flex">
|
||||
{ (offer.priceCredits > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black">{ offer.priceCredits }</span>
|
||||
<CurrencyIcon type={ -1 } />
|
||||
</div> }
|
||||
{ (offer.priceActivityPoints > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black">{ offer.priceActivityPoints }</span>
|
||||
<CurrencyIcon type={ offer.priceActivityPointsType } />
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
{ getPurchaseButton(offer) }
|
||||
</> }
|
||||
</div>
|
||||
</NitroCardGridItemView>
|
||||
);
|
||||
}) }
|
||||
</NitroCardGridView>
|
||||
{/* <div className="row row-cols-1 align-content-start g-0 mb-n1 w-100 catalog-offers-container h-100 overflow-auto">
|
||||
{ clubOffers && (clubOffers.length > 0) && clubOffers.map((offer, index) =>
|
||||
{
|
||||
return (
|
||||
<div key={ index } className="col pe-1 pb-1 catalog-offer-item-container">
|
||||
<div className="position-relative border border-2 rounded catalog-offer-item">
|
||||
<div className="d-flex align-items-center text-black text-small m-1">
|
||||
<i className="icon icon-catalogue-hc_small me-1"></i>
|
||||
{ getOfferText(offer) }
|
||||
</div>
|
||||
<div className="d-flex">
|
||||
{ (offer.priceCredits > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black ms-1">{ offer.priceCredits }</span>
|
||||
<CurrencyIcon type={ -1 } />
|
||||
</div> }
|
||||
{ (offer.priceActivityPoints > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end">
|
||||
<span className="text-black ms-1">{ offer.priceActivityPoints }</span>
|
||||
<CurrencyIcon type={ offer.priceActivityPointsType } />
|
||||
</div> }
|
||||
</div>
|
||||
<Button variant="primary" size="sm" onClick={ event => setPendingOffer(offer) } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}) }
|
||||
</div> */}
|
||||
</div>
|
||||
<div className="position-relative d-flex flex-column col-5 justify-content-center align-items-center">
|
||||
<div className="position-relative d-flex flex-column col-6 justify-content-center align-items-center">
|
||||
<div className="d-block mb-2">
|
||||
<img alt="" src={ GetCatalogPageImage(pageParser, 1) } />
|
||||
</div>
|
||||
<div className="fs-6 text-center text-black lh-sm overflow-hidden" dangerouslySetInnerHTML={ { __html: getSubscriptionDetails } }></div>
|
||||
<div className="text-center text-black small bg-muted rounded p-1" dangerouslySetInnerHTML={ { __html: getSubscriptionDetails } }></div>
|
||||
{ pendingOffer && <div className="mt-auto w-100 text-black">
|
||||
<div className="d-flex gap-2 mb-2 align-items-center">
|
||||
<div className="w-100">
|
||||
<div className="fw-bold">{ getPurchaseHeader() }</div>
|
||||
<div className="small">{ getPurchaseValidUntil() }</div>
|
||||
</div>
|
||||
<div>
|
||||
{ (pendingOffer.priceCredits > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end gap-1">
|
||||
<span className="text-black">{ pendingOffer.priceCredits }</span>
|
||||
<CurrencyIcon type={ -1 } />
|
||||
</div> }
|
||||
{ (pendingOffer.priceActivityPoints > 0) &&
|
||||
<div className="d-flex align-items-center justify-content-end gap-1">
|
||||
<span className="text-black">{ pendingOffer.priceActivityPoints }</span>
|
||||
<CurrencyIcon type={ pendingOffer.priceActivityPointsType } />
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
{ getPurchaseButton() }
|
||||
</div>}
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
|
@ -71,7 +71,7 @@ export const CatalogPurchaseView: FC<CatalogPurchaseViewProps> = props =>
|
||||
</div>
|
||||
<div className="d-flex flex-column mt-1">
|
||||
<CatalogPurchaseButtonView className="btn-sm w-100" offer={ offer } pageId={ pageId } extra={ extraData } quantity={ quantity } disabled={ disabled } />
|
||||
{ offer.giftable && <CatalogPurchaseGiftButtonView className="btn-sm w-100 mt-1" offer={ offer } pageId={ pageId } extra={ extraData } quantity={ quantity } /> }
|
||||
{ offer.giftable && <CatalogPurchaseGiftButtonView className="btn-sm w-100 mt-1" offer={ offer } pageId={ pageId } extra={ extraData } disabled={ disabled } /> }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -36,7 +36,6 @@ export const CatalogPurchaseButtonView: FC<CatalogPurchaseButtonViewProps> = pro
|
||||
|
||||
const purchase = useCallback(() =>
|
||||
{
|
||||
console.log(pageId, offer.offerId, extra, quantity);
|
||||
SendMessageHook(new PurchaseFromCatalogComposer(pageId, offer.offerId, extra, quantity));
|
||||
}, [ pageId, offer, extra, quantity ]);
|
||||
|
||||
|
@ -1,12 +1,19 @@
|
||||
import { FC } from 'react';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { LocalizeText } from '../../../../../../api';
|
||||
import { CatalogInitGiftEvent } from '../../../../../../events/catalog/CatalogInitGiftEvent';
|
||||
import { dispatchUiEvent } from '../../../../../../hooks';
|
||||
import { CatalogPurchaseGiftButtonViewProps } from './CatalogPurchaseGiftButtonView.types';
|
||||
|
||||
export const CatalogPurchaseGiftButtonView: FC<CatalogPurchaseGiftButtonViewProps> = props =>
|
||||
{
|
||||
const { className = '', offer = null, pageId = -1, extra = null, quantity = 1, isPurchaseAllowed = true, beforePurchase = null } = props;
|
||||
const { className = '', offer = null, pageId = -1, extra = null, disabled = false } = props;
|
||||
|
||||
const initGift = useCallback(() =>
|
||||
{
|
||||
dispatchUiEvent(new CatalogInitGiftEvent(pageId, offer.offerId, extra));
|
||||
}, [ extra, offer, pageId ]);
|
||||
|
||||
return (
|
||||
<button type="button" className={ 'btn btn-secondary ' + className }>{ LocalizeText('catalog.purchase_confirmation.gift') }</button>
|
||||
<button type="button" className={ 'btn btn-secondary ' + className } onClick={ initGift } disabled={ disabled }>{ LocalizeText('catalog.purchase_confirmation.gift') }</button>
|
||||
);
|
||||
}
|
||||
|
@ -6,7 +6,5 @@ export interface CatalogPurchaseGiftButtonViewProps
|
||||
offer: CatalogPageMessageOfferData;
|
||||
pageId: number;
|
||||
extra?: string;
|
||||
quantity?: number;
|
||||
isPurchaseAllowed?: boolean;
|
||||
beforePurchase?: () => void;
|
||||
disabled?: boolean;
|
||||
}
|
||||
|
@ -1,5 +0,0 @@
|
||||
.nitro-friend-list {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
@import './views//friend-bar/FriendBarView';
|
@ -1,17 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { FriendListFriendsItemView } from '../friends-item/FriendListFriendsItemView';
|
||||
import { FriendListFriendsViewProps } from './FriendListFriendsView.types';
|
||||
|
||||
export const FriendListFriendsView: FC<FriendListFriendsViewProps> = props =>
|
||||
{
|
||||
const { list = null } = props;
|
||||
|
||||
if(!list) return null;
|
||||
|
||||
return (<>
|
||||
{ list.map((friend, index) =>
|
||||
{
|
||||
return <FriendListFriendsItemView key={ index } friend={ friend } />
|
||||
}) }
|
||||
</>);
|
||||
}
|
@ -1,5 +0,0 @@
|
||||
import { MessengerFriend } from './../../common/MessengerFriend';
|
||||
export interface FriendListFriendsViewProps
|
||||
{
|
||||
list: MessengerFriend[];
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { MessengerRequest } from './../../common/MessengerRequest';
|
||||
|
||||
export interface FriendListRequestsItemViewProps
|
||||
{
|
||||
request: MessengerRequest;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { FriendListRequestsItemView } from '../requests-item/FriendListRequestsItemView';
|
||||
import { FriendListRequestsViewProps } from './FriendListRequestsView.types';
|
||||
|
||||
export const FriendListRequestsView: FC<FriendListRequestsViewProps> = props =>
|
||||
{
|
||||
const { list = null } = props;
|
||||
|
||||
if(!list) return null;
|
||||
|
||||
return (<>
|
||||
{ list.map((request, index) =>
|
||||
{
|
||||
return <FriendListRequestsItemView key={ index } request={ request } />
|
||||
}) }
|
||||
</>);
|
||||
};
|
@ -1,6 +0,0 @@
|
||||
import { MessengerRequest } from './../../common/MessengerRequest';
|
||||
|
||||
export interface FriendListRequestsViewProps
|
||||
{
|
||||
list: MessengerRequest[];
|
||||
}
|
5
src/views/friends/FriendsView.scss
Normal file
5
src/views/friends/FriendsView.scss
Normal file
@ -0,0 +1,5 @@
|
||||
.nitro-friend-list {
|
||||
width: 250px;
|
||||
}
|
||||
|
||||
@import './views/friend-bar/FriendBarView';
|
@ -11,15 +11,13 @@ import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||
import { NitroCardAccordionItemView, NitroCardAccordionView, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout';
|
||||
import { FriendListContextProvider } from './context/FriendListContext';
|
||||
import { FriendListMessageHandler } from './FriendListMessageHandler';
|
||||
import { FriendListViewProps } from './FriendListView.types';
|
||||
import { FriendListReducer, initialFriendList } from './reducers/FriendListReducer';
|
||||
import { FriendBarView } from './views/friend-bar/FriendBarView';
|
||||
import { FriendListFriendsView } from './views/friends/FriendListFriendsView';
|
||||
import { FriendListRequestsView } from './views/requests/FriendListRequestsView';
|
||||
import { FriendsListView } from './views/list/FriendsListView';
|
||||
|
||||
const TABS: string[] = ['friendlist.friends', 'generic.search'];
|
||||
|
||||
export const FriendListView: FC<FriendListViewProps> = props =>
|
||||
export const FriendsView: FC<{}> = props =>
|
||||
{
|
||||
const [ friendListState, dispatchFriendListState ] = useReducer(FriendListReducer, initialFriendList);
|
||||
const { friends = null, requests = null, settings = null } = friendListState;
|
||||
@ -120,14 +118,14 @@ export const FriendListView: FC<FriendListViewProps> = props =>
|
||||
</NitroCardTabsView>
|
||||
<div className="text-black">
|
||||
{ currentTab === 0 && <NitroCardAccordionView>
|
||||
<NitroCardAccordionItemView headerText={ LocalizeText('friendlist.friends') + ` (${onlineFriends.length})` }>
|
||||
<FriendListFriendsView list={ onlineFriends } />
|
||||
<NitroCardAccordionItemView headerText={ LocalizeText('friendlist.friends') + ` (${onlineFriends.length})` } defaultState={ true }>
|
||||
<FriendsListView list={ onlineFriends } />
|
||||
</NitroCardAccordionItemView>
|
||||
<NitroCardAccordionItemView headerText={ LocalizeText('friendlist.friends.offlinecaption') + ` (${offlineFriends.length})` }>
|
||||
<FriendListFriendsView list={ offlineFriends } />
|
||||
<FriendsListView list={ offlineFriends } />
|
||||
</NitroCardAccordionItemView>
|
||||
{ requests.length > 0 && <NitroCardAccordionItemView headerText={ LocalizeText('friendlist.tab.friendrequests') + ` (${requests.length})` }>
|
||||
<FriendListRequestsView list={ requests } />
|
||||
<FriendsListView list={ requests } />
|
||||
</NitroCardAccordionItemView> }
|
||||
</NitroCardAccordionView> }
|
||||
</div>
|
@ -1,6 +1,3 @@
|
||||
export interface FriendListViewProps
|
||||
{}
|
||||
|
||||
export class FriendListTabs
|
||||
{
|
||||
public static readonly FRIENDS: string = 'friendlist.friends';
|
@ -4,9 +4,9 @@ import { LocalizeText } from '../../../../api';
|
||||
import { SendMessageHook } from '../../../../hooks';
|
||||
import { UserProfileIconView } from '../../../shared/user-profile-icon/UserProfileIconView';
|
||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||
import { FriendListFriendsItemViewProps } from './FriendListFriendsItemView.types';
|
||||
import { FriendsListItemViewProps } from './FriendsListItemView.types';
|
||||
|
||||
export const FriendListFriendsItemView: FC<FriendListFriendsItemViewProps> = props =>
|
||||
export const FriendsListItemView: FC<FriendsListItemViewProps> = props =>
|
||||
{
|
||||
const { friend = null } = props;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||
|
||||
export interface FriendListFriendsItemViewProps
|
||||
export interface FriendsListItemViewProps
|
||||
{
|
||||
friend: MessengerFriend;
|
||||
}
|
25
src/views/friends/views/list/FriendsListView.tsx
Normal file
25
src/views/friends/views/list/FriendsListView.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import React, { FC } from 'react';
|
||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||
import { MessengerRequest } from '../../common/MessengerRequest';
|
||||
import { FriendsListItemView } from '../friend-item/FriendsListItemView';
|
||||
import { FriendsRequestItemView } from '../request-item/FriendsRequestItemView';
|
||||
import { FriendsListViewProps } from './FriendsListView.types';
|
||||
|
||||
export const FriendsListView: FC<FriendsListViewProps> = props =>
|
||||
{
|
||||
const { list = null } = props;
|
||||
|
||||
if(!list) return null;
|
||||
|
||||
return (<>
|
||||
{ list.map((item, index) =>
|
||||
{
|
||||
if(item instanceof MessengerFriend)
|
||||
return <FriendsListItemView key={ index } friend={ item } />
|
||||
else if(item instanceof MessengerRequest)
|
||||
return <FriendsRequestItemView key={ index } request={ item } />
|
||||
else
|
||||
return null;
|
||||
}) }
|
||||
</>);
|
||||
}
|
7
src/views/friends/views/list/FriendsListView.types.ts
Normal file
7
src/views/friends/views/list/FriendsListView.types.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { MessengerFriend } from '../../common/MessengerFriend';
|
||||
import { MessengerRequest } from '../../common/MessengerRequest';
|
||||
|
||||
export interface FriendsListViewProps
|
||||
{
|
||||
list: MessengerFriend[] | MessengerRequest[];
|
||||
}
|
@ -2,9 +2,9 @@ import { AcceptFriendMessageComposer, DeclineFriendMessageComposer } from '@nitr
|
||||
import { FC, useCallback } from 'react';
|
||||
import { SendMessageHook } from '../../../../hooks/messages/message-event';
|
||||
import { UserProfileIconView } from '../../../shared/user-profile-icon/UserProfileIconView';
|
||||
import { FriendListRequestsItemViewProps } from './FriendListRequestsItemView.types';
|
||||
import { FriendsRequestItemViewProps } from './FriendsRequestItemView.types';
|
||||
|
||||
export const FriendListRequestsItemView: FC<FriendListRequestsItemViewProps> = props =>
|
||||
export const FriendsRequestItemView: FC<FriendsRequestItemViewProps> = props =>
|
||||
{
|
||||
const { request = null } = props;
|
||||
|
@ -0,0 +1,6 @@
|
||||
import { MessengerRequest } from '../../common/MessengerRequest';
|
||||
|
||||
export interface FriendsRequestItemViewProps
|
||||
{
|
||||
request: MessengerRequest;
|
||||
}
|
@ -115,7 +115,7 @@ export const GroupMembersView: FC<GroupMembersViewProps> = props =>
|
||||
}
|
||||
|
||||
searchMembers(pageData.pageIndex);
|
||||
}, [ pageData ]);
|
||||
}, [ pageData, searchMembers ]);
|
||||
|
||||
const acceptMembership = useCallback((member) =>
|
||||
{
|
||||
@ -124,7 +124,7 @@ export const GroupMembersView: FC<GroupMembersViewProps> = props =>
|
||||
SendMessageHook(new GroupMembershipAcceptComposer(pageData.groupId, member.id));
|
||||
searchMembers(pageData.pageIndex);
|
||||
}
|
||||
}, [ pageData ]);
|
||||
}, [ pageData, searchMembers ]);
|
||||
|
||||
const removeMemberOrDeclineMembership = useCallback((member) =>
|
||||
{
|
||||
@ -138,66 +138,68 @@ export const GroupMembersView: FC<GroupMembersViewProps> = props =>
|
||||
setRemovingMemberName(member.name);
|
||||
SendMessageHook(new GroupConfirmRemoveMemberComposer(pageData.groupId, member.id));
|
||||
}
|
||||
}, [ pageData ]);
|
||||
}, [ pageData, searchMembers ]);
|
||||
|
||||
if(!pageData) return null;
|
||||
if(!groupId) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-group-members" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('group.members.title', ['groupName'], [ pageData.groupTitle ]) } onCloseClick={ onClose } />
|
||||
<NitroCardContentView className="pb-2">
|
||||
<div className="d-flex gap-2 align-items-center mb-2">
|
||||
<div className="group-badge">
|
||||
<BadgeImageView badgeCode={ pageData.badge } isGroup={ true } />
|
||||
<NitroCardHeaderView headerText={ LocalizeText('group.members.title', ['groupName'], [ pageData ? pageData.groupTitle : '' ]) } onCloseClick={ onClose } />
|
||||
{ pageData && <>
|
||||
<NitroCardContentView className="pb-2">
|
||||
<div className="d-flex gap-2 align-items-center mb-2">
|
||||
<div className="group-badge">
|
||||
<BadgeImageView badgeCode={ pageData.badge } isGroup={ true } />
|
||||
</div>
|
||||
<div className="w-100">
|
||||
<input type="text" className="form-control form-control-sm w-100 mb-1" placeholder={ LocalizeText('group.members.searchinfo') } value={ searchQuery } onChange={ (e) => setSearchQuery(e.target.value) } onBlur={ () => searchMembers(pageData.pageIndex) } onKeyDown={ onKeyDown } />
|
||||
<select className="form-select form-select-sm w-100" value={ searchLevelId } onChange={ (e) => selectSearchLevelId(Number(e.target.value)) }>
|
||||
<option value="0">{ LocalizeText('group.members.search.all') }</option>
|
||||
<option value="1">{ LocalizeText('group.members.search.admins') }</option>
|
||||
<option value="2">{ LocalizeText('group.members.search.pending') }</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="w-100">
|
||||
<input type="text" className="form-control form-control-sm w-100 mb-1" placeholder={ LocalizeText('group.members.searchinfo') } value={ searchQuery } onChange={ (e) => setSearchQuery(e.target.value) } onBlur={ () => searchMembers(pageData.pageIndex) } onKeyDown={ onKeyDown } />
|
||||
<select className="form-select form-select-sm w-100" value={ searchLevelId } onChange={ (e) => selectSearchLevelId(Number(e.target.value)) }>
|
||||
<option value="0">{ LocalizeText('group.members.search.all') }</option>
|
||||
<option value="1">{ LocalizeText('group.members.search.admins') }</option>
|
||||
<option value="2">{ LocalizeText('group.members.search.pending') }</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="row row-cols-2 align-content-start g-0 w-100 members-list overflow-auto">
|
||||
{ pageData.result.map((member, index) =>
|
||||
{
|
||||
return (
|
||||
<div key={ index } className={ 'col pb-1' + classNames({ ' pe-1': index % 2 === 0 }) }>
|
||||
<div className="list-member bg-white rounded d-flex text-black">
|
||||
<div className="avatar-head flex-shrink-0 cursor-pointer" onClick={ () => { GetUserProfile(member.id) } }>
|
||||
<AvatarImageView figure={ member.figure } headOnly={ true } direction={ 2 } />
|
||||
</div>
|
||||
<div className="p-1 w-100 d-flex flex-column justify-content-center">
|
||||
<div className="fw-bold small cursor-pointer" onClick={ () => { GetUserProfile(member.id) } }>{ member.name }</div>
|
||||
{ member.rank !== GroupRank.REQUESTED && <div className="text-muted fst-italic small">{ LocalizeText('group.members.since', ['date'], [member.joinedAt]) }</div> }
|
||||
</div>
|
||||
<div className="d-flex flex-column pe-2 align-items-center justify-content-center">
|
||||
<div className="d-flex align-items-center">
|
||||
<i className={ 'icon icon-group-small-' + classNames({ 'owner': member.rank === GroupRank.OWNER, 'admin': member.rank === GroupRank.ADMIN, 'not-admin': member.rank === GroupRank.MEMBER, 'cursor-pointer': pageData.admin }) } title={ LocalizeText(getRankDescription(member)) } onClick={ () => toggleAdmin(member) } />
|
||||
<div className="row row-cols-2 align-content-start g-0 w-100 members-list overflow-auto">
|
||||
{ pageData.result.map((member, index) =>
|
||||
{
|
||||
return (
|
||||
<div key={ index } className={ 'col pb-1' + classNames({ ' pe-1': index % 2 === 0 }) }>
|
||||
<div className="list-member bg-white rounded d-flex text-black">
|
||||
<div className="avatar-head flex-shrink-0 cursor-pointer" onClick={ () => { GetUserProfile(member.id) } }>
|
||||
<AvatarImageView figure={ member.figure } headOnly={ true } direction={ 2 } />
|
||||
</div>
|
||||
<div className="p-1 w-100 d-flex flex-column justify-content-center">
|
||||
<div className="fw-bold small cursor-pointer" onClick={ () => { GetUserProfile(member.id) } }>{ member.name }</div>
|
||||
{ member.rank !== GroupRank.REQUESTED && <div className="text-muted fst-italic small">{ LocalizeText('group.members.since', ['date'], [member.joinedAt]) }</div> }
|
||||
</div>
|
||||
<div className="d-flex flex-column pe-2 align-items-center justify-content-center">
|
||||
<div className="d-flex align-items-center">
|
||||
<i className={ 'icon icon-group-small-' + classNames({ 'owner': member.rank === GroupRank.OWNER, 'admin': member.rank === GroupRank.ADMIN, 'not-admin': member.rank === GroupRank.MEMBER, 'cursor-pointer': pageData.admin }) } title={ LocalizeText(getRankDescription(member)) } onClick={ () => toggleAdmin(member) } />
|
||||
</div>
|
||||
{ member.rank === GroupRank.REQUESTED && <div className="d-flex align-items-center">
|
||||
<i className="icon cursor-pointer icon-accept" title={ LocalizeText('group.members.accept') } onClick={ () => acceptMembership(member) } />
|
||||
</div> }
|
||||
{ member.rank !== GroupRank.OWNER && pageData.admin && member.id !== GetSessionDataManager().userId &&<div className="d-flex align-items-center mt-1">
|
||||
<i className="icon cursor-pointer icon-deny" title={ LocalizeText(member.rank === GroupRank.REQUESTED ? 'group.members.reject' : 'group.members.kick') } onClick={ () => removeMemberOrDeclineMembership(member) } />
|
||||
</div> }
|
||||
</div>
|
||||
{ member.rank === GroupRank.REQUESTED && <div className="d-flex align-items-center">
|
||||
<i className="icon cursor-pointer icon-accept" title={ LocalizeText('group.members.accept') } onClick={ () => acceptMembership(member) } />
|
||||
</div> }
|
||||
{ member.rank !== GroupRank.OWNER && pageData.admin && member.id !== GetSessionDataManager().userId &&<div className="d-flex align-items-center mt-1">
|
||||
<i className="icon cursor-pointer icon-deny" title={ LocalizeText(member.rank === GroupRank.REQUESTED ? 'group.members.reject' : 'group.members.kick') } onClick={ () => removeMemberOrDeclineMembership(member) } />
|
||||
</div> }
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
<div className="d-flex w-100 align-items-center">
|
||||
<div>
|
||||
<button disabled={ pageData.pageIndex === 0 } className="btn btn-primary" onClick={ previousPage }><i className="fas fa-chevron-left" /></button>
|
||||
);
|
||||
}) }
|
||||
</div>
|
||||
<div className="text-center text-black w-100">{ LocalizeText('group.members.pageinfo', ['amount', 'page', 'totalPages'], [pageData.totalMembersCount.toString(), (pageData.pageIndex + 1).toString(), totalPages.toString()]) }</div>
|
||||
<div>
|
||||
<button disabled={ pageData.pageIndex === totalPages - 1 } className="btn btn-primary" onClick={ nextPage }><i className="fas fa-chevron-right" /></button>
|
||||
<div className="d-flex w-100 align-items-center">
|
||||
<div>
|
||||
<button disabled={ pageData.pageIndex === 0 } className="btn btn-primary" onClick={ previousPage }><i className="fas fa-chevron-left" /></button>
|
||||
</div>
|
||||
<div className="text-center text-black w-100">{ LocalizeText('group.members.pageinfo', ['amount', 'page', 'totalPages'], [pageData.totalMembersCount.toString(), (pageData.pageIndex + 1).toString(), totalPages.toString()]) }</div>
|
||||
<div>
|
||||
<button disabled={ pageData.pageIndex === totalPages - 1 } className="btn btn-primary" onClick={ nextPage }><i className="fas fa-chevron-right" /></button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</NitroCardContentView>
|
||||
</NitroCardContentView>
|
||||
</> }
|
||||
</NitroCardView>
|
||||
);
|
||||
};
|
||||
|
@ -12,13 +12,13 @@ export const GroupRoomInformationView: FC<{}> = props =>
|
||||
const [ groupId, setGroupId ] = useState<number>(null);
|
||||
const [ groupInformation, setGroupInformation ] = useState<GroupInformationParser>(null);
|
||||
const [ isExpended, setIsExpended ] = useState<boolean>(true);
|
||||
|
||||
|
||||
const onRoomInfoEvent = useCallback((event: RoomInfoEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
setGroupInformation(null);
|
||||
|
||||
|
||||
if(parser.data.habboGroupId)
|
||||
{
|
||||
setGroupId(parser.data.habboGroupId);
|
||||
@ -33,7 +33,7 @@ export const GroupRoomInformationView: FC<{}> = props =>
|
||||
const parser = event.getParser();
|
||||
|
||||
if(parser.flag || groupId !== parser.id) return;
|
||||
|
||||
console.log(parser);
|
||||
setGroupInformation(null);
|
||||
setGroupInformation(parser);
|
||||
}, [ groupId ]);
|
||||
@ -110,7 +110,7 @@ export const GroupRoomInformationView: FC<{}> = props =>
|
||||
<i className={ 'fas fa-chevron-' + (isExpended ? 'up' : 'down') } />
|
||||
</div>
|
||||
{ isExpended && <>
|
||||
<div className="d-flex cursor-pointer" onClick={ () => GetGroupInformation(groupInformation.id) }>
|
||||
<div className="d-flex cursor-pointer" onClick={ () => GetGroupInformation(groupId) }>
|
||||
<div className="group-badge flex-shrink-0 me-1">
|
||||
<BadgeImageView badgeCode={ groupInformation.badge } isGroup={ true } />
|
||||
</div>
|
||||
|
@ -2,11 +2,12 @@ import { RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetCommunication } from '../../api';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { TransitionAnimation, TransitionAnimationTypes } from '../../layout';
|
||||
import { AchievementsView } from '../achievements/AchievementsView';
|
||||
import { AvatarEditorView } from '../avatar-editor/AvatarEditorView';
|
||||
import { CameraWidgetView } from '../camera/CameraWidgetView';
|
||||
import { CatalogView } from '../catalog/CatalogView';
|
||||
import { FriendListView } from '../friend-list/FriendListView';
|
||||
import { FriendsView } from '../friends/FriendsView';
|
||||
import { GroupsView } from '../groups/GroupsView';
|
||||
import { HotelView } from '../hotel-view/HotelView';
|
||||
import { InventoryView } from '../inventory/InventoryView';
|
||||
@ -50,7 +51,9 @@ export const MainView: FC<MainViewProps> = props =>
|
||||
|
||||
return (
|
||||
<div className="nitro-main">
|
||||
{ landingViewVisible && <HotelView /> }
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ landingViewVisible } timeout={ 300 }>
|
||||
<HotelView />
|
||||
</TransitionAnimation>
|
||||
<ToolbarView isInRoom={ !landingViewVisible } />
|
||||
<ModToolsView />
|
||||
<RoomHostView />
|
||||
@ -60,7 +63,7 @@ export const MainView: FC<MainViewProps> = props =>
|
||||
<NavigatorView />
|
||||
<InventoryView />
|
||||
<CatalogView />
|
||||
<FriendListView />
|
||||
<FriendsView />
|
||||
<RightSideView />
|
||||
<UserSettingsView />
|
||||
<UserProfileView />
|
||||
|
@ -3,6 +3,7 @@ import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomSession, SetActiveRoomId, StartRoomSession } from '../../api';
|
||||
import { useRoomEngineEvent } from '../../hooks/events/nitro/room/room-engine-event';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { TransitionAnimation, TransitionAnimationTypes } from '../../layout';
|
||||
import { RoomView } from '../room/RoomView';
|
||||
|
||||
export const RoomHostView: FC<{}> = props =>
|
||||
@ -49,8 +50,10 @@ export const RoomHostView: FC<{}> = props =>
|
||||
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
||||
|
||||
return (
|
||||
<div className="nitro-room-host w-100 h-100">
|
||||
<RoomView roomSession={ roomSession } />
|
||||
</div>
|
||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ !!roomSession } timeout={ 300 }>
|
||||
<div className="nitro-room-host w-100 h-100">
|
||||
<RoomView roomSession={ roomSession } />
|
||||
</div>
|
||||
</TransitionAnimation>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { ColorConverter, NitroAdjustmentFilter, NitroContainer, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineEvent, RoomId, RoomObjectHSLColorEnabledEvent } from '@nitrots/nitro-renderer';
|
||||
import { ColorConverter, NitroAdjustmentFilter, NitroContainer, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineDimmerStateEvent, RoomEngineEvent, RoomId, RoomObjectHSLColorEnabledEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetNitroInstance, GetRoomEngine, RoomWidgetUpdateBackgroundColorPreviewEvent, RoomWidgetUpdateRoomViewEvent } from '../../api';
|
||||
import { UseMountEffect } from '../../hooks';
|
||||
@ -11,8 +11,7 @@ export const RoomColorView: FC<{}> = props =>
|
||||
const [ roomBackgroundColor, setRoomBackgroundColor ] = useState(0);
|
||||
const [ originalRoomBackgroundColor, setOriginalRoomBackgroundColor ] = useState(0);
|
||||
const [ roomFilter, setRoomFilter ] = useState<NitroAdjustmentFilter>(null);
|
||||
const [ roomFilterColor, setRoomFilterColor ] = useState(-1);
|
||||
const { roomSession = null, canvasId = -1, eventDispatcher = null } = useRoomContext();
|
||||
const { roomSession = null, canvasId = -1, widgetHandler = null, eventDispatcher = null } = useRoomContext();
|
||||
|
||||
const getRenderingCanvas = useCallback(() =>
|
||||
{
|
||||
@ -113,7 +112,6 @@ export const RoomColorView: FC<{}> = props =>
|
||||
{
|
||||
const newColor = ColorConverter.hslToRGB(((ColorConverter.rgbToHSL(color) & 0xFFFF00) + brightness));
|
||||
|
||||
setRoomFilterColor(newColor);
|
||||
updateRoomFilter(newColor);
|
||||
}, [ updateRoomFilter ]);
|
||||
|
||||
@ -139,11 +137,15 @@ export const RoomColorView: FC<{}> = props =>
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomEngineDimmerStateEvent.ROOM_COLOR: {
|
||||
widgetHandler.processEvent(event);
|
||||
}
|
||||
}
|
||||
}, [ updateRoomBackgroundColor, updateRoomFilterColor ]);
|
||||
}, [ widgetHandler, updateRoomBackgroundColor, updateRoomFilterColor ]);
|
||||
|
||||
useRoomEngineEvent(RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR, onRoomEngineEvent);
|
||||
useRoomEngineEvent(RoomBackgroundColorEvent.ROOM_COLOR, onRoomEngineEvent);
|
||||
useRoomEngineEvent(RoomEngineDimmerStateEvent.ROOM_COLOR, onRoomEngineEvent);
|
||||
|
||||
const onRoomWidgetUpdateRoomViewEvent = useCallback((event: RoomWidgetUpdateRoomViewEvent) =>
|
||||
{
|
||||
|
@ -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, FurnitureCustomStackHeightWidgetHandler, FurnitureExternalImageWidgetHandler, GetNitroInstance, GetRoomEngine, InitializeRoomInstanceRenderingCanvas, IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler, RoomWidgetRoomToolsHandler, RoomWidgetUpdateRoomViewEvent, UserChooserWidgetHandler } from '../../api';
|
||||
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 { RoomContextProvider } from './context/RoomContext';
|
||||
import { RoomColorView } from './RoomColorView';
|
||||
import { RoomViewProps } from './RoomView.types';
|
||||
@ -34,13 +34,17 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetRoomToolsHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureCustomStackHeightWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureExternalImageWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurniChooserWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new UserChooserWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new DoorbellWidgetHandler());
|
||||
|
||||
widgetHandlerManager.registerHandler(new FurniChooserWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureContextMenuWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureCreditWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureCustomStackHeightWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureExternalImageWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurniturePresentWidgetHandler());
|
||||
widgetHandlerManager.registerHandler(new FurnitureDimmerWidgetHandler());
|
||||
|
||||
setWidgetHandler(widgetHandlerManager);
|
||||
|
||||
GetNitroInstance().renderer.resize(window.innerWidth, window.innerHeight);
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { RoomEngineDimmerStateEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomZoomEvent } from '@nitrots/nitro-renderer';
|
||||
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, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from '../../../api';
|
||||
import { CanManipulateFurniture, GetRoomEngine, GetSessionDataManager, IsFurnitureSelectionDisabled, LocalizeText, ProcessRoomObjectOperation, RoomWidgetFurniToWidgetMessage, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from '../../../api';
|
||||
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
|
||||
import { useRoomContext } from '../context/RoomContext';
|
||||
import { AvatarInfoWidgetView } from './avatar-info/AvatarInfoWidgetView';
|
||||
@ -41,16 +41,22 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomEngineDimmerStateEvent.ROOM_COLOR: {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, [ eventDispatcher ]);
|
||||
|
||||
useRoomEngineEvent(RoomEngineEvent.NORMAL_MODE, onRoomEngineEvent);
|
||||
useRoomEngineEvent(RoomEngineEvent.GAME_MODE, onRoomEngineEvent);
|
||||
useRoomEngineEvent(RoomZoomEvent.ROOM_ZOOM, onRoomEngineEvent);
|
||||
useRoomEngineEvent(RoomEngineDimmerStateEvent.ROOM_COLOR, onRoomEngineEvent);
|
||||
|
||||
const handleRoomAdClick = useCallback((event: RoomEngineRoomAdEvent) =>
|
||||
{
|
||||
|
||||
}, []);
|
||||
|
||||
const handleRoomAdTooltip = useCallback((event: RoomEngineRoomAdEvent) =>
|
||||
{
|
||||
|
||||
}, []);
|
||||
|
||||
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||
{
|
||||
@ -118,12 +124,76 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
case RoomEngineObjectEvent.MOUSE_LEAVE:
|
||||
updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT, objectId, category, event.roomId);
|
||||
break;
|
||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_CREDITFURNI, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_STICKIE:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_STICKIE, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_PRESENT:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_PRESENT, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_TROPHY:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_TROPHY, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_TEASER:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_TEASER, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_ECOTRONBOX:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_ECOTRONBOX, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_DIMMER:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_DIMMER, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_PLACEHOLDER:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_PLACEHOLDER, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_CLOTHING_CHANGE:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_CLOTHING_CHANGE, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_PLAYLIST_EDITOR:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_PLAYLIST_EDITOR, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING:
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_BADGE_DISPLAY_ENGRAVING, objectId, category, event.roomId));
|
||||
break;
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED: {
|
||||
const roomObject = GetRoomEngine().getRoomObject(event.roomId, objectId, category);
|
||||
const ownerId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
|
||||
|
||||
if(ownerId === GetSessionDataManager().userId)
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetFurniToWidgetMessage(RoomWidgetFurniToWidgetMessage.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED, objectId, category, event.roomId));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case RoomEngineTriggerWidgetEvent.OPEN_WIDGET:
|
||||
case RoomEngineTriggerWidgetEvent.CLOSE_WIDGET:
|
||||
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
|
||||
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
|
||||
case RoomEngineTriggerWidgetEvent.REMOVE_DIMMER:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN:
|
||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK:
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK:
|
||||
widgetHandler.processEvent(event);
|
||||
break;
|
||||
case RoomEngineRoomAdEvent.FURNI_CLICK:
|
||||
case RoomEngineRoomAdEvent.FURNI_DOUBLE_CLICK:
|
||||
handleRoomAdClick(event);
|
||||
break;
|
||||
case RoomEngineRoomAdEvent.TOOLTIP_SHOW:
|
||||
case RoomEngineRoomAdEvent.TOOLTIP_HIDE:
|
||||
handleRoomAdTooltip(event);
|
||||
break;
|
||||
}
|
||||
|
||||
if(updateEvent)
|
||||
@ -134,7 +204,7 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
|
||||
if(dispatchEvent) widgetHandler.eventDispatcher.dispatchEvent(updateEvent);
|
||||
}
|
||||
}, [ roomSession, widgetHandler ]);
|
||||
}, [ roomSession, widgetHandler, handleRoomAdClick, handleRoomAdTooltip ]);
|
||||
|
||||
useRoomEngineEvent(RoomEngineObjectEvent.SELECTED, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineObjectEvent.DESELECTED, onRoomEngineObjectEvent);
|
||||
@ -146,10 +216,37 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
||||
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MANIPULATION, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_ENTER, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TROPHY, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_TEASER, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ECOTRONBOX, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PLACEHOLDER, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_CLOTHING_CHANGE, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PLAYLIST_EDITOR, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_ENGRAVING, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BADGE_DISPLAY_ENGRAVING, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ACHIEVEMENT_RESOLUTION_FAILED, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_WIDGET, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REMOVE_DIMMER, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MANNEQUIN, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_FRIEND_FURNITURE_ENGRAVING, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIGH_SCORE_DISPLAY, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_HIDE_HIGH_SCORE_DISPLAY, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_INTERNAL_LINK, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_ROOM_LINK, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineRoomAdEvent.FURNI_CLICK, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineRoomAdEvent.FURNI_DOUBLE_CLICK, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineRoomAdEvent.TOOLTIP_SHOW, onRoomEngineObjectEvent);
|
||||
useRoomEngineEvent(RoomEngineRoomAdEvent.TOOLTIP_HIDE, onRoomEngineObjectEvent);
|
||||
|
||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ export const AvatarInfoWidgetView: FC<{}> = props =>
|
||||
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
|
||||
const [ isGameMode, setGameMode ] = useState(false);
|
||||
const [ isDancing, setIsDancing ] = useState(false);
|
||||
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
|
||||
const [ isDecorating, setIsDecorating ] = useState(false);
|
||||
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
|
||||
|
||||
const removeNameBubble = useCallback((index: number) =>
|
||||
|
@ -6,3 +6,4 @@
|
||||
@import './mannequin/FurnitureMannequinView';
|
||||
@import './stickie/FurnitureStickieView';
|
||||
@import './high-score/FurnitureHighScoreView';
|
||||
@import './gift-opening/FurnitureGiftOpeningView';
|
||||
|
@ -7,10 +7,10 @@ import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView';
|
||||
import { FurnitureExchangeCreditView } from './exchange-credit/FurnitureExchangeCreditView';
|
||||
import { FurnitureExternalImageView } from './external-image/FurnitureExternalImageView';
|
||||
import { FurnitureFriendFurniView } from './friend-furni/FurnitureFriendFurniView';
|
||||
import { FurnitureGiftOpeningView } from './gift-opening/FurnitureGiftOpeningView';
|
||||
import { FurnitureHighScoreView } from './high-score/FurnitureHighScoreView';
|
||||
import { FurnitureManipulationMenuView } from './manipulation-menu/FurnitureManipulationMenuView';
|
||||
import { FurnitureMannequinView } from './mannequin/FurnitureMannequinView';
|
||||
import { FurniturePresentView } from './present/FurniturePresentView';
|
||||
import { FurnitureStickieView } from './stickie/FurnitureStickieView';
|
||||
import { FurnitureTrophyView } from './trophy/FurnitureTrophyView';
|
||||
|
||||
@ -23,11 +23,11 @@ export const FurnitureWidgetsView: FC<{}> = props =>
|
||||
<FurnitureCustomStackHeightView />
|
||||
<FurnitureDimmerView />
|
||||
<FurnitureFriendFurniView />
|
||||
<FurnitureGiftOpeningView />
|
||||
<FurnitureExchangeCreditView />
|
||||
<FurnitureHighScoreView />
|
||||
<FurnitureManipulationMenuView />
|
||||
<FurnitureMannequinView />
|
||||
<FurniturePresentView />
|
||||
<FurnitureStickieView />
|
||||
<FurnitureTrophyView />
|
||||
<FurnitureBadgeDisplayView />
|
||||
|
@ -0,0 +1,8 @@
|
||||
export class DimmerFurnitureWidgetPresetItem
|
||||
{
|
||||
constructor(
|
||||
public id: number = 0,
|
||||
public type: number = 0,
|
||||
public color: number = 0,
|
||||
public light: number = 0) {}
|
||||
}
|
@ -2,6 +2,5 @@ export class FurnitureDimmerData
|
||||
{
|
||||
constructor(
|
||||
public objectId: number,
|
||||
public category: number,
|
||||
public active: boolean) {}
|
||||
public category: number) {}
|
||||
}
|
||||
|
@ -1,3 +1,13 @@
|
||||
.nitro-dimmer {
|
||||
width: 300px;
|
||||
|
||||
.dimmer-banner {
|
||||
width: 56px;
|
||||
height: 79px;
|
||||
background: url(../../../../../assets/images/room-widgets/dimmer-widget/dimmer_banner.png) center no-repeat;
|
||||
}
|
||||
|
||||
.color-swatch {
|
||||
height: 30px;
|
||||
}
|
||||
}
|
||||
|
@ -1,80 +1,205 @@
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||
import { NitroEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import ReactSlider from 'react-slider';
|
||||
import { ColorUtils, GetConfiguration, LocalizeText, RoomWidgetDimmerChangeStateMessage, RoomWidgetDimmerPreviewMessage, RoomWidgetDimmerSavePresetMessage, RoomWidgetUpdateDimmerEvent, RoomWidgetUpdateDimmerStateEvent } from '../../../../../api';
|
||||
import { BatchUpdates, CreateEventDispatcherHook } from '../../../../../hooks';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../../layout';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
import { FurnitureDimmerData } from './FurnitureDimmerData';
|
||||
import { DimmerFurnitureWidgetPresetItem } from './DimmerFurnitureWidgetPresetItem';
|
||||
|
||||
const AVAILABLE_COLORS: number[] = [7665141, 21495, 15161822, 15353138, 15923281, 8581961, 0];
|
||||
const HTML_COLORS: string[] = ['#74F5F5', '#0053F7', '#E759DE', '#EA4532', '#F2F851', '#82F349', '#000000'];
|
||||
const MIN_BRIGHTNESS: number = 75;
|
||||
const MAX_BRIGHTNESS: number = 255;
|
||||
|
||||
export const FurnitureDimmerView: FC<{}> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ presets, setPresets ] = useState<DimmerFurnitureWidgetPresetItem[]>([]);
|
||||
const [ selectedPresetId, setSelectedPresetId ] = useState(0);
|
||||
const [ dimmerState, setDimmerState ] = useState(0);
|
||||
const [ lastDimmerState, setLastDimmerState ] = useState(0);
|
||||
const [ effectId, setEffectId ] = useState(0);
|
||||
const [ color, setColor ] = useState(0xFFFFFF);
|
||||
const [ brightness, setBrightness ] = useState(0xFF);
|
||||
const [ selectedEffectId, setSelectedEffectId ] = useState(0);
|
||||
const [ selectedColor, setSelectedColor ] = useState(0);
|
||||
const [ selectedBrightness, setSelectedBrightness ] = useState(0);
|
||||
|
||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
const [ dimmerData, setDimmerData ] = useState<FurnitureDimmerData>(null);
|
||||
|
||||
// const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||
// {
|
||||
// switch(event.type)
|
||||
// {
|
||||
// case RoomEngineTriggerWidgetEvent.REQUEST_DIMMER: {
|
||||
// const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
||||
|
||||
// const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
||||
|
||||
// if(!roomObject) return;
|
||||
|
||||
// const data = roomObject.model.getValue<string[]>(RoomObjectVariable.FURNITURE_DATA);
|
||||
|
||||
// console.log('data', data);
|
||||
|
||||
// setDimmerData(new FurnitureDimmerData(widgetEvent.objectId, widgetEvent.category, false));
|
||||
// return;
|
||||
// }
|
||||
// case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
// const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
// setDimmerData(prevState =>
|
||||
// {
|
||||
// if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
||||
|
||||
// return null;
|
||||
// });
|
||||
// return;
|
||||
// }
|
||||
// case RoomWidgetDimmerUpdateEvent.RWDUE_PRESETS: {
|
||||
// const widgetEvent = (event as RoomWidgetDimmerUpdateEvent);
|
||||
|
||||
// console.log(widgetEvent);
|
||||
// return;
|
||||
// }
|
||||
// case RoomWidgetDimmerStateUpdateEvent.RWDSUE_DIMMER_STATE: {
|
||||
// const widgetEvent = (event as RoomWidgetDimmerStateUpdateEvent);
|
||||
|
||||
// console.log(widgetEvent);
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
// }, []);
|
||||
|
||||
// useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_DIMMER, onNitroEvent);
|
||||
// CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, props.events, onNitroEvent);
|
||||
// CreateEventDispatcherHook(RoomWidgetDimmerUpdateEvent.RWDUE_PRESETS, props.events, onNitroEvent);
|
||||
// CreateEventDispatcherHook(RoomWidgetDimmerStateUpdateEvent.RWDSUE_DIMMER_STATE, props.events, onNitroEvent);
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||
{
|
||||
switch(type)
|
||||
switch(event.type)
|
||||
{
|
||||
case 'close':
|
||||
setDimmerData(null);
|
||||
case RoomWidgetUpdateDimmerEvent.PRESETS: {
|
||||
const widgetEvent = (event as RoomWidgetUpdateDimmerEvent);
|
||||
|
||||
const presets: DimmerFurnitureWidgetPresetItem[] = [];
|
||||
|
||||
for(const preset of widgetEvent.presets) presets.push(new DimmerFurnitureWidgetPresetItem(preset.id, preset.type, preset.color, preset.brightness));
|
||||
|
||||
setPresets(presets);
|
||||
setSelectedPresetId(widgetEvent.selectedPresetId);
|
||||
setIsVisible(true);
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdateDimmerEvent.HIDE: {
|
||||
setIsVisible(false);
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE: {
|
||||
const widgetEvent = (event as RoomWidgetUpdateDimmerStateEvent);
|
||||
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
let prevDimmerState = 0;
|
||||
|
||||
setDimmerState(prevValue =>
|
||||
{
|
||||
setLastDimmerState(prevValue);
|
||||
|
||||
return widgetEvent.state;
|
||||
});
|
||||
|
||||
setLastDimmerState(prevDimmerState);
|
||||
setSelectedPresetId(widgetEvent.presetId);
|
||||
setEffectId(widgetEvent.effectId);
|
||||
setSelectedEffectId(widgetEvent.effectId);
|
||||
setColor(widgetEvent.color);
|
||||
setSelectedColor(widgetEvent.color);
|
||||
setBrightness(widgetEvent.brightness);
|
||||
setSelectedBrightness(widgetEvent.brightness);
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
}, []);
|
||||
|
||||
if(!dimmerData) return null;
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.PRESETS, eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateDimmerEvent.HIDE, eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateDimmerStateEvent.DIMMER_STATE, eventDispatcher, onNitroEvent);
|
||||
|
||||
const selectPresetId = useCallback((id: number) =>
|
||||
{
|
||||
const preset = presets[(id - 1)];
|
||||
|
||||
if(!preset) return;
|
||||
|
||||
setSelectedPresetId(preset.id);
|
||||
setSelectedEffectId(preset.type);
|
||||
setSelectedColor(preset.color);
|
||||
setSelectedBrightness(preset.light);
|
||||
}, [ presets ]);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(color, brightness, (effectId === 2)));
|
||||
|
||||
setIsVisible(false);
|
||||
}, [ widgetHandler, color, brightness, effectId ]);
|
||||
|
||||
const toggleState = useCallback(() =>
|
||||
{
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerChangeStateMessage());
|
||||
}, [ widgetHandler ]);
|
||||
|
||||
const applyChanges = useCallback(() =>
|
||||
{
|
||||
if(dimmerState === 0) return;
|
||||
|
||||
const selectedPresetIndex = (selectedPresetId - 1);
|
||||
|
||||
if((selectedPresetId < 1) || (selectedPresetId > presets.length)) return;
|
||||
|
||||
const preset = presets[selectedPresetIndex];
|
||||
|
||||
if(!preset || ((selectedEffectId === preset.type) && (selectedColor === preset.color) && (selectedBrightness === preset.light))) return;
|
||||
|
||||
setPresets(prevValue =>
|
||||
{
|
||||
const newValue = [ ...prevValue ];
|
||||
|
||||
newValue[selectedPresetIndex] = new DimmerFurnitureWidgetPresetItem(preset.id, selectedEffectId, selectedColor, selectedBrightness);
|
||||
|
||||
return newValue;
|
||||
});
|
||||
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerSavePresetMessage(preset.id, selectedEffectId, selectedColor, selectedBrightness, true));
|
||||
}, [ widgetHandler, dimmerState, selectedPresetId, presets, selectedEffectId, selectedColor, selectedBrightness ]);
|
||||
|
||||
const scaledBrightness = useCallback((value: number) =>
|
||||
{
|
||||
return ~~((((value - MIN_BRIGHTNESS) * (100 - 0)) / (MAX_BRIGHTNESS - MIN_BRIGHTNESS)) + 0);
|
||||
}, []);
|
||||
|
||||
const isFreeColorMode = useMemo(() =>
|
||||
{
|
||||
return GetConfiguration<boolean>('widget.dimmer.colorwheel', false);
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if((dimmerState === 0) && (lastDimmerState === 0)) return;
|
||||
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetDimmerPreviewMessage(selectedColor, selectedBrightness, (selectedEffectId === 2)));
|
||||
}, [ widgetHandler, dimmerState, lastDimmerState, selectedColor, selectedBrightness, selectedEffectId ]);
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-dimmer">
|
||||
<NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ event => processAction('close') } />
|
||||
<NitroCardContentView>
|
||||
|
||||
<NitroCardHeaderView headerText={ LocalizeText('widget.dimmer.title') } onCloseClick={ close } />
|
||||
<NitroCardContentView className="p-0">
|
||||
{ (dimmerState === 0) &&
|
||||
<div className="d-flex flex-column gap-2 align-items-center p-2">
|
||||
<div className="dimmer-banner"></div>
|
||||
<div className="bg-muted rounded p-1 text-center text-black">{ LocalizeText('widget.dimmer.info.off') }</div>
|
||||
<button className="btn-success btn w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.on') }</button>
|
||||
</div> }
|
||||
{ (dimmerState === 1) &&
|
||||
<>
|
||||
<NitroCardTabsView>
|
||||
{ presets.map(preset =>
|
||||
{
|
||||
return <NitroCardTabsItemView key={ preset.id } isActive={ (selectedPresetId === preset.id) } onClick={ event => selectPresetId(preset.id) }>{ LocalizeText(`widget.dimmer.tab.${preset.id}`) }</NitroCardTabsItemView>
|
||||
}) }
|
||||
</NitroCardTabsView>
|
||||
<div className="p-2">
|
||||
<div className="form-group mb-2">
|
||||
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.hue') }</label>
|
||||
{ isFreeColorMode &&
|
||||
<input type="color" className="form-control" value={ ColorUtils.makeColorNumberHex(selectedColor) } onChange={ event => setSelectedColor(ColorUtils.convertFromHex(event.target.value)) } /> }
|
||||
{ !isFreeColorMode &&
|
||||
<div className="d-flex gap-2">
|
||||
{ AVAILABLE_COLORS.map((color, index) =>
|
||||
{
|
||||
return <div key={ index } className="rounded w-100 color-swatch cursor-pointer" onClick={ () => setSelectedColor(color) } style={{ backgroundColor: HTML_COLORS[index] }}></div>;
|
||||
}) }
|
||||
</div> }
|
||||
</div>
|
||||
<div className="form-group mb-2">
|
||||
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.lightness') }</label>
|
||||
<ReactSlider
|
||||
className={ 'nitro-slider' }
|
||||
min={ MIN_BRIGHTNESS }
|
||||
max={ MAX_BRIGHTNESS }
|
||||
value={ selectedBrightness }
|
||||
onChange={ value => setSelectedBrightness(value) }
|
||||
thumbClassName={ 'thumb percent' }
|
||||
renderThumb={ (props, state) => <div {...props}>{ scaledBrightness(state.valueNow) }</div> } />
|
||||
</div>
|
||||
<div className="form-check mb-2">
|
||||
<input className="form-check-input" type="checkbox" checked={ (selectedEffectId === 2) } onChange={ event => setSelectedEffectId(event.target.checked ? 2 : 1) } />
|
||||
<label className="form-check-label text-black">{ LocalizeText('widget.dimmer.type.checkbox') }</label>
|
||||
</div>
|
||||
<div className="d-flex gap-2">
|
||||
<button className="btn btn-danger w-100" onClick={ toggleState }>{ LocalizeText('widget.dimmer.button.off') }</button>
|
||||
<button className="btn btn-success w-100" onClick={ applyChanges }>{ LocalizeText('widget.dimmer.button.apply') }</button>
|
||||
</div>
|
||||
</div>
|
||||
</> }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
|
@ -1,7 +0,0 @@
|
||||
export class FurnitureExchangeCreditData
|
||||
{
|
||||
constructor(
|
||||
public objectId: number,
|
||||
public category: number,
|
||||
public value: number) {}
|
||||
}
|
@ -1,73 +1,51 @@
|
||||
import { FurnitureExchangeComposer, NitroEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomEngine, GetRoomSession, IsOwnerOfFurniture, LocalizeText, RoomWidgetRoomObjectUpdateEvent } from '../../../../../api';
|
||||
import { LocalizeText, RoomWidgetCreditFurniRedeemMessage, RoomWidgetUpdateCreditFurniEvent } from '../../../../../api';
|
||||
import { BatchUpdates } 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 { useRoomContext } from '../../../context/RoomContext';
|
||||
import { FurnitureExchangeCreditData } from './FurnitureExchangeCreditData';
|
||||
|
||||
export const FurnitureExchangeCreditView: FC<{}> = props =>
|
||||
{
|
||||
const [ objectId, setObjectId ] = useState(-1);
|
||||
const [ value, setValue ] = useState(0);
|
||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
const [ exchangeCreditData, setExchangeCreditData ] = useState<FurnitureExchangeCreditData>(null);
|
||||
|
||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
||||
const onRoomWidgetUpdateCreditFurniEvent = useCallback((event: RoomWidgetUpdateCreditFurniEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI: {
|
||||
const widgetEvent = (event as RoomEngineTriggerWidgetEvent);
|
||||
|
||||
const roomObject = GetRoomEngine().getRoomObject(widgetEvent.roomId, widgetEvent.objectId, widgetEvent.category);
|
||||
|
||||
if(!roomObject || !IsOwnerOfFurniture(roomObject)) return;
|
||||
|
||||
const value = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_CREDIT_VALUE);
|
||||
|
||||
setExchangeCreditData(new FurnitureExchangeCreditData(widgetEvent.objectId, widgetEvent.category, value));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
setExchangeCreditData(prevState =>
|
||||
{
|
||||
if(!prevState || (widgetEvent.id !== prevState.objectId) || (widgetEvent.category !== prevState.category)) return prevState;
|
||||
|
||||
return null;
|
||||
});
|
||||
return;
|
||||
}
|
||||
}
|
||||
setObjectId(event.objectId);
|
||||
setValue(event.value);
|
||||
}, []);
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_CREDITFURNI, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateCreditFurniEvent.CREDIT_FURNI_UPDATE, eventDispatcher, onRoomWidgetUpdateCreditFurniEvent);
|
||||
|
||||
const processAction = useCallback((type: string, value: string = null) =>
|
||||
{
|
||||
switch(type)
|
||||
{
|
||||
case 'close':
|
||||
setExchangeCreditData(null);
|
||||
BatchUpdates(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setValue(0);
|
||||
});
|
||||
return;
|
||||
case 'redeem':
|
||||
if(!exchangeCreditData) return null;
|
||||
|
||||
GetRoomSession().connection.send(new FurnitureExchangeComposer(exchangeCreditData.objectId));
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetCreditFurniRedeemMessage(RoomWidgetCreditFurniRedeemMessage.REDEEM, objectId));
|
||||
|
||||
processAction('close');
|
||||
return;
|
||||
}
|
||||
}, [exchangeCreditData]);
|
||||
}, [ widgetHandler, objectId ]);
|
||||
|
||||
if(!exchangeCreditData) return null;
|
||||
if(objectId === -1) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-exchange-credit" simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('catalog.redeem.dialog.title') } onCloseClick={ event => processAction('close') } />
|
||||
<NitroCardContentView>
|
||||
<div className="text-black mb-2">
|
||||
{ LocalizeText('widgets.furniture.credit.redeem.value', [ 'value' ], [ exchangeCreditData.value.toString() ]) }
|
||||
{ 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>
|
||||
</NitroCardContentView>
|
||||
|
@ -0,0 +1,3 @@
|
||||
.nitro-gift-opening {
|
||||
min-width: 340px;
|
||||
}
|
@ -0,0 +1,227 @@
|
||||
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 { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView, NitroLayoutGiftCardView } from '../../../../../layout';
|
||||
import { ProductTypeEnum } from '../../../../catalog/common/ProductTypeEnum';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
|
||||
const FLOOR: string = 'floor';
|
||||
const WALLPAPER: string = 'wallpaper';
|
||||
const LANDSCAPE: string = 'landscape';
|
||||
|
||||
export const FurnitureGiftOpeningView: FC<{}> = props =>
|
||||
{
|
||||
const [ objectId, setObjectId ] = useState(-1);
|
||||
const [ classId, setClassId ] = useState(-1);
|
||||
const [ itemType, setItemType ] = useState<string>(null);
|
||||
const [ text, setText ] = useState<string>(null);
|
||||
const [ isOwnerOfFurniture, setIsOwnerOfFurniture ] = useState(false);
|
||||
const [ senderName, setSenderName ] = useState<string>(null);
|
||||
const [ senderFigure, setSenderFigure ] = useState<string>(null);
|
||||
const [ placedItemId, setPlacedItemId ] = useState(-1);
|
||||
const [ placedItemType, setPlacedItemType ] = useState<string>(null);
|
||||
const [ placedInRoom, setPlacedInRoom ] = useState(false);
|
||||
const [ imageUrl, setImageUrl ] = useState<string>(null);
|
||||
const [ openRequested, setOpenRequested ] = useState(false);
|
||||
const { roomSession = null, eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
|
||||
const clearGift = useCallback(() =>
|
||||
{
|
||||
if(!openRequested) setObjectId(-1);
|
||||
|
||||
setText(null);
|
||||
setIsOwnerOfFurniture(false);
|
||||
}, [ openRequested ]);
|
||||
|
||||
const getGiftImageUrl = useCallback((name: string) =>
|
||||
{
|
||||
return '';
|
||||
}, []);
|
||||
|
||||
const onRoomWidgetUpdatePresentDataEvent = useCallback((event: RoomWidgetUpdatePresentDataEvent) =>
|
||||
{
|
||||
switch(event.type)
|
||||
{
|
||||
case RoomWidgetUpdatePresentDataEvent.PACKAGEINFO: {
|
||||
setOpenRequested(false);
|
||||
setObjectId(event.objectId);
|
||||
setText(event.giftMessage);
|
||||
setIsOwnerOfFurniture(event.isController);
|
||||
setSenderName(event.purchaserName);
|
||||
setSenderFigure(event.purchaserFigure);
|
||||
setImageUrl(event.imageUrl);
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR:
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE:
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER: {
|
||||
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));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB: {
|
||||
setObjectId(event.objectId);
|
||||
setClassId(event.classId);
|
||||
setItemType(event.itemType);
|
||||
setText(event.giftMessage);
|
||||
setIsOwnerOfFurniture(event.isController);
|
||||
setImageUrl(getGiftImageUrl('packagecard_icon_hc'));
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS: {
|
||||
if(!openRequested) return;
|
||||
|
||||
setObjectId(event.objectId);
|
||||
setClassId(event.classId);
|
||||
setItemType(event.itemType);
|
||||
setText(event.giftMessage);
|
||||
setIsOwnerOfFurniture(event.isController);
|
||||
setPlacedItemId(event.placedItemId);
|
||||
setPlacedItemType(event.placedItemType);
|
||||
setPlacedInRoom(event.placedInRoom);
|
||||
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE: {
|
||||
if(!openRequested) return;
|
||||
|
||||
setImageUrl(event.imageUrl);
|
||||
}
|
||||
}
|
||||
}, [ openRequested, getGiftImageUrl ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.PACKAGEINFO, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_FLOOR, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_LANDSCAPE, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_WALLPAPER, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_CLUB, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetUpdatePresentDataEvent.CONTENTS_IMAGE, eventDispatcher, onRoomWidgetUpdatePresentDataEvent);
|
||||
|
||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||
{
|
||||
if(event.id === objectId) clearGift();
|
||||
|
||||
if(event.id === placedItemId)
|
||||
{
|
||||
if(placedInRoom) setPlacedInRoom(false);
|
||||
}
|
||||
}, [ objectId, placedItemId, placedInRoom, clearGift ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const close = useCallback(() =>
|
||||
{
|
||||
setObjectId(-1);
|
||||
setOpenRequested(false);
|
||||
setPlacedItemId(-1);
|
||||
setPlacedInRoom(false);
|
||||
setText(null);
|
||||
setIsOwnerOfFurniture(false);
|
||||
}, [ clearGift ]);
|
||||
|
||||
const isSpaces = useMemo(() =>
|
||||
{
|
||||
if(itemType !== ProductTypeEnum.WALL) return false;
|
||||
|
||||
const furniData = GetSessionDataManager().getWallItemData(classId);
|
||||
|
||||
if(!furniData) return false;
|
||||
|
||||
const className = furniData.className;
|
||||
|
||||
return (className === FLOOR || className === LANDSCAPE || className === WALLPAPER);
|
||||
}, [ classId, itemType ]);
|
||||
|
||||
const productName = useMemo(() =>
|
||||
{
|
||||
if(objectId === -1) return '';
|
||||
|
||||
if(isSpaces)
|
||||
return 'widget.furni.present.spaces.message_opened';
|
||||
|
||||
return 'widget.furni.present.message_opened';
|
||||
}, [ objectId, isSpaces ]);
|
||||
|
||||
const handleAction = useCallback((action: string) =>
|
||||
{
|
||||
switch(action)
|
||||
{
|
||||
case 'give_gift':
|
||||
CreateLinkEvent('catalog/open');
|
||||
return;
|
||||
case 'open':
|
||||
setOpenRequested(true);
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetPresentOpenMessage(RoomWidgetPresentOpenMessage.OPEN_PRESENT, objectId));
|
||||
return;
|
||||
case 'room':
|
||||
return;
|
||||
case 'inventory':
|
||||
if((placedItemId > 0) && placedInRoom)
|
||||
{
|
||||
if(placedItemType === ProductTypeEnum.PET)
|
||||
{
|
||||
roomSession.pickupPet(placedItemId);
|
||||
}
|
||||
else
|
||||
{
|
||||
const roomObject = GetRoomEngine().getRoomObject(roomSession.roomId, placedItemId, RoomObjectCategory.FLOOR);
|
||||
|
||||
if(roomObject) GetRoomEngine().processRoomObjectOperation(roomObject.id, RoomObjectCategory.FLOOR, RoomObjectOperationType.OBJECT_PICKUP);
|
||||
}
|
||||
}
|
||||
|
||||
close();
|
||||
return;
|
||||
}
|
||||
}, [ roomSession, widgetHandler, objectId, placedInRoom, placedItemId, placedItemType, close ]);
|
||||
|
||||
if(objectId === -1) return null;
|
||||
|
||||
return (
|
||||
<NitroCardView className="nitro-gift-opening" simple={ true }>
|
||||
<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>
|
||||
</> }
|
||||
</> }
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
import { NitroEvent, RoomEngineTriggerWidgetEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC } from 'react';
|
||||
import { useRoomEngineEvent } from '../../../../../hooks/events/nitro/room/room-engine-event';
|
||||
import { useRoomContext } from '../../../context/RoomContext';
|
||||
|
||||
export const FurniturePresentView: FC<{}> = props =>
|
||||
{
|
||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
|
||||
const onNitroEvent = (event: NitroEvent) =>
|
||||
{
|
||||
console.log(event);
|
||||
};
|
||||
|
||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PRESENT, onNitroEvent);
|
||||
|
||||
return null;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user