diff --git a/src/api/nitro/session/SendChatTypingMessage.ts b/src/api/nitro/session/SendChatTypingMessage.ts deleted file mode 100644 index 971db4ff..00000000 --- a/src/api/nitro/session/SendChatTypingMessage.ts +++ /dev/null @@ -1,6 +0,0 @@ -import { GetRoomSession } from './GetRoomSession'; - -export function SendChatTypingMessage(isTyping: boolean): void -{ - GetRoomSession().sendChatTypingMessage(isTyping); -} diff --git a/src/api/nitro/session/index.ts b/src/api/nitro/session/index.ts index cdf07f2a..ff45e484 100644 --- a/src/api/nitro/session/index.ts +++ b/src/api/nitro/session/index.ts @@ -11,5 +11,4 @@ export * from './HasHabboClub'; export * from './HasHabboVip'; export * from './IsOwnerOfFurniture'; export * from './IsRidingHorse'; -export * from './SendChatTypingMessage'; export * from './StartRoomSession'; diff --git a/src/views/room/RoomView.tsx b/src/views/room/RoomView.tsx index f4ea630f..fe7d0145 100644 --- a/src/views/room/RoomView.tsx +++ b/src/views/room/RoomView.tsx @@ -9,7 +9,7 @@ import { GetRoomEngine } from '../../api/nitro/room/GetRoomEngine'; import { useRoomEngineEvent } from '../../hooks/events'; import { RoomContextProvider } from './context/RoomContext'; import { RoomWidgetRoomEngineUpdateEvent, RoomWidgetRoomObjectUpdateEvent } from './events'; -import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; +import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers'; import { RoomViewProps } from './RoomView.types'; import { RoomWidgetsView } from './widgets/RoomWidgetsView'; @@ -36,6 +36,7 @@ export const RoomView: FC = props => widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler()); widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler()); widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler()); + widgetHandlerManager.registerHandler(new RoomWidgetChatHandler()); setWidgetHandler(widgetHandlerManager); diff --git a/src/views/room/events/RoomWidgetFloodControlEvent.ts b/src/views/room/events/RoomWidgetFloodControlEvent.ts index 4c07a560..a4d01c60 100644 --- a/src/views/room/events/RoomWidgetFloodControlEvent.ts +++ b/src/views/room/events/RoomWidgetFloodControlEvent.ts @@ -6,11 +6,11 @@ export class RoomWidgetFloodControlEvent extends RoomWidgetUpdateEvent private _seconds: number = 0; - constructor(k: number) + constructor(seconds: number) { super(RoomWidgetFloodControlEvent.FLOOD_CONTROL); - this._seconds = k; + this._seconds = seconds; } public get seconds(): number diff --git a/src/views/room/events/RoomWidgetUpdateChatEvent.ts b/src/views/room/events/RoomWidgetUpdateChatEvent.ts new file mode 100644 index 00000000..bef476b1 --- /dev/null +++ b/src/views/room/events/RoomWidgetUpdateChatEvent.ts @@ -0,0 +1,124 @@ +import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; + +export class RoomWidgetUpdateChatEvent extends RoomWidgetUpdateEvent +{ + public static CHAT_EVENT: string = 'RWUCE_CHAT_EVENT'; + public static CHAT_TYPE_SPEAK: number = 0; + public static CHAT_TYPE_WHISPER: number = 1; + public static CHAT_TYPE_SHOUT: number = 2; + public static CHAT_TYPE_RESPECT: number = 3; + public static CHAT_TYPE_PETRESPECT: number = 4; + public static CHAT_TYPE_NOTIFY: number = 5; + public static CHAT_TYPE_PETTREAT: number = 6; + public static CHAT_TYPE_PETREVIVE: number = 7; + public static CHAT_TYPE_PET_REBREED_FERTILIZE: number = 8; + public static CHAT_TYPE_PET_SPEED_FERTILIZE: number = 9; + public static CHAT_TYPE_BOT_SPEAK: number = 10; + public static CHAT_TYPE_BOT_SHOUT: number = 11; + public static CHAT_TYPE_BOT_WHISPER: number = 12; + + private _userId: number; + private _text: string; + private _chatType: number; + private _userName: string; + private _links: string[]; + private _userX: number; + private _userY: number; + private _userImage: string; + private _userColor: number; + private _roomId: number; + private _userCategory: number; + private _userType: number; + private _petType: number; + private _styleId: number; + + constructor(type: string, userId: number, text: string, userName: string, userCategory: number, userType: number, petType: number, userX: number, userY: number, userImage: string, userColor: number, roomId: number, chatType: number = 0, styleId: number = 0, links: string[] = null) + { + super(type); + + this._userId = userId; + this._text = text; + this._chatType = chatType; + this._userName = userName; + this._userCategory = userCategory; + this._userType = userType; + this._petType = petType; + this._links = links; + this._userX = userX; + this._userY = userY; + this._userImage = userImage; + this._userColor = userColor; + this._roomId = roomId; + this._styleId = styleId; + } + + public get userId(): number + { + return this._userId; + } + + public get text(): string + { + return this._text; + } + + public get chatType(): number + { + return this._chatType; + } + + public get userName(): string + { + return this._userName; + } + + public get userCategory(): number + { + return this._userCategory; + } + + public get userType(): number + { + return this._userType; + } + + public get petType(): number + { + return this._petType; + } + + public get links(): string[] + { + return this._links; + } + + public get userX(): number + { + return this._userX; + } + + public get userY(): number + { + return this._userY; + } + + public get userImage(): string + { + return this._userImage; + } + + public get userColor(): number + { + return this._userColor; + } + + public get roomId(): number + { + return this._roomId; + } + + public get styleId(): number + { + return this._styleId; + } +} diff --git a/src/views/room/events/RoomWidgetChatInputContentUpdateEvent.ts b/src/views/room/events/RoomWidgetUpdateChatInputContentEvent.ts similarity index 58% rename from src/views/room/events/RoomWidgetChatInputContentUpdateEvent.ts rename to src/views/room/events/RoomWidgetUpdateChatInputContentEvent.ts index c1b03c43..0b92b813 100644 --- a/src/views/room/events/RoomWidgetChatInputContentUpdateEvent.ts +++ b/src/views/room/events/RoomWidgetUpdateChatInputContentEvent.ts @@ -1,20 +1,20 @@ import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; -export class RoomWidgetChatInputContentUpdateEvent extends RoomWidgetUpdateEvent +export class RoomWidgetUpdateChatInputContentEvent extends RoomWidgetUpdateEvent { - public static CHAT_INPUT_CONTENT: string = 'RWCICUE_CHAT_INPUT_CONTENT'; + public static CHAT_INPUT_CONTENT: string = 'RWUCICE_CHAT_INPUT_CONTENT'; public static WHISPER: string = 'whisper'; public static SHOUT: string = 'shout'; private _chatMode: string = ''; private _userName: string = ''; - constructor(k: string, _arg_2: string) + constructor(chatMode: string, userName: string) { - super(RoomWidgetChatInputContentUpdateEvent.CHAT_INPUT_CONTENT); + super(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT); - this._chatMode = k; - this._userName = _arg_2; + this._chatMode = chatMode; + this._userName = userName; } public get chatMode(): string diff --git a/src/views/room/events/RoomWidgetUpdateUserDataEvent.ts b/src/views/room/events/RoomWidgetUpdateUserDataEvent.ts new file mode 100644 index 00000000..fbf65876 --- /dev/null +++ b/src/views/room/events/RoomWidgetUpdateUserDataEvent.ts @@ -0,0 +1,11 @@ +import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; + +export class RoomWidgetUpdateUserDataEvent extends RoomWidgetUpdateEvent +{ + public static USER_DATA_UPDATED: string = 'RWUUDE_USER_DATA_UPDATED'; + + constructor() + { + super(RoomWidgetUpdateUserDataEvent.USER_DATA_UPDATED); + } +} diff --git a/src/views/room/events/RoomWidgetUserDataUpdateEvent.ts b/src/views/room/events/RoomWidgetUserDataUpdateEvent.ts deleted file mode 100644 index 62a747b6..00000000 --- a/src/views/room/events/RoomWidgetUserDataUpdateEvent.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent'; - -export class RoomWidgetUserDataUpdateEvent extends RoomWidgetUpdateEvent -{ - public static USER_DATA_UPDATED: string = 'RWUDUE_USER_DATA_UPDATED'; - - constructor() - { - super(RoomWidgetUserDataUpdateEvent.USER_DATA_UPDATED); - } -} diff --git a/src/views/room/events/index.ts b/src/views/room/events/index.ts index 29a4f293..d281c2fc 100644 --- a/src/views/room/events/index.ts +++ b/src/views/room/events/index.ts @@ -1,9 +1,10 @@ export * from './RoomWidgetAvatarInfoEvent'; -export * from './RoomWidgetChatInputContentUpdateEvent'; export * from './RoomWidgetFloodControlEvent'; export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetRoomEngineUpdateEvent'; export * from './RoomWidgetRoomObjectUpdateEvent'; +export * from './RoomWidgetUpdateChatEvent'; +export * from './RoomWidgetUpdateChatInputContentEvent'; export * from './RoomWidgetUpdateDanceStatusEvent'; export * from './RoomWidgetUpdateEvent'; export * from './RoomWidgetUpdateInfostandEvent'; @@ -12,4 +13,4 @@ export * from './RoomWidgetUpdateInfostandPetEvent'; export * from './RoomWidgetUpdateInfostandRentableBotEvent'; export * from './RoomWidgetUpdateInfostandUserEvent'; export * from './RoomWidgetUpdateRentableBotChatEvent'; -export * from './RoomWidgetUserDataUpdateEvent'; +export * from './RoomWidgetUpdateUserDataEvent'; diff --git a/src/views/room/handlers/RoomWidgetAvatarInfoHandler.ts b/src/views/room/handlers/RoomWidgetAvatarInfoHandler.ts index 4ff95da1..c88ce7d4 100644 --- a/src/views/room/handlers/RoomWidgetAvatarInfoHandler.ts +++ b/src/views/room/handlers/RoomWidgetAvatarInfoHandler.ts @@ -1,6 +1,6 @@ import { NitroEvent, RoomSessionDanceEvent, RoomSessionUserDataUpdateEvent } from 'nitro-renderer'; import { GetRoomSession, GetSessionDataManager } from '../../../api'; -import { RoomWidgetAvatarInfoEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateEvent, RoomWidgetUserDataUpdateEvent } from '../events'; +import { RoomWidgetAvatarInfoEvent, RoomWidgetUpdateDanceStatusEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateUserDataEvent } from '../events'; import { RoomWidgetAvatarExpressionMessage, RoomWidgetChangePostureMessage, RoomWidgetDanceMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUserActionMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -11,7 +11,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler switch(event.type) { case RoomSessionUserDataUpdateEvent.USER_DATA_UPDATED: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetUserDataUpdateEvent()); + this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateUserDataEvent()); return; case RoomSessionDanceEvent.RSDE_DANCE: const danceEvent = (event as RoomSessionDanceEvent); diff --git a/src/views/room/handlers/RoomWidgetChatHandler.ts b/src/views/room/handlers/RoomWidgetChatHandler.ts new file mode 100644 index 00000000..63de3b7b --- /dev/null +++ b/src/views/room/handlers/RoomWidgetChatHandler.ts @@ -0,0 +1,205 @@ +import { AvatarFigurePartType, AvatarScaleType, AvatarSetType, IAvatarImageListener, INitroPoint, IVector3D, NitroEvent, NitroPoint, PetFigureData, RoomObjectCategory, RoomObjectType, RoomObjectVariable, RoomSessionChatEvent, SystemChatStyleEnum, TextureUtils, Vector3d } from 'nitro-renderer'; +import { GetAvatarRenderManager, GetRoomEngine } from '../../../api'; +import { LocalizeText } from '../../../utils/LocalizeText'; +import { RoomWidgetUpdateChatEvent, RoomWidgetUpdateEvent } from '../events'; +import { RoomWidgetMessage } from '../messages'; +import { RoomWidgetHandler } from './RoomWidgetHandler'; + +export class RoomWidgetChatHandler extends RoomWidgetHandler implements IAvatarImageListener +{ + private _avatarColorCache: Map = new Map(); + private _avatarImageCache: Map = new Map(); + private _petImageCache: Map = new Map(); + + public processEvent(event: NitroEvent): void + { + switch(event.type) + { + case RoomSessionChatEvent.CHAT_EVENT: { + const chatEvent = (event as RoomSessionChatEvent); + + const roomObject = GetRoomEngine().getRoomObject(chatEvent.session.roomId, chatEvent.objectId, RoomObjectCategory.UNIT); + + if(!roomObject) return; + + const objectLocation = roomObject.getLocation(); + const bubbleLocation = this.getBubbleLocation(chatEvent.session.roomId, objectLocation); + const userData = this.container.roomSession.userDataManager.getUserDataByIndex(chatEvent.objectId); + + let username = ''; + let avatarColor = 0; + let imageUrl: string = null; + let chatType = chatEvent.chatType; + let styleId = chatEvent.style; + let userType = 0; + let petType = -1; + let text = chatEvent.message; + + if(userData) + { + userType = userData.type; + + const figure = userData.figure; + + switch(userType) + { + case RoomObjectType.PET: + imageUrl = this.getPetImage(figure, 2, true, 64, roomObject.model.getValue(RoomObjectVariable.FIGURE_POSTURE)); + petType = new PetFigureData(figure).typeId; + break; + case RoomObjectType.USER: + imageUrl = this.getUserImage(figure); + break; + case RoomObjectType.RENTABLE_BOT: + case RoomObjectType.BOT: + styleId = SystemChatStyleEnum.BOT; + break; + } + + avatarColor = this._avatarColorCache.get(figure); + username = userData.name; + } + + switch(chatType) + { + case RoomSessionChatEvent.CHAT_TYPE_RESPECT: + text = LocalizeText('widgets.chatbubble.respect', [ 'username' ], [ username ]); + break; + case RoomSessionChatEvent.CHAT_TYPE_PETRESPECT: + text = LocalizeText('widget.chatbubble.petrespect', [ 'petname' ], [ username ]); + break; + case RoomSessionChatEvent.CHAT_TYPE_PETTREAT: + text = LocalizeText('widget.chatbubble.pettreat', [ 'petname' ], [ username ]); + break; + case RoomSessionChatEvent.CHAT_TYPE_HAND_ITEM_RECEIVED: + text = LocalizeText('widget.chatbubble.handitem', [ 'username', 'handitem' ], [ username, LocalizeText(('handitem' + chatEvent.extraParam))]); + break; + case RoomSessionChatEvent.CHAT_TYPE_MUTE_REMAINING: { + const hours = ((chatEvent.extraParam > 0) ? Math.floor((chatEvent.extraParam / 3600)) : 0).toString(); + const minutes = ((chatEvent.extraParam > 0) ? Math.floor((chatEvent.extraParam % 3600) / 60) : 0).toString(); + const seconds = (chatEvent.extraParam % 60).toString(); + + text = LocalizeText('widget.chatbubble.mutetime', [ 'hours', 'minutes', 'seconds' ], [ hours, minutes, seconds ]); + break; + } + } + + this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateChatEvent(RoomWidgetUpdateChatEvent.CHAT_EVENT, userData.roomIndex, text, username, RoomObjectCategory.UNIT, userType, petType, bubbleLocation.x, bubbleLocation.y, imageUrl, avatarColor, chatEvent.session.roomId, chatType, styleId, [])); + + return; + } + } + } + + public processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent + { + return null; + } + + private getBubbleLocation(roomId: number, userLocation: IVector3D, canvasId = 1): INitroPoint + { + const geometry = GetRoomEngine().getRoomInstanceGeometry(roomId, canvasId); + const scale = GetRoomEngine().getRoomInstanceRenderingCanvasScale(roomId, canvasId); + + let x = ((document.body.offsetWidth * scale) / 2); + let y = ((document.body.offsetHeight * scale) / 2); + + if(geometry && userLocation) + { + const screenPoint = geometry.getScreenPoint(userLocation); + + if(screenPoint) + { + x = (x + (screenPoint.x * scale)); + y = (y + (screenPoint.y * scale)); + + const offsetPoint = GetRoomEngine().getRoomInstanceRenderingCanvasOffset(roomId, canvasId); + + if(offsetPoint) + { + x = (x + offsetPoint.x); + y = (y + offsetPoint.y); + } + } + } + + return new NitroPoint(x, y); + } + + public getUserImage(figure: string): string + { + let existing = this._avatarImageCache.get(figure); + + if(!existing) + { + existing = this.setFigureImage(figure); + } + + return existing; + } + + private setFigureImage(figure: string): string + { + const avatarImage = GetAvatarRenderManager().createAvatarImage(figure, AvatarScaleType.LARGE, null, this); + + if(!avatarImage) return; + + const image = avatarImage.getCroppedImage(AvatarSetType.HEAD); + const color = avatarImage.getPartColor(AvatarFigurePartType.CHEST); + + this._avatarColorCache.set(figure, ((color && color.rgb) || 16777215)); + + avatarImage.dispose(); + + this._avatarImageCache.set(figure, image.src); + + return image.src; + } + + private getPetImage(figure: string, direction: number, _arg_3: boolean, scale: number = 64, posture: string = null): string + { + let existing = this._petImageCache.get((figure + posture)); + + if(existing) return existing; + + const figureData = new PetFigureData(figure); + const typeId = figureData.typeId; + const image = GetRoomEngine().getRoomObjectPetImage(typeId, figureData.paletteId, figureData.color, new Vector3d((direction * 45)), scale, null, false, 0, figureData.customParts, posture); + + if(image) + { + existing = TextureUtils.generateImageUrl(image.data); + + this._petImageCache.set((figure + posture), existing); + } + + return existing; + } + + public resetFigure(figure: string): void + { + this.setFigureImage(figure); + } + + public dispose(): void + { + + } + + public get disposed(): boolean + { + return false; + } + + public get eventTypes(): string[] + { + return [ + RoomSessionChatEvent.CHAT_EVENT + ]; + } + + public get messageTypes(): string[] + { + return []; + } +} diff --git a/src/views/room/handlers/RoomWidgetChatInputHandler.ts b/src/views/room/handlers/RoomWidgetChatInputHandler.ts index d726fc57..20f054e6 100644 --- a/src/views/room/handlers/RoomWidgetChatInputHandler.ts +++ b/src/views/room/handlers/RoomWidgetChatInputHandler.ts @@ -1,5 +1,5 @@ import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomZoomEvent } from 'nitro-renderer'; -import { GetConnection, GetRoomEngine, GetSessionDataManager, SendChatTypingMessage } from '../../../api'; +import { GetConnection, GetRoomEngine, GetSessionDataManager } from '../../../api'; import { RoomWidgetFloodControlEvent, RoomWidgetUpdateEvent } from '../events'; import { RoomWidgetChatMessage, RoomWidgetChatSelectAvatarMessage, RoomWidgetChatTypingMessage, RoomWidgetMessage, RoomWidgetRequestWidgetMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -25,7 +25,7 @@ export class RoomWidgetChatInputHandler extends RoomWidgetHandler case RoomWidgetChatTypingMessage.TYPING_STATUS: { const typingMessage = (message as RoomWidgetChatTypingMessage); - SendChatTypingMessage(typingMessage.isTyping); + this.container.roomSession.sendChatTypingMessage(typingMessage.isTyping); break; } case RoomWidgetChatMessage.MESSAGE_CHAT: { diff --git a/src/views/room/handlers/RoomWidgetInfostandHandler.ts b/src/views/room/handlers/RoomWidgetInfostandHandler.ts index b3d7f286..868911a7 100644 --- a/src/views/room/handlers/RoomWidgetInfostandHandler.ts +++ b/src/views/room/handlers/RoomWidgetInfostandHandler.ts @@ -3,7 +3,7 @@ import { GetConnection, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture import { WiredSelectObjectEvent } from '../../../events'; import { dispatchUiEvent } from '../../../hooks/events'; import { LocalizeText } from '../../../utils/LocalizeText'; -import { RoomWidgetChatInputContentUpdateEvent, RoomWidgetObjectNameEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events'; +import { RoomWidgetObjectNameEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateEvent, RoomWidgetUpdateInfostandFurniEvent, RoomWidgetUpdateInfostandPetEvent, RoomWidgetUpdateInfostandRentableBotEvent, RoomWidgetUpdateInfostandUserEvent } from '../events'; import { RoomWidgetChangeMottoMessage, RoomWidgetFurniActionMessage, RoomWidgetMessage, RoomWidgetRoomObjectMessage, RoomWidgetUserActionMessage } from '../messages'; import { RoomWidgetHandler } from './RoomWidgetHandler'; @@ -82,7 +82,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler GetSessionDataManager().givePetRespect(userId); break; case RoomWidgetUserActionMessage.WHISPER_USER: - this.container.eventDispatcher.dispatchEvent(new RoomWidgetChatInputContentUpdateEvent(RoomWidgetChatInputContentUpdateEvent.WHISPER, userData.name)); + this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateChatInputContentEvent(RoomWidgetUpdateChatInputContentEvent.WHISPER, userData.name)); break; case RoomWidgetUserActionMessage.IGNORE_USER: GetSessionDataManager().ignoreUser(userData.name); diff --git a/src/views/room/handlers/index.ts b/src/views/room/handlers/index.ts index 39d82f56..64596a0f 100644 --- a/src/views/room/handlers/index.ts +++ b/src/views/room/handlers/index.ts @@ -1,6 +1,7 @@ export * from './IRoomWidgetHandler'; export * from './IRoomWidgetHandlerManager'; export * from './RoomWidgetAvatarInfoHandler'; +export * from './RoomWidgetChatHandler'; export * from './RoomWidgetChatInputHandler'; export * from './RoomWidgetHandler'; export * from './RoomWidgetHandlerManager'; diff --git a/src/views/room/widgets/chat-input/ChatInputView.tsx b/src/views/room/widgets/chat-input/ChatInputView.tsx index 82c0aac4..471376ff 100644 --- a/src/views/room/widgets/chat-input/ChatInputView.tsx +++ b/src/views/room/widgets/chat-input/ChatInputView.tsx @@ -4,16 +4,13 @@ import { GetConfiguration, GetSessionDataManager } from '../../../../api'; import { CreateEventDispatcherHook } from '../../../../hooks/events'; import { LocalizeText } from '../../../../utils/LocalizeText'; import { useRoomContext } from '../../context/RoomContext'; -import { RoomWidgetChatInputContentUpdateEvent, RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events'; +import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events'; import { RoomWidgetChatMessage, RoomWidgetChatTypingMessage } from '../../messages'; import { ChatInputViewProps } from './ChatInputView.types'; import { ChatInputStyleSelectorView } from './style-selector/ChatInputStyleSelectorView'; -let lastContent = ''; - export const ChatInputView: FC = props => { - const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); const [ chatValue, setChatValue ] = useState(''); const [ selectedUsername, setSelectedUsername ] = useState(''); const [ isTyping, setIsTyping ] = useState(false); @@ -21,6 +18,7 @@ export const ChatInputView: FC = props => const [ isIdle, setIsIdle ] = useState(false); const [ chatStyleId, setChatStyleId ] = useState(GetSessionDataManager().chatStyle); const [ needsChatStyleUpdate, setNeedsChatStyleUpdate ] = useState(false); + const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); const inputRef = useRef(); const chatModeIdWhisper = useMemo(() => @@ -201,20 +199,20 @@ export const ChatInputView: FC = props => CreateEventDispatcherHook(RoomWidgetUpdateInfostandUserEvent.PEER, eventDispatcher, onRoomWidgetUpdateInfostandUserEvent); - const onRoomWidgetChatInputContentUpdateEvent = useCallback((event: RoomWidgetChatInputContentUpdateEvent) => + const onRoomWidgetChatInputContentUpdateEvent = useCallback((event: RoomWidgetUpdateChatInputContentEvent) => { switch(event.chatMode) { - case RoomWidgetChatInputContentUpdateEvent.WHISPER: { + case RoomWidgetUpdateChatInputContentEvent.WHISPER: { setChatValue(`${ chatModeIdWhisper } ${ event.userName } `); return; } - case RoomWidgetChatInputContentUpdateEvent.SHOUT: + case RoomWidgetUpdateChatInputContentEvent.SHOUT: return; } }, [ chatModeIdWhisper ]); - CreateEventDispatcherHook(RoomWidgetChatInputContentUpdateEvent.CHAT_INPUT_CONTENT, eventDispatcher, onRoomWidgetChatInputContentUpdateEvent); + CreateEventDispatcherHook(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT, eventDispatcher, onRoomWidgetChatInputContentUpdateEvent); useEffect(() => { diff --git a/src/views/room/widgets/chat/ChatWidgetView.tsx b/src/views/room/widgets/chat/ChatWidgetView.tsx index 4cf80c42..1612dc5f 100644 --- a/src/views/room/widgets/chat/ChatWidgetView.tsx +++ b/src/views/room/widgets/chat/ChatWidgetView.tsx @@ -1,18 +1,16 @@ -import { RoomDragEvent, RoomObjectCategory, RoomSessionChatEvent } from 'nitro-renderer'; +import { NitroPoint, RoomDragEvent } from 'nitro-renderer'; import { FC, useCallback, useEffect, useRef, useState } from 'react'; -import { GetRoomEngine, GetRoomSession } from '../../../../api'; -import { useRoomEngineEvent } from '../../../../hooks/events'; -import { useRoomSessionManagerEvent } from '../../../../hooks/events/nitro/session/room-session-manager-event'; +import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../hooks/events'; import { useRoomContext } from '../../context/RoomContext'; +import { RoomWidgetUpdateChatEvent } from '../../events'; import { ChatWidgetViewProps } from './ChatWidgetView.types'; import { ChatWidgetMessageView } from './message/ChatWidgetMessageView'; import { ChatBubbleMessage } from './utils/ChatBubbleMessage'; -import { GetBubbleLocation } from './utils/ChatWidgetUtilities'; export const ChatWidgetView: FC = props => { const [ chatMessages, setChatMessages ] = useState([]); - const { roomSession = null } = useRoomContext(); + const { roomSession = null, eventDispatcher = null } = useRoomContext(); const elementRef = useRef(); const removeHiddenChats = useCallback(() => @@ -63,65 +61,21 @@ export const ChatWidgetView: FC = props => }); }, []); - const onRoomSessionChatEvent = useCallback((event: RoomSessionChatEvent) => + const onRoomWidgetUpdateChatEvent = useCallback((event: RoomWidgetUpdateChatEvent) => { - const roomObject = GetRoomEngine().getRoomObject(event.session.roomId, event.objectId, RoomObjectCategory.UNIT); - - if(!roomObject) return; - - const canvasId = 1; - const objectLocation = roomObject.getLocation(); - const bubbleLocation = GetBubbleLocation(event.session.roomId, objectLocation, canvasId); - const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.objectId); - - let username = ''; - let avatarColor = ''; - let imageUrl: string = null; - let chatType = event.chatType; - let styleId = event.style; - let userType = 0; - let petType = -1; - let text = event.message; - - if(userData) - { - userType = userData.type; - - const figure = userData.figure; - - // switch(userType) - // { - // case RoomObjectType.PET: - // image = this.getPetImage(figure, 2, true, 64, roomObject.model.getValue(RoomObjectVariable.FIGURE_POSTURE)); - // petType = new PetFigureData(figure).typeId; - // break; - // case RoomObjectType.USER: - // image = this.getUserImage(figure); - // break; - // case RoomObjectType.RENTABLE_BOT: - // case RoomObjectType.BOT: - // styleId = SystemChatStyleEnum.BOT; - // break; - // } - - //avatarColor = this._avatarColorCache.get(figure); - username = userData.name; - } - const chatMessage = new ChatBubbleMessage( - text, - username, - bubbleLocation, - chatType, - styleId, - imageUrl, - avatarColor - ); + event.text, + event.userName, + new NitroPoint(event.userX, event.userY), + event.chatType, + event.styleId, + event.userImage, + (event.userColor && (('#' + (event.userColor.toString(16).padStart(6, '0'))) || null))); addChat(chatMessage); }, [ addChat ]); - useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onRoomSessionChatEvent); + CreateEventDispatcherHook(RoomWidgetUpdateChatEvent.CHAT_EVENT, eventDispatcher, onRoomWidgetUpdateChatEvent); const onRoomDragEvent = useCallback((event: RoomDragEvent) => { diff --git a/src/views/room/widgets/furniture/FurnitureWidgetsView.tsx b/src/views/room/widgets/furniture/FurnitureWidgetsView.tsx index d752d8a9..8c688a13 100644 --- a/src/views/room/widgets/furniture/FurnitureWidgetsView.tsx +++ b/src/views/room/widgets/furniture/FurnitureWidgetsView.tsx @@ -1,4 +1,5 @@ import { FC } from 'react'; +import { FurnitureBackgroundColorView } from './background-color/FurnitureBackgroundColorView'; import { FurnitureDimmerView } from './dimmer/FurnitureDimmerView'; import { FurnitureEngravingLockView } from './engraving-lock/FurnitureEngravingLockView'; import { FurnitureExchangeCreditView } from './exchange-credit/FurnitureExchangeCreditView'; @@ -14,6 +15,7 @@ export const FurnitureWidgetsView: FC = props => { return (
+ diff --git a/src/views/room/widgets/furniture/background-color/FurnitureBackgroundColorView.tsx b/src/views/room/widgets/furniture/background-color/FurnitureBackgroundColorView.tsx new file mode 100644 index 00000000..d698a70f --- /dev/null +++ b/src/views/room/widgets/furniture/background-color/FurnitureBackgroundColorView.tsx @@ -0,0 +1,74 @@ +import { NitroEvent, RoomControllerLevel, RoomEngineObjectEvent, RoomEngineTriggerWidgetEvent, RoomObjectVariable } from 'nitro-renderer'; +import { FC, useCallback, useState } from 'react'; +import { GetRoomEngine, GetSessionDataManager } from '../../../../../api'; +import { CreateEventDispatcherHook, useRoomEngineEvent } from '../../../../../hooks/events'; +import { NitroCardContentView, NitroCardHeaderView, NitroCardView } from '../../../../../layout'; +import { LocalizeText } from '../../../../../utils/LocalizeText'; +import { useRoomContext } from '../../../context/RoomContext'; +import { RoomWidgetRoomObjectUpdateEvent } from '../../../events'; + +export const FurnitureBackgroundColorView: FC<{}> = props => +{ + const [ furniId, setFurniId ] = useState(-1); + const [ objectId, setObjectId ] = useState(-1); + const [ hue, setHue ] = useState(0); + const [ saturation, setSaturation ] = useState(0); + const [ light, setLight ] = useState(0); + const { roomSession = null, eventDispatcher = null } = useRoomContext(); + + const canOpenBackgroundToner = useCallback(() => + { + const isRoomOwner = roomSession.isRoomOwner; + const hasLevel = (roomSession.controllerLevel >= RoomControllerLevel.GUEST); + const isGodMode = GetSessionDataManager().isGodMode; + + return (isRoomOwner || hasLevel || isGodMode); + }, [ roomSession ]); + + const onNitroEvent = useCallback((event: NitroEvent) => + { + switch(event.type) + { + case RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR: { + if(!canOpenBackgroundToner()) return; + + const roomEngineObjectEvent = (event as RoomEngineObjectEvent); + const roomObject = GetRoomEngine().getRoomObject(roomEngineObjectEvent.roomId, roomEngineObjectEvent.objectId, roomEngineObjectEvent.category); + const model = roomObject.model; + + setFurniId(roomObject.id); + setObjectId(roomObject.instanceId); + setHue(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_HUE))); + setSaturation(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_SATURATION))); + setLight(parseInt(model.getValue(RoomObjectVariable.FURNITURE_ROOM_BACKGROUND_COLOR_LIGHTNESS))); + + return; + } + case RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED: { + const widgetEvent = (event as RoomWidgetRoomObjectUpdateEvent); + + setObjectId(prevValue => + { + if(prevValue === widgetEvent.id) return null; + + return prevValue; + }); + return; + } + } + }, [ canOpenBackgroundToner ]); + + useRoomEngineEvent(RoomEngineTriggerWidgetEvent.REQUEST_BACKGROUND_COLOR, onNitroEvent); + CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.FURNI_REMOVED, eventDispatcher, onNitroEvent); + + if(objectId === -1) return null; + + return ( + + setObjectId(-1) } /> + + background toner + + + ); +}