Add separate chat setup window for rentable bots

This commit is contained in:
Bill 2021-06-30 19:48:24 -04:00
parent 97db013e45
commit 754cf2df2e
10 changed files with 156 additions and 77 deletions

View File

@ -60,6 +60,11 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
element.style.left = `${ left }px`; element.style.left = `${ left }px`;
element.style.top = `${ top }px`; element.style.top = `${ top }px`;
} }
else
{
element.style.left = `0px`;
element.style.top = `0px`;
}
element.style.visibility = 'visible'; element.style.visibility = 'visible';

View File

@ -1,41 +0,0 @@
import { NitroPoint, NitroRectangle } from 'nitro-renderer';
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
export class RoomWidgetRoomViewUpdateEvent extends RoomWidgetUpdateEvent
{
public static SIZE_CHANGED: string = 'RWRVUE_ROOM_VIEW_SIZE_CHANGED';
public static SCALE_CHANGED: string = 'RWRVUE_ROOM_VIEW_SCALE_CHANGED';
public static POSITION_CHANGED: string = 'RWRVUE_ROOM_VIEW_POSITION_CHANGED';
private _roomViewRectangle: NitroRectangle;
private _positionDelta: NitroPoint;
private _scale: number;
constructor(type: string, view: NitroRectangle = null, position: NitroPoint = null, scale: number = 0)
{
super(type);
this._roomViewRectangle = view;
this._positionDelta = position;
this._scale = scale;
}
public get roomViewRectangle(): NitroRectangle
{
if(!this._roomViewRectangle) return null;
return this._roomViewRectangle.clone();
}
public get positionDelta(): NitroPoint
{
if(!this._positionDelta) return null;
return this._positionDelta.clone();
}
public get scale(): number
{
return this._scale;
}
}

View File

@ -0,0 +1,62 @@
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
export class RoomWidgetUpdateRentableBotChatEvent extends RoomWidgetUpdateEvent
{
public static UPDATE_CHAT: string = 'RWURBCE_UPDATE_CHAT';
private _objectId: number;
private _category: number;
private _botId: number;
private _chat: string;
private _automaticChat: boolean;
private _chatDelay: number;
private _mixSentences: boolean;
constructor(objectId: number, category: number, botId: number, chat: string, automaticChat: boolean, chatDelay: number, mixSentences: boolean)
{
super(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT);
this._objectId = objectId;
this._category = category;
this._botId = botId;
this._chat = chat;
this._automaticChat = automaticChat;
this._chatDelay = chatDelay;
this._mixSentences = mixSentences;
}
public get objectId(): number
{
return this._objectId;
}
public get category(): number
{
return this._category;
}
public get botId(): number
{
return this._botId;
}
public get chat(): string
{
return this._chat;
}
public get automaticChat(): boolean
{
return this._automaticChat;
}
public get chatDelay(): number
{
return this._chatDelay;
}
public get mixSentences(): boolean
{
return this._mixSentences;
}
}

View File

@ -2,7 +2,6 @@ export * from './RoomWidgetAvatarInfoEvent';
export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetObjectNameEvent';
export * from './RoomWidgetRoomEngineUpdateEvent'; export * from './RoomWidgetRoomEngineUpdateEvent';
export * from './RoomWidgetRoomObjectUpdateEvent'; export * from './RoomWidgetRoomObjectUpdateEvent';
export * from './RoomWidgetRoomViewUpdateEvent';
export * from './RoomWidgetUpdateDanceStatusEvent'; export * from './RoomWidgetUpdateDanceStatusEvent';
export * from './RoomWidgetUpdateEvent'; export * from './RoomWidgetUpdateEvent';
export * from './RoomWidgetUpdateInfostandEvent'; export * from './RoomWidgetUpdateInfostandEvent';
@ -10,4 +9,5 @@ export * from './RoomWidgetUpdateInfostandFurniEvent';
export * from './RoomWidgetUpdateInfostandPetEvent'; export * from './RoomWidgetUpdateInfostandPetEvent';
export * from './RoomWidgetUpdateInfostandRentableBotEvent'; export * from './RoomWidgetUpdateInfostandRentableBotEvent';
export * from './RoomWidgetUpdateInfostandUserEvent'; export * from './RoomWidgetUpdateInfostandUserEvent';
export * from './RoomWidgetUpdateRentableBotChatEvent';
export * from './RoomWidgetUserDataUpdateEvent'; export * from './RoomWidgetUserDataUpdateEvent';

View File

