Update chat

This commit is contained in:
Bill 2021-07-02 02:50:17 -04:00
parent 24b5ba658c
commit 63bc890fd6
22 changed files with 643 additions and 218 deletions

View File

@ -9,7 +9,7 @@ import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine';
import { useRoomEngineEvent } from '../../hooks/events'; import { useRoomEngineEvent } from '../../hooks/events';
import { RoomContextProvider } from './context/RoomContext'; import { RoomContextProvider } from './context/RoomContext';
import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from './events'; import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from './events';
import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
import { RoomViewProps } from './RoomView.types'; import { RoomViewProps } from './RoomView.types';
import { RoomWidgetsView } from './widgets/RoomWidgetsView'; import { RoomWidgetsView } from './widgets/RoomWidgetsView';
@ -35,6 +35,7 @@ export const RoomView: FC<RoomViewProps> = props =>
widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler()); widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler());
widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler()); widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler());
widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler());
setWidgetHandler(widgetHandlerManager); setWidgetHandler(widgetHandlerManager);

View File

@ -0,0 +1,20 @@
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
export class RoomWidgetFloodControlEvent extends RoomWidgetUpdateEvent
{
public static FLOOD_CONTROL: string = 'RWFCE_FLOOD_CONTROL';
private _seconds: number = 0;
constructor(k: number)
{
super(RoomWidgetFloodControlEvent.FLOOD_CONTROL);
this._seconds = k;
}
public get seconds(): number
{
return this._seconds;
}
}

View File

@ -1,4 +1,5 @@
export * from './RoomWidgetAvatarInfoEvent'; export * from './RoomWidgetAvatarInfoEvent';
export * from './RoomWidgetFloodControlEvent';
export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetObjectNameEvent';
export * from './RoomWidgetRoomEngineUpdateEvent'; export * from './RoomWidgetRoomEngineUpdateEvent';
export * from './RoomWidgetRoomObjectUpdateEvent'; export * from './RoomWidgetRoomObjectUpdateEvent';

View File

@ -1,13 +1,13 @@
import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer'; import { NitroEvent } from 'nitro-renderer';
import { RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetUpdateEvent } from '../events';
import { RoomWidgetMessage } from '../messages'; import { RoomWidgetMessage } from '../messages';
import { IRoomWidgetHandlerManager } from './IRoomWidgetHandlerManager';
export interface IRoomWidgetHandler export interface IRoomWidgetHandler
{ {
processEvent: (event: NitroEvent) => void; processEvent: (event: NitroEvent) => void;
processWidgetMessage: (message: RoomWidgetMessage) => RoomWidgetUpdateEvent; processWidgetMessage: (message: RoomWidgetMessage) => RoomWidgetUpdateEvent;
roomSession: IRoomSession; container: IRoomWidgetHandlerManager;
eventDispatcher: IEventDispatcher;
eventTypes: string[]; eventTypes: string[];
messageTypes: string[]; messageTypes: string[];
} }

View File

@ -1,4 +1,4 @@
import { IEventDispatcher, NitroEvent } from 'nitro-renderer'; import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer';
import { RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetUpdateEvent } from '../events';
import { RoomWidgetMessage } from '../messages'; import { RoomWidgetMessage } from '../messages';
import { IRoomWidgetHandler } from './IRoomWidgetHandler'; import { IRoomWidgetHandler } from './IRoomWidgetHandler';
@ -8,5 +8,6 @@ export interface IRoomWidgetHandlerManager
registerHandler(handler: IRoomWidgetHandler): void; registerHandler(handler: IRoomWidgetHandler): void;
processEvent(event: NitroEvent): void; processEvent(event: NitroEvent): void;
processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent; processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent;
roomSession: IRoomSession;
eventDispatcher: IEventDispatcher; eventDispatcher: IEventDispatcher;
} }

View File

@ -11,7 +11,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
switch(event.type) switch(event.type)
{ {
case RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED: case RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED:
this.eventDispatcher.dispatchEvent(new RoomWidgetUserDataUpdateEvent()); this.container.eventDispatcher.dispatchEvent(new RoomWidgetUserDataUpdateEvent());
return; return;
case RoomSessionDanceEvent.RSDE_DANCE: case RoomSessionDanceEvent.RSDE_DANCE:
const danceEvent = (event as RoomSessionDanceEvent); const danceEvent = (event as RoomSessionDanceEvent);
@ -22,7 +22,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
if(userData && (userData.roomIndex === danceEvent.roomIndex)) isDancing = (danceEvent.danceId !== 0); if(userData && (userData.roomIndex === danceEvent.roomIndex)) isDancing = (danceEvent.danceId !== 0);
this.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDanceStatusEvent(isDancing)); this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDanceStatusEvent(isDancing));
return; return;
} }
} }
@ -68,7 +68,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
const allowNameChange = GetSessionDataManager().canChangeName; const allowNameChange = GetSessionDataManager().canChangeName;
const userData = GetRoomSession().userDataManager.getUserData(userId); const userData = GetRoomSession().userDataManager.getUserData(userId);
if(userData) this.eventDispatcher.dispatchEvent(new RoomWidgetAvatarInfoEvent(userId, userName, userData.type, userData.roomIndex, allowNameChange)); if(userData) this.container.eventDispatcher.dispatchEvent(new RoomWidgetAvatarInfoEvent(userId, userName, userData.type, userData.roomIndex, allowNameChange));
} }
public get eventTypes(): string[] public get eventTypes(): string[]

View File

