This commit is contained in:
Bill 2022-07-12 23:17:51 -04:00
parent 5412f3d3b3
commit fe6dd25859
11 changed files with 210 additions and 181 deletions

15
.vscode/settings.json vendored
View File

@ -4,9 +4,9 @@
"typescript.preferences.quoteStyle": "single",
"typescript.format.placeOpenBraceOnNewLineForControlBlocks": true,
"typescript.format.placeOpenBraceOnNewLineForFunctions": true,
"typescript.format.enable": false,
"editor.codeActionsOnSave": {
"source.fixAll": true,
"source.fixAll.sortJSON": false,
"source.fixAll.eslint": true,
"source.organizeImports": true
},
"git.ignoreLimitWarning": true,
@ -15,6 +15,13 @@
"files.trimFinalNewlines": true,
"editor.wordWrap": "on",
"emmet.showExpandedAbbreviation": "never",
"eslint.validate": [ "javascript", "javascriptreact", "html", "typescriptreact" ],
"eslint.workingDirectories": [ "./src" ]
"eslint.validate": [
"javascript",
"javascriptreact",
"html",
"typescriptreact"
],
"eslint.workingDirectories": [
"./src"
]
}

View File

@ -7,7 +7,6 @@ export * from './IRoomModel';
export * from './IRoomModerationSettings';
export * from './NavigatorSearchResultViewDisplayMode';
export * from './RoomInfoData';
export * from './RoomSettingsData';
export * from './RoomSettingsUtils';
export * from './SearchFilterOptions';
export * from './TryVisitRoom';

View File

@ -31,11 +31,9 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
const [ opacity, setOpacity ] = useState(1);
const [ isFading, setIsFading ] = useState(false);
const [ fadeTime, setFadeTime ] = useState(0);
const [ isFrozen, setIsFrozen ] = useState(false);
const [ isCollapsed, setIsCollapsed ] = useState(COLLAPSED);
const elementRef = useRef<HTMLDivElement>();
const [ collapsed, setCollapsed ] = useState(COLLAPSED);
const getOffset = useCallback((bounds: NitroRectangle) =>
{
let height = -(elementRef.current.offsetHeight);
@ -125,14 +123,14 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
{
const newClassNames: string[] = [ 'nitro-context-menu' ];
if (collapsed) newClassNames.push('menu-hidden');
if (isCollapsed) newClassNames.push('menu-hidden');
newClassNames.push((pos.x !== null) ? 'visible' : 'invisible');
if(classNames.length) newClassNames.push(...classNames);
return newClassNames;
}, [ pos, classNames, collapsed ]);
}, [ pos, classNames, isCollapsed ]);
const getStyle = useMemo(() =>
{
@ -155,20 +153,13 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
useEffect(() =>
{
let added = false;
if(!isFrozen)
{
added = true;
GetTicker().add(update);
}
return () =>
{
if(added) GetTicker().remove(update);
GetTicker().remove(update);
}
}, [ isFrozen, update ]);
}, [ update ]);
useEffect(() =>
{
@ -183,10 +174,13 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
const toggleCollapse = () =>
{
COLLAPSED = !COLLAPSED;
setCollapsed(COLLAPSED)
setIsCollapsed(COLLAPSED);
setOpacity(0);
console.log(opacity);
}
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } onMouseOver={ event => setIsFrozen(true) } onMouseOut={ event => setIsFrozen(false) } { ...rest }>
return <Base innerRef={ elementRef } position={ position } classNames={ getClassNames } style={ getStyle } { ...rest }>
{ !(collapsable && COLLAPSED) && children }
{ collapsable && <ContextMenuCaretView onClick={ () => toggleCollapse() } collapsed={ collapsed } /> }
{ collapsable && <ContextMenuCaretView onClick={ () => toggleCollapse() } collapsed={ isCollapsed } /> }
</Base>;
}

View File

@ -24,7 +24,7 @@ export const FurnitureCustomStackHeightView: FC<{}> = props =>
value={ height }
onChange={ event => updateHeight(event) }
renderThumb={ (props, state) => <div { ...props }>{ state.valueNow }</div> } />
<input type="number" min={ 0 } max={ maxHeight } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
<input className="show-number-arrows" type="number" min={ 0 } max={ maxHeight } value={ height } onChange={ event => updateHeight(parseFloat(event.target.value)) } />
</Flex>
<Column gap={ 1 }>
<Button onClick={ event => sendUpdate(-100) }>

View File

