mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
commit
a64c01b2db
@ -53,7 +53,7 @@
|
|||||||
"avatareditor.show.clubitems.first": true,
|
"avatareditor.show.clubitems.first": true,
|
||||||
"chat.history.max.items": 100,
|
"chat.history.max.items": 100,
|
||||||
"animation.fps": 24,
|
"animation.fps": 24,
|
||||||
"limits.fps": true,
|
"limits.fps": false,
|
||||||
"system.dispatcher.log": false,
|
"system.dispatcher.log": false,
|
||||||
"system.currency.types": [
|
"system.currency.types": [
|
||||||
-1,
|
-1,
|
||||||
|
@ -4,11 +4,14 @@ import { GetRoomEngine } from './GetRoomEngine';
|
|||||||
let didMouseMove = false;
|
let didMouseMove = false;
|
||||||
let lastClick = 0;
|
let lastClick = 0;
|
||||||
let clickCount = 0;
|
let clickCount = 0;
|
||||||
|
let touchTimer: ReturnType<typeof setTimeout> = null;
|
||||||
|
|
||||||
export function DispatchTouchEvent(roomId: number, canvasId: number, event: TouchEvent)
|
export function DispatchTouchEvent(roomId: number, canvasId: number, event: TouchEvent, longTouch: boolean = false, altKey: boolean = false, ctrlKey: boolean = false, shiftKey: boolean = false)
|
||||||
{
|
{
|
||||||
let eventType = event.type;
|
let eventType = event.type;
|
||||||
|
|
||||||
|
if(longTouch) eventType = TouchEventType.TOUCH_LONG;
|
||||||
|
|
||||||
if(eventType === TouchEventType.TOUCH_END && !didMouseMove)
|
if(eventType === TouchEventType.TOUCH_END && !didMouseMove)
|
||||||
{
|
{
|
||||||
eventType = MouseEventType.MOUSE_CLICK;
|
eventType = MouseEventType.MOUSE_CLICK;
|
||||||
@ -17,7 +20,7 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc
|
|||||||
{
|
{
|
||||||
clickCount = 1;
|
clickCount = 1;
|
||||||
|
|
||||||
if(lastClick >= Date.now() - 300) clickCount++;
|
if(lastClick >= (Date.now() - 300)) clickCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
lastClick = Date.now();
|
lastClick = Date.now();
|
||||||
@ -31,24 +34,7 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(eventType)
|
if(touchTimer) clearTimeout(touchTimer);
|
||||||
{
|
|
||||||
case MouseEventType.MOUSE_CLICK:
|
|
||||||
break;
|
|
||||||
case MouseEventType.DOUBLE_CLICK:
|
|
||||||
break;
|
|
||||||
case TouchEventType.TOUCH_START:
|
|
||||||
eventType = MouseEventType.MOUSE_DOWN;
|
|
||||||
|
|
||||||
didMouseMove = false;
|
|
||||||
break;
|
|
||||||
case TouchEventType.TOUCH_MOVE:
|
|
||||||
eventType = MouseEventType.MOUSE_MOVE;
|
|
||||||
|
|
||||||
didMouseMove = true;
|
|
||||||
break;
|
|
||||||
default: return;
|
|
||||||
}
|
|
||||||
|
|
||||||
let x = 0;
|
let x = 0;
|
||||||
let y = 0;
|
let y = 0;
|
||||||
@ -66,5 +52,38 @@ export function DispatchTouchEvent(roomId: number, canvasId: number, event: Touc
|
|||||||
}
|
}
|
||||||
|
|
||||||
GetRoomEngine().setActiveRoomId(roomId);
|
GetRoomEngine().setActiveRoomId(roomId);
|
||||||
GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, event.altKey, (event.ctrlKey || event.metaKey), event.shiftKey, false);
|
|
||||||
|
switch(eventType)
|
||||||
|
{
|
||||||
|
case MouseEventType.MOUSE_CLICK:
|
||||||
|
break;
|
||||||
|
case MouseEventType.DOUBLE_CLICK:
|
||||||
|
break;
|
||||||
|
case TouchEventType.TOUCH_START:
|
||||||
|
touchTimer = setTimeout(() =>
|
||||||
|
{
|
||||||
|
if(didMouseMove) return;
|
||||||
|
|
||||||
|
DispatchTouchEvent(roomId, canvasId, event, true);
|
||||||
|
}, 300);
|
||||||
|
|
||||||
|
eventType = MouseEventType.MOUSE_DOWN;
|
||||||
|
|
||||||
|
didMouseMove = false;
|
||||||
|
break;
|
||||||
|
case TouchEventType.TOUCH_MOVE:
|
||||||
|
eventType = MouseEventType.MOUSE_MOVE;
|
||||||
|
|
||||||
|
didMouseMove = true;
|
||||||
|
break;
|
||||||
|
case TouchEventType.TOUCH_END:
|
||||||
|
eventType = MouseEventType.MOUSE_UP;
|
||||||
|
break;
|
||||||
|
case TouchEventType.TOUCH_LONG:
|
||||||
|
eventType = MouseEventType.MOUSE_DOWN_LONG;
|
||||||
|
break;
|
||||||
|
default: return;
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRoomEngine().dispatchMouseEvent(canvasId, x, y, eventType, altKey, ctrlKey, shiftKey, false);
|
||||||
}
|
}
|
||||||
|
@ -32,10 +32,7 @@ ul {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.cursor-pointer {
|
.cursor-pointer {
|
||||||
|
|
||||||
&:hover {
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.pointer-events-none {
|
.pointer-events-none {
|
||||||
|
@ -10,4 +10,5 @@ export class CatalogEvent extends NitroEvent
|
|||||||
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
public static SOLD_OUT: string = 'CE_SOLD_OUT';
|
||||||
public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT';
|
public static APPROVE_NAME_RESULT: string = 'CE_APPROVE_NAME_RESULT';
|
||||||
public static PURCHASE_APPROVED: string = 'CE_PURCHASE_APPROVED';
|
public static PURCHASE_APPROVED: string = 'CE_PURCHASE_APPROVED';
|
||||||
|
public static CATALOG_RESET: string = 'CE_RESET';
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
.draggable-window {
|
.draggable-window {
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
.drag-handler {
|
.drag-handler {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
|
@ -62,6 +62,8 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
|||||||
element.style.top = `${ top }px`;
|
element.style.top = `${ top }px`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
element.style.visibility = 'visible';
|
||||||
|
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
const index = currentWindows.indexOf(element);
|
const index = currentWindows.indexOf(element);
|
||||||
|
@ -1,24 +1,17 @@
|
|||||||
import { IEventDispatcher, NitroEvent } from 'nitro-renderer';
|
import { IEventDispatcher, NitroEvent } from 'nitro-renderer';
|
||||||
import { useEffect, useRef } from 'react';
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
export function CreateEventDispatcherHook(type: string, eventDispatcher: IEventDispatcher, handler: (event: NitroEvent) => void): void
|
export function CreateEventDispatcherHook(type: string, eventDispatcher: IEventDispatcher, handler: (event: NitroEvent) => void): void
|
||||||
{
|
{
|
||||||
const handlerRef = useRef<(event: NitroEvent) => void>();
|
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
handlerRef.current = handler;
|
eventDispatcher.addEventListener(type, handler);
|
||||||
}, [ handler ]);
|
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
eventDispatcher.addEventListener(type, handlerRef.current);
|
|
||||||
|
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
eventDispatcher.removeEventListener(type, handlerRef.current);
|
eventDispatcher.removeEventListener(type, handler);
|
||||||
}
|
}
|
||||||
}, [ type, eventDispatcher ]);
|
}, [ type, eventDispatcher, handler ]);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function DispatchEventHook(eventDispatcher: IEventDispatcher, event: NitroEvent): void
|
export function DispatchEventHook(eventDispatcher: IEventDispatcher, event: NitroEvent): void
|
||||||
|
@ -19,7 +19,7 @@ $nitro-card-top-height: $nitro-card-header-height + $nitro-card-tabs-height;
|
|||||||
@import './tabs/NitroCardTabsView';
|
@import './tabs/NitroCardTabsView';
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-down(md) {
|
@include media-breakpoint-down(lg) {
|
||||||
|
|
||||||
.draggable-window {
|
.draggable-window {
|
||||||
top: 0 !important;
|
top: 0 !important;
|
||||||
@ -31,6 +31,7 @@ $nitro-card-top-height: $nitro-card-header-height + $nitro-card-tabs-height;
|
|||||||
|
|
||||||
.nitro-card {
|
.nitro-card {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
|
||||||
&.rounded {
|
&.rounded {
|
||||||
border-radius: 0 !important;
|
border-radius: 0 !important;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
padding-bottom: $container-padding-x;
|
padding-bottom: $container-padding-x;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-breakpoint-down(md) {
|
@include media-breakpoint-down(lg) {
|
||||||
|
|
||||||
.content-area {
|
.content-area {
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
|
@ -4,11 +4,11 @@ import { NitroCardTabsItemViewProps } from './NitroCardTabsItemView.types';
|
|||||||
|
|
||||||
export const NitroCardTabsItemView: FC<NitroCardTabsItemViewProps> = props =>
|
export const NitroCardTabsItemView: FC<NitroCardTabsItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { tabText = '', isActive = false, onClick = null } = props;
|
const { children = null, isActive = false, onClick = null } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="nav-item me-1 cursor-pointer" onClick={ onClick }>
|
<li className="nav-item me-1 cursor-pointer" onClick={ onClick }>
|
||||||
<span className={ 'nav-link ' + classNames({ 'active': isActive }) }>{ tabText }</span>
|
<span className={ 'nav-link ' + classNames({ 'active': isActive }) }>{ children }</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ import { MouseEventHandler } from 'react';
|
|||||||
|
|
||||||
export interface NitroCardTabsItemViewProps
|
export interface NitroCardTabsItemViewProps
|
||||||
{
|
{
|
||||||
tabText?: string;
|
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
onClick?: MouseEventHandler<HTMLLIElement>;
|
onClick?: MouseEventHandler<HTMLLIElement>;
|
||||||
}
|
}
|
||||||
|
32
src/layout/scrollable-area/ScrollableAreaView.tsx
Normal file
32
src/layout/scrollable-area/ScrollableAreaView.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { ScrollableAreaViewProps } from './ScrollableAreaView.types';
|
||||||
|
|
||||||
|
export const ScrollableAreaView: FC<ScrollableAreaViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { className = null, children = null } = props;
|
||||||
|
const [ height, setHeight ] = useState(0);
|
||||||
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
|
const resize = useCallback(() =>
|
||||||
|
{
|
||||||
|
setHeight(elementRef.current.parentElement.clientHeight);
|
||||||
|
}, [ elementRef ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
resize();
|
||||||
|
|
||||||
|
window.addEventListener('resize', resize);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
window.removeEventListener('resize', resize);
|
||||||
|
}
|
||||||
|
}, [ resize ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ elementRef } className={ className } style={ { 'overflowY': 'auto', height } }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
4
src/layout/scrollable-area/ScrollableAreaView.types.ts
Normal file
4
src/layout/scrollable-area/ScrollableAreaView.types.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface ScrollableAreaViewProps
|
||||||
|
{
|
||||||
|
className?: string;
|
||||||
|
}
|
@ -1 +0,0 @@
|
|||||||
@import './currency-icon/CurrencyIcon.scss';
|
|
@ -3,6 +3,7 @@
|
|||||||
@import './badge-image/BadgeImage';
|
@import './badge-image/BadgeImage';
|
||||||
@import './catalog/CatalogView';
|
@import './catalog/CatalogView';
|
||||||
@import './catalog-icon/CatalogIconView';
|
@import './catalog-icon/CatalogIconView';
|
||||||
|
@import './currency-icon/CurrencyIcon';
|
||||||
@import './friend-list/FriendListView';
|
@import './friend-list/FriendListView';
|
||||||
@import './furni-image/FurniImageView';
|
@import './furni-image/FurniImageView';
|
||||||
@import './hotel-view/HotelView';
|
@import './hotel-view/HotelView';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { CatalogApproveNameResultEvent, CatalogClubEvent, CatalogPageEvent, CatalogPagesEvent, CatalogPurchaseEvent, CatalogPurchaseFailedEvent, CatalogPurchaseUnavailableEvent, CatalogSearchEvent, CatalogSoldOutEvent, SellablePetPalettesEvent } from 'nitro-renderer';
|
import { CatalogApproveNameResultEvent, CatalogClubEvent, CatalogPageEvent, CatalogPagesEvent, CatalogPurchaseEvent, CatalogPurchaseFailedEvent, CatalogPurchaseUnavailableEvent, CatalogSearchEvent, CatalogSoldOutEvent, CatalogUpdatedEvent, SellablePetPalettesEvent, UserSubscriptionEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent } from '../../events';
|
import { CatalogNameResultEvent, CatalogPurchaseFailureEvent } from '../../events';
|
||||||
import { CatalogPurchasedEvent } from '../../events/catalog/CatalogPurchasedEvent';
|
import { CatalogPurchasedEvent } from '../../events/catalog/CatalogPurchasedEvent';
|
||||||
@ -9,6 +9,7 @@ import { CatalogMessageHandlerProps } from './CatalogMessageHandler.types';
|
|||||||
import { useCatalogContext } from './context/CatalogContext';
|
import { useCatalogContext } from './context/CatalogContext';
|
||||||
import { CatalogActions } from './reducers/CatalogReducer';
|
import { CatalogActions } from './reducers/CatalogReducer';
|
||||||
import { CatalogPetPalette } from './utils/CatalogPetPalette';
|
import { CatalogPetPalette } from './utils/CatalogPetPalette';
|
||||||
|
import { SubscriptionInfo } from './utils/SubscriptionInfo';
|
||||||
|
|
||||||
export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
@ -106,6 +107,32 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
|||||||
});
|
});
|
||||||
}, [ dispatchCatalogState ]);
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
|
const onUserSubscriptionEvent = useCallback((event: UserSubscriptionEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchCatalogState({
|
||||||
|
type: CatalogActions.SET_SUBSCRIPTION_INFO,
|
||||||
|
payload: {
|
||||||
|
subscriptionInfo: new SubscriptionInfo(
|
||||||
|
Math.max(0, parser.days),
|
||||||
|
Math.max(0, parser.months),
|
||||||
|
parser.isVip,
|
||||||
|
parser.pastClubDays,
|
||||||
|
parser.pastVIPDays
|
||||||
|
)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
|
const onCatalogUpdatedEvent = useCallback((event: CatalogUpdatedEvent) =>
|
||||||
|
{
|
||||||
|
dispatchCatalogState({
|
||||||
|
type: CatalogActions.RESET_STATE,
|
||||||
|
payload: {}
|
||||||
|
});
|
||||||
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
CreateMessageHook(CatalogPagesEvent, onCatalogPagesEvent);
|
CreateMessageHook(CatalogPagesEvent, onCatalogPagesEvent);
|
||||||
CreateMessageHook(CatalogPageEvent, onCatalogPageEvent);
|
CreateMessageHook(CatalogPageEvent, onCatalogPageEvent);
|
||||||
CreateMessageHook(CatalogPurchaseEvent, onCatalogPurchaseEvent);
|
CreateMessageHook(CatalogPurchaseEvent, onCatalogPurchaseEvent);
|
||||||
@ -116,6 +143,8 @@ export const CatalogMessageHandler: FC<CatalogMessageHandlerProps> = props =>
|
|||||||
CreateMessageHook(SellablePetPalettesEvent, onSellablePetPalettesEvent);
|
CreateMessageHook(SellablePetPalettesEvent, onSellablePetPalettesEvent);
|
||||||
CreateMessageHook(CatalogApproveNameResultEvent, onCatalogApproveNameResultEvent);
|
CreateMessageHook(CatalogApproveNameResultEvent, onCatalogApproveNameResultEvent);
|
||||||
CreateMessageHook(CatalogClubEvent, onCatalogClubEvent);
|
CreateMessageHook(CatalogClubEvent, onCatalogClubEvent);
|
||||||
|
CreateMessageHook(UserSubscriptionEvent, onUserSubscriptionEvent);
|
||||||
|
CreateMessageHook(CatalogUpdatedEvent, onCatalogUpdatedEvent);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { CatalogModeComposer, ICatalogPageData, RoomPreviewer } from 'nitro-renderer';
|
import { CatalogModeComposer, ICatalogPageData, RoomPreviewer } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../api';
|
import { GetRoomEngine } from '../../api';
|
||||||
|
import { GetCatalogPageComposer } from '../../api/catalog/GetCatalogPageComposer';
|
||||||
import { CatalogEvent } from '../../events';
|
import { CatalogEvent } from '../../events';
|
||||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { SendMessageHook } from '../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||||
@ -12,14 +13,13 @@ import { CatalogContextProvider } from './context/CatalogContext';
|
|||||||
import { CatalogActions, CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
import { CatalogActions, CatalogReducer, initialCatalog } from './reducers/CatalogReducer';
|
||||||
import { CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
import { CatalogNavigationView } from './views/navigation/CatalogNavigationView';
|
||||||
import { CatalogPageView } from './views/page/CatalogPageView';
|
import { CatalogPageView } from './views/page/CatalogPageView';
|
||||||
import { CatalogSearchView } from './views/search/CatalogSearchView';
|
|
||||||
|
|
||||||
export const CatalogView: FC<CatalogViewProps> = props =>
|
export const CatalogView: FC<CatalogViewProps> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
||||||
const [ catalogState, dispatchCatalogState ] = useReducer(CatalogReducer, initialCatalog);
|
const [ catalogState, dispatchCatalogState ] = useReducer(CatalogReducer, initialCatalog);
|
||||||
const { root = null, currentTab = null, activeOffer = null, searchResult = null } = catalogState;
|
const { root = null, currentTab = null, pageParser = null, activeOffer = null, searchResult = null } = catalogState;
|
||||||
|
|
||||||
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
const onCatalogEvent = useCallback((event: CatalogEvent) =>
|
||||||
{
|
{
|
||||||
@ -40,6 +40,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
useUiEvent(CatalogEvent.SHOW_CATALOG, onCatalogEvent);
|
useUiEvent(CatalogEvent.SHOW_CATALOG, onCatalogEvent);
|
||||||
useUiEvent(CatalogEvent.HIDE_CATALOG, onCatalogEvent);
|
useUiEvent(CatalogEvent.HIDE_CATALOG, onCatalogEvent);
|
||||||
useUiEvent(CatalogEvent.TOGGLE_CATALOG, onCatalogEvent);
|
useUiEvent(CatalogEvent.TOGGLE_CATALOG, onCatalogEvent);
|
||||||
|
useUiEvent(CatalogEvent.CATALOG_RESET, onCatalogEvent);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -51,6 +52,13 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ isVisible, catalogState.root ]);
|
}, [ isVisible, catalogState.root ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!currentTab) return;
|
||||||
|
|
||||||
|
SendMessageHook(GetCatalogPageComposer(currentTab.pageId, -1, CatalogMode.MODE_NORMAL));
|
||||||
|
}, [ currentTab ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
||||||
@ -66,7 +74,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
function setCurrentTab(page: ICatalogPageData): void
|
const setCurrentTab = useCallback((page: ICatalogPageData) =>
|
||||||
{
|
{
|
||||||
dispatchCatalogState({
|
dispatchCatalogState({
|
||||||
type: CatalogActions.SET_CATALOG_CURRENT_TAB,
|
type: CatalogActions.SET_CATALOG_CURRENT_TAB,
|
||||||
@ -74,7 +82,7 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
currentTab: page
|
currentTab: page
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}, [ dispatchCatalogState ]);
|
||||||
|
|
||||||
const currentNavigationPage = ((searchResult && searchResult.page) || currentTab);
|
const currentNavigationPage = ((searchResult && searchResult.page) || currentTab);
|
||||||
|
|
||||||
@ -87,15 +95,19 @@ export const CatalogView: FC<CatalogViewProps> = props =>
|
|||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
{ root && root.children.length && root.children.map((page, index) =>
|
{ root && root.children.length && root.children.map((page, index) =>
|
||||||
{
|
{
|
||||||
return <NitroCardTabsItemView key={ index } tabText={ page.localization } isActive={ (currentTab === page) } onClick={ event => setCurrentTab(page) } />
|
return (
|
||||||
|
<NitroCardTabsItemView key={ index } isActive={ (currentTab === page) } onClick={ event => setCurrentTab(page) }>
|
||||||
|
{ page.localization }
|
||||||
|
</NitroCardTabsItemView>
|
||||||
|
);
|
||||||
}) }
|
}) }
|
||||||
</NitroCardTabsView>
|
</NitroCardTabsView>
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
<div className="row h-100">
|
<div className="row h-100">
|
||||||
|
{ pageParser && !pageParser.frontPageItems.length &&
|
||||||
<div className="col-3">
|
<div className="col-3">
|
||||||
<CatalogSearchView />
|
|
||||||
<CatalogNavigationView page={ currentNavigationPage } />
|
<CatalogNavigationView page={ currentNavigationPage } />
|
||||||
</div>
|
</div> }
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<CatalogPageView roomPreviewer={ roomPreviewer } />
|
<CatalogPageView roomPreviewer={ roomPreviewer } />
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,17 +2,20 @@ import { CatalogClubOfferData, CatalogPageOfferData, ICatalogPageData, ICatalogP
|
|||||||
import { Reducer } from 'react';
|
import { Reducer } from 'react';
|
||||||
import { CatalogPetPalette } from '../utils/CatalogPetPalette';
|
import { CatalogPetPalette } from '../utils/CatalogPetPalette';
|
||||||
import { ICatalogOffers, ICatalogSearchResult, SetOffersToNodes } from '../utils/CatalogUtilities';
|
import { ICatalogOffers, ICatalogSearchResult, SetOffersToNodes } from '../utils/CatalogUtilities';
|
||||||
|
import { SubscriptionInfo } from '../utils/SubscriptionInfo';
|
||||||
|
|
||||||
export interface ICatalogState
|
export interface ICatalogState
|
||||||
{
|
{
|
||||||
root: ICatalogPageData;
|
root: ICatalogPageData;
|
||||||
offerRoot: ICatalogOffers;
|
offerRoot: ICatalogOffers;
|
||||||
currentTab: ICatalogPageData;
|
currentTab: ICatalogPageData;
|
||||||
|
currentPage: ICatalogPageData;
|
||||||
pageParser: ICatalogPageParser;
|
pageParser: ICatalogPageParser;
|
||||||
activeOffer: CatalogPageOfferData;
|
activeOffer: CatalogPageOfferData;
|
||||||
searchResult: ICatalogSearchResult;
|
searchResult: ICatalogSearchResult;
|
||||||
petPalettes: CatalogPetPalette[];
|
petPalettes: CatalogPetPalette[];
|
||||||
clubOffers: CatalogClubOfferData[];
|
clubOffers: CatalogClubOfferData[];
|
||||||
|
subscriptionInfo: SubscriptionInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ICatalogAction
|
export interface ICatalogAction
|
||||||
@ -22,11 +25,13 @@ export interface ICatalogAction
|
|||||||
root?: ICatalogPageData;
|
root?: ICatalogPageData;
|
||||||
offerRoot?: ICatalogOffers;
|
offerRoot?: ICatalogOffers;
|
||||||
currentTab?: ICatalogPageData;
|
currentTab?: ICatalogPageData;
|
||||||
|
currentPage?: ICatalogPageData;
|
||||||
pageParser?: ICatalogPageParser;
|
pageParser?: ICatalogPageParser;
|
||||||
activeOffer?: CatalogPageOfferData;
|
activeOffer?: CatalogPageOfferData;
|
||||||
searchResult?: ICatalogSearchResult;
|
searchResult?: ICatalogSearchResult;
|
||||||
petPalette?: CatalogPetPalette;
|
petPalette?: CatalogPetPalette;
|
||||||
clubOffers?: CatalogClubOfferData[];
|
clubOffers?: CatalogClubOfferData[];
|
||||||
|
subscriptionInfo?: SubscriptionInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,22 +39,27 @@ export class CatalogActions
|
|||||||
{
|
{
|
||||||
public static SET_CATALOG_ROOT: string = 'CA_SET_CATALOG_ROOT';
|
public static SET_CATALOG_ROOT: string = 'CA_SET_CATALOG_ROOT';
|
||||||
public static SET_CATALOG_CURRENT_TAB: string = 'CA_SET_CATALOG_CURRENT_TAB';
|
public static SET_CATALOG_CURRENT_TAB: string = 'CA_SET_CATALOG_CURRENT_TAB';
|
||||||
|
public static SET_CATALOG_CURRENT_PAGE: string = 'CA_SET_CATALOG_CURRENT_PAGE';
|
||||||
public static SET_CATALOG_PAGE_PARSER: string = 'CA_SET_CATALOG_PAGE';
|
public static SET_CATALOG_PAGE_PARSER: string = 'CA_SET_CATALOG_PAGE';
|
||||||
public static SET_CATALOG_ACTIVE_OFFER: string = 'CA_SET_ACTIVE_OFFER';
|
public static SET_CATALOG_ACTIVE_OFFER: string = 'CA_SET_ACTIVE_OFFER';
|
||||||
public static SET_SEARCH_RESULT: string = 'CA_SET_SEARCH_RESULT';
|
public static SET_SEARCH_RESULT: string = 'CA_SET_SEARCH_RESULT';
|
||||||
public static SET_PET_PALETTE: string = 'CA_SET_PET_PALETTE';
|
public static SET_PET_PALETTE: string = 'CA_SET_PET_PALETTE';
|
||||||
public static SET_CLUB_OFFERS: string = 'CA_SET_CLUB_OFFERS';
|
public static SET_CLUB_OFFERS: string = 'CA_SET_CLUB_OFFERS';
|
||||||
|
public static SET_SUBSCRIPTION_INFO: string = 'CA_SET_SUBSCRIPTION_INFO';
|
||||||
|
public static RESET_STATE = 'CA_RESET_STATE';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialCatalog: ICatalogState = {
|
export const initialCatalog: ICatalogState = {
|
||||||
root: null,
|
root: null,
|
||||||
offerRoot: null,
|
offerRoot: null,
|
||||||
currentTab: null,
|
currentTab: null,
|
||||||
|
currentPage: null,
|
||||||
pageParser: null,
|
pageParser: null,
|
||||||
activeOffer: null,
|
activeOffer: null,
|
||||||
searchResult: null,
|
searchResult: null,
|
||||||
petPalettes: [],
|
petPalettes: [],
|
||||||
clubOffers: null
|
clubOffers: null,
|
||||||
|
subscriptionInfo: new SubscriptionInfo()
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, action) =>
|
export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, action) =>
|
||||||
@ -72,8 +82,13 @@ export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, ac
|
|||||||
|
|
||||||
return { ...state, currentTab, searchResult };
|
return { ...state, currentTab, searchResult };
|
||||||
}
|
}
|
||||||
|
case CatalogActions.SET_CATALOG_CURRENT_PAGE: {
|
||||||
|
const currentPage = (action.payload.currentPage || state.currentPage || null);
|
||||||
|
|
||||||
|
return { ...state, currentPage };
|
||||||
|
}
|
||||||
case CatalogActions.SET_CATALOG_PAGE_PARSER: {
|
case CatalogActions.SET_CATALOG_PAGE_PARSER: {
|
||||||
let pageParser = Object.create(action.payload.pageParser);
|
let pageParser = (Object.create(action.payload.pageParser) as ICatalogPageParser);
|
||||||
let activeOffer = null;
|
let activeOffer = null;
|
||||||
|
|
||||||
if(pageParser.layoutCode === 'single_bundle')
|
if(pageParser.layoutCode === 'single_bundle')
|
||||||
@ -126,6 +141,14 @@ export const CatalogReducer: Reducer<ICatalogState, ICatalogAction> = (state, ac
|
|||||||
|
|
||||||
return { ...state, clubOffers };
|
return { ...state, clubOffers };
|
||||||
}
|
}
|
||||||
|
case CatalogActions.SET_SUBSCRIPTION_INFO: {
|
||||||
|
const subscriptionInfo = (action.payload.subscriptionInfo || null);
|
||||||
|
|
||||||
|
return { ...state, subscriptionInfo };
|
||||||
|
}
|
||||||
|
case CatalogActions.RESET_STATE: {
|
||||||
|
return { ...initialCatalog };
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
14
src/views/catalog/utils/IPurse.ts
Normal file
14
src/views/catalog/utils/IPurse.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface IPurse
|
||||||
|
{
|
||||||
|
_Str_14389: boolean;
|
||||||
|
_Str_4458: number;
|
||||||
|
credits: number;
|
||||||
|
clubDays: number;
|
||||||
|
clubPeriods: number;
|
||||||
|
_Str_13571: boolean;
|
||||||
|
_Str_3738: boolean;
|
||||||
|
_Str_6288: number;
|
||||||
|
_Str_4605: number;
|
||||||
|
_Str_6312: number;
|
||||||
|
_Str_5590(_arg_1: number): number;
|
||||||
|
}
|
144
src/views/catalog/utils/Purse.ts
Normal file
144
src/views/catalog/utils/Purse.ts
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
import { Nitro } from 'nitro-renderer';
|
||||||
|
import { IPurse } from './IPurse';
|
||||||
|
|
||||||
|
export class Purse implements IPurse
|
||||||
|
{
|
||||||
|
private _credits: number = 0;
|
||||||
|
private _activityPoints: Map<number, number>;
|
||||||
|
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;
|
||||||
|
|
||||||
|
public get credits(): number
|
||||||
|
{
|
||||||
|
return this._credits;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set credits(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._credits = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get clubDays(): number
|
||||||
|
{
|
||||||
|
return this._clubDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set clubDays(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._clubDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get clubPeriods(): number
|
||||||
|
{
|
||||||
|
return this._clubPeriods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set clubPeriods(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._clubPeriods = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_13571(): boolean
|
||||||
|
{
|
||||||
|
return (this._clubDays > 0) || (this._clubPeriods > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_3738(): boolean
|
||||||
|
{
|
||||||
|
return this._isVIP;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_14389(): boolean
|
||||||
|
{
|
||||||
|
return this._isExpiring;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_14389(k: boolean)
|
||||||
|
{
|
||||||
|
this._isExpiring = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_3738(k: boolean)
|
||||||
|
{
|
||||||
|
this._isVIP = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_6288(): number
|
||||||
|
{
|
||||||
|
return this._pastClubDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_6288(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._pastClubDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_4605(): number
|
||||||
|
{
|
||||||
|
return this._pastVipDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_4605(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._pastVipDays = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_18527(): Map<number, number>
|
||||||
|
{
|
||||||
|
return this._activityPoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_18527(k: Map<number, number>)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._activityPoints = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public _Str_5590(k: number): number
|
||||||
|
{
|
||||||
|
return this._activityPoints[k];
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_4458(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
|
||||||
|
this._minutesUntilExpiration = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_4458(): number
|
||||||
|
{
|
||||||
|
const k = ((Nitro.instance.time - this._lastUpdated) / (1000 * 60));
|
||||||
|
const _local_2 = (this._minutesUntilExpiration - k);
|
||||||
|
|
||||||
|
return (_local_2 > 0) ? _local_2 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set _Str_6312(k: number)
|
||||||
|
{
|
||||||
|
this._lastUpdated = Nitro.instance.time;
|
||||||
|
this._minutesSinceLastModified = k;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_6312(): number
|
||||||
|
{
|
||||||
|
return this._minutesSinceLastModified;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get _Str_26225(): number
|
||||||
|
{
|
||||||
|
return this._lastUpdated;
|
||||||
|
}
|
||||||
|
}
|
17
src/views/catalog/utils/SubscriptionInfo.ts
Normal file
17
src/views/catalog/utils/SubscriptionInfo.ts
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
|
||||||
|
export class SubscriptionInfo
|
||||||
|
{
|
||||||
|
private _lastUpdated: number;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
public clubDays: number = 0,
|
||||||
|
public clubPeriods: number = 0,
|
||||||
|
public isVip: boolean = false,
|
||||||
|
public pastDays: number = 0,
|
||||||
|
public pastVipDays: number = 0) {}
|
||||||
|
|
||||||
|
public get lastUpdated(): number
|
||||||
|
{
|
||||||
|
return this._lastUpdated;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import { ICatalogPageData } from 'nitro-renderer';
|
import { ICatalogPageData } from 'nitro-renderer';
|
||||||
import { FC, useEffect } from 'react';
|
import { FC, useEffect } from 'react';
|
||||||
|
import { CatalogSearchView } from '../search/CatalogSearchView';
|
||||||
import { CatalogNavigationViewProps } from './CatalogNavigationView.types';
|
import { CatalogNavigationViewProps } from './CatalogNavigationView.types';
|
||||||
import { CatalogNavigationSetView } from './set/CatalogNavigationSetView';
|
import { CatalogNavigationSetView } from './set/CatalogNavigationSetView';
|
||||||
|
|
||||||
@ -17,10 +18,13 @@ export const CatalogNavigationView: FC<CatalogNavigationViewProps> = props =>
|
|||||||
}, [ page ]);
|
}, [ page ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<>
|
||||||
|
<CatalogSearchView />
|
||||||
<div className="border border-2 rounded overflow-hidden nitro-catalog-navigation">
|
<div className="border border-2 rounded overflow-hidden nitro-catalog-navigation">
|
||||||
<div className="navigation-container m-1">
|
<div className="navigation-container m-1">
|
||||||
<CatalogNavigationSetView page={ page } isFirstSet={ true } />
|
<CatalogNavigationSetView page={ page } isFirstSet={ true } />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,12 @@ export const CatalogNavigationSetView: FC<CatalogNavigationSetViewProps> = props
|
|||||||
{
|
{
|
||||||
if(!isFirstSet || !page || (page.pageId === -1)) return;
|
if(!isFirstSet || !page || (page.pageId === -1)) return;
|
||||||
|
|
||||||
if(page && page.children.length) setActiveChild(page.children[0]);
|
if(page && page.children.length)
|
||||||
|
{
|
||||||
|
const child = page.children[0];
|
||||||
|
|
||||||
|
setActiveChild(child);
|
||||||
|
}
|
||||||
}, [ page, isFirstSet ]);
|
}, [ page, isFirstSet ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@import './header/CatalogPageHeaderView';
|
||||||
@import './layout/CatalogLayout';
|
@import './layout/CatalogLayout';
|
||||||
@import './offer/CatalogPageOfferView';
|
@import './offer/CatalogPageOfferView';
|
||||||
@import './offers/CatalogPageOffersView';
|
@import './offers/CatalogPageOffersView';
|
||||||
|
@ -0,0 +1,3 @@
|
|||||||
|
.nitro-catalog-page-header {
|
||||||
|
padding-top: $container-padding-x;
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { CatalogIconView } from '../../../../catalog-icon/CatalogIconView';
|
||||||
|
import { useCatalogContext } from '../../../context/CatalogContext';
|
||||||
|
import { CatalogPageHeaderViewProps } from './CatalogPageHeaderView.types';
|
||||||
|
|
||||||
|
export const CatalogPageHeaderView: FC<CatalogPageHeaderViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { catalogState = null } = useCatalogContext();
|
||||||
|
const { currentPage = null, pageParser = null } = catalogState;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container-fluid nitro-catalog-page-header bg-light">
|
||||||
|
<div className="row h-100">
|
||||||
|
<div className="col-2">
|
||||||
|
<CatalogIconView icon={ currentPage.icon } />
|
||||||
|
</div>
|
||||||
|
<div className="d-flex col-10 flex-column">
|
||||||
|
<div className="d-block">
|
||||||
|
{ currentPage.localization }
|
||||||
|
</div>
|
||||||
|
{ pageParser && <div className="d-block">
|
||||||
|
{ pageParser.localization.texts[0] }
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { ICatalogPageParser } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export interface CatalogPageHeaderViewProps
|
||||||
|
{
|
||||||
|
pageParser: ICatalogPageParser;
|
||||||
|
}
|
@ -1,5 +1,7 @@
|
|||||||
@import './default/CatalogLayoutDefaultView';
|
@import './default/CatalogLayoutDefaultView';
|
||||||
|
@import './frontpage4/CatalogLayoutFrontpage4View';
|
||||||
@import './pets/CatalogLayoutPetView';
|
@import './pets/CatalogLayoutPetView';
|
||||||
|
@import './pets3/CatalogLayoutPets3View';
|
||||||
@import './single-bundle/CatalogLayoutSingleBundleView';
|
@import './single-bundle/CatalogLayoutSingleBundleView';
|
||||||
@import './spaces-new/CatalogLayoutSpacesView';
|
@import './spaces-new/CatalogLayoutSpacesView';
|
||||||
@import './trophies/CatalogLayoutTrophiesView';
|
@import './trophies/CatalogLayoutTrophiesView';
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { ICatalogPageParser, RoomPreviewer } from 'nitro-renderer';
|
import { ICatalogPageParser, RoomPreviewer } from 'nitro-renderer';
|
||||||
import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView';
|
import { CatalogLayoutDefaultView } from './default/CatalogLayoutDefaultView';
|
||||||
|
import { CatalogLayoutFrontpage4View } from './frontpage4/CatalogLayoutFrontpage4View';
|
||||||
import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView';
|
import { CatalogLayoutPetView } from './pets/CatalogLayoutPetView';
|
||||||
|
import { CatalogLayoutPets3View } from './pets3/CatalogLayoutPets3View';
|
||||||
import { CatalogLayoutSingleBundleView } from './single-bundle/CatalogLayoutSingleBundleView';
|
import { CatalogLayoutSingleBundleView } from './single-bundle/CatalogLayoutSingleBundleView';
|
||||||
import { CatalogLayoutSpacesView } from './spaces-new/CatalogLayoutSpacesView';
|
import { CatalogLayoutSpacesView } from './spaces-new/CatalogLayoutSpacesView';
|
||||||
import { CatalogLayoutTrophiesView } from './trophies/CatalogLayoutTrophiesView';
|
import { CatalogLayoutTrophiesView } from './trophies/CatalogLayoutTrophiesView';
|
||||||
@ -13,13 +15,13 @@ export function GetCatalogLayout(pageParser: ICatalogPageParser, roomPreviewer:
|
|||||||
case 'frontpage_featured':
|
case 'frontpage_featured':
|
||||||
return null;
|
return null;
|
||||||
case 'frontpage4':
|
case 'frontpage4':
|
||||||
return null;
|
return <CatalogLayoutFrontpage4View roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'pets':
|
case 'pets':
|
||||||
return <CatalogLayoutPetView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
return <CatalogLayoutPetView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'pets2':
|
case 'pets2':
|
||||||
return null;
|
return null;
|
||||||
case 'pets3':
|
case 'pets3':
|
||||||
return null;
|
return <CatalogLayoutPets3View roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'vip_buy':
|
case 'vip_buy':
|
||||||
return <CatalogLayoutVipBuyView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
return <CatalogLayoutVipBuyView roomPreviewer={ roomPreviewer } pageParser={ pageParser } />;
|
||||||
case 'guild_frontpage':
|
case 'guild_frontpage':
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
.nitro-catalog-layout-frontpage4 {
|
||||||
|
|
||||||
|
.front-page-item {
|
||||||
|
position: relative;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.front-page-item-caption {
|
||||||
|
position: absolute;
|
||||||
|
background: rgba(0, 0, 0, .5);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 16px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 10px;
|
||||||
|
padding: 5px 15px;
|
||||||
|
bottom: 0;
|
||||||
|
text-shadow: 2px 2px rgba(0, 0, 0, .2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
import { FC, useCallback, useMemo } from 'react';
|
||||||
|
import { GetConfiguration } from '../../../../../../utils/GetConfiguration';
|
||||||
|
import { CatalogLayoutFrontpage4ViewProps } from './CatalogLayoutFrontpage4View.types';
|
||||||
|
|
||||||
|
export const CatalogLayoutFrontpage4View: FC<CatalogLayoutFrontpage4ViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { pageParser = null } = props;
|
||||||
|
|
||||||
|
const getFrontPageItem = useCallback((position: number) =>
|
||||||
|
{
|
||||||
|
for(const item of pageParser.frontPageItems)
|
||||||
|
{
|
||||||
|
if(item.position !== position) continue;
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}, [ pageParser ]);
|
||||||
|
|
||||||
|
const getFrontPageItemImage = useCallback((position: number) =>
|
||||||
|
{
|
||||||
|
const item = getFrontPageItem(position);
|
||||||
|
|
||||||
|
if(!item) return null;
|
||||||
|
|
||||||
|
return item.itemPromoImage;
|
||||||
|
}, [ getFrontPageItem ]);
|
||||||
|
|
||||||
|
const imageLibraryUrl = useMemo(() =>
|
||||||
|
{
|
||||||
|
return GetConfiguration<string>('image.library.url');
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
if(!pageParser) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row h-100 nitro-catalog-layout-frontpage4">
|
||||||
|
<div className="col-4">
|
||||||
|
{ pageParser.frontPageItems[0] &&
|
||||||
|
<div className="front-page-item h-100" style={ { backgroundImage: `url('${ imageLibraryUrl }${ pageParser.frontPageItems[0].itemPromoImage }')`}}>
|
||||||
|
<div className="front-page-item-caption">{ pageParser.frontPageItems[0].itemName }</div>
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
<div className="d-flex col-8 flex-column">
|
||||||
|
{ pageParser.frontPageItems[1] &&
|
||||||
|
<div className="front-page-item h-100 mb-2" style={ { backgroundImage: `url('${ imageLibraryUrl }${ pageParser.frontPageItems[1].itemPromoImage }')`}}>
|
||||||
|
<div className="front-page-item-caption">{ pageParser.frontPageItems[1].itemName }</div>
|
||||||
|
</div> }
|
||||||
|
{ pageParser.frontPageItems[2] &&
|
||||||
|
<div className="front-page-item h-100 mb-2" style={ { backgroundImage: `url('${ imageLibraryUrl }${ pageParser.frontPageItems[2].itemPromoImage }')`}}>
|
||||||
|
<div className="front-page-item-caption">{ pageParser.frontPageItems[2].itemName }</div>
|
||||||
|
</div> }
|
||||||
|
{ pageParser.frontPageItems[3] &&
|
||||||
|
<div className="front-page-item h-100" style={ { backgroundImage: `url('${ imageLibraryUrl }${ pageParser.frontPageItems[3].itemPromoImage }')`}}>
|
||||||
|
<div className="front-page-item-caption">{ pageParser.frontPageItems[3].itemName }</div>
|
||||||
|
</div> }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||||
|
|
||||||
|
export interface CatalogLayoutFrontpage4ViewProps extends CatalogLayoutProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -7,7 +7,7 @@ import { PetImageView } from '../../../../../pet-image/PetImageView';
|
|||||||
import { RoomPreviewerView } from '../../../../../room-previewer/RoomPreviewerView';
|
import { RoomPreviewerView } from '../../../../../room-previewer/RoomPreviewerView';
|
||||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||||
import { CatalogActions } from '../../../../reducers/CatalogReducer';
|
import { CatalogActions } from '../../../../reducers/CatalogReducer';
|
||||||
import { GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../utils/CatalogUtilities';
|
import { GetCatalogPageImage, GetCatalogPageText, GetPetAvailableColors, GetPetIndexFromLocalization } from '../../../../utils/CatalogUtilities';
|
||||||
import { CatalogLayoutPetViewProps } from './CatalogLayoutPetView.types';
|
import { CatalogLayoutPetViewProps } from './CatalogLayoutPetView.types';
|
||||||
import { CatalogLayoutPetPurchaseView } from './purchase/CatalogLayoutPetPurchaseView';
|
import { CatalogLayoutPetPurchaseView } from './purchase/CatalogLayoutPetPurchaseView';
|
||||||
|
|
||||||
@ -160,6 +160,14 @@ export const CatalogLayoutPetView: FC<CatalogLayoutPetViewProps> = props =>
|
|||||||
}) }
|
}) }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{ (petIndex === -1) &&
|
||||||
|
<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">{ GetCatalogPageText(pageParser, 0) }</div>
|
||||||
|
</div> }
|
||||||
|
{ (petIndex >= 0) &&
|
||||||
<div className="position-relative d-flex flex-column col-5">
|
<div className="position-relative d-flex flex-column col-5">
|
||||||
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 }>
|
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 }>
|
||||||
{ (petIndex > -1 && petIndex <= 7) &&
|
{ (petIndex > -1 && petIndex <= 7) &&
|
||||||
@ -169,7 +177,7 @@ export const CatalogLayoutPetView: FC<CatalogLayoutPetViewProps> = props =>
|
|||||||
</RoomPreviewerView>
|
</RoomPreviewerView>
|
||||||
<div className="fs-6 text-black mt-1 overflow-hidden">{ petBreedName }</div>
|
<div className="fs-6 text-black mt-1 overflow-hidden">{ petBreedName }</div>
|
||||||
<CatalogLayoutPetPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ petPurchaseString } />
|
<CatalogLayoutPetPurchaseView offer={ activeOffer } pageId={ pageParser.pageId } extra={ petPurchaseString } />
|
||||||
</div>
|
</div> }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,8 +3,8 @@ import { FC, useCallback, useState } from 'react';
|
|||||||
import { CatalogEvent } from '../../../../../../../events';
|
import { CatalogEvent } from '../../../../../../../events';
|
||||||
import { useUiEvent } from '../../../../../../../hooks/events/ui/ui-event';
|
import { useUiEvent } from '../../../../../../../hooks/events/ui/ui-event';
|
||||||
import { SendMessageHook } from '../../../../../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../../../../../hooks/messages/message-event';
|
||||||
import { CurrencyIcon } from '../../../../../../../utils/currency-icon/CurrencyIcon';
|
|
||||||
import { LocalizeText } from '../../../../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../../../../utils/LocalizeText';
|
||||||
|
import { CurrencyIcon } from '../../../../../../currency-icon/CurrencyIcon';
|
||||||
import { CatalogPurchaseButtonView } from '../../../purchase/purchase-button/CatalogPurchaseButtonView';
|
import { CatalogPurchaseButtonView } from '../../../purchase/purchase-button/CatalogPurchaseButtonView';
|
||||||
import { CatalogPetNameApprovalView } from '../name-approval/CatalogPetNameApprovalView';
|
import { CatalogPetNameApprovalView } from '../name-approval/CatalogPetNameApprovalView';
|
||||||
import { CatalogLayoutPetPurchaseViewProps } from './CatalogLayoutPetPurchaseView.types';
|
import { CatalogLayoutPetPurchaseViewProps } from './CatalogLayoutPetPurchaseView.types';
|
||||||
|
@ -0,0 +1,2 @@
|
|||||||
|
.nitro-catalog-layout-pets3 {
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { GetCatalogPageImage, GetCatalogPageText } from '../../../../utils/CatalogUtilities';
|
||||||
|
import { CatalogLayoutPets3ViewProps } from './CatalogLayoutPets3View.types';
|
||||||
|
|
||||||
|
export const CatalogLayoutPets3View: FC<CatalogLayoutPets3ViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { pageParser = null } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row h-100 nitro-catalog-layout-pets3">
|
||||||
|
<div className="col-7">
|
||||||
|
<div className="" dangerouslySetInnerHTML={ {__html: GetCatalogPageText(pageParser, 1) } } />
|
||||||
|
<div className="" dangerouslySetInnerHTML={ {__html: GetCatalogPageText(pageParser, 2) } } />
|
||||||
|
<div className="" dangerouslySetInnerHTML={ {__html: GetCatalogPageText(pageParser, 3) } } />
|
||||||
|
</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">{ GetCatalogPageText(pageParser, 0) }</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { CatalogLayoutProps } from '../CatalogLayout.types';
|
||||||
|
|
||||||
|
export interface CatalogLayoutPets3ViewProps extends CatalogLayoutProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -5,7 +5,7 @@ import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
|||||||
import { RoomPreviewerView } from '../../../../../room-previewer/RoomPreviewerView';
|
import { RoomPreviewerView } from '../../../../../room-previewer/RoomPreviewerView';
|
||||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||||
import { ProductTypeEnum } from '../../../../enums/ProductTypeEnum';
|
import { ProductTypeEnum } from '../../../../enums/ProductTypeEnum';
|
||||||
import { GetOfferName } from '../../../../utils/CatalogUtilities';
|
import { GetCatalogPageImage, GetCatalogPageText, GetOfferName } from '../../../../utils/CatalogUtilities';
|
||||||
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
|
import { CatalogPageOffersView } from '../../offers/CatalogPageOffersView';
|
||||||
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
|
import { CatalogPurchaseView } from '../../purchase/CatalogPurchaseView';
|
||||||
import { CatalogLayoutSpacesViewProps } from './CatalogLayoutSpacesView.types';
|
import { CatalogLayoutSpacesViewProps } from './CatalogLayoutSpacesView.types';
|
||||||
@ -81,6 +81,13 @@ export const CatalogLayoutSpacesView: FC<CatalogLayoutSpacesViewProps> = props =
|
|||||||
</div>
|
</div>
|
||||||
<CatalogPageOffersView offers={ groups[activeGroupIndex] } />
|
<CatalogPageOffersView offers={ groups[activeGroupIndex] } />
|
||||||
</div>
|
</div>
|
||||||
|
{ !product &&
|
||||||
|
<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">{ GetCatalogPageText(pageParser, 0) }</div>
|
||||||
|
</div> }
|
||||||
{ product &&
|
{ product &&
|
||||||
<div className="position-relative d-flex flex-column col">
|
<div className="position-relative d-flex flex-column col">
|
||||||
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
||||||
|
@ -1,16 +1,16 @@
|
|||||||
import { CatalogClubOfferData, CatalogRequestVipOffersComposer } from 'nitro-renderer';
|
import { CatalogClubOfferData, CatalogRequestVipOffersComposer } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect } from 'react';
|
import { FC, useCallback, useEffect, useMemo } from 'react';
|
||||||
import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../../../../hooks/messages/message-event';
|
||||||
import { CurrencyIcon } from '../../../../../../utils/currency-icon/CurrencyIcon';
|
|
||||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||||
|
import { CurrencyIcon } from '../../../../../currency-icon/CurrencyIcon';
|
||||||
import { useCatalogContext } from '../../../../context/CatalogContext';
|
import { useCatalogContext } from '../../../../context/CatalogContext';
|
||||||
import { GetCatalogPageImage, GetCatalogPageText } from '../../../../utils/CatalogUtilities';
|
import { GetCatalogPageImage } from '../../../../utils/CatalogUtilities';
|
||||||
import { CatalogLayoutVipBuyViewProps } from './CatalogLayoutVipBuyView.types';
|
import { CatalogLayoutVipBuyViewProps } from './CatalogLayoutVipBuyView.types';
|
||||||
|
|
||||||
export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =>
|
export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { catalogState = null } = useCatalogContext();
|
const { catalogState = null } = useCatalogContext();
|
||||||
const { pageParser = null, clubOffers = null } = catalogState;
|
const { pageParser = null, clubOffers = null, subscriptionInfo = null } = catalogState;
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
@ -41,6 +41,17 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
|||||||
return offerText;
|
return offerText;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const getSubscriptionDetails = useMemo(() =>
|
||||||
|
{
|
||||||
|
if(!subscriptionInfo) return '';
|
||||||
|
|
||||||
|
const clubDays = subscriptionInfo.clubDays;
|
||||||
|
const clubPeriods = subscriptionInfo.clubPeriods;
|
||||||
|
const totalDays = (clubPeriods * 31) + clubDays;
|
||||||
|
|
||||||
|
return LocalizeText('catalog.vip.extend.info', [ 'days' ], [ totalDays.toString() ]);
|
||||||
|
}, [ subscriptionInfo ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row h-100 nitro-catalog-layout-vip-buy">
|
<div className="row h-100 nitro-catalog-layout-vip-buy">
|
||||||
<div className="col-7">
|
<div className="col-7">
|
||||||
@ -74,7 +85,7 @@ export const CatalogLayoutVipBuyView: FC<CatalogLayoutVipBuyViewProps> = props =
|
|||||||
<div className="d-block mb-2">
|
<div className="d-block mb-2">
|
||||||
<img alt="" src={ GetCatalogPageImage(pageParser, 1) } />
|
<img alt="" src={ GetCatalogPageImage(pageParser, 1) } />
|
||||||
</div>
|
</div>
|
||||||
<div className="fs-6 text-center text-black lh-sm overflow-hidden">{ GetCatalogPageText(pageParser, 0) }</div>
|
<div className="fs-6 text-center text-black lh-sm overflow-hidden" dangerouslySetInnerHTML={ {__html: getSubscriptionDetails } }></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { CurrencyIcon } from '../../../../../utils/currency-icon/CurrencyIcon';
|
|
||||||
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||||
|
import { CurrencyIcon } from '../../../../currency-icon/CurrencyIcon';
|
||||||
import { CatalogPurchaseViewProps } from './CatalogPurchaseView.types';
|
import { CatalogPurchaseViewProps } from './CatalogPurchaseView.types';
|
||||||
import { CatalogPurchaseButtonView } from './purchase-button/CatalogPurchaseButtonView';
|
import { CatalogPurchaseButtonView } from './purchase-button/CatalogPurchaseButtonView';
|
||||||
|
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import { GetConfiguration } from '../GetConfiguration';
|
import { FC } from 'react';
|
||||||
|
import { GetConfiguration } from '../../utils/GetConfiguration';
|
||||||
import { CurrencyIconProps } from './CurrencyIcon.types';
|
import { CurrencyIconProps } from './CurrencyIcon.types';
|
||||||
|
|
||||||
export function CurrencyIcon(props: CurrencyIconProps): JSX.Element
|
export const CurrencyIcon: FC<CurrencyIconProps> = props =>
|
||||||
{
|
{
|
||||||
let url = GetConfiguration<string>('currency.asset.icon.url', '');
|
let url = GetConfiguration<string>('currency.asset.icon.url', '');
|
||||||
|
|
@ -42,8 +42,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.left {
|
.left {
|
||||||
width: 100%;
|
width: 1200px;
|
||||||
height: 100%;
|
height: 800px;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
animation-iteration-count: 1;
|
animation-iteration-count: 1;
|
||||||
|
@ -105,7 +105,11 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
{ tabs.map((name, index) =>
|
{ tabs.map((name, index) =>
|
||||||
{
|
{
|
||||||
return <NitroCardTabsItemView key={ index } tabText={ LocalizeText(name) } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) } />
|
return (
|
||||||
|
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) }>
|
||||||
|
{ LocalizeText(name) }
|
||||||
|
</NitroCardTabsItemView>
|
||||||
|
);
|
||||||
}) }
|
}) }
|
||||||
</NitroCardTabsView>
|
</NitroCardTabsView>
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
|
@ -76,8 +76,8 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="row">
|
<div className="row h-100">
|
||||||
<div className="col-7">
|
<div className="d-flex flex-column col-7">
|
||||||
<InventoryBadgeResultsView badges={ badges } activeBadges={ activeBadges } />
|
<InventoryBadgeResultsView badges={ badges } activeBadges={ activeBadges } />
|
||||||
</div>
|
</div>
|
||||||
<div className="col">
|
<div className="col">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { ScrollableAreaView } from '../../../../../layout/scrollable-area/ScrollableAreaView';
|
||||||
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
||||||
import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types';
|
import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types';
|
||||||
|
|
||||||
@ -7,13 +8,15 @@ export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = pro
|
|||||||
const { badges = [], activeBadges = [] } = props;
|
const { badges = [], activeBadges = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row row-cols-5 align-content-start g-0 badge-item-container">
|
<div className="d-flex flex-grow-1">
|
||||||
|
<ScrollableAreaView className="row row-cols-5 align-content-start g-0 w-100">
|
||||||
{ badges && (badges.length > 0) && badges.map((code, index) =>
|
{ badges && (badges.length > 0) && badges.map((code, index) =>
|
||||||
{
|
{
|
||||||
if(activeBadges.indexOf(code) >= 0) return null;
|
if(activeBadges.indexOf(code) >= 0) return null;
|
||||||
|
|
||||||
return <InventoryBadgeItemView key={ index } badge={ code } />
|
return <InventoryBadgeItemView key={ index } badge={ code } />
|
||||||
}) }
|
}) }
|
||||||
|
</ScrollableAreaView>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -81,8 +81,8 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row h-100">
|
||||||
<div className="col-7">
|
<div className="d-flex flex-column col-7">
|
||||||
<InventoryBotResultsView botItems={ botItems } />
|
<InventoryBotResultsView botItems={ botItems } />
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex flex-column col-5 justify-space-between">
|
<div className="d-flex flex-column col-5 justify-space-between">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { ScrollableAreaView } from '../../../../../layout/scrollable-area/ScrollableAreaView';
|
||||||
import { InventoryBotItemView } from '../item/InventoryBotItemView';
|
import { InventoryBotItemView } from '../item/InventoryBotItemView';
|
||||||
import { InventoryBotResultsViewProps } from './InventoryBotResultsView.types';
|
import { InventoryBotResultsViewProps } from './InventoryBotResultsView.types';
|
||||||
|
|
||||||
@ -7,11 +8,13 @@ export const InventoryBotResultsView: FC<InventoryBotResultsViewProps> = props =
|
|||||||
const { botItems = [] } = props;
|
const { botItems = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row row-cols-5 align-content-start g-0 bot-item-container">
|
<div className="d-flex flex-grow-1">
|
||||||
|
<ScrollableAreaView className="row row-cols-5 align-content-start g-0 w-100">
|
||||||
{ botItems && (botItems.length > 0) && botItems.map((item, index) =>
|
{ botItems && (botItems.length > 0) && botItems.map((item, index) =>
|
||||||
{
|
{
|
||||||
return <InventoryBotItemView key={ index } botItem={ item } />
|
return <InventoryBotItemView key={ index } botItem={ item } />
|
||||||
}) }
|
}) }
|
||||||
|
</ScrollableAreaView>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -116,8 +116,8 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className="row h-100">
|
||||||
<div className="col-7">
|
<div className="d-flex flex-column col-7">
|
||||||
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
|
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
|
||||||
<InventoryFurnitureResultsView groupItems={ filteredGroupItems } />
|
<InventoryFurnitureResultsView groupItems={ filteredGroupItems } />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,5 +1,2 @@
|
|||||||
.furni-item-container {
|
.furni-item-container {
|
||||||
height: 188px;
|
|
||||||
max-height: 188px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { ScrollableAreaView } from '../../../../../layout/scrollable-area/ScrollableAreaView';
|
||||||
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
|
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
|
||||||
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
|
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
|
||||||
|
|
||||||
@ -7,11 +8,13 @@ export const InventoryFurnitureResultsView: FC<InventoryFurnitureResultsViewProp
|
|||||||
const { groupItems = [] } = props;
|
const { groupItems = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row row-cols-5 align-content-start g-0 furni-item-container">
|
<div className="d-flex flex-grow-1">
|
||||||
|
<ScrollableAreaView className="row row-cols-5 align-content-start g-0 w-100">
|
||||||
{ groupItems && (groupItems.length > 0) && groupItems.map((item, index) =>
|
{ groupItems && (groupItems.length > 0) && groupItems.map((item, index) =>
|
||||||
{
|
{
|
||||||
return <InventoryFurnitureItemView key={ index } groupItem={ item } />
|
return <InventoryFurnitureItemView key={ index } groupItem={ item } />
|
||||||
}) }
|
}) }
|
||||||
|
</ScrollableAreaView>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
|
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||||
import { InventoryFurnitureSearchViewProps } from './InventoryFurnitureSearchView.types';
|
import { InventoryFurnitureSearchViewProps } from './InventoryFurnitureSearchView.types';
|
||||||
|
|
||||||
export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props =>
|
export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props =>
|
||||||
@ -31,7 +32,7 @@ export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps>
|
|||||||
return (
|
return (
|
||||||
<div className="d-flex mb-1">
|
<div className="d-flex mb-1">
|
||||||
<div className="d-flex flex-grow-1 me-1">
|
<div className="d-flex flex-grow-1 me-1">
|
||||||
<input type="text" className="form-control form-control-sm" placeholder="search" value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
<input type="text" className="form-control form-control-sm" placeholder={ LocalizeText('generic.search') } value={ searchValue } onChange={ event => setSearchValue(event.target.value) } />
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex">
|
<div className="d-flex">
|
||||||
<button type="button" className="btn btn-primary btn-sm">
|
<button type="button" className="btn btn-primary btn-sm">
|
||||||
|
@ -82,7 +82,7 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row h-100">
|
<div className="row h-100">
|
||||||
<div className="col-7">
|
<div className="d-flex flex-column col-7">
|
||||||
<InventoryPetResultsView petItems={ petItems } />
|
<InventoryPetResultsView petItems={ petItems } />
|
||||||
</div>
|
</div>
|
||||||
<div className="d-flex flex-column col-5 justify-space-between">
|
<div className="d-flex flex-column col-5 justify-space-between">
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { ScrollableAreaView } from '../../../../../layout/scrollable-area/ScrollableAreaView';
|
||||||
import { InventoryPetItemView } from '../item/InventoryPetItemView';
|
import { InventoryPetItemView } from '../item/InventoryPetItemView';
|
||||||
import { InventoryPetResultsViewProps } from './InventoryPetResultsView.types';
|
import { InventoryPetResultsViewProps } from './InventoryPetResultsView.types';
|
||||||
|
|
||||||
@ -7,11 +8,13 @@ export const InventoryPetResultsView: FC<InventoryPetResultsViewProps> = props =
|
|||||||
const { petItems = [] } = props;
|
const { petItems = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row row-cols-5 align-content-start g-0 pet-item-container">
|
<div className="d-flex flex-grow-1">
|
||||||
|
<ScrollableAreaView className="row row-cols-5 align-content-start g-0 w-100">
|
||||||
{ petItems && (petItems.length > 0) && petItems.map((item, index) =>
|
{ petItems && (petItems.length > 0) && petItems.map((item, index) =>
|
||||||
{
|
{
|
||||||
return <InventoryPetItemView key={ index } petItem={ item } />
|
return <InventoryPetItemView key={ index } petItem={ item } />
|
||||||
}) }
|
}) }
|
||||||
|
</ScrollableAreaView>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
|||||||
export const NavigatorView: FC<NavigatorViewProps> = props =>
|
export const NavigatorView: FC<NavigatorViewProps> = props =>
|
||||||
{
|
{
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
|
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||||
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator);
|
||||||
const { needsNavigatorUpdate = false, topLevelContext = null, topLevelContexts = null } = navigatorState;
|
const { needsNavigatorUpdate = false, topLevelContext = null, topLevelContexts = null } = navigatorState;
|
||||||
|
|
||||||
@ -86,8 +87,15 @@ export const NavigatorView: FC<NavigatorViewProps> = props =>
|
|||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
{ topLevelContexts.map((context, index) =>
|
{ topLevelContexts.map((context, index) =>
|
||||||
{
|
{
|
||||||
return <NitroCardTabsItemView key={ index } tabText={ LocalizeText(('navigator.toplevelview.' + context.code)) } isActive={ (topLevelContext === context) } onClick={ event => sendSearch('', context.code) } />
|
return (
|
||||||
|
<NitroCardTabsItemView key={ index } isActive={ ((topLevelContext === context) && !isCreatorOpen) } onClick={ event => sendSearch('', context.code) }>
|
||||||
|
{ LocalizeText(('navigator.toplevelview.' + context.code)) }
|
||||||
|
</NitroCardTabsItemView>
|
||||||
|
);
|
||||||
}) }
|
}) }
|
||||||
|
<NitroCardTabsItemView>
|
||||||
|
|
||||||
|
</NitroCardTabsItemView>
|
||||||
</NitroCardTabsView>
|
</NitroCardTabsView>
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
@import './creator/NavigatorRoomCreatorView';
|
||||||
@import './search/NavigatorSearchView';
|
@import './search/NavigatorSearchView';
|
||||||
@import './search-result/NavigatorSearchResultView';
|
@import './search-result/NavigatorSearchResultView';
|
||||||
@import './search-result-item/NavigatorSearchResultItemView';
|
@import './search-result-item/NavigatorSearchResultItemView';
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { NavigatorRoomCreatorViewProps } from './NavigatorRoomCreatorView.types';
|
||||||
|
|
||||||
|
export const NavigatorRoomCreatorView: FC<NavigatorRoomCreatorViewProps> = props =>
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export interface NavigatorRoomCreatorViewProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import { CurrencyIcon } from '../../../utils/currency-icon/CurrencyIcon';
|
import { CurrencyIcon } from '../../currency-icon/CurrencyIcon';
|
||||||
import { CurrencyViewProps } from './CurrencyView.types';
|
import { CurrencyViewProps } from './CurrencyView.types';
|
||||||
|
|
||||||
export function CurrencyView(props: CurrencyViewProps): JSX.Element
|
export function CurrencyView(props: CurrencyViewProps): JSX.Element
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { EventDispatcher, IEventDispatcher, IRoomSession, RoomBackgroundColorEvent, RoomEngineDimmerStateEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomId, RoomObjectCategory, RoomObjectHSLColorEnabledEvent, RoomObjectOperationType, RoomSessionEvent, RoomZoomEvent } from 'nitro-renderer';
|
import { EventDispatcher, IEventDispatcher, IRoomSession, RoomBackgroundColorEvent, RoomEngineDimmerStateEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomId, RoomObjectCategory, RoomObjectHSLColorEnabledEvent, RoomObjectOperationType, RoomSessionEvent, RoomZoomEvent } from 'nitro-renderer';
|
||||||
import { useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { ProcessRoomObjectOperation } from '../../api/nitro/room/ProcessRoomObjectOperation';
|
import { ProcessRoomObjectOperation } from '../../api/nitro/room/ProcessRoomObjectOperation';
|
||||||
import { SetActiveRoomId } from '../../api/nitro/room/SetActiveRoomId';
|
import { SetActiveRoomId } from '../../api/nitro/room/SetActiveRoomId';
|
||||||
import { GetRoomSession } from '../../api/nitro/session/GetRoomSession';
|
import { GetRoomSession } from '../../api/nitro/session/GetRoomSession';
|
||||||
@ -13,7 +13,7 @@ import { RoomHostViewProps } from './RoomHostView.types';
|
|||||||
import { CanManipulateFurniture } from './utils/CanManipulateFurniture';
|
import { CanManipulateFurniture } from './utils/CanManipulateFurniture';
|
||||||
import { IsFurnitureSelectionDisabled } from './utils/IsFurnitureSelectionDisabled';
|
import { IsFurnitureSelectionDisabled } from './utils/IsFurnitureSelectionDisabled';
|
||||||
|
|
||||||
export function RoomHostView(props: RoomHostViewProps): JSX.Element
|
export const RoomHostView: FC<RoomHostViewProps> = props =>
|
||||||
{
|
{
|
||||||
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
||||||
const [ eventDispatcher, setEventDispatcher ] = useState<IEventDispatcher>(null);
|
const [ eventDispatcher, setEventDispatcher ] = useState<IEventDispatcher>(null);
|
||||||
@ -40,7 +40,7 @@ export function RoomHostView(props: RoomHostViewProps): JSX.Element
|
|||||||
|
|
||||||
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||||
{
|
{
|
||||||
if(!eventDispatcher) return;
|
if(!roomSession || !eventDispatcher) return;
|
||||||
|
|
||||||
const objectId = event.objectId;
|
const objectId = event.objectId;
|
||||||
const category = event.category;
|
const category = event.category;
|
||||||
@ -101,6 +101,10 @@ export function RoomHostView(props: RoomHostViewProps): JSX.Element
|
|||||||
case RoomEngineObjectEvent.REQUEST_ROTATE:
|
case RoomEngineObjectEvent.REQUEST_ROTATE:
|
||||||
if(CanManipulateFurniture(roomSession, objectId, category)) ProcessRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
if(CanManipulateFurniture(roomSession, objectId, category)) ProcessRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
||||||
break;
|
break;
|
||||||
|
case RoomEngineObjectEvent.REQUEST_MANIPULATION:
|
||||||
|
console.log('yaaa')
|
||||||
|
if(CanManipulateFurniture(roomSession, objectId, category)) updateEvent = new RoomWidgetRoomObjectUpdateEvent(RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION, objectId, category, event.roomId);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(updateEvent)
|
if(updateEvent)
|
||||||
@ -152,6 +156,7 @@ export function RoomHostView(props: RoomHostViewProps): JSX.Element
|
|||||||
useRoomEngineEvent(RoomEngineObjectEvent.PLACED, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.PLACED, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MOVE, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MOVE, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_ROTATE, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_ROTATE, onRoomEngineObjectEvent);
|
||||||
|
useRoomEngineEvent(RoomEngineObjectEvent.REQUEST_MANIPULATION, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_ENTER, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_ENTER, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
||||||
|
|
||||||
|
@ -1 +1 @@
|
|||||||
@import './widgets/Widgets';
|
@import './widgets/RoomWidgets';
|
||||||
|
@ -6,6 +6,7 @@ import { WindowResizeEvent } from '../../api/nitro/room/DispatchResizeEvent';
|
|||||||
import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent';
|
import { DispatchTouchEvent } from '../../api/nitro/room/DispatchTouchEvent';
|
||||||
import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
|
import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
|
||||||
import { RoomViewProps } from './RoomView.types';
|
import { RoomViewProps } from './RoomView.types';
|
||||||
|
import { AvatarInfoWidgetView } from './widgets/avatar-info/AvatarInfoWidgetView';
|
||||||
import { ChatInputView } from './widgets/chat-input/ChatInputView';
|
import { ChatInputView } from './widgets/chat-input/ChatInputView';
|
||||||
import { ChatWidgetView } from './widgets/chat/ChatWidgetView';
|
import { ChatWidgetView } from './widgets/chat/ChatWidgetView';
|
||||||
import { FurnitureWidgetsView } from './widgets/furniture/FurnitureWidgetsView';
|
import { FurnitureWidgetsView } from './widgets/furniture/FurnitureWidgetsView';
|
||||||
@ -90,9 +91,10 @@ export function RoomView(props: RoomViewProps): JSX.Element
|
|||||||
{ roomSession && events && roomCanvas &&
|
{ roomSession && events && roomCanvas &&
|
||||||
createPortal(props.children, document.getElementById('room-view').appendChild(roomCanvas)) &&
|
createPortal(props.children, document.getElementById('room-view').appendChild(roomCanvas)) &&
|
||||||
<>
|
<>
|
||||||
|
<AvatarInfoWidgetView events={ events } />
|
||||||
|
<ChatWidgetView />
|
||||||
<ChatInputView />
|
<ChatInputView />
|
||||||
<FurnitureWidgetsView events={ events } />
|
<FurnitureWidgetsView events={ events } />
|
||||||
<ChatWidgetView />
|
|
||||||
</> }
|
</> }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
6
src/views/room/widgets/RoomWidgets.types.ts
Normal file
6
src/views/room/widgets/RoomWidgets.types.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { IEventDispatcher } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export interface RoomWidgetProps
|
||||||
|
{
|
||||||
|
events: IEventDispatcher;
|
||||||
|
}
|
91
src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx
Normal file
91
src/views/room/widgets/avatar-info/AvatarInfoWidgetView.tsx
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
import { IFurnitureData, RoomObjectCategory, RoomObjectVariable } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback } from 'react';
|
||||||
|
import { GetRoomEngine, GetRoomSession, GetSessionDataManager } from '../../../../api';
|
||||||
|
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||||
|
import { RoomObjectNameEvent, RoomWidgetRoomObjectUpdateEvent } from '../events';
|
||||||
|
import { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types';
|
||||||
|
|
||||||
|
export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { events = null } = props;
|
||||||
|
|
||||||
|
const processObjectName = useCallback((roomId: number, objectId: number, category: number) =>
|
||||||
|
{
|
||||||
|
let id = -1;
|
||||||
|
let name: string = null;
|
||||||
|
let type = 0;
|
||||||
|
let roomIndex = 0;
|
||||||
|
|
||||||
|
switch(category)
|
||||||
|
{
|
||||||
|
case RoomObjectCategory.FLOOR:
|
||||||
|
case RoomObjectCategory.WALL:
|
||||||
|
const roomObject = GetRoomEngine().getRoomObject(roomId, id, category);
|
||||||
|
|
||||||
|
if(!roomObject) return;
|
||||||
|
|
||||||
|
if(roomObject.type.indexOf('poster') === 0)
|
||||||
|
{
|
||||||
|
name = ('${poster_' + parseInt(roomObject.type.replace('poster', '')) + '_name}');
|
||||||
|
roomIndex = roomObject.id;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
let furniData: IFurnitureData = null;
|
||||||
|
|
||||||
|
const typeId = roomObject.model.getValue<number>(RoomObjectVariable.FURNITURE_TYPE_ID);
|
||||||
|
|
||||||
|
if(category === RoomObjectCategory.FLOOR)
|
||||||
|
{
|
||||||
|
furniData = GetSessionDataManager().getFloorItemData(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(category === RoomObjectCategory.WALL)
|
||||||
|
{
|
||||||
|
furniData = GetSessionDataManager().getWallItemData(typeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!furniData) return;
|
||||||
|
|
||||||
|
id = furniData.id;
|
||||||
|
name = furniData.name;
|
||||||
|
roomIndex = roomObject.id;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case RoomObjectCategory.UNIT:
|
||||||
|
const userData = GetRoomSession().userDataManager.getUserDataByIndex(id);
|
||||||
|
|
||||||
|
if(!userData) return;
|
||||||
|
|
||||||
|
id = userData.webID;
|
||||||
|
name = userData.name;
|
||||||
|
type = userData.type;
|
||||||
|
roomIndex = userData.roomIndex;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!name) return;
|
||||||
|
|
||||||
|
events.dispatchEvent(new RoomObjectNameEvent(id, category, name, type, roomIndex));
|
||||||
|
}, [ events ]);
|
||||||
|
|
||||||
|
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OVER: {
|
||||||
|
processObjectName(event.roomId, event.id, event.category);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT: {
|
||||||
|
console.log('out');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OVER, events, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_ROLL_OUT, events, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
import { RoomWidgetProps } from '../RoomWidgets.types';
|
||||||
|
|
||||||
|
export interface AvatarInfoWidgetViewProps extends RoomWidgetProps
|
||||||
|
{}
|
@ -13,19 +13,19 @@ export function ChatWidgetView(props: ChatWidgetViewProps): JSX.Element
|
|||||||
const [ chatMessages, setChatMessages ] = useState<ChatBubbleMessage[]>([]);
|
const [ chatMessages, setChatMessages ] = useState<ChatBubbleMessage[]>([]);
|
||||||
const elementRef = useRef<HTMLDivElement>();
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
const removeLastHiddenChat = useCallback(() =>
|
const removeFirstHiddenChat = useCallback(() =>
|
||||||
{
|
{
|
||||||
if(!chatMessages.length) return;
|
if(!chatMessages.length) return;
|
||||||
|
|
||||||
const lastChat = chatMessages[chatMessages.length - 1];
|
const lastChat = chatMessages[0];
|
||||||
|
|
||||||
if((lastChat.lastTop > -(lastChat.height))) return;
|
if((lastChat.lastTop > (-(lastChat.height) * 2))) return;
|
||||||
|
|
||||||
setChatMessages(prevValue =>
|
setChatMessages(prevValue =>
|
||||||
{
|
{
|
||||||
const newMessages = [ ...prevValue ];
|
const newMessages = [ ...prevValue ];
|
||||||
|
|
||||||
newMessages.splice((newMessages.length - 1), 1);
|
newMessages.shift();
|
||||||
|
|
||||||
return newMessages;
|
return newMessages;
|
||||||
});
|
});
|
||||||
@ -33,42 +33,33 @@ export function ChatWidgetView(props: ChatWidgetViewProps): JSX.Element
|
|||||||
|
|
||||||
const moveChatUp = useCallback((chat: ChatBubbleMessage, amount: number) =>
|
const moveChatUp = useCallback((chat: ChatBubbleMessage, amount: number) =>
|
||||||
{
|
{
|
||||||
if(!chat.elementRef) return;
|
chat.lastTop -= amount;
|
||||||
|
|
||||||
let y = chat.elementRef.offsetHeight;
|
if(chat.elementRef) chat.elementRef.style.top = (chat.lastTop + 'px');
|
||||||
|
|
||||||
if(amount > 0) y = amount;
|
|
||||||
|
|
||||||
let top = (chat.elementRef.offsetTop - y);
|
|
||||||
|
|
||||||
chat.lastTop = top;
|
|
||||||
chat.elementRef.style.top = (top + 'px');
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const moveAllChatsUp = useCallback((amount: number) =>
|
const moveAllChatsUp = useCallback((amount: number) =>
|
||||||
{
|
{
|
||||||
chatMessages.forEach(chat => moveChatUp(chat, amount));
|
chatMessages.forEach(chat => moveChatUp(chat, amount));
|
||||||
}, [ chatMessages, moveChatUp ]);
|
|
||||||
|
|
||||||
const makeRoom = useCallback((amount: number = 0, skipLast: boolean = false) =>
|
removeFirstHiddenChat();
|
||||||
|
}, [ chatMessages, moveChatUp, removeFirstHiddenChat ]);
|
||||||
|
|
||||||
|
const makeRoom = useCallback((chat: ChatBubbleMessage) =>
|
||||||
{
|
{
|
||||||
const lastChat = chatMessages[chatMessages.length - 1];
|
const lowestPoint = ((chat.lastTop + chat.height) - 1);
|
||||||
|
const requiredSpace = (chat.height + 1);
|
||||||
if(!lastChat) return;
|
|
||||||
|
|
||||||
const lowestPoint = ((lastChat.lastTop + lastChat.height) - 1);
|
|
||||||
const requiredSpace = ((amount || lastChat.height) + 1);
|
|
||||||
const spaceAvailable = (elementRef.current.offsetHeight - lowestPoint);
|
const spaceAvailable = (elementRef.current.offsetHeight - lowestPoint);
|
||||||
|
|
||||||
if(spaceAvailable < requiredSpace)
|
if(spaceAvailable < requiredSpace)
|
||||||
{
|
{
|
||||||
amount = (requiredSpace - spaceAvailable);
|
const amount = (requiredSpace - spaceAvailable);
|
||||||
|
|
||||||
chatMessages.forEach((chat, index) =>
|
chatMessages.forEach((existingChat, index) =>
|
||||||
{
|
{
|
||||||
if(skipLast && (index === (chatMessages.length - 1))) return;
|
if(existingChat === chat) return;
|
||||||
|
|
||||||
moveChatUp(chat, amount)
|
moveChatUp(existingChat, amount)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}, [ chatMessages, moveChatUp ]);
|
}, [ chatMessages, moveChatUp ]);
|
||||||
@ -146,25 +137,25 @@ export function ChatWidgetView(props: ChatWidgetViewProps): JSX.Element
|
|||||||
|
|
||||||
useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onRoomSessionChatEvent);
|
useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onRoomSessionChatEvent);
|
||||||
|
|
||||||
|
// useEffect(() =>
|
||||||
|
// {
|
||||||
|
// const interval = setInterval(() => moveAllChatsUp(15), 500);
|
||||||
|
|
||||||
|
// return () =>
|
||||||
|
// {
|
||||||
|
// if(interval) clearInterval(interval);
|
||||||
|
// }
|
||||||
|
// }, [ chatMessages, moveAllChatsUp ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
const interval = setInterval(() => moveAllChatsUp(15), 500);
|
const interval = setInterval(() => removeFirstHiddenChat(), 1000);
|
||||||
|
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
if(interval) clearInterval(interval);
|
if(interval) clearInterval(interval);
|
||||||
}
|
}
|
||||||
}, [ chatMessages, moveAllChatsUp ]);
|
}, [ removeFirstHiddenChat ]);
|
||||||
|
|
||||||
useEffect(() =>
|
|
||||||
{
|
|
||||||
const interval = setInterval(() => removeLastHiddenChat(), 500);
|
|
||||||
|
|
||||||
return () =>
|
|
||||||
{
|
|
||||||
if(interval) clearInterval(interval);
|
|
||||||
}
|
|
||||||
}, [ removeLastHiddenChat ]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className="nitro-chat-widget">
|
<div ref={ elementRef } className="nitro-chat-widget">
|
||||||
|
@ -25,8 +25,6 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
|||||||
chat.height = height;
|
chat.height = height;
|
||||||
chat.elementRef = element;
|
chat.elementRef = element;
|
||||||
|
|
||||||
if(isVisible || !chat) return;
|
|
||||||
|
|
||||||
let left = chat.lastLeft;
|
let left = chat.lastLeft;
|
||||||
let top = chat.lastTop;
|
let top = chat.lastTop;
|
||||||
|
|
||||||
@ -34,22 +32,27 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
|||||||
{
|
{
|
||||||
left = (chat.location.x - (width / 2));
|
left = (chat.location.x - (width / 2));
|
||||||
top = (element.parentElement.offsetHeight - height);
|
top = (element.parentElement.offsetHeight - height);
|
||||||
}
|
|
||||||
|
|
||||||
chat.lastLeft = left;
|
chat.lastLeft = left;
|
||||||
chat.lastTop = top;
|
chat.lastTop = top;
|
||||||
|
}
|
||||||
|
|
||||||
element.style.left = (left + 'px');
|
element.style.left = (left + 'px');
|
||||||
element.style.top = (top + 'px');
|
element.style.top = (top + 'px');
|
||||||
|
|
||||||
makeRoom(0, true);
|
if(!chat.visible)
|
||||||
setIsVisible(true);
|
{
|
||||||
|
makeRoom(chat);
|
||||||
|
}
|
||||||
|
|
||||||
|
chat.visible = true;
|
||||||
|
//setIsVisible(true);
|
||||||
|
|
||||||
return () =>
|
return () =>
|
||||||
{
|
{
|
||||||
chat.elementRef = null;
|
chat.elementRef = null;
|
||||||
}
|
}
|
||||||
}, [ isVisible, elementRef, chat, makeRoom ]);
|
}, [ elementRef, isVisible, chat, makeRoom ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className="bubble-container" style={ { visibility: (isVisible ? 'visible' : 'hidden') } }>
|
<div ref={ elementRef } className="bubble-container" style={ { visibility: (isVisible ? 'visible' : 'hidden') } }>
|
||||||
|
@ -3,5 +3,5 @@ import { ChatBubbleMessage } from '../utils/ChatBubbleMessage';
|
|||||||
export interface ChatWidgetMessageViewProps
|
export interface ChatWidgetMessageViewProps
|
||||||
{
|
{
|
||||||
chat: ChatBubbleMessage;
|
chat: ChatBubbleMessage;
|
||||||
makeRoom: (amount?: number, skipLast?: boolean) => void;
|
makeRoom: (chat: ChatBubbleMessage) => void;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
import { ChatMessagesWidgetViewProps } from './ChatMessagesWidgetView.types';
|
|
||||||
|
|
||||||
export function ChatMessagesWidgetView(props: ChatMessagesWidgetViewProps): JSX.Element
|
|
||||||
{
|
|
||||||
const {} = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<></>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
export interface ChatMessagesWidgetViewProps
|
|
||||||
{}
|
|
@ -1,10 +0,0 @@
|
|||||||
import { ChatMessageWidgetViewProps } from './ChatMessageWidgetView.types';
|
|
||||||
|
|
||||||
export function ChatMessageWidgetView(props: ChatMessageWidgetViewProps): JSX.Element
|
|
||||||
{
|
|
||||||
const {} = props;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<></>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,2 +0,0 @@
|
|||||||
export interface ChatMessageWidgetViewProps
|
|
||||||
{}
|
|
@ -10,6 +10,7 @@ export class ChatBubbleMessage
|
|||||||
public lastTop: number = 0;
|
public lastTop: number = 0;
|
||||||
public lastLeft: number = 0;
|
public lastLeft: number = 0;
|
||||||
public elementRef: HTMLDivElement = null;
|
public elementRef: HTMLDivElement = null;
|
||||||
|
public visible: boolean = false;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
public text: string = '',
|
public text: string = '',
|
||||||
|
@ -10,6 +10,7 @@ export class RoomWidgetRoomObjectUpdateEvent extends RoomWidgetUpdateEvent
|
|||||||
public static USER_ADDED: string = 'RWROUE_USER_ADDED';
|
public static USER_ADDED: string = 'RWROUE_USER_ADDED';
|
||||||
public static OBJECT_ROLL_OVER: string = 'RWROUE_OBJECT_ROLL_OVER';
|
public static OBJECT_ROLL_OVER: string = 'RWROUE_OBJECT_ROLL_OVER';
|
||||||
public static OBJECT_ROLL_OUT: string = 'RWROUE_OBJECT_ROLL_OUT';
|
public static OBJECT_ROLL_OUT: string = 'RWROUE_OBJECT_ROLL_OUT';
|
||||||
|
public static OBJECT_REQUEST_MANIPULATION: string = 'RWROUE_OBJECT_REQUEST_MANIPULATION';
|
||||||
|
|
||||||
private _id: number;
|
private _id: number;
|
||||||
private _category: number;
|
private _category: number;
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
import { IEventDispatcher } from 'nitro-renderer';
|
import { RoomWidgetProps } from '../RoomWidgets.types';
|
||||||
|
|
||||||
export interface FurnitureWidgetProps
|
export interface FurnitureWidgetProps extends RoomWidgetProps
|
||||||
{
|
{}
|
||||||
events: IEventDispatcher;
|
|
||||||
}
|
|
||||||
|
@ -1 +1,2 @@
|
|||||||
|
@import './manipulation-menu/FurnitureManipulationMenuView';
|
||||||
@import './stickie/FurnitureStickieView';
|
@import './stickie/FurnitureStickieView';
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { FurnitureWidgetsViewProps } from './FurnitureWidgetsView.types';
|
import { FurnitureWidgetsViewProps } from './FurnitureWidgetsView.types';
|
||||||
import { FurnitureHighScoreView } from './high-score/FurnitureHighScoreView';
|
import { FurnitureHighScoreView } from './high-score/FurnitureHighScoreView';
|
||||||
|
import { FurnitureManipulationMenuView } from './manipulation-menu/FurnitureManipulationMenuView';
|
||||||
import { FurnitureMannequinView } from './mannequin/FurnitureMannequinView';
|
import { FurnitureMannequinView } from './mannequin/FurnitureMannequinView';
|
||||||
import { FurniturePresentView } from './present/FurniturePresentView';
|
import { FurniturePresentView } from './present/FurniturePresentView';
|
||||||
import { FurnitureStickieView } from './stickie/FurnitureStickieView';
|
import { FurnitureStickieView } from './stickie/FurnitureStickieView';
|
||||||
@ -11,6 +12,7 @@ export function FurnitureWidgetsView(props: FurnitureWidgetsViewProps): JSX.Elem
|
|||||||
return (
|
return (
|
||||||
<div className="position-absolute nitro-room-widgets t-0 l-0">
|
<div className="position-absolute nitro-room-widgets t-0 l-0">
|
||||||
<FurnitureHighScoreView events={ events } />
|
<FurnitureHighScoreView events={ events } />
|
||||||
|
<FurnitureManipulationMenuView events={ events } />
|
||||||
<FurnitureMannequinView events={ events } />
|
<FurnitureMannequinView events={ events } />
|
||||||
<FurniturePresentView events={ events } />
|
<FurniturePresentView events={ events } />
|
||||||
<FurnitureStickieView events={ events } />
|
<FurnitureStickieView events={ events } />
|
||||||
|
@ -0,0 +1,71 @@
|
|||||||
|
import { RoomObjectOperationType } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import { ProcessRoomObjectOperation } from '../../../../../api';
|
||||||
|
import { CreateEventDispatcherHook } from '../../../../../hooks/events/event-dispatcher.base';
|
||||||
|
import { RoomWidgetRoomObjectUpdateEvent } from '../../events';
|
||||||
|
import { ObjectLocationView } from '../../object-location/ObjectLocationView';
|
||||||
|
import { FurnitureManipulationMenuViewProps } from './FurnitureManipulationMenuView.types';
|
||||||
|
|
||||||
|
export const FurnitureManipulationMenuView: FC<FurnitureManipulationMenuViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { events = null } = props;
|
||||||
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
|
const [ objectId, setObjectId ] = useState(-1);
|
||||||
|
const [ objectType, setObjectType ] = useState(-1);
|
||||||
|
|
||||||
|
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION: {
|
||||||
|
setIsVisible(true);
|
||||||
|
setObjectId(event.id);
|
||||||
|
setObjectType(event.category);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED: {
|
||||||
|
console.log('tru')
|
||||||
|
setIsVisible(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const rotateFurniture = useCallback(() =>
|
||||||
|
{
|
||||||
|
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
||||||
|
}, [ objectId, objectType ]);
|
||||||
|
|
||||||
|
const moveFurniture = useCallback(() =>
|
||||||
|
{
|
||||||
|
ProcessRoomObjectOperation(objectId, objectType, RoomObjectOperationType.OBJECT_MOVE);
|
||||||
|
}, [ objectId, objectType ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isVisible) return;
|
||||||
|
|
||||||
|
moveFurniture();
|
||||||
|
}, [ isVisible, moveFurniture ]);
|
||||||
|
|
||||||
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_REQUEST_MANIPULATION, events, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, events, onRoomWidgetRoomObjectUpdateEvent);
|
||||||
|
|
||||||
|
if(!isVisible) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ObjectLocationView objectId={ objectId } objectType={ objectType }>
|
||||||
|
<div className="btn-group">
|
||||||
|
<button type="button" className="btn btn-primary btn-sm">
|
||||||
|
<i className="fas fa-times" />
|
||||||
|
</button>
|
||||||
|
<button type="button" className="btn btn-primary btn-sm" onClick={ rotateFurniture }>
|
||||||
|
<i className="fas fa-undo" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</ObjectLocationView>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
import { FurnitureWidgetProps } from '../FurnitureWidget.types';
|
||||||
|
|
||||||
|
export interface FurnitureManipulationMenuViewProps extends FurnitureWidgetProps
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
import { Nitro } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
|
import { GetRoomEngine, GetRoomSession } from '../../../../api';
|
||||||
|
import { ObjectLocationViewProps } from './ObjectLocationView.types';
|
||||||
|
|
||||||
|
export const ObjectLocationView: FC<ObjectLocationViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { objectId = -1, objectType = -1, children = null } = props;
|
||||||
|
const [ posX, setPosX ] = useState(0);
|
||||||
|
const [ posY, setPosY ] = useState(0);
|
||||||
|
const elementRef = useRef<HTMLDivElement>();
|
||||||
|
|
||||||
|
const updatePosition = useCallback(() =>
|
||||||
|
{
|
||||||
|
const roomSession = GetRoomSession();
|
||||||
|
const objectBounds = GetRoomEngine().getRoomObjectBoundingRectangle(roomSession.roomId, objectId, objectType, 1);
|
||||||
|
|
||||||
|
if(!objectBounds) return;
|
||||||
|
|
||||||
|
setPosX(Math.round(((objectBounds.left + (objectBounds.width / 2)) - (elementRef.current.offsetWidth / 2))));
|
||||||
|
setPosY(Math.round((objectBounds.top - elementRef.current.offsetHeight) + 10));
|
||||||
|
}, [ objectId, objectType ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
Nitro.instance.ticker.add(updatePosition);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
Nitro.instance.ticker.remove(updatePosition);
|
||||||
|
}
|
||||||
|
}, [ updatePosition ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div ref={ elementRef } className="position-absolute w-100" style={ { left: posX, top: posY } }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,5 @@
|
|||||||
|
export interface ObjectLocationViewProps
|
||||||
|
{
|
||||||
|
objectId: number;
|
||||||
|
objectType: number;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user