mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Context menu updates
This commit is contained in:
parent
d601507d38
commit
64198100a1
@ -10,5 +10,5 @@ export function GetCanUseExpression(): boolean
|
|||||||
const model = roomObject.model;
|
const model = roomObject.model;
|
||||||
const effectId = model.getValue<number>(RoomObjectVariable.FIGURE_EFFECT);
|
const effectId = model.getValue<number>(RoomObjectVariable.FIGURE_EFFECT);
|
||||||
|
|
||||||
return ((effectId === 29) || (effectId === 30) || (effectId === 185));
|
return !((effectId === 29) || (effectId === 30) || (effectId === 185));
|
||||||
}
|
}
|
||||||
|
@ -102,6 +102,8 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
{
|
{
|
||||||
if(!infoStandEvent) return;
|
if(!infoStandEvent) return;
|
||||||
|
|
||||||
|
console.log('tru')
|
||||||
|
|
||||||
setInfoStandEvent(null);
|
setInfoStandEvent(null);
|
||||||
}, [ infoStandEvent ]);
|
}, [ infoStandEvent ]);
|
||||||
|
|
||||||
@ -119,7 +121,9 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
const onRoomWidgetUpdateInfostandEvent = useCallback((event: RoomWidgetUpdateInfostandEvent) =>
|
const onRoomWidgetUpdateInfostandEvent = useCallback((event: RoomWidgetUpdateInfostandEvent) =>
|
||||||
{
|
{
|
||||||
if(name) setName(null);
|
if(name) setName(null);
|
||||||
setInfoStandEvent(event);
|
|
||||||
|
if(event.type === RoomWidgetUpdateInfostandFurniEvent.FURNI) setInfoStandEvent(null);
|
||||||
|
else setInfoStandEvent(event);
|
||||||
}, [ name ]);
|
}, [ name ]);
|
||||||
|
|
||||||
CreateEventDispatcherHook(RoomWidgetUpdateInfostandFurniEvent.FURNI, eventDispatcher, onRoomWidgetUpdateInfostandEvent);
|
CreateEventDispatcherHook(RoomWidgetUpdateInfostandFurniEvent.FURNI, eventDispatcher, onRoomWidgetUpdateInfostandEvent);
|
||||||
@ -228,7 +232,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
|||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}, [ isGameMode, decorateView, name, isDancing, infoStandEvent, clearInfoStandEvent ]);
|
}, [ isGameMode, decorateView, name, isDancing, infoStandEvent, clearName, clearInfoStandEvent ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -1,9 +1,340 @@
|
|||||||
import { FC } from 'react';
|
import { RoomControllerLevel, RoomObjectCategory, RoomObjectVariable } from 'nitro-renderer';
|
||||||
|
import { FC, useCallback, useEffect, useMemo, useState } from 'react';
|
||||||
|
import { GetOwnRoomObject } from '../../../../../../api';
|
||||||
|
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||||
|
import { useRoomContext } from '../../../../context/RoomContext';
|
||||||
|
import { RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../messages';
|
||||||
|
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
||||||
|
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
||||||
|
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
||||||
import { AvatarInfoWidgetAvatarViewProps } from './AvatarInfoWidgetAvatarView.types';
|
import { AvatarInfoWidgetAvatarViewProps } from './AvatarInfoWidgetAvatarView.types';
|
||||||
|
|
||||||
|
const MODE_NORMAL = 0;
|
||||||
|
const MODE_MODERATE = 1;
|
||||||
|
const MODE_MODERATE_BAN = 2;
|
||||||
|
const MODE_MODERATE_MUTE = 3;
|
||||||
|
const MODE_AMBASSADOR = 4;
|
||||||
|
const MODE_AMBASSADOR_MUTE = 5;
|
||||||
|
|
||||||
export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = props =>
|
export const AvatarInfoWidgetAvatarView: FC<AvatarInfoWidgetAvatarViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { userData = null } = props;
|
const { userData = null, close = null } = props;
|
||||||
|
const [ mode, setMode ] = useState(MODE_NORMAL);
|
||||||
|
const [ respectsLeft, setRespectsLeft ] = useState(0);
|
||||||
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
return null;
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
setRespectsLeft(userData.respectLeft);
|
||||||
|
}, [ userData ])
|
||||||
|
|
||||||
|
const isShowGiveRights = useMemo(() =>
|
||||||
|
{
|
||||||
|
return (userData.amIOwner && (userData.targetRoomControllerLevel < RoomControllerLevel.GUEST) && !userData.isGuildRoom);
|
||||||
|
}, [ userData ]);
|
||||||
|
|
||||||
|
const isShowRemoveRights = useMemo(() =>
|
||||||
|
{
|
||||||
|
return (userData.amIOwner && (userData.targetRoomControllerLevel === RoomControllerLevel.GUEST) && !userData.isGuildRoom);
|
||||||
|
}, [ userData ]);
|
||||||
|
|
||||||
|
const moderateMenuHasContent = useMemo(() =>
|
||||||
|
{
|
||||||
|
return (userData.canBeKicked || userData.canBeBanned || userData.canBeMuted || isShowGiveRights || isShowRemoveRights);
|
||||||
|
}, [ isShowGiveRights, isShowRemoveRights, userData ]);
|
||||||
|
|
||||||
|
const processAction = useCallback((name: string) =>
|
||||||
|
{
|
||||||
|
let messageType: string = null;
|
||||||
|
let message: RoomWidgetMessage = null;
|
||||||
|
let hideMenu = true;
|
||||||
|
|
||||||
|
if(name)
|
||||||
|
{
|
||||||
|
switch(name)
|
||||||
|
{
|
||||||
|
case 'moderate':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_MODERATE);
|
||||||
|
break;
|
||||||
|
case 'ban':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_MODERATE_BAN);
|
||||||
|
break;
|
||||||
|
case 'mute':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_MODERATE_MUTE);
|
||||||
|
break;
|
||||||
|
case 'ambassador':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_AMBASSADOR);
|
||||||
|
break;
|
||||||
|
case 'ambassador_mute':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_AMBASSADOR_MUTE);
|
||||||
|
break;
|
||||||
|
case 'back_moderate':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_MODERATE);
|
||||||
|
break;
|
||||||
|
case 'back_ambassador':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_AMBASSADOR);
|
||||||
|
break;
|
||||||
|
case 'back':
|
||||||
|
hideMenu = false;
|
||||||
|
setMode(MODE_NORMAL);
|
||||||
|
break;
|
||||||
|
case 'whisper':
|
||||||
|
messageType = RoomWidgetUserActionMessage.WHISPER_USER;
|
||||||
|
break;
|
||||||
|
case 'friend':
|
||||||
|
//userData.canBeAskedAsFriend = false;
|
||||||
|
messageType = RoomWidgetUserActionMessage.SEND_FRIEND_REQUEST;
|
||||||
|
break;
|
||||||
|
case 'respect':
|
||||||
|
let newRespectsLeft = 0;
|
||||||
|
|
||||||
|
setRespectsLeft(prevValue =>
|
||||||
|
{
|
||||||
|
newRespectsLeft = (prevValue - 1);
|
||||||
|
|
||||||
|
return newRespectsLeft;
|
||||||
|
});
|
||||||
|
|
||||||
|
//userData.respectLeft--;
|
||||||
|
|
||||||
|
messageType = RoomWidgetUserActionMessage.RESPECT_USER;
|
||||||
|
|
||||||
|
if(newRespectsLeft > 0) hideMenu = false;
|
||||||
|
break;
|
||||||
|
case 'ignore':
|
||||||
|
messageType = RoomWidgetUserActionMessage.IGNORE_USER;
|
||||||
|
break;
|
||||||
|
case 'unignore':
|
||||||
|
messageType = RoomWidgetUserActionMessage.UNIGNORE_USER;
|
||||||
|
break;
|
||||||
|
case 'kick':
|
||||||
|
messageType = RoomWidgetUserActionMessage.KICK_USER;
|
||||||
|
break;
|
||||||
|
case 'ban_hour':
|
||||||
|
messageType = RoomWidgetUserActionMessage.BAN_USER_HOUR;
|
||||||
|
break;
|
||||||
|
case 'ban_day':
|
||||||
|
messageType = RoomWidgetUserActionMessage.BAN_USER_DAY;
|
||||||
|
break;
|
||||||
|
case 'perm_ban':
|
||||||
|
messageType = RoomWidgetUserActionMessage.BAN_USER_PERM;
|
||||||
|
break;
|
||||||
|
case 'mute_2min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.MUTE_USER_2MIN;
|
||||||
|
break;
|
||||||
|
case 'mute_5min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.MUTE_USER_5MIN;
|
||||||
|
break;
|
||||||
|
case 'mute_10min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.MUTE_USER_10MIN;
|
||||||
|
break;
|
||||||
|
case 'give_rights':
|
||||||
|
messageType = RoomWidgetUserActionMessage.GIVE_RIGHTS;
|
||||||
|
break;
|
||||||
|
case 'remove_rights':
|
||||||
|
messageType = RoomWidgetUserActionMessage.TAKE_RIGHTS;
|
||||||
|
break;
|
||||||
|
case 'trade':
|
||||||
|
messageType = RoomWidgetUserActionMessage.START_TRADING;
|
||||||
|
break;
|
||||||
|
case 'report':
|
||||||
|
messageType = RoomWidgetUserActionMessage.REPORT_CFH_OTHER;
|
||||||
|
break;
|
||||||
|
case 'pass_hand_item':
|
||||||
|
messageType = RoomWidgetUserActionMessage.PASS_CARRY_ITEM;
|
||||||
|
break;
|
||||||
|
case 'ambassador_alert':
|
||||||
|
messageType = RoomWidgetUserActionMessage.AMBASSADOR_ALERT_USER;
|
||||||
|
break;
|
||||||
|
case 'ambassador_kick':
|
||||||
|
messageType = RoomWidgetUserActionMessage.AMBASSADOR_KICK_USER;
|
||||||
|
break;
|
||||||
|
case 'ambassador_mute_2min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.MUTE_USER_2MIN;
|
||||||
|
break;
|
||||||
|
case 'ambassador_mute_10min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_10MIN;
|
||||||
|
break;
|
||||||
|
case 'ambassador_mute_60min':
|
||||||
|
messageType = RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_60MIN;
|
||||||
|
break;
|
||||||
|
case 'ambassador_mute_18hour':
|
||||||
|
messageType = RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_18HOUR;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(messageType) message = new RoomWidgetUserActionMessage(messageType, userData.webID);
|
||||||
|
|
||||||
|
if(message) widgetHandler.processWidgetMessage(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hideMenu) close();
|
||||||
|
}, [ widgetHandler, userData, close ]);
|
||||||
|
|
||||||
|
const canGiveHandItem = useMemo(() =>
|
||||||
|
{
|
||||||
|
let flag = false;
|
||||||
|
|
||||||
|
const roomObject = GetOwnRoomObject();
|
||||||
|
|
||||||
|
if(roomObject)
|
||||||
|
{
|
||||||
|
const carryId = roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT);
|
||||||
|
|
||||||
|
if((carryId > 0) && (carryId < 999999)) flag = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return flag;
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ContextMenuView objectId={ userData.roomIndex } category={ RoomObjectCategory.UNIT } close={ close }>
|
||||||
|
<ContextMenuHeaderView>
|
||||||
|
{ userData.name }
|
||||||
|
</ContextMenuHeaderView>
|
||||||
|
{ (mode === MODE_NORMAL) &&
|
||||||
|
<>
|
||||||
|
{ userData.canBeAskedAsFriend &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('friend') }>
|
||||||
|
{ LocalizeText('infostand.button.friend') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('trade') }>
|
||||||
|
{ LocalizeText('infostand.button.trade') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('whisper') }>
|
||||||
|
{ LocalizeText('infostand.button.whisper') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
{ (respectsLeft > 0) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('respect') }>
|
||||||
|
{ LocalizeText('infostand.button.respect', [ 'count' ], [ respectsLeft.toString() ]) }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ !userData.isIgnored &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ignore') }>
|
||||||
|
{ LocalizeText('infostand.button.ignore') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ userData.isIgnored &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('unignore') }>
|
||||||
|
{ LocalizeText('infostand.button.unignore') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('report') }>
|
||||||
|
{ LocalizeText('infostand.button.report') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
{ moderateMenuHasContent &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('moderate') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
|
{ LocalizeText('infostand.link.moderate') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ userData.isAmbassador &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
|
{ LocalizeText('infostand.link.ambassador') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ canGiveHandItem && <ContextMenuListItemView onClick={ event => processAction('pass_hand_item') }>
|
||||||
|
{ LocalizeText('avatar.widget.pass_hand_item') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_MODERATE) &&
|
||||||
|
<>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('kick') }>
|
||||||
|
{ LocalizeText('infostand.button.kick') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('mute') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
|
{ LocalizeText('infostand.button.mute') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ban') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
|
{ LocalizeText('infostand.button.ban') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
{ isShowGiveRights &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('give_rights') }>
|
||||||
|
{ LocalizeText('infostand.button.giverights') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ isShowRemoveRights &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('remove_rights') }>
|
||||||
|
{ LocalizeText('infostand.button.removerights') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_MODERATE_BAN) &&
|
||||||
|
<>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ban_hour') }>
|
||||||
|
{ LocalizeText('infostand.button.ban_hour') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ban_day') }>
|
||||||
|
{ LocalizeText('infostand.button.ban_day') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ban_perm') }>
|
||||||
|
{ LocalizeText('infostand.button.perm_ban') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_MODERATE_MUTE) &&
|
||||||
|
<>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('mute_2min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_2min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('mute_5min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_5min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('mute_10min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_10min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back_moderate') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_AMBASSADOR) &&
|
||||||
|
<>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_alert') }>
|
||||||
|
{ LocalizeText('infostand.button.alert') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_kick') }>
|
||||||
|
{ LocalizeText('infostand.button.kick') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
|
{ LocalizeText('infostand.button.mute') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_AMBASSADOR_MUTE) &&
|
||||||
|
<>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute_2min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_2min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute_10min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_10min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute_60min') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_60min') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('ambassador_mute_18hr') }>
|
||||||
|
{ LocalizeText('infostand.button.mute_18hour') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back_ambassador') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
|
</> }
|
||||||
|
</ContextMenuView>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { FC, useMemo } from 'react';
|
import { FC, useMemo } from 'react';
|
||||||
import { GetSessionDataManager } from '../../../../../../api';
|
import { GetSessionDataManager } from '../../../../../../api';
|
||||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
||||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
|
||||||
import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types';
|
import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types';
|
||||||
|
|
||||||
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props =>
|
||||||
@ -14,10 +13,10 @@ export const AvatarInfoWidgetNameView: FC<AvatarInfoWidgetNameViewProps> = props
|
|||||||
}, [ nameData ]);
|
}, [ nameData ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ContextMenuView objectId={ nameData.roomIndex } category={ nameData.category } fades={ fades } close= { close }>
|
<ContextMenuView objectId={ nameData.roomIndex } category={ nameData.category } fades={ fades } className="name-only" close= { close }>
|
||||||
<ContextMenuHeaderView>
|
<div className="text-shadow">
|
||||||
{ nameData.name }
|
{ nameData.name }
|
||||||
</ContextMenuHeaderView>
|
</div>
|
||||||
</ContextMenuView>
|
</ContextMenuView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ import { AvatarAction, AvatarExpressionEnum, RoomObjectCategory } from 'nitro-re
|
|||||||
import { FC, useCallback, useState } from 'react';
|
import { FC, useCallback, useState } from 'react';
|
||||||
import { GetCanStandUp, GetCanUseExpression, GetOwnPosture, HasHabboClub, HasHabboVip, IsRidingHorse } from '../../../../../../api';
|
import { GetCanStandUp, GetCanUseExpression, GetOwnPosture, HasHabboClub, HasHabboVip, IsRidingHorse } from '../../../../../../api';
|
||||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||||
|
import { CurrencyIcon } from '../../../../../shared/currency-icon/CurrencyIcon';
|
||||||
import { useRoomContext } from '../../../../context/RoomContext';
|
import { useRoomContext } from '../../../../context/RoomContext';
|
||||||
import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../messages';
|
import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetUserActionMessage } from '../../../../messages';
|
||||||
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 { ContextMenuListView } from '../../../context-menu/views/list/ContextMenuListView';
|
|
||||||
import { AvatarInfoWidgetOwnAvatarViewProps } from './AvatarInfoWidgetOwnAvatarView.types';
|
import { AvatarInfoWidgetOwnAvatarViewProps } from './AvatarInfoWidgetOwnAvatarView.types';
|
||||||
|
|
||||||
const MODE_NORMAL = 0;
|
const MODE_NORMAL = 0;
|
||||||
@ -15,7 +15,6 @@ const MODE_CLUB_DANCES = 1;
|
|||||||
const MODE_NAME_CHANGE = 2;
|
const MODE_NAME_CHANGE = 2;
|
||||||
const MODE_EXPRESSIONS = 3;
|
const MODE_EXPRESSIONS = 3;
|
||||||
const MODE_SIGNS = 4;
|
const MODE_SIGNS = 4;
|
||||||
const MODE_CHANGE_LOOKS = 5;
|
|
||||||
|
|
||||||
export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProps> = props =>
|
export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProps> = props =>
|
||||||
{
|
{
|
||||||
@ -110,7 +109,6 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuHeaderView>
|
<ContextMenuHeaderView>
|
||||||
{ userData.name }
|
{ userData.name }
|
||||||
</ContextMenuHeaderView>
|
</ContextMenuHeaderView>
|
||||||
<ContextMenuListView columns={ (mode === MODE_SIGNS) ? 4 : 1 }>
|
|
||||||
{ (mode === MODE_NORMAL) &&
|
{ (mode === MODE_NORMAL) &&
|
||||||
<>
|
<>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('decorate') }>
|
<ContextMenuListItemView onClick={ event => processAction('decorate') }>
|
||||||
@ -121,6 +119,7 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ (HasHabboClub() && !isRidingHorse) &&
|
{ (HasHabboClub() && !isRidingHorse) &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('dance_menu') }>
|
<ContextMenuListItemView onClick={ event => processAction('dance_menu') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
{ LocalizeText('widget.memenu.dance') }
|
{ LocalizeText('widget.memenu.dance') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (!isDancing && !HasHabboClub() && !isRidingHorse) &&
|
{ (!isDancing && !HasHabboClub() && !isRidingHorse) &&
|
||||||
@ -132,9 +131,11 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.dance.stop') }
|
{ LocalizeText('widget.memenu.dance.stop') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
<ContextMenuListItemView onClick={ event => processAction('expressions') }>
|
<ContextMenuListItemView onClick={ event => processAction('expressions') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
{ LocalizeText('infostand.link.expressions') }
|
{ LocalizeText('infostand.link.expressions') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('signs') }>
|
<ContextMenuListItemView onClick={ event => processAction('signs') }>
|
||||||
|
<i className="fas fa-chevron-right right" />
|
||||||
{ LocalizeText('infostand.show.signs') }
|
{ LocalizeText('infostand.show.signs') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
{ (userData.carryItem > 0) &&
|
{ (userData.carryItem > 0) &&
|
||||||
@ -161,6 +162,7 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
{ LocalizeText('widget.memenu.dance4') }
|
{ LocalizeText('widget.memenu.dance4') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
@ -178,23 +180,27 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('wave') }>
|
<ContextMenuListItemView onClick={ event => processAction('wave') }>
|
||||||
{ LocalizeText('widget.memenu.wave') }
|
{ LocalizeText('widget.memenu.wave') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (GetCanUseExpression() && HasHabboVip()) &&
|
{ GetCanUseExpression() &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('laugh') }>
|
<ContextMenuListItemView canSelect={ HasHabboVip() } onClick={ event => processAction('laugh') }>
|
||||||
|
<CurrencyIcon type="hc" />
|
||||||
{ LocalizeText('widget.memenu.laugh') }
|
{ LocalizeText('widget.memenu.laugh') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
{ (GetCanUseExpression() && HasHabboVip()) &&
|
{ GetCanUseExpression() &&
|
||||||
<ContextMenuListItemView onClick={ event => processAction('blow') }>
|
<ContextMenuListItemView canSelect={ HasHabboVip() } onClick={ event => processAction('blow') }>
|
||||||
|
<CurrencyIcon type="hc" />
|
||||||
{ LocalizeText('widget.memenu.blow') }
|
{ LocalizeText('widget.memenu.blow') }
|
||||||
</ContextMenuListItemView> }
|
</ContextMenuListItemView> }
|
||||||
<ContextMenuListItemView onClick={ event => processAction('idle') }>
|
<ContextMenuListItemView onClick={ event => processAction('idle') }>
|
||||||
{ LocalizeText('widget.memenu.idle') }
|
{ LocalizeText('widget.memenu.idle') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
{ LocalizeText('generic.back') }
|
{ LocalizeText('generic.back') }
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
{ (mode === MODE_SIGNS) &&
|
{ (mode === MODE_SIGNS) &&
|
||||||
<>
|
<>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_1') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_1') }>
|
||||||
1
|
1
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -204,6 +210,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_3') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_3') }>
|
||||||
3
|
3
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_4') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_4') }>
|
||||||
4
|
4
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -213,6 +221,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_6') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_6') }>
|
||||||
6
|
6
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_7') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_7') }>
|
||||||
7
|
7
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -222,6 +232,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_9') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_9') }>
|
||||||
9
|
9
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_10') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_10') }>
|
||||||
10
|
10
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -231,6 +243,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_15') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_15') }>
|
||||||
<i className="icon icon-sign-smile" />
|
<i className="icon icon-sign-smile" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_12') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_12') }>
|
||||||
<i className="icon icon-sign-skull" />
|
<i className="icon icon-sign-skull" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -240,6 +254,8 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_17') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_17') }>
|
||||||
<i className="icon icon-sign-yellow" />
|
<i className="icon icon-sign-yellow" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<div className="d-flex menu-list-split-3">
|
||||||
<ContextMenuListItemView onClick={ event => processAction('sign_16') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_16') }>
|
||||||
<i className="icon icon-sign-red" />
|
<i className="icon icon-sign-red" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
@ -249,8 +265,12 @@ export const AvatarInfoWidgetOwnAvatarView: FC<AvatarInfoWidgetOwnAvatarViewProp
|
|||||||
<ContextMenuListItemView onClick={ event => processAction('sign_11') }>
|
<ContextMenuListItemView onClick={ event => processAction('sign_11') }>
|
||||||
<i className="icon icon-sign-heart" />
|
<i className="icon icon-sign-heart" />
|
||||||
</ContextMenuListItemView>
|
</ContextMenuListItemView>
|
||||||
|
</div>
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('back') }>
|
||||||
|
<i className="fas fa-chevron-left left" />
|
||||||
|
{ LocalizeText('generic.back') }
|
||||||
|
</ContextMenuListItemView>
|
||||||
</> }
|
</> }
|
||||||
</ContextMenuListView>
|
|
||||||
</ContextMenuView>
|
</ContextMenuView>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,189 @@
|
|||||||
import { FC } from 'react';
|
import { BotCommandConfigurationEvent, BotRemoveComposer, BotSkillSaveComposer, Nitro, RequestBotCommandConfigurationComposer, RoomObjectCategory } from 'nitro-renderer';
|
||||||
import { AvatarInfoWidgetRentableBotViewProps } from './AvatarInfoWidgetRentableBotView.types';
|
import { FC, useCallback, useState } from 'react';
|
||||||
|
import { GetConnection } from '../../../../../../api';
|
||||||
|
import { CreateMessageHook } from '../../../../../../hooks/messages';
|
||||||
|
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||||
|
import { useRoomContext } from '../../../../context/RoomContext';
|
||||||
|
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
||||||
|
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
||||||
|
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
||||||
|
import { BotSkillsEnum } from '../../utils/BotSkillsEnum';
|
||||||
|
import { AvatarInfoWidgetRentableBotViewProps, BotChatOptions } from './AvatarInfoWidgetRentableBotView.types';
|
||||||
|
|
||||||
|
const MODE_NORMAL = 0;
|
||||||
|
const MODE_CHANGE_NAME = 1;
|
||||||
|
const MODE_CHANGE_MOTTO = 2;
|
||||||
|
const MODE_CHANGE_SPEECH = 3;
|
||||||
|
|
||||||
export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotViewProps> = props =>
|
export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { rentableBotData = null } = props;
|
const { rentableBotData = null, close = null } = props;
|
||||||
|
const [ mode, setMode ] = useState(MODE_NORMAL);
|
||||||
|
const [ newName, setNewName ] = useState('');
|
||||||
|
const [ newMotto, setNewMotto ] = useState('');
|
||||||
|
const [ newChat, setNewChat ] = useState('');
|
||||||
|
const [ chatOptions, setChatOptions ] = useState<BotChatOptions>({ automaticChat: false, chatDelay: 0, mixSentences: false });
|
||||||
|
const { widgetHandler = null } = useRoomContext();
|
||||||
|
|
||||||
return null;
|
const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) =>
|
||||||
|
{
|
||||||
|
const parser = event.getParser();
|
||||||
|
|
||||||
|
if(!parser) return;
|
||||||
|
|
||||||
|
if(parser.botId !== rentableBotData.webID) return;
|
||||||
|
|
||||||
|
switch(parser.commandId)
|
||||||
|
{
|
||||||
|
case BotSkillsEnum.CHANGE_BOT_NAME:
|
||||||
|
setNewName(parser.data);
|
||||||
|
setMode(MODE_CHANGE_NAME);
|
||||||
|
return;
|
||||||
|
case BotSkillsEnum.CHANGE_BOT_MOTTO:
|
||||||
|
setNewMotto(parser.data);
|
||||||
|
setMode(MODE_CHANGE_MOTTO);
|
||||||
|
return;
|
||||||
|
case BotSkillsEnum.SETUP_CHAT: {
|
||||||
|
const data = parser.data;
|
||||||
|
const pieces = data.split(((data.indexOf(';#;') === -1) ? ';' : ';#;'));
|
||||||
|
|
||||||
|
if((pieces.length === 3) || (pieces.length === 4))
|
||||||
|
{
|
||||||
|
setNewChat(pieces[0]);
|
||||||
|
setChatOptions({
|
||||||
|
automaticChat: ((pieces[1].toLowerCase() === 'true') || (pieces[1] === '1')),
|
||||||
|
chatDelay: parseInt(pieces[2]),
|
||||||
|
mixSentences: ((pieces[3]) ? ((pieces[3].toLowerCase() === 'true') || (pieces[3] === '1')) : false)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setMode(MODE_CHANGE_SPEECH);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, [ rentableBotData ]);
|
||||||
|
|
||||||
|
CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent);
|
||||||
|
|
||||||
|
const requestBotCommandConfiguration = useCallback((skillType: number) =>
|
||||||
|
{
|
||||||
|
GetConnection().send(new RequestBotCommandConfigurationComposer(rentableBotData.webID, skillType));
|
||||||
|
}, [ rentableBotData ]);
|
||||||
|
|
||||||
|
const processAction = useCallback((name: string) =>
|
||||||
|
{
|
||||||
|
let hideMenu = true;
|
||||||
|
|
||||||
|
if(name)
|
||||||
|
{
|
||||||
|
switch(name)
|
||||||
|
{
|
||||||
|
case 'donate_to_all':
|
||||||
|
requestBotCommandConfiguration(BotSkillsEnum.DONATE_TO_ALL);
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.DONATE_TO_ALL, ''));
|
||||||
|
break;
|
||||||
|
case 'donate_to_user':
|
||||||
|
requestBotCommandConfiguration(BotSkillsEnum.DONATE_TO_USER);
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.DONATE_TO_USER, ''));
|
||||||
|
break;
|
||||||
|
case 'change_bot_name':
|
||||||
|
requestBotCommandConfiguration(BotSkillsEnum.CHANGE_BOT_NAME);
|
||||||
|
hideMenu = false;
|
||||||
|
break;
|
||||||
|
case 'save_bot_name':
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.CHANGE_BOT_NAME, newName));
|
||||||
|
break;
|
||||||
|
case 'change_bot_motto':
|
||||||
|
requestBotCommandConfiguration(BotSkillsEnum.CHANGE_BOT_MOTTO);
|
||||||
|
hideMenu = false;
|
||||||
|
break;
|
||||||
|
case 'save_bot_motto':
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.CHANGE_BOT_MOTTO, newMotto));
|
||||||
|
break;
|
||||||
|
case 'dress_up':
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.DRESS_UP, ''));
|
||||||
|
break;
|
||||||
|
case 'random_walk':
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.RANDOM_WALK, ''));
|
||||||
|
break;
|
||||||
|
case 'setup_chat':
|
||||||
|
requestBotCommandConfiguration(BotSkillsEnum.SETUP_CHAT);
|
||||||
|
hideMenu = false;
|
||||||
|
break;
|
||||||
|
case 'dance':
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.DANCE, ''));
|
||||||
|
break;
|
||||||
|
case 'nux_take_tour':
|
||||||
|
Nitro.instance.createLinkEvent('help/tour');
|
||||||
|
GetConnection().send(new BotSkillSaveComposer(rentableBotData.webID, BotSkillsEnum.NUX_TAKE_TOUR, ''));
|
||||||
|
break;
|
||||||
|
case 'pick':
|
||||||
|
GetConnection().send(new BotRemoveComposer(rentableBotData.webID));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(hideMenu) close();
|
||||||
|
}, [ rentableBotData, newName, newMotto, requestBotCommandConfiguration, close ]);
|
||||||
|
|
||||||
|
const canControl = (rentableBotData.amIOwner || rentableBotData.amIAnyRoomController);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ContextMenuView objectId={ rentableBotData.roomIndex } category={ RoomObjectCategory.UNIT } close={ close }>
|
||||||
|
<ContextMenuHeaderView>
|
||||||
|
{ rentableBotData.name }
|
||||||
|
</ContextMenuHeaderView>
|
||||||
|
{ (mode === MODE_NORMAL) &&
|
||||||
|
<>
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_ALL) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('donate_to_all') }>
|
||||||
|
{ LocalizeText('avatar.widget.donate_to_all') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DONATE_TO_USER) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('donate_to_user') }>
|
||||||
|
{ LocalizeText('avatar.widget.donate_to_user') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_NAME) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('change_bot_name') }>
|
||||||
|
{ LocalizeText('avatar.widget.change_bot_name') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.CHANGE_BOT_MOTTO) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('change_bot_motto') }>
|
||||||
|
{ LocalizeText('avatar.widget.change_bot_motto') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DRESS_UP) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('dress_up') }>
|
||||||
|
{ LocalizeText('avatar.widget.dress_up') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.RANDOM_WALK) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('random_walk') }>
|
||||||
|
{ LocalizeText('avatar.widget.random_walk') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.SETUP_CHAT) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('setup_chat') }>
|
||||||
|
{ LocalizeText('avatar.widget.setup_chat') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.DANCE) >= 0) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('dance') }>
|
||||||
|
{ LocalizeText('avatar.widget.dance') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
{ ((rentableBotData.botSkills.indexOf(BotSkillsEnum.NO_PICK_UP) === -1) && canControl) &&
|
||||||
|
<ContextMenuListItemView onClick={ event => processAction('pick') }>
|
||||||
|
{ LocalizeText('avatar.widget.pick_up') }
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
</> }
|
||||||
|
{ (mode === MODE_CHANGE_NAME) &&
|
||||||
|
<ContextMenuListItemView className="flex-column" onClick={ null }>
|
||||||
|
<p className="mb-1">{ LocalizeText('bot.skill.name.configuration.new.name') }</p>
|
||||||
|
<input type="text" className="form-control form-control-sm mb-2" value={ newName } onChange={ event => setNewName(event.target.value) } />
|
||||||
|
<div className="d-flex justify-content-between align-items-center">
|
||||||
|
<button type="button" className="btn btn-secondary btn-sm" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</button>
|
||||||
|
<button type="button" className="btn btn-success btn-sm" onClick={ event => processAction('save_bot_name') }>{ LocalizeText('save') }</button>
|
||||||
|
</div>
|
||||||
|
</ContextMenuListItemView> }
|
||||||
|
</ContextMenuView>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
@ -5,3 +5,10 @@ export interface AvatarInfoWidgetRentableBotViewProps
|
|||||||
rentableBotData: RoomWidgetUpdateInfostandRentableBotEvent;
|
rentableBotData: RoomWidgetUpdateInfostandRentableBotEvent;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface BotChatOptions
|
||||||
|
{
|
||||||
|
automaticChat: boolean;
|
||||||
|
chatDelay: number;
|
||||||
|
mixSentences: boolean;
|
||||||
|
}
|
||||||
|
@ -7,10 +7,20 @@
|
|||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
font-size: $font-size-sm;
|
font-size: $font-size-sm;
|
||||||
|
|
||||||
|
&.name-only {
|
||||||
|
background-color: rgba($black, 0.7);
|
||||||
|
padding: 1px 8px;
|
||||||
|
min-width: 60px;
|
||||||
|
width: unset;
|
||||||
|
max-width: unset;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 18px;
|
||||||
|
}
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: "";
|
content: "";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: -8px;
|
bottom: -7px;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
@ -19,7 +29,7 @@
|
|||||||
transform: rotate(45deg);
|
transform: rotate(45deg);
|
||||||
border-color: transparent rgba($white, 0.5) rgba($white, 0.5) transparent;
|
border-color: transparent rgba($white, 0.5) rgba($white, 0.5) transparent;
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 6px;
|
border-width: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-header {
|
.menu-header {
|
||||||
@ -27,25 +37,48 @@
|
|||||||
color: $white;
|
color: $white;
|
||||||
height: 25px;
|
height: 25px;
|
||||||
max-height: 25px;
|
max-height: 25px;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.menu-list {
|
.menu-list-split-3 {
|
||||||
margin: 0;
|
|
||||||
|
|
||||||
.menu-list-item-container {
|
|
||||||
margin-top: 2px;
|
|
||||||
|
|
||||||
.menu-list-item {
|
.menu-list-item {
|
||||||
|
margin-right: 2px;
|
||||||
|
|
||||||
|
&:nth-child(3n+3) {
|
||||||
|
margin-right: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menu-list-item {
|
||||||
|
position: relative;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
max-height: 24px;
|
max-height: 24px;
|
||||||
|
margin-top: 2px;
|
||||||
padding: 3px;
|
padding: 3px;
|
||||||
background: $bg-mirage-split-background;
|
background: $bg-mirage-split-background;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
&:hover {
|
&.disabled {
|
||||||
|
filter: brightness(0.7);
|
||||||
|
cursor: not-allowed;
|
||||||
|
}
|
||||||
|
|
||||||
|
.fas,
|
||||||
|
.nitro-currency-icon {
|
||||||
|
position: absolute;
|
||||||
|
right: 8px;
|
||||||
|
|
||||||
|
&.left {
|
||||||
|
left: 8px;
|
||||||
|
right: unset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.disabled):hover {
|
||||||
background: $bg-cello-split-background;
|
background: $bg-cello-split-background;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { FixedSizeStack } from 'nitro-renderer';
|
||||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||||
import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
||||||
import { ContextMenuViewProps } from './ContextMenuView.types';
|
import { ContextMenuViewProps } from './ContextMenuView.types';
|
||||||
@ -7,8 +8,9 @@ const fadeLength = 75;
|
|||||||
|
|
||||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { objectId = -1, category = -1, fades = false, close = null, children = null } = props;
|
const { objectId = -1, category = -1, fades = false, className = '', close = null, children = null } = props;
|
||||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: null, y: null });
|
||||||
|
const [ stack, setStack ] = useState<FixedSizeStack>(null);
|
||||||
const [ opacity, setOpacity ] = useState(1);
|
const [ opacity, setOpacity ] = useState(1);
|
||||||
const [ isFading, setIsFading ] = useState(false);
|
const [ isFading, setIsFading ] = useState(false);
|
||||||
const [ fadeTime, setFadeTime ] = useState(0);
|
const [ fadeTime, setFadeTime ] = useState(0);
|
||||||
@ -16,19 +18,19 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
|
|
||||||
const update = useCallback((time: number) =>
|
const update = useCallback((time: number) =>
|
||||||
{
|
{
|
||||||
let fadeTime = time;
|
let newFadeTime = time;
|
||||||
let newOpacity = 1;
|
let newOpacity = 1;
|
||||||
|
|
||||||
if(isFading)
|
if(isFading)
|
||||||
{
|
{
|
||||||
setFadeTime(prevValue =>
|
setFadeTime(prevValue =>
|
||||||
{
|
{
|
||||||
fadeTime += prevValue;
|
newFadeTime += prevValue;
|
||||||
|
|
||||||
return fadeTime;
|
return newFadeTime;
|
||||||
});
|
});
|
||||||
|
|
||||||
newOpacity = ((1 - (fadeTime / fadeLength)) * 1);
|
newOpacity = ((1 - (newFadeTime / fadeLength)) * 1);
|
||||||
|
|
||||||
if(newOpacity <= 0)
|
if(newOpacity <= 0)
|
||||||
{
|
{
|
||||||
@ -50,6 +52,11 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
});
|
});
|
||||||
}, [ objectId, category, isFading, close ]);
|
}, [ objectId, category, isFading, close ]);
|
||||||
|
|
||||||
|
useEffect(() =>
|
||||||
|
{
|
||||||
|
setStack(new FixedSizeStack(25));
|
||||||
|
}, []);
|
||||||
|
|
||||||
useEffect(() =>
|
useEffect(() =>
|
||||||
{
|
{
|
||||||
GetTicker().add(update);
|
GetTicker().add(update);
|
||||||
@ -73,7 +80,7 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
|||||||
}, [ fades ]);
|
}, [ fades ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div ref={ elementRef } className={ 'position-absolute nitro-context-menu ' + (pos.x !== null ? 'visible' : 'invisible') } style={ { left: (pos.x || 0), top: (pos.y || 0), opacity: opacity } }>
|
<div ref={ elementRef } className={ `position-absolute nitro-context-menu ${ className }${ (pos.x !== null ? ' visible' : ' invisible') }` } style={ { left: (pos.x || 0), top: (pos.y || 0), opacity: opacity } }>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -3,5 +3,6 @@ export interface ContextMenuViewProps
|
|||||||
objectId: number;
|
objectId: number;
|
||||||
category: number;
|
category: number;
|
||||||
fades?: boolean;
|
fades?: boolean;
|
||||||
|
className?: string;
|
||||||
close: () => void;
|
close: () => void;
|
||||||
}
|
}
|
||||||
|
@ -1,15 +1,20 @@
|
|||||||
import { FC } from 'react';
|
import { FC, MouseEvent, useCallback } from 'react';
|
||||||
import { ContextMenuListItemViewProps } from './ContextMenuListItemView.types';
|
import { ContextMenuListItemViewProps } from './ContextMenuListItemView.types';
|
||||||
|
|
||||||
export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =>
|
export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =>
|
||||||
{
|
{
|
||||||
const { onClick = null, children = null } = props;
|
const { className = '', canSelect = true, onClick = null, children = null } = props;
|
||||||
|
|
||||||
|
const handleClick = useCallback((event: MouseEvent<HTMLDivElement>) =>
|
||||||
|
{
|
||||||
|
if(!canSelect) return;
|
||||||
|
|
||||||
|
onClick(event);
|
||||||
|
}, [ canSelect, onClick ]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col menu-list-item-container" onClick={ onClick }>
|
<div className={ `d-flex justify-content-center align-items-center w-100 menu-list-item ${ !canSelect ? 'disabled ' : '' }${ className }` } onClick={ handleClick }>
|
||||||
<div className="d-flex justify-content-center align-items-center menu-list-item">
|
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -2,5 +2,7 @@ import { MouseEvent } from 'react';
|
|||||||
|
|
||||||
export interface ContextMenuListItemViewProps
|
export interface ContextMenuListItemViewProps
|
||||||
{
|
{
|
||||||
|
className?: string;
|
||||||
|
canSelect?: boolean;
|
||||||
onClick: (event: MouseEvent) => void;
|
onClick: (event: MouseEvent) => void;
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ export const ContextMenuListView: FC<ContextMenuListViewProps> = props =>
|
|||||||
const { columns = 1, children = null } = props;
|
const { columns = 1, children = null } = props;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={ `row row-cols-${ columns } menu-list g-1` }>
|
<div className={ `d-flex flex-column menu-list` }>
|
||||||
{ children }
|
{ children }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
export interface CurrencyIconProps
|
export interface CurrencyIconProps
|
||||||
{
|
{
|
||||||
type: number;
|
type: number | string;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user