Update inventory

This commit is contained in:
Bill 2022-01-11 00:54:48 -05:00
parent 0a8e8fa67a
commit 59321bb133
10 changed files with 92 additions and 109 deletions

View File

@ -151,12 +151,12 @@ export const InventoryView: FC<{}> = props =>
}
}, [ furnitureState.groupItems, unseenTracker ]);
const switchTab = useCallback((prevTab: string, nextTab: string) =>
const switchTab = (prevTab: string, nextTab: string) =>
{
if(nextTab) setCurrentTab(nextTab);
resetTrackerForTab(prevTab);
}, [ resetTrackerForTab ]);
}
useEffect(() =>
{

View File

@ -1,5 +1,5 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback } from 'react';
import { FC, MouseEvent } from 'react';
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
import { BadgeImageView } from '../../../../views/shared/badge-image/BadgeImageView';
import { useInventoryContext } from '../../context/InventoryContext';
@ -15,7 +15,7 @@ export const InventoryBadgeItemView: FC<InventoryBadgeItemViewProps> = props =>
const { badgeCode = null } = props;
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
const onMouseEvent = useCallback((event: MouseEvent) =>
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
@ -25,7 +25,7 @@ export const InventoryBadgeItemView: FC<InventoryBadgeItemViewProps> = props =>
payload: { badgeCode }
});
}
}, [ badgeCode, dispatchBadgeState ]);
}
return (
<LayoutGridItem itemActive={ (badgeState.badge === badgeCode) } onMouseDown={ onMouseEvent }>

View File

@ -21,6 +21,34 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
const { badgeState = null, dispatchBadgeState = null } = useInventoryContext();
const { needsBadgeUpdate = false, badge = null, badges = [], activeBadges = [] } = badgeState;
const isWearingBadge = (badgeCode: string) => (activeBadges.indexOf(badgeCode) >= 0);
const canWearBadges = () => (activeBadges.length < 5);
const toggleBadge = () =>
{
if(isWearingBadge(badge))
{
dispatchBadgeState({
type: InventoryBadgeActions.REMOVE_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
else
{
if(!canWearBadges()) return;
dispatchBadgeState({
type: InventoryBadgeActions.ADD_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
}
useEffect(() =>
{
if(needsBadgeUpdate)
@ -46,40 +74,6 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
}, [ needsBadgeUpdate, badges, dispatchBadgeState ]);
function isWearingBadge(badgeCode: string): boolean
{
return (activeBadges.indexOf(badgeCode) >= 0);
}
function canWearBadges(): boolean
{
return (activeBadges.length < 5);
}
function toggleBadge(): void
{
if(isWearingBadge(badge))
{
dispatchBadgeState({
type: InventoryBadgeActions.REMOVE_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
else
{
if(!canWearBadges()) return;
dispatchBadgeState({
type: InventoryBadgeActions.ADD_ACTIVE_BADGE,
payload: {
badgeCode: badge
}
});
}
}
return (
<Grid>
<Column size={ 7 } overflow="hidden">
@ -105,7 +99,7 @@ export const InventoryBadgeView: FC<InventoryBadgeViewProps> = props =>
<BadgeImageView badgeCode={ badge } />
<Text>{ LocalizeBadgeName(badge) }</Text>
</Flex>
<Button variant={ (isWearingBadge(badge) ? 'danger' : 'success') } size="sm" disabled={ !isWearingBadge(badge) && !canWearBadges() } onClick={ toggleBadge }>{ LocalizeText(isWearingBadge(badge) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }</Button>
<Button variant={ (isWearingBadge(badge) ? 'danger' : 'success') } disabled={ !isWearingBadge(badge) && !canWearBadges() } onClick={ toggleBadge }>{ LocalizeText(isWearingBadge(badge) ? 'inventory.badges.clearbadge' : 'inventory.badges.wearbadge') }</Button>
</Column> }
</Column>
</Grid>

View File

@ -1,5 +1,5 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
import { AvatarImageView } from '../../../../views/shared/avatar-image/AvatarImageView';
import { BotItem } from '../../common/BotItem';
@ -15,11 +15,11 @@ export interface InventoryBotItemViewProps
export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props =>
{
const { botItem } = props;
const { botState = null, dispatchBotState = null } = useInventoryContext();
const [ isMouseDown, setMouseDown ] = useState(false);
const { botState = null, dispatchBotState = null } = useInventoryContext();
const isActive = (botState.botItem === botItem);
const onMouseEvent = useCallback((event: MouseEvent) =>
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
@ -40,7 +40,7 @@ export const InventoryBotItemView: FC<InventoryBotItemViewProps> = props =>
attemptBotPlacement(botItem);
return;
}
}, [ isActive, isMouseDown, botItem, dispatchBotState ]);
}
useEffect(() =>
{

View File

@ -89,7 +89,7 @@ export const InventoryBotView: FC<InventoryBotViewProps> = props =>
<Column grow justifyContent="between" gap={ 2 }>
<Text grow truncate>{ botItem.botData.name }</Text>
{ !!roomSession &&
<Button variant="success" size="sm" onClick={ event => attemptBotPlacement(botItem) }>
<Button variant="success" onClick={ event => attemptBotPlacement(botItem) }>
{ LocalizeText('inventory.furni.placetoroom') }
</Button> }
</Column> }

View File

@ -1,5 +1,5 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
import { attemptItemPlacement } from '../../common/FurnitureUtilities';
import { GroupItem } from '../../common/GroupItem';
@ -18,7 +18,7 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
const { furnitureState, dispatchFurnitureState } = useInventoryContext();
const isActive = (furnitureState.groupItem === groupItem);
const onMouseEvent = useCallback((event: MouseEvent) =>
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
@ -39,7 +39,7 @@ export const InventoryFurnitureItemView: FC<InventoryFurnitureItemViewProps> = p
attemptItemPlacement(groupItem);
return;
}
}, [ isActive, isMouseDown, groupItem, dispatchFurnitureState ]);
}
useEffect(() =>
{

View File

@ -129,15 +129,16 @@ export const InventoryFurnitureView: FC<InventoryFurnitureViewProps> = props =>
{ groupItem &&
<Column grow justifyContent="between" gap={ 2 }>
<Text grow truncate>{ groupItem.name }</Text>
{ !!roomSession &&
<Button variant="success" size="sm" onClick={ event => attemptItemPlacement(groupItem) }>
{ LocalizeText('inventory.furni.placetoroom') }
</Button> }
{ (groupItem && groupItem.isSellable) &&
<Button variant="primary" size="sm" onClick={ event => attemptPlaceMarketplaceOffer(groupItem) }>
{ LocalizeText('inventory.marketplace.sell') }
</Button>
}
<Column gap={ 1 }>
{ !!roomSession &&
<Button variant="success" onClick={ event => attemptItemPlacement(groupItem) }>
{ LocalizeText('inventory.furni.placetoroom') }
</Button> }
{ (groupItem && groupItem.isSellable) &&
<Button onClick={ event => attemptPlaceMarketplaceOffer(groupItem) }>
{ LocalizeText('inventory.marketplace.sell') }
</Button> }
</Column>
</Column> }
</Column>
</Grid>

View File

@ -1,5 +1,5 @@
import { MouseEventType } from '@nitrots/nitro-renderer';
import { FC, MouseEvent, useCallback, useEffect, useState } from 'react';
import { FC, MouseEvent, useEffect, useState } from 'react';
import { LayoutGridItem } from '../../../../common/layout/LayoutGridItem';
import { PetImageView } from '../../../../views/shared/pet-image/PetImageView';
import { PetItem } from '../../common/PetItem';
@ -19,7 +19,7 @@ export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
const { petState = null, dispatchPetState = null } = useInventoryContext();
const isActive = (petState.petItem === petItem);
const onMouseEvent = useCallback((event: MouseEvent) =>
const onMouseEvent = (event: MouseEvent) =>
{
switch(event.type)
{
@ -40,7 +40,7 @@ export const InventoryPetItemView: FC<InventoryPetItemViewProps> = props =>
attemptPetPlacement(petItem);
return;
}
}, [ isActive, isMouseDown, petItem, dispatchPetState ]);
}
useEffect(() =>
{

View File

@ -88,7 +88,7 @@ export const InventoryPetView: FC<InventoryPetViewProps> = props =>
<Column grow justifyContent="between" gap={ 2 }>
<Text grow truncate>{ petItem.petData.name }</Text>
{ !!roomSession &&
<Button variant="success" size="sm" onClick={ event => attemptPetPlacement(petItem) }>
<Button variant="success" onClick={ event => attemptPetPlacement(petItem) }>
{ LocalizeText('inventory.furni.placetoroom') }
</Button> }
</Column> }

View File

@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { FurnitureListComposer, IObjectData, TradingAcceptComposer, TradingConfirmationComposer, TradingListAddItemComposer, TradingListAddItemsComposer, TradingListItemRemoveComposer, TradingUnacceptComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
import { FC, useEffect, useState } from 'react';
import { LocalizeText } from '../../../../api';
import { Base } from '../../../../common/Base';
import { Button } from '../../../../common/Button';
@ -26,7 +26,6 @@ export interface InventoryTradeViewProps
cancelTrade: () => void;
}
const MAX_ITEMS_TO_TRADE: number = 9;
export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
@ -40,7 +39,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
const { furnitureState = null, dispatchFurnitureState = null } = useInventoryContext();
const { needsFurniUpdate = false, groupItems = [], tradeData = null } = furnitureState;
const canTradeItem = useCallback((isWallItem: boolean, spriteId: number, category: number, groupable: boolean, stuffData: IObjectData) =>
const canTradeItem = (isWallItem: boolean, spriteId: number, category: number, groupable: boolean, stuffData: IObjectData) =>
{
if(!tradeData || !tradeData.ownUser || tradeData.ownUser.accepts || !tradeData.ownUser.items) return false;
@ -67,9 +66,9 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
}
return !!tradeData.ownUser.items.getValue(type);
}, [ tradeData ]);
}
const attemptItemOffer = useCallback((count: number) =>
const attemptItemOffer = (count: number) =>
{
if(!tradeData || !groupItem) return;
@ -124,42 +123,25 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
{
NotificationUtilities.simpleAlert(LocalizeText('trading.items.too_many_items.desc'), NotificationAlertType.DEFAULT, null, null, LocalizeText('trading.items.too_many_items.title'));
}
}, [ groupItem, tradeData, canTradeItem ]);
}
const removeItem = useCallback((group: GroupItem) =>
const removeItem = (group: GroupItem) =>
{
const item = group.getLastItem();
if(!item) return;
SendMessageHook(new TradingListItemRemoveComposer(item.id));
}, []);
}
useEffect(() =>
{
if(needsFurniUpdate)
{
dispatchFurnitureState({
type: InventoryFurnitureActions.SET_NEEDS_UPDATE,
payload: {
flag: false
}
});
SendMessageHook(new FurnitureListComposer());
}
}, [ needsFurniUpdate, groupItems, dispatchFurnitureState ]);
const progressTrade = useCallback(() =>
const progressTrade = () =>
{
switch(tradeData.state)
{
case TradeState.TRADING_STATE_RUNNING:
if(!tradeData.otherUser.itemCount && !tradeData.ownUser.accepts)
{
// eslint-disable-next-line no-template-curly-in-string
NotificationUtilities.simpleAlert(LocalizeText('${inventory.trading.warning.other_not_offering}'), null, null, null);
NotificationUtilities.simpleAlert(LocalizeText('inventory.trading.warning.other_not_offering'), null, null, null);
}
if(tradeData.ownUser.accepts)
@ -182,7 +164,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
});
return;
}
}, [ tradeData, dispatchFurnitureState ]);
}
const getLockIcon = (accepts: boolean) =>
{
@ -192,24 +174,21 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
return <FontAwesomeIcon icon={ iconName } className={ 'text-' + textColor } />
};
const getTradeButton = useMemo(() =>
useEffect(() =>
{
if(!tradeData) return null;
switch(tradeData.state)
if(needsFurniUpdate)
{
case TradeState.TRADING_STATE_READY:
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:
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:
return <Button variant="secondary" size="sm" disabled>{ LocalizeText('inventory.trading.countdown', [ 'counter' ], [ countdownTick.toString() ]) }</Button>;
case TradeState.TRADING_STATE_CONFIRMING:
return <Button variant="secondary" size="sm" onClick={ progressTrade }>{ LocalizeText('inventory.trading.button.restore') }</Button>;
case TradeState.TRADING_STATE_CONFIRMED:
return <Button variant="secondary" size="sm">{ LocalizeText('inventory.trading.info.waiting') }</Button>;
dispatchFurnitureState({
type: InventoryFurnitureActions.SET_NEEDS_UPDATE,
payload: {
flag: false
}
});
SendMessageHook(new FurnitureListComposer());
}
}, [ tradeData, countdownTick, progressTrade ]);
}, [ needsFurniUpdate, groupItems, dispatchFurnitureState ]);
useEffect(() =>
{
@ -223,7 +202,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
{
const newValue = (prevValue - 1);
if(newValue === -1)
if(newValue === 0)
{
dispatchFurnitureState({
type: InventoryFurnitureActions.SET_TRADE_STATE,
@ -258,7 +237,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
return (
<LayoutGridItem 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)) &&
<Button position="absolute" variant="success" size="sm" className="trade-button bottom-1 end-1" onClick={ event => attemptItemOffer(1) }>
<Button position="absolute" variant="success" className="trade-button bottom-1 end-1" onClick={ event => attemptItemOffer(1) }>
<FontAwesomeIcon icon="chevron-right" />
</Button> }
</LayoutGridItem>
@ -287,7 +266,7 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
return (
<LayoutGridItem key={ i } itemActive={ (ownGroupItem === item) } itemImage={ item.iconUrl } itemCount={ item.getTotalCount() } itemUniqueNumber={ item.stuffData.uniqueNumber } onClick={ event => setOwnGroupItem(item) }>
{ (ownGroupItem === item) &&
<Button position="absolute" variant="danger" size="sm" className="trade-button bottom-1 start-1" onClick={ event => removeItem(item) }>
<Button position="absolute" variant="danger" className="trade-button bottom-1 start-1" onClick={ event => removeItem(item) }>
<FontAwesomeIcon icon="chevron-left" />
</Button> }
</LayoutGridItem>
@ -319,8 +298,17 @@ export const InventoryTradeView: FC<InventoryTradeViewProps> = props =>
</Column>
</Grid>
<Flex grow justifyContent="between">
<Button variant="danger" size="sm" onClick={ cancelTrade }>{ LocalizeText('generic.cancel') }</Button>
{ getTradeButton }
<Button variant="danger" onClick={ cancelTrade }>{ LocalizeText('generic.cancel') }</Button>
{ (tradeData.state === TradeState.TRADING_STATE_READY) &&
<Button variant="secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText('inventory.trading.accept') }</Button> }
{ (tradeData.state === TradeState.TRADING_STATE_RUNNING) &&
<Button variant="secondary" disabled={ (!tradeData.ownUser.itemCount && !tradeData.otherUser.itemCount) } onClick={ progressTrade }>{ LocalizeText(tradeData.ownUser.accepts ? 'inventory.trading.modify' : 'inventory.trading.accept') }</Button> }
{ (tradeData.state === TradeState.TRADING_STATE_COUNTDOWN) &&
<Button variant="secondary" disabled>{ LocalizeText('inventory.trading.countdown', [ 'counter' ], [ countdownTick.toString() ]) }</Button> }
{ (tradeData.state === TradeState.TRADING_STATE_CONFIRMING) &&
<Button variant="secondary" onClick={ progressTrade }>{ LocalizeText('inventory.trading.button.restore') }</Button> }
{ (tradeData.state === TradeState.TRADING_STATE_CONFIRMED) &&
<Button variant="secondary">{ LocalizeText('inventory.trading.info.waiting') }</Button> }
</Flex>
</Column>
</Grid>