mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-18 21:36:27 +01:00
Merge branch 'feature/hotelview' of https://github.com/billsonnn/nitro-react into feature/hotelview
This commit is contained in:
commit
9ce3f103ad
@ -91,8 +91,8 @@
|
||||
"widgets": {
|
||||
"slot.1.widget": "promoarticle",
|
||||
"slot.1.conf": "",
|
||||
"slot.2.widget": "",
|
||||
"slot.2.conf": "",
|
||||
"slot.2.widget": "widgetcontainer",
|
||||
"slot.2.conf": "image:${image.library.url}web_promo_small/spromo_Canal_Bundle.png,btn:HelloHELLO,btnLink:https://google.com/",
|
||||
"slot.3.widget": "",
|
||||
"slot.3.conf": "",
|
||||
"slot.4.widget": "",
|
||||
|
18
src/App.tsx
18
src/App.tsx
@ -1,6 +1,6 @@
|
||||
import { ConfigurationEvent, LegacyExternalInterface, Nitro, NitroCommunicationDemoEvent, NitroEvent, NitroLocalizationEvent, RoomEngineEvent, WebGL } from 'nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetConfiguration } from './api';
|
||||
import { GetCommunication, GetConfiguration, GetNitroInstance } from './api';
|
||||
import { useConfigurationEvent } from './hooks/events/core/configuration/configuration-event';
|
||||
import { useLocalizationEvent } from './hooks/events/nitro/localization/localization-event';
|
||||
import { dispatchMainEvent, useMainEvent } from './hooks/events/nitro/main-event';
|
||||
@ -19,7 +19,7 @@ export const App: FC<{}> = props =>
|
||||
//@ts-ignore
|
||||
if(!NitroConfig) throw new Error('NitroConfig is not defined!');
|
||||
|
||||
if(!Nitro.instance) Nitro.bootstrap();
|
||||
if(!GetNitroInstance()) Nitro.bootstrap();
|
||||
|
||||
const getPreloadAssetUrls = useCallback(() =>
|
||||
{
|
||||
@ -28,7 +28,7 @@ export const App: FC<{}> = props =>
|
||||
|
||||
if(assetUrls && assetUrls.length)
|
||||
{
|
||||
for(const url of assetUrls) urls.push(Nitro.instance.core.configuration.interpolate(url));
|
||||
for(const url of assetUrls) urls.push(GetNitroInstance().core.configuration.interpolate(url));
|
||||
}
|
||||
|
||||
return urls;
|
||||
@ -39,7 +39,7 @@ export const App: FC<{}> = props =>
|
||||
switch(event.type)
|
||||
{
|
||||
case ConfigurationEvent.LOADED:
|
||||
Nitro.instance.localization.init();
|
||||
GetNitroInstance().localization.init();
|
||||
return;
|
||||
case ConfigurationEvent.FAILED:
|
||||
setIsError(true);
|
||||
@ -73,14 +73,14 @@ export const App: FC<{}> = props =>
|
||||
case NitroCommunicationDemoEvent.CONNECTION_AUTHENTICATED:
|
||||
setMessage('Finishing Up');
|
||||
|
||||
Nitro.instance.init();
|
||||
GetNitroInstance().init();
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_ERROR:
|
||||
setIsError(true);
|
||||
setMessage('Connection Error');
|
||||
return;
|
||||
case NitroCommunicationDemoEvent.CONNECTION_CLOSED:
|
||||
if(Nitro.instance.roomEngine) Nitro.instance.roomEngine.dispose();
|
||||
if(GetNitroInstance().roomEngine) GetNitroInstance().roomEngine.dispose();
|
||||
|
||||
setIsError(true);
|
||||
setMessage('Connection Error');
|
||||
@ -91,13 +91,13 @@ export const App: FC<{}> = props =>
|
||||
setIsReady(true);
|
||||
return;
|
||||
case NitroLocalizationEvent.LOADED:
|
||||
Nitro.instance.core.asset.downloadAssets(getPreloadAssetUrls(), (status: boolean) =>
|
||||
GetNitroInstance().core.asset.downloadAssets(getPreloadAssetUrls(), (status: boolean) =>
|
||||
{
|
||||
if(status)
|
||||
{
|
||||
setMessage('Connecting');
|
||||
|
||||
Nitro.instance.communication.init();
|
||||
GetCommunication().init();
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -127,7 +127,7 @@ export const App: FC<{}> = props =>
|
||||
}
|
||||
else
|
||||
{
|
||||
Nitro.instance.core.configuration.init();
|
||||
GetNitroInstance().core.configuration.init();
|
||||
}
|
||||
|
||||
return (
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { CatalogPageComposer } from 'nitro-renderer';
|
||||
|
||||
export function GetCatalogPageComposer(...args: ConstructorParameters<typeof CatalogPageComposer>): CatalogPageComposer
|
||||
{
|
||||
return new CatalogPageComposer(...args);
|
||||
}
|
7
src/api/core/GetConfigurationManager.ts
Normal file
7
src/api/core/GetConfigurationManager.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { IConfigurationManager } from 'nitro-renderer';
|
||||
import { GetNitroCore } from './GetNitroCore';
|
||||
|
||||
export function GetConfigurationManager(): IConfigurationManager
|
||||
{
|
||||
return GetNitroCore().configuration;
|
||||
}
|
7
src/api/core/GetNitroCore.ts
Normal file
7
src/api/core/GetNitroCore.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { INitroCore } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../nitro';
|
||||
|
||||
export function GetNitroCore(): INitroCore
|
||||
{
|
||||
return GetNitroInstance().core;
|
||||
}
|
2
src/api/core/index.ts
Normal file
2
src/api/core/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './GetConfigurationManager';
|
||||
export * from './GetNitroCore';
|
@ -1 +1,2 @@
|
||||
export * from './core';
|
||||
export * from './nitro';
|
||||
|
7
src/api/nitro/AddLinkEventTracker.ts
Normal file
7
src/api/nitro/AddLinkEventTracker.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ILinkEventTracker } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function AddEventLinkTracker(tracker: ILinkEventTracker): void
|
||||
{
|
||||
GetNitroInstance().addLinkEventTracker(tracker);
|
||||
}
|
7
src/api/nitro/GetCommunication.ts
Normal file
7
src/api/nitro/GetCommunication.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { INitroCommunicationManager } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function GetCommunication(): INitroCommunicationManager
|
||||
{
|
||||
return GetNitroInstance().communication;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function GetConfiguration<T>(key: string, value: T = null): T
|
||||
{
|
||||
return Nitro.instance.getConfiguration(key, value);
|
||||
return GetNitroInstance().getConfiguration(key, value);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { IConnection, Nitro } from 'nitro-renderer';
|
||||
import { IConnection } from 'nitro-renderer';
|
||||
import { GetCommunication } from './GetCommunication';
|
||||
|
||||
export function GetConnection(): IConnection
|
||||
{
|
||||
return Nitro.instance.communication.connection;
|
||||
return GetCommunication().connection;
|
||||
}
|
||||
|
6
src/api/nitro/GetNitroInstance.ts
Normal file
6
src/api/nitro/GetNitroInstance.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { INitro, Nitro } from 'nitro-renderer';
|
||||
|
||||
export function GetNitroInstance(): INitro
|
||||
{
|
||||
return Nitro.instance;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function GetTicker()
|
||||
{
|
||||
return Nitro.instance.ticker;
|
||||
return GetNitroInstance().ticker;
|
||||
}
|
||||
|
7
src/api/nitro/RemoveLinkEventTracker.ts
Normal file
7
src/api/nitro/RemoveLinkEventTracker.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { ILinkEventTracker } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from './GetNitroInstance';
|
||||
|
||||
export function RemoveLinkEventTracker(tracker: ILinkEventTracker): void
|
||||
{
|
||||
GetNitroInstance().removeLinkEventTracker(tracker);
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
import { IAvatarRenderManager, Nitro } from 'nitro-renderer';
|
||||
import { IAvatarRenderManager } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetAvatarRenderManager(): IAvatarRenderManager
|
||||
{
|
||||
return Nitro.instance.avatar;
|
||||
return GetNitroInstance().avatar;
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { IRoomCameraWidgetManager } from 'nitro-renderer/src/nitro/camera/IRoomCameraWidgetManager';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetRoomCameraWidgetManager(): IRoomCameraWidgetManager
|
||||
{
|
||||
return Nitro.instance.cameraManager;
|
||||
return GetNitroInstance().cameraManager;
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
export * from './AddLinkEventTracker';
|
||||
export * from './avatar';
|
||||
export * from './camera';
|
||||
export * from './GetCommunication';
|
||||
export * from './GetConfiguration';
|
||||
export * from './GetConnection';
|
||||
export * from './GetNitroInstance';
|
||||
export * from './GetTicker';
|
||||
export * from './RemoveLinkEventTracker';
|
||||
export * from './room';
|
||||
export * from './session';
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { IRoomEngine, Nitro } from 'nitro-renderer';
|
||||
import { IRoomEngine } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetRoomEngine(): IRoomEngine
|
||||
{
|
||||
return Nitro.instance.roomEngine;
|
||||
return GetNitroInstance().roomEngine;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { IRoomSessionManager, Nitro } from 'nitro-renderer';
|
||||
import { IRoomSessionManager } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetRoomSessionManager(): IRoomSessionManager
|
||||
{
|
||||
return Nitro.instance.roomSessionManager;
|
||||
return GetNitroInstance().roomSessionManager;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ISessionDataManager, Nitro } from 'nitro-renderer';
|
||||
import { ISessionDataManager } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../GetNitroInstance';
|
||||
|
||||
export function GetSessionDataManager(): ISessionDataManager
|
||||
{
|
||||
return Nitro.instance.sessionDataManager;
|
||||
return GetNitroInstance().sessionDataManager;
|
||||
}
|
||||
|
@ -80,7 +80,9 @@ $cello-light: #21516e !default;
|
||||
$cello-dark: #1e465e !default;
|
||||
$pale-sky: #677181 !default;
|
||||
$oslo-gray: #8F9297 !default;
|
||||
|
||||
$gainsboro: #d9d9d9 !default;
|
||||
$ghost: #c8cad0 !default;
|
||||
$gray-chateau: #a3a7b1 !default;
|
||||
$success: $green !default;
|
||||
$info: $cyan !default;
|
||||
$warning: $yellow !default;
|
||||
@ -122,7 +124,8 @@ $theme-colors: (
|
||||
"white": $white,
|
||||
"black": $black,
|
||||
"muted": $muted,
|
||||
"purple": $purple
|
||||
"purple": $purple,
|
||||
"gainsboro": $gainsboro
|
||||
) !default;
|
||||
// scss-docs-end theme-colors-map
|
||||
|
||||
|
6
src/events/inventory/InventoryBadgesRequestEvent.ts
Normal file
6
src/events/inventory/InventoryBadgesRequestEvent.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
|
||||
export class InventoryBadgesRequestEvent extends NitroEvent
|
||||
{
|
||||
public static REQUEST_BADGES: string = 'IBRE_REQUEST_BADGES';
|
||||
}
|
20
src/events/inventory/InventoryBadgesUpdatedEvent.ts
Normal file
20
src/events/inventory/InventoryBadgesUpdatedEvent.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
|
||||
export class InventoryBadgesUpdatedEvent extends NitroEvent
|
||||
{
|
||||
public static BADGES_UPDATED: string = 'IBUE_BADGES_UPDATED';
|
||||
|
||||
private _badges: string[] = [];
|
||||
|
||||
constructor(type: string, badges: string[] = [])
|
||||
{
|
||||
super(type);
|
||||
|
||||
this._badges = badges;
|
||||
}
|
||||
|
||||
public get badges(): string[]
|
||||
{
|
||||
return this._badges;
|
||||
}
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
export * from './InventoryBadgesUpdatedEvent';
|
||||
export * from './InventoryEvent';
|
||||
export * from './InventoryTradeRequestEvent';
|
||||
export * from './InventoryTradeStartEvent';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetCommunication } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useCommunicationEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.communication.events, handler);
|
||||
CreateEventDispatcherHook(type, GetCommunication().events, handler);
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetConfigurationManager } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useConfigurationEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.core.configuration.events, handler);
|
||||
CreateEventDispatcherHook(type, GetConfigurationManager().events, handler);
|
||||
}
|
||||
|
@ -1 +1,2 @@
|
||||
export * from './communication';
|
||||
export * from './configuration';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetAvatarRenderManager } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useAvatarEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.avatar.events, handler);
|
||||
CreateEventDispatcherHook(type, GetAvatarRenderManager().events, handler);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetNitroInstance } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useCameraEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.cameraManager.events, handler);
|
||||
CreateEventDispatcherHook(type, GetNitroInstance().cameraManager.events, handler);
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
export * from './avatar';
|
||||
export * from './camera';
|
||||
export * from './communication';
|
||||
export * from './localization';
|
||||
export * from './main-event';
|
||||
export * from './room';
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetNitroInstance } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useLocalizationEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.localization.events, handler);
|
||||
CreateEventDispatcherHook(type, GetNitroInstance().localization.events, handler);
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
import { Nitro, NitroEvent } from 'nitro-renderer';
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../../../api';
|
||||
import { CreateEventDispatcherHook, DispatchEventHook } from '../event-dispatcher.base';
|
||||
|
||||
export function useMainEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.events, handler);
|
||||
CreateEventDispatcherHook(type, GetNitroInstance().events, handler);
|
||||
}
|
||||
|
||||
export function dispatchMainEvent(event: NitroEvent): void
|
||||
{
|
||||
DispatchEventHook(Nitro.instance.events, event);
|
||||
DispatchEventHook(GetNitroInstance().events, event);
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { GetRoomEngine } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useRoomEngineEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.roomEngine.events, handler);
|
||||
CreateEventDispatcherHook(type, GetRoomEngine().events, handler);
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { Nitro, NitroEvent } from 'nitro-renderer';
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { GetRoomSessionManager } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../event-dispatcher.base';
|
||||
|
||||
export function useRoomSessionManagerEvent(type: string, handler: (event: NitroEvent) => void): void
|
||||
{
|
||||
CreateEventDispatcherHook(type, Nitro.instance.roomSessionManager.events, handler);
|
||||
CreateEventDispatcherHook(type, GetRoomSessionManager().events, handler);
|
||||
}
|
||||
|
@ -1,13 +1,6 @@
|
||||
export * from './events';
|
||||
export * from './events/core';
|
||||
export * from './events/core/configuration';
|
||||
export * from './events/nitro';
|
||||
export * from './events/nitro/avatar';
|
||||
export * from './events/nitro/camera';
|
||||
export * from './events/nitro/communication';
|
||||
export * from './events/nitro/localization';
|
||||
export * from './events/nitro/room';
|
||||
export * from './events/nitro/session';
|
||||
export * from './events/ui';
|
||||
export * from './messages';
|
||||
export * from './UseMountEffect';
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { IMessageComposer, IMessageEvent, MessageEvent } from 'nitro-renderer';
|
||||
import { Nitro } from 'nitro-renderer/src/nitro/Nitro';
|
||||
import { useEffect } from 'react';
|
||||
import { GetCommunication, GetConnection } from '../../api';
|
||||
|
||||
export function CreateMessageHook(eventType: typeof MessageEvent, handler: (event: IMessageEvent) => void): void
|
||||
{
|
||||
@ -9,13 +9,13 @@ export function CreateMessageHook(eventType: typeof MessageEvent, handler: (even
|
||||
//@ts-ignore
|
||||
const event = new eventType(handler);
|
||||
|
||||
Nitro.instance.communication.registerMessageEvent(event);
|
||||
GetCommunication().registerMessageEvent(event);
|
||||
|
||||
return () => Nitro.instance.communication.removeMessageEvent(event);
|
||||
return () => GetCommunication().removeMessageEvent(event);
|
||||
}, [ eventType, handler ]);
|
||||
}
|
||||
|
||||
export function SendMessageHook(event: IMessageComposer<unknown[]>): void
|
||||
{
|
||||
Nitro.instance.communication.connection.send(event);
|
||||
GetConnection().send(event);
|
||||
}
|
||||
|
@ -64,11 +64,9 @@
|
||||
}
|
||||
|
||||
.avatar-image {
|
||||
width: 100% !important;
|
||||
height: 100% !important;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
background-position-y: -32px !important;
|
||||
background-position-y: 12px !important;
|
||||
}
|
||||
|
||||
.trade-button {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../api';
|
||||
|
||||
export function LocalizeBadgeName(key: string): string
|
||||
{
|
||||
return Nitro.instance.localization.getBadgeName(key);
|
||||
return GetNitroInstance().localization.getBadgeName(key);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../api';
|
||||
|
||||
export function LocalizeText(key: string, parameters: string[] = null, replacements: string[] = null): string
|
||||
{
|
||||
return Nitro.instance.getLocalizationWithParameters(key, parameters, replacements);
|
||||
return GetNitroInstance().getLocalizationWithParameters(key, parameters, replacements);
|
||||
}
|
||||
|
@ -83,8 +83,36 @@
|
||||
.wardrobe-grid {
|
||||
|
||||
.grid-item-container {
|
||||
height: 100% !important;
|
||||
max-height: 100% !important;
|
||||
height: 142px !important;
|
||||
max-height: 142px !important;
|
||||
|
||||
.grid-item {
|
||||
background-color: $ghost;
|
||||
|
||||
.avatar-image {
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
background-position-y: -23px !important;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.figure-button-container {
|
||||
background-color: $gray-chateau;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
&:after {
|
||||
position: absolute;
|
||||
content: '';
|
||||
height: 50%;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background-color: $gray-chateau;
|
||||
box-shadow: 0 0 8px 2px rgba($white,.6);
|
||||
z-index: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -79,12 +79,20 @@ export const AvatarEditorView: FC<AvatarEditorViewProps> = props =>
|
||||
const onUserWardrobePageEvent = useCallback((event: UserWardrobePageEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
const savedFigures: [ string, string ][] = [];
|
||||
|
||||
const savedFigures: [ string, string ][] = new Array(MAX_SAVED_FIGURES);
|
||||
let i = 0;
|
||||
|
||||
for(const value of parser.looks.values())
|
||||
while(i < MAX_SAVED_FIGURES)
|
||||
{
|
||||
console.log(value);
|
||||
savedFigures.push([ null, null ]);
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
for(let [ index, value ] of parser.looks.entries())
|
||||
{
|
||||
savedFigures[(index - 1)] = [ value[0], value[1] ];
|
||||
}
|
||||
|
||||
setSavedFigures(savedFigures)
|
||||
@ -280,7 +288,7 @@ export const AvatarEditorView: FC<AvatarEditorViewProps> = props =>
|
||||
<div className="row h-100">
|
||||
<div className="col-9 d-flex flex-column h-100">
|
||||
{ (activeCategory && !isWardrobeVisible) && <AvatarEditorModelView model={ activeCategory } gender={ figureData.gender } setGender={ setGender } /> }
|
||||
{ isWardrobeVisible && <AvatarEditorWardrobeView figures={ savedFigures } /> }
|
||||
{ isWardrobeVisible && <AvatarEditorWardrobeView figureData={ figureData } savedFigures={ savedFigures } setSavedFigures={ setSavedFigures } loadAvatarInEditor={ loadAvatarInEditor } /> }
|
||||
</div>
|
||||
<div className="col-3 d-flex flex-column h-100">
|
||||
<div className="figure-preview-container">
|
||||
|
@ -162,7 +162,7 @@ export class AvatarEditorUtilities
|
||||
|
||||
partItems.sort(this.clubItemsFirst ? this.clubSorter : this.noobSorter);
|
||||
|
||||
// if(this._forceSellableClothingVisibility || Nitro.instance.getConfiguration<boolean>("avatareditor.support.sellablefurni", false))
|
||||
// if(this._forceSellableClothingVisibility || GetNitroInstance().getConfiguration<boolean>("avatareditor.support.sellablefurni", false))
|
||||
// {
|
||||
// _local_31 = (this._manager.windowManager.assets.getAssetByName("camera_zoom_in") as BitmapDataAsset);
|
||||
// _local_32 = (_local_31.content as BitmapData).clone();
|
||||
|
@ -206,7 +206,7 @@ export class FigureData
|
||||
{
|
||||
const colors = this._colors.get(setType);
|
||||
|
||||
if(colors === undefined) continue;
|
||||
if(!colors) continue;
|
||||
|
||||
let setId = this._data.get(setType);
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
import { FC, useMemo } from 'react';
|
||||
import { UserWardrobeSaveComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useMemo } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { SendMessageHook } from '../../../../hooks';
|
||||
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
|
||||
import { NitroCardGridThemes } from '../../../../layout/card/grid/NitroCardGridView.types';
|
||||
@ -7,48 +10,68 @@ import { AvatarEditorWardrobeViewProps } from './AvatarEditorWardrobeView.types'
|
||||
|
||||
export const AvatarEditorWardrobeView: FC<AvatarEditorWardrobeViewProps> = props =>
|
||||
{
|
||||
const { figures = [] } = props;
|
||||
const { figureData = null, savedFigures = [], setSavedFigures = null, loadAvatarInEditor = null } = props;
|
||||
|
||||
const savedFigures = useMemo(() =>
|
||||
const wearFigureAtIndex = useCallback((index: number) =>
|
||||
{
|
||||
if(!figures) return [];
|
||||
if((index >= savedFigures.length) || (index < 0)) return;
|
||||
|
||||
let i = 0;
|
||||
const [ figure, gender ] = savedFigures[index];
|
||||
|
||||
loadAvatarInEditor(figure, gender);
|
||||
}, [ savedFigures, loadAvatarInEditor ]);
|
||||
|
||||
const saveFigureAtWardrobeIndex = useCallback((index: number) =>
|
||||
{
|
||||
if(!figureData || (index >= savedFigures.length) || (index < 0)) return;
|
||||
|
||||
const newFigures = [ ...savedFigures ];
|
||||
|
||||
const figure = figureData.getFigureString();
|
||||
const gender = figureData.gender;
|
||||
|
||||
newFigures[index] = [ figure, gender ];
|
||||
|
||||
setSavedFigures(newFigures);
|
||||
SendMessageHook(new UserWardrobeSaveComposer((index + 1), figure, gender));
|
||||
}, [ figureData, savedFigures, setSavedFigures ]);
|
||||
|
||||
const figures = useMemo(() =>
|
||||
{
|
||||
if(!savedFigures) return [];
|
||||
|
||||
const items: JSX.Element[] = [];
|
||||
|
||||
while(i < figures.length)
|
||||
{
|
||||
const figure = figures[i];
|
||||
|
||||
let figureString = null;
|
||||
let gender = null;
|
||||
|
||||
if(figure)
|
||||
savedFigures.forEach((figure, index) =>
|
||||
{
|
||||
figureString = (figure[0] || null);
|
||||
gender = (figure[1] || null);
|
||||
}
|
||||
let figureString = null;
|
||||
let gender = null;
|
||||
|
||||
items.push(
|
||||
<NitroCardGridItemView key={ i } columns={ 2 }>
|
||||
<AvatarImageView figure={ figureString } gender={ gender } />
|
||||
</NitroCardGridItemView>
|
||||
);
|
||||
|
||||
i++
|
||||
}
|
||||
if(figure)
|
||||
{
|
||||
figureString = (figure[0] || null);
|
||||
gender = (figure[1] || null);
|
||||
}
|
||||
|
||||
items.push(
|
||||
<NitroCardGridItemView key={ index } className="flex-column justify-content-end">
|
||||
{ figureString && <AvatarImageView figure={ figureString } gender={ gender } direction={ 2 } /> }
|
||||
<div className="d-flex w-100 figure-button-container p-1">
|
||||
<Button variant="link" size="sm" className="w-100" onClick={ event => saveFigureAtWardrobeIndex(index) }>Save</Button>
|
||||
{ figureString && <Button variant="link" size="sm" className="w-100" onClick={ event => wearFigureAtIndex(index) }>Use</Button> }
|
||||
</div>
|
||||
</NitroCardGridItemView>
|
||||
);
|
||||
});
|
||||
|
||||
return items;
|
||||
}, [ figures ]);
|
||||
|
||||
console.log(figures.length);
|
||||
}, [ savedFigures, saveFigureAtWardrobeIndex, wearFigureAtIndex ]);
|
||||
|
||||
return (
|
||||
<div className="row h-100">
|
||||
<div className="col-12 d-flex h-100">
|
||||
<NitroCardGridView className="wardrobe-grid" columns={ 12 } theme={ NitroCardGridThemes.THEME_DEFAULT }>
|
||||
{ savedFigures }
|
||||
<NitroCardGridView className="wardrobe-grid" columns={ 5 } theme={ NitroCardGridThemes.THEME_DEFAULT }>
|
||||
{ figures }
|
||||
</NitroCardGridView>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,4 +1,10 @@
|
||||
import { Dispatch, SetStateAction } from 'react';
|
||||
import { FigureData } from '../../common/FigureData';
|
||||
|
||||
export interface AvatarEditorWardrobeViewProps
|
||||
{
|
||||
figures: [ string, string ][];
|
||||
figureData: FigureData;
|
||||
savedFigures: [ string, string ][];
|
||||
setSavedFigures: Dispatch<SetStateAction<[ string, string][]>>;
|
||||
loadAvatarInEditor: (figure: string, gender: string, reset?: boolean) => void;
|
||||
}
|
||||
|
@ -127,11 +127,11 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||
type: CatalogActions.SET_SUBSCRIPTION_INFO,
|
||||
payload: {
|
||||
subscriptionInfo: new SubscriptionInfo(
|
||||
Math.max(0, parser.days),
|
||||
Math.max(0, parser.months),
|
||||
Math.max(0, parser.daysToPeriodEnd),
|
||||
Math.max(0, parser.periodsSubscribedAhead),
|
||||
parser.isVip,
|
||||
parser.pastClubDays,
|
||||
parser.pastVIPDays
|
||||
parser.pastVipDays
|
||||
)
|
||||
}
|
||||
});
|
||||
@ -149,8 +149,6 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
console.log(parser);
|
||||
|
||||
dispatchCatalogState({
|
||||
type: CatalogActions.SET_GIFT_CONFIGURATION,
|
||||
payload: {
|
||||
|
@ -1,7 +1,6 @@
|
||||
import { CatalogModeComposer, CatalogRequestGiftConfigurationComposer, ICatalogPageData, RoomPreviewer } from 'nitro-renderer';
|
||||
import { CatalogModeComposer, CatalogPageComposer, CatalogRequestGiftConfigurationComposer, ICatalogPageData, ILinkEventTracker, RoomPreviewer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||
import { GetRoomEngine } from '../../api';
|
||||
import { GetCatalogPageComposer } from '../../api/catalog/GetCatalogPageComposer';
|
||||
import { AddEventLinkTracker, GetRoomEngine, RemoveLinkEventTracker } from '../../api';
|
||||
import { CatalogEvent } from '../../events';
|
||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||
@ -9,6 +8,7 @@ import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, Nitro
|
||||
import { LocalizeText } from '../../utils/LocalizeText';
|
||||
import { CatalogMessageHandler } from './CatalogMessageHandler';
|
||||
import { CatalogMode, CatalogViewProps } from './CatalogView.types';
|
||||
import { GetCatalogPageTree } from './common/CatalogUtilities';
|
||||
import { CatalogContextProvider } from './context/CatalogContext';
|
||||
import { CatalogActions, CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
||||
import { CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
||||
@ -18,8 +18,10 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
||||
const [ pendingPageId, setPendingPageId ] = useState(-1);
|
||||
const [ pendingTree, setPendingTree ] = useState<ICatalogPageData[]>(null);
|
||||
const [ catalogState, dispatchCatalogState ] = useReducer(CatalogReducer, initialCatalog);
|
||||
const { root = null, currentTab = null, pageParser = null, activeOffer = null, searchResult = null } = catalogState;
|
||||
const { root = null, currentTab = null, pageParser = null, activeOffer = null, searchResult = null} = catalogState;
|
||||
|
||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||
{
|
||||
@ -42,22 +44,99 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
||||
useUiEvent(CatalogEvent.TOGGLE_CATALOG, onCatalogEvent);
|
||||
useUiEvent(CatalogEvent.CATALOG_RESET, onCatalogEvent);
|
||||
|
||||
const setCurrentTab = useCallback((page: ICatalogPageData) =>
|
||||
{
|
||||
dispatchCatalogState({
|
||||
type: CatalogActions.SET_CATALOG_CURRENT_TAB,
|
||||
payload: {
|
||||
currentTab: page
|
||||
}
|
||||
});
|
||||
}, [ dispatchCatalogState ]);
|
||||
|
||||
const buildCatalogPageTree = useCallback((page: ICatalogPageData, targetPageId: number) =>
|
||||
{
|
||||
const pageTree: ICatalogPageData[] = [];
|
||||
|
||||
GetCatalogPageTree(page, targetPageId, pageTree);
|
||||
|
||||
if(pageTree.length) pageTree.reverse();
|
||||
|
||||
return pageTree;
|
||||
}, []);
|
||||
|
||||
const linkReceived = useCallback((url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
if(parts.length < 2) return;
|
||||
|
||||
switch(parts[1])
|
||||
{
|
||||
case 'open':
|
||||
if(parts.length > 2)
|
||||
{
|
||||
dispatchCatalogState({
|
||||
type: CatalogActions.SET_PENDING_PAGE_ID,
|
||||
payload: {
|
||||
pendingPageId: parseInt(parts[2])
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
setIsVisible(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}, [ dispatchCatalogState ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible) return;
|
||||
|
||||
if(!catalogState.root)
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived,
|
||||
eventUrlPrefix: 'catalog/'
|
||||
};
|
||||
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const loadCatalog = (((pendingPageId > -1) && !catalogState.root) || (isVisible && !catalogState.root));
|
||||
|
||||
if(loadCatalog)
|
||||
{
|
||||
SendMessageHook(new CatalogModeComposer(CatalogMode.MODE_NORMAL));
|
||||
SendMessageHook(new CatalogRequestGiftConfigurationComposer());
|
||||
}
|
||||
}, [ isVisible, catalogState.root ]);
|
||||
|
||||
if(catalogState.root)
|
||||
{
|
||||
if(!isVisible && (pendingPageId > -1))
|
||||
{
|
||||
setIsVisible(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(pendingPageId > -1)
|
||||
{
|
||||
const tree = buildCatalogPageTree(catalogState.root, pendingPageId);
|
||||
|
||||
setCurrentTab(tree.shift());
|
||||
setPendingTree(tree);
|
||||
}
|
||||
}
|
||||
}, [ isVisible, pendingPageId, catalogState.root, buildCatalogPageTree, setCurrentTab ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!currentTab) return;
|
||||
|
||||
SendMessageHook(GetCatalogPageComposer(currentTab.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
SendMessageHook(new CatalogPageComposer(currentTab.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
}, [ currentTab ]);
|
||||
|
||||
useEffect(() =>
|
||||
@ -75,16 +154,6 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
||||
}
|
||||
}, []);
|
||||
|
||||
const setCurrentTab = useCallback((page: ICatalogPageData) =>
|
||||
{
|
||||
dispatchCatalogState({
|
||||
type: CatalogActions.SET_CATALOG_CURRENT_TAB,
|
||||
payload: {
|
||||
currentTab: page
|
||||
}
|
||||
});
|
||||
}, [ dispatchCatalogState ]);
|
||||
|
||||
const currentNavigationPage = ((searchResult && searchResult.page) || currentTab);
|
||||
|
||||
return (
|
||||
@ -105,7 +174,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
||||
</NitroCardTabsView>
|
||||
<NitroCardContentView>
|
||||
<div className="row h-100">
|
||||
{ pageParser && !pageParser.frontPageItems.length &&
|
||||
{ (!pageParser || (pageParser && !pageParser.frontPageItems.length)) &&
|
||||
<div className="col-3 d-flex flex-column h-100">
|
||||
<CatalogNavigationView page={ currentNavigationPage } />
|
||||
</div> }
|
||||
|
@ -149,3 +149,20 @@ export function GetPetAvailableColors(petIndex: number, palettes: SellablePetPal
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export function GetCatalogPageTree(page: ICatalogPageData, targetPageId: number, tree: ICatalogPageData[])
|
||||
{
|
||||
if(page.pageId === targetPageId) return page;
|
||||
|
||||
for(const pageData of page.children)
|
||||
{
|
||||
const foundPageData = GetCatalogPageTree(pageData, targetPageId, tree);
|
||||
|
||||
if(foundPageData)
|
||||
{
|
||||
tree.push(pageData);
|
||||
|
||||
return pageData;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../../../api';
|
||||
import { IPurse } from './IPurse';
|
||||
|
||||
export class Purse implements IPurse
|
||||
@ -22,7 +22,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set credits(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._credits = k;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set clubDays(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._clubDays = k;
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set clubPeriods(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._clubPeriods = k;
|
||||
}
|
||||
|
||||
@ -80,7 +80,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set _Str_6288(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._pastClubDays = k;
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set _Str_4605(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._pastVipDays = k;
|
||||
}
|
||||
|
||||
@ -102,7 +102,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set _Str_18527(k: Map<number, number>)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._activityPoints = k;
|
||||
}
|
||||
|
||||
@ -113,14 +113,14 @@ export class Purse implements IPurse
|
||||
|
||||
public set _Str_4458(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
|
||||
this._minutesUntilExpiration = k;
|
||||
}
|
||||
|
||||
public get _Str_4458(): number
|
||||
{
|
||||
const k = ((Nitro.instance.time - this._lastUpdated) / (1000 * 60));
|
||||
const k = ((GetNitroInstance().time - this._lastUpdated) / (1000 * 60));
|
||||
const _local_2 = (this._minutesUntilExpiration - k);
|
||||
|
||||
return (_local_2 > 0) ? _local_2 : 0;
|
||||
@ -128,7 +128,7 @@ export class Purse implements IPurse
|
||||
|
||||
public set _Str_6312(k: number)
|
||||
{
|
||||
this._lastUpdated = Nitro.instance.time;
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._minutesSinceLastModified = k;
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,7 @@ export interface ICatalogState
|
||||
clubOffers: CatalogClubOfferData[];
|
||||
subscriptionInfo: SubscriptionInfo;
|
||||
giftConfiguration: GiftWrappingConfiguration;
|
||||
pendingPageId: number;
|
||||
}
|
||||
|
||||
export interface ICatalogAction
|
||||
@ -37,6 +38,7 @@ export interface ICatalogAction
|
||||
clubOffers?: CatalogClubOfferData[];
|
||||
subscriptionInfo?: SubscriptionInfo;
|
||||
giftConfiguration?: CatalogGiftConfigurationParser;
|
||||
pendingPageId?: number;
|
||||
}
|
||||
}
|
||||
|
||||
@ -54,6 +56,7 @@ export class CatalogActions
|
||||
public static SET_SEARCH_RESULT: string = 'CA_SET_SEARCH_RESULT';
|
||||
public static SET_SUBSCRIPTION_INFO: string = 'CA_SET_SUBSCRIPTION_INFO';
|
||||
public static SET_GIFT_CONFIGURATION: string = 'CA_SET_GIFT_CONFIGURATION';
|
||||
public static SET_PENDING_PAGE_ID: string = 'CA_SET_PENDING_PAGE_ID';
|
||||
}
|
||||
|
||||
export const initialCatalog: ICatalogState = {
|
||||
@ -68,7 +71,8 @@ export const initialCatalog: ICatalogState = {
|
||||
petPalettes: [],
|
||||
clubOffers: null,
|
||||
subscriptionInfo: new SubscriptionInfo(),
|
||||
giftConfiguration: null
|
||||
giftConfiguration: null,
|
||||
pendingPageId: -1
|
||||
}
|
||||
|
||||
export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, action) =>
|
||||
@ -168,6 +172,11 @@ export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, ac
|
||||
|
||||
return { ...state, giftConfiguration };
|
||||
}
|
||||
case CatalogActions.SET_PENDING_PAGE_ID: {
|
||||
const pendingPageId = (action.payload.pendingPageId || -1);
|
||||
|
||||
return { ...state, pendingPageId };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
import { CatalogPageComposer, ICatalogPageData } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useState } from 'react';
|
||||
import { GetCatalogPageComposer } from '../../../../../api/catalog/GetCatalogPageComposer';
|
||||
import { SendMessageHook } from '../../../../../hooks/messages/message-event';
|
||||
import { CatalogMode } from '../../../CatalogView.types';
|
||||
import { useCatalogContext } from '../../../context/CatalogContext';
|
||||
import { CatalogIconView } from '../../catalog-icon/CatalogIconView';
|
||||
import { CatalogNavigationSetView } from '../set/CatalogNavigationSetView';
|
||||
import { CatalogNavigationItemViewProps } from './CatalogNavigationItemView.types';
|
||||
@ -10,42 +11,46 @@ export const CatalogNavigationItemView: FC<CatalogNavigationItemViewProps> = pro
|
||||
{
|
||||
const { page = null, isActive = false, setActiveChild = null } = props;
|
||||
const [ isExpanded, setIsExpanded ] = useState(false);
|
||||
const [ myTree, setMyTree ] = useState<ICatalogPageData[]>(null);
|
||||
const { dispatchCatalogState = null } = useCatalogContext();
|
||||
|
||||
useEffect(() =>
|
||||
const select = useCallback((selectPage: ICatalogPageData) =>
|
||||
{
|
||||
if(!isActive || !page) return;
|
||||
|
||||
setIsExpanded(true);
|
||||
|
||||
SendMessageHook(GetCatalogPageComposer(page.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
}, [ isActive, page ]);
|
||||
|
||||
const select = useCallback(() =>
|
||||
{
|
||||
if(!page) return;
|
||||
if(!selectPage) return;
|
||||
|
||||
setActiveChild(prevValue =>
|
||||
{
|
||||
if(prevValue === page)
|
||||
if(prevValue === selectPage)
|
||||
{
|
||||
SendMessageHook(GetCatalogPageComposer(page.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
SendMessageHook(new CatalogPageComposer(selectPage.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
}
|
||||
|
||||
return page;
|
||||
return selectPage;
|
||||
});
|
||||
|
||||
if(page.children && page.children.length)
|
||||
if(selectPage.children && selectPage.children.length)
|
||||
{
|
||||
setIsExpanded(prevValue =>
|
||||
{
|
||||
return !prevValue;
|
||||
});
|
||||
}
|
||||
}, [ page, setActiveChild ]);
|
||||
}, [ setActiveChild ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isActive || !page) return;
|
||||
|
||||
setIsExpanded(true);
|
||||
|
||||
SendMessageHook(new CatalogPageComposer(page.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||
}, [ isActive, page, select, dispatchCatalogState ]);
|
||||
|
||||
if(!page.visible) return null;
|
||||
|
||||
return (
|
||||
<div className="col pb-1 catalog-navigation-item-container">
|
||||
<div className={ 'd-flex align-items-center cursor-pointer catalog-navigation-item ' + (isActive ? 'active ': '') } onClick={ select }>
|
||||
<div className={ 'd-flex align-items-center cursor-pointer catalog-navigation-item ' + (isActive ? 'active ': '') } onClick={ event => select(page) }>
|
||||
<CatalogIconView icon={ page.icon } />
|
||||
<div className="flex-grow-1 text-black text-truncate px-1">{ page.localization }</div>
|
||||
{ (page.children.length > 0) && <i className={ 'fas fa-caret-' + (isExpanded ? 'up' : 'down') } /> }
|
||||
|
@ -1,3 +1,4 @@
|
||||
@import './badge-display/CatalogLayoutBadgeDisplayView';
|
||||
@import './default/CatalogLayoutDefaultView';
|
||||
@import './frontpage4/CatalogLayoutFrontpage4View';
|
||||
@import './pets/CatalogLayoutPetView';
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ICatalogPageParser, RoomPreviewer } from 'nitro-renderer';
|
||||
import { CatalogLayoutBadgeDisplayView } from './badge-display/CatalogLayoutBadgeDisplayView';
|
||||
import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView';
|
||||
import { CatalogLayoutFrontpage4View } from './frontpage4/CatalogLayoutFrontpage4View';
|
||||
import { CatalogLayouGuildCustomFurniView } from './guild-custom-furni/CatalogLayoutGuildCustomFurniView';
|
||||
@ -47,9 +48,11 @@ export const GetCatalogLayout = (pageParser: ICatalogPageParser, roomPreviewer:
|
||||
case 'spaces_new':
|
||||
return <CatalogLayoutSpacesView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||
case 'trophies':
|
||||
return <CatalogLayoutTrophiesView roomPreviewer={roomPreviewer} pageParser={pageParser} />;
|
||||
return <CatalogLayoutTrophiesView roomPreviewer={roomPreviewer} pageParser={ pageParser } />;
|
||||
case 'info_loyalty':
|
||||
return <CatalogLayoutInfoLoyaltyView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||
case 'badge_display':
|
||||
return <CatalogLayoutBadgeDisplayView roomPreviewer={roomPreviewer} pageParser={ pageParser } />;
|
||||
case 'bots':
|
||||
case 'default_3x3':
|
||||
default:
|
||||
|
@ -0,0 +1,7 @@
|
||||
.nitro-catalog-layout-badge-display {
|
||||
|
||||
.inventory-badge-grid {
|
||||
height: 200px;
|
||||
max-height: 200px;
|
||||
}
|
||||
}
|
@ -0,0 +1,80 @@
|
||||
import { StringDataType } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { InventoryBadgesUpdatedEvent } from '../../../../../../events';
|
||||
import { InventoryBadgesRequestEvent } from '../../../../../../events/inventory/InventoryBadgesRequestEvent';
|
||||
import { dispatchUiEvent, useUiEvent } from '../../../../../../hooks';
|
||||
import { NitroCardGridItemView } from '../../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||
import { NitroCardGridView } from '../../../../../../layout/card/grid/NitroCardGridView';
|
||||
import { BadgeImageView } from '../../../../../shared/badge-image/BadgeImageView';
|
||||
import { GetOfferName } from '../../../../common/CatalogUtilities';
|
||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||
import { CatalogRoomPreviewerView } from '../../../catalog-room-previewer/CatalogRoomPreviewerView';
|
||||
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
|
||||
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
|
||||
import { CatalogLayoutBadgeDisplayViewProps } from './CatalogLayoutBadgeDisplayView.types';
|
||||
|
||||
export const CatalogLayoutBadgeDisplayView: FC<CatalogLayoutBadgeDisplayViewProps> = props =>
|
||||
{
|
||||
const { roomPreviewer = null, pageParser = null } = props;
|
||||
const { catalogState = null, dispatchCatalogState = null } = useCatalogContext();
|
||||
const { activeOffer = null } = catalogState;
|
||||
const [ currentBadge, setCurrentBadge ] = useState<string>(null);
|
||||
const [ badges, setBadges ] = useState<string[]>([]);
|
||||
|
||||
const product = ((activeOffer && activeOffer.products[0]) || null);
|
||||
|
||||
const onInventoryBadgesUpdatedEvent = useCallback((event: InventoryBadgesUpdatedEvent) =>
|
||||
{
|
||||
console.log(event);
|
||||
setBadges(event.badges);
|
||||
}, []);
|
||||
|
||||
useUiEvent(InventoryBadgesUpdatedEvent.BADGES_UPDATED, onInventoryBadgesUpdatedEvent);
|
||||
|
||||
const badgeElements = useMemo(() =>
|
||||
{
|
||||
return badges.map(code =>
|
||||
{
|
||||
return (
|
||||
<NitroCardGridItemView key={ code } itemActive={ (currentBadge === code) } onMouseDown={ event => setCurrentBadge(code) }>
|
||||
<BadgeImageView badgeCode={ code } />
|
||||
</NitroCardGridItemView>
|
||||
);
|
||||
});
|
||||
}, [ badges, currentBadge ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
dispatchUiEvent(new InventoryBadgesRequestEvent(InventoryBadgesRequestEvent.REQUEST_BADGES));
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!currentBadge || !activeOffer) return;
|
||||
|
||||
const stuffData = new StringDataType();
|
||||
|
||||
stuffData.setValue([ null, currentBadge ]);
|
||||
|
||||
roomPreviewer.updateObjectStuffData(stuffData);
|
||||
}, [ currentBadge, activeOffer, roomPreviewer ]);
|
||||
|
||||
return (
|
||||
<div className="row h-100 nitro-catalog-layout-badge-display">
|
||||
<div className="d-flex flex-column col-7 h-100">
|
||||
<CatalogPageOffersView offers={ pageParser.offers } />
|
||||
<div className="d-flex mt-2">
|
||||
<NitroCardGridView className="inventory-badge-grid">
|
||||
{ badgeElements }
|
||||
</NitroCardGridView>
|
||||
</div>
|
||||
</div>
|
||||
{ product &&
|
||||
<div className="position-relative d-flex flex-column col">
|
||||
<CatalogRoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
||||
<div className="fs-6 text-black mt-1 overflow-hidden">{ GetOfferName(activeOffer) }</div>
|
||||
<CatalogPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ 'Bill 22-7-2021 ADM' } />
|
||||
</div> }
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||
|
||||
export interface CatalogLayoutBadgeDisplayViewProps extends CatalogLayoutProps
|
||||
{
|
||||
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
.nitro-catalog-layout-vip-buy {
|
||||
|
||||
.catalog-offer-item-container {
|
||||
height: 60px !important;
|
||||
max-height: 60px !important;
|
||||
.vip-buy-grid {
|
||||
|
||||
.grid-item-container {
|
||||
height: 70px !important;
|
||||
max-height: 70px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,11 @@
|
||||
import { CatalogClubOfferData, CatalogRequestVipOffersComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo } from 'react';
|
||||
import { CatalogClubOfferData, CatalogPurchaseComposer, CatalogRequestVipOffersComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { Button } from 'react-bootstrap';
|
||||
import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
|
||||
import { NitroCardGridItemView } from '../../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||
import { NitroCardGridView } from '../../../../../../layout/card/grid/NitroCardGridView';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import { GLOBAL_PURSE } from '../../../../../purse/PurseView';
|
||||
import { CurrencyIcon } from '../../../../../shared/currency-icon/CurrencyIcon';
|
||||
import { GetCatalogPageImage } from '../../../../common/CatalogUtilities';
|
||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||
@ -11,16 +15,7 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
||||
{
|
||||
const { catalogState = null } = useCatalogContext();
|
||||
const { pageParser = null, clubOffers = null, subscriptionInfo = null } = catalogState;
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(clubOffers === null)
|
||||
{
|
||||
SendMessageHook(new CatalogRequestVipOffersComposer(1));
|
||||
|
||||
return;
|
||||
}
|
||||
}, [ clubOffers ]);
|
||||
const [ pendingOffer, setPendingOffer ] = useState<CatalogClubOfferData>(null);
|
||||
|
||||
const getOfferText = useCallback((offer: CatalogClubOfferData) =>
|
||||
{
|
||||
@ -41,6 +36,31 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
||||
return offerText;
|
||||
}, []);
|
||||
|
||||
const getPurchaseHeader = useCallback(() =>
|
||||
{
|
||||
const purse = GLOBAL_PURSE;
|
||||
|
||||
if(!purse) return '';
|
||||
|
||||
const extensionOrSubscription = (purse.clubDays > 0 || purse.clubPeriods > 0) ? 'extension.' : 'subscription.';
|
||||
const daysOrMonths = ((pendingOffer.months === 0) ? 'days' : 'months');
|
||||
const daysOrMonthsText = ((pendingOffer.months === 0) ? pendingOffer.extraDays : pendingOffer.months);
|
||||
const locale = LocalizeText('catalog.vip.buy.confirm.' + extensionOrSubscription + daysOrMonths);
|
||||
|
||||
return locale.replace('%NUM_' + daysOrMonths.toUpperCase() + '%', daysOrMonthsText.toString());
|
||||
}, [ pendingOffer ]);
|
||||
|
||||
const getPurchaseValidUntil = useCallback(() =>
|
||||
{
|
||||
let locale = LocalizeText('catalog.vip.buy.confirm.end_date');
|
||||
|
||||
locale = locale.replace('%month%', pendingOffer.month.toString());
|
||||
locale = locale.replace('%day%', pendingOffer.day.toString());
|
||||
locale = locale.replace('%year%', pendingOffer.year.toString());
|
||||
|
||||
return locale;
|
||||
}, [ pendingOffer ]);
|
||||
|
||||
const getSubscriptionDetails = useMemo(() =>
|
||||
{
|
||||
if(!subscriptionInfo) return '';
|
||||
@ -52,41 +72,100 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
||||
return LocalizeText('catalog.vip.extend.info', [ 'days' ], [ totalDays.toString() ]);
|
||||
}, [ subscriptionInfo ]);
|
||||
|
||||
const purchaseSubscription = useCallback(() =>
|
||||
{
|
||||
if(!pendingOffer) return;
|
||||
|
||||
SendMessageHook(new CatalogPurchaseComposer(pageParser.pageId, pendingOffer.offerId, null, 1));
|
||||
}, [ pendingOffer, pageParser ])
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(clubOffers === null)
|
||||
{
|
||||
SendMessageHook(new CatalogRequestVipOffersComposer(1));
|
||||
|
||||
return;
|
||||
}
|
||||
}, [ clubOffers ]);
|
||||
|
||||
return (
|
||||
<div className="row h-100 nitro-catalog-layout-vip-buy">
|
||||
<div className="col-7 h-100">
|
||||
<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 className="row h-100 nitro-catalog-layout-vip-buy">
|
||||
<div className="col-7 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 justify-content-center align-items-center w-100">
|
||||
<div className="text-black text-small">{ getPurchaseHeader() }</div>
|
||||
<div className="text-black text-small">{ getPurchaseValidUntil() }</div>
|
||||
<Button variant="primary" size="sm" onClick={ purchaseSubscription }>{ LocalizeText('buy') }</Button>
|
||||
</div> }
|
||||
{ (pendingOffer !== offer) &&
|
||||
<>
|
||||
<div className="d-flex flex-column text-black text-small m-1">
|
||||
<div>
|
||||
<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>
|
||||
</div>
|
||||
<Button variant="primary" size="sm" onClick={ event => setPendingOffer(offer) }>{ LocalizeText('buy') }</Button>
|
||||
</> }
|
||||
</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> */}
|
||||
</div>
|
||||
<div className="position-relative d-flex flex-column col-5 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>
|
||||
</div>
|
||||
<div className="position-relative d-flex flex-column col-5 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>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
@ -96,3 +96,4 @@
|
||||
@import './views/widgets/promo-article/PromoArticleWidgetView.scss';
|
||||
@import './views/widgets/bonus-rare/BonusRareWidgetView.scss';
|
||||
@import './views/widgets/hall-of-fame/HallOfFameWidgetView.scss';
|
||||
@import './views/widgets/widgetcontainer/WidgetContainerView.scss'
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Nitro, RoomSessionEvent } from 'nitro-renderer';
|
||||
import { RoomSessionEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetConfiguration } from '../../api';
|
||||
import { GetConfiguration, GetConfigurationManager } from '../../api';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { HotelViewProps } from './HotelView.types';
|
||||
import { WidgetSlotView } from './views/widget-slot/WidgetSlotView';
|
||||
@ -29,12 +29,12 @@ export const HotelView: FC<HotelViewProps> = props =>
|
||||
if (!isVisible) return null;
|
||||
|
||||
const backgroundColor = GetConfiguration('hotelview')['images']['background.colour'];
|
||||
const background = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['background']);
|
||||
const sun = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['sun']);
|
||||
const drape = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['drape']);
|
||||
const left = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['left']);
|
||||
const rightRepeat = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['right.repeat']);
|
||||
const right = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['right']);
|
||||
const background = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['background']);
|
||||
const sun = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['sun']);
|
||||
const drape = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['drape']);
|
||||
const left = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['left']);
|
||||
const rightRepeat = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right.repeat']);
|
||||
const right = GetConfigurationManager().interpolate(GetConfiguration('hotelview')['images']['right']);
|
||||
|
||||
return (
|
||||
<div className="nitro-hotel-view" style={(backgroundColor && backgroundColor) ? { background: backgroundColor } : {}}>
|
||||
@ -44,9 +44,10 @@ export const HotelView: FC<HotelViewProps> = props =>
|
||||
<WidgetSlotView
|
||||
widgetSlot={ 1 }
|
||||
widgetType={GetConfiguration('hotelview')['widgets']['slot.' + 1 + '.widget']}
|
||||
widgetConf={GetConfiguration('hotelview')['widgets']['slot.' + 1 +'.conf']}
|
||||
widgetConf={GetConfiguration('hotelview')['widgets']['slot.' + 1 + '.conf']}
|
||||
className="col-6"
|
||||
/>
|
||||
<div className="row mx-0">
|
||||
<div className="col-12 row mx-0">
|
||||
<WidgetSlotView
|
||||
widgetSlot={ 2 }
|
||||
widgetType={GetConfiguration('hotelview')['widgets']['slot.' + 2 + '.widget']}
|
||||
|
@ -3,6 +3,7 @@ import { BonusRareWidgetView } from './bonus-rare/BonusRareWidgetView';
|
||||
import { GetWidgetLayoutProps } from './GetWidgetLayout.types';
|
||||
import { HallOfFameWidgetView } from './hall-of-fame/HallOfFameWidgetView';
|
||||
import { PromoArticleWidgetView } from './promo-article/PromoArticleWidgetView';
|
||||
import { WidgetContainerView } from './widgetcontainer/WIdgetContainerView';
|
||||
|
||||
export const GetWidgetLayout: FC<GetWidgetLayoutProps> = props =>
|
||||
{
|
||||
@ -14,6 +15,8 @@ export const GetWidgetLayout: FC<GetWidgetLayoutProps> = props =>
|
||||
return <HallOfFameWidgetView slot={props.slot} conf={props.widgetConf} />;
|
||||
case "bonusrare":
|
||||
return <BonusRareWidgetView />;
|
||||
case "widgetcontainer":
|
||||
return <WidgetContainerView conf={props.widgetConf} />
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
@ -37,15 +37,16 @@ export const PromoArticleWidgetView: FC<PromoArticleWidgetViewProps> = props =>
|
||||
</div>
|
||||
<div className="d-flex flex-row mb-1">
|
||||
{articles && (articles.length > 0) && articles.map((article, ind) =>
|
||||
<div className={`promo-articles-bullet ` + (article === articles[index] ? 'promo-articles-bullet-active' : '')} key={article.id} onClick={event => handleSelect(ind)} />
|
||||
<div className={`promo-articles-bullet cursor-pointer ` + (article === articles[index] ? 'promo-articles-bullet-active' : '')} key={article.id} onClick={event => handleSelect(ind)} />
|
||||
)}
|
||||
</div>
|
||||
{articles && articles[index] &&
|
||||
<div className="promo-article d-flex flex-row row mx-0">
|
||||
<div className="promo-article-image" style={ {backgroundImage: `url(${articles[index].imageUrl})`} }/>
|
||||
<div className="col-3">
|
||||
<div className="col-3 d-flex flex-column h-100">
|
||||
<h3 className="my-0">{articles[index].title}</h3>
|
||||
<b>{ articles[index].bodyText }</b>
|
||||
<button className="btn btn-sm mt-auto btn-gainsboro">{ articles[index].buttonText }</button>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
@ -0,0 +1,47 @@
|
||||
import { FC, useCallback, useMemo } from 'react';
|
||||
import { GetConfigurationManager } from '../../../../../api/core/';
|
||||
import { WidgetContainerViewProps } from './WidgetContainerView.types';
|
||||
|
||||
export const WidgetContainerView: FC<WidgetContainerViewProps> = props =>
|
||||
{
|
||||
const { conf = null } = props;
|
||||
|
||||
const config = useMemo(() =>
|
||||
{
|
||||
const config = {};
|
||||
|
||||
if(!conf || !conf.length) return config;
|
||||
|
||||
let options = conf.split(",");
|
||||
|
||||
options.forEach(option =>
|
||||
{
|
||||
let [ key, value ] = option.split(':');
|
||||
|
||||
if(key && value) config[key] = value;
|
||||
});
|
||||
|
||||
return config;
|
||||
}, [ conf ]);
|
||||
|
||||
const getOption = useCallback((key: string) =>
|
||||
{
|
||||
const option = config[key];
|
||||
|
||||
if(!option) return null;
|
||||
|
||||
switch(key)
|
||||
{
|
||||
case 'image':
|
||||
return GetConfigurationManager().interpolate(option);
|
||||
}
|
||||
|
||||
return option;
|
||||
}, [ config ]);
|
||||
|
||||
return (
|
||||
<div className="widgetcontainer widget">
|
||||
{ getOption('image') }
|
||||
</div>
|
||||
);
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export interface WidgetContainerViewProps
|
||||
{
|
||||
conf: string;
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
import { AdvancedMap, BadgesEvent, BotAddedToInventoryEvent, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent, PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, TradingAcceptEvent, TradingCloseEvent, TradingCompletedEvent, TradingConfirmationEvent, TradingListItemEvent, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingYouAreNotAllowedEvent, UnseenItemsEvent } from 'nitro-renderer';
|
||||
import { AdvancedMap, BadgeReceivedEvent, BadgesEvent, BotAddedToInventoryEvent, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent, PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, RequestBadgesComposer, TradingAcceptEvent, TradingCloseEvent, TradingCompletedEvent, TradingConfirmationEvent, TradingListItemEvent, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingYouAreNotAllowedEvent, UnseenItemsEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { GetRoomSession, GetSessionDataManager } from '../../api';
|
||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||
import { InventoryBadgesUpdatedEvent } from '../../events';
|
||||
import { InventoryBadgesRequestEvent } from '../../events/inventory/InventoryBadgesRequestEvent';
|
||||
import { dispatchUiEvent, useUiEvent } from '../../hooks';
|
||||
import { CreateMessageHook, SendMessageHook } from '../../hooks/messages/message-event';
|
||||
import { mergeFurniFragments } from './common/FurnitureUtilities';
|
||||
import { mergePetFragments } from './common/PetUtilities';
|
||||
import { TradeState } from './common/TradeState';
|
||||
@ -17,7 +20,7 @@ let petMsgFragments: Map<number, PetData>[] = null;
|
||||
|
||||
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =>
|
||||
{
|
||||
const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, dispatchBadgeState = null, unseenTracker = null } = useInventoryContext();
|
||||
const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, badgeState = null, dispatchBadgeState = null, unseenTracker = null } = useInventoryContext();
|
||||
|
||||
const onFurnitureListAddOrUpdateEvent = useCallback((event: FurnitureListAddOrUpdateEvent) =>
|
||||
{
|
||||
@ -163,6 +166,18 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
||||
});
|
||||
}, [ dispatchBadgeState ]);
|
||||
|
||||
const onBadgeReceivedEvent = useCallback((event: BadgeReceivedEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchBadgeState({
|
||||
type: InventoryBadgeActions.ADD_BADGE,
|
||||
payload: {
|
||||
badgeCode: parser.badgeCode
|
||||
}
|
||||
});
|
||||
}, [ dispatchBadgeState ]);
|
||||
|
||||
const onTradingAcceptEvent = useCallback((event: TradingAcceptEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
@ -318,6 +333,7 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
||||
CreateMessageHook(PetRemovedFromInventory, onPetRemovedFromInventory);
|
||||
CreateMessageHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
|
||||
CreateMessageHook(BadgesEvent, onBadgesEvent);
|
||||
CreateMessageHook(BadgeReceivedEvent, onBadgeReceivedEvent);
|
||||
CreateMessageHook(TradingAcceptEvent, onTradingAcceptEvent);
|
||||
CreateMessageHook(TradingCloseEvent, onTradingCloseEvent);
|
||||
CreateMessageHook(TradingCompletedEvent, onTradingCompletedEvent);
|
||||
@ -330,5 +346,19 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
||||
CreateMessageHook(TradingYouAreNotAllowedEvent, onTradingYouAreNotAllowedEvent);
|
||||
CreateMessageHook(UnseenItemsEvent, onUnseenItemsEvent);
|
||||
|
||||
const onInventoryBadgesRequestEvent = useCallback((event: InventoryBadgesRequestEvent) =>
|
||||
{
|
||||
if(badgeState.needsBadgeUpdate)
|
||||
{
|
||||
SendMessageHook(new RequestBadgesComposer());
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
dispatchUiEvent(new InventoryBadgesUpdatedEvent(InventoryBadgesUpdatedEvent.BADGES_UPDATED, badgeState.badges));
|
||||
}, [ badgeState ])
|
||||
|
||||
useUiEvent(InventoryBadgesRequestEvent.REQUEST_BADGES, onInventoryBadgesRequestEvent);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
@ -1,10 +1,10 @@
|
||||
import { IRoomSession, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomPreviewer, RoomSessionEvent, TradingCancelComposer, TradingCloseComposer, TradingOpenComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||
import { GetRoomEngine } from '../../api';
|
||||
import { InventoryEvent, InventoryTradeRequestEvent } from '../../events';
|
||||
import { InventoryBadgesUpdatedEvent, InventoryEvent, InventoryTradeRequestEvent } from '../../events';
|
||||
import { useRoomEngineEvent } from '../../hooks/events/nitro/room/room-engine-event';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
import { SendMessageHook } from '../../hooks/messages';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout';
|
||||
import { LocalizeText } from '../../utils/LocalizeText';
|
||||
@ -186,6 +186,13 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
||||
}
|
||||
}, [ furnitureState.tradeData, isVisible ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!badgeState.badges) return;
|
||||
|
||||
dispatchUiEvent(new InventoryBadgesUpdatedEvent(InventoryBadgesUpdatedEvent.BADGES_UPDATED, badgeState.badges));
|
||||
}, [ badgeState.badges ]);
|
||||
|
||||
return (
|
||||
<InventoryContextProvider value={ { furnitureState, dispatchFurnitureState, botState, dispatchBotState, petState, dispatchPetState, badgeState, dispatchBadgeState, unseenTracker } }>
|
||||
<InventoryMessageHandler />
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { IFurnitureItemData, IObjectData, Nitro } from 'nitro-renderer';
|
||||
import { IFurnitureItemData, IObjectData } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../../../api';
|
||||
import { IFurnitureItem } from './IFurnitureItem';
|
||||
|
||||
export class FurnitureItem implements IFurnitureItem
|
||||
@ -122,7 +123,7 @@ export class FurnitureItem implements IFurnitureItem
|
||||
|
||||
if(this._hasRentPeriodStarted)
|
||||
{
|
||||
time = (this._secondsToExpiration - ((Nitro.instance.time - this._expirationTimeStamp) / 1000));
|
||||
time = (this._secondsToExpiration - ((GetNitroInstance().time - this._expirationTimeStamp) / 1000));
|
||||
|
||||
if(time < 0) time = 0;
|
||||
}
|
||||
|
@ -23,11 +23,12 @@ export interface IInventoryBadgeAction
|
||||
|
||||
export class InventoryBadgeActions
|
||||
{
|
||||
public static SET_NEEDS_UPDATE: string = 'IBDA_SET_NEEDS_UPDATE';
|
||||
public static SET_BADGE: string = 'IBDA_SET_BADGE';
|
||||
public static SET_BADGES: string = 'IBDA_SET_BADGES';
|
||||
public static ADD_ACTIVE_BADGE: string = 'IBDA_ADD_ACTIVE_BADGE';
|
||||
public static REMOVE_ACTIVE_BADGE: string = 'IBDA_REMOVE_ACTIVE_BADGE';
|
||||
public static SET_NEEDS_UPDATE: string = 'IBA_SET_NEEDS_UPDATE';
|
||||
public static SET_BADGE: string = 'IBA_SET_BADGE';
|
||||
public static SET_BADGES: string = 'IBA_SET_BADGES';
|
||||
public static ADD_BADGE: string = 'IBA_ADD_BADGE';
|
||||
public static ADD_ACTIVE_BADGE: string = 'IBA_ADD_ACTIVE_BADGE';
|
||||
public static REMOVE_ACTIVE_BADGE: string = 'IBA_REMOVE_ACTIVE_BADGE';
|
||||
}
|
||||
|
||||
export const initialInventoryBadge: IInventoryBadgeState = {
|
||||
@ -77,6 +78,14 @@ export const InventoryBadgeReducer: Reducer<IInventoryBadgeState, IInventoryBadg
|
||||
|
||||
return { ...state, badges, activeBadges };
|
||||
}
|
||||
case InventoryBadgeActions.ADD_BADGE: {
|
||||
const badges = [ ...state.badges ];
|
||||
const badge = (action.payload.badgeCode);
|
||||
|
||||
if(badges.indexOf(badge) === -1) badges.push(badge);
|
||||
|
||||
return { ...state, badges };
|
||||
}
|
||||
case InventoryBadgeActions.ADD_ACTIVE_BADGE: {
|
||||
const badgeCode = action.payload.badgeCode;
|
||||
|
||||
|
@ -19,6 +19,7 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
|
||||
{
|
||||
if(needsBadgeUpdate)
|
||||
{
|
||||
console.log('yee')
|
||||
dispatchBadgeState({
|
||||
type: InventoryBadgeActions.SET_NEEDS_UPDATE,
|
||||
payload: {
|
||||
|
@ -1,5 +1,6 @@
|
||||
import { Nitro, RoomSessionEvent } from 'nitro-renderer';
|
||||
import { RoomSessionEvent } from '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 { AchievementsView } from '../achievements/AchievementsView';
|
||||
import { AvatarEditorView } from '../avatar-editor/AvatarEditorView';
|
||||
@ -41,7 +42,7 @@ export const MainView: FC<MainViewProps> = props =>
|
||||
{
|
||||
setIsReady(true);
|
||||
|
||||
Nitro.instance.communication.connection.onReady();
|
||||
GetCommunication().connection.onReady();
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
@ -1,5 +1,7 @@
|
||||
import { NavigatorInitComposer, NavigatorSearchComposer, RoomSessionEvent } from 'nitro-renderer';
|
||||
import { ILinkEventTracker, NavigatorInitComposer, NavigatorSearchComposer, RoomSessionEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||
import { AddEventLinkTracker, RemoveLinkEventTracker } from '../../api';
|
||||
import { TryVisitRoom } from '../../api/navigator/TryVisitRoom';
|
||||
import { NavigatorEvent } from '../../events';
|
||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||
@ -73,6 +75,45 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
||||
SendMessageHook(new NavigatorSearchComposer(contextCode, searchValue));
|
||||
}, []);
|
||||
|
||||
const linkReceived = useCallback((url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
if(parts.length < 2) return;
|
||||
|
||||
switch(parts[1])
|
||||
{
|
||||
case 'goto':
|
||||
if(parts.length > 2)
|
||||
{
|
||||
switch(parts[2])
|
||||
{
|
||||
case 'home':
|
||||
//goToHomeRoom();
|
||||
break;
|
||||
default: {
|
||||
const roomId = parseInt(parts[2]);
|
||||
|
||||
TryVisitRoom(roomId);
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}, []);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived,
|
||||
eventUrlPrefix: 'navigator/'
|
||||
};
|
||||
|
||||
AddEventLinkTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ linkReceived]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible || !needsNavigatorUpdate) return;
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { Nitro } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetConfiguration } from '../../../../api';
|
||||
import { GetConfiguration, GetNitroInstance } from '../../../../api';
|
||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../layout';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { useNavigatorContext } from '../../context/NavigatorContext';
|
||||
@ -26,7 +25,7 @@ export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
|
||||
setRoomThumbnail(GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
|
||||
}
|
||||
|
||||
const roomLinkRaw = Nitro.instance.core.configuration.interpolate(LocalizeText('navigator.embed.src', ['roomId'], [roomInfoData.enteredGuestRoom.roomId.toString()]));
|
||||
const roomLinkRaw = GetNitroInstance().core.configuration.interpolate(LocalizeText('navigator.embed.src', ['roomId'], [roomInfoData.enteredGuestRoom.roomId.toString()]));
|
||||
|
||||
setRoomLink(roomLinkRaw);
|
||||
}, [ roomInfoData ]);
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
.content-area {
|
||||
min-height: 125px;
|
||||
max-height: 300px;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,69 +1,59 @@
|
||||
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent, UserSubscriptionEvent } from 'nitro-renderer';
|
||||
import { UserCreditsEvent, UserCurrencyEvent, UserCurrencyUpdateEvent, UserSubscriptionEvent, UserSubscriptionParser } from 'nitro-renderer';
|
||||
import { FC, useCallback } from 'react';
|
||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||
import { Currency } from './common/Currency';
|
||||
import { usePurseContext } from './context/PurseContext';
|
||||
import { PurseMessageHandlerProps } from './PurseMessageHandler.types';
|
||||
import { PurseActions } from './reducers/PurseReducer';
|
||||
|
||||
export const PurseMessageHandler: FC<PurseMessageHandlerProps> = props =>
|
||||
{
|
||||
const { dispatchPurseState = null } = usePurseContext();
|
||||
const { purse = null } = usePurseContext();
|
||||
|
||||
const onUserCreditsEvent = useCallback((event: UserCreditsEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchPurseState({
|
||||
type: PurseActions.SET_CURRENCY,
|
||||
payload: {
|
||||
currency: { type: -1, amount: parseFloat(parser.credits) }
|
||||
}
|
||||
});
|
||||
}, [ dispatchPurseState ]);
|
||||
purse.credits = parseFloat(parser.credits);
|
||||
|
||||
purse.notify();
|
||||
}, [ purse ]);
|
||||
|
||||
const onUserCurrencyEvent = useCallback((event: UserCurrencyEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
const currencies: Currency[] = [];
|
||||
purse.activityPoints = parser.currencies;
|
||||
|
||||
for(const [ key, value ] of parser.currencies.entries()) currencies.push({ type: key, amount: value });
|
||||
|
||||
dispatchPurseState({
|
||||
type: PurseActions.SET_CURRENCIES,
|
||||
payload: { currencies }
|
||||
});
|
||||
}, [ dispatchPurseState ]);
|
||||
purse.notify();
|
||||
}, [ purse ]);
|
||||
|
||||
const onUserCurrencyUpdateEvent = useCallback((event: UserCurrencyUpdateEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
dispatchPurseState({
|
||||
type: PurseActions.SET_CURRENCY,
|
||||
payload: {
|
||||
currency: { type: parser.type, amount: parser.amount }
|
||||
}
|
||||
});
|
||||
}, [ dispatchPurseState ]);
|
||||
purse.activityPoints.set(parser.type, parser.amount);
|
||||
|
||||
purse.notify();
|
||||
}, [ purse ]);
|
||||
|
||||
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
|
||||
{
|
||||
const parser = event.getParser();
|
||||
|
||||
switch(parser.name)
|
||||
{
|
||||
case 'habbo_club':
|
||||
dispatchPurseState({
|
||||
type: PurseActions.SET_CLUB_SUBSCRIPTION,
|
||||
payload: {
|
||||
clubSubscription: parser
|
||||
}
|
||||
});
|
||||
return;
|
||||
}
|
||||
}, [ dispatchPurseState ]);
|
||||
const productName = parser.productName;
|
||||
|
||||
if((productName !== 'club_habbo') && (productName !== 'habbo_club')) return;
|
||||
|
||||
purse.clubDays = Math.max(0, parser.daysToPeriodEnd);
|
||||
purse.clubPeriods = Math.max(0, parser.periodsSubscribedAhead);
|
||||
purse.isVip = parser.isVip;
|
||||
purse.pastClubDays = parser.pastClubDays;
|
||||
purse.pastVipDays = parser.pastVipDays;
|
||||
purse.isExpiring = ((parser.responseType === UserSubscriptionParser.RESPONSE_TYPE_DISCOUNT_AVAILABLE) ? true : false);
|
||||
purse.minutesUntilExpiration = parser.minutesUntilExpiration;
|
||||
purse.minutesSinceLastModified = parser.minutesSinceLastModified;
|
||||
|
||||
purse.notify();
|
||||
}, [ purse ]);
|
||||
|
||||
CreateMessageHook(UserCreditsEvent, onUserCreditsEvent);
|
||||
CreateMessageHook(UserCurrencyEvent, onUserCurrencyEvent);
|
||||
|
@ -1,15 +1,37 @@
|
||||
.nitro-purse {
|
||||
background: rgba($dark,.95);
|
||||
border: 1px solid lighten($dark,8.3);
|
||||
box-shadow: inset 0px 3px lighten(rgba($dark,.6),2.5), inset 0 -2px darken(rgba($dark,.6),4);
|
||||
font-weight: bolder;
|
||||
padding: 2px;
|
||||
background-color: #1c323f;
|
||||
border: 2px solid rgba($white, 0.5);
|
||||
border-top: 0;
|
||||
font-size: $font-size-sm;
|
||||
pointer-events: all;
|
||||
margin-bottom:5px;
|
||||
|
||||
|
||||
.notification-button {
|
||||
color:lighten($dark,20);
|
||||
cursor: pointer;
|
||||
font-size: 0.9rem;
|
||||
pointer-events: all;
|
||||
display: none
|
||||
}
|
||||
|
||||
.nitro-purse-hc {
|
||||
background-color: #3d5f6e;
|
||||
margin:0 2px;
|
||||
}
|
||||
|
||||
.nitro-purse-button {
|
||||
background: $bg-mirage-split-background;
|
||||
|
||||
&:not(:first-child) {
|
||||
margin-top:2px;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: $bg-cello-split-background;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './currency/CurrencyView';
|
||||
@import './views';
|
||||
|
@ -1,52 +1,144 @@
|
||||
import { UserCurrencyComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useReducer } from 'react';
|
||||
import { FriendlyTime, HabboClubLevelEnum, UserCurrencyComposer, UserSubscriptionComposer } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||
import { GetConfiguration } from '../../api';
|
||||
import { NotificationCenterEvent } from '../../events';
|
||||
import { dispatchUiEvent } from '../../hooks/events';
|
||||
import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||
import { SetLastCurrencies } from './common/CurrencyHelper';
|
||||
import { LocalizeText } from '../../utils/LocalizeText';
|
||||
import { CurrencyIcon } from '../shared/currency-icon/CurrencyIcon';
|
||||
import { IPurse } from './common/IPurse';
|
||||
import { Purse } from './common/Purse';
|
||||
import { PurseContextProvider } from './context/PurseContext';
|
||||
import { CurrencyView } from './currency/CurrencyView';
|
||||
import { PurseMessageHandler } from './PurseMessageHandler';
|
||||
import { PurseViewProps } from './PurseView.types';
|
||||
import { initialPurse, PurseReducer } from './reducers/PurseReducer';
|
||||
import { CurrencyView } from './views/currency/CurrencyView';
|
||||
import { SeasonalView } from './views/seasonal/SeasonalView';
|
||||
|
||||
export const PurseView: FC<PurseViewProps> = props =>
|
||||
export let GLOBAL_PURSE: IPurse = null;
|
||||
|
||||
export const PurseView: FC<{}> = props =>
|
||||
{
|
||||
const [ purseState, dispatchPurseState ] = useReducer(PurseReducer, initialPurse);
|
||||
const { currencies = [] } = purseState;
|
||||
const [ purse, setPurse ] = useState<IPurse>(new Purse());
|
||||
const [ updateId, setUpdateId ] = useState(-1);
|
||||
|
||||
const displayedCurrencies = useMemo(() =>
|
||||
{
|
||||
return GetConfiguration<number[]>('system.currency.types', []);
|
||||
}, []);
|
||||
|
||||
const getCurrencyElements = useCallback((offset: number, limit: number = -1, seasonal: boolean = false) =>
|
||||
{
|
||||
if(!purse.activityPoints.size) return null;
|
||||
|
||||
const types = Array.from(purse.activityPoints.keys()).filter(type => (displayedCurrencies.indexOf(type) >= 0));
|
||||
|
||||
let count = 0;
|
||||
|
||||
while(count < offset)
|
||||
{
|
||||
types.shift();
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
count = 0;
|
||||
|
||||
const elements: JSX.Element[] = [];
|
||||
|
||||
for(const type of types)
|
||||
{
|
||||
if((limit > -1) && (count === limit)) break;
|
||||
|
||||
if(seasonal) elements.push(<SeasonalView key={ type } type={ type } amount={ purse.activityPoints.get(type) } />);
|
||||
else elements.push(<CurrencyView key={ type } type={ type } amount={ purse.activityPoints.get(type) } />);
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return elements;
|
||||
}, [ purse, displayedCurrencies ]);
|
||||
|
||||
const getClubText = useCallback(() =>
|
||||
{
|
||||
const totalDays = ((purse.clubPeriods * 31) + purse.clubDays);
|
||||
const minutesUntilExpiration = purse.minutesUntilExpiration;
|
||||
|
||||
if(purse.clubLevel === HabboClubLevelEnum.NO_CLUB)
|
||||
{
|
||||
return LocalizeText('purse.clubdays.zero.amount.text');
|
||||
}
|
||||
|
||||
else if((minutesUntilExpiration > -1) && (minutesUntilExpiration < (60 * 24)))
|
||||
{
|
||||
return FriendlyTime.shortFormat(minutesUntilExpiration * 60);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
return FriendlyTime.shortFormat(totalDays * 86400);
|
||||
}
|
||||
}, [ purse ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageHook(new UserCurrencyComposer());
|
||||
const purse = new Purse();
|
||||
|
||||
GLOBAL_PURSE = purse;
|
||||
|
||||
purse.notifier = () => setUpdateId(prevValue => (prevValue + 1));
|
||||
|
||||
setPurse(purse);
|
||||
|
||||
return () => (purse.notifier = null);
|
||||
}, []);
|
||||
|
||||
SetLastCurrencies(currencies);
|
||||
|
||||
const toggleNotificationCenter = useCallback(() =>
|
||||
useEffect(() =>
|
||||
{
|
||||
dispatchUiEvent(new NotificationCenterEvent(NotificationCenterEvent.TOGGLE_NOTIFICATION_CENTER));
|
||||
}, []);
|
||||
if(!purse) return;
|
||||
|
||||
SendMessageHook(new UserCurrencyComposer());
|
||||
}, [ purse ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
SendMessageHook(new UserSubscriptionComposer('habbo_club'));
|
||||
|
||||
const interval = setInterval(() =>
|
||||
{
|
||||
SendMessageHook(new UserSubscriptionComposer('habbo_club'));
|
||||
}, 50000);
|
||||
|
||||
return () => clearInterval(interval);
|
||||
}, [ purse ]);
|
||||
|
||||
if(!purse) return null;
|
||||
|
||||
return (
|
||||
<PurseContextProvider value={ { purseState, dispatchPurseState }}>
|
||||
<PurseContextProvider value={ { purse } }>
|
||||
<PurseMessageHandler />
|
||||
<div className="nitro-purse rounded d-flex flex-row py-1 justify-content-between">
|
||||
{ currencies && currencies.map(currency =>
|
||||
{
|
||||
if(displayedCurrencies.indexOf(currency.type) === -1) return null;
|
||||
|
||||
return <CurrencyView key={ currency.type } currency={ currency } />;
|
||||
}) }
|
||||
<div className="notification-button px-2" onClick={ toggleNotificationCenter }>
|
||||
<div className="nitro-purse rounded-bottom d-flex flex-row justify-content-between">
|
||||
<div className="row mx-0 w-100">
|
||||
<div className="col-6 px-0">
|
||||
<div className="d-flex flex-column nitro-currencies">
|
||||
<CurrencyView type={ -1 } amount={ purse.credits } />
|
||||
{ getCurrencyElements(0, 2) }
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-4 px-0">
|
||||
<div className="nitro-purse-hc p-1 d-flex flex-column justify-content-center align-items-center h-100">
|
||||
<CurrencyIcon className="flex-shrink-0" type="hc" />
|
||||
<span>{ getClubText() }</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col-2 px-0">
|
||||
<div className="d-flex flex-column nitro-purse-buttons h-100 justify-content-center">
|
||||
<div className="nitro-purse-button text-white h-100 text-center d-flex align-items-center justify-content-center"><i className="fas fa-life-ring"/></div>
|
||||
<div className="nitro-purse-button text-white h-100 text-center d-flex align-items-center justify-content-center"><i className="fas fa-cogs"/></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{/*<div className="notification-button px-2" onClick={toggleNotificationCenter}>
|
||||
<i className="fas fa-bars" />
|
||||
</div>
|
||||
</div>*/}
|
||||
</div>
|
||||
{ getCurrencyElements(2, -1, true) }
|
||||
</PurseContextProvider>
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +0,0 @@
|
||||
export interface PurseViewProps
|
||||
{
|
||||
|
||||
}
|
@ -1,19 +1,16 @@
|
||||
import { Currency } from './Currency';
|
||||
|
||||
let lastCurrencies: Currency[] = [];
|
||||
|
||||
export function SetLastCurrencies(currencies: Currency[]): void
|
||||
{
|
||||
lastCurrencies = currencies;
|
||||
}
|
||||
import { GLOBAL_PURSE } from '../PurseView';
|
||||
|
||||
export function GetCurrencyAmount(type: number): number
|
||||
{
|
||||
for(const currency of lastCurrencies)
|
||||
{
|
||||
if(currency.type !== type) continue;
|
||||
const purse = GLOBAL_PURSE;
|
||||
|
||||
return currency.amount;
|
||||
if(type === -1) return purse.credits;
|
||||
|
||||
for(const [ key, value ] of purse.activityPoints.entries())
|
||||
{
|
||||
if(key !== type) continue;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
17
src/views/purse/common/IPurse.ts
Normal file
17
src/views/purse/common/IPurse.ts
Normal file
@ -0,0 +1,17 @@
|
||||
export interface IPurse
|
||||
{
|
||||
credits: number;
|
||||
activityPoints: Map<number, number>;
|
||||
clubDays: number;
|
||||
clubPeriods: number;
|
||||
_Str_13571: boolean;
|
||||
isVip: boolean;
|
||||
pastClubDays: number;
|
||||
pastVipDays: number;
|
||||
isExpiring: boolean;
|
||||
minutesUntilExpiration: number;
|
||||
minutesSinceLastModified: number;
|
||||
clubLevel: number;
|
||||
notifier: () => void
|
||||
notify(): void;
|
||||
}
|
163
src/views/purse/common/Purse.ts
Normal file
163
src/views/purse/common/Purse.ts
Normal file
@ -0,0 +1,163 @@
|
||||
import { HabboClubLevelEnum } from 'nitro-renderer';
|
||||
import { GetNitroInstance } from '../../../api';
|
||||
import { IPurse } from './IPurse';
|
||||
|
||||
export class Purse implements IPurse
|
||||
{
|
||||
private _credits: number = 0;
|
||||
private _activityPoints: Map<number, number> = new Map();
|
||||
private _clubDays: number = 0;
|
||||
private _clubPeriods: number = 0;
|
||||
private _isVIP: boolean = false;
|
||||
private _pastClubDays: number = 0;
|
||||
private _pastVipDays: number = 0;
|
||||
private _isExpiring: boolean = false;
|
||||
private _minutesUntilExpiration: number = 0;
|
||||
private _minutesSinceLastModified: number;
|
||||
private _lastUpdated: number;
|
||||
private _notifier: () => void;
|
||||
|
||||
public get credits(): number
|
||||
{
|
||||
return this._credits;
|
||||
}
|
||||
|
||||
public set credits(credits: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._credits = credits;
|
||||
}
|
||||
|
||||
public get activityPoints(): Map<number, number>
|
||||
{
|
||||
return this._activityPoints;
|
||||
}
|
||||
|
||||
public set activityPoints(k: Map<number, number>)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._activityPoints = k;
|
||||
}
|
||||
|
||||
public get clubDays(): number
|
||||
{
|
||||
return this._clubDays;
|
||||
}
|
||||
|
||||
public set clubDays(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._clubDays = k;
|
||||
}
|
||||
|
||||
public get clubPeriods(): number
|
||||
{
|
||||
return this._clubPeriods;
|
||||
}
|
||||
|
||||
public set clubPeriods(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._clubPeriods = k;
|
||||
}
|
||||
|
||||
public get _Str_13571(): boolean
|
||||
{
|
||||
return (this._clubDays > 0) || (this._clubPeriods > 0);
|
||||
}
|
||||
|
||||
public get isVip(): boolean
|
||||
{
|
||||
return this._isVIP;
|
||||
}
|
||||
|
||||
public set isVip(k: boolean)
|
||||
{
|
||||
this._isVIP = k;
|
||||
}
|
||||
|
||||
public get pastClubDays(): number
|
||||
{
|
||||
return this._pastClubDays;
|
||||
}
|
||||
|
||||
public set pastClubDays(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._pastClubDays = k;
|
||||
}
|
||||
|
||||
public get pastVipDays(): number
|
||||
{
|
||||
return this._pastVipDays;
|
||||
}
|
||||
|
||||
public set pastVipDays(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._pastVipDays = k;
|
||||
}
|
||||
|
||||
public get isExpiring(): boolean
|
||||
{
|
||||
return this._isExpiring;
|
||||
}
|
||||
|
||||
public set isExpiring(k: boolean)
|
||||
{
|
||||
this._isExpiring = k;
|
||||
}
|
||||
|
||||
public get minutesUntilExpiration(): number
|
||||
{
|
||||
var k: number = ((GetNitroInstance().time - this._lastUpdated) / (1000 * 60));
|
||||
var _local_2: number = (this._minutesUntilExpiration - k);
|
||||
return (_local_2 > 0) ? _local_2 : 0;
|
||||
}
|
||||
|
||||
public set minutesUntilExpiration(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._minutesUntilExpiration = k;
|
||||
}
|
||||
|
||||
public get minutesSinceLastModified(): number
|
||||
{
|
||||
return this._minutesSinceLastModified;
|
||||
}
|
||||
|
||||
public set minutesSinceLastModified(k: number)
|
||||
{
|
||||
this._lastUpdated = GetNitroInstance().time;
|
||||
this._minutesSinceLastModified = k;
|
||||
}
|
||||
|
||||
public get lastUpdated(): number
|
||||
{
|
||||
return this._lastUpdated;
|
||||
}
|
||||
|
||||
public get notifier(): () => void
|
||||
{
|
||||
return this._notifier;
|
||||
}
|
||||
|
||||
public set notifier(notifier: () => void)
|
||||
{
|
||||
this._notifier = notifier;
|
||||
}
|
||||
|
||||
public get clubLevel(): number
|
||||
{
|
||||
if(((this.clubDays === 0) && (this.clubPeriods === 0))) return HabboClubLevelEnum.NO_CLUB;
|
||||
|
||||
if (this.isVip) return HabboClubLevelEnum.VIP;
|
||||
|
||||
return HabboClubLevelEnum.CLUB;
|
||||
}
|
||||
|
||||
public notify(): void
|
||||
{
|
||||
if(this._notifier) this._notifier();
|
||||
}
|
||||
}
|
@ -2,8 +2,7 @@ import { createContext, FC, useContext } from 'react';
|
||||
import { IPurseContext, PurseContextProps } from './PurseContext.types';
|
||||
|
||||
const PurseContext = createContext<IPurseContext>({
|
||||
purseState: null,
|
||||
dispatchPurseState: null
|
||||
purse: null
|
||||
});
|
||||
|
||||
export const PurseContextProvider: FC<PurseContextProps> = props =>
|
||||
|
@ -1,10 +1,9 @@
|
||||
import { Dispatch, ProviderProps } from 'react';
|
||||
import { IPurseAction, IPurseState } from '../reducers/PurseReducer';
|
||||
import { ProviderProps } from 'react';
|
||||
import { IPurse } from '../common/IPurse';
|
||||
|
||||
export interface IPurseContext
|
||||
{
|
||||
purseState: IPurseState;
|
||||
dispatchPurseState: Dispatch<IPurseAction>;
|
||||
purse: IPurse;
|
||||
}
|
||||
|
||||
export interface PurseContextProps extends ProviderProps<IPurseContext>
|
||||
|
@ -1,10 +0,0 @@
|
||||
.nitro-currency {
|
||||
pointer-events: all;
|
||||
.nitro-currency-text {
|
||||
max-width: 60px;
|
||||
}
|
||||
&:not(:last-child) {
|
||||
border-right:1px solid #000;
|
||||
box-shadow: 1px 0 lighten($dark,8.3)
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
|
||||
import { LocalizeShortNumber } from '../../../utils/LocalizeShortNumber';
|
||||
import { CurrencyIcon } from '../../shared/currency-icon/CurrencyIcon';
|
||||
import { CurrencyViewProps } from './CurrencyView.types';
|
||||
|
||||
export const CurrencyView: FC<CurrencyViewProps> = props =>
|
||||
{
|
||||
const { currency = null } = props;
|
||||
|
||||
return (
|
||||
<OverlayTrigger
|
||||
placement="left"
|
||||
overlay={
|
||||
<Tooltip id={`tooltip-${currency.type}`}>
|
||||
{ currency.amount }
|
||||
</Tooltip>
|
||||
}>
|
||||
<div className="nitro-currency px-1 d-flex">
|
||||
<div className="px-1 text-end text-truncate nitro-currency-text">{LocalizeShortNumber(currency.amount)}</div>
|
||||
<div className="icon">
|
||||
<CurrencyIcon type={ currency.type } />
|
||||
</div>
|
||||
</div>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
}
|
@ -1,6 +0,0 @@
|
||||
import { Currency } from '../common/Currency';
|
||||
|
||||
export interface CurrencyViewProps
|
||||
{
|
||||
currency: Currency;
|
||||
}
|
@ -1,77 +0,0 @@
|
||||
import { UserSubscriptionParser } from 'nitro-renderer';
|
||||
import { Reducer } from 'react';
|
||||
import { Currency } from '../common/Currency';
|
||||
|
||||
export interface IPurseState
|
||||
{
|
||||
currencies: Currency[];
|
||||
clubSubscription: UserSubscriptionParser;
|
||||
}
|
||||
|
||||
export interface IPurseAction
|
||||
{
|
||||
type: string;
|
||||
payload: {
|
||||
currency?: Currency;
|
||||
currencies?: Currency[];
|
||||
clubSubscription?: UserSubscriptionParser;
|
||||
}
|
||||
}
|
||||
|
||||
export class PurseActions
|
||||
{
|
||||
public static SET_CURRENCY: string = 'PA_SET_CURRENCY';
|
||||
public static SET_CURRENCIES: string = 'PA_SET_CURRENCIES';
|
||||
public static SET_CLUB_SUBSCRIPTION: string = 'PA_SET_CLUB_SUBSCRIPTION';
|
||||
}
|
||||
|
||||
export const initialPurse: IPurseState = {
|
||||
currencies: [],
|
||||
clubSubscription: null
|
||||
}
|
||||
|
||||
export const PurseReducer: Reducer<IPurseState, IPurseAction> = (state, action) =>
|
||||
{
|
||||
switch(action.type)
|
||||
{
|
||||
case PurseActions.SET_CURRENCY: {
|
||||
const updated = action.payload.currency;
|
||||
|
||||
let didSet = false;
|
||||
|
||||
const currencies = state.currencies.map(existing =>
|
||||
{
|
||||
if(existing.type !== updated.type) return existing;
|
||||
|
||||
didSet = true;
|
||||
|
||||
return { ...updated };
|
||||
});
|
||||
|
||||
if(!didSet) currencies.push({ ...updated });
|
||||
|
||||
return { ...state, currencies };
|
||||
}
|
||||
case PurseActions.SET_CURRENCIES: {
|
||||
const updated = action.payload.currencies;
|
||||
|
||||
const currencies = state.currencies.filter(existing =>
|
||||
{
|
||||
if(existing.type !== -1) return null;
|
||||
|
||||
return existing;
|
||||
});
|
||||
|
||||
if(updated && updated.length) currencies.push(...updated);
|
||||
|
||||
return { ...state, currencies };
|
||||
}
|
||||
case PurseActions.SET_CLUB_SUBSCRIPTION: {
|
||||
const clubSubscription = action.payload.clubSubscription;
|
||||
|
||||
return { ...state, clubSubscription };
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
9
src/views/purse/views/currency/CurrencyView.scss
Normal file
9
src/views/purse/views/currency/CurrencyView.scss
Normal file
@ -0,0 +1,9 @@
|
||||
.nitro-currency {
|
||||
pointer-events: all;
|
||||
background: $bg-mirage-split-background;
|
||||
position: relative;
|
||||
|
||||
&:not(:first-of-type) {
|
||||
margin-top:2px;
|
||||
}
|
||||
}
|
25
src/views/purse/views/currency/CurrencyView.tsx
Normal file
25
src/views/purse/views/currency/CurrencyView.tsx
Normal file
@ -0,0 +1,25 @@
|
||||
import { FC } from 'react';
|
||||
import { OverlayTrigger, Tooltip } from 'react-bootstrap';
|
||||
import { LocalizeShortNumber } from '../../../../utils/LocalizeShortNumber';
|
||||
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||
import { CurrencyViewProps } from './CurrencyView.types';
|
||||
|
||||
export const CurrencyView: FC<CurrencyViewProps> = props =>
|
||||
{
|
||||
const { type = -1, amount = -1 } = props;
|
||||
|
||||
return (
|
||||
<OverlayTrigger
|
||||
placement="left"
|
||||
overlay={
|
||||
<Tooltip id={`tooltip-${ type }`}>
|
||||
{ amount }
|
||||
</Tooltip>
|
||||
}>
|
||||
<div className="nitro-currency d-flex justify-content-end nitro-purse-button">
|
||||
<div className="px-1 text-end text-truncate nitro-currency-text align-self-center">{LocalizeShortNumber(amount)}</div>
|
||||
<CurrencyIcon className="flex-shrink-0" type={ type } />
|
||||
</div>
|
||||
</OverlayTrigger>
|
||||
);
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
export interface Currency
|
||||
export interface CurrencyViewProps
|
||||
{
|
||||
type: number;
|
||||
amount: number;
|
2
src/views/purse/views/index.scss
Normal file
2
src/views/purse/views/index.scss
Normal file
@ -0,0 +1,2 @@
|
||||
@import './currency/CurrencyView';
|
||||
@import './seasonal/SeasonalView';
|
16
src/views/purse/views/seasonal/SeasonalView.scss
Normal file
16
src/views/purse/views/seasonal/SeasonalView.scss
Normal file
@ -0,0 +1,16 @@
|
||||
.nitro-seasonal-currency {
|
||||
pointer-events: all;
|
||||
padding: 2px;
|
||||
background-color: #1c323f;
|
||||
border: 2px solid rgba($white, 0.5);
|
||||
font-size: $font-size-sm;
|
||||
margin-bottom: 5px;
|
||||
|
||||
.nitro-currency-text {
|
||||
background: $bg-mirage-split-background;
|
||||
}
|
||||
|
||||
.nitro-seasonal-icon {
|
||||
background-color: #3d5f6e
|
||||
}
|
||||
}
|
22
src/views/purse/views/seasonal/SeasonalView.tsx
Normal file
22
src/views/purse/views/seasonal/SeasonalView.tsx
Normal file
@ -0,0 +1,22 @@
|
||||
import { FC } from 'react';
|
||||
import { LocalizeShortNumber } from '../../../../utils/LocalizeShortNumber';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { CurrencyIcon } from '../../../shared/currency-icon/CurrencyIcon';
|
||||
import { SeasonalViewProps } from './SeasonalView.types';
|
||||
|
||||
export const SeasonalView: FC<SeasonalViewProps> = props =>
|
||||
{
|
||||
const { type = -1, amount = -1 } = props;
|
||||
|
||||
return (
|
||||
<div className="nitro-seasonal-currency rounded d-flex justify-content-end">
|
||||
<div className="nitro-currency-text w-100 px-1 d-flex justify-content-between">
|
||||
<span>{ LocalizeText(`purse.seasonal.currency.${ type }`) }</span>
|
||||
<span>{ LocalizeShortNumber(amount) }</span>
|
||||
</div>
|
||||
<div className="nitro-seasonal-icon">
|
||||
<CurrencyIcon type={ type } />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
6
src/views/purse/views/seasonal/SeasonalView.types.ts
Normal file
6
src/views/purse/views/seasonal/SeasonalView.types.ts
Normal file
@ -0,0 +1,6 @@
|
||||
|
||||
export interface SeasonalViewProps
|
||||
{
|
||||
type: number;
|
||||
amount: number;
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
.nitro-right-side {
|
||||
position: absolute;
|
||||
top: 10px;
|
||||
top: 0px;
|
||||
right: 10px;
|
||||
min-width: 200px;
|
||||
max-width: 400px;
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { ColorConverter, Nitro, NitroAdjustmentFilter, NitroContainer, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineEvent, RoomId, RoomObjectHSLColorEnabledEvent } from 'nitro-renderer';
|
||||
import { ColorConverter, NitroAdjustmentFilter, NitroContainer, NitroSprite, NitroTexture, RoomBackgroundColorEvent, RoomEngineEvent, RoomId, RoomObjectHSLColorEnabledEvent } from 'nitro-renderer';
|
||||
import { FC, useCallback, useState } from 'react';
|
||||
import { GetRoomEngine } from '../../api';
|
||||
import { GetNitroInstance, GetRoomEngine } from '../../api';
|
||||
import { UseMountEffect } from '../../hooks';
|
||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../hooks/events';
|
||||
import { useRoomContext } from './context/RoomContext';
|
||||
@ -48,8 +48,8 @@ export const RoomColorView: FC<{}> = props =>
|
||||
if(color === undefined) color = 0x000000;
|
||||
|
||||
background.tint = color;
|
||||
background.width = Nitro.instance.width;
|
||||
background.height = Nitro.instance.height;
|
||||
background.width = GetNitroInstance().width;
|
||||
background.height = GetNitroInstance().height;
|
||||
}, [ getRoomBackground ]);
|
||||
|
||||
const updateRoomBackgroundColor = useCallback((hue: number, saturation: number, lightness: number, original: boolean = false) =>
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { EventDispatcher, Nitro, NitroRectangle, RoomGeometry, RoomVariableEnum, Vector3d } from 'nitro-renderer';
|
||||
import { EventDispatcher, NitroRectangle, RoomGeometry, RoomVariableEnum, Vector3d } from 'nitro-renderer';
|
||||
import { FC, useEffect, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import { InitializeRoomInstanceRenderingCanvas } from '../../api';
|
||||
import { GetNitroInstance, InitializeRoomInstanceRenderingCanvas } from '../../api';
|
||||
import { DispatchMouseEvent } from '../../api/nitro/room/DispatchMouseEvent';
|
||||
import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent';
|
||||
import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
|
||||
@ -47,11 +47,11 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
|
||||
setWidgetHandler(widgetHandlerManager);
|
||||
|
||||
Nitro.instance.renderer.resize(window.innerWidth, window.innerHeight);
|
||||
GetNitroInstance().renderer.resize(window.innerWidth, window.innerHeight);
|
||||
|
||||
const canvasId = 1;
|
||||
|
||||
const displayObject = GetRoomEngine().getRoomInstanceDisplay(roomSession.roomId, canvasId, Nitro.instance.width, Nitro.instance.height, RoomGeometry.SCALE_ZOOMED_IN);
|
||||
const displayObject = GetRoomEngine().getRoomInstanceDisplay(roomSession.roomId, canvasId, GetNitroInstance().width, GetNitroInstance().height, RoomGeometry.SCALE_ZOOMED_IN);
|
||||
|
||||
if(!displayObject) return;
|
||||
|
||||
@ -77,13 +77,13 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
geometry.location = new Vector3d(x, y, z);
|
||||
}
|
||||
|
||||
const stage = Nitro.instance.stage;
|
||||
const stage = GetNitroInstance().stage;
|
||||
|
||||
if(!stage) return;
|
||||
|
||||
stage.addChild(displayObject);
|
||||
|
||||
const canvas = Nitro.instance.renderer.view;
|
||||
const canvas = GetNitroInstance().renderer.view;
|
||||
|
||||
if(!canvas) return;
|
||||
|
||||
@ -99,16 +99,16 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
|
||||
window.onresize = () =>
|
||||
{
|
||||
Nitro.instance.renderer.resize(window.innerWidth, window.innerHeight);
|
||||
GetNitroInstance().renderer.resize(window.innerWidth, window.innerHeight);
|
||||
|
||||
InitializeRoomInstanceRenderingCanvas(roomSession.roomId, canvasId, Nitro.instance.width, Nitro.instance.height);
|
||||
InitializeRoomInstanceRenderingCanvas(roomSession.roomId, canvasId, GetNitroInstance().width, GetNitroInstance().height);
|
||||
|
||||
const bounds = canvas.getBoundingClientRect();
|
||||
const rectangle = new NitroRectangle((bounds.x || 0), (bounds.y || 0), (bounds.width || 0), (bounds.height || 0));
|
||||
|
||||
widgetHandlerManager.eventDispatcher.dispatchEvent(new RoomWidgetUpdateRoomViewEvent(RoomWidgetUpdateRoomViewEvent.SIZE_CHANGED, rectangle));
|
||||
|
||||
Nitro.instance.render();
|
||||
GetNitroInstance().render();
|
||||
}
|
||||
|
||||
setRoomCanvas(canvas);
|
||||
|
@ -30,4 +30,6 @@ export class RoomWidgetUpdateInfostandFurniEvent extends RoomWidgetUpdateInfosta
|
||||
public purchaseCouldBeUsedForBuyout: boolean = false;
|
||||
public rentCouldBeUsedForBuyout: boolean = false;
|
||||
public availableForBuildersClub: boolean = false;
|
||||
public tileSizeX: number = 1;
|
||||
public tileSizeY: number = 1;
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { IFurnitureData, Nitro, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomAdsUpdateComposer, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, SecurityLevel, Vector3d } from 'nitro-renderer';
|
||||
import { GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api';
|
||||
import { IFurnitureData, NitroEvent, ObjectDataFactory, PetFigureData, PetRespectComposer, PetSupplementComposer, PetType, RoomAdsUpdateComposer, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnum, RoomWidgetEnumItemExtradataParameter, SecurityLevel, Vector3d } from 'nitro-renderer';
|
||||
import { GetNitroInstance, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api';
|
||||
import { InventoryTradeRequestEvent, WiredSelectObjectEvent } from '../../../events';
|
||||
import { FriendListSendFriendRequestEvent } from '../../../events/friend-list/FriendListSendFriendRequestEvent';
|
||||
import { dispatchUiEvent } from '../../../hooks/events';
|
||||
@ -390,6 +390,8 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
event.rentOfferId = furnitureData.rentOfferId;
|
||||
event.rentCouldBeUsedForBuyout = furnitureData.rentCouldBeUsedForBuyout;
|
||||
event.availableForBuildersClub = furnitureData.availableForBuildersClub;
|
||||
event.tileSizeX = furnitureData.tileSizeX;
|
||||
event.tileSizeY = furnitureData.tileSizeY;
|
||||
|
||||
dispatchUiEvent(new WiredSelectObjectEvent(event.id, event.category));
|
||||
}
|
||||
@ -400,7 +402,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
const expiryTime = model.getValue<number>(RoomObjectVariable.FURNITURE_EXPIRY_TIME);
|
||||
const expiryTimestamp = model.getValue<number>(RoomObjectVariable.FURNITURE_EXPIRTY_TIMESTAMP);
|
||||
|
||||
event.expiration = ((expiryTime < 0) ? expiryTime : Math.max(0, (expiryTime - ((Nitro.instance.time - expiryTimestamp) / 1000))));
|
||||
event.expiration = ((expiryTime < 0) ? expiryTime : Math.max(0, (expiryTime - ((GetNitroInstance().time - expiryTimestamp) / 1000))));
|
||||
|
||||
let roomObjectImage = GetRoomEngine().getRoomObjectImage(roomId, message.id, message.category, new Vector3d(180), 64, 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