@ -0,0 +1,198 @@
import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomZoomEvent } from 'nitro-renderer';
import { GetConnection, GetRoomEngine, GetSessionDataManager, SendChatTypingMessage } from '../../../api';
import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events';
import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages';
import { RoomWidgetHandler } from './RoomWidgetHandler';
export class RoomWidgetChatInputHandler extends RoomWidgetHandler
{
public processEvent(event: NitroEvent): void
{
switch(event.type)
{
case RoomSessionChatEvent.FLOOD_EVENT: {
const floodEvent = (event as RoomSessionChatEvent);
this.container.eventDispatcher.dispatchEvent(new RoomWidgetFloodControlEvent(parseInt(floodEvent.message)));
}
}
}
public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent
{
switch(message.type)
{
case RoomWidgetChatTypingMessage.TYPING_STATUS: {
const typingMessage = (message as RoomWidgetChatTypingMessage);
SendChatTypingMessage(typingMessage.isTyping);
break;
}
case RoomWidgetChatMessage.MESSAGE_CHAT: {
const chatMessage = (message as RoomWidgetChatMessage);
if(chatMessage.text === '') return null;
let text = chatMessage.text;
const parts = text.split(' ');
if(parts.length > 0)
{
const firstPart = parts[0];
let secondPart = '';
if(parts.length > 1) secondPart = parts[1];
if((firstPart.charAt(0) === ':') && (secondPart === 'x'))
{
const selectedAvatarId = GetRoomEngine().selectedAvatarId;
if(selectedAvatarId > -1)
{
const userData = this.container.roomSession.userDataManager.getUserDataByIndex(selectedAvatarId);
if(userData)
{
secondPart = userData.name;
text = chatMessage.text.replace(' x', (' ' + userData.name));
}
}
}
switch(firstPart.toLowerCase())
{
case ':d':
case ';d':
if(GetSessionDataManager().clubLevel === HabboClubLevelEnum.VIP)
{
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.LAUGH.ordinal);
}
break;
case 'o/':
case '_o/':
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.WAVE.ordinal);
return null;
case ':kiss':
if(GetSessionDataManager().clubLevel === HabboClubLevelEnum.VIP)
{
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.BLOW.ordinal);
return null;
}
break;
case ':jump':
if(GetSessionDataManager().clubLevel === HabboClubLevelEnum.VIP)
{
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.JUMP.ordinal);
return null;
}
break;
case ':idle':
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.IDLE.ordinal);
return null;
case '_b':
this.container.roomSession.sendExpressionMessage(AvatarExpressionEnum.RESPECT.ordinal);
return null;
case ':sign':
this.container.roomSession.sendSignMessage(parseInt(secondPart));
return null;
case ':iddqd':
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(this.container.roomSession.roomId, -1, true));
return null;
case ':zoom':
GetRoomEngine().events.dispatchEvent(new RoomZoomEvent(this.container.roomSession.roomId, parseInt(secondPart), false));
return null;
case ':screenshot':
GetRoomEngine().createRoomScreenshot(this.container.roomSession.roomId, 1);
return null;
case ':pickall':
// this.container.notificationService.alertWithConfirm('${room.confirm.pick_all}', '${generic.alert.title}', () =>
// {
// GetSessionDataManager().sendSpecialCommandMessage(':pickall');
// });
return null;
case ':furni':
this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FURNI_CHOOSER));
return null;
case ':chooser':
this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.USER_CHOOSER));
return null;
case ':floor':
case ':bcfloor':
if(this.container.roomSession.controllerLevel >= RoomControllerLevel.ROOM_OWNER)
{
this.container.processWidgetMessage(new RoomWidgetRequestWidgetMessage(RoomWidgetRequestWidgetMessage.FLOOR_EDITOR));
}
return null;
case ':client':
case ':nitro':
case ':billsonnn':
// this.container.notificationService.alertWithScrollableMessages([
// '<div class="d-flex flex-column justify-content-center align-items-center"><div class="nitro-info-box"></div><b>Version: ' + Nitro.RELEASE_VERSION + '</b><br />This client is powered by Nitro HTML5<br /><br /><div class="d-flex"><a class="btn btn-primary" href="https://discord.gg/66UR68FPgy" target="_blank">Discord</a><a class="btn btn-primary" href="https://git.krews.org/nitro" target="_blank">Git</a></div><br /></div>'], 'Nitro HTML5');
return null;
case ':settings':
if(this.container.roomSession.isRoomOwner || GetSessionDataManager().isModerator)
{
GetConnection().send(new RoomSettingsComposer(this.container.roomSession.roomId));
}
return null;
}
}
const styleId = chatMessage.styleId;
if(this.container && this.container.roomSession)
{
switch(chatMessage.chatType)
{
case RoomWidgetChatMessage.CHAT_DEFAULT:
this.container.roomSession.sendChatMessage(text, styleId);
break;
case RoomWidgetChatMessage.CHAT_SHOUT:
this.container.roomSession.sendShoutMessage(text, styleId);
break;
case RoomWidgetChatMessage.CHAT_WHISPER:
this.container.roomSession.sendWhisperMessage(chatMessage.recipientName, text, styleId);
break;
}
}
break;
}
}
return null;
}
public get eventTypes(): string[]
{
return [
RoomSessionChatEvent.FLOOD_EVENT
];
}
public get messageTypes(): string[]
{
return [
RoomWidgetChatTypingMessage.TYPING_STATUS,
RoomWidgetChatMessage.MESSAGE_CHAT,
RoomWidgetChatSelectAvatarMessage.MESSAGE_SELECT_AVATAR
];
}
}

View File

@ -1,35 +1,25 @@
import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer'; import { NitroEvent } from 'nitro-renderer';
import { RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetUpdateEvent } from '../events';
import { RoomWidgetMessage } from '../messages'; import { RoomWidgetMessage } from '../messages';
import { IRoomWidgetHandler } from './IRoomWidgetHandler'; import { IRoomWidgetHandler } from './IRoomWidgetHandler';
import { IRoomWidgetHandlerManager } from './IRoomWidgetHandlerManager';
export abstract class RoomWidgetHandler implements IRoomWidgetHandler export abstract class RoomWidgetHandler implements IRoomWidgetHandler
{ {
private _roomSession: IRoomSession = null; private _container: IRoomWidgetHandlerManager = null;
private _eventDispatcher: IEventDispatcher = null;
public abstract processEvent(event: NitroEvent): void; public abstract processEvent(event: NitroEvent): void;
public abstract processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent; public abstract processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent;
public get roomSession(): IRoomSession public get container(): IRoomWidgetHandlerManager
{ {
return this._roomSession; return this._container;
} }
public set roomSession(roomSession: IRoomSession) public set container(container: IRoomWidgetHandlerManager)
{ {
this._roomSession = roomSession; this._container = container;
}
public get eventDispatcher(): IEventDispatcher
{
return this._eventDispatcher;
}
public set eventDispatcher(eventDispatcher: IEventDispatcher)
{
this._eventDispatcher = eventDispatcher;
} }
public abstract get eventTypes(): string[]; public abstract get eventTypes(): string[];

View File

@ -62,8 +62,7 @@ export class RoomWidgetHandlerManager implements IRoomWidgetHandlerManager
} }
} }
handler.roomSession = this._roomSession; handler.container = this;
handler.eventDispatcher = this._eventDispatcher;
this._handlers.push(handler); this._handlers.push(handler);
} }

