Inventory changes

This commit is contained in:
Bill 2021-12-09 00:37:19 -05:00
parent 2c8f6ac0c1
commit 3e4f313f07
39 changed files with 356 additions and 485 deletions

View File

@ -10,7 +10,6 @@ import { mergePetFragments } from './common/PetUtilities';
import { TradeState } from './common/TradeState'; import { TradeState } from './common/TradeState';
import { TradeUserData } from './common/TradeUserData'; import { TradeUserData } from './common/TradeUserData';
import { useInventoryContext } from './context/InventoryContext'; import { useInventoryContext } from './context/InventoryContext';
import { InventoryMessageHandlerProps } from './InventoryMessageHandler.types';
import { InventoryBadgeActions } from './reducers/InventoryBadgeReducer'; import { InventoryBadgeActions } from './reducers/InventoryBadgeReducer';
import { InventoryBotActions } from './reducers/InventoryBotReducer'; import { InventoryBotActions } from './reducers/InventoryBotReducer';
import { InventoryFurnitureActions } from './reducers/InventoryFurnitureReducer'; import { InventoryFurnitureActions } from './reducers/InventoryFurnitureReducer';
@ -18,7 +17,7 @@ import { InventoryPetActions } from './reducers/InventoryPetReducer';
let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null; let furniMsgFragments: Map<number, FurnitureListItemParser>[] = null;
let petMsgFragments: Map<number, PetData>[] = null; let petMsgFragments: Map<number, PetData>[] = null;
export const InventoryMessageHandler: FC<InventoryMessageHandlerProps> = props => export const InventoryMessageHandler: FC<{}> = props =>
{ {
const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, badgeState = null, dispatchBadgeState = null, unseenTracker = null } = useInventoryContext(); const { dispatchFurnitureState = null, dispatchBotState = null, dispatchPetState = null, badgeState = null, dispatchBadgeState = null, unseenTracker = null } = useInventoryContext();

View File

@ -1,3 +0,0 @@
export interface InventoryMessageHandlerProps
{
}

View File

@ -14,7 +14,6 @@ import { UnseenItemCategory } from './common/unseen/UnseenItemCategory';
import { UnseenItemTracker } from './common/unseen/UnseenItemTracker'; 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 { initialInventoryBadge, InventoryBadgeReducer } from './reducers/InventoryBadgeReducer'; import { initialInventoryBadge, InventoryBadgeReducer } from './reducers/InventoryBadgeReducer';
import { initialInventoryBot, InventoryBotReducer } from './reducers/InventoryBotReducer'; import { initialInventoryBot, InventoryBotReducer } from './reducers/InventoryBotReducer';
import { initialInventoryFurniture, InventoryFurnitureReducer } from './reducers/InventoryFurnitureReducer'; import { initialInventoryFurniture, InventoryFurnitureReducer } from './reducers/InventoryFurnitureReducer';
@ -25,10 +24,14 @@ 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 TAB_FURNITURE: string = 'inventory.furni';
const TAB_BOTS: string = 'inventory.bots';
const TAB_PETS: string = 'inventory.furni.tab.pets';
const TAB_BADGES: string = 'inventory.badges';
const TABS = [ TAB_FURNITURE, TAB_BOTS, TAB_PETS, TAB_BADGES ];
const UNSEEN_CATEGORIES = [ UnseenItemCategory.FURNI, UnseenItemCategory.BOT, UnseenItemCategory.PET, UnseenItemCategory.BADGE ]; const UNSEEN_CATEGORIES = [ UnseenItemCategory.FURNI, UnseenItemCategory.BOT, UnseenItemCategory.PET, UnseenItemCategory.BADGE ];
export const InventoryView: FC<InventoryViewProps> = props => export const InventoryView: FC<{}> = 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]);
@ -213,13 +216,13 @@ export const InventoryView: FC<InventoryViewProps> = props =>
}) } }) }
</NitroCardTabsView> </NitroCardTabsView>
<NitroCardContentView> <NitroCardContentView>
{ (currentTab === InventoryTabs.FURNITURE ) && { (currentTab === TAB_FURNITURE ) &&
<InventoryFurnitureView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> } <InventoryFurnitureView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
{ (currentTab === InventoryTabs.BOTS ) && { (currentTab === TAB_BOTS ) &&
<InventoryBotView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> } <InventoryBotView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
{ (currentTab === InventoryTabs.PETS ) && { (currentTab === TAB_PETS ) &&
<InventoryPetView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> } <InventoryPetView roomSession={ roomSession } roomPreviewer={ roomPreviewer } /> }
{ (currentTab === InventoryTabs.BADGES ) && { (currentTab === TAB_BADGES ) &&
<InventoryBadgeView /> } <InventoryBadgeView /> }
</NitroCardContentView> </NitroCardContentView>
</> } </> }

View File

@ -1,10 +0,0 @@
export interface InventoryViewProps
{}
export class InventoryTabs
{
public static readonly FURNITURE: string = 'inventory.furni';
public static readonly BOTS: string = 'inventory.bots';
public static readonly PETS: string = 'inventory.furni.tab.pets';
public static readonly BADGES: string = 'inventory.badges';
}

View File