@ -3,7 +3,7 @@ import { FC, useCallback, useMemo, useState } from 'react';
import { GetRoomSession, GetSessionDataManager } from '../../../../api'; import { GetRoomSession, GetSessionDataManager } from '../../../../api';
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base'; import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events'; import { RoomWidgetObjectNameEvent, RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateInfostandEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent, RoomWidgetUpdateRentableBotChatEvent } from '../../events';
import { RoomWidgetRoomObjectMessage } from '../../messages'; import { RoomWidgetRoomObjectMessage } from '../../messages';
import { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types'; import { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types';
import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView'; import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView';
@ -12,6 +12,7 @@ import { AvatarInfoWidgetNameView } from './views/name/AvatarInfoWidgetNameView'
import { AvatarInfoWidgetOwnAvatarView } from './views/own-avatar/AvatarInfoWidgetOwnAvatarView'; import { AvatarInfoWidgetOwnAvatarView } from './views/own-avatar/AvatarInfoWidgetOwnAvatarView';
import { AvatarInfoWidgetOwnPetView } from './views/own-pet/AvatarInfoWidgetOwnPetView'; import { AvatarInfoWidgetOwnPetView } from './views/own-pet/AvatarInfoWidgetOwnPetView';
import { AvatarInfoWidgetPetView } from './views/pet/AvatarInfoWidgetPetView'; import { AvatarInfoWidgetPetView } from './views/pet/AvatarInfoWidgetPetView';
import { AvatarInfoRentableBotChatView } from './views/rentable-bot-chat/AvatarInfoRentableBotChatView';
import { AvatarInfoWidgetRentableBotView } from './views/rentable-bot/AvatarInfoWidgetRentableBotView'; import { AvatarInfoWidgetRentableBotView } from './views/rentable-bot/AvatarInfoWidgetRentableBotView';
export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props => export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
@ -22,6 +23,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
const [ isGameMode, setGameMode ] = useState(false); const [ isGameMode, setGameMode ] = useState(false);
const [ isDancing, setIsDancing ] = useState(false); const [ isDancing, setIsDancing ] = useState(false);
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating); const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) => const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
{ {
@ -160,6 +162,13 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent); CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent); CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) =>
{
setRentableBotChatEvent(event);
}, []);
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
const decorateView = useMemo(() => const decorateView = useMemo(() =>
{ {
GetRoomSession().isDecorating = isDecorating; GetRoomSession().isDecorating = isDecorating;
@ -237,6 +246,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
return ( return (
<> <>
{ currentView } { currentView }
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
</> </>
) )
} }

View File

@ -0,0 +1,19 @@
import { FC } from 'react';
import { DraggableWindow } from '../../../../../../layout';
import { ObjectLocationView } from '../../../object-location/ObjectLocationView';
import { AvatarInfoRentableBotChatViewProps } from './AvatarInfoRentableBotChatView.types';
export const AvatarInfoRentableBotChatView: FC<AvatarInfoRentableBotChatViewProps> = props =>
{
const { chatEvent = null } = props;
return (
<DraggableWindow noCenter={ true } handle=".drag-handler">
<ObjectLocationView objectId={ chatEvent.objectId } category={ chatEvent.category } noFollow={ true }>
<div className="nitro-context-menu">
<div className="drag-handler">test!!!!!</div>
</div>
</ObjectLocationView>
</DraggableWindow>
);
}

View File

@ -0,0 +1,6 @@
import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../events';
export interface AvatarInfoRentableBotChatViewProps
{
chatEvent: RoomWidgetUpdateRentableBotChatEvent;
}

View File

@ -1,19 +1,19 @@
import { BotCommandConfigurationEvent, BotRemoveComposer, BotSkillSaveComposer, Nitro, RequestBotCommandConfigurationComposer, RoomObjectCategory } from 'nitro-renderer'; import { BotCommandConfigurationEvent, BotRemoveComposer, BotSkillSaveComposer, Nitro, RequestBotCommandConfigurationComposer, RoomObjectCategory } from 'nitro-renderer';
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { GetConnection } from '../../../../../../api'; import { GetConnection } from '../../../../../../api';
import { CreateMessageHook } from '../../../../../../hooks/messages'; import { CreateMessageHook } from '../../../../../../hooks/messages';
import { LocalizeText } from '../../../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../../../utils/LocalizeText';
import { useRoomContext } from '../../../../context/RoomContext'; import { useRoomContext } from '../../../../context/RoomContext';
import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../events';
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 { BotSkillsEnum } from '../../utils/BotSkillsEnum'; import { BotSkillsEnum } from '../../utils/BotSkillsEnum';
import { AvatarInfoWidgetRentableBotViewProps, BotChatOptions } from './AvatarInfoWidgetRentableBotView.types'; import { AvatarInfoWidgetRentableBotViewProps } from './AvatarInfoWidgetRentableBotView.types';
const MODE_NORMAL = 0; const MODE_NORMAL = 0;
const MODE_CHANGE_NAME = 1; const MODE_CHANGE_NAME = 1;
const MODE_CHANGE_MOTTO = 2; const MODE_CHANGE_MOTTO = 2;
const MODE_CHANGE_SPEECH = 3;
export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotViewProps> = props => export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotViewProps> = props =>
{ {
@ -21,9 +21,12 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
const [ mode, setMode ] = useState(MODE_NORMAL); const [ mode, setMode ] = useState(MODE_NORMAL);
const [ newName, setNewName ] = useState(''); const [ newName, setNewName ] = useState('');
const [ newMotto, setNewMotto ] = useState(''); const [ newMotto, setNewMotto ] = useState('');
const [ newChat, setNewChat ] = useState(''); const { eventDispatcher = null } = useRoomContext();
const [ chatOptions, setChatOptions ] = useState<BotChatOptions>({ automaticChat: false, chatDelay: 0, mixSentences: false });
const { widgetHandler = null } = useRoomContext(); useEffect(() =>
{
setMode(MODE_NORMAL);
}, [ rentableBotData ]);
const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) => const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) =>
{ {
@ -49,20 +52,22 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
if((pieces.length === 3) || (pieces.length === 4)) if((pieces.length === 3) || (pieces.length === 4))
{ {
setNewChat(pieces[0]); eventDispatcher.dispatchEvent(new RoomWidgetUpdateRentableBotChatEvent(
setChatOptions({ rentableBotData.roomIndex,
automaticChat: ((pieces[1].toLowerCase() === 'true') || (pieces[1] === '1')), RoomObjectCategory.UNIT,
chatDelay: parseInt(pieces[2]), rentableBotData.webID,
mixSentences: ((pieces[3]) ? ((pieces[3].toLowerCase() === 'true') || (pieces[3] === '1')) : false) pieces[0],
}); ((pieces[1].toLowerCase() === 'true') || (pieces[1] === '1')),
} parseInt(pieces[2]),
((pieces[3]) ? ((pieces[3].toLowerCase() === 'true') || (pieces[3] === '1')) : false)));
setMode(MODE_CHANGE_SPEECH); close();
}
return; return;
} }
} }
}, [ rentableBotData ]); }, [ rentableBotData, eventDispatcher, close ]);
CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent); CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent);
@ -176,14 +181,23 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
</ContextMenuListItemView> } </ContextMenuListItemView> }
</> } </> }
{ (mode === MODE_CHANGE_NAME) && { (mode === MODE_CHANGE_NAME) &&
<ContextMenuListItemView className="flex-column" onClick={ null }> <div className="d-flex flex-column menu-item" onClick={ null }>
<p className="mb-1">{ LocalizeText('bot.skill.name.configuration.new.name') }</p> <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) } /> <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"> <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-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> <button type="button" className="btn btn-success btn-sm" onClick={ event => processAction('save_bot_name') }>{ LocalizeText('save') }</button>
</div> </div>
</ContextMenuListItemView> } </div> }
{ (mode === MODE_CHANGE_MOTTO) &&
<div className="d-flex flex-column menu-item" onClick={ null }>
<p className="mb-1">{ LocalizeText('bot.skill.name.configuration.new.motto') }</p>
<input type="text" className="form-control form-control-sm mb-2" value={ newMotto } onChange={ event => setNewMotto(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_motto') }>{ LocalizeText('save') }</button>
</div>
</div> }
</ContextMenuView> </ContextMenuView>
); );
} }

View File

@ -52,19 +52,26 @@
} }
} }
.menu-list-item { .menu-item {
position: relative; position: relative;
height: 24px;
max-height: 24px;
margin-top: 2px; margin-top: 2px;
padding: 3px; padding: 3px;
background: $bg-mirage-split-background;
cursor: pointer;
overflow: hidden; overflow: hidden;
&.disabled { &.disabled {
filter: brightness(0.7); filter: brightness(0.7);
cursor: not-allowed; cursor: not-allowed !important;
}
&.list-item {
height: 24px;
max-height: 24px;
padding: 3px;
background: $bg-mirage-split-background;
cursor: pointer;
&:not(.disabled):hover {
background: $bg-cello-split-background;
} }
.fas, .fas,
@ -77,9 +84,6 @@
right: unset; right: unset;
} }
} }
&:not(.disabled):hover {
background: $bg-cello-split-background;
} }
} }
} }

View File

@ -13,7 +13,7 @@ export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =
}, [ canSelect, onClick ]); }, [ canSelect, onClick ]);
return ( return (
<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 w-100 menu-item list-item ${ !canSelect ? 'disabled ' : '' }${ className }` } onClick={ handleClick }>
{ children } { children }
</div> </div>
) )