Update context menus

This commit is contained in:
Bill 2022-02-25 21:52:27 -05:00
parent 66bb329b74
commit d40cb08973
8 changed files with 165 additions and 146 deletions

View File

@ -3,15 +3,15 @@ import { GroupFurniContextMenuInfoMessageEvent } from '@nitrots/nitro-renderer/s
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryVisitRoom } from '../../../../../api'; import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryVisitRoom } from '../../../../../api';
import { TryJoinGroup } from '../../../../../api/groups/TryJoinGroup'; import { TryJoinGroup } from '../../../../../api/groups/TryJoinGroup';
import { CreateMessageHook } from '../../../../../hooks'; import { BatchUpdates, CreateMessageHook } from '../../../../../hooks';
import { useRoomEngineEvent } from '../../../../../hooks/events'; import { useRoomEngineEvent } from '../../../../../hooks/events';
import { useRoomContext } from '../../../context/RoomContext'; import { useRoomContext } from '../../../context/RoomContext';
import { ContextMenuView } from '../../context-menu/ContextMenuView'; import { ContextMenuView } from '../../context-menu/ContextMenuView';
import { ContextMenuHeaderView } from '../../context-menu/views/header/ContextMenuHeaderView'; import { ContextMenuHeaderView } from '../../context-menu/views/header/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../context-menu/views/list-item/ContextMenuListItemView'; import { ContextMenuListItemView } from '../../context-menu/views/list-item/ContextMenuListItemView';
import { EffectBoxConfirmView } from './views/effect-box/EffectBoxConfirmView'; import { EffectBoxConfirmView } from './views/EffectBoxConfirmView';
import { MonsterPlantSeedConfirmView } from './views/monsterplant-seed/MonsterPlantSeedConfirmView'; import { MonsterPlantSeedConfirmView } from './views/MonsterPlantSeedConfirmView';
import { PurchasableClothingConfirmView } from './views/purchaseable-clothing/PurchasableClothingConfirmView'; import { PurchasableClothingConfirmView } from './views/PurchasableClothingConfirmView';
const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION'; const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION';
const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION'; const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION';
@ -26,22 +26,24 @@ export const FurnitureContextMenuView: FC<{}> = props =>
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1); const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null); const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
const [ isGroupMember, setIsGroupMember ] = useState(false); const [ isGroupMember, setIsGroupMember ] = useState(false);
const { roomSession = null, widgetHandler = null } = useRoomContext(); const { roomSession = null, widgetHandler = null } = useRoomContext();
const close = useCallback(() => const close = useCallback(() =>
{
BatchUpdates(() =>
{ {
setObjectId(-1); setObjectId(-1);
setGroupData(null); setGroupData(null);
setIsGroupMember(false); setIsGroupMember(false);
setMode(null); setMode(null);
});
}, []); }, []);
const closeConfirm = useCallback(() => const closeConfirm = () =>
{ {
setConfirmMode(null); setConfirmMode(null);
setConfirmingObjectId(-1); setConfirmingObjectId(-1);
}, []); }
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) => const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
{ {
@ -54,28 +56,40 @@ export const FurnitureContextMenuView: FC<{}> = props =>
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG: case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return; if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id); setConfirmingObjectId(object.id);
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION); setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
});
close(); close();
return; return;
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG: case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return; if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id); setConfirmingObjectId(object.id);
setConfirmMode(EFFECTBOX_OPEN); setConfirmMode(EFFECTBOX_OPEN);
});
close(); close();
return; return;
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG: case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return; if(!IsOwnerOfFurniture(object)) return;
BatchUpdates(() =>
{
setConfirmingObjectId(object.id); setConfirmingObjectId(object.id);
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION); setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
});
close(); close();
return; return;
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU: case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
BatchUpdates(() =>
{
setObjectId(object.id); setObjectId(object.id);
switch(event.contextMenu) switch(event.contextMenu)
@ -95,6 +109,7 @@ export const FurnitureContextMenuView: FC<{}> = props =>
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING); if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
return; return;
} }
});
return; return;
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU: case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
@ -113,15 +128,18 @@ export const FurnitureContextMenuView: FC<{}> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
BatchUpdates(() =>
{
setObjectId(parser.objectId); setObjectId(parser.objectId);
setGroupData(parser); setGroupData(parser);
setIsGroupMember(parser.userIsMember); setIsGroupMember(parser.userIsMember);
setMode(GROUP_FURNITURE); setMode(GROUP_FURNITURE);
});
}, []); }, []);
CreateMessageHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent); CreateMessageHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);
const processAction = useCallback((name: string) => const processAction = (name: string) =>
{ {
if(name) if(name)
{ {
@ -152,7 +170,7 @@ export const FurnitureContextMenuView: FC<{}> = props =>
} }
close(); close();
}, [ roomSession, widgetHandler, objectId, groupData, close ]); }
return ( return (
<> <>

View File

@ -0,0 +1,41 @@
import { FC } from 'react';
import { LocalizeText } from '../../../../../../api';
import { Button, Column, Flex, Text } from '../../../../../../common';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
import { useRoomContext } from '../../../../context/RoomContext';
interface EffectBoxConfirmViewProps
{
objectId: number;
close: () => void;
}
export const EffectBoxConfirmView: FC<EffectBoxConfirmViewProps> = props =>
{
const { objectId = -1, close = null } = props;
const { roomSession = null } = useRoomContext();
const useProduct = () =>
{
roomSession.useMultistateItem(objectId);
close();
}
return (
<NitroCardView className="nitro-use-product-confirmation">
<NitroCardHeaderView headerText={ LocalizeText('effectbox.header.title') } onCloseClick={ close } />
<NitroCardContentView center>
<Flex gap={ 2 }>
<Column justifyContent="between">
<Text>{ LocalizeText('effectbox.header.description') }</Text>
<Flex alignItems="center" justifyContent="between">
<Button variant="danger" onClick={ close }>{ LocalizeText('generic.cancel') }</Button>
<Button variant="success" onClick={ useProduct }>{ LocalizeText('generic.ok') }</Button>
</Flex>
</Column>
</Flex>
</NitroCardContentView>
</NitroCardView>
);
}

View File

@ -1,10 +1,16 @@
import { IFurnitureData, RoomObjectCategory } from '@nitrots/nitro-renderer'; import { IFurnitureData, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetFurnitureDataForRoomObject, LocalizeText, RoomWidgetUseProductMessage } from '../../../../../../../api'; import { GetFurnitureDataForRoomObject, LocalizeText, RoomWidgetUseProductMessage } from '../../../../../../api';
import { FurniCategory } from '../../../../../../../components/inventory/common/FurniCategory'; import { Base, Button, Column, Flex, Text } from '../../../../../../common';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout'; import { FurniCategory } from '../../../../../../components/inventory/common/FurniCategory';
import { useRoomContext } from '../../../../../context/RoomContext'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
import { MonsterPlantSeedConfirmViewProps } from './MonsterPlantSeedConfirmView.types'; import { useRoomContext } from '../../../../context/RoomContext';
interface MonsterPlantSeedConfirmViewProps
{
objectId: number;
close: () => void;
}
const MODE_DEFAULT: number = -1; const MODE_DEFAULT: number = -1;
const MODE_MONSTERPLANT_SEED: number = 0; const MODE_MONSTERPLANT_SEED: number = 0;
@ -16,12 +22,12 @@ export const MonsterPlantSeedConfirmView: FC<MonsterPlantSeedConfirmViewProps> =
const [ mode, setMode ] = useState(MODE_DEFAULT); const [ mode, setMode ] = useState(MODE_DEFAULT);
const { roomSession = null, widgetHandler = null } = useRoomContext(); const { roomSession = null, widgetHandler = null } = useRoomContext();
const useProduct = useCallback(() => const useProduct = () =>
{ {
widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.MONSTERPLANT_SEED, objectId)); widgetHandler.processWidgetMessage(new RoomWidgetUseProductMessage(RoomWidgetUseProductMessage.MONSTERPLANT_SEED, objectId));
close(); close();
}, [ widgetHandler, objectId, close ]); }
useEffect(() => useEffect(() =>
{ {
@ -57,24 +63,24 @@ export const MonsterPlantSeedConfirmView: FC<MonsterPlantSeedConfirmViewProps> =
return ( return (
<NitroCardView className="nitro-use-product-confirmation"> <NitroCardView className="nitro-use-product-confirmation">
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.plant_seed', [ 'name' ], [ furniData.name ]) } onCloseClick={ close } /> <NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.plant_seed', [ 'name' ], [ furniData.name ]) } onCloseClick={ close } />
<NitroCardContentView className="d-flex"> <NitroCardContentView center>
<div className="row"> <Flex gap={ 2 } overflow="hidden">
<div className="w-unset"> <Column>
<div className="product-preview"> <Base className="product-preview">
<div className="monsterplant-image" /> <Base className="monsterplant-image" />
</div> </Base>
</div> </Column>
<div className="col d-flex flex-column justify-content-between"> <Column justifyContent="between" overflow="auto">
<div className="d-flex flex-column"> <Column gap={ 2 }>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.plant_seed', [ 'productName' ], [ furniData.name ] ) }</div> <Text>{ LocalizeText('useproduct.widget.text.plant_seed', [ 'productName' ], [ furniData.name ] ) }</Text>
<div className="text-black">{ LocalizeText('useproduct.widget.info.plant_seed') }</div> <Text>{ LocalizeText('useproduct.widget.info.plant_seed') }</Text>
</div> </Column>
<div className="d-flex justify-content-between align-items-end w-100 h-100"> <Flex alignItems="center" justifyContent="between">
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button> <Button variant="danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</Button>
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('widget.monsterplant_seed.button.use') }</button> <Button variant="success" onClick={ useProduct }>{ LocalizeText('widget.monsterplant_seed.button.use') }</Button>
</div> </Flex>
</div> </Column>
</div> </Flex>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -1,12 +1,18 @@
import { RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer'; import { RedeemItemClothingComposer, RoomObjectCategory, UserFigureComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../../../api'; import { GetAvatarRenderManager, GetConnection, GetFurnitureDataForRoomObject, GetSessionDataManager, LocalizeText } from '../../../../../../api';
import { FigureData } from '../../../../../../../components/avatar-editor/common/FigureData'; import { Base, Button, Column, Flex, Text } from '../../../../../../common';
import { FurniCategory } from '../../../../../../../components/inventory/common/FurniCategory'; import { FigureData } from '../../../../../../components/avatar-editor/common/FigureData';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout'; import { FurniCategory } from '../../../../../../components/inventory/common/FurniCategory';
import { AvatarImageView } from '../../../../../../shared/avatar-image/AvatarImageView'; import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../layout';
import { useRoomContext } from '../../../../../context/RoomContext'; import { AvatarImageView } from '../../../../../shared/avatar-image/AvatarImageView';
import { PurchasableClothingConfirmViewProps } from './PurchasableClothingConfirmView.types'; import { useRoomContext } from '../../../../context/RoomContext';
interface PurchasableClothingConfirmViewProps
{
objectId: number;
close: () => void;
}
const MODE_DEFAULT: number = -1; const MODE_DEFAULT: number = -1;
const MODE_PURCHASABLE_CLOTHING: number = 0; const MODE_PURCHASABLE_CLOTHING: number = 0;
@ -19,13 +25,13 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
const [ newFigure, setNewFigure ] = useState<string>(null); const [ newFigure, setNewFigure ] = useState<string>(null);
const { roomSession = null } = useRoomContext(); const { roomSession = null } = useRoomContext();
const useProduct = useCallback(() => const useProduct = () =>
{ {
GetConnection().send(new RedeemItemClothingComposer(objectId)); GetConnection().send(new RedeemItemClothingComposer(objectId));
GetConnection().send(new UserFigureComposer(gender, newFigure)); GetConnection().send(new UserFigureComposer(gender, newFigure));
close(); close();
}, [ objectId, gender, newFigure, close ]); }
useEffect(() => useEffect(() =>
{ {
@ -78,24 +84,24 @@ export const PurchasableClothingConfirmView: FC<PurchasableClothingConfirmViewPr
return ( return (
<NitroCardView className="nitro-use-product-confirmation"> <NitroCardView className="nitro-use-product-confirmation">
<NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.bind_clothing') } onCloseClick={ close } /> <NitroCardHeaderView headerText={ LocalizeText('useproduct.widget.title.bind_clothing') } onCloseClick={ close } />
<NitroCardContentView className="d-flex"> <NitroCardContentView center>
<div className="row"> <Flex gap={ 2 } overflow="hidden">
<div className="w-unset"> <Column>
<div className="mannequin-preview"> <Base className="mannequin-preview">
<AvatarImageView figure={ newFigure } direction={ 2 } /> <AvatarImageView figure={ newFigure } direction={ 2 } />
</div> </Base>
</div> </Column>
<div className="col d-flex flex-column justify-content-between"> <Column justifyContent="between" overflow="auto">
<div className="d-flex flex-column"> <Column gap={ 2 }>
<div className="text-black mb-3">{ LocalizeText('useproduct.widget.text.bind_clothing') }</div> <Text>{ LocalizeText('useproduct.widget.text.bind_clothing') }</Text>
<div className="text-black">{ LocalizeText('useproduct.widget.info.bind_clothing') }</div> <Text>{ LocalizeText('useproduct.widget.info.bind_clothing') }</Text>
</div> </Column>
<div className="d-flex justify-content-between align-items-end w-100 h-100"> <Flex alignItems="center" justifyContent="between">
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</button> <Button variant="danger" onClick={ close }>{ LocalizeText('useproduct.widget.cancel') }</Button>
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('useproduct.widget.bind_clothing') }</button> <Button variant="success" onClick={ useProduct }>{ LocalizeText('useproduct.widget.bind_clothing') }</Button>
</div> </Flex>
</div> </Column>
</div> </Flex>
</NitroCardContentView> </NitroCardContentView>
</NitroCardView> </NitroCardView>
); );

View File

@ -1,37 +0,0 @@
import { FC, useCallback } from 'react';
import { LocalizeText } from '../../../../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../../../layout';
import { useRoomContext } from '../../../../../context/RoomContext';
import { EffectBoxConfirmViewProps } from './EffectBoxConfirmView.types';
export const EffectBoxConfirmView: FC<EffectBoxConfirmViewProps> = props =>
{
const { objectId = -1, close = null } = props;
const { roomSession = null, widgetHandler = null } = useRoomContext();
const useProduct = useCallback(() =>
{
roomSession.useMultistateItem(objectId);
close();
}, [ roomSession, objectId, close ]);
return (
<NitroCardView className="nitro-use-product-confirmation">
<NitroCardHeaderView headerText={ LocalizeText('effectbox.header.title') } onCloseClick={ close } />
<NitroCardContentView className="d-flex">
<div className="row">
<div className="col d-flex flex-column justify-content-between">
<div className="d-flex flex-column">
<div className="text-black">{ LocalizeText('effectbox.header.description') }</div>
</div>
<div className="d-flex justify-content-between align-items-end w-100 h-100">
<button type="button" className="btn btn-danger" onClick={ close }>{ LocalizeText('generic.cancel') }</button>
<button type="button" className="btn btn-primary" onClick={ useProduct }>{ LocalizeText('generic.ok') }</button>
</div>
</div>
</div>
</NitroCardContentView>
</NitroCardView>
);
}

View File

@ -1,5 +0,0 @@
export interface EffectBoxConfirmViewProps
{
objectId: number;
close: () => void;
}

View File

@ -1,5 +0,0 @@
export interface MonsterPlantSeedConfirmViewProps
{
objectId: number;
close: () => void;
}

View File

@ -1,5 +0,0 @@
export interface PurchasableClothingConfirmViewProps
{
objectId: number;
close: () => void;
}