@ -1,5 +1,23 @@
import { createContext, FC, useContext } from 'react'; import { createContext, Dispatch, FC, ProviderProps, useContext } from 'react';
import { IInventoryContext, InventoryContextProps } from './InventoryContext.types'; import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
import { IInventoryBadgeAction, IInventoryBadgeState } from '../reducers/InventoryBadgeReducer';
import { IInventoryBotAction, IInventoryBotState } from '../reducers/InventoryBotReducer';
import { IInventoryFurnitureAction, IInventoryFurnitureState } from '../reducers/InventoryFurnitureReducer';
import { IInventoryPetAction, IInventoryPetState } from '../reducers/InventoryPetReducer';
export interface IInventoryContext
{
furnitureState: IInventoryFurnitureState;
dispatchFurnitureState: Dispatch<IInventoryFurnitureAction>;
botState: IInventoryBotState;
dispatchBotState: Dispatch<IInventoryBotAction>;
petState: IInventoryPetState;
dispatchPetState: Dispatch<IInventoryPetAction>;
badgeState: IInventoryBadgeState;
dispatchBadgeState: Dispatch<IInventoryBadgeAction>;
unseenTracker: IUnseenItemTracker;
}
const InventoryContext = createContext<IInventoryContext>({ const InventoryContext = createContext<IInventoryContext>({
furnitureState: null, furnitureState: null,
@ -13,7 +31,7 @@ const InventoryContext = createContext<IInventoryContext>({
unseenTracker: null unseenTracker: null
}); });
export const InventoryContextProvider: FC<InventoryContextProps> = props => export const InventoryContextProvider: FC<ProviderProps<IInventoryContext>> = props =>
{ {
return <InventoryContext.Provider value={ props.value }>{ props.children }</InventoryContext.Provider> return <InventoryContext.Provider value={ props.value }>{ props.children }</InventoryContext.Provider>
} }

View File

@ -1,24 +0,0 @@
import { Dispatch, ProviderProps } from 'react';
import { IUnseenItemTracker } from '../common/unseen/IUnseenItemTracker';
import { IInventoryBadgeAction, IInventoryBadgeState } from '../reducers/InventoryBadgeReducer';
import { IInventoryBotAction, IInventoryBotState } from '../reducers/InventoryBotReducer';
import { IInventoryFurnitureAction, IInventoryFurnitureState } from '../reducers/InventoryFurnitureReducer';
import { IInventoryPetAction, IInventoryPetState } from '../reducers/InventoryPetReducer';
export interface IInventoryContext
{
furnitureState: IInventoryFurnitureState;
dispatchFurnitureState: Dispatch<IInventoryFurnitureAction>;
botState: IInventoryBotState;
dispatchBotState: Dispatch<IInventoryBotAction>;
petState: IInventoryPetState;
dispatchPetState: Dispatch<IInventoryPetAction>;
badgeState: IInventoryBadgeState;
dispatchBadgeState: Dispatch<IInventoryBadgeAction>;
unseenTracker: IUnseenItemTracker;
}
export interface InventoryContextProps extends ProviderProps<IInventoryContext>
{
}

View File

@ -0,0 +1,35 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback } from 'react';
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer';
export interface InventoryBadgeItemViewProps
{
badgeCode: string;
}
export const InventoryBadgeItemView: FC<InventoryBadgeItemViewProps> = props =>
{
const { badgeCode = null } = props;
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
const onMouseEvent = useCallback((event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
dispatchBadgeState({
type: InventoryBadgeActions.SET_BADGE,
payload: { badgeCode }
});
}
}, [ badgeCode, dispatchBadgeState ]);
return (
<NitroCardGridItemView itemActive={ (badgeState.badge === badgeCode) } onMouseDown={ onMouseEvent }>
<BadgeImageView badgeCode={ badgeCode } />
</NitroCardGridItemView>
);
}

View File

@ -1,18 +1,20 @@
import { RequestBadgesComposer } from '@nitrots/nitro-renderer'; import { RequestBadgesComposer } from '@nitrots/nitro-renderer';
import { FC, useEffect } from 'react'; import { FC, useEffect } from 'react';
import { LocalizeBadgeName, LocalizeText } from '../../../../api'; import { LocalizeBadgeName, LocalizeText } from '../../../../api';
import { Button } from '../../../../common/Button';
import { Column } from '../../../../common/Column';
import { Flex } from '../../../../common/Flex';
import { Grid } from '../../../../common/Grid';
import { Text } from '../../../../common/Text';
import { SendMessageHook } from '../../../../hooks/messages/message-event'; import { SendMessageHook } from '../../../../hooks/messages/message-event';
import { NitroLayoutButton, NitroLayoutFlex } from '../../../../layout';
import { NitroLayoutBase } from '../../../../layout/base';
import { NitroLayoutFlexColumn } from '../../../../layout/flex-column/NitroLayoutFlexColumn';
import { NitroLayoutGridColumn } from '../../../../layout/grid/column/NitroLayoutGridColumn';
import { NitroLayoutGrid } from '../../../../layout/grid/NitroLayoutGrid';
import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView'; import { BadgeImageView } from '../../../shared/badge-image/BadgeImageView';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer'; import { InventoryBadgeActions } from '../../reducers/InventoryBadgeReducer';
import { InventoryActiveBadgeResultsView } from './active-results/InventoryActiveBadgeResultsView'; import { InventoryBadgeItemView } from './InventoryBadgeItemView';
import { InventoryBadgeViewProps } from './InventoryBadgeView.types';
import { InventoryBadgeResultsView } from './results/InventoryBadgeResultsView'; export interface InventoryBadgeViewProps
{
}
export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props => export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
{ {
@ -79,26 +81,33 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
} }
return ( return (
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn size={ 7 }> <Column size={ 7 } overflow="hidden">
<InventoryBadgeResultsView badges={ badges } activeBadges={ activeBadges } /> <Grid grow columnCount={ 5 } overflow="auto">
</NitroLayoutGridColumn> { badges && (badges.length > 0) && badges.map((code, index) =>
<NitroLayoutGridColumn className="justify-content-between" size={ 5 } overflow="auto"> {
<NitroLayoutFlexColumn overflow="hidden" gap={ 2 }> if(activeBadges.indexOf(code) >= 0) return null;
<NitroLayoutBase className="text-black text-truncate flex-shrink-0">{ LocalizeText('inventory.badges.activebadges') }</NitroLayoutBase>
<InventoryActiveBadgeResultsView badges={ activeBadges } /> return <InventoryBadgeItemView key={ code } badgeCode={ code } />
</NitroLayoutFlexColumn> }) }
</Grid>
</Column>
<Column className="justify-content-between" size={ 5 } overflow="auto">
<Column overflow="hidden" gap={ 2 }>
<Text>{ LocalizeText('inventory.badges.activebadges') }</Text>
<Grid grow columnCount={ 3 } overflow="auto">
{ activeBadges && (activeBadges.length > 0) && activeBadges.map((code, index) => <InventoryBadgeItemView key={ code } badgeCode={ code } />) }
</Grid>
</Column>
{ badge && (badge.length > 0) && { badge && (badge.length > 0) &&
<NitroLayoutFlexColumn gap={ 2 }> <Column grow justifyContent="end" gap={ 2 }>
<NitroLayoutFlex className="justify-content-between align-items-center"> <Flex alignItems="center" gap={ 2 }>
<NitroLayoutFlex className="flex-grow-1 align-items-center" gap={ 2 } overflow="hidden"> <BadgeImageView badgeCode={ badge } />
<BadgeImageView badgeCode={ badge } /> <Text>{ LocalizeBadgeName(badge) }</Text>
<NitroLayoutBase className="flex-grow-1 text-black text-truncate">{ LocalizeBadgeName(badge) }</NitroLayoutBase> </Flex>
</NitroLayoutFlex> <Button variant={ (isWearingBadge(badge) ? 'danger' : 'success') } size="sm" disabled={ !isWearingBadge(badge) && !canWearBadges() } onClick={ toggleBadge }>{ LocalizeText(isWearingBadge(badge) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }</Button>
</NitroLayoutFlex> </Column> }
<NitroLayoutButton variant={ (isWearingBadge(badge) ? 'danger' : 'success') } size="sm" disabled={ !isWearingBadge(badge) && !canWearBadges() } onClick={ toggleBadge }>{ LocalizeText(isWearingBadge(badge) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }</NitroLayoutButton> </Column>
</NitroLayoutFlexColumn> } </Grid>
</NitroLayoutGridColumn>
</NitroLayoutGrid>
); );
} }