@ -1,8 +1,7 @@
import { ContextMenuEnum, GroupFurniContextMenuInfoMessageEvent, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react';
import { GetGroupInformation, GetRoomEngine, IsOwnerOfFurniture, LocalizeText, RoomWidgetFurniActionMessage, TryJoinGroup, TryVisitRoom } from '../../../../../api';
import { UseMessageEventHook, UseRoomEngineEvent } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext';
import { ContextMenuEnum, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { FC } from 'react';
import { GetGroupInformation, LocalizeText } from '../../../../../api';
import { useFurnitureContextMenuWidget } from '../../../../../hooks';
import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView';
import { ContextMenuListItemView } from '../../context-menu/ContextMenuListItemView';
import { ContextMenuView } from '../../context-menu/ContextMenuView';
@ -17,145 +16,16 @@ const EFFECTBOX_OPEN: string = 'EFFECTBOX_OPEN';
export const FurnitureContextMenuView: FC<{}> = props =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ mode, setMode ] = useState<string>(null);
const [ confirmMode, setConfirmMode ] = useState<string>(null);
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
const [ isGroupMember, setIsGroupMember ] = useState(false);
const { roomSession = null, widgetHandler = null } = useRoomContext();
const close = useCallback(() =>
{
setObjectId(-1);
setGroupData(null);
setIsGroupMember(false);
setMode(null);
}, []);
const closeConfirm = () =>
{
setConfirmMode(null);
setConfirmingObjectId(-1);
}
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
{
const object = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, event.category);
if(!object) return;
switch(event.type)
{
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(EFFECTBOX_OPEN);
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
close();
return;
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
setObjectId(object.id);
switch(event.contextMenu)
{
case ContextMenuEnum.FRIEND_FURNITURE:
setMode(ContextMenuEnum.FRIEND_FURNITURE);
return;
case ContextMenuEnum.MONSTERPLANT_SEED:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MONSTERPLANT_SEED);
return;
case ContextMenuEnum.MYSTERY_BOX:
return;
case ContextMenuEnum.RANDOM_TELEPORT:
setMode(ContextMenuEnum.RANDOM_TELEPORT);
return;
case ContextMenuEnum.PURCHASABLE_CLOTHING:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
return;
}
return;
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
if(object.id === objectId) close();
return;
}
}, [ roomSession, objectId, close ]);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG, onRoomEngineTriggerWidgetEvent);
const onGroupFurniContextMenuInfoMessageEvent = useCallback((event: GroupFurniContextMenuInfoMessageEvent) =>
{
const parser = event.getParser();
setObjectId(parser.objectId);
setGroupData(parser);
setIsGroupMember(parser.userIsMember);
setMode(GROUP_FURNITURE);
}, []);
UseMessageEventHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);
const processAction = (name: string) =>
{
if(name)
{
switch(name)
{
case 'use_friend_furni':
roomSession.useMultistateItem(objectId);
break;
case 'use_monsterplant_seed':
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'use_random_teleport':
widgetHandler.processWidgetMessage(new RoomWidgetFurniActionMessage(RoomWidgetFurniActionMessage.USE, objectId, RoomObjectCategory.FLOOR));
break;
case 'use_purchaseable_clothing':
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'join_group':
TryJoinGroup(groupData.guildId);
setIsGroupMember(true);
return;
case 'go_to_group_homeroom':
if(groupData) TryVisitRoom(groupData.guildHomeRoomId);
break;
}
}
close();
}
const { closeConfirm = null, processAction = null, objectId = -1, mode = null, confirmMode = null, confirmingObjectId = -1, groupData = null, isGroupMember = false } = useFurnitureContextMenuWidget();
return (
<>
{ (confirmMode === MONSTERPLANT_SEED_CONFIRMATION) && <MonsterPlantSeedConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (confirmMode === PURCHASABLE_CLOTHING_CONFIRMATION) && <PurchasableClothingConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (confirmMode === EFFECTBOX_OPEN) && <EffectBoxConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (confirmMode === MONSTERPLANT_SEED_CONFIRMATION) &&
<MonsterPlantSeedConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (confirmMode === PURCHASABLE_CLOTHING_CONFIRMATION) &&
<PurchasableClothingConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (confirmMode === EFFECTBOX_OPEN) &&
<EffectBoxConfirmView objectId={ confirmingObjectId } close={ closeConfirm } /> }
{ (objectId >= 0) && mode &&
<ContextMenuView objectId={ objectId } category={ RoomObjectCategory.FLOOR } close={ close } fades={ true }>
{ (mode === ContextMenuEnum.FRIEND_FURNITURE) &&
@ -199,13 +69,15 @@ export const FurnitureContextMenuView: FC<{}> = props =>
<ContextMenuHeaderView className="cursor-pointer text-truncate" onClick={ () => GetGroupInformation(groupData.guildId) }>
{ groupData.guildName }
</ContextMenuHeaderView>
{ !isGroupMember && <ContextMenuListItemView onClick={ event => processAction('join_group') }>
{ !isGroupMember &&
<ContextMenuListItemView onClick={ event => processAction('join_group') }>
{ LocalizeText('widget.furniture.button.join.group') }
</ContextMenuListItemView> }
<ContextMenuListItemView onClick={ event => processAction('go_to_group_homeroom') }>
{ LocalizeText('widget.furniture.button.go.to.group.home.room') }
</ContextMenuListItemView>
{ groupData.guildHasReadableForum && <ContextMenuListItemView onClick={ event => processAction('open_forum') }>
{ groupData.guildHasReadableForum &&
<ContextMenuListItemView onClick={ event => processAction('open_forum') }>
{ LocalizeText('widget.furniture.button.open_group_forum') }
</ContextMenuListItemView> }
</> }

View File

@ -17,7 +17,7 @@ export const WiredTriggerBotReachedStuffView: FC<{}> = props =>
}, [ trigger ]);
return (
<WiredTriggerBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_NONE } hasSpecialInput={ true } save={ save }>
<WiredTriggerBaseView requiresFurni={ WiredFurniType.STUFF_SELECTION_OPTION_BY_ID_OR_BY_TYPE } hasSpecialInput={ true } save={ save }>
<Column gap={ 1 }>
<Text bold>{ LocalizeText('wiredfurni.params.bot.name') }</Text>
<input type="text" className="form-control form-control-sm" maxLength={ 32 } value={ botName } onChange={ event => setBotName(event.target.value) } />

View File

@ -1,5 +1,6 @@
export * from './useFurnitureBackgroundColorWidget';
export * from './useFurnitureBadgeDisplayWidget';
export * from './useFurnitureContextMenuWidget';
export * from './useFurnitureDimmerWidget';
export * from './useFurnitureExchangeWidget';
export * from './useFurnitureExternalImageWidget';

View File

@ -0,0 +1,152 @@
import { ContextMenuEnum, GroupFurniContextMenuInfoMessageEvent, GroupFurniContextMenuInfoMessageParser, RoomEngineTriggerWidgetEvent, RoomObjectCategory } from '@nitrots/nitro-renderer';
import { useCallback, useState } from 'react';
import { GetRoomEngine, IsOwnerOfFurniture, RoomWidgetFurniActionMessage, TryJoinGroup, TryVisitRoom } from '../../../../api';
import { UseRoomEngineEvent } from '../../../events';
import { UseMessageEventHook } from '../../../messages';
import { useRoom } from '../../useRoom';
const MONSTERPLANT_SEED_CONFIRMATION: string = 'MONSTERPLANT_SEED_CONFIRMATION';
const PURCHASABLE_CLOTHING_CONFIRMATION: string = 'PURCHASABLE_CLOTHING_CONFIRMATION';
const GROUP_FURNITURE: string = 'GROUP_FURNITURE';
const EFFECTBOX_OPEN: string = 'EFFECTBOX_OPEN';
const useFurnitureContextMenuWidgetState = () =>
{
const [ objectId, setObjectId ] = useState(-1);
const [ mode, setMode ] = useState<string>(null);
const [ confirmMode, setConfirmMode ] = useState<string>(null);
const [ confirmingObjectId, setConfirmingObjectId ] = useState(-1);
const [ groupData, setGroupData ] = useState<GroupFurniContextMenuInfoMessageParser>(null);
const [ isGroupMember, setIsGroupMember ] = useState(false);
const { roomSession = null, widgetHandler = null } = useRoom();
const close = useCallback(() =>
{
setObjectId(-1);
setGroupData(null);
setIsGroupMember(false);
setMode(null);
}, []);
const closeConfirm = () =>
{
setConfirmMode(null);
setConfirmingObjectId(-1);
}
const processAction = (name: string) =>
{
if(name)
{
switch(name)
{
case 'use_friend_furni':
roomSession.useMultistateItem(objectId);
break;
case 'use_monsterplant_seed':
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'use_random_teleport':
widgetHandler.processWidgetMessage(new RoomWidgetFurniActionMessage(RoomWidgetFurniActionMessage.USE, objectId, RoomObjectCategory.FLOOR));
break;
case 'use_purchaseable_clothing':
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
setConfirmingObjectId(objectId);
break;
case 'join_group':
TryJoinGroup(groupData.guildId);
setIsGroupMember(true);
return;
case 'go_to_group_homeroom':
if(groupData) TryVisitRoom(groupData.guildHomeRoomId);
break;
}
}
close();
}
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
{
const object = GetRoomEngine().getRoomObject(roomSession.roomId, event.objectId, event.category);
if(!object) return;
switch(event.type)
{
case RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(MONSTERPLANT_SEED_CONFIRMATION);
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(EFFECTBOX_OPEN);
close();
return;
case RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG:
if(!IsOwnerOfFurniture(object)) return;
setConfirmingObjectId(object.id);
setConfirmMode(PURCHASABLE_CLOTHING_CONFIRMATION);
close();
return;
case RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU:
setObjectId(object.id);
switch(event.contextMenu)
{
case ContextMenuEnum.FRIEND_FURNITURE:
setMode(ContextMenuEnum.FRIEND_FURNITURE);
return;
case ContextMenuEnum.MONSTERPLANT_SEED:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.MONSTERPLANT_SEED);
return;
case ContextMenuEnum.MYSTERY_BOX:
return;
case ContextMenuEnum.RANDOM_TELEPORT:
setMode(ContextMenuEnum.RANDOM_TELEPORT);
return;
case ContextMenuEnum.PURCHASABLE_CLOTHING:
if(IsOwnerOfFurniture(object)) setMode(ContextMenuEnum.PURCHASABLE_CLOTHING);
return;
}
return;
case RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU:
if(object.id === objectId) close();
return;
}
}, [ roomSession, objectId, close ]);
const onGroupFurniContextMenuInfoMessageEvent = useCallback((event: GroupFurniContextMenuInfoMessageEvent) =>
{
const parser = event.getParser();
setObjectId(parser.objectId);
setGroupData(parser);
setIsGroupMember(parser.userIsMember);
setMode(GROUP_FURNITURE);
}, []);
UseMessageEventHook(GroupFurniContextMenuInfoMessageEvent, onGroupFurniContextMenuInfoMessageEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.OPEN_FURNI_CONTEXT_MENU, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.CLOSE_FURNI_CONTEXT_MENU, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_MONSTERPLANT_SEED_PLANT_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_PURCHASABLE_CLOTHING_CONFIRMATION_DIALOG, onRoomEngineTriggerWidgetEvent);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_EFFECTBOX_OPEN_DIALOG, onRoomEngineTriggerWidgetEvent);
return { objectId, mode, confirmMode, confirmingObjectId, groupData, isGroupMember, closeConfirm, processAction };
}
export const useFurnitureContextMenuWidget = useFurnitureContextMenuWidgetState;