View File

@ -17,7 +17,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
this.processPetInfoEvent((event as RoomSessionPetInfoUpdateEvent)); this.processPetInfoEvent((event as RoomSessionPetInfoUpdateEvent));
return; return;
case RoomSessionUserBadgesEvent.RSUBE_BADGES: case RoomSessionUserBadgesEvent.RSUBE_BADGES:
this.eventDispatcher.dispatchEvent(event); this.container.eventDispatcher.dispatchEvent(event);
return; return;
} }
} }
@ -50,11 +50,11 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
if(petMessages.indexOf(message.type) >= 0) if(petMessages.indexOf(message.type) >= 0)
{ {
userData = this.roomSession.userDataManager.getPetData(userId); userData = this.container.roomSession.userDataManager.getPetData(userId);
} }
else else
{ {
userData = this.roomSession.userDataManager.getUserData(userId); userData = this.container.roomSession.userDataManager.getUserData(userId);
} }
if(!userData) return null; if(!userData) return null;
@ -82,7 +82,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
GetSessionDataManager().givePetRespect(userId); GetSessionDataManager().givePetRespect(userId);
break; break;
case RoomWidgetUserActionMessage.WHISPER_USER: case RoomWidgetUserActionMessage.WHISPER_USER:
//this.eventDispatcher.dispatchEvent(new RoomWidgetChatInputContentUpdateEvent(RoomWidgetChatInputContentUpdateEvent.WHISPER, userData.name)); //this.container.eventDispatcher.dispatchEvent(new RoomWidgetChatInputContentUpdateEvent(RoomWidgetChatInputContentUpdateEvent.WHISPER, userData.name));
break; break;
case RoomWidgetUserActionMessage.IGNORE_USER: case RoomWidgetUserActionMessage.IGNORE_USER:
GetSessionDataManager().ignoreUser(userData.name); GetSessionDataManager().ignoreUser(userData.name);
@ -91,27 +91,27 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
GetSessionDataManager().unignoreUser(userData.name); GetSessionDataManager().unignoreUser(userData.name);
break; break;
case RoomWidgetUserActionMessage.KICK_USER: case RoomWidgetUserActionMessage.KICK_USER:
this.roomSession.sendKickMessage((message as RoomWidgetUserActionMessage).userId); this.container.roomSession.sendKickMessage((message as RoomWidgetUserActionMessage).userId);
break; break;
case RoomWidgetUserActionMessage.BAN_USER_DAY: case RoomWidgetUserActionMessage.BAN_USER_DAY:
case RoomWidgetUserActionMessage.BAN_USER_HOUR: case RoomWidgetUserActionMessage.BAN_USER_HOUR:
case RoomWidgetUserActionMessage.BAN_USER_PERM: case RoomWidgetUserActionMessage.BAN_USER_PERM:
this.roomSession.sendBanMessage((message as RoomWidgetUserActionMessage).userId, message.type); this.container.roomSession.sendBanMessage((message as RoomWidgetUserActionMessage).userId, message.type);
break; break;
case RoomWidgetUserActionMessage.MUTE_USER_2MIN: case RoomWidgetUserActionMessage.MUTE_USER_2MIN:
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 2); this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 2);
break; break;
case RoomWidgetUserActionMessage.MUTE_USER_5MIN: case RoomWidgetUserActionMessage.MUTE_USER_5MIN:
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 5); this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 5);
break; break;
case RoomWidgetUserActionMessage.MUTE_USER_10MIN: case RoomWidgetUserActionMessage.MUTE_USER_10MIN:
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 10); this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 10);
break; break;
case RoomWidgetUserActionMessage.GIVE_RIGHTS: case RoomWidgetUserActionMessage.GIVE_RIGHTS:
this.roomSession.sendGiveRightsMessage((message as RoomWidgetUserActionMessage).userId); this.container.roomSession.sendGiveRightsMessage((message as RoomWidgetUserActionMessage).userId);
break; break;
case RoomWidgetUserActionMessage.TAKE_RIGHTS: case RoomWidgetUserActionMessage.TAKE_RIGHTS:
this.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId); this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
break; break;
case RoomWidgetUserActionMessage.START_TRADING: case RoomWidgetUserActionMessage.START_TRADING:
//if(userData) this._widget.inventoryTrading.startTrade(userData.roomIndex, userData.name); //if(userData) this._widget.inventoryTrading.startTrade(userData.roomIndex, userData.name);
@ -156,29 +156,29 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
GetConnection().send(new RoomUnitDropHandItemComposer()); GetConnection().send(new RoomUnitDropHandItemComposer());
break; break;
case RoomWidgetUserActionMessage.REQUEST_PET_UPDATE: case RoomWidgetUserActionMessage.REQUEST_PET_UPDATE:
this.roomSession.userDataManager.requestPetInfo(userId); this.container.roomSession.userDataManager.requestPetInfo(userId);
return; return;
case RoomWidgetUserActionMessage.REPORT: case RoomWidgetUserActionMessage.REPORT:
return; return;
case RoomWidgetUserActionMessage.REPORT_CFH_OTHER: case RoomWidgetUserActionMessage.REPORT_CFH_OTHER:
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_ALERT_USER: case RoomWidgetUserActionMessage.AMBASSADOR_ALERT_USER:
this.roomSession.sendAmbassadorAlertMessage(userId); this.container.roomSession.sendAmbassadorAlertMessage(userId);
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_KICK_USER: case RoomWidgetUserActionMessage.AMBASSADOR_KICK_USER:
this.roomSession.sendKickMessage(userId); this.container.roomSession.sendKickMessage(userId);
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_2MIN: case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_2MIN:
this.roomSession.sendMuteMessage(userId, 2); this.container.roomSession.sendMuteMessage(userId, 2);
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_10MIN: case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_10MIN:
this.roomSession.sendMuteMessage(userId, 10); this.container.roomSession.sendMuteMessage(userId, 10);
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_60MIN: case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_60MIN:
this.roomSession.sendMuteMessage(userId, 60); this.container.roomSession.sendMuteMessage(userId, 60);
return; return;
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_18HOUR: case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_18HOUR:
this.roomSession.sendMuteMessage(userId, 1080); this.container.roomSession.sendMuteMessage(userId, 1080);
return; return;
case RoomWidgetFurniActionMessage.ROTATE: case RoomWidgetFurniActionMessage.ROTATE:
GetRoomEngine().processRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE); GetRoomEngine().processRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
@ -226,7 +226,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
return; return;
} }
case RoomWidgetChangeMottoMessage.CHANGE_MOTTO: case RoomWidgetChangeMottoMessage.CHANGE_MOTTO:
this.roomSession.sendMottoMessage((message as RoomWidgetChangeMottoMessage).motto); this.container.roomSession.sendMottoMessage((message as RoomWidgetChangeMottoMessage).motto);
return; return;
} }
@ -243,7 +243,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
{ {
case RoomObjectCategory.FLOOR: case RoomObjectCategory.FLOOR:
case RoomObjectCategory.WALL: { case RoomObjectCategory.WALL: {
const roomObject = GetRoomEngine().getRoomObject(this.roomSession.roomId, message.id, message.category); const roomObject = GetRoomEngine().getRoomObject(this.container.roomSession.roomId, message.id, message.category);
if(!roomObject) break; if(!roomObject) break;
@ -275,7 +275,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
break; break;
} }
case RoomObjectCategory.UNIT: { case RoomObjectCategory.UNIT: {
const userData = this.roomSession.userDataManager.getUserDataByIndex(message.id); const userData = this.container.roomSession.userDataManager.getUserDataByIndex(message.id);
if(!userData) break; if(!userData) break;
@ -286,14 +286,14 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
} }
} }
if(name) this.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(message.id, message.category, id, name, userType)); if(name) this.container.eventDispatcher.dispatchEvent(new RoomWidgetObjectNameEvent(message.id, message.category, id, name, userType));
return null; return null;
} }
private processObjectInfoMessage(message: RoomWidgetRoomObjectMessage): RoomWidgetUpdateEvent private processObjectInfoMessage(message: RoomWidgetRoomObjectMessage): RoomWidgetUpdateEvent
{ {
const roomId = this.roomSession.roomId; const roomId = this.container.roomSession.roomId;
switch(message.category) switch(message.category)
{ {
@ -302,14 +302,14 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
this.processFurniInfoMessage(message, roomId); this.processFurniInfoMessage(message, roomId);
break; break;
case RoomObjectCategory.UNIT: { case RoomObjectCategory.UNIT: {
const userData = this.roomSession.userDataManager.getUserDataByIndex(message.id); const userData = this.container.roomSession.userDataManager.getUserDataByIndex(message.id);
if(!userData) break; if(!userData) break;
switch(userData.type) switch(userData.type)
{ {
case RoomObjectType.PET: case RoomObjectType.PET:
this.roomSession.userDataManager.requestPetInfo(userData.webID); this.container.roomSession.userDataManager.requestPetInfo(userData.webID);
break; break;
case RoomObjectType.USER: case RoomObjectType.USER:
this.processUserInfoMessage(message, roomId, userData); this.processUserInfoMessage(message, roomId, userData);
@ -408,8 +408,8 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
event.image = roomObjectImage.getImage(); event.image = roomObjectImage.getImage();
event.isWallItem = (message.category === RoomObjectCategory.WALL); event.isWallItem = (message.category === RoomObjectCategory.WALL);
event.isRoomOwner = this.roomSession.isRoomOwner; event.isRoomOwner = this.container.roomSession.isRoomOwner;
event.roomControllerLevel = this.roomSession.controllerLevel; event.roomControllerLevel = this.container.roomSession.controllerLevel;
event.isAnyRoomController = GetSessionDataManager().isModerator; event.isAnyRoomController = GetSessionDataManager().isModerator;
event.ownerId = model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID); event.ownerId = model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
event.ownerName = model.getValue<string>(RoomObjectVariable.FURNITURE_OWNER_NAME); event.ownerName = model.getValue<string>(RoomObjectVariable.FURNITURE_OWNER_NAME);
@ -425,7 +425,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
if(IsOwnerOfFurniture(roomObject)) event.isOwner = true; if(IsOwnerOfFurniture(roomObject)) event.isOwner = true;
this.eventDispatcher.dispatchEvent(event); this.container.eventDispatcher.dispatchEvent(event);
} }
private processUserInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void private processUserInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void
@ -436,7 +436,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
const event = new RoomWidgetUpdateInfostandUserEvent(eventType); const event = new RoomWidgetUpdateInfostandUserEvent(eventType);
event.isSpectatorMode = this.roomSession.isSpectator; event.isSpectatorMode = this.container.roomSession.isSpectator;
event.name = userData.name; event.name = userData.name;
event.motto = userData.custom; event.motto = userData.custom;
event.achievementScore = userData.activityPoints; event.achievementScore = userData.activityPoints;
@ -454,9 +454,9 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
event.allowNameChange = GetSessionDataManager().canChangeName; event.allowNameChange = GetSessionDataManager().canChangeName;
} }
event.amIOwner = this.roomSession.isRoomOwner; event.amIOwner = this.container.roomSession.isRoomOwner;
event.isGuildRoom = this.roomSession.isGuildRoom; event.isGuildRoom = this.container.roomSession.isGuildRoom;
event.roomControllerLevel = this.roomSession.controllerLevel; event.roomControllerLevel = this.container.roomSession.controllerLevel;
event.amIAnyRoomController = GetSessionDataManager().isModerator; event.amIAnyRoomController = GetSessionDataManager().isModerator;
event.isAmbassador = GetSessionDataManager().isAmbassador; event.isAmbassador = GetSessionDataManager().isAmbassador;
@ -487,7 +487,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
event.respectLeft = GetSessionDataManager().respectsLeft; event.respectLeft = GetSessionDataManager().respectsLeft;
const isShuttingDown = GetSessionDataManager().isSystemShutdown; const isShuttingDown = GetSessionDataManager().isSystemShutdown;
const tradeMode = this.roomSession.tradeMode; const tradeMode = this.container.roomSession.tradeMode;
if(isShuttingDown) if(isShuttingDown)
{ {
@ -527,14 +527,14 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
event.groupId = parseInt(userData.guildId); event.groupId = parseInt(userData.guildId);
//event._Str_5235 = GetSessionDataManager()._Str_17173(int(userData._Str_4592)); //event._Str_5235 = GetSessionDataManager()._Str_17173(int(userData._Str_4592));
event.groupName = userData.groupName; event.groupName = userData.groupName;
event.badges = this.roomSession.userDataManager.getUserBadges(userData.webID); event.badges = this.container.roomSession.userDataManager.getUserBadges(userData.webID);
event.figure = userData.figure; event.figure = userData.figure;
//var _local_8:Array = GetSessionDataManager()._Str_18437(userData.webID); //var _local_8:Array = GetSessionDataManager()._Str_18437(userData.webID);
//this._Str_16287(userData._Str_2394, _local_8); //this._Str_16287(userData._Str_2394, _local_8);
//this._container._Str_8097._Str_14387(userData.webID); //this._container._Str_8097._Str_14387(userData.webID);
//this._container.connection.send(new _Str_8049(userData._Str_2394)); //this._container.connection.send(new _Str_8049(userData._Str_2394));
this.eventDispatcher.dispatchEvent(event); this.container.eventDispatcher.dispatchEvent(event);
} }
private processBotInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void private processBotInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void
@ -551,15 +551,15 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
if(roomObject) event.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); if(roomObject) event.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0);
event.amIOwner = this.roomSession.isRoomOwner; event.amIOwner = this.container.roomSession.isRoomOwner;
event.isGuildRoom = this.roomSession.isGuildRoom; event.isGuildRoom = this.container.roomSession.isGuildRoom;
event.roomControllerLevel = this.roomSession.controllerLevel; event.roomControllerLevel = this.container.roomSession.controllerLevel;
event.amIAnyRoomController = GetSessionDataManager().isModerator; event.amIAnyRoomController = GetSessionDataManager().isModerator;
event.isAmbassador = GetSessionDataManager().isAmbassador; event.isAmbassador = GetSessionDataManager().isAmbassador;
event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ]; event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ];
event.figure = userData.figure; event.figure = userData.figure;
this.eventDispatcher.dispatchEvent(event); this.container.eventDispatcher.dispatchEvent(event);
} }
private processRentableBotInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void private processRentableBotInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void
@ -578,13 +578,13 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
if(roomObject) event.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0); if(roomObject) event.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0);
event.amIOwner = this.roomSession.isRoomOwner; event.amIOwner = this.container.roomSession.isRoomOwner;
event.roomControllerLevel = this.roomSession.controllerLevel; event.roomControllerLevel = this.container.roomSession.controllerLevel;
event.amIAnyRoomController = GetSessionDataManager().isModerator; event.amIAnyRoomController = GetSessionDataManager().isModerator;
event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ]; event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ];
event.figure = userData.figure; event.figure = userData.figure;
this.eventDispatcher.dispatchEvent(event); this.container.eventDispatcher.dispatchEvent(event);
} }
private processPetInfoEvent(event: RoomSessionPetInfoUpdateEvent): void private processPetInfoEvent(event: RoomSessionPetInfoUpdateEvent): void
@ -593,7 +593,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
if(!petData) return; if(!petData) return;
const roomPetData = this.roomSession.userDataManager.getPetData(petData.id); const roomPetData = this.container.roomSession.userDataManager.getPetData(petData.id);
if(!roomPetData) return; if(!roomPetData) return;
@ -652,10 +652,10 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
} }
else else
{ {
if(this.roomSession.isRoomOwner || GetSessionDataManager().isModerator || (this.roomSession.controllerLevel >= RoomControllerLevel.GUEST)) infostandEvent.canRemovePet = true; if(this.container.roomSession.isRoomOwner || GetSessionDataManager().isModerator || (this.container.roomSession.controllerLevel >= RoomControllerLevel.GUEST)) infostandEvent.canRemovePet = true;
} }
this.eventDispatcher.dispatchEvent(infostandEvent); this.container.eventDispatcher.dispatchEvent(infostandEvent);
} }
private checkGuildSetting(event: RoomWidgetUpdateInfostandUserEvent): boolean private checkGuildSetting(event: RoomWidgetUpdateInfostandUserEvent): boolean
@ -717,9 +717,9 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
private isValidSetting(event: RoomWidgetUpdateInfostandUserEvent, checkSetting: (event: RoomWidgetUpdateInfostandUserEvent, moderation: RoomModerationSettings) => boolean): boolean private isValidSetting(event: RoomWidgetUpdateInfostandUserEvent, checkSetting: (event: RoomWidgetUpdateInfostandUserEvent, moderation: RoomModerationSettings) => boolean): boolean
{ {
if(!this.roomSession._Str_7411) return false; if(!this.container.roomSession._Str_7411) return false;
const moderation = this.roomSession.moderationSettings; const moderation = this.container.roomSession.moderationSettings;
let flag = false; let flag = false;

View File

@ -1,6 +1,7 @@
export * from './IRoomWidgetHandler'; export * from './IRoomWidgetHandler';
export * from './IRoomWidgetHandlerManager'; export * from './IRoomWidgetHandlerManager';
export * from './RoomWidgetAvatarInfoHandler'; export * from './RoomWidgetAvatarInfoHandler';
export * from './RoomWidgetChatInputHandler';
export * from './RoomWidgetHandler'; export * from './RoomWidgetHandler';
export * from './RoomWidgetHandlerManager'; export * from './RoomWidgetHandlerManager';
export * from './RoomWidgetInfostandHandler'; export * from './RoomWidgetInfostandHandler';

View File

@ -0,0 +1,44 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetChatMessage extends RoomWidgetMessage
{
public static MESSAGE_CHAT: string = 'RWCM_MESSAGE_CHAT';
public static CHAT_DEFAULT: number = 0;
public static CHAT_WHISPER: number = 1;
public static CHAT_SHOUT: number = 2;
private _chatType: number;
private _text: string;
private _recipientName: string;
private _styleId: number;
constructor(type: string, text: string, chatType: number, recipientName: string, styleId: number)
{
super(type);
this._text = text;
this._chatType = chatType;
this._recipientName = recipientName;
this._styleId = styleId;
}
public get text(): string
{
return this._text;
}
public get chatType(): number
{
return this._chatType;
}
public get recipientName(): string
{
return this._recipientName;
}
public get styleId(): number
{
return this._styleId;
}
}

View File

@ -0,0 +1,34 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetChatSelectAvatarMessage extends RoomWidgetMessage
{
public static MESSAGE_SELECT_AVATAR: string = 'RWCSAM_MESSAGE_SELECT_AVATAR';
private _objectId: number;
private _userName: string;
private _roomId: number;
constructor(type: string, objectId: number, userName: string, roomId: number)
{
super(type);
this._objectId = objectId;
this._userName = userName;
this._roomId = roomId;
}
public get objectId(): number
{
return this._objectId;
}
public get userName(): string
{
return this._userName;
}
public get roomId(): number
{
return this._roomId;
}
}

View File

@ -0,0 +1,20 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetChatTypingMessage extends RoomWidgetMessage
{
public static TYPING_STATUS: string = 'RWCTM_TYPING_STATUS';
private _isTyping: boolean;
constructor(isTyping: boolean)
{
super(RoomWidgetChatTypingMessage.TYPING_STATUS);
this._isTyping = isTyping;
}
public get isTyping(): boolean
{
return this._isTyping;
}
}

View File

@ -0,0 +1,10 @@
import { RoomWidgetMessage } from './RoomWidgetMessage';
export class RoomWidgetRequestWidgetMessage extends RoomWidgetMessage
{
public static USER_CHOOSER: string = 'RWRWM_USER_CHOOSER';
public static FURNI_CHOOSER: string = 'RWRWM_FURNI_CHOOSER';
public static ME_MENU: string = 'RWRWM_ME_MENU';
public static EFFECTS: string = 'RWRWM_EFFECTS';
public static FLOOR_EDITOR: string = 'RWRWM_FLOOR_EDITOR';
}

View File

@ -1,8 +1,12 @@
export * from './RoomWidgetAvatarExpressionMessage'; export * from './RoomWidgetAvatarExpressionMessage';
export * from './RoomWidgetChangeMottoMessage'; export * from './RoomWidgetChangeMottoMessage';
export * from './RoomWidgetChangePostureMessage'; export * from './RoomWidgetChangePostureMessage';
export * from './RoomWidgetChatMessage';
export * from './RoomWidgetChatSelectAvatarMessage';
export * from './RoomWidgetChatTypingMessage';
export * from './RoomWidgetDanceMessage'; export * from './RoomWidgetDanceMessage';
export * from './RoomWidgetFurniActionMessage'; export * from './RoomWidgetFurniActionMessage';
export * from './RoomWidgetMessage'; export * from './RoomWidgetMessage';
export * from './RoomWidgetRequestWidgetMessage';
export * from './RoomWidgetRoomObjectMessage'; export * from './RoomWidgetRoomObjectMessage';
export * from './RoomWidgetUserActionMessage'; export * from './RoomWidgetUserActionMessage';

View File

@ -4,72 +4,62 @@
left: 50%; left: 50%;
transform: translateX(-50%); transform: translateX(-50%);
bottom: 65px !important; bottom: 65px !important;
z-index: $chatinput-zindex;
} }
} }
.nitro-chat-input { .nitro-chat-input-container {
pointer-events: none; display: flex;
z-index: $chatinput-zindex; justify-content: center;
align-items: center;
position: relative;
height: 40px;
border-radius: 8px;
border: 2px solid rgb(0, 0, 0);
background: #EDEDED;
padding-right: 30px;
width: 100%;
.chatinput-container { &:before {
position: relative; content: "";
height: 40px; position: absolute;
width: 98%;
height: 5px;
border-radius: 8px; border-radius: 8px;
border: 2px solid rgb(0, 0, 0); top: 1px;
background: #EDEDED; left: 0;
pointer-events: all; right: 0;
padding-right: 30px; margin: auto;
width: 100%; background: rgb(255, 255, 255);
z-index: 1;
}
.input-sizer { .input-sizer {
display: inline-grid; display: inline-grid;
vertical-align: top; vertical-align: top;
align-items: center; height: 100%;
position: relative; padding: 0 10px;
height: 100%;
padding: 0 10px; &::after,
input,
&::after, textarea {
input, width: auto;
textarea { min-width: 1em;
width: auto; grid-area: 1 / 2;
min-width: 1em; margin: 0;
grid-area: 1 / 2; resize: none;
margin: 0; background: none;
resize: none; appearance: none;
background: none; border: none;
appearance: none; outline: none;
border: none;
}
&::after {
content: attr(data-value) ' ';
visibility: hidden;
white-space: pre-wrap;
}
}
.chat-input {
height: 100%;
font-size: 16px;
outline: 0;
border: 0;
position: relative;
background: transparent;
} }
&:before { &::after {
content: ""; content: attr(data-value) ' ';
position: absolute; visibility: hidden;
width: 98%; white-space: pre-wrap;
height: 5px;
border-radius: 8px;
top: 1px;
left: 0;
right: 0;
margin: auto;
background: rgb(255, 255, 255);
z-index: 1;
} }
} }
} }
@import './style-selector/ChatInputStyleSelectorView';