View File

@ -1,3 +0,0 @@
export interface InventoryBadgeViewProps
{
}

View File

@ -1,18 +0,0 @@
import { FC } from 'react';
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
import { InventoryActiveBadgeResultsViewProps } from './InventoryActiveBadgeResultsView.types';
export const InventoryActiveBadgeResultsView: FC<InventoryActiveBadgeResultsViewProps> = props =>
{
const { badges = [] } = props;
return (
<NitroCardGridView>
{ badges && (badges.length > 0) && badges.map(code =>
{
return <InventoryBadgeItemView key={ code } badge={ code } />
}) }
</NitroCardGridView>
);
}

View File

@ -1,4 +0,0 @@
export interface InventoryActiveBadgeResultsViewProps
{
badges?: string[];
}

View File

@ -1,32 +0,0 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback } from 'react';
import { NitroCardGridItemView } from '../../../../../layout/card/grid/item/NitroCardGridItemView';
import { BadgeImageView } from '../../../../shared/badge-image/BadgeImageView';
import { useInventoryContext } from '../../../context/InventoryContext';
import { InventoryBadgeActions } from '../../../reducers/InventoryBadgeReducer';
import { InventoryBadgeItemViewProps } from './InventoryBadgeItemView.types';
export const InventoryBadgeItemView: FC<InventoryBadgeItemViewProps> = props =>
{
const { badge } = props;
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
const isActive = (badgeState.badge === badge);
const onMouseEvent = useCallback((event: MouseEvent) =>
{
switch(event.type)
{
case MouseEventType.MOUSE_DOWN:
dispatchBadgeState({
type: InventoryBadgeActions.SET_BADGE,
payload: { badgeCode: badge }
});
}
}, [ badge, dispatchBadgeState ]);
return (
<NitroCardGridItemView itemActive={ isActive } onMouseDown={ onMouseEvent }>
<BadgeImageView badgeCode={ badge } />
</NitroCardGridItemView>
);
}

View File

@ -1,4 +0,0 @@
export interface InventoryBadgeItemViewProps
{
badge: string;
}

View File

@ -1,20 +0,0 @@
import { FC } from 'react';
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
import { InventoryBadgeItemView } from '../item/InventoryBadgeItemView';
import { InventoryBadgeResultsViewProps } from './InventoryBadgeResultsView.types';
export const InventoryBadgeResultsView: FC<InventoryBadgeResultsViewProps> = props =>
{
const { badges = [], activeBadges = [] } = props;
return (
<NitroCardGridView>
{ badges && (badges.length > 0) && badges.map(code =>
{
if(activeBadges.indexOf(code) >= 0) return null;
return <InventoryBadgeItemView key={ code } badge={ code } />
}) }
</NitroCardGridView>
);
}

View File

@ -1,5 +0,0 @@
export interface InventoryBadgeResultsViewProps
{
badges: string[];
activeBadges: string[];
}

View File

@ -1,11 +1,16 @@
import { MouseEventType } from '@nitrots/nitro-renderer'; import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, 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 { BotItem } from '../../common/BotItem';
import { useInventoryContext } from '../../../context/InventoryContext'; import { attemptBotPlacement } from '../../common/BotUtilities';
import { InventoryBotActions } from '../../../reducers/InventoryBotReducer'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryBotItemViewProps } from './InventoryBotItemView.types'; import { InventoryBotActions } from '../../reducers/InventoryBotReducer';
export interface InventoryBotItemViewProps
{
botItem: BotItem;
}
export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props => export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props =>
{ {

View File

@ -1,19 +1,23 @@
import { GetBotInventoryComposer, RoomObjectVariable } from '@nitrots/nitro-renderer'; import { GetBotInventoryComposer, IRoomSession, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, useEffect } from 'react'; import { FC, useEffect } from 'react';
import { GetRoomEngine, LocalizeText } from '../../../../api'; import { GetRoomEngine, LocalizeText } from '../../../../api';
import { Button } from '../../../../common/Button';
import { Column } from '../../../../common/Column';
import { Grid } from '../../../../common/Grid';
import { Text } from '../../../../common/Text';
import { SendMessageHook } from '../../../../hooks/messages/message-event'; import { SendMessageHook } from '../../../../hooks/messages/message-event';
import { NitroLayoutButton } from '../../../../layout';
import { NitroLayoutBase } from '../../../../layout/base';
import { NitroLayoutFlexColumn } from '../../../../layout/flex-column/NitroLayoutFlexColumn';
import { NitroLayoutGridColumn } from '../../../../layout/grid/column/NitroLayoutGridColumn';
import { NitroLayoutGrid } from '../../../../layout/grid/NitroLayoutGrid';
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView'; import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
import { attemptBotPlacement } from '../../common/BotUtilities'; import { attemptBotPlacement } from '../../common/BotUtilities';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryBotActions } from '../../reducers/InventoryBotReducer'; import { InventoryBotActions } from '../../reducers/InventoryBotReducer';
import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView';
import { InventoryBotViewProps } from './InventoryBotView.types'; import { InventoryBotItemView } from './InventoryBotItemView';
import { InventoryBotResultsView } from './results/InventoryBotResultsView';
export interface InventoryBotViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}
export const InventoryBotView: FC<InventoryBotViewProps> = props => export const InventoryBotView: FC<InventoryBotViewProps> = props =>
{ {
@ -54,13 +58,13 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
const roomEngine = GetRoomEngine(); const roomEngine = GetRoomEngine();
let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
wallType = (wallType && wallType.length) ? wallType : '101'; wallType = (wallType && wallType.length) ? wallType : '101';
floorType = (floorType && floorType.length) ? floorType : '101'; floorType = (floorType && floorType.length) ? floorType : '101';
landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1';
roomPreviewer.reset(false); roomPreviewer.reset(false);
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
@ -71,23 +75,25 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
if(!botItems || !botItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.bots.title') } desc={ LocalizeText('inventory.empty.bots.desc') } />; if(!botItems || !botItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.bots.title') } desc={ LocalizeText('inventory.empty.bots.desc') } />;
return ( return (
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn size={ 7 }> <Column size={ 7 } overflow="hidden">
<InventoryBotResultsView botItems={ botItems } /> <Grid grow columnCount={ 5 } overflow="auto">
</NitroLayoutGridColumn> { botItems && (botItems.length > 0) && botItems.map(item => <InventoryBotItemView key={ item.id } botItem={ item } />) }
<NitroLayoutGridColumn size={ 5 } overflow="auto"> </Grid>
<NitroLayoutFlexColumn overflow="hidden" position="relative"> </Column>
<Column size={ 5 } overflow="auto">
<Column overflow="hidden" position="relative">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
</NitroLayoutFlexColumn> </Column>
{ botItem && { botItem &&
<NitroLayoutFlexColumn className="flex-grow-1" gap={ 2 }> <Column grow justifyContent="between" gap={ 2 }>
<NitroLayoutBase className="flex-grow-1 text-black text-truncate">{ botItem.botData.name }</NitroLayoutBase> <Text>{ botItem.botData.name }</Text>
{ !!roomSession && { !!roomSession &&
<NitroLayoutButton variant="success" size="sm" onClick={ event => attemptBotPlacement(botItem) }> <Button variant="success" size="sm" onClick={ event => attemptBotPlacement(botItem) }>
{ LocalizeText('inventory.furni.placetoroom') } { LocalizeText('inventory.furni.placetoroom') }
</NitroLayoutButton> } </Button> }
</NitroLayoutFlexColumn> } </Column> }
</NitroLayoutGridColumn> </Column>
</NitroLayoutGrid> </Grid>
); );
} }

