mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-23 14:40:50 +01:00
commit
2ad0f8a999
@ -1,25 +1,21 @@
|
|||||||
::-webkit-scrollbar {
|
::-webkit-scrollbar {
|
||||||
width: 7px;
|
width: 0.5rem;
|
||||||
height: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-track {
|
::-webkit-scrollbar-track {
|
||||||
border-radius: $border-radius;
|
background-clip: padding-box;
|
||||||
background: rgba($black,.1);
|
border-right: 0.25rem solid rgba($black, .1);
|
||||||
box-shadow:inset 0 0 1px 1px rgba($black,.1);
|
|
||||||
padding-top:3px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb {
|
::-webkit-scrollbar-thumb {
|
||||||
border-radius: $border-radius;
|
background-clip: padding-box;
|
||||||
background: rgba($primary,.4);
|
border-right: 0.25rem solid rgba($primary, .4);
|
||||||
width: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:hover {
|
&:hover {
|
||||||
background: rgba($primary,.8);
|
border-right: 0.25rem solid rgba($primary, .8);
|
||||||
}
|
}
|
||||||
|
|
||||||
::-webkit-scrollbar-thumb:active {
|
&:active {
|
||||||
background: $secondary;
|
border-right: 0.25rem solid $secondary;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
transform: scale(2) translateZ(0);
|
transform: scale(2) translateZ(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.opacity-0-5 {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
.text-shadow {
|
.text-shadow {
|
||||||
text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
text-shadow: 0px 4px 4px rgba(0, 0, 0, 0.25);
|
||||||
}
|
}
|
||||||
|
11
src/events/friend-list/FriendEnteredRoomEvent.ts
Normal file
11
src/events/friend-list/FriendEnteredRoomEvent.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
import { RoomWidgetObjectNameEvent } from '../../views/room/events';
|
||||||
|
|
||||||
|
export class FriendEnteredRoomEvent extends RoomWidgetObjectNameEvent
|
||||||
|
{
|
||||||
|
public static ENTERED: string = 'FERE_ENTERED';
|
||||||
|
|
||||||
|
constructor(roomIndex: number, category: number, id: number, name: string, userType: number)
|
||||||
|
{
|
||||||
|
super(FriendEnteredRoomEvent.ENTERED, roomIndex, category, id, name, userType);
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,2 @@
|
|||||||
|
export * from './FriendEnteredRoomEvent';
|
||||||
export * from './FriendListEvent';
|
export * from './FriendListEvent';
|
||||||
|
27
src/events/inventory/InventoryTradeRequestEvent.ts
Normal file
27
src/events/inventory/InventoryTradeRequestEvent.ts
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { InventoryEvent } from './InventoryEvent';
|
||||||
|
|
||||||
|
export class InventoryTradeRequestEvent extends InventoryEvent
|
||||||
|
{
|
||||||
|
public static REQUEST_TRADE: string = 'ITSE_REQUEST_TRADE';
|
||||||
|
|
||||||
|
private _objectId: number;
|
||||||
|
private _username: string;
|
||||||
|
|
||||||
|
constructor(objectId: number, username: string)
|
||||||
|
{
|
||||||
|
super(InventoryTradeRequestEvent.REQUEST_TRADE);
|
||||||
|
|
||||||
|
this._objectId = objectId;
|
||||||
|
this._username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get objectId(): number
|
||||||
|
{
|
||||||
|
return this._objectId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get username(): string
|
||||||
|
{
|
||||||
|
return this._username;
|
||||||
|
}
|
||||||
|
}
|
28
src/events/inventory/InventoryTradeStartEvent.ts
Normal file
28
src/events/inventory/InventoryTradeStartEvent.ts
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import { TradeUserData } from '../../views/inventory/common/TradeUserData';
|
||||||
|
import { InventoryEvent } from './InventoryEvent';
|
||||||
|
|
||||||
|
export class InventoryTradeStartEvent extends InventoryEvent
|
||||||
|
{
|
||||||
|
public static START_TRADE: string = 'ITSE_START_TRADE';
|
||||||
|
|
||||||
|
private _ownUserTradeData: TradeUserData;
|
||||||
|
private _otherUserTradeData: TradeUserData;
|
||||||
|
|
||||||
|
constructor(ownUserTradeData: TradeUserData, otherUserTradeData: TradeUserData)
|
||||||
|
{
|
||||||
|
super(InventoryTradeStartEvent.START_TRADE);
|
||||||
|
|
||||||
|
this._ownUserTradeData = ownUserTradeData;
|
||||||
|
this._otherUserTradeData = otherUserTradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get ownUserTradeData(): TradeUserData
|
||||||
|
{
|
||||||
|
return this._ownUserTradeData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get otherUserTradeData(): TradeUserData
|
||||||
|
{
|
||||||
|
return this._otherUserTradeData;
|
||||||
|
}
|
||||||
|
}
|
@ -1 +1,3 @@
|
|||||||
export * from './InventoryEvent';
|
export * from './InventoryEvent';
|
||||||
|
export * from './InventoryTradeRequestEvent';
|
||||||
|
export * from './InventoryTradeStartEvent';
|
||||||
|
@ -6,6 +6,7 @@ $nitro-card-tabs-height: 33px;
|
|||||||
|
|
||||||
@import './accordion/NitroCardAccordionView';
|
@import './accordion/NitroCardAccordionView';
|
||||||
@import './content/NitroCardContentView';
|
@import './content/NitroCardContentView';
|
||||||
|
@import './grid/NitroCardGridView';
|
||||||
@import './header/NitroCardHeaderView';
|
@import './header/NitroCardHeaderView';
|
||||||
@import './tabs/NitroCardTabsView';
|
@import './tabs/NitroCardTabsView';
|
||||||
}
|
}
|
||||||
|
26
src/layout/card/grid/NitroCardGridView.scss
Normal file
26
src/layout/card/grid/NitroCardGridView.scss
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
.nitro-card-grid {
|
||||||
|
|
||||||
|
.row-cols-3 {
|
||||||
|
|
||||||
|
.col {
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
|
||||||
|
&:nth-child(3n+3) {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-cols-5 {
|
||||||
|
|
||||||
|
.col {
|
||||||
|
padding-right: 0.25rem;
|
||||||
|
|
||||||
|
&:nth-child(5n+5) {
|
||||||
|
padding-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@import './item/NitroCardGridItemView.scss';
|
||||||
|
}
|
15
src/layout/card/grid/NitroCardGridView.tsx
Normal file
15
src/layout/card/grid/NitroCardGridView.tsx
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridViewProps } from './NitroCardGridView.types';
|
||||||
|
|
||||||
|
export const NitroCardGridView: FC<NitroCardGridViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { columns = 5, children = null } = props;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="h-100 overflow-hidden nitro-card-grid">
|
||||||
|
<div className={ `row row-cols-${ columns } align-content-start g-0 w-100 h-100 overflow-auto` }>
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
4
src/layout/card/grid/NitroCardGridView.types.ts
Normal file
4
src/layout/card/grid/NitroCardGridView.types.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
export interface NitroCardGridViewProps
|
||||||
|
{
|
||||||
|
columns?: number;
|
||||||
|
}
|
47
src/layout/card/grid/item/NitroCardGridItemView.scss
Normal file
47
src/layout/card/grid/item/NitroCardGridItemView.scss
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
.grid-item-container {
|
||||||
|
height: 48px;
|
||||||
|
max-height: 48px;
|
||||||
|
|
||||||
|
.grid-item {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border-color: $grid-border-color !important;
|
||||||
|
background-color: $grid-bg-color !important;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
border-color: $grid-active-border-color !important;
|
||||||
|
background-color: $grid-active-bg-color !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
top: 2px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-image {
|
||||||
|
width: 100% !important;
|
||||||
|
height: 100% !important;
|
||||||
|
background-position: center;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position-y: -32px !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trade-button {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 2px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 5px;
|
||||||
|
padding: 3px;
|
||||||
|
min-height: unset;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
right: unset;
|
||||||
|
left: 2px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/layout/card/grid/item/NitroCardGridItemView.tsx
Normal file
24
src/layout/card/grid/item/NitroCardGridItemView.tsx
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { FC } from 'react';
|
||||||
|
import { LimitedEditionStyledNumberView } from '../../../../views/shared/limited-edition/styled-number/LimitedEditionStyledNumberView';
|
||||||
|
import { NitroCardGridItemViewProps } from './NitroCardGridItemView.types';
|
||||||
|
|
||||||
|
export const NitroCardGridItemView: FC<NitroCardGridItemViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { itemActive = false, itemCount = 1, itemUnique = false, itemUniqueNumber = 0, itemImage = null, className = '', style = {}, children = null, ...rest } = props;
|
||||||
|
|
||||||
|
const imageUrl = `url(${ itemImage })`;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="col pb-1 grid-item-container">
|
||||||
|
<div className={ `position-relative border border-2 rounded grid-item cursor-pointer${ itemActive ? ' active' : '' }${ itemUnique ? ' unique-item' : '' } ${ className || '' }` } style={ itemImage ? { ...style, backgroundImage: imageUrl } : style } { ...rest }>
|
||||||
|
{ (itemCount > 1) &&
|
||||||
|
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ itemCount }</span> }
|
||||||
|
{ itemUnique &&
|
||||||
|
<div className="position-absolute unique-item-counter">
|
||||||
|
<LimitedEditionStyledNumberView value={ itemUniqueNumber } />
|
||||||
|
</div> }
|
||||||
|
{ children }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
10
src/layout/card/grid/item/NitroCardGridItemView.types.ts
Normal file
10
src/layout/card/grid/item/NitroCardGridItemView.types.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
import { DetailsHTMLAttributes } from 'react';
|
||||||
|
|
||||||
|
export interface NitroCardGridItemViewProps extends DetailsHTMLAttributes<HTMLDivElement>
|
||||||
|
{
|
||||||
|
itemImage?: string;
|
||||||
|
itemActive?: boolean;
|
||||||
|
itemCount?: number;
|
||||||
|
itemUnique?: boolean;
|
||||||
|
itemUniqueNumber?: number;
|
||||||
|
}
|
@ -44,7 +44,7 @@ export const CatalogNavigationItemView: FC<CatalogNavigationItemViewProps> = pro
|
|||||||
}, [ page, setActiveChild ]);
|
}, [ page, setActiveChild ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pe-1 pb-1 catalog-navigation-item-container">
|
<div className="col pb-1 catalog-navigation-item-container">
|
||||||
<div className={ 'd-flex align-items-center cursor-pointer catalog-navigation-item ' + (isActive ? 'active ': '') } onClick={ select }>
|
<div className={ 'd-flex align-items-center cursor-pointer catalog-navigation-item ' + (isActive ? 'active ': '') } onClick={ select }>
|
||||||
<CatalogIconView icon={ page.icon } />
|
<CatalogIconView icon={ page.icon } />
|
||||||
<div className="flex-grow-1 text-black text-truncate px-1">{ page.localization }</div>
|
<div className="flex-grow-1 text-black text-truncate px-1">{ page.localization }</div>
|
||||||
|
@ -87,12 +87,10 @@ export const CatalogPageView: FC<CatalogPageViewProps> = props =>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const windowData = Nitro.instance.sessionDataManager.getWallItemDataByName('ads_twi_windw');
|
const windowData = GetSessionDataManager().getWallItemDataByName('noob_window_double');
|
||||||
|
|
||||||
|
if(windowData) roomPreviewer.addWallItemIntoRoom(windowData.id, new Vector3d(90, 0, 0), windowData.customParams);
|
||||||
|
|
||||||
// if(windowData)
|
|
||||||
// {
|
|
||||||
// this._roomPreviewer.addWallItemIntoRoom(windowData.id, new Vector3d(90), windowData.customParams)
|
|
||||||
// }
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,14 +70,12 @@ export const CatalogLayoutSpacesView: FC<CatalogLayoutSpacesViewProps> = props =
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row h-100 nitro-catalog-layout-spaces">
|
<div className="row h-100 nitro-catalog-layout-spaces">
|
||||||
<div className="col-7 h-100 d-flex flex-column">
|
<div className="d-flex col-7 flex-column h-100 overflow-hidden">
|
||||||
<div className="d-flex">
|
<div className="btn-group mx-auto mb-1 w-100">
|
||||||
<div className="btn-group mx-auto mb-1 w-100">
|
{ groupNames.map((name, index) =>
|
||||||
{ groupNames.map((name, index) =>
|
{
|
||||||
{
|
return <button key={ index } type="button" className={ 'btn btn-primary btn-sm ' + ((activeGroupIndex === index) ? 'active ' : '' )} onClick={ event => setActiveGroupIndex(index) }>{ LocalizeText(`catalog.spaces.tab.${ name }`) }</button>
|
||||||
return <button key={ index } type="button" className={ 'btn btn-primary btn-sm ' + ((activeGroupIndex === index) ? 'active ' : '' )} onClick={ event => setActiveGroupIndex(index) }>{ LocalizeText(`catalog.spaces.tab.${ name }`) }</button>
|
})}
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<CatalogPageOffersView offers={ groups[activeGroupIndex] } />
|
<CatalogPageOffersView offers={ groups[activeGroupIndex] } />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { MessengerInitComposer } from 'nitro-renderer';
|
import { MessengerInitComposer, RoomEngineObjectEvent, RoomObjectCategory } from 'nitro-renderer';
|
||||||
import React, { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
import React, { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
import { FriendListEvent } from '../../events';
|
import { GetRoomSession } from '../../api';
|
||||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { FriendEnteredRoomEvent, FriendListEvent } from '../../events';
|
||||||
|
import { useRoomEngineEvent } from '../../hooks/events';
|
||||||
|
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { SendMessageHook } from '../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { NitroCardAccordionItemView, NitroCardAccordionView, NitroCardHeaderView, NitroCardView } from '../../layout';
|
import { NitroCardAccordionItemView, NitroCardAccordionView, NitroCardHeaderView, NitroCardView } from '../../layout';
|
||||||
import { LocalizeText } from '../../utils/LocalizeText';
|
import { LocalizeText } from '../../utils/LocalizeText';
|
||||||
@ -48,6 +50,30 @@ export const FriendListView: FC<FriendListViewProps> = props =>
|
|||||||
SendMessageHook(new MessengerInitComposer());
|
SendMessageHook(new MessengerInitComposer());
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||||
|
{
|
||||||
|
const roomSession = GetRoomSession();
|
||||||
|
|
||||||
|
if(!roomSession) return;
|
||||||
|
|
||||||
|
if(event.category !== RoomObjectCategory.UNIT) return;
|
||||||
|
|
||||||
|
const userData = roomSession.userDataManager.getUserDataByIndex(event.objectId);
|
||||||
|
|
||||||
|
if(!userData) return;
|
||||||
|
|
||||||
|
const friend = friendListState.friends.find(friend =>
|
||||||
|
{
|
||||||
|
return (friend.id === userData.webID);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(!friend) return;
|
||||||
|
|
||||||
|
dispatchUiEvent(new FriendEnteredRoomEvent(userData.roomIndex, RoomObjectCategory.UNIT, userData.webID, userData.name, userData.type));
|
||||||
|
}, [ friendListState.friends ]);
|
||||||
|
|
||||||
|
useRoomEngineEvent(RoomEngineObjectEvent.ADDED, onRoomEngineObjectEvent);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FriendListContextProvider value={ { friendListState, dispatchFriendListState } }>
|
<FriendListContextProvider value={ { friendListState, dispatchFriendListState } }>
|
||||||
<FriendListMessageHandler />
|
<FriendListMessageHandler />
|
||||||
|
@ -36,7 +36,7 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
|||||||
</button>
|
</button>
|
||||||
{ Array.from(Array(maxDisplayCount), (e, i) =>
|
{ Array.from(Array(maxDisplayCount), (e, i) =>
|
||||||
{
|
{
|
||||||
return <FriendBarItemView friend={ (onlineFriends[ indexOffset + i ] || null) } />;
|
return <FriendBarItemView key={ i } friend={ (onlineFriends[ indexOffset + i ] || null) } />;
|
||||||
}) }
|
}) }
|
||||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>
|
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>
|
||||||
<i className="fas fa-chevron-right" />
|
<i className="fas fa-chevron-right" />
|
||||||
|
@ -1,15 +1,17 @@
|
|||||||
import { BadgesEvent, BotAddedToInventoryEvent, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent, PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory } from 'nitro-renderer';
|
import { AdvancedMap, BadgesEvent, BotAddedToInventoryEvent, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent, PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, TradingAcceptEvent, TradingCloseEvent, TradingCompletedEvent, TradingConfirmationEvent, TradingListItemEvent, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingYouAreNotAllowedEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
|
import { GetRoomSession, GetSessionDataManager } from '../../api';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { mergeFurniFragments } from './common/FurnitureUtilities';
|
import { mergeFurniFragments } from './common/FurnitureUtilities';
|
||||||
import { mergePetFragments } from './common/PetUtilities';
|
import { mergePetFragments } from './common/PetUtilities';
|
||||||
|
import { TradeState } from './common/TradeState';
|
||||||
|
import { TradeUserData } from './common/TradeUserData';
|
||||||
import { useInventoryContext } from './context/InventoryContext';
|
import { useInventoryContext } from './context/InventoryContext';
|
||||||
import { InventoryMessageHandlerProps } from './InventoryMessageHandler.types';
|
import { InventoryMessageHandlerProps } from './InventoryMessageHandler.types';
|
||||||
import { InventoryBadgeActions } from './reducers/InventoryBadgeReducer';
|
import { InventoryBadgeActions } from './reducers/InventoryBadgeReducer';
|
||||||
import { InventoryBotActions } from './reducers/InventoryBotReducer';
|
import { InventoryBotActions } from './reducers/InventoryBotReducer';
|
||||||
import { InventoryFurnitureActions } from './reducers/InventoryFurnitureReducer';
|
import { InventoryFurnitureActions } from './reducers/InventoryFurnitureReducer';
|
||||||
import { InventoryPetActions } from './reducers/InventoryPetReducer';
|
import { InventoryPetActions } from './reducers/InventoryPetReducer';
|
||||||
|
|
||||||
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
|
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
|
||||||
let petMsgFragments: Map<number, PetData>[] = null;
|
let petMsgFragments: Map<number, PetData>[] = null;
|
||||||
|
|
||||||
@ -161,6 +163,137 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
});
|
});
|
||||||
}, [ dispatchBadgeState ]);
|
}, [ dispatchBadgeState ]);
|
||||||
|
|
||||||
|
const onTradingAcceptEvent = useCallback((event: TradingAcceptEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_TRADE_ACCEPTANCE,
|
||||||
|
payload: {
|
||||||
|
userId: parser.userID,
|
||||||
|
flag: parser.userAccepts
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingCloseEvent = useCallback((event: TradingCloseEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.CLOSE_TRADE,
|
||||||
|
payload: {}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingCompletedEvent = useCallback((event: TradingCompletedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.CLOSE_TRADE,
|
||||||
|
payload: {}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingConfirmationEvent = useCallback((event: TradingConfirmationEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_TRADE_STATE,
|
||||||
|
payload: {
|
||||||
|
tradeState: TradeState.TRADING_STATE_COUNTDOWN
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingListItemEvent = useCallback((event: TradingListItemEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.UPDATE_TRADE,
|
||||||
|
payload: {
|
||||||
|
tradeParser: event.getParser()
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingNotOpenEvent = useCallback((event: TradingNotOpenEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onTradingOpenEvent = useCallback((event: TradingOpenEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
const ownUser = new TradeUserData();
|
||||||
|
const otherUser = new TradeUserData();
|
||||||
|
|
||||||
|
ownUser.userItems = new AdvancedMap();
|
||||||
|
otherUser.userItems = new AdvancedMap();
|
||||||
|
|
||||||
|
const userDataOne = GetRoomSession().userDataManager.getUserData(parser.userID);
|
||||||
|
const userDataTwo = GetRoomSession().userDataManager.getUserData(parser.otherUserID);
|
||||||
|
|
||||||
|
if(userDataOne.webID === GetSessionDataManager().userId)
|
||||||
|
{
|
||||||
|
ownUser.userId = userDataOne.webID;
|
||||||
|
ownUser.userName = userDataOne.name;
|
||||||
|
ownUser.canTrade = parser.userCanTrade;
|
||||||
|
|
||||||
|
otherUser.userId = userDataTwo.webID;
|
||||||
|
otherUser.userName = userDataTwo.name;
|
||||||
|
otherUser.canTrade = parser.otherUserCanTrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(userDataTwo.webID === GetSessionDataManager().userId)
|
||||||
|
{
|
||||||
|
ownUser.userId = userDataTwo.webID;
|
||||||
|
ownUser.userName = userDataTwo.name;
|
||||||
|
ownUser.canTrade = parser.otherUserCanTrade;
|
||||||
|
|
||||||
|
otherUser.userId = userDataOne.webID;
|
||||||
|
otherUser.userName = userDataOne.name;
|
||||||
|
otherUser.canTrade = parser.userCanTrade;
|
||||||
|
}
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_TRADE_DATA,
|
||||||
|
payload: {
|
||||||
|
ownTradeUser: ownUser,
|
||||||
|
otherTradeUser: otherUser
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, [ dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const onTradingOpenFailedEvent = useCallback((event: TradingOpenFailedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onTradingOtherNotAllowedEvent = useCallback((event: TradingOtherNotAllowedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onTradingYouAreNotAllowedEvent = useCallback((event: TradingYouAreNotAllowedEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(FurnitureListAddOrUpdateEvent, onFurnitureListAddOrUpdateEvent);
|
CreateMessageHook(FurnitureListAddOrUpdateEvent, onFurnitureListAddOrUpdateEvent);
|
||||||
CreateMessageHook(FurnitureListEvent, onFurnitureListEvent);
|
CreateMessageHook(FurnitureListEvent, onFurnitureListEvent);
|
||||||
CreateMessageHook(FurnitureListInvalidateEvent, onFurnitureListInvalidateEvent);
|
CreateMessageHook(FurnitureListInvalidateEvent, onFurnitureListInvalidateEvent);
|
||||||
@ -173,6 +306,16 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
CreateMessageHook(PetRemovedFromInventory, onPetRemovedFromInventory);
|
CreateMessageHook(PetRemovedFromInventory, onPetRemovedFromInventory);
|
||||||
CreateMessageHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
|
CreateMessageHook(PetAddedToInventoryEvent, onPetAddedToInventoryEvent);
|
||||||
CreateMessageHook(BadgesEvent, onBadgesEvent);
|
CreateMessageHook(BadgesEvent, onBadgesEvent);
|
||||||
|
CreateMessageHook(TradingAcceptEvent, onTradingAcceptEvent);
|
||||||
|
CreateMessageHook(TradingCloseEvent, onTradingCloseEvent);
|
||||||
|
CreateMessageHook(TradingCompletedEvent, onTradingCompletedEvent);
|
||||||
|
CreateMessageHook(TradingConfirmationEvent, onTradingConfirmationEvent);
|
||||||
|
CreateMessageHook(TradingListItemEvent, onTradingListItemEvent);
|
||||||
|
CreateMessageHook(TradingNotOpenEvent, onTradingNotOpenEvent);
|
||||||
|
CreateMessageHook(TradingOpenEvent, onTradingOpenEvent);
|
||||||
|
CreateMessageHook(TradingOpenFailedEvent, onTradingOpenFailedEvent);
|
||||||
|
CreateMessageHook(TradingOtherNotAllowedEvent, onTradingOtherNotAllowedEvent);
|
||||||
|
CreateMessageHook(TradingYouAreNotAllowedEvent, onTradingYouAreNotAllowedEvent);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
height: 240px;
|
height: 240px;
|
||||||
max-height: 430px;
|
max-height: 430px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
overflow:auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.empty-image {
|
.empty-image {
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
import { IRoomSession, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomPreviewer, RoomSessionEvent } from 'nitro-renderer';
|
import { IRoomSession, RoomEngineObjectEvent, RoomEngineObjectPlacedEvent, RoomPreviewer, RoomSessionEvent, TradingCancelComposer, TradingCloseComposer, TradingOpenComposer } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
import { FC, useCallback, useEffect, useReducer, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../api';
|
import { GetConnection, GetRoomEngine } from '../../api';
|
||||||
import { InventoryEvent } from '../../events';
|
import { InventoryEvent, InventoryTradeRequestEvent } from '../../events';
|
||||||
import { useRoomEngineEvent } from '../../hooks/events/nitro/room/room-engine-event';
|
import { useRoomEngineEvent } from '../../hooks/events/nitro/room/room-engine-event';
|
||||||
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
|
||||||
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
import { useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
|
import { SendMessageHook } from '../../hooks/messages';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../layout';
|
||||||
import { LocalizeText } from '../../utils/LocalizeText';
|
import { LocalizeText } from '../../utils/LocalizeText';
|
||||||
import { isObjectMoverRequested, setObjectMoverRequested } from './common/InventoryUtilities';
|
import { isObjectMoverRequested, setObjectMoverRequested } from './common/InventoryUtilities';
|
||||||
|
import { TradeState } from './common/TradeState';
|
||||||
import { InventoryContextProvider } from './context/InventoryContext';
|
import { InventoryContextProvider } from './context/InventoryContext';
|
||||||
import { InventoryMessageHandler } from './InventoryMessageHandler';
|
import { InventoryMessageHandler } from './InventoryMessageHandler';
|
||||||
import { InventoryTabs, InventoryViewProps } from './InventoryView.types';
|
import { InventoryTabs, InventoryViewProps } from './InventoryView.types';
|
||||||
@ -19,11 +21,12 @@ import { InventoryBadgeView } from './views/badge/InventoryBadgeView';
|
|||||||
import { InventoryBotView } from './views/bot/InventoryBotView';
|
import { InventoryBotView } from './views/bot/InventoryBotView';
|
||||||
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
|
import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView';
|
||||||
import { InventoryPetView } from './views/pet/InventoryPetView';
|
import { InventoryPetView } from './views/pet/InventoryPetView';
|
||||||
|
import { InventoryTradeView } from './views/trade/InventoryTradeView';
|
||||||
|
|
||||||
|
const tabs = [ InventoryTabs.FURNITURE, InventoryTabs.BOTS, InventoryTabs.PETS, InventoryTabs.BADGES ];
|
||||||
|
|
||||||
export const InventoryView: FC<InventoryViewProps> = props =>
|
export const InventoryView: FC<InventoryViewProps> = props =>
|
||||||
{
|
{
|
||||||
const tabs = [ InventoryTabs.FURNITURE, InventoryTabs.BOTS, InventoryTabs.PETS, InventoryTabs.BADGES ];
|
|
||||||
|
|
||||||
const [ isVisible, setIsVisible ] = useState(false);
|
const [ isVisible, setIsVisible ] = useState(false);
|
||||||
const [ currentTab, setCurrentTab ] = useState<string>(tabs[0]);
|
const [ currentTab, setCurrentTab ] = useState<string>(tabs[0]);
|
||||||
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
||||||
@ -33,25 +36,60 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
const [ petState, dispatchPetState ] = useReducer(InventoryPetReducer, initialInventoryPet);
|
const [ petState, dispatchPetState ] = useReducer(InventoryPetReducer, initialInventoryPet);
|
||||||
const [ badgeState, dispatchBadgeState ] = useReducer(InventoryBadgeReducer, initialInventoryBadge);
|
const [ badgeState, dispatchBadgeState ] = useReducer(InventoryBadgeReducer, initialInventoryBadge);
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
if(furnitureState.tradeData)
|
||||||
|
{
|
||||||
|
switch(furnitureState.tradeData.state)
|
||||||
|
{
|
||||||
|
case TradeState.TRADING_STATE_RUNNING:
|
||||||
|
SendMessageHook(new TradingCloseComposer());
|
||||||
|
return;
|
||||||
|
case TradeState.TRADING_STATE_CONFIRMING:
|
||||||
|
SendMessageHook(new TradingCancelComposer());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsVisible(false);
|
||||||
|
}, [ furnitureState.tradeData ]);
|
||||||
|
|
||||||
const onInventoryEvent = useCallback((event: InventoryEvent) =>
|
const onInventoryEvent = useCallback((event: InventoryEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case InventoryEvent.SHOW_INVENTORY:
|
case InventoryEvent.SHOW_INVENTORY:
|
||||||
|
if(isVisible) return;
|
||||||
|
|
||||||
setIsVisible(true);
|
setIsVisible(true);
|
||||||
return;
|
return;
|
||||||
case InventoryEvent.HIDE_INVENTORY:
|
case InventoryEvent.HIDE_INVENTORY:
|
||||||
setIsVisible(false);
|
if(!isVisible) return;
|
||||||
|
|
||||||
|
close();
|
||||||
return;
|
return;
|
||||||
case InventoryEvent.TOGGLE_INVENTORY:
|
case InventoryEvent.TOGGLE_INVENTORY:
|
||||||
setIsVisible(value => !value);
|
if(!isVisible)
|
||||||
|
{
|
||||||
|
setIsVisible(true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
close();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
|
case InventoryTradeRequestEvent.REQUEST_TRADE: {
|
||||||
|
const tradeEvent = (event as InventoryTradeRequestEvent);
|
||||||
|
|
||||||
|
GetConnection().send(new TradingOpenComposer(tradeEvent.objectId));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}, []);
|
}, [ isVisible, close ]);
|
||||||
|
|
||||||
useUiEvent(InventoryEvent.SHOW_INVENTORY, onInventoryEvent);
|
useUiEvent(InventoryEvent.SHOW_INVENTORY, onInventoryEvent);
|
||||||
useUiEvent(InventoryEvent.HIDE_INVENTORY, onInventoryEvent);
|
useUiEvent(InventoryEvent.HIDE_INVENTORY, onInventoryEvent);
|
||||||
useUiEvent(InventoryEvent.TOGGLE_INVENTORY, onInventoryEvent);
|
useUiEvent(InventoryEvent.TOGGLE_INVENTORY, onInventoryEvent);
|
||||||
|
useUiEvent(InventoryTradeRequestEvent.REQUEST_TRADE, onInventoryEvent);
|
||||||
|
|
||||||
const onRoomEngineObjectPlacedEvent = useCallback((event: RoomEngineObjectPlacedEvent) =>
|
const onRoomEngineObjectPlacedEvent = useCallback((event: RoomEngineObjectPlacedEvent) =>
|
||||||
{
|
{
|
||||||
@ -96,32 +134,47 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isVisible)
|
||||||
|
{
|
||||||
|
if(furnitureState.tradeData) setIsVisible(true);
|
||||||
|
}
|
||||||
|
}, [ furnitureState.tradeData, isVisible ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<InventoryContextProvider value={ { furnitureState, dispatchFurnitureState, botState, dispatchBotState, petState, dispatchPetState, badgeState, dispatchBadgeState } }>
|
<InventoryContextProvider value={ { furnitureState, dispatchFurnitureState, botState, dispatchBotState, petState, dispatchPetState, badgeState, dispatchBadgeState } }>
|
||||||
<InventoryMessageHandler />
|
<InventoryMessageHandler />
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
<NitroCardView className="nitro-inventory">
|
<NitroCardView className="nitro-inventory">
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('inventory.title') } onCloseClick={ event => setIsVisible(false) } />
|
<NitroCardHeaderView headerText={ LocalizeText('inventory.title') } onCloseClick={ close } />
|
||||||
<NitroCardTabsView>
|
{ !furnitureState.tradeData &&
|
||||||
{ tabs.map((name, index) =>
|
<>
|
||||||
{
|
<NitroCardTabsView>
|
||||||
return (
|
{ tabs.map((name, index) =>
|
||||||
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) }>
|
{
|
||||||
{ LocalizeText(name) }
|
return (
|
||||||
</NitroCardTabsItemView>
|
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) }>
|
||||||
);
|
{ LocalizeText(name) }
|
||||||
}) }
|
</NitroCardTabsItemView>
|
||||||
</NitroCardTabsView>
|
);
|
||||||
<NitroCardContentView>
|
}) }
|
||||||
{ (currentTab === InventoryTabs.FURNITURE ) &&
|
</NitroCardTabsView>
|
||||||
<InventoryFurnitureView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
<NitroCardContentView>
|
||||||
{ (currentTab === InventoryTabs.BOTS ) &&
|
{ (currentTab === InventoryTabs.FURNITURE ) &&
|
||||||
<InventoryBotView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
<InventoryFurnitureView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
||||||
{ (currentTab === InventoryTabs.PETS ) &&
|
{ (currentTab === InventoryTabs.BOTS ) &&
|
||||||
<InventoryPetView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
<InventoryBotView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
||||||
{ (currentTab === InventoryTabs.BADGES ) &&
|
{ (currentTab === InventoryTabs.PETS ) &&
|
||||||
<InventoryBadgeView /> }
|
<InventoryPetView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
|
||||||
</NitroCardContentView>
|
{ (currentTab === InventoryTabs.BADGES ) &&
|
||||||
|
<InventoryBadgeView /> }
|
||||||
|
</NitroCardContentView>
|
||||||
|
</> }
|
||||||
|
{ furnitureState.tradeData &&
|
||||||
|
<NitroCardContentView>
|
||||||
|
<InventoryTradeView cancelTrade={ close } />
|
||||||
|
</NitroCardContentView> }
|
||||||
</NitroCardView> }
|
</NitroCardView> }
|
||||||
</InventoryContextProvider>
|
</InventoryContextProvider>
|
||||||
);
|
);
|
||||||
|
@ -3,8 +3,8 @@ export interface InventoryViewProps
|
|||||||
|
|
||||||
export class InventoryTabs
|
export class InventoryTabs
|
||||||
{
|
{
|
||||||
public static readonly FURNITURE: string = 'inventory.furni';
|
public static readonly FURNITURE: string = 'inventory.furni';
|
||||||
public static readonly BOTS: string = 'inventory.bots';
|
public static readonly BOTS: string = 'inventory.bots';
|
||||||
public static readonly PETS: string = 'inventory.furni.tab.pets';
|
public static readonly PETS: string = 'inventory.furni.tab.pets';
|
||||||
public static readonly BADGES: string = 'inventory.badges';
|
public static readonly BADGES: string = 'inventory.badges';
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,8 @@ export class FurnitureItem implements IFurnitureItem
|
|||||||
|
|
||||||
constructor(parser: IFurnitureItemData)
|
constructor(parser: IFurnitureItemData)
|
||||||
{
|
{
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
this._locked = false;
|
this._locked = false;
|
||||||
this._id = parser.itemId;
|
this._id = parser.itemId;
|
||||||
this._type = parser.spriteId;
|
this._type = parser.spriteId;
|
||||||
@ -189,26 +191,26 @@ export class FurnitureItem implements IFurnitureItem
|
|||||||
|
|
||||||
public update(parser: IFurnitureItemData): void
|
public update(parser: IFurnitureItemData): void
|
||||||
{
|
{
|
||||||
this._type = parser.spriteId;
|
this._type = parser.spriteId;
|
||||||
this._ref = parser.ref;
|
this._ref = parser.ref;
|
||||||
this._category = parser.category;
|
this._category = parser.category;
|
||||||
this._groupable = (parser.isGroupable && !parser.rentable);
|
this._groupable = (parser.isGroupable && !parser.rentable);
|
||||||
this._tradeable = parser.tradable;
|
this._tradeable = parser.tradable;
|
||||||
this._recyclable = parser.isRecycleable;
|
this._recyclable = parser.isRecycleable;
|
||||||
this._sellable = parser.sellable;
|
this._sellable = parser.sellable;
|
||||||
this._stuffData = parser.stuffData;
|
this._stuffData = parser.stuffData;
|
||||||
this._extra = parser.extra;
|
this._extra = parser.extra;
|
||||||
this._secondsToExpiration = parser.secondsToExpiration;
|
this._secondsToExpiration = parser.secondsToExpiration;
|
||||||
this._expirationTimeStamp = parser.expirationTimeStamp;
|
this._expirationTimeStamp = parser.expirationTimeStamp;
|
||||||
this._hasRentPeriodStarted = parser.hasRentPeriodStarted;
|
this._hasRentPeriodStarted = parser.hasRentPeriodStarted;
|
||||||
this._creationDay = parser.creationDay;
|
this._creationDay = parser.creationDay;
|
||||||
this._creationMonth = parser.creationMonth;
|
this._creationMonth = parser.creationMonth;
|
||||||
this._creationYear = parser.creationYear;
|
this._creationYear = parser.creationYear;
|
||||||
this._slotId = parser.slotId;
|
this._slotId = parser.slotId;
|
||||||
this._songId = parser.songId;
|
this._songId = parser.songId;
|
||||||
this._flatId = parser.flatId;
|
this._flatId = parser.flatId;
|
||||||
this._isRented = parser.rentable;
|
this._isRented = parser.rentable;
|
||||||
this._isWallItem = parser.isWallItem;
|
this._isWallItem = parser.isWallItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public clone(): FurnitureItem
|
public clone(): FurnitureItem
|
||||||
|
@ -310,7 +310,7 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
return existingGroup;
|
return existingGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
function createGroupItem(type: number, category: number, stuffData: IObjectData, extra: number = NaN, flag: boolean = false): GroupItem
|
export function createGroupItem(type: number, category: number, stuffData: IObjectData, extra: number = NaN, flag: boolean = false): GroupItem
|
||||||
{
|
{
|
||||||
// const iconImage: HTMLImageElement = null;
|
// const iconImage: HTMLImageElement = null;
|
||||||
|
|
||||||
|
@ -20,21 +20,42 @@ export class GroupItem
|
|||||||
private _hasUnseenItems: boolean;
|
private _hasUnseenItems: boolean;
|
||||||
private _items: FurnitureItem[];
|
private _items: FurnitureItem[];
|
||||||
|
|
||||||
constructor(type: number, category: number, roomEngine: IRoomEngine, stuffData: IObjectData, extra: number)
|
constructor(type: number = -1, category: number = -1, roomEngine: IRoomEngine = null, stuffData: IObjectData = null, extra: number = -1)
|
||||||
{
|
{
|
||||||
this._type = type;
|
this._type = type;
|
||||||
this._category = category;
|
this._category = category;
|
||||||
this._roomEngine = roomEngine;
|
this._roomEngine = roomEngine;
|
||||||
this._stuffData = stuffData;
|
this._stuffData = stuffData;
|
||||||
this._extra = extra;
|
this._extra = extra;
|
||||||
this._isWallItem = false;
|
this._isWallItem = false;
|
||||||
this._iconUrl = null;
|
this._iconUrl = null;
|
||||||
this._name = null;
|
this._name = null;
|
||||||
this._description = null;
|
this._description = null;
|
||||||
this._locked = false;
|
this._locked = false;
|
||||||
this._selected = false;
|
this._selected = false;
|
||||||
this._hasUnseenItems = false;
|
this._hasUnseenItems = false;
|
||||||
this._items = [];
|
this._items = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
public clone(): GroupItem
|
||||||
|
{
|
||||||
|
const groupItem = new GroupItem();
|
||||||
|
|
||||||
|
groupItem._type = this._type;
|
||||||
|
groupItem._category = this._category;
|
||||||
|
groupItem._roomEngine = this._roomEngine;
|
||||||
|
groupItem._stuffData = this._stuffData;
|
||||||
|
groupItem._extra = this._extra;
|
||||||
|
groupItem._isWallItem = this._isWallItem;
|
||||||
|
groupItem._iconUrl = this._iconUrl;
|
||||||
|
groupItem._name = this._name;
|
||||||
|
groupItem._description = this._description;
|
||||||
|
groupItem._locked = this._locked;
|
||||||
|
groupItem._selected = this._selected;
|
||||||
|
groupItem._hasUnseenItems = this._hasUnseenItems;
|
||||||
|
groupItem._items = this._items;
|
||||||
|
|
||||||
|
return groupItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
public prepareGroup(): void
|
public prepareGroup(): void
|
||||||
@ -251,11 +272,12 @@ export class GroupItem
|
|||||||
this._items = items;
|
this._items = items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public lockItemIds(itemIds: number[]): void
|
public lockItemIds(itemIds: number[]): boolean
|
||||||
{
|
{
|
||||||
const items = [ ...this._items ];
|
const items = [ ...this._items ];
|
||||||
|
|
||||||
let index = 0;
|
let index = 0;
|
||||||
|
let updated = false;
|
||||||
|
|
||||||
while(index < items.length)
|
while(index < items.length)
|
||||||
{
|
{
|
||||||
@ -264,6 +286,8 @@ export class GroupItem
|
|||||||
|
|
||||||
if(item.locked !== locked)
|
if(item.locked !== locked)
|
||||||
{
|
{
|
||||||
|
updated = true;
|
||||||
|
|
||||||
const newItem = item.clone();
|
const newItem = item.clone();
|
||||||
|
|
||||||
newItem.locked = locked;
|
newItem.locked = locked;
|
||||||
@ -275,6 +299,8 @@ export class GroupItem
|
|||||||
}
|
}
|
||||||
|
|
||||||
this._items = items;
|
this._items = items;
|
||||||
|
|
||||||
|
return updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
private setName(): void
|
private setName(): void
|
||||||
|
10
src/views/inventory/common/TradeState.ts
Normal file
10
src/views/inventory/common/TradeState.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export class TradeState
|
||||||
|
{
|
||||||
|
public static TRADING_STATE_READY: number = 0;
|
||||||
|
public static TRADING_STATE_RUNNING: number = 1;
|
||||||
|
public static TRADING_STATE_COUNTDOWN: number = 2;
|
||||||
|
public static TRADING_STATE_CONFIRMING: number = 3;
|
||||||
|
public static TRADING_STATE_CONFIRMED: number = 4;
|
||||||
|
public static TRADING_STATE_COMPLETED: number = 5;
|
||||||
|
public static TRADING_STATE_CANCELLED: number = 6;
|
||||||
|
}
|
15
src/views/inventory/common/TradeUserData.ts
Normal file
15
src/views/inventory/common/TradeUserData.ts
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
import { AdvancedMap } from 'nitro-renderer';
|
||||||
|
import { GroupItem } from './GroupItem';
|
||||||
|
|
||||||
|
export class TradeUserData
|
||||||
|
{
|
||||||
|
constructor(
|
||||||
|
public userId: number = -1,
|
||||||
|
public userName: string = '',
|
||||||
|
public userItems: AdvancedMap<string, GroupItem> = null,
|
||||||
|
public itemCount: number = 0,
|
||||||
|
public creditsCount: number = 0,
|
||||||
|
public accepts: boolean = false,
|
||||||
|
public canTrade: boolean = false,
|
||||||
|
public items: AdvancedMap<string, GroupItem> = new AdvancedMap()) {}
|
||||||
|
}
|
73
src/views/inventory/common/TradingUtilities.ts
Normal file
73
src/views/inventory/common/TradingUtilities.ts
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
import { AdvancedMap, IObjectData, ItemDataStructure, StringDataType } from 'nitro-renderer';
|
||||||
|
import { GetSessionDataManager } from '../../../api';
|
||||||
|
import { FurniCategory } from './FurniCategory';
|
||||||
|
import { FurnitureItem } from './FurnitureItem';
|
||||||
|
import { createGroupItem } from './FurnitureUtilities';
|
||||||
|
import { GroupItem } from './GroupItem';
|
||||||
|
|
||||||
|
function isExternalImage(spriteId: number): boolean
|
||||||
|
{
|
||||||
|
const furnitureData = GetSessionDataManager().getWallItemData(spriteId);
|
||||||
|
|
||||||
|
return (furnitureData && furnitureData.isExternalImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function parseTradeItems(items: ItemDataStructure[], _arg_2: AdvancedMap<string, GroupItem>): void
|
||||||
|
{
|
||||||
|
const totalItems = items.length;
|
||||||
|
|
||||||
|
if(!totalItems) return;
|
||||||
|
|
||||||
|
for(const item of items)
|
||||||
|
{
|
||||||
|
const spriteId = item.spriteId;
|
||||||
|
const category = item.category;
|
||||||
|
|
||||||
|
let name = (item.furniType + spriteId);
|
||||||
|
|
||||||
|
if(!item.isGroupable || isExternalImage(spriteId))
|
||||||
|
{
|
||||||
|
name = ('itemid' + item.itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(item.category === FurniCategory._Str_5186)
|
||||||
|
{
|
||||||
|
name = (item.itemId + 'poster' + item.stuffData.getLegacyString());
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(item.category === FurniCategory._Str_12454)
|
||||||
|
{
|
||||||
|
name = '';
|
||||||
|
}
|
||||||
|
|
||||||
|
let groupItem = ((item.isGroupable && !isExternalImage(item.spriteId)) ? _arg_2.getValue(name) : null);
|
||||||
|
|
||||||
|
if(!groupItem)
|
||||||
|
{
|
||||||
|
groupItem = createGroupItem(spriteId, category, item.stuffData);
|
||||||
|
|
||||||
|
_arg_2.add(name, groupItem);
|
||||||
|
}
|
||||||
|
|
||||||
|
groupItem.push(new FurnitureItem(item));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function _Str_16998(spriteId: number, stuffData: IObjectData): string
|
||||||
|
{
|
||||||
|
let type = spriteId.toString();
|
||||||
|
const _local_4 = (stuffData as StringDataType);
|
||||||
|
|
||||||
|
if(!(stuffData instanceof StringDataType)) return type;
|
||||||
|
|
||||||
|
let _local_5 = 1;
|
||||||
|
|
||||||
|
while(_local_5 < 5)
|
||||||
|
{
|
||||||
|
type = (type + (',' + _local_4.getValue(_local_5)));
|
||||||
|
|
||||||
|
_local_5++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return type;
|
||||||
|
}
|
@ -1,14 +1,22 @@
|
|||||||
import { FurnitureListItemParser } from 'nitro-renderer';
|
import { AdvancedMap, FurnitureListItemParser, TradingListItemParser } from 'nitro-renderer';
|
||||||
import { Reducer } from 'react';
|
import { Reducer } from 'react';
|
||||||
import { FurnitureItem } from '../common/FurnitureItem';
|
import { FurnitureItem } from '../common/FurnitureItem';
|
||||||
import { addFurnitureItem, processFurniFragment, removeFurniItemById } from '../common/FurnitureUtilities';
|
import { addFurnitureItem, processFurniFragment, removeFurniItemById } from '../common/FurnitureUtilities';
|
||||||
import { GroupItem } from '../common/GroupItem';
|
import { GroupItem } from '../common/GroupItem';
|
||||||
|
import { TradeState } from '../common/TradeState';
|
||||||
|
import { TradeUserData } from '../common/TradeUserData';
|
||||||
|
import { parseTradeItems } from '../common/TradingUtilities';
|
||||||
|
|
||||||
export interface IInventoryFurnitureState
|
export interface IInventoryFurnitureState
|
||||||
{
|
{
|
||||||
needsFurniUpdate: boolean;
|
needsFurniUpdate: boolean;
|
||||||
groupItem: GroupItem;
|
groupItem: GroupItem;
|
||||||
groupItems: GroupItem[];
|
groupItems: GroupItem[];
|
||||||
|
tradeData: {
|
||||||
|
ownUser: TradeUserData;
|
||||||
|
otherUser: TradeUserData;
|
||||||
|
state: number;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IInventoryFurnitureAction
|
export interface IInventoryFurnitureAction
|
||||||
@ -20,6 +28,11 @@ export interface IInventoryFurnitureAction
|
|||||||
parsers?: FurnitureListItemParser[];
|
parsers?: FurnitureListItemParser[];
|
||||||
itemId?: number;
|
itemId?: number;
|
||||||
fragment?: Map<number, FurnitureListItemParser>;
|
fragment?: Map<number, FurnitureListItemParser>;
|
||||||
|
ownTradeUser?: TradeUserData;
|
||||||
|
otherTradeUser?: TradeUserData;
|
||||||
|
tradeState?: number;
|
||||||
|
userId?: number;
|
||||||
|
tradeParser?: TradingListItemParser;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,12 +43,18 @@ export class InventoryFurnitureActions
|
|||||||
public static PROCESS_FRAGMENT: string = 'IFA_PROCESS_FRAGMENT';
|
public static PROCESS_FRAGMENT: string = 'IFA_PROCESS_FRAGMENT';
|
||||||
public static ADD_OR_UPDATE_FURNITURE: string = 'IFA_ADD_OR_UPDATE_FURNITURE';
|
public static ADD_OR_UPDATE_FURNITURE: string = 'IFA_ADD_OR_UPDATE_FURNITURE';
|
||||||
public static REMOVE_FURNITURE: string = 'IFA_REMOVE_FURNITURE';
|
public static REMOVE_FURNITURE: string = 'IFA_REMOVE_FURNITURE';
|
||||||
|
public static SET_TRADE_DATA: string = 'IFA_SET_TRADE_DATA';
|
||||||
|
public static SET_TRADE_STATE: string = 'IFA_SET_TRADE_STATE';
|
||||||
|
public static SET_TRADE_ACCEPTANCE: string = 'FA_SET_TRADE_ACCEPTANCE';
|
||||||
|
public static CLOSE_TRADE: string = 'IFA_CLOSE_STRING';
|
||||||
|
public static UPDATE_TRADE: string = 'IFA_UPDATE_TRADE';
|
||||||
}
|
}
|
||||||
|
|
||||||
export const initialInventoryFurniture: IInventoryFurnitureState = {
|
export const initialInventoryFurniture: IInventoryFurnitureState = {
|
||||||
needsFurniUpdate: true,
|
needsFurniUpdate: true,
|
||||||
groupItem: null,
|
groupItem: null,
|
||||||
groupItems: []
|
groupItems: [],
|
||||||
|
tradeData: null
|
||||||
}
|
}
|
||||||
|
|
||||||
export const InventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInventoryFurnitureAction> = (state, action) =>
|
export const InventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInventoryFurnitureAction> = (state, action) =>
|
||||||
@ -131,6 +150,121 @@ export const InventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInven
|
|||||||
|
|
||||||
return { ...state, groupItems };
|
return { ...state, groupItems };
|
||||||
}
|
}
|
||||||
|
case InventoryFurnitureActions.SET_TRADE_DATA: {
|
||||||
|
const tradeData = { ...state.tradeData };
|
||||||
|
|
||||||
|
tradeData.ownUser = (action.payload.ownTradeUser || null);
|
||||||
|
tradeData.otherUser = (action.payload.otherTradeUser || null);
|
||||||
|
tradeData.state = TradeState.TRADING_STATE_RUNNING;
|
||||||
|
|
||||||
|
return { ...state, tradeData };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.SET_TRADE_STATE: {
|
||||||
|
const tradeData = { ...state.tradeData };
|
||||||
|
|
||||||
|
tradeData.state = (action.payload.tradeState || TradeState.TRADING_STATE_RUNNING);
|
||||||
|
|
||||||
|
return { ...state, tradeData };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.SET_TRADE_ACCEPTANCE: {
|
||||||
|
const tradeData = { ...state.tradeData };
|
||||||
|
|
||||||
|
const userId = (action.payload.userId || -1);
|
||||||
|
|
||||||
|
if(tradeData.ownUser.userId === userId)
|
||||||
|
{
|
||||||
|
const ownUserData = Object.assign({}, tradeData.ownUser);
|
||||||
|
|
||||||
|
ownUserData.accepts = (action.payload.flag || false);
|
||||||
|
|
||||||
|
tradeData.ownUser = ownUserData;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(tradeData.otherUser.userId === userId)
|
||||||
|
{
|
||||||
|
const otherUserData = Object.assign({}, tradeData.otherUser);
|
||||||
|
|
||||||
|
otherUserData.accepts = (action.payload.flag || false);
|
||||||
|
|
||||||
|
tradeData.otherUser = otherUserData;
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...state, tradeData };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.CLOSE_TRADE: {
|
||||||
|
const tradeData = null;
|
||||||
|
|
||||||
|
return { ...state, tradeData };
|
||||||
|
}
|
||||||
|
case InventoryFurnitureActions.UPDATE_TRADE: {
|
||||||
|
const tradeData = { ...state.tradeData };
|
||||||
|
const groupItems = [ ...state.groupItems ];
|
||||||
|
|
||||||
|
const parser = (action.payload.tradeParser || null);
|
||||||
|
|
||||||
|
if(parser)
|
||||||
|
{
|
||||||
|
const firstUserItems: AdvancedMap<string, GroupItem> = new AdvancedMap();
|
||||||
|
const secondUserItems: AdvancedMap<string, GroupItem> = new AdvancedMap();
|
||||||
|
|
||||||
|
parseTradeItems(parser.firstUserItemArray, firstUserItems);
|
||||||
|
parseTradeItems(parser.secondUserItemArray, secondUserItems);
|
||||||
|
|
||||||
|
const ownUserData = Object.assign({}, tradeData.ownUser);
|
||||||
|
const otherUserData = Object.assign({}, tradeData.otherUser);
|
||||||
|
|
||||||
|
if(tradeData.ownUser.userId === parser.firstUserID)
|
||||||
|
{
|
||||||
|
ownUserData.creditsCount = parser.firstUserNumCredits;
|
||||||
|
ownUserData.itemCount = parser.firstUserNumItems;
|
||||||
|
ownUserData.items = firstUserItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(tradeData.ownUser.userId === parser.secondUserID)
|
||||||
|
{
|
||||||
|
ownUserData.creditsCount = parser.secondUserNumCredits;
|
||||||
|
ownUserData.itemCount = parser.secondUserNumItems;
|
||||||
|
ownUserData.items = secondUserItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeData.otherUser.userId === parser.firstUserID)
|
||||||
|
{
|
||||||
|
otherUserData.creditsCount = parser.firstUserNumCredits;
|
||||||
|
otherUserData.itemCount = parser.firstUserNumItems;
|
||||||
|
otherUserData.items = firstUserItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
else if(tradeData.otherUser.userId === parser.secondUserID)
|
||||||
|
{
|
||||||
|
otherUserData.creditsCount = parser.secondUserNumCredits;
|
||||||
|
otherUserData.itemCount = parser.secondUserNumItems;
|
||||||
|
otherUserData.items = secondUserItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
tradeData.ownUser = ownUserData;
|
||||||
|
tradeData.otherUser = otherUserData;
|
||||||
|
|
||||||
|
const tradeIds: number[] = [];
|
||||||
|
|
||||||
|
for(const groupItem of ownUserData.items.getValues())
|
||||||
|
{
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
while(i < groupItem.getTotalCount())
|
||||||
|
{
|
||||||
|
const item = groupItem.getItemByIndex(i);
|
||||||
|
|
||||||
|
if(item) tradeIds.push(item.ref);
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const groupItem of groupItems) groupItem.lockItemIds(tradeIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
return { ...state, groupItems, tradeData };
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,2 @@
|
|||||||
@import './badge/InventoryBadgeView';
|
@import './badge/InventoryBadgeView';
|
||||||
@import './bot/InventoryBotView';
|
|
||||||
@import './furniture/InventoryFurnitureView';
|
@import './furniture/InventoryFurnitureView';
|
||||||
@import './pet/InventoryPetView';
|
|
||||||
|
@ -5,5 +5,9 @@
|
|||||||
height: 45px;
|
height: 45px;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.inventory-badge-overflow {
|
||||||
|
height: calc(100% - 91px);
|
||||||
|
}
|
||||||
|
|
||||||
@import './item/InventoryBadgeItemView';
|
@import './item/InventoryBadgeItemView';
|
||||||
@import './results/InventoryBadgeResultsView';
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
.badge-item-container {
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
|
||||||
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
||||||
import { InventoryActiveBadgeResultsViewProps } from './InventoryActiveBadgeResultsView.types';
|
import { InventoryActiveBadgeResultsViewProps } from './InventoryActiveBadgeResultsView.types';
|
||||||
|
|
||||||
@ -7,11 +8,11 @@ export const InventoryActiveBadgeResultsView: FC<InventoryActiveBadgeResultsView
|
|||||||
const { badges = [] } = props;
|
const { badges = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="row row-cols-3 align-content-start g-0">
|
<NitroCardGridView columns={ 3 }>
|
||||||
{ badges && (badges.length > 0) && badges.map(code =>
|
{ badges && (badges.length > 0) && badges.map(code =>
|
||||||
{
|
{
|
||||||
return <InventoryBadgeItemView key={ code } badge={ code } />
|
return <InventoryBadgeItemView key={ code } badge={ code } />
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</NitroCardGridView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback } from 'react';
|
import { FC, MouseEvent, useCallback } from 'react';
|
||||||
|
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||||
import { BadgeImageView } from '../../../../shared/badge-image/BadgeImageView';
|
import { BadgeImageView } from '../../../../shared/badge-image/BadgeImageView';
|
||||||
import { useInventoryContext } from '../../../context/InventoryContext';
|
import { useInventoryContext } from '../../../context/InventoryContext';
|
||||||
import { InventoryBadgeActions } from '../../../reducers/InventoryBadgeReducer';
|
import { InventoryBadgeActions } from '../../../reducers/InventoryBadgeReducer';
|
||||||
@ -24,10 +25,8 @@ export const InventoryBadgeItemView: FC<InventoryBadgeItemViewProps> = props =>
|
|||||||
}, [ badge, dispatchBadgeState ]);
|
}, [ badge, dispatchBadgeState ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pe-1 pb-1 inventory-badge-item-container">
|
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent }>
|
||||||
<div className={ 'position-relative border border-2 rounded inventory-badge-item cursor-pointer ' + (isActive ? 'active' : '') } onMouseDown={ onMouseEvent }>
|
<BadgeImageView badgeCode={ badge } />
|
||||||
<BadgeImageView badgeCode={ badge } />
|
</NitroCardGridItemView>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
.badge-item-container {
|
|
||||||
height: 139px;
|
|
||||||
max-height: 139px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inventory-badge-overflow {
|
|
||||||
height:calc(100% - 86px)
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
|
||||||
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
|
||||||
import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types';
|
import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types';
|
||||||
|
|
||||||
@ -7,15 +8,13 @@ export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = pro
|
|||||||
const { badges = [], activeBadges = [] } = props;
|
const { badges = [], activeBadges = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-100 overflow-hidden">
|
<NitroCardGridView>
|
||||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
|
||||||
{ badges && (badges.length > 0) && badges.map(code =>
|
{ badges && (badges.length > 0) && badges.map(code =>
|
||||||
{
|
{
|
||||||
if(activeBadges.indexOf(code) >= 0) return null;
|
if(activeBadges.indexOf(code) >= 0) return null;
|
||||||
|
|
||||||
return <InventoryBadgeItemView key={ code } badge={ code } />
|
return <InventoryBadgeItemView key={ code } badge={ code } />
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</NitroCardGridView>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
@import './item/InventoryBotItemView';
|
|
||||||
@import './results/InventoryBotResultsView';
|
|
@ -1,25 +0,0 @@
|
|||||||
.inventory-bot-item-container {
|
|
||||||
height: 48px;
|
|
||||||
max-height: 48px;
|
|
||||||
|
|
||||||
.inventory-bot-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-color: $grid-border-color !important;
|
|
||||||
background-color: $grid-bg-color;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
border-color: $grid-active-border-color !important;
|
|
||||||
background-color: $grid-active-bg-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
.avatar-image {
|
|
||||||
width: 100% !important;
|
|
||||||
height: 100% !important;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position-y: -32px !important;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useState } from 'react';
|
||||||
|
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||||
import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView';
|
import { AvatarImageView } from '../../../../shared/avatar-image/AvatarImageView';
|
||||||
import { attemptBotPlacement } from '../../../common/BotUtilities';
|
import { attemptBotPlacement } from '../../../common/BotUtilities';
|
||||||
import { useInventoryContext } from '../../../context/InventoryContext';
|
import { useInventoryContext } from '../../../context/InventoryContext';
|
||||||
@ -37,10 +38,8 @@ export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props =>
|
|||||||
}, [ isActive, isMouseDown, botItem, dispatchBotState ]);
|
}, [ isActive, isMouseDown, botItem, dispatchBotState ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pe-1 pb-1 inventory-bot-item-container">
|
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||||
<div className={ 'position-relative border border-2 rounded inventory-bot-item cursor-pointer ' + (isActive ? 'active' : '') } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
<AvatarImageView figure={ botItem.botData.figure } direction={ 3 } headOnly={ true } />
|
||||||
<AvatarImageView figure={ botItem.botData.figure } direction={ 3 } headOnly={ true } />
|
</NitroCardGridItemView>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
.bot-item-container {
|
|
||||||
height: 220px;
|
|
||||||
max-height: 220px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
|
||||||
import { InventoryBotItemView } from '../item/InventoryBotItemView';
|
import { InventoryBotItemView } from '../item/InventoryBotItemView';
|
||||||
import { InventoryBotResultsViewProps } from './InventoryBotResultsView.types';
|
import { InventoryBotResultsViewProps } from './InventoryBotResultsView.types';
|
||||||
|
|
||||||
@ -7,13 +8,11 @@ export const InventoryBotResultsView: FC<InventoryBotResultsViewProps> = props =
|
|||||||
const { botItems = [] } = props;
|
const { botItems = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-100 overflow-hidden">
|
<NitroCardGridView>
|
||||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
|
||||||
{ botItems && (botItems.length > 0) && botItems.map(item =>
|
{ botItems && (botItems.length > 0) && botItems.map(item =>
|
||||||
{
|
{
|
||||||
return <InventoryBotItemView key={ item.id } botItem={ item } />
|
return <InventoryBotItemView key={ item.id } botItem={ item } />
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</NitroCardGridView>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,3 @@
|
|||||||
top: 5px;
|
top: 5px;
|
||||||
right: 15px;
|
right: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './item/InventoryFurnitureItemView';
|
|
||||||
@import './results/InventoryFurnitureResultsView';
|
|
||||||
@import './search/InventoryFurnitureSearchView';
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { FurnitureListComposer, RoomObjectVariable, Vector3d } from 'nitro-renderer';
|
import { FurnitureListComposer, RoomObjectVariable, Vector3d } from 'nitro-renderer';
|
||||||
import { FC, useEffect, useState } from 'react';
|
import { FC, useEffect, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../../../api';
|
import { GetRoomEngine, GetSessionDataManager } from '../../../../api';
|
||||||
import { SendMessageHook } from '../../../../hooks/messages/message-event';
|
import { SendMessageHook } from '../../../../hooks/messages';
|
||||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
import { LimitedEditionCompactPlateView } from '../../../shared/limited-edition/compact-plate/LimitedEditionCompactPlateView';
|
import { LimitedEditionCompactPlateView } from '../../../shared/limited-edition/compact-plate/LimitedEditionCompactPlateView';
|
||||||
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
|
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
|
||||||
@ -80,9 +80,9 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
|
|
||||||
if(furnitureItem.category === FurniCategory._Str_3432)
|
if(furnitureItem.category === FurniCategory._Str_3432)
|
||||||
{
|
{
|
||||||
// insert a window if the type is landscape
|
const data = GetSessionDataManager().getWallItemDataByName('noob_window_double');
|
||||||
//_local_19 = this._model.controller._Str_18225("ads_twi_windw", ProductTypeEnum.WALL);
|
|
||||||
//this._roomPreviewer._Str_12087(_local_19.id, new Vector3d(90, 0, 0), _local_19._Str_4558);
|
if(data) roomPreviewer.addWallItemIntoRoom(data.id, new Vector3d(90, 0, 0), data.customParams);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -123,14 +123,16 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
|||||||
</div>
|
</div>
|
||||||
<div className="position-relative d-flex flex-column col-5 justify-space-between">
|
<div className="position-relative d-flex flex-column col-5 justify-space-between">
|
||||||
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
|
||||||
{ groupItem && groupItem.stuffData.isUnique &&
|
{ groupItem &&groupItem.stuffData.isUnique &&
|
||||||
<div className="position-absolute limited-edition-info-container">
|
<div className="position-absolute limited-edition-info-container">
|
||||||
<LimitedEditionCompactPlateView uniqueNumber={ groupItem.stuffData.uniqueNumber } uniqueSeries={ groupItem.stuffData.uniqueSeries } />
|
<LimitedEditionCompactPlateView uniqueNumber={ groupItem.stuffData.uniqueNumber } uniqueSeries={ groupItem.stuffData.uniqueSeries } />
|
||||||
</div> }
|
</div> }
|
||||||
{ groupItem && <div className="d-flex flex-column flex-grow-1">
|
{ groupItem &&
|
||||||
<p className="flex-grow-1 fs-6 text-black my-2">{ groupItem.name }</p>
|
<div className="d-flex flex-column flex-grow-1">
|
||||||
{ !!roomSession && <button type="button" className="btn btn-success btn-sm" onClick={ event => attemptItemPlacement(groupItem) }>{ LocalizeText('inventory.furni.placetoroom') }</button> }
|
<p className="flex-grow-1 fs-6 text-black my-2">{ groupItem.name }</p>
|
||||||
</div> }
|
{ !!roomSession &&
|
||||||
|
<button type="button" className="btn btn-success btn-sm" onClick={ event => attemptItemPlacement(groupItem) }>{ LocalizeText('inventory.furni.placetoroom') }</button> }
|
||||||
|
</div> }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,25 +0,0 @@
|
|||||||
.inventory-furniture-item-container {
|
|
||||||
height: 48px;
|
|
||||||
max-height: 48px;
|
|
||||||
|
|
||||||
.inventory-furniture-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-color: $grid-border-color !important;
|
|
||||||
background-color: $grid-bg-color !important;
|
|
||||||
background-position: center;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
border-color: $grid-active-border-color !important;
|
|
||||||
background-color: $grid-active-bg-color !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.badge {
|
|
||||||
top: 2px;
|
|
||||||
right: 2px;
|
|
||||||
font-size: 8px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,6 +1,6 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useState } from 'react';
|
||||||
import { LimitedEditionStyledNumberView } from '../../../../shared/limited-edition/styled-number/LimitedEditionStyledNumberView';
|
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||||
import { attemptItemPlacement } from '../../../common/FurnitureUtilities';
|
import { attemptItemPlacement } from '../../../common/FurnitureUtilities';
|
||||||
import { useInventoryContext } from '../../../context/InventoryContext';
|
import { useInventoryContext } from '../../../context/InventoryContext';
|
||||||
import { InventoryFurnitureActions } from '../../../reducers/InventoryFurnitureReducer';
|
import { InventoryFurnitureActions } from '../../../reducers/InventoryFurnitureReducer';
|
||||||
@ -10,6 +10,7 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
|
|||||||
{
|
{
|
||||||
const { groupItem } = props;
|
const { groupItem } = props;
|
||||||
const { furnitureState, dispatchFurnitureState } = useInventoryContext();
|
const { furnitureState, dispatchFurnitureState } = useInventoryContext();
|
||||||
|
const { tradeData = null } = furnitureState;
|
||||||
const [ isMouseDown, setMouseDown ] = useState(false);
|
const [ isMouseDown, setMouseDown ] = useState(false);
|
||||||
const isActive = (furnitureState.groupItem === groupItem);
|
const isActive = (furnitureState.groupItem === groupItem);
|
||||||
|
|
||||||
@ -36,18 +37,7 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
|
|||||||
}
|
}
|
||||||
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
|
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
|
||||||
|
|
||||||
const imageUrl = `url(${ groupItem.iconUrl })`;
|
const count = groupItem.getUnlockedCount();
|
||||||
|
|
||||||
return (
|
return <NitroCardGridItemView className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUnique={ groupItem.stuffData.isUnique } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
|
||||||
<div className="col pe-1 pb-1 inventory-furniture-item-container">
|
|
||||||
<div className={ 'position-relative border border-2 rounded inventory-furniture-item cursor-pointer ' + (isActive ? 'active ' : '') + (groupItem.stuffData.isUnique ? 'unique-item ' : '') } style={ { backgroundImage: imageUrl }} onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
|
||||||
{groupItem.getUnlockedCount() > 1 &&
|
|
||||||
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{groupItem.getUnlockedCount()}</span> }
|
|
||||||
{ groupItem.stuffData.isUnique &&
|
|
||||||
<div className="position-absolute unique-item-counter">
|
|
||||||
<LimitedEditionStyledNumberView value={ groupItem.stuffData.uniqueNumber } />
|
|
||||||
</div> }
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
.furni-item-container {
|
|
||||||
}
|
|
@ -1,19 +1,18 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
|
||||||
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
|
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
|
||||||
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
|
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
|
||||||
|
|
||||||
export const InventoryFurnitureResultsView: FC<InventoryFurnitureResultsViewProps> = props =>
|
export const InventoryFurnitureResultsView: FC<InventoryFurnitureResultsViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { groupItems = [] } = props;
|
const { groupItems = [], columns = 5 } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-100 overflow-hidden">
|
<NitroCardGridView columns={ columns }>
|
||||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
|
||||||
{ 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 } />
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</NitroCardGridView>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,4 +3,5 @@ import { GroupItem } from '../../../common/GroupItem';
|
|||||||
export interface InventoryFurnitureResultsViewProps
|
export interface InventoryFurnitureResultsViewProps
|
||||||
{
|
{
|
||||||
groupItems: GroupItem[];
|
groupItems: GroupItem[];
|
||||||
|
columns?: number;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps>
|
|||||||
{
|
{
|
||||||
const comparison = searchValue.toLocaleLowerCase();
|
const comparison = searchValue.toLocaleLowerCase();
|
||||||
|
|
||||||
filteredGroupItems = filteredGroupItems.filter(item =>
|
filteredGroupItems = groupItems.filter(item =>
|
||||||
{
|
{
|
||||||
if(comparison && comparison.length)
|
if(comparison && comparison.length)
|
||||||
{
|
{
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
@import './item/InventoryPetItemView';
|
|
||||||
@import './results/InventoryPetResultsView';
|
|
@ -1,17 +0,0 @@
|
|||||||
.inventory-pet-item-container {
|
|
||||||
height: 48px;
|
|
||||||
max-height: 48px;
|
|
||||||
|
|
||||||
.inventory-pet-item {
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
border-color: $grid-border-color !important;
|
|
||||||
background-color: $grid-bg-color;
|
|
||||||
overflow: hidden;
|
|
||||||
|
|
||||||
&.active {
|
|
||||||
border-color: $grid-active-border-color!important;
|
|
||||||
background-color: $grid-active-bg-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,5 +1,6 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useState } from 'react';
|
||||||
|
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||||
import { PetImageView } from '../../../../shared/pet-image/PetImageView';
|
import { PetImageView } from '../../../../shared/pet-image/PetImageView';
|
||||||
import { attemptPetPlacement } from '../../../common/PetUtilities';
|
import { attemptPetPlacement } from '../../../common/PetUtilities';
|
||||||
import { useInventoryContext } from '../../../context/InventoryContext';
|
import { useInventoryContext } from '../../../context/InventoryContext';
|
||||||
@ -37,10 +38,8 @@ export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
|
|||||||
}, [ isActive, isMouseDown, petItem, dispatchPetState ]);
|
}, [ isActive, isMouseDown, petItem, dispatchPetState ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pe-1 pb-1 inventory-pet-item-container">
|
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||||
<div className={ 'position-relative border border-2 rounded inventory-pet-item cursor-pointer ' + (isActive ? 'active' : '') } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
<PetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
|
||||||
<PetImageView figure={ petItem.petData.figureData.figuredata } direction={ 3 } headOnly={ true } />
|
</NitroCardGridItemView>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +0,0 @@
|
|||||||
.pet-item-container {
|
|
||||||
height: 220px;
|
|
||||||
max-height: 220px;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
@ -1,4 +1,5 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
|
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
|
||||||
import { InventoryPetItemView } from '../item/InventoryPetItemView';
|
import { InventoryPetItemView } from '../item/InventoryPetItemView';
|
||||||
import { InventoryPetResultsViewProps } from './InventoryPetResultsView.types';
|
import { InventoryPetResultsViewProps } from './InventoryPetResultsView.types';
|
||||||
|
|
||||||
@ -7,13 +8,11 @@ export const InventoryPetResultsView: FC<InventoryPetResultsViewProps> = props =
|
|||||||
const { petItems = [] } = props;
|
const { petItems = [] } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="h-100 overflow-hidden">
|
<NitroCardGridView>
|
||||||
<div className="row row-cols-5 align-content-start g-0 w-100 h-100 overflow-auto">
|
|
||||||
{ petItems && (petItems.length > 0) && petItems.map(item =>
|
{ petItems && (petItems.length > 0) && petItems.map(item =>
|
||||||
{
|
{
|
||||||
return <InventoryPetItemView key={ item.id } petItem={ item } />
|
return <InventoryPetItemView key={ item.id } petItem={ item } />
|
||||||
}) }
|
}) }
|
||||||
</div>
|
</NitroCardGridView>
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
290
src/views/inventory/views/trade/InventoryTradeView.tsx
Normal file
290
src/views/inventory/views/trade/InventoryTradeView.tsx
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
import { FurnitureListComposer, IObjectData, TradingAcceptComposer, TradingConfirmationComposer, TradingListAddItemComposer, TradingListAddItemsComposer, TradingListItemRemoveComposer, TradingUnacceptComposer } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { SendMessageHook } from '../../../../hooks/messages';
|
||||||
|
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
|
||||||
|
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
|
||||||
|
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||||
|
import { FurniCategory } from '../../common/FurniCategory';
|
||||||
|
import { GroupItem } from '../../common/GroupItem';
|
||||||
|
import { IFurnitureItem } from '../../common/IFurnitureItem';
|
||||||
|
import { TradeState } from '../../common/TradeState';
|
||||||
|
import { _Str_16998 } from '../../common/TradingUtilities';
|
||||||
|
import { useInventoryContext } from '../../context/InventoryContext';
|
||||||
|
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
|
||||||
|
import { InventoryFurnitureSearchView } from '../furniture/search/InventoryFurnitureSearchView';
|
||||||
|
import { InventoryTradeViewProps } from './InventoryTradeView.types';
|
||||||
|
|
||||||
|
const MAX_ITEMS_TO_TRADE: number = 9;
|
||||||
|
|
||||||
|
export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
|
||||||
|
{
|
||||||
|
const { cancelTrade = null } = props;
|
||||||
|
const [ groupItem, setGroupItem ] = useState<GroupItem>(null);
|
||||||
|
const [ ownGroupItem, setOwnGroupItem ] = useState<GroupItem>(null);
|
||||||
|
const [ otherGroupItem, setOtherGroupItem ] = useState<GroupItem>(null);
|
||||||
|
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>(null);
|
||||||
|
const [ countdownTick, setCountdownTick ] = useState(3);
|
||||||
|
const { furnitureState = null, dispatchFurnitureState = null } = useInventoryContext();
|
||||||
|
const { needsFurniUpdate = false, groupItems = [], tradeData = null } = furnitureState;
|
||||||
|
|
||||||
|
const canTradeItem = useCallback((isWallItem: boolean, spriteId: number, category: number, groupable: boolean, stuffData: IObjectData) =>
|
||||||
|
{
|
||||||
|
if(!tradeData || !tradeData.ownUser || tradeData.ownUser.accepts || !tradeData.ownUser.items) return false;
|
||||||
|
|
||||||
|
if(tradeData.ownUser.items.length < MAX_ITEMS_TO_TRADE) return true;
|
||||||
|
|
||||||
|
if(!groupable) return false;
|
||||||
|
|
||||||
|
let type = spriteId.toString();
|
||||||
|
|
||||||
|
if(category === FurniCategory._Str_5186)
|
||||||
|
{
|
||||||
|
type = ((type + 'poster') + stuffData.getLegacyString());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(category === FurniCategory._Str_12454)
|
||||||
|
{
|
||||||
|
type = _Str_16998(spriteId, stuffData);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
type = (((isWallItem) ? 'I' : 'S') + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!tradeData.ownUser.items.getValue(type);
|
||||||
|
}, [ tradeData ]);
|
||||||
|
|
||||||
|
const attemptItemOffer = useCallback((count: number) =>
|
||||||
|
{
|
||||||
|
if(!tradeData || !groupItem) return;
|
||||||
|
|
||||||
|
const tradeItems = groupItem.getTradeItems(count);
|
||||||
|
|
||||||
|
if(!tradeItems || !tradeItems.length) return;
|
||||||
|
|
||||||
|
let coreItem: IFurnitureItem = null;
|
||||||
|
const itemIds: number[] = [];
|
||||||
|
|
||||||
|
for(const item of tradeItems)
|
||||||
|
{
|
||||||
|
itemIds.push(item.id);
|
||||||
|
|
||||||
|
if(!coreItem) coreItem = item;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ownItemCount = tradeData.ownUser.items.length;
|
||||||
|
|
||||||
|
if((ownItemCount + itemIds.length) <= 1500)
|
||||||
|
{
|
||||||
|
if(!coreItem.isGroupable && (itemIds.length))
|
||||||
|
{
|
||||||
|
SendMessageHook(new TradingListAddItemComposer(itemIds.pop()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const tradeIds: number[] = [];
|
||||||
|
|
||||||
|
for(const itemId of itemIds)
|
||||||
|
{
|
||||||
|
if(canTradeItem(coreItem.isWallItem, coreItem.type, coreItem.category, coreItem.isGroupable, coreItem.stuffData))
|
||||||
|
{
|
||||||
|
tradeIds.push(itemId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeIds.length)
|
||||||
|
{
|
||||||
|
if(tradeIds.length === 1)
|
||||||
|
{
|
||||||
|
SendMessageHook(new TradingListAddItemComposer(tradeIds.pop()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessageHook(new TradingListAddItemsComposer(...tradeIds));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//this._notificationService.alert('${trading.items.too_many_items.desc}', '${trading.items.too_many_items.title}');
|
||||||
|
}
|
||||||
|
}, [ groupItem, tradeData, canTradeItem ]);
|
||||||
|
|
||||||
|
const removeItem = useCallback((group: GroupItem) =>
|
||||||
|
{
|
||||||
|
const item = group.getLastItem();
|
||||||
|
|
||||||
|
if(!item) return;
|
||||||
|
|
||||||
|
SendMessageHook(new TradingListItemRemoveComposer(item.id));
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(needsFurniUpdate)
|
||||||
|
{
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_NEEDS_UPDATE,
|
||||||
|
payload: {
|
||||||
|
flag: false
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
SendMessageHook(new FurnitureListComposer());
|
||||||
|
}
|
||||||
|
|
||||||
|
}, [ needsFurniUpdate, groupItems, dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const progressTrade = useCallback(() =>
|
||||||
|
{
|
||||||
|
switch(tradeData.state)
|
||||||
|
{
|
||||||
|
case TradeState.TRADING_STATE_RUNNING:
|
||||||
|
if(!tradeData.otherUser.itemCount && !tradeData.ownUser.accepts)
|
||||||
|
{
|
||||||
|
//this._notificationService.alert('${inventory.trading.warning.other_not_offering}');
|
||||||
|
}
|
||||||
|
|
||||||
|
if(tradeData.ownUser.accepts)
|
||||||
|
{
|
||||||
|
SendMessageHook(new TradingUnacceptComposer());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SendMessageHook(new TradingAcceptComposer());
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case TradeState.TRADING_STATE_CONFIRMING:
|
||||||
|
SendMessageHook(new TradingConfirmationComposer());
|
||||||
|
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_TRADE_STATE,
|
||||||
|
payload: {
|
||||||
|
tradeState: TradeState.TRADING_STATE_CONFIRMED
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ tradeData, dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
const getTradeButton = useMemo(() =>
|
||||||
|
{
|
||||||
|
if(!tradeData) return null;
|
||||||
|
|
||||||
|
switch(tradeData.state)
|
||||||
|
{
|
||||||
|
case TradeState.TRADING_STATE_READY:
|
||||||
|
return <button type="button" className="btn btn-secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText('inventory.trading.accept') }</button>;
|
||||||
|
case TradeState.TRADING_STATE_RUNNING:
|
||||||
|
return <button type="button" className="btn btn-secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText(tradeData.ownUser.accepts ? 'inventory.trading.modify' : 'inventory.trading.accept') }</button>;
|
||||||
|
case TradeState.TRADING_STATE_COUNTDOWN:
|
||||||
|
return <button type="button" className="btn btn-secondary" disabled>{ LocalizeText('inventory.trading.countdown', [ 'counter' ], [ countdownTick.toString() ]) }</button>;
|
||||||
|
case TradeState.TRADING_STATE_CONFIRMING:
|
||||||
|
return <button type="button" className="btn btn-secondary" onClick={ progressTrade }>{ LocalizeText('inventory.trading.button.restore') }</button>;
|
||||||
|
case TradeState.TRADING_STATE_CONFIRMED:
|
||||||
|
return <button type="button" className="btn btn-secondary">{ LocalizeText('inventory.trading.info.waiting') }</button>;
|
||||||
|
}
|
||||||
|
}, [ tradeData, countdownTick, progressTrade ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!tradeData || (tradeData.state !== TradeState.TRADING_STATE_COUNTDOWN)) return;
|
||||||
|
|
||||||
|
setCountdownTick(3);
|
||||||
|
|
||||||
|
const interval = setInterval(() =>
|
||||||
|
{
|
||||||
|
setCountdownTick(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = (prevValue - 1);
|
||||||
|
|
||||||
|
if(newValue === -1)
|
||||||
|
{
|
||||||
|
dispatchFurnitureState({
|
||||||
|
type: InventoryFurnitureActions.SET_TRADE_STATE,
|
||||||
|
payload: {
|
||||||
|
tradeState: TradeState.TRADING_STATE_CONFIRMING
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
return () =>
|
||||||
|
{
|
||||||
|
clearInterval(interval);
|
||||||
|
}
|
||||||
|
}, [ tradeData, dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="row h-100">
|
||||||
|
<div className="d-flex flex-column col-4 h-100">
|
||||||
|
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
|
||||||
|
<NitroCardGridView columns={ 3 }>
|
||||||
|
{ filteredGroupItems && (filteredGroupItems.length > 0) && filteredGroupItems.map((item, index) =>
|
||||||
|
{
|
||||||
|
const count = item.getUnlockedCount();
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardGridItemView key={ index } className={ !count ? 'opacity-0-5 ' : '' } itemImage={ item.iconUrl } itemCount={ count } itemActive={ (groupItem === item) } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => (count && setGroupItem(item)) }>
|
||||||
|
{ ((count > 0) && (groupItem === item)) &&
|
||||||
|
<button className="btn btn-success btn-sm trade-button" onClick={ event => attemptItemOffer(1) }>
|
||||||
|
<i className="fas fa-chevron-right" />
|
||||||
|
</button> }
|
||||||
|
</NitroCardGridItemView>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
</NitroCardGridView>
|
||||||
|
<div className="col-12 badge bg-muted w-100 mt-1">{ groupItem ? groupItem.name : LocalizeText('catalog_selectproduct') }</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-8 row">
|
||||||
|
<div className="d-flex flex-column col-6">
|
||||||
|
<span className="d-flex justify-content-between align-items-center text-black small mb-1">{ LocalizeText('inventory.trading.you') } { LocalizeText('inventory.trading.areoffering') }: <i className={ 'small fas ' + (tradeData.ownUser.accepts ? 'fa-lock text-success' : 'fa-unlock text-danger') } /></span>
|
||||||
|
<NitroCardGridView columns={ 3 }>
|
||||||
|
{ Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) =>
|
||||||
|
{
|
||||||
|
const item = (tradeData.ownUser.items.getWithIndex(i) || null);
|
||||||
|
|
||||||
|
if(!item) return <NitroCardGridItemView key={ i } />;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardGridItemView key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }>
|
||||||
|
{ (ownGroupItem === item) &&
|
||||||
|
<button className="btn btn-danger btn-sm trade-button left" onClick={ event => removeItem(item) }>
|
||||||
|
<i className="fas fa-chevron-left" />
|
||||||
|
</button> }
|
||||||
|
</NitroCardGridItemView>
|
||||||
|
);
|
||||||
|
}) }
|
||||||
|
<div className="col-12 badge bg-muted w-100">{ ownGroupItem ? ownGroupItem.name : LocalizeText('catalog_selectproduct') }</div>
|
||||||
|
</NitroCardGridView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex flex-column col-6">
|
||||||
|
<span className="d-flex justify-content-between align-items-center text-black small mb-1">{ tradeData.otherUser.userName } { LocalizeText('inventory.trading.isoffering') }: <i className={ 'small fas ' + (tradeData.otherUser.accepts ? 'fa-lock text-success' : 'fa-unlock text-danger') } /></span>
|
||||||
|
<NitroCardGridView columns={ 3 }>
|
||||||
|
{ Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) =>
|
||||||
|
{
|
||||||
|
const item = (tradeData.otherUser.items.getWithIndex(i) || null);
|
||||||
|
|
||||||
|
if(!item) return <NitroCardGridItemView key={ i } />;
|
||||||
|
|
||||||
|
return <NitroCardGridItemView key={ i } itemActive={ (otherGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUnique={ item.stuffData.isUnique } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOtherGroupItem(item) } />;
|
||||||
|
}) }
|
||||||
|
<div className="col-12 badge bg-muted w-100">{ otherGroupItem ? otherGroupItem.name : LocalizeText('catalog_selectproduct') }</div>
|
||||||
|
</NitroCardGridView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex col-12 justify-content-between align-items-end w-100">
|
||||||
|
<button type="button" className="btn btn-danger" onClick={ cancelTrade }>{ LocalizeText('generic.cancel') }</button>
|
||||||
|
{ getTradeButton }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -0,0 +1,4 @@
|
|||||||
|
export interface InventoryTradeViewProps
|
||||||
|
{
|
||||||
|
cancelTrade: () => void;
|
||||||
|
}
|
@ -37,11 +37,11 @@ export const PurseView: FC<PurseViewProps> = props =>
|
|||||||
<PurseContextProvider value={ { purseState, dispatchPurseState }}>
|
<PurseContextProvider value={ { purseState, dispatchPurseState }}>
|
||||||
<PurseMessageHandler />
|
<PurseMessageHandler />
|
||||||
<div className="nitro-purse rounded d-flex flex-row py-1 justify-content-between">
|
<div className="nitro-purse rounded d-flex flex-row py-1 justify-content-between">
|
||||||
{ currencies && currencies.map((currency, index) =>
|
{ currencies && currencies.map(currency =>
|
||||||
{
|
{
|
||||||
if(displayedCurrencies.indexOf(currency.type) === -1) return null;
|
if(displayedCurrencies.indexOf(currency.type) === -1) return null;
|
||||||
|
|
||||||
return <CurrencyView key={ index } currency={ currency } />;
|
return <CurrencyView key={ currency.type } currency={ currency } />;
|
||||||
}) }
|
}) }
|
||||||
<div className="notification-button px-2" onClick={ toggleNotificationCenter }>
|
<div className="notification-button px-2" onClick={ toggleNotificationCenter }>
|
||||||
<i className="fas fa-bars" />
|
<i className="fas fa-bars" />
|
||||||
|
@ -10,9 +10,9 @@ export class RoomWidgetObjectNameEvent extends RoomWidgetUpdateEvent
|
|||||||
private _name: string;
|
private _name: string;
|
||||||
private _userType: number;
|
private _userType: number;
|
||||||
|
|
||||||
constructor(roomIndex: number, category: number, id: number, name: string, userType: number)
|
constructor(type: string, roomIndex: number, category: number, id: number, name: string, userType: number)
|
||||||
{
|
{
|
||||||
super(RoomWidgetObjectNameEvent.TYPE);
|
super(type);
|
||||||
|
|
||||||
this._roomIndex = roomIndex;
|
this._roomIndex = roomIndex;
|
||||||
this._category = category;
|
this._category = category;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { IFurnitureData, Nitro, NitroEvent, ObjectDataFactory, PetFigureData, PetType, RoomAdsUpdateComposer, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnumItemExtradataParameter, SecurityLevel, Vector3d } from 'nitro-renderer';
|
import { IFurnitureData, Nitro, NitroEvent, ObjectDataFactory, PetFigureData, PetType, RoomAdsUpdateComposer, RoomControllerLevel, RoomModerationSettings, RoomObjectCategory, RoomObjectOperationType, RoomObjectType, RoomObjectVariable, RoomSessionPetInfoUpdateEvent, RoomSessionUserBadgesEvent, RoomTradingLevelEnum, RoomUnitDropHandItemComposer, RoomUnitGiveHandItemComposer, RoomUnitGiveHandItemPetComposer, RoomUserData, RoomWidgetEnumItemExtradataParameter, SecurityLevel, Vector3d } from 'nitro-renderer';
|
||||||
import { GetConnection, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api';
|
import { GetConnection, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture } from '../../../api';
|
||||||
import { WiredSelectObjectEvent } from '../../../events';
|
import { InventoryTradeRequestEvent, WiredSelectObjectEvent } from '../../../events';
|
||||||
import { dispatchUiEvent } from '../../../hooks/events';
|
import { dispatchUiEvent } from '../../../hooks/events';
|
||||||
import { LocalizeText } from '../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../utils/LocalizeText';
|
||||||
import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events';
|
import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events';
|
||||||
@ -114,7 +114,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
|||||||
this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||||
break;
|
break;
|
||||||
case RoomWidgetUserActionMessage.START_TRADING:
|
case RoomWidgetUserActionMessage.START_TRADING:
|
||||||
//if(userData) this._widget.inventoryTrading.startTrade(userData.roomIndex, userData.name);
|
dispatchUiEvent(new InventoryTradeRequestEvent(userData.roomIndex, userData.name));
|
||||||
break;
|
break;
|
||||||
// case RoomWidgetUserActionMessage.RWUAM_OPEN_HOME_PAGE:
|
// case RoomWidgetUserActionMessage.RWUAM_OPEN_HOME_PAGE:
|
||||||
// this._container.sessionDataManager._Str_21275((message as RoomWidgetUserActionMessage).userId, _local_3.name);
|
// this._container.sessionDataManager._Str_21275((message as RoomWidgetUserActionMessage).userId, _local_3.name);
|
||||||
@ -286,7 +286,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(name) this.container.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(message.id, message.category, id, name, userType));
|
if(name) this.container.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(RoomWidgetObjectNameEvent.TYPE, message.id, message.category, id, name, userType));
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { RoomEnterEffect, RoomObjectCategory } from 'nitro-renderer';
|
import { RoomEnterEffect, RoomObjectCategory } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useMemo, useState } from 'react';
|
import { FC, useCallback, useMemo, useState } from 'react';
|
||||||
import { GetRoomSession, GetSessionDataManager } from '../../../../api';
|
import { GetRoomSession, GetSessionDataManager } from '../../../../api';
|
||||||
|
import { FriendEnteredRoomEvent } from '../../../../events';
|
||||||
|
import { useUiEvent } from '../../../../hooks/events';
|
||||||
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events';
|
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events';
|
||||||
@ -19,12 +21,35 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
{
|
{
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||||
const [ name, setName ] = useState<RoomWidgetObjectNameEvent>(null);
|
const [ name, setName ] = useState<RoomWidgetObjectNameEvent>(null);
|
||||||
|
const [ nameBubbles, setNameBubbles ] = useState<RoomWidgetObjectNameEvent[]>([]);
|
||||||
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
|
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
|
||||||
const [ isGameMode, setGameMode ] = useState(false);
|
const [ isGameMode, setGameMode ] = useState(false);
|
||||||
const [ isDancing, setIsDancing ] = useState(false);
|
const [ isDancing, setIsDancing ] = useState(false);
|
||||||
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
|
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
|
||||||
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
|
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
|
||||||
|
|
||||||
|
const removeNameBubble = useCallback((index: number) =>
|
||||||
|
{
|
||||||
|
setNameBubbles(prevValue =>
|
||||||
|
{
|
||||||
|
const newValue = [ ...prevValue ];
|
||||||
|
|
||||||
|
newValue.splice(index, 1);
|
||||||
|
|
||||||
|
return newValue;
|
||||||
|
});
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const clearInfoStandEvent = useCallback(() =>
|
||||||
|
{
|
||||||
|
setInfoStandEvent(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const clearName = useCallback(() =>
|
||||||
|
{
|
||||||
|
setName(null);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
|
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
@ -50,6 +75,16 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
if(event.id === name.id) setName(null);
|
if(event.id === name.id) setName(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(event.category === RoomObjectCategory.UNIT)
|
||||||
|
{
|
||||||
|
const nameBubbleIndex = nameBubbles.findIndex(bubble =>
|
||||||
|
{
|
||||||
|
return (bubble.roomIndex === event.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
|
||||||
|
}
|
||||||
|
|
||||||
if(infoStandEvent)
|
if(infoStandEvent)
|
||||||
{
|
{
|
||||||
if(infoStandEvent instanceof RoomWidgetUpdateInfostandFurniEvent)
|
if(infoStandEvent instanceof RoomWidgetUpdateInfostandFurniEvent)
|
||||||
@ -67,7 +102,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
|
if(infoStandEvent.roomIndex === event.id) setInfoStandEvent(null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [ name, infoStandEvent ]);
|
}, [ name, infoStandEvent, nameBubbles, removeNameBubble ]);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomObjectRemoved);
|
||||||
@ -104,8 +139,6 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
{
|
{
|
||||||
if(!infoStandEvent) return;
|
if(!infoStandEvent) return;
|
||||||
|
|
||||||
console.log('tru')
|
|
||||||
|
|
||||||
setInfoStandEvent(null);
|
setInfoStandEvent(null);
|
||||||
}, [ infoStandEvent ]);
|
}, [ infoStandEvent ]);
|
||||||
|
|
||||||
@ -142,26 +175,6 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateDanceStatusEvent.UPDATE_DANCE, eventDispatcher, onRoomWidgetUpdateDanceStatusEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateDanceStatusEvent.UPDATE_DANCE, eventDispatcher, onRoomWidgetUpdateDanceStatusEvent);
|
||||||
|
|
||||||
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
|
|
||||||
{
|
|
||||||
switch(event.type)
|
|
||||||
{
|
|
||||||
case RoomWidgetRoomObjectUpdateEvent.USER_ADDED: {
|
|
||||||
// bubble if friend
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
case RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED: {
|
|
||||||
// set if waiting for pet
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
|
||||||
|
|
||||||
const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) =>
|
const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) =>
|
||||||
{
|
{
|
||||||
setRentableBotChatEvent(event);
|
setRentableBotChatEvent(event);
|
||||||
@ -169,6 +182,16 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
|
||||||
|
|
||||||
|
const onFriendEnteredRoomEvent = useCallback((event: FriendEnteredRoomEvent) =>
|
||||||
|
{
|
||||||
|
setNameBubbles(prevValue =>
|
||||||
|
{
|
||||||
|
return [ ...prevValue, event ];
|
||||||
|
})
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(FriendEnteredRoomEvent.ENTERED, onFriendEnteredRoomEvent);
|
||||||
|
|
||||||
const decorateView = useMemo(() =>
|
const decorateView = useMemo(() =>
|
||||||
{
|
{
|
||||||
GetRoomSession().isDecorating = isDecorating;
|
GetRoomSession().isDecorating = isDecorating;
|
||||||
@ -182,23 +205,23 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
return <AvatarInfoWidgetDecorateView userId={ userId } userName={ userName } roomIndex={ roomIndex } setIsDecorating={ setIsDecorating } />;
|
return <AvatarInfoWidgetDecorateView userId={ userId } userName={ userName } roomIndex={ roomIndex } setIsDecorating={ setIsDecorating } />;
|
||||||
}, [ isDecorating ]);
|
}, [ isDecorating ]);
|
||||||
|
|
||||||
const clearInfoStandEvent = useCallback(() =>
|
|
||||||
{
|
|
||||||
setInfoStandEvent(null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const clearName = useCallback(() =>
|
|
||||||
{
|
|
||||||
setName(null);
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const currentView = useMemo(() =>
|
const currentView = useMemo(() =>
|
||||||
{
|
{
|
||||||
if(isGameMode) return null;
|
if(isGameMode) return null;
|
||||||
|
|
||||||
if(decorateView) return decorateView;
|
if(decorateView) return decorateView;
|
||||||
|
|
||||||
if(name) return <AvatarInfoWidgetNameView nameData={ name } close={ clearName } />;
|
if(name)
|
||||||
|
{
|
||||||
|
const nameBubbleIndex = nameBubbles.findIndex(bubble =>
|
||||||
|
{
|
||||||
|
return (bubble.roomIndex === name.roomIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
|
||||||
|
|
||||||
|
return <AvatarInfoWidgetNameView nameData={ name } close={ clearName } />;
|
||||||
|
}
|
||||||
|
|
||||||
if(infoStandEvent)
|
if(infoStandEvent)
|
||||||
{
|
{
|
||||||
@ -210,7 +233,12 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
|
|
||||||
if(event.isSpectatorMode) return null;
|
if(event.isSpectatorMode) return null;
|
||||||
|
|
||||||
// if existing name bubble remove it
|
const nameBubbleIndex = nameBubbles.findIndex(bubble =>
|
||||||
|
{
|
||||||
|
return (bubble.roomIndex === event.roomIndex);
|
||||||
|
});
|
||||||
|
|
||||||
|
if(nameBubbleIndex > -1) removeNameBubble(nameBubbleIndex);
|
||||||
|
|
||||||
if(event.isOwnUser)
|
if(event.isOwnUser)
|
||||||
{
|
{
|
||||||
@ -241,11 +269,15 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, [ isGameMode, decorateView, name, isDancing, infoStandEvent, clearName, clearInfoStandEvent ]);
|
}, [ isGameMode, decorateView, name, nameBubbles, isDancing, infoStandEvent, clearName, clearInfoStandEvent, removeNameBubble ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{ currentView }
|
{ currentView }
|
||||||
|
{ (nameBubbles.length > 0) && nameBubbles.map((name, index) =>
|
||||||
|
{
|
||||||
|
return <AvatarInfoWidgetNameView key={ index } nameData={ name } close={ () => removeNameBubble(index) } />;
|
||||||
|
}) }
|
||||||
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
|
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
|
@ -97,13 +97,12 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
|||||||
</div>
|
</div>
|
||||||
<div className="chat-content">
|
<div className="chat-content">
|
||||||
<b className="username mr-1" dangerouslySetInnerHTML={ {__html: `${ chat.username }: ` } } />
|
<b className="username mr-1" dangerouslySetInnerHTML={ {__html: `${ chat.username }: ` } } />
|
||||||
{ chat.text }
|
<span className="message">{ chat.text }</span>
|
||||||
<span className="message"> {
|
{/* {
|
||||||
messageParts && messageParts.map((part, index) =>
|
messageParts && messageParts.map((part, index) =>
|
||||||
{
|
{
|
||||||
return <span key={ index } className={ part.className } style={ part.style } onClick={ part.onClick }>{ part.text }</span>
|
return <span key={ index } className={ part.className } style={ part.style } onClick={ part.onClick }>{ part.text }</span>
|
||||||
})
|
}) */}
|
||||||
}</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="pointer"></div>
|
<div className="pointer"></div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user