mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Add unseen tracker
This commit is contained in:
parent
bc9d0aa4a1
commit
183f4f6d53
@ -750,6 +750,7 @@
|
|||||||
"${images.url}/additions/number_3.png",
|
"${images.url}/additions/number_3.png",
|
||||||
"${images.url}/additions/number_4.png",
|
"${images.url}/additions/number_4.png",
|
||||||
"${images.url}/additions/number_5.png",
|
"${images.url}/additions/number_5.png",
|
||||||
|
"${images.url}/additions/pet_experience_bubble.png",
|
||||||
"${images.url}/loading_icon.png",
|
"${images.url}/loading_icon.png",
|
||||||
"${images.url}/clear_icon.png",
|
"${images.url}/clear_icon.png",
|
||||||
"${images.url}/big_arrow.png"
|
"${images.url}/big_arrow.png"
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
@import './fontawesome/brands';
|
@import './fontawesome/brands';
|
||||||
@import './fontawesome/regular';
|
@import './fontawesome/regular';
|
||||||
@import './scrollbars';
|
@import './scrollbars';
|
||||||
|
@import './slider';
|
||||||
@import './grid';
|
@import './grid';
|
||||||
@import './icons';
|
@import './icons';
|
||||||
@import './utils';
|
@import './utils';
|
||||||
|
54
src/assets/styles/slider.scss
Normal file
54
src/assets/styles/slider.scss
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
.nitro-slider {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
width: 100%;
|
||||||
|
height: 25px;
|
||||||
|
|
||||||
|
.track {
|
||||||
|
height: 3px;
|
||||||
|
border-radius: $border-radius;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
&.track-0 {
|
||||||
|
background-color: $primary;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.track-1 {
|
||||||
|
background-color: $muted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.thumb {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
background-color: gray;
|
||||||
|
font-size: 10px;
|
||||||
|
text-align: center;
|
||||||
|
line-height: 25px;
|
||||||
|
padding: 0 3px;
|
||||||
|
|
||||||
|
&:hover,
|
||||||
|
.active {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.degree {
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "\00b0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.percent {
|
||||||
|
|
||||||
|
&:after {
|
||||||
|
content: "\0025"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
20
src/events/inventory/UnseenItemTrackerUpdateEvent.ts
Normal file
20
src/events/inventory/UnseenItemTrackerUpdateEvent.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { NitroEvent } from 'nitro-renderer';
|
||||||
|
|
||||||
|
export class UnseenItemTrackerUpdateEvent extends NitroEvent
|
||||||
|
{
|
||||||
|
public static UPDATE_COUNT: string = 'UITUE_UPDATE_COUNTER';
|
||||||
|
|
||||||
|
private _count: number;
|
||||||
|
|
||||||
|
constructor(count: number)
|
||||||
|
{
|
||||||
|
super(UnseenItemTrackerUpdateEvent.UPDATE_COUNT);
|
||||||
|
|
||||||
|
this._count = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get count(): number
|
||||||
|
{
|
||||||
|
return this._count;
|
||||||
|
}
|
||||||
|
}
|
@ -1,3 +1,4 @@
|
|||||||
export * from './InventoryEvent';
|
export * from './InventoryEvent';
|
||||||
export * from './InventoryTradeRequestEvent';
|
export * from './InventoryTradeRequestEvent';
|
||||||
export * from './InventoryTradeStartEvent';
|
export * from './InventoryTradeStartEvent';
|
||||||
|
export * from './UnseenItemTrackerUpdateEvent';
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
border-color: $grid-border-color !important;
|
border-color: $grid-border-color !important;
|
||||||
background-color: $grid-bg-color !important;
|
background-color: $grid-bg-color;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@ -16,6 +16,10 @@
|
|||||||
background-color: $grid-active-bg-color !important;
|
background-color: $grid-active-bg-color !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.unseen {
|
||||||
|
background-color: rgba($success, 0.4);
|
||||||
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
top: 2px;
|
top: 2px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
|
@ -4,13 +4,13 @@ import { NitroCardGridItemViewProps } from './NitroCardGridItemView.types';
|
|||||||
|
|
||||||
export const NitroCardGridItemView: FC<NitroCardGridItemViewProps> = props =>
|
export const NitroCardGridItemView: FC<NitroCardGridItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { itemActive = false, itemCount = 1, itemUnique = false, itemUniqueNumber = 0, itemImage = null, className = '', style = {}, children = null, ...rest } = props;
|
const { itemImage = null, itemActive = false, itemCount = 1, itemUnique = false, itemUniqueNumber = 0, itemUnseen = false, className = '', style = {}, children = null, ...rest } = props;
|
||||||
|
|
||||||
const imageUrl = `url(${ itemImage })`;
|
const imageUrl = `url(${ itemImage })`;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col pb-1 grid-item-container">
|
<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 }>
|
<div className={ `position-relative border border-2 rounded grid-item cursor-pointer${ itemActive ? ' active' : '' }${ itemUnique ? ' unique-item' : '' }${ itemUnseen ? ' unseen' : ''} ${ className || '' }` } style={ itemImage ? { ...style, backgroundImage: imageUrl } : style } { ...rest }>
|
||||||
{ (itemCount > 1) &&
|
{ (itemCount > 1) &&
|
||||||
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ itemCount }</span> }
|
<span className="position-absolute badge border bg-danger px-1 rounded-circle">{ itemCount }</span> }
|
||||||
{ itemUnique &&
|
{ itemUnique &&
|
||||||
|
@ -7,4 +7,5 @@ export interface NitroCardGridItemViewProps extends DetailsHTMLAttributes<HTMLDi
|
|||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
itemUnique?: boolean;
|
itemUnique?: boolean;
|
||||||
itemUniqueNumber?: number;
|
itemUniqueNumber?: number;
|
||||||
|
itemUnseen?: boolean;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,12 @@
|
|||||||
.nitro-card-header {
|
.nitro-card-header {
|
||||||
min-height: 33px;
|
min-height: 33px;
|
||||||
max-height: 33px;
|
max-height: 33px;
|
||||||
|
white-space: nowrap;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
.header-text {
|
||||||
|
margin: 0 35px;
|
||||||
|
}
|
||||||
|
|
||||||
&.simple-header {
|
&.simple-header {
|
||||||
min-height: 28px;
|
min-height: 28px;
|
||||||
|
@ -27,7 +27,7 @@ export const NitroCardHeaderView: FC<NitroCardHeaderViewProps> = props =>
|
|||||||
<div className="drag-handler container-fluid bg-primary">
|
<div className="drag-handler container-fluid bg-primary">
|
||||||
<div className="row nitro-card-header">
|
<div className="row nitro-card-header">
|
||||||
<div className="d-flex justify-content-center align-items-center w-100 position-relative">
|
<div className="d-flex justify-content-center align-items-center w-100 position-relative">
|
||||||
<div className="h4 m-0 text-white text-shadow">{ headerText }</div>
|
<div className="h4 text-white text-shadow header-text">{ headerText }</div>
|
||||||
<div className="position-absolute header-close" onMouseDown={ event => event.stopPropagation() } onClick={ onCloseClick }>
|
<div className="position-absolute header-close" onMouseDown={ event => event.stopPropagation() } onClick={ onCloseClick }>
|
||||||
<i className="fas fa-times" />
|
<i className="fas fa-times" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -3,4 +3,11 @@
|
|||||||
&:last-child() {
|
&:last-child() {
|
||||||
margin-right: 0 !important;
|
margin-right: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
color: $white;
|
||||||
|
font-size: 10px;
|
||||||
|
line-height: 10px;
|
||||||
|
padding: 2px 3px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,15 @@ import { NitroCardTabsItemViewProps } from './NitroCardTabsItemView.types';
|
|||||||
|
|
||||||
export const NitroCardTabsItemView: FC<NitroCardTabsItemViewProps> = props =>
|
export const NitroCardTabsItemView: FC<NitroCardTabsItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { children = null, isActive = false, onClick = null } = props;
|
const { children = null, isActive = false, count = 0, onClick = null } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li className="nav-item me-1 cursor-pointer" onClick={ onClick }>
|
<li className="nav-item me-1 cursor-pointer" onClick={ onClick }>
|
||||||
<span className={ 'nav-link ' + classNames({ 'active': isActive }) }>{ children }</span>
|
<span className={ 'nav-link ' + classNames({ 'active': isActive }) }>
|
||||||
|
{ children }
|
||||||
|
{ (count > 0) &&
|
||||||
|
<span className="bg-danger ms-1 rounded count">{ count }</span> }
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -3,5 +3,6 @@ import { MouseEventHandler } from 'react';
|
|||||||
export interface NitroCardTabsItemViewProps
|
export interface NitroCardTabsItemViewProps
|
||||||
{
|
{
|
||||||
isActive?: boolean;
|
isActive?: boolean;
|
||||||
|
count?: number;
|
||||||
onClick?: MouseEventHandler<HTMLLIElement>;
|
onClick?: MouseEventHandler<HTMLLIElement>;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
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 { AdvancedMap, BadgesEvent, BotAddedToInventoryEvent, BotInventoryMessageEvent, BotRemovedFromInventoryEvent, FurnitureListAddOrUpdateEvent, FurnitureListEvent, FurnitureListInvalidateEvent, FurnitureListItemParser, FurnitureListRemovedEvent, FurniturePostItPlacedEvent, PetAddedToInventoryEvent, PetData, PetInventoryEvent, PetRemovedFromInventory, TradingAcceptEvent, TradingCloseEvent, TradingCompletedEvent, TradingConfirmationEvent, TradingListItemEvent, TradingNotOpenEvent, TradingOpenEvent, TradingOpenFailedEvent, TradingOtherNotAllowedEvent, TradingYouAreNotAllowedEvent, UnseenItemsEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { GetRoomSession, GetSessionDataManager } from '../../api';
|
import { GetRoomSession, GetSessionDataManager } from '../../api';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
@ -17,7 +17,7 @@ let petMsgFragments: Map<number, PetData>[] = null;
|
|||||||
|
|
||||||
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =>
|
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =>
|
||||||
{
|
{
|
||||||
const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, dispatchBadgeState = null } = useInventoryContext();
|
const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, dispatchBadgeState = null, unseenTracker = null } = useInventoryContext();
|
||||||
|
|
||||||
const onFurnitureListAddOrUpdateEvent = useCallback((event: FurnitureListAddOrUpdateEvent) =>
|
const onFurnitureListAddOrUpdateEvent = useCallback((event: FurnitureListAddOrUpdateEvent) =>
|
||||||
{
|
{
|
||||||
@ -43,9 +43,9 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
|
|
||||||
dispatchFurnitureState({
|
dispatchFurnitureState({
|
||||||
type: InventoryFurnitureActions.PROCESS_FRAGMENT,
|
type: InventoryFurnitureActions.PROCESS_FRAGMENT,
|
||||||
payload: { fragment }
|
payload: { fragment, unseenTracker }
|
||||||
});
|
});
|
||||||
}, [ dispatchFurnitureState ]);
|
}, [ unseenTracker, dispatchFurnitureState ]);
|
||||||
|
|
||||||
const onFurnitureListInvalidateEvent = useCallback((event: FurnitureListInvalidateEvent) =>
|
const onFurnitureListInvalidateEvent = useCallback((event: FurnitureListInvalidateEvent) =>
|
||||||
{
|
{
|
||||||
@ -82,9 +82,9 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
|
|
||||||
dispatchBotState({
|
dispatchBotState({
|
||||||
type: InventoryBotActions.PROCESS_FRAGMENT,
|
type: InventoryBotActions.PROCESS_FRAGMENT,
|
||||||
payload: { fragment }
|
payload: { fragment, unseenTracker }
|
||||||
});
|
});
|
||||||
}, [ dispatchBotState ]);
|
}, [ dispatchBotState, unseenTracker ]);
|
||||||
|
|
||||||
const onBotAddedToInventoryEvent = useCallback((event: BotAddedToInventoryEvent) =>
|
const onBotAddedToInventoryEvent = useCallback((event: BotAddedToInventoryEvent) =>
|
||||||
{
|
{
|
||||||
@ -122,9 +122,9 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
|
|
||||||
dispatchPetState({
|
dispatchPetState({
|
||||||
type: InventoryPetActions.PROCESS_FRAGMENT,
|
type: InventoryPetActions.PROCESS_FRAGMENT,
|
||||||
payload: { fragment }
|
payload: { fragment, unseenTracker }
|
||||||
});
|
});
|
||||||
}, [dispatchPetState ]);
|
}, [ dispatchPetState, unseenTracker ]);
|
||||||
|
|
||||||
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
|
const onPetAddedToInventoryEvent = useCallback((event: PetAddedToInventoryEvent) =>
|
||||||
{
|
{
|
||||||
@ -294,6 +294,20 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
console.log(parser);
|
console.log(parser);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const onUnseenItemsEvent = useCallback((event: UnseenItemsEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
console.log(parser);
|
||||||
|
|
||||||
|
for(const category of parser.categories)
|
||||||
|
{
|
||||||
|
const itemIds = parser.getItemsByCategory(category);
|
||||||
|
|
||||||
|
unseenTracker.addItems(category, itemIds);
|
||||||
|
}
|
||||||
|
}, [ unseenTracker ]);
|
||||||
|
|
||||||
CreateMessageHook(FurnitureListAddOrUpdateEvent, onFurnitureListAddOrUpdateEvent);
|
CreateMessageHook(FurnitureListAddOrUpdateEvent, onFurnitureListAddOrUpdateEvent);
|
||||||
CreateMessageHook(FurnitureListEvent, onFurnitureListEvent);
|
CreateMessageHook(FurnitureListEvent, onFurnitureListEvent);
|
||||||
CreateMessageHook(FurnitureListInvalidateEvent, onFurnitureListInvalidateEvent);
|
CreateMessageHook(FurnitureListInvalidateEvent, onFurnitureListInvalidateEvent);
|
||||||
@ -316,6 +330,7 @@ export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props =
|
|||||||
CreateMessageHook(TradingOpenFailedEvent, onTradingOpenFailedEvent);
|
CreateMessageHook(TradingOpenFailedEvent, onTradingOpenFailedEvent);
|
||||||
CreateMessageHook(TradingOtherNotAllowedEvent, onTradingOtherNotAllowedEvent);
|
CreateMessageHook(TradingOtherNotAllowedEvent, onTradingOtherNotAllowedEvent);
|
||||||
CreateMessageHook(TradingYouAreNotAllowedEvent, onTradingYouAreNotAllowedEvent);
|
CreateMessageHook(TradingYouAreNotAllowedEvent, onTradingYouAreNotAllowedEvent);
|
||||||
|
CreateMessageHook(UnseenItemsEvent, onUnseenItemsEvent);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,9 @@ import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, Nitro
|
|||||||
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 { TradeState } from './common/TradeState';
|
||||||
|
import { IUnseenItemTracker } from './common/unseen/IUnseenItemTracker';
|
||||||
|
import { UnseenItemCategory } from './common/unseen/UnseenItemCategory';
|
||||||
|
import { UnseenItemTracker } from './common/unseen/UnseenItemTracker';
|
||||||
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';
|
||||||
@ -23,18 +26,20 @@ import { InventoryFurnitureView } from './views/furniture/InventoryFurnitureView
|
|||||||
import { InventoryPetView } from './views/pet/InventoryPetView';
|
import { InventoryPetView } from './views/pet/InventoryPetView';
|
||||||
import { InventoryTradeView } from './views/trade/InventoryTradeView';
|
import { InventoryTradeView } from './views/trade/InventoryTradeView';
|
||||||
|
|
||||||
const tabs = [ InventoryTabs.FURNITURE, InventoryTabs.BOTS, InventoryTabs.PETS, InventoryTabs.BADGES ];
|
const TABS = [ InventoryTabs.FURNITURE, InventoryTabs.BOTS, InventoryTabs.PETS, InventoryTabs.BADGES ];
|
||||||
|
const UNSEEN_CATEGORIES = [ UnseenItemCategory.FURNI, UnseenItemCategory.BOT, UnseenItemCategory.PET, UnseenItemCategory.BADGE ];
|
||||||
|
|
||||||
export const InventoryView: FC<InventoryViewProps> = props =>
|
export const InventoryView: FC<InventoryViewProps> = props =>
|
||||||
{
|
{
|
||||||
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);
|
||||||
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
const [ roomPreviewer, setRoomPreviewer ] = useState<RoomPreviewer>(null);
|
||||||
const [ furnitureState, dispatchFurnitureState ] = useReducer(InventoryFurnitureReducer, initialInventoryFurniture);
|
const [ furnitureState, dispatchFurnitureState ] = useReducer(InventoryFurnitureReducer, initialInventoryFurniture);
|
||||||
const [ botState, dispatchBotState ] = useReducer(InventoryBotReducer, initialInventoryBot);
|
const [ botState, dispatchBotState ] = useReducer(InventoryBotReducer, initialInventoryBot);
|
||||||
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 [ unseenTracker ] = useState<IUnseenItemTracker>(new UnseenItemTracker());
|
||||||
|
|
||||||
const close = useCallback(() =>
|
const close = useCallback(() =>
|
||||||
{
|
{
|
||||||
@ -119,6 +124,45 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
useRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
|
useRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
|
||||||
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
|
||||||
|
|
||||||
|
const resetTrackerForTab = useCallback((name: string) =>
|
||||||
|
{
|
||||||
|
const tabIndex = TABS.indexOf(name);
|
||||||
|
|
||||||
|
if(tabIndex === -1) return;
|
||||||
|
|
||||||
|
const unseenCategory = UNSEEN_CATEGORIES[tabIndex];
|
||||||
|
|
||||||
|
if(unseenCategory === -1) return;
|
||||||
|
|
||||||
|
const count = unseenTracker.getCount(unseenCategory);
|
||||||
|
|
||||||
|
if(!count) return;
|
||||||
|
|
||||||
|
unseenTracker.resetCategory(unseenCategory);
|
||||||
|
|
||||||
|
switch(unseenCategory)
|
||||||
|
{
|
||||||
|
case UnseenItemCategory.FURNI:
|
||||||
|
for(const groupItem of furnitureState.groupItems) groupItem.hasUnseenItems = false;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}, [ furnitureState.groupItems, unseenTracker ]);
|
||||||
|
|
||||||
|
const switchTab = useCallback((prevTab: string, nextTab: string) =>
|
||||||
|
{
|
||||||
|
if(nextTab) setCurrentTab(nextTab);
|
||||||
|
|
||||||
|
resetTrackerForTab(prevTab);
|
||||||
|
}, [ resetTrackerForTab ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(isVisible) return;
|
||||||
|
|
||||||
|
if(currentTab) resetTrackerForTab(currentTab);
|
||||||
|
}, [ currentTab, isVisible, resetTrackerForTab ]);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
setRoomPreviewer(new RoomPreviewer(GetRoomEngine(), ++RoomPreviewer.PREVIEW_COUNTER));
|
||||||
@ -143,7 +187,7 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
}, [ furnitureState.tradeData, isVisible ]);
|
}, [ 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, unseenTracker } }>
|
||||||
<InventoryMessageHandler />
|
<InventoryMessageHandler />
|
||||||
{ isVisible &&
|
{ isVisible &&
|
||||||
<NitroCardView className="nitro-inventory">
|
<NitroCardView className="nitro-inventory">
|
||||||
@ -151,10 +195,12 @@ export const InventoryView: FC<InventoryViewProps> = props =>
|
|||||||
{ !furnitureState.tradeData &&
|
{ !furnitureState.tradeData &&
|
||||||
<>
|
<>
|
||||||
<NitroCardTabsView>
|
<NitroCardTabsView>
|
||||||
{ tabs.map((name, index) =>
|
{ TABS.map((name, index) =>
|
||||||
{
|
{
|
||||||
|
const unseenCount = unseenTracker.getCount(UNSEEN_CATEGORIES[index]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => setCurrentTab(name) }>
|
<NitroCardTabsItemView key={ index } isActive={ (currentTab === name) } onClick={ event => switchTab(currentTab, name) } count={ unseenCount }>
|
||||||
{ LocalizeText(name) }
|
{ LocalizeText(name) }
|
||||||
</NitroCardTabsItemView>
|
</NitroCardTabsItemView>
|
||||||
);
|
);
|
||||||
|
26
src/views/inventory/common/BadgeItem.ts
Normal file
26
src/views/inventory/common/BadgeItem.ts
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
export class BadgeItem
|
||||||
|
{
|
||||||
|
private _code: string;
|
||||||
|
private _isUnseen: boolean;
|
||||||
|
|
||||||
|
constructor(code: string)
|
||||||
|
{
|
||||||
|
this._code = code;
|
||||||
|
this._isUnseen = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get code(): string
|
||||||
|
{
|
||||||
|
return this._code;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get isUnseen(): boolean
|
||||||
|
{
|
||||||
|
return this._isUnseen;
|
||||||
|
}
|
||||||
|
|
||||||
|
public set isUnseen(flag: boolean)
|
||||||
|
{
|
||||||
|
this._isUnseen = flag;
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,8 @@ import { InventoryEvent } from '../../../events';
|
|||||||
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
||||||
import { BotItem } from './BotItem';
|
import { BotItem } from './BotItem';
|
||||||
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
||||||
|
import { IUnseenItemTracker } from './unseen/IUnseenItemTracker';
|
||||||
|
import { UnseenItemCategory } from './unseen/UnseenItemCategory';
|
||||||
|
|
||||||
export function cancelRoomObjectPlacement(): void
|
export function cancelRoomObjectPlacement(): void
|
||||||
{
|
{
|
||||||
@ -45,7 +47,7 @@ function getAllItemIds(botItems: BotItem[]): number[]
|
|||||||
return itemIds;
|
return itemIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processBotFragment(set: BotItem[], fragment: BotData[]): BotItem[]
|
export function processBotFragment(set: BotItem[], fragment: BotData[], unseenTracker: IUnseenItemTracker): BotItem[]
|
||||||
{
|
{
|
||||||
const existingIds = getAllItemIds(set);
|
const existingIds = getAllItemIds(set);
|
||||||
const addedDatas: BotData[] = [];
|
const addedDatas: BotData[] = [];
|
||||||
@ -55,21 +57,28 @@ export function processBotFragment(set: BotItem[], fragment: BotData[]): BotItem
|
|||||||
|
|
||||||
for(const itemId of existingIds)
|
for(const itemId of existingIds)
|
||||||
{
|
{
|
||||||
|
let remove = true;
|
||||||
|
|
||||||
for(const botData of fragment)
|
for(const botData of fragment)
|
||||||
{
|
{
|
||||||
if(botData.id === itemId) continue;
|
if(botData.id === itemId)
|
||||||
|
{
|
||||||
|
remove = false;
|
||||||
|
|
||||||
removedIds.push(itemId);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(remove) removedIds.push(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
const emptyExistingSet = (existingIds.length === 0);
|
const emptyExistingSet = (existingIds.length === 0);
|
||||||
|
|
||||||
for(const id of removedIds) removeBotItemById(id, set);
|
for(const id of removedIds) removeBotItemById(id, set);
|
||||||
|
|
||||||
for(const botData of addedDatas)
|
for(const botData of addedDatas)
|
||||||
{
|
{
|
||||||
addSingleBotItem(botData, set, true);
|
addSingleBotItem(botData, set, unseenTracker.isUnseen(UnseenItemCategory.BOT, botData.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
@ -109,6 +118,8 @@ export function addSingleBotItem(botData: BotData, set: BotItem[], unseen: boole
|
|||||||
|
|
||||||
if(unseen)
|
if(unseen)
|
||||||
{
|
{
|
||||||
|
botItem.isUnseen = true;
|
||||||
|
|
||||||
set.unshift(botItem);
|
set.unshift(botItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -7,6 +7,8 @@ import { FurniCategory } from './FurniCategory';
|
|||||||
import { FurnitureItem } from './FurnitureItem';
|
import { FurnitureItem } from './FurnitureItem';
|
||||||
import { GroupItem } from './GroupItem';
|
import { GroupItem } from './GroupItem';
|
||||||
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
||||||
|
import { IUnseenItemTracker } from './unseen/IUnseenItemTracker';
|
||||||
|
import { UnseenItemCategory } from './unseen/UnseenItemCategory';
|
||||||
|
|
||||||
export function attemptItemPlacement(groupItem: GroupItem, flag: boolean = false): boolean
|
export function attemptItemPlacement(groupItem: GroupItem, flag: boolean = false): boolean
|
||||||
{
|
{
|
||||||
@ -121,7 +123,7 @@ function getAllItemIds(groupItems: GroupItem[]): number[]
|
|||||||
return itemIds;
|
return itemIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processFurniFragment(set: GroupItem[], fragment: Map<number, FurnitureListItemParser>): GroupItem[]
|
export function processFurniFragment(set: GroupItem[], fragment: Map<number, FurnitureListItemParser>, unseenTracker: IUnseenItemTracker): GroupItem[]
|
||||||
{
|
{
|
||||||
const existingIds = getAllItemIds(set);
|
const existingIds = getAllItemIds(set);
|
||||||
const addedIds: number[] = [];
|
const addedIds: number[] = [];
|
||||||
@ -143,7 +145,7 @@ export function processFurniFragment(set: GroupItem[], fragment: Map<number, Fur
|
|||||||
|
|
||||||
const item = new FurnitureItem(parser);
|
const item = new FurnitureItem(parser);
|
||||||
|
|
||||||
addFurnitureItem(set, item, true);
|
addFurnitureItem(set, item, unseenTracker.isUnseen(UnseenItemCategory.FURNI, id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
@ -186,23 +188,19 @@ export function removeFurniItemById(id: number, set: GroupItem[]): GroupItem
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function addFurnitureItem(set: GroupItem[], item: FurnitureItem, flag: boolean): void
|
export function addFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen: boolean): void
|
||||||
{
|
{
|
||||||
let groupItem: GroupItem = null;
|
|
||||||
|
|
||||||
if(!item.isGroupable)
|
if(!item.isGroupable)
|
||||||
{
|
{
|
||||||
groupItem = addSingleFurnitureItem(set, item, flag);
|
addSingleFurnitureItem(set, item, unseen);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
groupItem = addGroupableFurnitureItem(set, item, flag);
|
addGroupableFurnitureItem(set, item, unseen);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!flag) groupItem.hasUnseenItems = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSingleFurnitureItem(set: GroupItem[], item: FurnitureItem, flag: boolean): GroupItem
|
function addSingleFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen: boolean): GroupItem
|
||||||
{
|
{
|
||||||
const groupItems: GroupItem[] = [];
|
const groupItems: GroupItem[] = [];
|
||||||
|
|
||||||
@ -216,10 +214,9 @@ function addSingleFurnitureItem(set: GroupItem[], item: FurnitureItem, flag: boo
|
|||||||
if(groupItem.getItemById(item.id)) return groupItem;
|
if(groupItem.getItemById(item.id)) return groupItem;
|
||||||
}
|
}
|
||||||
|
|
||||||
const unseen = flag; //this.isFurnitureUnseen(item);
|
const groupItem = createGroupItem(item.type, item.category, item.stuffData, item.extra);
|
||||||
const groupItem = createGroupItem(item.type, item.category, item.stuffData, item.extra, unseen);
|
|
||||||
|
|
||||||
groupItem.push(item, unseen);
|
groupItem.push(item);
|
||||||
|
|
||||||
if(unseen)
|
if(unseen)
|
||||||
{
|
{
|
||||||
@ -272,11 +269,9 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// unseen = unseen; //this.isFurnitureUnseen(item);
|
|
||||||
|
|
||||||
if(existingGroup)
|
if(existingGroup)
|
||||||
{
|
{
|
||||||
existingGroup.push(item, unseen);
|
existingGroup.push(item);
|
||||||
|
|
||||||
if(unseen)
|
if(unseen)
|
||||||
{
|
{
|
||||||
@ -292,9 +287,9 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
return existingGroup;
|
return existingGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
existingGroup = createGroupItem(item.type, item.category, item.stuffData, item.extra, unseen);
|
existingGroup = createGroupItem(item.type, item.category, item.stuffData, item.extra);
|
||||||
|
|
||||||
existingGroup.push(item, unseen);
|
existingGroup.push(item);
|
||||||
|
|
||||||
if(unseen)
|
if(unseen)
|
||||||
{
|
{
|
||||||
@ -310,7 +305,7 @@ function addGroupableFurnitureItem(set: GroupItem[], item: FurnitureItem, unseen
|
|||||||
return existingGroup;
|
return existingGroup;
|
||||||
}
|
}
|
||||||
|
|
||||||
export 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): GroupItem
|
||||||
{
|
{
|
||||||
// const iconImage: HTMLImageElement = null;
|
// const iconImage: HTMLImageElement = null;
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ export class GroupItem
|
|||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
|
||||||
public push(item: FurnitureItem, unseen: boolean = false): void
|
public push(item: FurnitureItem): void
|
||||||
{
|
{
|
||||||
const items = [ ...this._items ];
|
const items = [ ...this._items ];
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import { InventoryEvent } from '../../../events';
|
|||||||
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
import { dispatchUiEvent } from '../../../hooks/events/ui/ui-event';
|
||||||
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
import { getPlacingItemId, setObjectMoverRequested, setPlacingItemId } from './InventoryUtilities';
|
||||||
import { PetItem } from './PetItem';
|
import { PetItem } from './PetItem';
|
||||||
|
import { IUnseenItemTracker } from './unseen/IUnseenItemTracker';
|
||||||
|
import { UnseenItemCategory } from './unseen/UnseenItemCategory';
|
||||||
|
|
||||||
export function cancelRoomObjectPlacement(): void
|
export function cancelRoomObjectPlacement(): void
|
||||||
{
|
{
|
||||||
@ -75,7 +77,7 @@ function getAllItemIds(petItems: PetItem[]): number[]
|
|||||||
return itemIds;
|
return itemIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processPetFragment(set: PetItem[], fragment: Map<number, PetData>): PetItem[]
|
export function processPetFragment(set: PetItem[], fragment: Map<number, PetData>, unseenTracker: IUnseenItemTracker): PetItem[]
|
||||||
{
|
{
|
||||||
const existingIds = getAllItemIds(set);
|
const existingIds = getAllItemIds(set);
|
||||||
const addedIds: number[] = [];
|
const addedIds: number[] = [];
|
||||||
@ -95,7 +97,7 @@ export function processPetFragment(set: PetItem[], fragment: Map<number, PetData
|
|||||||
|
|
||||||
if(!parser) continue;
|
if(!parser) continue;
|
||||||
|
|
||||||
addSinglePetItem(parser, set, true);
|
addSinglePetItem(parser, set, unseenTracker.isUnseen(UnseenItemCategory.PET, parser.id));
|
||||||
}
|
}
|
||||||
|
|
||||||
return set;
|
return set;
|
||||||
@ -135,6 +137,8 @@ export function addSinglePetItem(petData: PetData, set: PetItem[], unseen: boole
|
|||||||
|
|
||||||
if(unseen)
|
if(unseen)
|
||||||
{
|
{
|
||||||
|
petItem.isUnseen = true;
|
||||||
|
|
||||||
set.unshift(petItem);
|
set.unshift(petItem);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
13
src/views/inventory/common/unseen/IUnseenItemTracker.ts
Normal file
13
src/views/inventory/common/unseen/IUnseenItemTracker.ts
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export interface IUnseenItemTracker
|
||||||
|
{
|
||||||
|
dispose(): void;
|
||||||
|
resetCategory(category: number): boolean;
|
||||||
|
resetItems(category: number, itemIds: number[]): boolean;
|
||||||
|
resetCategoryIfEmpty(category: number): boolean;
|
||||||
|
isUnseen(category: number, itemId: number): boolean;
|
||||||
|
removeUnseen(category: number, itemId: number): boolean;
|
||||||
|
getIds(category: number): number[];
|
||||||
|
getCount(category: number): number;
|
||||||
|
getFullCount(): number;
|
||||||
|
addItems(category: number, itemIds: number[]): void;
|
||||||
|
}
|
10
src/views/inventory/common/unseen/UnseenItemCategory.ts
Normal file
10
src/views/inventory/common/unseen/UnseenItemCategory.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
export class UnseenItemCategory
|
||||||
|
{
|
||||||
|
public static FURNI: number = 1;
|
||||||
|
public static RENTABLE: number = 2;
|
||||||
|
public static PET: number = 3;
|
||||||
|
public static BADGE: number = 4;
|
||||||
|
public static BOT: number = 5;
|
||||||
|
public static GAMES: number = 6;
|
||||||
|
public static _Str_12463: number[] = [ UnseenItemCategory.FURNI, UnseenItemCategory.RENTABLE, UnseenItemCategory.PET, UnseenItemCategory.BADGE, UnseenItemCategory.BOT ];
|
||||||
|
}
|
145
src/views/inventory/common/unseen/UnseenItemTracker.ts
Normal file
145
src/views/inventory/common/unseen/UnseenItemTracker.ts
Normal file
@ -0,0 +1,145 @@
|
|||||||
|
import { UnseenResetCategoryComposer, UnseenResetItemsComposer } from 'nitro-renderer';
|
||||||
|
import { UnseenItemTrackerUpdateEvent } from '../../../../events';
|
||||||
|
import { dispatchUiEvent, SendMessageHook } from '../../../../hooks';
|
||||||
|
import { IUnseenItemTracker } from './IUnseenItemTracker';
|
||||||
|
|
||||||
|
export class UnseenItemTracker implements IUnseenItemTracker
|
||||||
|
{
|
||||||
|
private _unseenItems: Map<number, number[]> = new Map();
|
||||||
|
|
||||||
|
public dispose(): void
|
||||||
|
{
|
||||||
|
this._unseenItems.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetCategory(category: number): boolean
|
||||||
|
{
|
||||||
|
if(!this.getCount(category)) return false;
|
||||||
|
|
||||||
|
this._unseenItems.delete(category);
|
||||||
|
|
||||||
|
this.dispatchUpdateEvent();
|
||||||
|
|
||||||
|
this.sendResetCategoryMessage(category);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetItems(category: number, itemIds: number[]): boolean
|
||||||
|
{
|
||||||
|
if(!this.getCount(category)) return false;
|
||||||
|
|
||||||
|
const existing = this._unseenItems.get(category);
|
||||||
|
|
||||||
|
for(const itemId of itemIds)
|
||||||
|
{
|
||||||
|
existing.splice(existing.indexOf(itemId), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatchUpdateEvent();
|
||||||
|
|
||||||
|
this.sendResetItemsMessage(category, itemIds);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public resetCategoryIfEmpty(category: number): boolean
|
||||||
|
{
|
||||||
|
if(this.getCount(category)) return false;
|
||||||
|
|
||||||
|
this._unseenItems.delete(category);
|
||||||
|
|
||||||
|
this.dispatchUpdateEvent();
|
||||||
|
|
||||||
|
this.sendResetCategoryMessage(category);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isUnseen(category: number, itemId: number): boolean
|
||||||
|
{
|
||||||
|
if(!this._unseenItems.get(category)) return false;
|
||||||
|
|
||||||
|
const items = this._unseenItems.get(category);
|
||||||
|
|
||||||
|
return (items.indexOf(itemId) >= 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public removeUnseen(category: number, itemId: number): boolean
|
||||||
|
{
|
||||||
|
if(!this._unseenItems.get(category)) return false;
|
||||||
|
|
||||||
|
const items = this._unseenItems.get(category);
|
||||||
|
const index = items.indexOf(itemId);
|
||||||
|
|
||||||
|
if(index === -1) return false;
|
||||||
|
|
||||||
|
items.splice(index, 1);
|
||||||
|
|
||||||
|
this.dispatchUpdateEvent();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getIds(category: number): number[]
|
||||||
|
{
|
||||||
|
if(!this._unseenItems) return [];
|
||||||
|
|
||||||
|
return this._unseenItems.get(category);
|
||||||
|
}
|
||||||
|
|
||||||
|
public getCount(category: number): number
|
||||||
|
{
|
||||||
|
if(!this._unseenItems.get(category)) return 0;
|
||||||
|
|
||||||
|
return this._unseenItems.get(category).length;
|
||||||
|
}
|
||||||
|
|
||||||
|
public getFullCount(): number
|
||||||
|
{
|
||||||
|
let count = 0;
|
||||||
|
|
||||||
|
for(const key of this._unseenItems.keys())
|
||||||
|
{
|
||||||
|
count += this.getCount(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
public addItems(category: number, itemIds: number[]): void
|
||||||
|
{
|
||||||
|
if(!itemIds) return;
|
||||||
|
|
||||||
|
let unseenItems = this._unseenItems.get(category);
|
||||||
|
|
||||||
|
if(!unseenItems)
|
||||||
|
{
|
||||||
|
unseenItems = [];
|
||||||
|
|
||||||
|
this._unseenItems.set(category, unseenItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(const itemId of itemIds)
|
||||||
|
{
|
||||||
|
if(unseenItems.indexOf(itemId) === -1) unseenItems.push(itemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.dispatchUpdateEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private dispatchUpdateEvent(): void
|
||||||
|
{
|
||||||
|
dispatchUiEvent(new UnseenItemTrackerUpdateEvent(this.getFullCount()));
|
||||||
|
}
|
||||||
|
|
||||||
|
private sendResetCategoryMessage(category: number): void
|
||||||
|
{
|
||||||
|
SendMessageHook(new UnseenResetCategoryComposer(category));
|
||||||
|
}
|
||||||
|
|
||||||
|
private sendResetItemsMessage(category: number, itemIds: number[]): void
|
||||||
|
{
|
||||||
|
SendMessageHook(new UnseenResetItemsComposer(category, ...itemIds));
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,8 @@ const InventoryContext = createContext<IInventoryContext>({
|
|||||||
petState: null,
|
petState: null,
|
||||||
dispatchPetState: null,
|
dispatchPetState: null,
|
||||||
badgeState: null,
|
badgeState: null,
|
||||||
dispatchBadgeState: null
|
dispatchBadgeState: null,
|
||||||
|
unseenTracker: null
|
||||||
});
|
});
|
||||||
|
|
||||||
export const InventoryContextProvider: FC<InventoryContextProps> = props =>
|
export const InventoryContextProvider: FC<InventoryContextProps> = props =>
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { Dispatch, ProviderProps } from 'react';
|
import { Dispatch, ProviderProps } from 'react';
|
||||||
|
import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
|
||||||
import { IInventoryBadgeAction, IInventoryBadgeState } from '../reducers/InventoryBadgeReducer';
|
import { IInventoryBadgeAction, IInventoryBadgeState } from '../reducers/InventoryBadgeReducer';
|
||||||
import { IInventoryBotAction, IInventoryBotState } from '../reducers/InventoryBotReducer';
|
import { IInventoryBotAction, IInventoryBotState } from '../reducers/InventoryBotReducer';
|
||||||
import { IInventoryFurnitureAction, IInventoryFurnitureState } from '../reducers/InventoryFurnitureReducer';
|
import { IInventoryFurnitureAction, IInventoryFurnitureState } from '../reducers/InventoryFurnitureReducer';
|
||||||
@ -14,6 +15,7 @@ export interface IInventoryContext
|
|||||||
dispatchPetState: Dispatch<IInventoryPetAction>;
|
dispatchPetState: Dispatch<IInventoryPetAction>;
|
||||||
badgeState: IInventoryBadgeState;
|
badgeState: IInventoryBadgeState;
|
||||||
dispatchBadgeState: Dispatch<IInventoryBadgeAction>;
|
dispatchBadgeState: Dispatch<IInventoryBadgeAction>;
|
||||||
|
unseenTracker: IUnseenItemTracker;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface InventoryContextProps extends ProviderProps<IInventoryContext>
|
export interface InventoryContextProps extends ProviderProps<IInventoryContext>
|
||||||
|
@ -2,6 +2,7 @@ import { BotData } from 'nitro-renderer';
|
|||||||
import { Reducer } from 'react';
|
import { Reducer } from 'react';
|
||||||
import { BotItem } from '../common/BotItem';
|
import { BotItem } from '../common/BotItem';
|
||||||
import { addSingleBotItem, processBotFragment, removeBotItemById } from '../common/BotUtilities';
|
import { addSingleBotItem, processBotFragment, removeBotItemById } from '../common/BotUtilities';
|
||||||
|
import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
|
||||||
|
|
||||||
export interface IInventoryBotState
|
export interface IInventoryBotState
|
||||||
{
|
{
|
||||||
@ -19,6 +20,7 @@ export interface IInventoryBotAction
|
|||||||
botId?: number;
|
botId?: number;
|
||||||
botData?: BotData;
|
botData?: BotData;
|
||||||
fragment?: BotData[];
|
fragment?: BotData[];
|
||||||
|
unseenTracker?: IUnseenItemTracker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +64,7 @@ export const InventoryBotReducer: Reducer<IInventoryBotState, IInventoryBotActio
|
|||||||
case InventoryBotActions.PROCESS_FRAGMENT: {
|
case InventoryBotActions.PROCESS_FRAGMENT: {
|
||||||
const botItems = [ ...state.botItems ];
|
const botItems = [ ...state.botItems ];
|
||||||
|
|
||||||
processBotFragment(botItems, action.payload.fragment);
|
processBotFragment(botItems, action.payload.fragment, (action.payload.unseenTracker || null));
|
||||||
|
|
||||||
return { ...state, botItems };
|
return { ...state, botItems };
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ import { GroupItem } from '../common/GroupItem';
|
|||||||
import { TradeState } from '../common/TradeState';
|
import { TradeState } from '../common/TradeState';
|
||||||
import { TradeUserData } from '../common/TradeUserData';
|
import { TradeUserData } from '../common/TradeUserData';
|
||||||
import { parseTradeItems } from '../common/TradingUtilities';
|
import { parseTradeItems } from '../common/TradingUtilities';
|
||||||
|
import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
|
||||||
|
|
||||||
export interface IInventoryFurnitureState
|
export interface IInventoryFurnitureState
|
||||||
{
|
{
|
||||||
@ -33,6 +34,7 @@ export interface IInventoryFurnitureAction
|
|||||||
tradeState?: number;
|
tradeState?: number;
|
||||||
userId?: number;
|
userId?: number;
|
||||||
tradeParser?: TradingListItemParser;
|
tradeParser?: TradingListItemParser;
|
||||||
|
unseenTracker?: IUnseenItemTracker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,7 +84,7 @@ export const InventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInven
|
|||||||
case InventoryFurnitureActions.PROCESS_FRAGMENT: {
|
case InventoryFurnitureActions.PROCESS_FRAGMENT: {
|
||||||
const groupItems = [ ...state.groupItems ];
|
const groupItems = [ ...state.groupItems ];
|
||||||
|
|
||||||
processFurniFragment(groupItems, (action.payload.fragment || null));
|
processFurniFragment(groupItems, (action.payload.fragment || null), (action.payload.unseenTracker || null));
|
||||||
|
|
||||||
return { ...state, groupItems };
|
return { ...state, groupItems };
|
||||||
}
|
}
|
||||||
@ -137,7 +139,7 @@ export const InventoryFurnitureReducer: Reducer<IInventoryFurnitureState, IInven
|
|||||||
{
|
{
|
||||||
const furniture = new FurnitureItem(item);
|
const furniture = new FurnitureItem(item);
|
||||||
|
|
||||||
addFurnitureItem(groupItems, furniture, false);
|
addFurnitureItem(groupItems, furniture, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ import { PetData } from 'nitro-renderer';
|
|||||||
import { Reducer } from 'react';
|
import { Reducer } from 'react';
|
||||||
import { PetItem } from '../common/PetItem';
|
import { PetItem } from '../common/PetItem';
|
||||||
import { addSinglePetItem, processPetFragment, removePetItemById } from '../common/PetUtilities';
|
import { addSinglePetItem, processPetFragment, removePetItemById } from '../common/PetUtilities';
|
||||||
|
import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
|
||||||
|
|
||||||
export interface IInventoryPetState
|
export interface IInventoryPetState
|
||||||
{
|
{
|
||||||
@ -19,6 +20,7 @@ export interface IInventoryPetAction
|
|||||||
petId?: number;
|
petId?: number;
|
||||||
petData?: PetData;
|
petData?: PetData;
|
||||||
fragment?: Map<number, PetData>;
|
fragment?: Map<number, PetData>;
|
||||||
|
unseenTracker?: IUnseenItemTracker;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +64,7 @@ export const InventoryPetReducer: Reducer<IInventoryPetState, IInventoryPetActio
|
|||||||
case InventoryPetActions.PROCESS_FRAGMENT: {
|
case InventoryPetActions.PROCESS_FRAGMENT: {
|
||||||
const petItems = [ ...state.petItems ];
|
const petItems = [ ...state.petItems ];
|
||||||
|
|
||||||
processPetFragment(petItems, (action.payload.fragment || null));
|
processPetFragment(petItems, (action.payload.fragment || null), (action.payload.unseenTracker || null));
|
||||||
|
|
||||||
return { ...state, petItems };
|
return { ...state, petItems };
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
|
||||||
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
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';
|
||||||
@ -37,8 +37,15 @@ export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ isActive, isMouseDown, botItem, dispatchBotState ]);
|
}, [ isActive, isMouseDown, botItem, dispatchBotState ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isActive) return;
|
||||||
|
|
||||||
|
botItem.isUnseen = false;
|
||||||
|
}, [ isActive, botItem ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
<NitroCardGridItemView itemActive={ isActive } itemUnseen={ botItem.isUnseen } 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>
|
</NitroCardGridItemView>
|
||||||
);
|
);
|
||||||
|
@ -17,7 +17,7 @@ import { InventoryFurnitureSearchView } from './search/InventoryFurnitureSearchV
|
|||||||
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { roomSession = null, roomPreviewer = null } = props;
|
const { roomSession = null, roomPreviewer = null } = props;
|
||||||
const { furnitureState = null, dispatchFurnitureState = null } = useInventoryContext();
|
const { furnitureState = null, dispatchFurnitureState = null, unseenTracker = null } = useInventoryContext();
|
||||||
const { needsFurniUpdate = false, groupItem = null, groupItems = [] } = furnitureState;
|
const { needsFurniUpdate = false, groupItem = null, groupItems = [] } = furnitureState;
|
||||||
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>(groupItems);
|
const [ filteredGroupItems, setFilteredGroupItems ] = useState<GroupItem[]>(groupItems);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
|
||||||
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
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';
|
||||||
@ -37,7 +37,14 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
|
|||||||
}
|
}
|
||||||
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
|
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isActive) return;
|
||||||
|
|
||||||
|
groupItem.hasUnseenItems = false;
|
||||||
|
}, [ isActive, groupItem ]);
|
||||||
|
|
||||||
const count = groupItem.getUnlockedCount();
|
const count = groupItem.getUnlockedCount();
|
||||||
|
|
||||||
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 } />;
|
return <NitroCardGridItemView className={ !count ? 'opacity-0-5 ' : '' } itemImage={ groupItem.iconUrl } itemCount={ count } itemActive={ isActive } itemUnique={ groupItem.stuffData.isUnique } itemUniqueNumber={ groupItem.stuffData.uniqueNumber } itemUnseen={ groupItem.hasUnseenItems } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent } />;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { MouseEventType } from 'nitro-renderer';
|
import { MouseEventType } from 'nitro-renderer';
|
||||||
import { FC, MouseEvent, useCallback, useState } from 'react';
|
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
|
||||||
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
|
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';
|
||||||
@ -37,8 +37,15 @@ export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, [ isActive, isMouseDown, petItem, dispatchPetState ]);
|
}, [ isActive, isMouseDown, petItem, dispatchPetState ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(!isActive) return;
|
||||||
|
|
||||||
|
petItem.isUnseen = false;
|
||||||
|
}, [ isActive, petItem ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
<NitroCardGridItemView itemActive={ isActive } itemUnseen={ petItem.isUnseen } onMouseDown={ onMouseEvent } onMouseUp={ onMouseEvent } onMouseOut={ onMouseEvent }>
|
||||||
<PetImageView figure={ petItem.petData.figureString } direction={ 3 } headOnly={ true } />
|
<PetImageView figure={ petItem.petData.figureString } direction={ 3 } headOnly={ true } />
|
||||||
</NitroCardGridItemView>
|
</NitroCardGridItemView>
|
||||||
);
|
);
|
||||||
|
@ -6,9 +6,8 @@ import { StartRoomSession } from '../../api/nitro/session/StartRoomSession';
|
|||||||
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 { RoomView } from '../room/RoomView';
|
import { RoomView } from '../room/RoomView';
|
||||||
import { RoomHostViewProps } from './RoomHostView.types';
|
|
||||||
|
|
||||||
export const RoomHostView: FC<RoomHostViewProps> = props =>
|
export const RoomHostView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
const [ roomSession, setRoomSession ] = useState<IRoomSession>(null);
|
||||||
|
|
||||||
|
@ -1,4 +0,0 @@
|
|||||||
export interface RoomHostViewProps
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -4,12 +4,14 @@ import { GetRoomEngine } from '../../api';
|
|||||||
import { UseMountEffect } from '../../hooks';
|
import { UseMountEffect } from '../../hooks';
|
||||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../hooks/events';
|
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../hooks/events';
|
||||||
import { useRoomContext } from './context/RoomContext';
|
import { useRoomContext } from './context/RoomContext';
|
||||||
|
import { RoomWidgetUpdateBackgroundColorPreviewEvent } from './events';
|
||||||
import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent';
|
import { RoomWidgetUpdateRoomViewEvent } from './events/RoomWidgetUpdateRoomViewEvent';
|
||||||
|
|
||||||
export const RoomColorView: FC<{}> = props =>
|
export const RoomColorView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ roomBackground, setRoomBackground ] = useState<NitroSprite>(null);
|
const [ roomBackground, setRoomBackground ] = useState<NitroSprite>(null);
|
||||||
const [ roomBackgroundColor, setRoomBackgroundColor ] = useState(0x000000);
|
const [ roomBackgroundColor, setRoomBackgroundColor ] = useState(0);
|
||||||
|
const [ originalRoomBackgroundColor, setOriginalRoomBackgroundColor ] = useState(0);
|
||||||
const [ roomFilter, setRoomFilter ] = useState<NitroAdjustmentFilter>(null);
|
const [ roomFilter, setRoomFilter ] = useState<NitroAdjustmentFilter>(null);
|
||||||
const [ roomFilterColor, setRoomFilterColor ] = useState(-1);
|
const [ roomFilterColor, setRoomFilterColor ] = useState(-1);
|
||||||
const { roomSession = null, canvasId = -1, eventDispatcher = null } = useRoomContext();
|
const { roomSession = null, canvasId = -1, eventDispatcher = null } = useRoomContext();
|
||||||
@ -37,20 +39,25 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
return background;
|
return background;
|
||||||
}, [ roomBackground, getRenderingCanvas ]);
|
}, [ roomBackground, getRenderingCanvas ]);
|
||||||
|
|
||||||
const updateRoomBackground = useCallback(() =>
|
const updateRoomBackground = useCallback((color: number) =>
|
||||||
{
|
{
|
||||||
const background = getRoomBackground();
|
const background = getRoomBackground();
|
||||||
|
|
||||||
if(!background) return;
|
if(!background) return;
|
||||||
|
|
||||||
background.tint = roomBackgroundColor;
|
if(color === undefined) color = 0x000000;
|
||||||
|
|
||||||
|
background.tint = color;
|
||||||
background.width = Nitro.instance.width;
|
background.width = Nitro.instance.width;
|
||||||
background.height = Nitro.instance.height;
|
background.height = Nitro.instance.height;
|
||||||
}, [ roomBackgroundColor, getRoomBackground ]);
|
}, [ getRoomBackground ]);
|
||||||
|
|
||||||
const updateRoomBackgroundColor = useCallback((hue: number, saturation: number, lightness: number) =>
|
const updateRoomBackgroundColor = useCallback((hue: number, saturation: number, lightness: number, original: boolean = false) =>
|
||||||
{
|
{
|
||||||
setRoomBackgroundColor(ColorConverter.hslToRGB(((((hue & 0xFF) << 16) + ((saturation & 0xFF) << 8)) + (lightness & 0xFF))));
|
const newColor = ColorConverter.hslToRGB(((((hue & 0xFF) << 16) + ((saturation & 0xFF) << 8)) + (lightness & 0xFF)));
|
||||||
|
|
||||||
|
setRoomBackgroundColor(newColor);
|
||||||
|
if(original) setOriginalRoomBackgroundColor(newColor);
|
||||||
|
|
||||||
const background = getRoomBackground();
|
const background = getRoomBackground();
|
||||||
|
|
||||||
@ -62,7 +69,7 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
updateRoomBackground();
|
updateRoomBackground(newColor);
|
||||||
|
|
||||||
background.visible = true;
|
background.visible = true;
|
||||||
}
|
}
|
||||||
@ -89,26 +96,27 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
return filter;
|
return filter;
|
||||||
}, [ roomFilter, getRenderingCanvas ]);
|
}, [ roomFilter, getRenderingCanvas ]);
|
||||||
|
|
||||||
const updateRoomFilter = useCallback(() =>
|
const updateRoomFilter = useCallback((color: number) =>
|
||||||
{
|
{
|
||||||
const colorMatrix = getRoomFilter();
|
const colorMatrix = getRoomFilter();
|
||||||
|
|
||||||
if(!colorMatrix) return;
|
if(!colorMatrix) return;
|
||||||
|
|
||||||
const r = ((roomFilterColor >> 16) & 0xFF);
|
const r = ((color >> 16) & 0xFF);
|
||||||
const g = ((roomFilterColor >> 8) & 0xFF);
|
const g = ((color >> 8) & 0xFF);
|
||||||
const b = (roomFilterColor & 0xFF);
|
const b = (color & 0xFF);
|
||||||
|
|
||||||
colorMatrix.red = (r / 255);
|
colorMatrix.red = (r / 255);
|
||||||
colorMatrix.green = (g / 255);
|
colorMatrix.green = (g / 255);
|
||||||
colorMatrix.blue = (b / 255);
|
colorMatrix.blue = (b / 255);
|
||||||
}, [ roomFilterColor, getRoomFilter ]);
|
}, [ getRoomFilter ]);
|
||||||
|
|
||||||
const updateRoomFilterColor = useCallback((color: number, brightness: number) =>
|
const updateRoomFilterColor = useCallback((color: number, brightness: number) =>
|
||||||
{
|
{
|
||||||
setRoomFilterColor(ColorConverter.hslToRGB(((ColorConverter.rgbToHSL(color) & 0xFFFF00) + brightness)));
|
const newColor = ColorConverter.hslToRGB(((ColorConverter.rgbToHSL(color) & 0xFFFF00) + brightness));
|
||||||
|
|
||||||
updateRoomFilter();
|
setRoomFilterColor(newColor);
|
||||||
|
updateRoomFilter(newColor);
|
||||||
}, [ updateRoomFilter ]);
|
}, [ updateRoomFilter ]);
|
||||||
|
|
||||||
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
const onRoomEngineEvent = useCallback((event: RoomEngineEvent) =>
|
||||||
@ -120,15 +128,15 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
case RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR: {
|
case RoomObjectHSLColorEnabledEvent.ROOM_BACKGROUND_COLOR: {
|
||||||
const hslColorEvent = (event as RoomObjectHSLColorEnabledEvent);
|
const hslColorEvent = (event as RoomObjectHSLColorEnabledEvent);
|
||||||
|
|
||||||
if(hslColorEvent.enable) updateRoomBackgroundColor(hslColorEvent.hue, hslColorEvent.saturation, hslColorEvent.lightness);
|
if(hslColorEvent.enable) updateRoomBackgroundColor(hslColorEvent.hue, hslColorEvent.saturation, hslColorEvent.lightness, true);
|
||||||
else updateRoomBackgroundColor(0, 0, 0);
|
else updateRoomBackgroundColor(0, 0, 0, true);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case RoomBackgroundColorEvent.ROOM_COLOR: {
|
case RoomBackgroundColorEvent.ROOM_COLOR: {
|
||||||
const colorEvent = (event as RoomBackgroundColorEvent);
|
const colorEvent = (event as RoomBackgroundColorEvent);
|
||||||
|
|
||||||
if(colorEvent.bgOnly) updateRoomFilterColor(0xFF0000, 0xFF);
|
if(colorEvent.bgOnly) updateRoomFilterColor(0x000000, 0xFF);
|
||||||
else updateRoomFilterColor(colorEvent.color, colorEvent.brightness);
|
else updateRoomFilterColor(colorEvent.color, colorEvent.brightness);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -141,11 +149,32 @@ export const RoomColorView: FC<{}> = props =>
|
|||||||
|
|
||||||
const onRoomWidgetUpdateRoomViewEvent = useCallback((event: RoomWidgetUpdateRoomViewEvent) =>
|
const onRoomWidgetUpdateRoomViewEvent = useCallback((event: RoomWidgetUpdateRoomViewEvent) =>
|
||||||
{
|
{
|
||||||
updateRoomBackground();
|
updateRoomBackground(roomBackgroundColor);
|
||||||
}, [ updateRoomBackground ]);
|
}, [ roomBackgroundColor, updateRoomBackground ]);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateRoomViewEvent.SIZE_CHANGED, eventDispatcher, onRoomWidgetUpdateRoomViewEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateRoomViewEvent.SIZE_CHANGED, eventDispatcher, onRoomWidgetUpdateRoomViewEvent);
|
||||||
|
|
||||||
|
const onRoomWidgetUpdateBackgroundColorPreviewEvent = useCallback((event: RoomWidgetUpdateBackgroundColorPreviewEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
case RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW: {
|
||||||
|
updateRoomBackgroundColor(event.hue, event.saturation, event.lightness);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
case RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW: {
|
||||||
|
const color = originalRoomBackgroundColor;
|
||||||
|
|
||||||
|
setRoomBackgroundColor(color);
|
||||||
|
updateRoomBackground(color);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ originalRoomBackgroundColor, updateRoomBackgroundColor, updateRoomBackground ]);
|
||||||
|
|
||||||
|
CreateEventDispatcherHook(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, eventDispatcher, onRoomWidgetUpdateBackgroundColorPreviewEvent);
|
||||||
|
CreateEventDispatcherHook(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW, eventDispatcher, onRoomWidgetUpdateBackgroundColorPreviewEvent);
|
||||||
|
|
||||||
UseMountEffect(updateRoomBackground);
|
UseMountEffect(updateRoomBackground);
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
|
@ -0,0 +1,35 @@
|
|||||||
|
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||||
|
|
||||||
|
export class RoomWidgetUpdateBackgroundColorPreviewEvent extends RoomWidgetUpdateEvent
|
||||||
|
{
|
||||||
|
public static PREVIEW = 'RWUBCPE_PREVIEW';
|
||||||
|
public static CLEAR_PREVIEW = 'RWUBCPE_CLEAR_PREVIEW';
|
||||||
|
|
||||||
|
private _hue: number;
|
||||||
|
private _saturation: number;
|
||||||
|
private _lightness: number;
|
||||||
|
|
||||||
|
constructor(type: string, hue: number = 0, saturation: number = 0, lightness: number = 0)
|
||||||
|
{
|
||||||
|
super(type);
|
||||||
|
|
||||||
|
this._hue = hue;
|
||||||
|
this._saturation = saturation;
|
||||||
|
this._lightness = lightness;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get hue(): number
|
||||||
|
{
|
||||||
|
return this._hue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get saturation(): number
|
||||||
|
{
|
||||||
|
return this._saturation;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get lightness(): number
|
||||||
|
{
|
||||||
|
return this._lightness;
|
||||||
|
}
|
||||||
|
}
|
@ -3,6 +3,7 @@ export * from './RoomWidgetFloodControlEvent';
|
|||||||
export * from './RoomWidgetObjectNameEvent';
|
export * from './RoomWidgetObjectNameEvent';
|
||||||
export * from './RoomWidgetRoomEngineUpdateEvent';
|
export * from './RoomWidgetRoomEngineUpdateEvent';
|
||||||
export * from './RoomWidgetRoomObjectUpdateEvent';
|
export * from './RoomWidgetRoomObjectUpdateEvent';
|
||||||
|
export * from './RoomWidgetUpdateBackgroundColorPreviewEvent';
|
||||||
export * from './RoomWidgetUpdateChatEvent';
|
export * from './RoomWidgetUpdateChatEvent';
|
||||||
export * from './RoomWidgetUpdateChatInputContentEvent';
|
export * from './RoomWidgetUpdateChatInputContentEvent';
|
||||||
export * from './RoomWidgetUpdateDanceStatusEvent';
|
export * from './RoomWidgetUpdateDanceStatusEvent';
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { RoomEngineDimmerStateEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomZoomEvent } from 'nitro-renderer';
|
import { RoomEngineDimmerStateEvent, RoomEngineEvent, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomEngineUseProductEvent, RoomId, RoomObjectCategory, RoomObjectOperationType, RoomSessionChatEvent, RoomSessionDanceEvent, RoomSessionDimmerPresetsEvent, RoomSessionDoorbellEvent, RoomSessionErrorMessageEvent, RoomSessionEvent, RoomSessionFriendRequestEvent, RoomSessionPetInfoUpdateEvent, RoomSessionPresentEvent, RoomSessionUserBadgesEvent, RoomZoomEvent } from 'nitro-renderer';
|
||||||
import { FC, useCallback } from 'react';
|
import { FC, useCallback } from 'react';
|
||||||
import { CanManipulateFurniture, GetRoomEngine, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation } from '../../../api';
|
import { CanManipulateFurniture, GetRoomEngine, IsFurnitureSelectionDisabled, ProcessRoomObjectOperation } from '../../../api';
|
||||||
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
|
import { useRoomEngineEvent, useRoomSessionManagerEvent } from '../../../hooks/events';
|
||||||
@ -119,6 +119,8 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
|||||||
break;
|
break;
|
||||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY:
|
||||||
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
case RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM:
|
||||||
|
case RoomEngineTriggerWidgetEvent.OPEN_WIDGET:
|
||||||
|
case RoomEngineTriggerWidgetEvent.CLOSE_WIDGET:
|
||||||
widgetHandler.processEvent(event);
|
widgetHandler.processEvent(event);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -145,6 +147,8 @@ export const RoomWidgetsView: FC<RoomWidgetViewProps> = props =>
|
|||||||
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineObjectEvent.MOUSE_LEAVE, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_INVENTORY, onRoomEngineObjectEvent);
|
||||||
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
useRoomEngineEvent(RoomEngineUseProductEvent.USE_PRODUCT_FROM_ROOM, onRoomEngineObjectEvent);
|
||||||
|
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_WIDGET, onRoomEngineObjectEvent);
|
||||||
|
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_WIDGET, onRoomEngineObjectEvent);
|
||||||
|
|
||||||
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
|
||||||
{
|
{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
|
import { IRoomCameraWidgetSelectedEffect } from 'nitro-renderer/src/nitro/camera/IRoomCameraWidgetSelectedEffect';
|
||||||
import { ProviderProps } from 'react';
|
import { ProviderProps } from 'react';
|
||||||
import { IRoomCameraWidgetSelectedEffect } from '../../../../../../../nitro-renderer/src/nitro/camera/IRoomCameraWidgetSelectedEffect';
|
|
||||||
|
|
||||||
export interface ICameraWidgetContext
|
export interface ICameraWidgetContext
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { FurnitureBackgroundColorView } from './background-color/FurnitureBackgroundColorView';
|
import { FurnitureBackgroundColorView } from './background-color/FurnitureBackgroundColorView';
|
||||||
import { FurnitureContextMenuView } from './context-menu/FurnitureContextMenuView';
|
import { FurnitureContextMenuView } from './context-menu/FurnitureContextMenuView';
|
||||||
|
import { FurnitureCustomStackHeightView } from './custom-stack-height/FurnitureCustomStackHeightView';
|
||||||
import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView';
|
import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView';
|
||||||
import { FurnitureExchangeCreditView } from './exchange-credit/FurnitureExchangeCreditView';
|
import { FurnitureExchangeCreditView } from './exchange-credit/FurnitureExchangeCreditView';
|
||||||
import { FurnitureFriendFurniView } from './friend-furni/FurnitureFriendFurniView';
|
import { FurnitureFriendFurniView } from './friend-furni/FurnitureFriendFurniView';
|
||||||
@ -17,6 +18,7 @@ export const FurnitureWidgetsView: FC<{}> = props =>
|
|||||||
<div className="position-absolute nitro-room-widgets t-0 l-0">
|
<div className="position-absolute nitro-room-widgets t-0 l-0">
|
||||||
<FurnitureBackgroundColorView />
|
<FurnitureBackgroundColorView />
|
||||||
<FurnitureContextMenuView />
|
<FurnitureContextMenuView />
|
||||||
|
<FurnitureCustomStackHeightView />
|
||||||
<FurnitureDimmerView />
|
<FurnitureDimmerView />
|
||||||
<FurnitureFriendFurniView />
|
<FurnitureFriendFurniView />
|
||||||
<FurnitureExchangeCreditView />
|
<FurnitureExchangeCreditView />
|
||||||
|
@ -1,21 +1,29 @@
|
|||||||
import { NitroEvent, RoomControllerLevel, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from 'nitro-renderer';
|
import { ApplyTonerComposer, RoomControllerLevel, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
|
import ReactSlider from 'react-slider';
|
||||||
import { GetRoomEngine, GetSessionDataManager } from '../../../../../api';
|
import { GetRoomEngine, GetSessionDataManager } from '../../../../../api';
|
||||||
|
import { SendMessageHook } from '../../../../../hooks';
|
||||||
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
|
import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events';
|
||||||
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||||
import { useRoomContext } from '../../../context/RoomContext';
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
import { RoomWidgetRoomObjectUpdateEvent } from '../../../events';
|
import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateBackgroundColorPreviewEvent } from '../../../events';
|
||||||
|
|
||||||
export const FurnitureBackgroundColorView: FC<{}> = props =>
|
export const FurnitureBackgroundColorView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const [ furniId, setFurniId ] = useState(-1);
|
|
||||||
const [ objectId, setObjectId ] = useState(-1);
|
const [ objectId, setObjectId ] = useState(-1);
|
||||||
const [ hue, setHue ] = useState(0);
|
const [ hue, setHue ] = useState(0);
|
||||||
const [ saturation, setSaturation ] = useState(0);
|
const [ saturation, setSaturation ] = useState(0);
|
||||||
const [ light, setLight ] = useState(0);
|
const [ lightness, setLightness ] = useState(0);
|
||||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
eventDispatcher.dispatchEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.CLEAR_PREVIEW));
|
||||||
|
|
||||||
|
setObjectId(-1);
|
||||||
|
}, [ eventDispatcher ]);
|
||||||
|
|
||||||
const canOpenBackgroundToner = useCallback(() =>
|
const canOpenBackgroundToner = useCallback(() =>
|
||||||
{
|
{
|
||||||
const isRoomOwner = roomSession.isRoomOwner;
|
const isRoomOwner = roomSession.isRoomOwner;
|
||||||
@ -25,49 +33,98 @@ export const FurnitureBackgroundColorView: FC<{}> = props =>
|
|||||||
return (isRoomOwner || hasLevel || isGodMode);
|
return (isRoomOwner || hasLevel || isGodMode);
|
||||||
}, [ roomSession ]);
|
}, [ roomSession ]);
|
||||||
|
|
||||||
const onNitroEvent = useCallback((event: NitroEvent) =>
|
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||||
{
|
{
|
||||||
switch(event.type)
|
switch(event.type)
|
||||||
{
|
{
|
||||||
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR: {
|
case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR: {
|
||||||
if(!canOpenBackgroundToner()) return;
|
if(!canOpenBackgroundToner()) return;
|
||||||
|
|
||||||
const roomEngineObjectEvent = (event as RoomEngineObjectEvent);
|
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
|
||||||
const roomObject = GetRoomEngine().getRoomObject(roomEngineObjectEvent.roomId, roomEngineObjectEvent.objectId, roomEngineObjectEvent.category);
|
|
||||||
const model = roomObject.model;
|
const model = roomObject.model;
|
||||||
|
|
||||||
setFurniId(roomObject.id);
|
setObjectId(roomObject.id);
|
||||||
setObjectId(roomObject.instanceId);
|
setHue(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
|
||||||
setHue(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE)));
|
setSaturation(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
|
||||||
setSaturation(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION)));
|
setLightness(parseInt(model.getValue<string>(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
|
||||||
setLight(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS)));
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||||
const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent);
|
if(objectId !== event.objectId) return;
|
||||||
|
|
||||||
setObjectId(prevValue =>
|
close();
|
||||||
{
|
|
||||||
if(prevValue === widgetEvent.id) return null;
|
|
||||||
|
|
||||||
return prevValue;
|
|
||||||
});
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [ canOpenBackgroundToner ]);
|
}, [ objectId, canOpenBackgroundToner, close ]);
|
||||||
|
|
||||||
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onNitroEvent);
|
useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onRoomEngineObjectEvent);
|
||||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent);
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomEngineObjectEvent);
|
||||||
|
|
||||||
|
const processAction = useCallback((name: string) =>
|
||||||
|
{
|
||||||
|
switch(name)
|
||||||
|
{
|
||||||
|
case 'apply':
|
||||||
|
SendMessageHook(new ApplyTonerComposer(objectId, hue, saturation, lightness));
|
||||||
|
break;
|
||||||
|
case 'toggle':
|
||||||
|
roomSession.useMultistateItem(objectId);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, [ roomSession, objectId, hue, saturation, lightness ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
if(objectId === -1) return;
|
||||||
|
|
||||||
|
eventDispatcher.dispatchEvent(new RoomWidgetUpdateBackgroundColorPreviewEvent(RoomWidgetUpdateBackgroundColorPreviewEvent.PREVIEW, hue, saturation, lightness));
|
||||||
|
}, [ eventDispatcher, objectId, hue, saturation, lightness ]);
|
||||||
|
|
||||||
if(objectId === -1) return null;
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<NitroCardView simple={ true }>
|
<NitroCardView>
|
||||||
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ event => setObjectId(-1) } />
|
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
||||||
<NitroCardContentView>
|
<NitroCardContentView>
|
||||||
background toner
|
<div className="form-group">
|
||||||
|
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.hue') }</label>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 360 }
|
||||||
|
value={ hue }
|
||||||
|
onChange={ event => setHue(event) }
|
||||||
|
thumbClassName={ 'thumb degree' }
|
||||||
|
renderThumb={ (props, state) => <div {...props}>{ state.valueNow }</div> } />
|
||||||
|
</div>
|
||||||
|
<div className="form-group">
|
||||||
|
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.saturation') }</label>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 100 }
|
||||||
|
value={ saturation }
|
||||||
|
onChange={ event => setSaturation(event) }
|
||||||
|
thumbClassName={ 'thumb percent' }
|
||||||
|
renderThumb={ (props, state) => <div {...props}>{ state.valueNow }</div> } />
|
||||||
|
</div>
|
||||||
|
<div className="form-group mb-2">
|
||||||
|
<label className="fw-bold text-black">{ LocalizeText('widget.backgroundcolor.lightness') }</label>
|
||||||
|
<ReactSlider
|
||||||
|
className={ 'nitro-slider' }
|
||||||
|
min={ 0 }
|
||||||
|
max={ 100 }
|
||||||
|
value={ lightness }
|
||||||
|
onChange={ event => setLightness(event) }
|
||||||
|
thumbClassName={ 'thumb percent' }
|
||||||
|
renderThumb={ (props, state) => <div {...props}>{ state.valueNow }</div> } />
|
||||||
|
</div>
|
||||||
|
<div className="d-flex form-group justify-content-between align-items-center">
|
||||||
|
<button type="button" className="btn btn-primary" onClick={ event => processAction('toggle') }>{ LocalizeText('widget.backgroundcolor.button.on') }</button>
|
||||||
|
<button type="button" className="btn btn-primary" onClick={ event => processAction('apply') }>{ LocalizeText('widget.backgroundcolor.button.apply') }</button>
|
||||||
|
</div>
|
||||||
</NitroCardContentView>
|
</NitroCardContentView>
|
||||||
</NitroCardView>
|
</NitroCardView>
|
||||||
);
|
);
|
||||||
|
@ -0,0 +1,49 @@
|
|||||||
|
import { RoomEngineObjectEvent } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { CreateEventDispatcherHook } from '../../../../../hooks/events';
|
||||||
|
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout';
|
||||||
|
import { LocalizeText } from '../../../../../utils/LocalizeText';
|
||||||
|
import { useRoomContext } from '../../../context/RoomContext';
|
||||||
|
import { RoomWidgetRoomObjectUpdateEvent } from '../../../events';
|
||||||
|
|
||||||
|
export const FurnitureCustomStackHeightView: FC<{}> = props =>
|
||||||
|
{
|
||||||
|
const [ objectId, setObjectId ] = useState(-1);
|
||||||
|
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
||||||
|
|
||||||
|
const close = useCallback(() =>
|
||||||
|
{
|
||||||
|
setObjectId(-1);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onRoomEngineObjectEvent = useCallback((event: RoomEngineObjectEvent) =>
|
||||||
|
{
|
||||||
|
switch(event.type)
|
||||||
|
{
|
||||||
|
// case RoomEngineTriggerWidgetEvent.REQUEST_CUSTOM_STACK_HEIGHT: {
|
||||||
|
// setObjectId(event.objectId);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: {
|
||||||
|
if(objectId !== event.objectId) return;
|
||||||
|
|
||||||
|
close();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ objectId, close ]);
|
||||||
|
|
||||||
|
//useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_CUSTOM_STACK_HEIGHT, onRoomEngineObjectEvent);
|
||||||
|
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onRoomEngineObjectEvent);
|
||||||
|
|
||||||
|
if(objectId === -1) return null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<NitroCardView>
|
||||||
|
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ close } />
|
||||||
|
<NitroCardContentView>
|
||||||
|
custom stack height
|
||||||
|
</NitroCardContentView>
|
||||||
|
</NitroCardView>
|
||||||
|
);
|
||||||
|
}
|
@ -3,14 +3,13 @@ import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispat
|
|||||||
import { useRoomContext } from '../../context/RoomContext';
|
import { useRoomContext } from '../../context/RoomContext';
|
||||||
import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events';
|
import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events';
|
||||||
import { RoomWidgetRoomObjectMessage } from '../../messages';
|
import { RoomWidgetRoomObjectMessage } from '../../messages';
|
||||||
import { InfoStandWidgetViewProps } from './InfoStandWidgetView.types';
|
|
||||||
import { InfoStandWidgetBotView } from './views/bot/InfoStandWidgetBotView';
|
import { InfoStandWidgetBotView } from './views/bot/InfoStandWidgetBotView';
|
||||||
import { InfoStandWidgetFurniView } from './views/furni/InfoStandWidgetFurniView';
|
import { InfoStandWidgetFurniView } from './views/furni/InfoStandWidgetFurniView';
|
||||||
import { InfoStandWidgetPetView } from './views/pet/InfoStandWidgetPetView';
|
import { InfoStandWidgetPetView } from './views/pet/InfoStandWidgetPetView';
|
||||||
import { InfoStandWidgetRentableBotView } from './views/rentable-bot/InfoStandWidgetRentableBotView';
|
import { InfoStandWidgetRentableBotView } from './views/rentable-bot/InfoStandWidgetRentableBotView';
|
||||||
import { InfoStandWidgetUserView } from './views/user/InfoStandWidgetUserView';
|
import { InfoStandWidgetUserView } from './views/user/InfoStandWidgetUserView';
|
||||||
|
|
||||||
export const InfoStandWidgetView: FC<InfoStandWidgetViewProps> = props =>
|
export const InfoStandWidgetView: FC<{}> = props =>
|
||||||
{
|
{
|
||||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||||
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
|
const [ infoStandEvent, setInfoStandEvent ] = useState<RoomWidgetUpdateInfostandEvent>(null);
|
||||||
|
@ -1,6 +0,0 @@
|
|||||||
import { RoomWidgetProps } from '../RoomWidgets.types';
|
|
||||||
|
|
||||||
export interface InfoStandWidgetViewProps extends RoomWidgetProps
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from 'nitro-renderer';
|
import { IGetImageListener, ImageResult, TextureUtils, Vector3d } from 'nitro-renderer';
|
||||||
import { RenderTexture } from 'pixi.js';
|
|
||||||
import { FC, useCallback, useEffect, useState } from 'react';
|
import { FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { GetRoomEngine } from '../../../api';
|
import { GetRoomEngine } from '../../../api';
|
||||||
import { ProductTypeEnum } from '../../catalog/common/ProductTypeEnum';
|
import { ProductTypeEnum } from '../../catalog/common/ProductTypeEnum';
|
||||||
@ -17,7 +16,7 @@ export const FurniImageView: FC<FurniImageViewProps> = props =>
|
|||||||
const furniType = type.toLocaleLowerCase();
|
const furniType = type.toLocaleLowerCase();
|
||||||
|
|
||||||
const listener: IGetImageListener = {
|
const listener: IGetImageListener = {
|
||||||
imageReady: (id: number, texture: RenderTexture, image: HTMLImageElement) =>
|
imageReady: (id, texture, image) =>
|
||||||
{
|
{
|
||||||
if(!image && texture)
|
if(!image && texture)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { ColorConverter, IRoomRenderingCanvas, Nitro } from 'nitro-renderer';
|
import { ColorConverter, IRoomRenderingCanvas, Nitro, TextureUtils } from 'nitro-renderer';
|
||||||
import { createRef, FC, useCallback, useEffect, useState } from 'react';
|
import { createRef, FC, useCallback, useEffect, useState } from 'react';
|
||||||
import { RoomPreviewerViewProps } from './RoomPreviewerView.types';
|
import { RoomPreviewerViewProps } from './RoomPreviewerView.types';
|
||||||
|
|
||||||
@ -18,7 +18,7 @@ export const RoomPreviewerView: FC<RoomPreviewerViewProps> = props =>
|
|||||||
|
|
||||||
if(!renderingCanvas.canvasUpdated) return;
|
if(!renderingCanvas.canvasUpdated) return;
|
||||||
|
|
||||||
elementRef.current.style.backgroundImage = `url(${ Nitro.instance.renderer.extract.base64(renderingCanvas.master) })`;
|
elementRef.current.style.backgroundImage = `url(${ TextureUtils.generateImageUrl(renderingCanvas.master) })`;
|
||||||
}, [ roomPreviewer, renderingCanvas, elementRef ]);
|
}, [ roomPreviewer, renderingCanvas, elementRef ]);
|
||||||
|
|
||||||
const setupPreviewer = useCallback(() =>
|
const setupPreviewer = useCallback(() =>
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
box-shadow: inset 0px 5px lighten(rgba($dark,.6),2.5), inset 0 -4px darken(rgba($dark,.6),4);
|
||||||
|
|
||||||
#toolbar-chat-input-container {
|
#toolbar-chat-input-container {
|
||||||
margin-left: 25px;
|
margin: 0 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.navigation-items {
|
.navigation-items {
|
||||||
@ -31,6 +31,7 @@
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
width: 50px;
|
width: 50px;
|
||||||
margin: 0 1px;
|
margin: 0 1px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
.toolbar-avatar {
|
.toolbar-avatar {
|
||||||
height: 50px;
|
height: 50px;
|
||||||
@ -47,6 +48,7 @@
|
|||||||
|
|
||||||
.icon,
|
.icon,
|
||||||
.toolbar-avatar {
|
.toolbar-avatar {
|
||||||
|
position: relative;
|
||||||
transition: transform .2s ease-out;
|
transition: transform .2s ease-out;
|
||||||
|
|
||||||
&:hover, &.active {
|
&:hover, &.active {
|
||||||
@ -119,6 +121,7 @@
|
|||||||
max-width: 120px;
|
max-width: 120px;
|
||||||
max-height: 150px;
|
max-height: 150px;
|
||||||
z-index: 500;
|
z-index: 500;
|
||||||
|
filter: drop-shadow(2px 1px 0 rgba($white, 1)) drop-shadow(-2px 1px 0 rgba($white, 1)) drop-shadow(0 -2px 0 rgba($white, 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@import './me/ToolbarMeView';
|
@import './me/ToolbarMeView';
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
|
import { Dispose, DropBounce, EaseOut, JumpBy, Motions, NitroToolbarAnimateIconEvent, Queue, Wait } from 'nitro-renderer';
|
||||||
import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent';
|
import { UserInfoEvent } from 'nitro-renderer/src/nitro/communication/messages/incoming/user/data/UserInfoEvent';
|
||||||
import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser';
|
import { UserInfoDataParser } from 'nitro-renderer/src/nitro/communication/messages/parser/user/data/UserInfoDataParser';
|
||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent } from '../../events';
|
import { AvatarEditorEvent, CatalogEvent, FriendListEvent, InventoryEvent, NavigatorEvent, RoomWidgetCameraEvent, UnseenItemTrackerUpdateEvent } from '../../events';
|
||||||
import { dispatchUiEvent } from '../../hooks/events/ui/ui-event';
|
import { useRoomEngineEvent } from '../../hooks';
|
||||||
|
import { dispatchUiEvent, useUiEvent } from '../../hooks/events/ui/ui-event';
|
||||||
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
import { CreateMessageHook } from '../../hooks/messages/message-event';
|
||||||
import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation';
|
import { TransitionAnimation } from '../../layout/transitions/TransitionAnimation';
|
||||||
import { TransitionAnimationTypes } from '../../layout/transitions/TransitionAnimation.types';
|
import { TransitionAnimationTypes } from '../../layout/transitions/TransitionAnimation.types';
|
||||||
@ -16,8 +18,8 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
|
|
||||||
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
const [ userInfo, setUserInfo ] = useState<UserInfoDataParser>(null);
|
||||||
const [ isMeExpanded, setMeExpanded ] = useState(false);
|
const [ isMeExpanded, setMeExpanded ] = useState(false);
|
||||||
|
const [ unseenInventoryCount, setUnseenInventoryCount ] = useState(0);
|
||||||
|
|
||||||
const unseenInventoryCount = 0;
|
|
||||||
const unseenFriendListCount = 0;
|
const unseenFriendListCount = 0;
|
||||||
const unseenAchievementsCount = 0;
|
const unseenAchievementsCount = 0;
|
||||||
|
|
||||||
@ -28,6 +30,56 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
setUserInfo(parser.userInfo);
|
setUserInfo(parser.userInfo);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
CreateMessageHook(UserInfoEvent, onUserInfoEvent);
|
||||||
|
|
||||||
|
const onUnseenItemTrackerUpdateEvent = useCallback((event: UnseenItemTrackerUpdateEvent) =>
|
||||||
|
{
|
||||||
|
setUnseenInventoryCount(event.count);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
useUiEvent(UnseenItemTrackerUpdateEvent.UPDATE_COUNT, onUnseenItemTrackerUpdateEvent);
|
||||||
|
|
||||||
|
const animationIconToToolbar = useCallback((iconName: string, image: HTMLImageElement, x: number, y: number) =>
|
||||||
|
{
|
||||||
|
const target = (document.body.getElementsByClassName(iconName)[0] as HTMLElement);
|
||||||
|
|
||||||
|
if(!target) return;
|
||||||
|
|
||||||
|
image.className = 'toolbar-icon-animation';
|
||||||
|
image.style.visibility = 'visible';
|
||||||
|
image.style.left = (x + 'px');
|
||||||
|
image.style.top = (y + 'px');
|
||||||
|
|
||||||
|
document.body.append(image);
|
||||||
|
|
||||||
|
const targetBounds = target.getBoundingClientRect();
|
||||||
|
const imageBounds = image.getBoundingClientRect();
|
||||||
|
|
||||||
|
const left = (imageBounds.x - targetBounds.x);
|
||||||
|
const top = (imageBounds.y - targetBounds.y);
|
||||||
|
const squared = Math.sqrt(((left * left) + (top * top)));
|
||||||
|
const wait = (500 - Math.abs(((((1 / squared) * 100) * 500) * 0.5)));
|
||||||
|
const height = 20;
|
||||||
|
|
||||||
|
const motionName = (`ToolbarBouncing[${ iconName }]`);
|
||||||
|
|
||||||
|
if(!Motions.getMotionByTag(motionName))
|
||||||
|
{
|
||||||
|
Motions.runMotion(new Queue(new Wait((wait + 8)), new DropBounce(target, 400, 12))).tag = motionName;
|
||||||
|
}
|
||||||
|
|
||||||
|
const motion = new Queue(new EaseOut(new JumpBy(image, wait, ((targetBounds.x - imageBounds.x) + height), (targetBounds.y - imageBounds.y), 100, 1), 1), new Dispose(image));
|
||||||
|
|
||||||
|
Motions.runMotion(motion);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const onNitroToolbarAnimateIconEvent = useCallback((event: NitroToolbarAnimateIconEvent) =>
|
||||||
|
{
|
||||||
|
animationIconToToolbar('icon-inventory', event.image, event.x, event.y);
|
||||||
|
}, [ animationIconToToolbar ]);
|
||||||
|
|
||||||
|
useRoomEngineEvent(NitroToolbarAnimateIconEvent.ANIMATE_ICON, onNitroToolbarAnimateIconEvent);
|
||||||
|
|
||||||
const handleToolbarItemClick = useCallback((item: string) =>
|
const handleToolbarItemClick = useCallback((item: string) =>
|
||||||
{
|
{
|
||||||
switch(item)
|
switch(item)
|
||||||
@ -54,8 +106,6 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
CreateMessageHook(UserInfoEvent, onUserInfoEvent);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="nitro-toolbar-container">
|
<div className="nitro-toolbar-container">
|
||||||
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }>
|
<TransitionAnimation type={ TransitionAnimationTypes.FADE_IN } inProp={ isMeExpanded } timeout={ 300 }>
|
||||||
|
Loading…
Reference in New Issue
Block a user