View File

@ -1,7 +0,0 @@
import { IRoomSession, RoomPreviewer } from '@nitrots/nitro-renderer';
export interface InventoryBotViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}

View File

@ -1,6 +0,0 @@
import { BotItem } from '../../../common/BotItem';
export interface InventoryBotItemViewProps
{
botItem: BotItem;
}

View File

@ -1,18 +0,0 @@
import { FC } from 'react';
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
import { InventoryBotItemView } from '../item/InventoryBotItemView';
import { InventoryBotResultsViewProps } from './InventoryBotResultsView.types';
export const InventoryBotResultsView: FC<InventoryBotResultsViewProps> = props =>
{
const { botItems = [] } = props;
return (
<NitroCardGridView>
{ botItems && (botItems.length > 0) && botItems.map(item =>
{
return <InventoryBotItemView key={ item.id } botItem={ item } />
}) }
</NitroCardGridView>
);
}

View File

@ -1,6 +0,0 @@
import { BotItem } from '../../../common/BotItem';
export interface InventoryBotResultsViewProps
{
botItems: BotItem[];
}

View File

@ -1,21 +1,28 @@
import { FC } from 'react'; import { FC } from 'react';
import { NitroLayoutGrid, NitroLayoutGridColumn } from '../../../../layout'; import { Column } from '../../../../common/Column';
import { NitroLayoutBase } from '../../../../layout/base'; import { Grid, GridProps } from '../../../../common/Grid';
import { InventoryCategoryEmptyViewProps } from './InventoryCategoryEmptyView.types'; import { Text } from '../../../../common/Text';
export interface InventoryCategoryEmptyViewProps extends GridProps
{
title: string;
desc: string;
}
export const InventoryCategoryEmptyView: FC<InventoryCategoryEmptyViewProps> = props => export const InventoryCategoryEmptyView: FC<InventoryCategoryEmptyViewProps> = props =>
{ {
const { title = '', desc = '', ...rest } = props; const { title = '', desc = '', children = null, ...rest } = props;
return ( return (
<NitroLayoutGrid { ...rest }> <Grid { ...rest }>
<NitroLayoutGridColumn className="justify-content-center align-items-center" size={ 5 } overflow="hidden"> <Column center size={ 5 } overflow="hidden">
<div className="empty-image" /> <div className="empty-image" />
</NitroLayoutGridColumn> </Column>
<NitroLayoutGridColumn className="justify-content-center" size={ 7 } overflow="hidden"> <Column justifyContent="center" size={ 7 } overflow="hidden">
<NitroLayoutBase className="text-black text-truncate fs-5 fw-bold">{ title }</NitroLayoutBase> <Text fontWeight="bold" fontSize={ 5 } truncate>{ title }</Text>
<NitroLayoutBase className="text-black" overflow="auto">{ desc }</NitroLayoutBase> <Text overflow="auto">{ desc }</Text>
</NitroLayoutGridColumn> </Column>
</NitroLayoutGrid> { children }
</Grid>
); );
} }

View File

@ -1,7 +0,0 @@
import { NitroLayoutGridProps } from '../../../../layout';
export interface InventoryCategoryEmptyViewProps extends NitroLayoutGridProps
{
title: string;
desc: string;
}

View File