View File

@ -1,6 +1,6 @@
import { RoomEngineTriggerWidgetEvent, RoomObjectVariable } from '@nitrots/nitro-renderer';
import { useCallback, useState } from 'react';
import { GetRoomEngine, GetRoomSession, GetSessionDataManager } from '../../../../api';
import { GetRoomEngine, GetRoomSession, GetSessionDataManager, IsOwnerOfFurniture } from '../../../../api';
import { UseRoomEngineEvent } from '../../../events';
import { useFurniRemovedEvent } from '../../useFurniRemovedEvent';
@ -10,8 +10,7 @@ const useFurnitureStickieWidgetState = () =>
const [ category, setCategory ] = useState(-1);
const [ color, setColor ] = useState('0');
const [ text, setText ] = useState('');
const canModify = (GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator);
const [ canModify, setCanModify ] = useState(false);
const close = useCallback(() =>
{
@ -19,6 +18,7 @@ const useFurnitureStickieWidgetState = () =>
setCategory(-1);
setColor('0');
setText('');
setCanModify(false);
}, []);
const updateColor = (newColor: string) =>
@ -39,7 +39,7 @@ const useFurnitureStickieWidgetState = () =>
const trash = () => GetRoomEngine().deleteRoomObject(objectId, category);
const onRoomEngineTriggerWidgetEvent = useCallback((event: RoomEngineTriggerWidgetEvent) =>
UseRoomEngineEvent<RoomEngineTriggerWidgetEvent>(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, event =>
{
const roomObject = GetRoomEngine().getRoomObject(event.roomId, event.objectId, event.category);
@ -66,9 +66,8 @@ const useFurnitureStickieWidgetState = () =>
setCategory(event.category);
setColor(color || '0');
setText(text || '');
}, []);
UseRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_STICKIE, onRoomEngineTriggerWidgetEvent);
setCanModify(GetRoomSession().isRoomOwner || GetSessionDataManager().isModerator || IsOwnerOfFurniture(roomObject));
});
useFurniRemovedEvent(((objectId !== -1) && (category !== -1)), event =>
{

View File

@ -0,0 +1,5 @@
import { useBetween } from 'use-between';
const useInfostandWidgetState = () => {};
export const useInfostandWidget = () => useBetween(useInfostandWidgetState);