View File

@ -1,9 +1,13 @@
import { FC, MouseEvent, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { createPortal } from 'react-dom'; import { createPortal } from 'react-dom';
import { GetConfiguration, GetRoomSession, SendChatTypingMessage } from '../../../../api'; import { GetConfiguration } from '../../../../api';
import { CreateEventDispatcherHook } from '../../../../hooks/events';
import { LocalizeText } from '../../../../utils/LocalizeText'; import { LocalizeText } from '../../../../utils/LocalizeText';
import { useRoomContext } from '../../context/RoomContext'; import { useRoomContext } from '../../context/RoomContext';
import { ChatInputMessageType, ChatInputViewProps } from './ChatInputView.types'; import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events';
import { RoomWidgetChatMessage, RoomWidgetChatTypingMessage } from '../../messages';
import { ChatInputViewProps } from './ChatInputView.types';
import { ChatInputStyleSelectorView } from './style-selector/ChatInputStyleSelectorView';
let lastContent = ''; let lastContent = '';
@ -13,6 +17,8 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
const [ chatValue, setChatValue ] = useState<string>(''); const [ chatValue, setChatValue ] = useState<string>('');
const [ selectedUsername, setSelectedUsername ] = useState(''); const [ selectedUsername, setSelectedUsername ] = useState('');
const [ isTyping, setIsTyping ] = useState(false); const [ isTyping, setIsTyping ] = useState(false);
const [ typingStartedSent, setTypingStartedSent ] = useState(false);
const [ isIdle, setIsIdle ] = useState(false);
const inputRef = useRef<HTMLInputElement>(); const inputRef = useRef<HTMLInputElement>();
const chatModeIdWhisper = useMemo(() => const chatModeIdWhisper = useMemo(() =>
@ -59,35 +65,24 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
{ {
setChatValue(prevValue => setChatValue(prevValue =>
{ {
if((prevValue !== LocalizeText('widgets.chatinput.mode.whisper')) || !selectedUsername.length) return prevValue; if((prevValue !== chatModeIdWhisper) || !selectedUsername.length) return prevValue;
return (`${ prevValue } ${ selectedUsername }`); return (`${ prevValue } ${ selectedUsername }`);
}); });
}, [ selectedUsername ]); }, [ selectedUsername, chatModeIdWhisper ]);
const sendChat = useCallback((text: string, chatType: number, recipientName: string = '', styleId: number = 0) => const sendChat = useCallback((text: string, chatType: number, recipientName: string = '', styleId: number = 0) =>
{ {
setChatValue(''); setChatValue('');
switch(chatType) widgetHandler.processWidgetMessage(new RoomWidgetChatMessage(RoomWidgetChatMessage.MESSAGE_CHAT, text, chatType, recipientName, styleId));
{ }, [ widgetHandler ]);
case ChatInputMessageType.CHAT_DEFAULT:
GetRoomSession().sendChatMessage(text, styleId);
return;
case ChatInputMessageType.CHAT_WHISPER:
GetRoomSession().sendWhisperMessage(recipientName, text, styleId);
return;
case ChatInputMessageType.CHAT_SHOUT:
GetRoomSession().sendShoutMessage(text, styleId);
return;
}
}, []);
const sendChatValue = useCallback((value: string, shiftKey: boolean = false) => const sendChatValue = useCallback((value: string, shiftKey: boolean = false) =>
{ {
if(!value || (value === '')) return; if(!value || (value === '')) return;
let chatType = (shiftKey ? ChatInputMessageType.CHAT_SHOUT : ChatInputMessageType.CHAT_DEFAULT); let chatType = (shiftKey ? RoomWidgetChatMessage.CHAT_SHOUT : RoomWidgetChatMessage.CHAT_DEFAULT);
let text = value; let text = value;
const parts = text.split(' '); const parts = text.split(' ');
@ -98,7 +93,7 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
switch(parts[0]) switch(parts[0])
{ {
case chatModeIdWhisper: case chatModeIdWhisper:
chatType = ChatInputMessageType.CHAT_WHISPER; chatType = RoomWidgetChatMessage.CHAT_WHISPER;
recipientName = parts[1]; recipientName = parts[1];
append = (chatModeIdWhisper + ' ' + recipientName + ' '); append = (chatModeIdWhisper + ' ' + recipientName + ' ');
@ -106,12 +101,12 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
parts.shift(); parts.shift();
break; break;
case chatModeIdShout: case chatModeIdShout:
chatType = ChatInputMessageType.CHAT_SHOUT; chatType = RoomWidgetChatMessage.CHAT_SHOUT;
parts.shift(); parts.shift();
break; break;
case chatModeIdSpeak: case chatModeIdSpeak:
chatType = ChatInputMessageType.CHAT_DEFAULT; chatType = RoomWidgetChatMessage.CHAT_DEFAULT;
parts.shift(); parts.shift();
break; break;
@ -119,6 +114,9 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
text = parts.join(' '); text = parts.join(' ');
setIsTyping(false);
setIsIdle(false);
if(text.length <= maxChatLength) if(text.length <= maxChatLength)
{ {
// if(this.needsStyleUpdate) // if(this.needsStyleUpdate)
@ -132,32 +130,114 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
sendChat(text, chatType, recipientName, currentStyle); sendChat(text, chatType, recipientName, currentStyle);
} }
setChatValue(append);
}, [ chatModeIdWhisper, chatModeIdShout, chatModeIdSpeak, maxChatLength, sendChat ]); }, [ chatModeIdWhisper, chatModeIdShout, chatModeIdSpeak, maxChatLength, sendChat ]);
const updateChatInput = useCallback((value: string) =>
{
if(!value || !value.length)
{
setIsTyping(false);
}
else
{
setIsTyping(true);
setIsIdle(true);
}
setChatValue(value);
}, []);
const onKeyDownEvent = useCallback((event: KeyboardEvent) => const onKeyDownEvent = useCallback((event: KeyboardEvent) =>
{ {
if(!inputRef.current || anotherInputHasFocus()) return; if(!inputRef.current || anotherInputHasFocus()) return;
if(document.activeElement !== inputRef.current) setInputFocus(); if(document.activeElement !== inputRef.current) setInputFocus();
switch(event.key) const value = (event.target as HTMLInputElement).value;
switch(event.code)
{ {
case 'Space': case 'Space':
checkSpecialKeywordForInput(); checkSpecialKeywordForInput();
return; return;
case 'Enter': case 'Enter':
sendChatValue((event.target as HTMLInputElement).value, event.shiftKey); sendChatValue(value, event.shiftKey);
return; return;
case 'Backspace': case 'Backspace':
if(value)
{
const parts = value.split(' ');
if((parts[0] === chatModeIdWhisper) && (parts.length === 3) && (parts[2] === ''))
{
setChatValue('');
}
}
return; return;
} }
}, [ inputRef, anotherInputHasFocus, setInputFocus, checkSpecialKeywordForInput, sendChatValue ]); }, [ inputRef, chatModeIdWhisper, anotherInputHasFocus, setInputFocus, checkSpecialKeywordForInput, sendChatValue ]);
const onInputMouseDownEvent = useCallback((event: MouseEvent<HTMLInputElement>) => const onStyleSelected = useCallback((styleId: number) =>
{ {
setInputFocus();
}, [ setInputFocus ]); }, []);
const onRoomWidgetRoomObjectUpdateEvent = useCallback((event: RoomWidgetRoomObjectUpdateEvent) =>
{
setSelectedUsername('');
}, []);
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_DESELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
const onRoomWidgetUpdateInfostandUserEvent = useCallback((event: RoomWidgetUpdateInfostandUserEvent) =>
{
setSelectedUsername(event.name);
}, []);
CreateEventDispatcherHook(RoomWidgetUpdateInfostandUserEvent.PEER, eventDispatcher, onRoomWidgetUpdateInfostandUserEvent);
useEffect(() =>
{
if(isTyping)
{
if(!typingStartedSent)
{
setTypingStartedSent(true);
widgetHandler.processWidgetMessage(new RoomWidgetChatTypingMessage(isTyping));
}
}
else
{
if(typingStartedSent)
{
setTypingStartedSent(false);
widgetHandler.processWidgetMessage(new RoomWidgetChatTypingMessage(isTyping));
}
}
}, [ widgetHandler, isTyping, typingStartedSent ]);
useEffect(() =>
{
if(!isIdle) return;
let timeout: ReturnType<typeof setTimeout> = null;
if(isIdle)
{
timeout = setTimeout(() =>
{
setIsIdle(false);
setIsTyping(false)
}, 10000);
}
return () => clearTimeout(timeout);
}, [ isIdle ]);
useEffect(() => useEffect(() =>
{ {
@ -169,59 +249,13 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
} }
}, [ onKeyDownEvent ]); }, [ onKeyDownEvent ]);
useEffect(() =>
{
let idleTimer: ReturnType<typeof setTimeout> = null;
if(!chatValue || !chatValue.length)
{
setIsTyping(prevValue =>
{
if(!prevValue) return prevValue;
if(prevValue) SendChatTypingMessage(false);
return false;
});
}
else
{
setIsTyping(prevValue =>
{
if(prevValue) return prevValue;
if(!prevValue) SendChatTypingMessage(true);
return true;
});
lastContent = chatValue;
idleTimer = setTimeout(() =>
{
setIsTyping(prevValue =>
{
if(prevValue) SendChatTypingMessage(false);
return false;
});
}, 3000);
}
return () =>
{
if(idleTimer) clearTimeout(idleTimer);
}
}, [ chatValue ]);
return ( return (
createPortal( createPortal(
<div className="nitro-chat-input"> <div className="nitro-chat-input-container">
<div className="chatinput-container"> <div className="input-sizer">
<div className="input-sizer"> <input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } maxLength={ maxChatLength } onChange={ event => { event.target.parentElement.dataset.value = event.target.value; updateChatInput(event.target.value) } } onMouseDown={ event => setInputFocus() } />
<input ref={ inputRef } type="text" className="chat-input" placeholder={ LocalizeText('widgets.chatinput.default') } value={ chatValue } maxLength={ maxChatLength } onChange={ event => { event.target.parentElement.dataset.value = event.target.value; setChatValue(event.target.value) } } onMouseDown={ onInputMouseDownEvent } />
</div>
</div> </div>
<ChatInputStyleSelectorView onStyleSelected={ onStyleSelected } />
</div>, document.getElementById('toolbar-chat-input-container')) </div>, document.getElementById('toolbar-chat-input-container'))
); );
} }