@ -1,10 +1,15 @@
import { MouseEventType } from '@nitrots/nitro-renderer'; import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, 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 { GroupItem } from '../../common/GroupItem';
import { InventoryFurnitureActions } from '../../../reducers/InventoryFurnitureReducer'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryFurnitureItemViewProps } from './InventoryFurnitureItemView.types'; import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
export interface InventoryFurnitureItemViewProps
{
groupItem: GroupItem;
}
export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = props => export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = props =>
{ {

View File

@ -1,9 +1,15 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { FC, useEffect, useState } from 'react'; import { Dispatch, FC, SetStateAction, useEffect, useState } from 'react';
import { LocalizeText } from '../../../../../api'; import { LocalizeText } from '../../../../api';
import { Button } from '../../../../../common/Button'; import { Button } from '../../../../common/Button';
import { Flex } from '../../../../../common/Flex'; import { Flex } from '../../../../common/Flex';
import { InventoryFurnitureSearchViewProps } from './InventoryFurnitureSearchView.types'; import { GroupItem } from '../../common/GroupItem';
export interface InventoryFurnitureSearchViewProps
{
groupItems: GroupItem[];
setGroupItems: Dispatch<SetStateAction<GroupItem[]>>;
}
export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props => export const InventoryFurnitureSearchView: FC<InventoryFurnitureSearchViewProps> = props =>
{ {

View File

@ -1,12 +1,11 @@
import { FurnitureListComposer, RoomObjectVariable, Vector3d } from '@nitrots/nitro-renderer'; import { FurnitureListComposer, IRoomSession, RoomObjectVariable, RoomPreviewer, Vector3d } from '@nitrots/nitro-renderer';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetRoomEngine, GetSessionDataManager, LocalizeText } from '../../../../api'; import { GetRoomEngine, GetSessionDataManager, LocalizeText } from '../../../../api';
import { Button } from '../../../../common/Button';
import { Column } from '../../../../common/Column'; import { Column } from '../../../../common/Column';
import { Grid } from '../../../../common/Grid'; import { Grid } from '../../../../common/Grid';
import { Text } from '../../../../common/Text'; import { Text } from '../../../../common/Text';
import { SendMessageHook } from '../../../../hooks/messages'; import { SendMessageHook } from '../../../../hooks/messages';
import { NitroLayoutButton } from '../../../../layout';
import { NitroLayoutBase } from '../../../../layout/base';
import { LimitedEditionCompactPlateView } from '../../../shared/limited-edition/compact-plate/LimitedEditionCompactPlateView'; import { LimitedEditionCompactPlateView } from '../../../shared/limited-edition/compact-plate/LimitedEditionCompactPlateView';
import { RarityLevelView } from '../../../shared/rarity-level/RarityLevelView'; import { RarityLevelView } from '../../../shared/rarity-level/RarityLevelView';
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView'; import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
@ -16,9 +15,14 @@ import { GroupItem } from '../../common/GroupItem';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer'; import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView';
import { InventoryFurnitureViewProps } from './InventoryFurnitureView.types'; import { InventoryFurnitureItemView } from './InventoryFurnitureItemView';
import { InventoryFurnitureResultsView } from './results/InventoryFurnitureResultsView'; import { InventoryFurnitureSearchView } from './InventoryFurnitureSearchView';
import { InventoryFurnitureSearchView } from './search/InventoryFurnitureSearchView';
export interface InventoryFurnitureViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}
export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props => export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
{ {
@ -64,13 +68,13 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
const roomEngine = GetRoomEngine(); const roomEngine = GetRoomEngine();
let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
wallType = (wallType && wallType.length) ? wallType : '101'; wallType = (wallType && wallType.length) ? wallType : '101';
floorType = (floorType && floorType.length) ? floorType : '101'; floorType = (floorType && floorType.length) ? floorType : '101';
landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1';
roomPreviewer.reset(false); roomPreviewer.reset(false);
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
@ -78,9 +82,9 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
if((furnitureItem.category === FurniCategory._Str_3639) || (furnitureItem.category === FurniCategory._Str_3683) || (furnitureItem.category === FurniCategory._Str_3432)) if((furnitureItem.category === FurniCategory._Str_3639) || (furnitureItem.category === FurniCategory._Str_3683) || (furnitureItem.category === FurniCategory._Str_3432))
{ {
floorType = ((furnitureItem.category === FurniCategory._Str_3683) ? groupItem.stuffData.getLegacyString() : floorType); floorType = ((furnitureItem.category === FurniCategory._Str_3683) ? groupItem.stuffData.getLegacyString() : floorType);
wallType = ((furnitureItem.category === FurniCategory._Str_3639) ? groupItem.stuffData.getLegacyString() : wallType); wallType = ((furnitureItem.category === FurniCategory._Str_3639) ? groupItem.stuffData.getLegacyString() : wallType);
landscapeType = ((furnitureItem.category === FurniCategory._Str_3432) ? groupItem.stuffData.getLegacyString() : landscapeType); landscapeType = ((furnitureItem.category === FurniCategory._Str_3432) ? groupItem.stuffData.getLegacyString() : landscapeType);
roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType); roomPreviewer.updateObjectRoom(floorType, wallType, landscapeType);
@ -110,27 +114,25 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
<Grid> <Grid>
<Column size={ 7 } overflow="hidden"> <Column size={ 7 } overflow="hidden">
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } /> <InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
<InventoryFurnitureResultsView groupItems={ filteredGroupItems } /> <Grid grow columnCount={ 5 } overflow="auto">
{ filteredGroupItems && (filteredGroupItems.length > 0) && filteredGroupItems.map((item, index) => <InventoryFurnitureItemView key={ index } groupItem={ item } />) }
</Grid>
</Column> </Column>
<Column size={ 5 } overflow="auto"> <Column size={ 5 } overflow="auto">
<Column overflow="hidden" position="relative"> <Column overflow="hidden" position="relative">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
{ groupItem && groupItem.stuffData.isUnique && { groupItem && groupItem.stuffData.isUnique &&
<NitroLayoutBase className="top-2 end-2" position="absolute"> <LimitedEditionCompactPlateView className="top-2 end-2" position="absolute" uniqueNumber={ groupItem.stuffData.uniqueNumber } uniqueSeries={ groupItem.stuffData.uniqueSeries } /> }
<LimitedEditionCompactPlateView uniqueNumber={ groupItem.stuffData.uniqueNumber } uniqueSeries={ groupItem.stuffData.uniqueSeries } />
</NitroLayoutBase> }
{ (groupItem && groupItem.stuffData.rarityLevel > -1) && { (groupItem && groupItem.stuffData.rarityLevel > -1) &&
<NitroLayoutBase className="top-2 end-2" position="absolute"> <RarityLevelView className="top-2 end-2" position="absolute" level={ groupItem.stuffData.rarityLevel } /> }
<RarityLevelView level={ groupItem.stuffData.rarityLevel } />
</NitroLayoutBase> }
</Column> </Column>
{ groupItem && { groupItem &&
<Column grow justifyContent="between" gap={ 2 }> <Column grow justifyContent="between" gap={ 2 }>
<Text>{ groupItem.name }</Text> <Text>{ groupItem.name }</Text>
{ !!roomSession && { !!roomSession &&
<NitroLayoutButton variant="success" size="sm" onClick={ event => attemptItemPlacement(groupItem) }> <Button variant="success" size="sm" onClick={ event => attemptItemPlacement(groupItem) }>
{ LocalizeText('inventory.furni.placetoroom') } { LocalizeText('inventory.furni.placetoroom') }
</NitroLayoutButton> } </Button> }
</Column> } </Column> }
</Column> </Column>
</Grid> </Grid>

View File

@ -1,7 +0,0 @@
import { IRoomSession, RoomPreviewer } from '@nitrots/nitro-renderer';
export interface InventoryFurnitureViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}

View File

@ -1,6 +0,0 @@
import { GroupItem } from '../../../common/GroupItem';
export interface InventoryFurnitureItemViewProps
{
groupItem: GroupItem;
}

View File

@ -1,18 +0,0 @@
import { FC } from 'react';
import { Grid } from '../../../../../common/Grid';
import { InventoryFurnitureItemView } from '../item/InventoryFurnitureItemView';
import { InventoryFurnitureResultsViewProps } from './InventoryFurnitureResultsView.types';
export const InventoryFurnitureResultsView: FC<InventoryFurnitureResultsViewProps> = props =>
{
const { groupItems = [] } = props;
return (
<Grid grow columnCount={ 5 } overflow="auto">
{ groupItems && (groupItems.length > 0) && groupItems.map((item, index) =>
{
return <InventoryFurnitureItemView key={ index } groupItem={ item } />
}) }
</Grid>
);
}

View File

@ -1,6 +0,0 @@
import { GroupItem } from '../../../common/GroupItem';
export interface InventoryFurnitureResultsViewProps
{
groupItems: GroupItem[];
}

View File

@ -1,8 +0,0 @@
import { Dispatch, SetStateAction } from 'react';
import { GroupItem } from '../../../common/GroupItem';
export interface InventoryFurnitureSearchViewProps
{
groupItems: GroupItem[];
setGroupItems: Dispatch<SetStateAction<GroupItem[]>>;
}

View File

@ -1,11 +1,16 @@
import { MouseEventType } from '@nitrots/nitro-renderer'; import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, 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 { PetItem } from '../../common/PetItem';
import { useInventoryContext } from '../../../context/InventoryContext'; import { attemptPetPlacement } from '../../common/PetUtilities';
import { InventoryPetActions } from '../../../reducers/InventoryPetReducer'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryPetItemViewProps } from './InventoryPetItemView.types'; import { InventoryPetActions } from '../../reducers/InventoryPetReducer';
export interface InventoryPetItemViewProps
{
petItem: PetItem;
}
export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props => export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
{ {

View File

@ -1,18 +1,23 @@
import { RequestPetsComposer, RoomObjectVariable } from '@nitrots/nitro-renderer'; import { IRoomSession, RequestPetsComposer, RoomObjectVariable, RoomPreviewer } from '@nitrots/nitro-renderer';
import { FC, useEffect } from 'react'; import { FC, useEffect } from 'react';
import { GetRoomEngine, LocalizeText } from '../../../../api'; import { GetRoomEngine, LocalizeText } from '../../../../api';
import { Button } from '../../../../common/Button';
import { Column } from '../../../../common/Column';
import { Grid } from '../../../../common/Grid';
import { Text } from '../../../../common/Text';
import { SendMessageHook } from '../../../../hooks/messages/message-event'; import { SendMessageHook } from '../../../../hooks/messages/message-event';
import { NitroLayoutBase } from '../../../../layout/base';
import { NitroLayoutFlexColumn } from '../../../../layout/flex-column/NitroLayoutFlexColumn';
import { NitroLayoutGridColumn } from '../../../../layout/grid/column/NitroLayoutGridColumn';
import { NitroLayoutGrid } from '../../../../layout/grid/NitroLayoutGrid';
import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView'; import { RoomPreviewerView } from '../../../shared/room-previewer/RoomPreviewerView';
import { attemptPetPlacement } from '../../common/PetUtilities'; import { attemptPetPlacement } from '../../common/PetUtilities';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryPetActions } from '../../reducers/InventoryPetReducer'; import { InventoryPetActions } from '../../reducers/InventoryPetReducer';
import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView'; import { InventoryCategoryEmptyView } from '../category-empty/InventoryCategoryEmptyView';
import { InventoryPetViewProps } from './InventoryPetView.types'; import { InventoryPetItemView } from './InventoryPetItemView';
import { InventoryPetResultsView } from './results/InventoryPetResultsView';
export interface InventoryPetViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}
export const InventoryPetView: FC<InventoryPetViewProps> = props => export const InventoryPetView: FC<InventoryPetViewProps> = props =>
{ {
@ -50,16 +55,15 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
if(!petItem || !roomPreviewer) return; if(!petItem || !roomPreviewer) return;
const petData = petItem.petData; const petData = petItem.petData;
const roomEngine = GetRoomEngine(); const roomEngine = GetRoomEngine();
let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE); let wallType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_WALL_TYPE);
let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE); let floorType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_FLOOR_TYPE);
let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE); let landscapeType = roomEngine.getRoomInstanceVariable<string>(roomEngine.activeRoomId, RoomObjectVariable.ROOM_LANDSCAPE_TYPE);
wallType = (wallType && wallType.length) ? wallType : '101'; wallType = (wallType && wallType.length) ? wallType : '101';
floorType = (floorType && floorType.length) ? floorType : '101'; floorType = (floorType && floorType.length) ? floorType : '101';
landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1'; landscapeType = (landscapeType && landscapeType.length) ? landscapeType : '1.1';
roomPreviewer.reset(false); roomPreviewer.reset(false);
roomPreviewer.updateRoomWallsAndFloorVisibility(true, true); roomPreviewer.updateRoomWallsAndFloorVisibility(true, true);
@ -70,20 +74,25 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
if(!petItems || !petItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.pets.title') } desc={ LocalizeText('inventory.empty.pets.desc') } />; if(!petItems || !petItems.length) return <InventoryCategoryEmptyView title={ LocalizeText('inventory.empty.pets.title') } desc={ LocalizeText('inventory.empty.pets.desc') } />;
return ( return (
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn size={ 7 }> <Column size={ 7 } overflow="hidden">
<InventoryPetResultsView petItems={ petItems } /> <Grid grow columnCount={ 5 } overflow="auto">
</NitroLayoutGridColumn> { petItems && (petItems.length > 0) && petItems.map(item => <InventoryPetItemView key={ item.id } petItem={ item } />) }
<NitroLayoutGridColumn size={ 5 } overflow="auto"> </Grid>
<NitroLayoutFlexColumn overflow="hidden" position="relative"> </Column>
<Column size={ 5 } overflow="auto">
<Column overflow="hidden" position="relative">
<RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } /> <RoomPreviewerView roomPreviewer={ roomPreviewer } height={ 140 } />
</NitroLayoutFlexColumn> </Column>
{ petItem && { petItem &&
<NitroLayoutFlexColumn className="flex-grow-1" gap={ 2 }> <Column grow justifyContent="between" gap={ 2 }>
<NitroLayoutBase className="flex-grow-1 text-black text-truncate">{ petItem.petData.name }</NitroLayoutBase> <Text>{ petItem.petData.name }</Text>
{ !!roomSession && <button type="button" className="btn btn-success btn-sm" onClick={ event => attemptPetPlacement(petItem) }>{ LocalizeText('inventory.furni.placetoroom') }</button> } { !!roomSession &&
</NitroLayoutFlexColumn> } <Button variant="success" size="sm" onClick={ event => attemptPetPlacement(petItem) }>
</NitroLayoutGridColumn> { LocalizeText('inventory.furni.placetoroom') }
</NitroLayoutGrid> </Button> }
</Column> }
</Column>
</Grid>
); );
} }

View File

@ -1,7 +0,0 @@
import { IRoomSession, RoomPreviewer } from '@nitrots/nitro-renderer';
export interface InventoryPetViewProps
{
roomSession: IRoomSession;
roomPreviewer: RoomPreviewer;
}

View File

@ -1,6 +0,0 @@
import { PetItem } from '../../../common/PetItem';
export interface InventoryPetItemViewProps
{
petItem: PetItem;
}

View File

@ -1,18 +0,0 @@
import { FC } from 'react';
import { NitroCardGridView } from '../../../../../layout/card/grid/NitroCardGridView';
import { InventoryPetItemView } from '../item/InventoryPetItemView';
import { InventoryPetResultsViewProps } from './InventoryPetResultsView.types';
export const InventoryPetResultsView: FC<InventoryPetResultsViewProps> = props =>
{
const { petItems = [] } = props;
return (
<NitroCardGridView>
{ petItems && (petItems.length > 0) && petItems.map(item =>
{
return <InventoryPetItemView key={ item.id } petItem={ item } />
}) }
</NitroCardGridView>
);
}

View File

@ -1,6 +0,0 @@
import { PetItem } from '../../../common/PetItem';
export interface InventoryPetResultsViewProps
{
petItems: PetItem[];
}

View File

@ -1,13 +1,15 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { FurnitureListComposer, IObjectData, TradingAcceptComposer, TradingConfirmationComposer, TradingListAddItemComposer, TradingListAddItemsComposer, TradingListItemRemoveComposer, TradingUnacceptComposer } from '@nitrots/nitro-renderer'; import { FurnitureListComposer, IObjectData, TradingAcceptComposer, TradingConfirmationComposer, TradingListAddItemComposer, TradingListAddItemsComposer, TradingListItemRemoveComposer, TradingUnacceptComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { LocalizeText } from '../../../../api'; import { LocalizeText } from '../../../../api';
import { Base } from '../../../../common/Base';
import { Button } from '../../../../common/Button';
import { Column } from '../../../../common/Column';
import { Flex } from '../../../../common/Flex';
import { Grid } from '../../../../common/Grid';
import { Text } from '../../../../common/Text';
import { SendMessageHook } from '../../../../hooks/messages'; import { SendMessageHook } from '../../../../hooks/messages';
import { NitroLayoutButton, NitroLayoutFlex, NitroLayoutFlexColumn } from '../../../../layout';
import { NitroLayoutBase } from '../../../../layout/base';
import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView'; import { NitroCardGridItemView } from '../../../../layout/card/grid/item/NitroCardGridItemView';
import { NitroCardGridView } from '../../../../layout/card/grid/NitroCardGridView';
import { NitroLayoutGridColumn } from '../../../../layout/grid/column/NitroLayoutGridColumn';
import { NitroLayoutGrid } from '../../../../layout/grid/NitroLayoutGrid';
import { FurniCategory } from '../../common/FurniCategory'; import { FurniCategory } from '../../common/FurniCategory';
import { GroupItem } from '../../common/GroupItem'; import { GroupItem } from '../../common/GroupItem';
import { IFurnitureItem } from '../../common/IFurnitureItem'; import { IFurnitureItem } from '../../common/IFurnitureItem';
@ -15,8 +17,13 @@ import { TradeState } from '../../common/TradeState';
import { _Str_16998 } from '../../common/TradingUtilities'; import { _Str_16998 } from '../../common/TradingUtilities';
import { useInventoryContext } from '../../context/InventoryContext'; import { useInventoryContext } from '../../context/InventoryContext';
import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer'; import { InventoryFurnitureActions } from '../../reducers/InventoryFurnitureReducer';
import { InventoryFurnitureSearchView } from '../furniture/search/InventoryFurnitureSearchView'; import { InventoryFurnitureSearchView } from '../furniture/InventoryFurnitureSearchView';
import { InventoryTradeViewProps } from './InventoryTradeView.types';
export interface InventoryTradeViewProps
{
cancelTrade: () => void;
}
const MAX_ITEMS_TO_TRADE: number = 9; const MAX_ITEMS_TO_TRADE: number = 9;
@ -174,6 +181,14 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
} }
}, [ tradeData, dispatchFurnitureState ]); }, [ tradeData, dispatchFurnitureState ]);
const getLockIcon = (accepts: boolean) =>
{
const iconName = accepts ? 'lock' : 'unlock';
const textColor = accepts ? 'success' : 'danger';
return <FontAwesomeIcon icon={ iconName } className={ 'text-' + textColor } />
};
const getTradeButton = useMemo(() => const getTradeButton = useMemo(() =>
{ {
if(!tradeData) return null; if(!tradeData) return null;
@ -181,15 +196,15 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
switch(tradeData.state) switch(tradeData.state)
{ {
case TradeState.TRADING_STATE_READY: case TradeState.TRADING_STATE_READY:
return <button type="button" className="btn btn-secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText('inventory.trading.accept') }</button>; return <Button variant="secondary" size="sm" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText('inventory.trading.accept') }</Button>;
case TradeState.TRADING_STATE_RUNNING: case TradeState.TRADING_STATE_RUNNING:
return <button type="button" className="btn btn-secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText(tradeData.ownUser.accepts ? 'inventory.trading.modify' : 'inventory.trading.accept') }</button>; return <Button variant="secondary" size="sm" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText(tradeData.ownUser.accepts ? 'inventory.trading.modify' : 'inventory.trading.accept') }</Button>;
case TradeState.TRADING_STATE_COUNTDOWN: case TradeState.TRADING_STATE_COUNTDOWN:
return <button type="button" className="btn btn-secondary" disabled>{ LocalizeText('inventory.trading.countdown', [ 'counter' ], [ countdownTick.toString() ]) }</button>; return <Button variant="secondary" size="sm" disabled>{ LocalizeText('inventory.trading.countdown', [ 'counter' ], [ countdownTick.toString() ]) }</Button>;
case TradeState.TRADING_STATE_CONFIRMING: case TradeState.TRADING_STATE_CONFIRMING:
return <button type="button" className="btn btn-secondary" onClick={ progressTrade }>{ LocalizeText('inventory.trading.button.restore') }</button>; return <Button variant="secondary" size="sm" onClick={ progressTrade }>{ LocalizeText('inventory.trading.button.restore') }</Button>;
case TradeState.TRADING_STATE_CONFIRMED: case TradeState.TRADING_STATE_CONFIRMED:
return <button type="button" className="btn btn-secondary">{ LocalizeText('inventory.trading.info.waiting') }</button>; return <Button variant="secondary" size="sm">{ LocalizeText('inventory.trading.info.waiting') }</Button>;
} }
}, [ tradeData, countdownTick, progressTrade ]); }, [ tradeData, countdownTick, progressTrade ]);
@ -228,81 +243,81 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
}, [ tradeData, dispatchFurnitureState ]); }, [ tradeData, dispatchFurnitureState ]);
return ( return (
<NitroLayoutGrid> <Grid>
<NitroLayoutGridColumn size={ 4 }> <Column size={ 4 } overflow="hidden">
<NitroLayoutFlexColumn className="h-100" overflow="auto" gap={ 2 }> <InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } />
<InventoryFurnitureSearchView groupItems={ groupItems } setGroupItems={ setFilteredGroupItems } /> <Grid grow fullHeight columnCount={ 3 } overflow="auto">
<NitroCardGridView> { filteredGroupItems && (filteredGroupItems.length > 0) && filteredGroupItems.map((item, index) =>
{ filteredGroupItems && (filteredGroupItems.length > 0) && filteredGroupItems.map((item, index) => {
{ const count = item.getUnlockedCount();
const count = item.getUnlockedCount();
return ( return (
<NitroCardGridItemView key={ index } className={ !count ? 'opacity-0-5 ' : '' } itemImage={ item.iconUrl } itemCount={ count } itemActive={ (groupItem === item) } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => (count && setGroupItem(item)) }> <NitroCardGridItemView key={ index } className={ !count ? 'opacity-0-5 ' : '' } itemImage={ item.iconUrl } itemCount={ count } itemActive={ (groupItem === item) } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => (count && setGroupItem(item)) }>
{ ((count > 0) && (groupItem === item)) && { ((count > 0) && (groupItem === item)) &&
<button className="btn btn-success btn-sm trade-button" onClick={ event => attemptItemOffer(1) }> <Button variant="success" size="sm" className="trade-button" onClick={ event => attemptItemOffer(1) }>
<i className="fas fa-chevron-right" /> <FontAwesomeIcon icon="chevron-right" />
</button> } </Button> }
</NitroCardGridItemView> </NitroCardGridItemView>
); );
}) } }) }
</NitroCardGridView> </Grid>
</NitroLayoutFlexColumn> <Base fullWidth className="badge bg-muted">
<NitroLayoutBase className="badge bg-muted w-100">
{ groupItem ? groupItem.name : LocalizeText('catalog_selectproduct') } { groupItem ? groupItem.name : LocalizeText('catalog_selectproduct') }
</NitroLayoutBase> </Base>
</NitroLayoutGridColumn> </Column>
<NitroLayoutGridColumn size={ 8 }> <Column size={ 8 } overflow="hidden">
<NitroLayoutGrid overflow="hidden"> <Grid overflow="hidden">
<NitroLayoutGridColumn size={ 6 }> <Column size={ 6 } overflow="hidden">
<NitroLayoutFlexColumn className="h-100" overflow="auto" gap={ 2 }> <Flex justifyContent="between" alignItems="center">
<span className="d-flex justify-content-between align-items-center text-black small mb-1">{ LocalizeText('inventory.trading.you') } { LocalizeText('inventory.trading.areoffering') }: <i className={ 'small fas ' + (tradeData.ownUser.accepts ? 'fa-lock text-success' : 'fa-unlock text-danger') } /></span> <Text>{ LocalizeText('inventory.trading.you') } { LocalizeText('inventory.trading.areoffering') }:</Text>
<NitroCardGridView> { getLockIcon(tradeData.ownUser.accepts) }
{ Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) => </Flex>
{ <Grid grow columnCount={ 3 } overflow="auto">
const item = (tradeData.ownUser.items.getWithIndex(i) || null); { Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) =>
{
const item = (tradeData.ownUser.items.getWithIndex(i) || null);
if(!item) return <NitroCardGridItemView key={ i } />; if(!item) return <NitroCardGridItemView key={ i } />;
return ( return (
<NitroCardGridItemView key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }> <NitroCardGridItemView key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }>
{ (ownGroupItem === item) && { (ownGroupItem === item) &&
<button className="btn btn-danger btn-sm trade-button left" onClick={ event => removeItem(item) }> <Button variant="danger" size="sm" className="trade-button left" onClick={ event => removeItem(item) }>
<i className="fas fa-chevron-left" /> <FontAwesomeIcon icon="chevron-left" />
</button> } </Button> }
</NitroCardGridItemView> </NitroCardGridItemView>
); );
}) } }) }
</NitroCardGridView> </Grid>
</NitroLayoutFlexColumn> <Base fullWidth className="badge bg-muted">
<NitroLayoutBase className="badge bg-muted w-100">
{ ownGroupItem ? ownGroupItem.name : LocalizeText('catalog_selectproduct') } { ownGroupItem ? ownGroupItem.name : LocalizeText('catalog_selectproduct') }
</NitroLayoutBase> </Base>
</NitroLayoutGridColumn> </Column>
<NitroLayoutGridColumn size={ 6 }> <Column size={ 6 } overflow="hidden">
<NitroLayoutFlexColumn className="h-100" overflow="auto" gap={ 2 }> <Flex justifyContent="between" alignItems="center">
<span className="d-flex justify-content-between align-items-center text-black small mb-1">{ tradeData.otherUser.userName } { LocalizeText('inventory.trading.isoffering') }: <i className={ 'small fas ' + (tradeData.otherUser.accepts ? 'fa-lock text-success' : 'fa-unlock text-danger') } /></span> <Text>{ tradeData.otherUser.userName } { LocalizeText('inventory.trading.isoffering') }:</Text>
<NitroCardGridView> { getLockIcon(tradeData.otherUser.accepts) }
{ Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) => </Flex>
{ <Grid grow columnCount={ 3 } overflow="auto">
const item = (tradeData.otherUser.items.getWithIndex(i) || null); { Array.from(Array(MAX_ITEMS_TO_TRADE), (e, i) =>
{
const item = (tradeData.otherUser.items.getWithIndex(i) || null);
if(!item) return <NitroCardGridItemView key={ i } />; if(!item) return <NitroCardGridItemView key={ i } />;
return <NitroCardGridItemView key={ i } itemActive={ (otherGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOtherGroupItem(item) } />; return <NitroCardGridItemView key={ i } itemActive={ (otherGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOtherGroupItem(item) } />;
}) } }) }
</NitroCardGridView> </Grid>
</NitroLayoutFlexColumn> <Base fullWidth className="badge bg-muted w-100">
<NitroLayoutBase className="badge bg-muted w-100">
{ otherGroupItem ? otherGroupItem.name : LocalizeText('catalog_selectproduct') } { otherGroupItem ? otherGroupItem.name : LocalizeText('catalog_selectproduct') }
</NitroLayoutBase> </Base>
</NitroLayoutGridColumn> </Column>
</NitroLayoutGrid> </Grid>
<NitroLayoutFlex className="flex-grow-1 justify-content-between"> <Flex grow justifyContent="between">
<NitroLayoutButton variant="danger" onClick={ cancelTrade }>{ LocalizeText('generic.cancel') }</NitroLayoutButton> <Button variant="danger" size="sm" onClick={ cancelTrade }>{ LocalizeText('generic.cancel') }</Button>
{ getTradeButton } { getTradeButton }
</NitroLayoutFlex> </Flex>
</NitroLayoutGridColumn> </Column>
</NitroLayoutGrid> </Grid>
); );
} }

View File

@ -1,4 +0,0 @@
export interface InventoryTradeViewProps
{
cancelTrade: () => void;
}