View File

@ -4,10 +4,3 @@ export interface ChatInputViewProps extends RoomWidgetProps
{ {
} }
export class ChatInputMessageType
{
public static CHAT_DEFAULT: number = 0;
public static CHAT_WHISPER: number = 1;
public static CHAT_SHOUT: number = 2;
}

View File

@ -0,0 +1,61 @@
.nitro-chat-style-selector-button {
position: absolute;
display: flex;
justify-content: center;
align-items: center;
height: 100%;
right: 7px;
}
.nitro-chat-style-selector-test {
display: flex;
position: relative;
right: 30px;
pointer-events: all;
height: 100%;
i.icon {
cursor: pointer;
align-self: center;
}
.nitro-chatstyle-selector {
position: absolute;
width: 250px;
top: -4px;
transition: transform 0.22s ease-in-out;
transform: translate(-81px, -50%) scale(0);
&.active {
visibility: visible;
transform: translate(-160px, -100%) scale(1);
}
.grid-container {
.grid-items {
margin-top: -7px;
.item-detail {
height: 30px;
max-height: 30px;
width: calc(1 / 3 * 100% - (1 - 1 / 3) * 7px);
margin: 7px 7px 0 0;
overflow: visible;
&:hover {
cursor: pointer;
}
.detail-info {
.bubble-container {
visibility: visible;
width: 75%;
}
}
}
}
}
}
}

View File

@ -0,0 +1,20 @@
import { FC, useState } from 'react';
import { ChatInputStyleSelectorViewProps } from './ChatInputStyleSelectorView.types';
export const ChatInputStyleSelectorView: FC<ChatInputStyleSelectorViewProps> = props =>
{
const { onStyleSelected = null } = props;
const [ selectorVisible, setSelectorVisible ] = useState(false);
return (
<>
<div className="nitro-chat-style-selector-button">
<i className="icon chatstyles-icon" />
</div>
{ selectorVisible &&
<div className="nitro-chat-style-selector-container">
</div> }
</>
)
}

View File

@ -0,0 +1,4 @@
export interface ChatInputStyleSelectorViewProps
{
onStyleSelected: (styleId: number) => void;
}