mirror of
https://github.com/billsonnn/nitro-react.git
synced 2024-11-26 23:50:52 +01:00
Merge remote-tracking branch 'origin/dev' into @feature/room-tools
This commit is contained in:
commit
8fe70d4c7e
@ -87,16 +87,24 @@
|
||||
"roomId": 2346
|
||||
}
|
||||
],
|
||||
"hotelview.images": {
|
||||
"background": "${asset.url}/images/reception/stretch_blue.png",
|
||||
"background.colour": "#6eadc8",
|
||||
"sun": "${asset.url}/images/reception/sun.png",
|
||||
"drape": "${asset.url}/images/reception/drape.png",
|
||||
"left": "${asset.url}/images/reception/ts.png",
|
||||
"right": "${asset.url}/images/reception/US_right.png",
|
||||
"right.repeat": "${asset.url}/images/reception/US_top_right.png"
|
||||
"hotelview": {
|
||||
"widgets": {
|
||||
"types": "news,",
|
||||
"slot1": "news"
|
||||
},
|
||||
"images": {
|
||||
"background": "${asset.url}/images/reception/stretch_blue.png",
|
||||
"background.colour": "#6eadc8",
|
||||
"sun": "${asset.url}/images/reception/sun.png",
|
||||
"drape": "${asset.url}/images/reception/drape.png",
|
||||
"left": "${asset.url}/images/reception/ts.png",
|
||||
"right": "${asset.url}/images/reception/US_right.png",
|
||||
"right.repeat": "${asset.url}/images/reception/US_top_right.png"
|
||||
}
|
||||
},
|
||||
"achievements.unseen.ignored": ["ACH_AllTimeHotelPresence"],
|
||||
"achievements.unseen.ignored": [
|
||||
"ACH_AllTimeHotelPresence"
|
||||
],
|
||||
"avatareditor.show.clubitems.dimmed": true,
|
||||
"avatareditor.show.clubitems.first": true,
|
||||
"chat.history.max.items": 100,
|
||||
|
@ -1,6 +0,0 @@
|
||||
import { GetRoomSession } from './GetRoomSession';
|
||||
|
||||
export function SendChatTypingMessage(isTyping: boolean): void
|
||||
{
|
||||
GetRoomSession().sendChatTypingMessage(isTyping);
|
||||
}
|
@ -11,5 +11,4 @@ export * from './HasHabboClub';
|
||||
export * from './HasHabboVip';
|
||||
export * from './IsOwnerOfFurniture';
|
||||
export * from './IsRidingHorse';
|
||||
export * from './SendChatTypingMessage';
|
||||
export * from './StartRoomSession';
|
||||
|
BIN
src/assets/images/toolbar/friend-search.png
Normal file
BIN
src/assets/images/toolbar/friend-search.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.2 KiB |
BIN
src/assets/images/toolbar/icons/friend-bar/chat.png
Normal file
BIN
src/assets/images/toolbar/icons/friend-bar/chat.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
src/assets/images/toolbar/icons/friend-bar/profile.png
Normal file
BIN
src/assets/images/toolbar/icons/friend-bar/profile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
BIN
src/assets/images/toolbar/icons/friend-bar/visit.png
Normal file
BIN
src/assets/images/toolbar/icons/friend-bar/visit.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -486,6 +486,24 @@ i {
|
||||
height: 15px;
|
||||
}
|
||||
|
||||
&.icon-fb-profile {
|
||||
background: url('../images/toolbar/icons/friend-bar/profile.png');
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
&.icon-fb-chat {
|
||||
background: url('../images/toolbar/icons/friend-bar/chat.png');
|
||||
width: 20px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
&.icon-fb-visit {
|
||||
background: url('../images/toolbar/icons/friend-bar/visit.png');
|
||||
width: 21px;
|
||||
height: 21px;
|
||||
}
|
||||
|
||||
&.spin {
|
||||
animation: rotating 1s linear infinite;
|
||||
}
|
||||
|
@ -60,6 +60,11 @@ export const DraggableWindow: FC<DraggableWindowProps> = props =>
|
||||
element.style.left = `${ left }px`;
|
||||
element.style.top = `${ top }px`;
|
||||
}
|
||||
else
|
||||
{
|
||||
element.style.left = `0px`;
|
||||
element.style.top = `0px`;
|
||||
}
|
||||
|
||||
element.style.visibility = 'visible';
|
||||
|
||||
|
@ -3,4 +3,3 @@
|
||||
}
|
||||
|
||||
@import './views//friend-bar/FriendBarView';
|
||||
@import './views/friend-bar-item/FriendBarItemView';
|
||||
|
@ -0,0 +1,28 @@
|
||||
.friend-bar-item {
|
||||
width: 130px;
|
||||
margin: 0 3px;
|
||||
z-index: 0;
|
||||
position: relative;
|
||||
padding-left:38px;
|
||||
text-align: left;
|
||||
|
||||
&.friend-bar-item-active {
|
||||
margin-bottom:21px;
|
||||
}
|
||||
|
||||
.friend-bar-item-head {
|
||||
top: -30px;
|
||||
left: -30px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
&.friend-bar-search {
|
||||
.friend-bar-item-head {
|
||||
top: -3px;
|
||||
left: 5px;
|
||||
width: 31px;
|
||||
height: 34px;
|
||||
background-image: url('../../../../assets/images/toolbar/friend-search.png');
|
||||
}
|
||||
}
|
||||
}
|
@ -1,18 +1,66 @@
|
||||
import { FC } from 'react';
|
||||
import { FollowFriendComposer, MouseEventType, Nitro } from 'nitro-renderer';
|
||||
import { FC, useEffect, useRef, useState } from 'react';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { AvatarImageView } from '../../../shared/avatar-image/AvatarImageView';
|
||||
import { FriendBarItemViewProps } from './FriendBarItemView.types';
|
||||
|
||||
export const FriendBarItemView: FC<FriendBarItemViewProps> = props =>
|
||||
{
|
||||
const { friend = null } = props;
|
||||
const [isVisible, setVisible] = useState(false);
|
||||
|
||||
const toggleVisible = () => setVisible(prevCheck => !prevCheck);
|
||||
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
function onClick(event: MouseEvent): void
|
||||
{
|
||||
const element = elementRef.current;
|
||||
|
||||
if((event.target !== element) && !element.contains((event.target as Node)))
|
||||
{
|
||||
setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener(MouseEventType.MOUSE_CLICK, onClick);
|
||||
|
||||
return () =>
|
||||
{
|
||||
document.removeEventListener(MouseEventType.MOUSE_CLICK, onClick);
|
||||
}
|
||||
}, [ elementRef, setVisible ]);
|
||||
|
||||
|
||||
const followFriend = () =>
|
||||
{
|
||||
|
||||
Nitro.instance.communication.connection.send(new FollowFriendComposer(friend.id));
|
||||
}
|
||||
|
||||
if(!friend)
|
||||
{
|
||||
return (
|
||||
<div>offline</div>
|
||||
<div ref={ elementRef } className="btn btn-primary friend-bar-item friend-bar-search">
|
||||
<div className="friend-bar-item-head position-absolute"/>
|
||||
<div className="text-truncate">{ LocalizeText("friend.bar.find.title") }</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div>{ friend.name }</div>
|
||||
<div ref={ elementRef } className={"btn btn-success friend-bar-item " + (isVisible ? "friend-bar-item-active" : "")} onClick={ event => toggleVisible()}>
|
||||
<div className="friend-bar-item-head position-absolute">
|
||||
<AvatarImageView headOnly={true} figure={friend.figure} direction={2} />
|
||||
</div>
|
||||
<div className="text-truncate">{friend.name}</div>
|
||||
{isVisible && <div className="d-flex justify-content-between">
|
||||
<i className="icon icon-fb-chat cursor-pointer" />
|
||||
{friend.followingAllowed && <i onClick={ event => followFriend() } className="icon icon-fb-visit cursor-pointer" />}
|
||||
<i className="icon icon-fb-profile cursor-pointer" />
|
||||
</div>}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -0,0 +1,7 @@
|
||||
.friend-bar {
|
||||
.friend-bar-button {
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
@import '../friend-bar-item/FriendBarItemView.scss';
|
||||
}
|
@ -24,12 +24,16 @@ export const FriendBarView: FC<FriendBarViewProps> = props =>
|
||||
}, [ indexOffset, friends ]);
|
||||
|
||||
return (
|
||||
<div className="d-flex">
|
||||
<button type="button" className="btn btn-sm btn-primary" disabled={ !canDecreaseIndex } onClick={ event => setIndexOffset(indexOffset - 1) }>back</button>
|
||||
<div className="d-flex friend-bar align-items-center">
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={!canDecreaseIndex} onClick={event => setIndexOffset(indexOffset - 1)}>
|
||||
<i className="fas fa-chevron-left" />
|
||||
</button>
|
||||
<FriendBarItemView friend={ (friends[ indexOffset ] || null) } />
|
||||
<FriendBarItemView friend={ (friends[ indexOffset + 1 ] || null) } />
|
||||
<FriendBarItemView friend={ (friends[ indexOffset + 2 ] || null) } />
|
||||
<button type="button" className="btn btn-sm btn-primary" disabled={ !canIncreaseIndex } onClick={ event => setIndexOffset(indexOffset + 1) }>forward</button>
|
||||
<button type="button" className="btn btn-sm btn-black align-self-center friend-bar-button" disabled={!canIncreaseIndex} onClick={event => setIndexOffset(indexOffset + 1)}>
|
||||
<i className="fas fa-chevron-right" />
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
display: block;
|
||||
position: fixed;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
height: calc(100% - 55px);
|
||||
background: rgba($black, 1);
|
||||
|
||||
.avatar-image {
|
||||
@ -39,6 +39,7 @@
|
||||
right: 0;
|
||||
margin: auto;
|
||||
background-repeat: no-repeat;
|
||||
background-position: top center;
|
||||
}
|
||||
|
||||
.left {
|
||||
@ -61,6 +62,7 @@
|
||||
animation-name: slideUp;
|
||||
animation-duration: 1s;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right bottom;
|
||||
}
|
||||
|
||||
.right-repeat {
|
||||
@ -68,9 +70,7 @@
|
||||
height: 100%;
|
||||
right: 0;
|
||||
top: 0;
|
||||
animation-iteration-count: 1;
|
||||
animation-name: slideRight;
|
||||
animation-duration: 1s;
|
||||
background-repeat: no-repeat;
|
||||
background-position: right top;
|
||||
}
|
||||
}
|
||||
|
@ -26,13 +26,13 @@ export const HotelView: FC<HotelViewProps> = props =>
|
||||
|
||||
if(!isVisible) return null;
|
||||
|
||||
const backgroundColor = GetConfiguration('hotelview.images')['background.colour'];
|
||||
const background = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['background']);
|
||||
const sun = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['sun']);
|
||||
const drape = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['drape']);
|
||||
const left = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['left']);
|
||||
//const rightRepeat = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['right.repeat']);
|
||||
//const right = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview.images')['right']);
|
||||
const backgroundColor = GetConfiguration('hotelview')['images']['background.colour'];
|
||||
const background = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['background']);
|
||||
const sun = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['sun']);
|
||||
const drape = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['drape']);
|
||||
const left = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['left']);
|
||||
const rightRepeat = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['right.repeat']);
|
||||
const right = Nitro.instance.core.configuration.interpolate(GetConfiguration('hotelview')['images']['right']);
|
||||
|
||||
return (
|
||||
<div className="nitro-hotel-view" style={ (backgroundColor && backgroundColor) ? { background: backgroundColor } : {} }>
|
||||
@ -40,8 +40,8 @@ export const HotelView: FC<HotelViewProps> = props =>
|
||||
<div className="sun position-absolute" style={ (sun && sun.length) ? { backgroundImage: `url(${ sun })` } : {} } />
|
||||
<div className="drape position-absolute" style={ (drape && drape.length) ? { backgroundImage: `url(${ drape })` } : {} } />
|
||||
<div className="left position-absolute" style={ (left && left.length) ? { backgroundImage: `url(${ left })` } : {} } />
|
||||
{/* <div className="right-repeat position-absolute" style={ (rightRepeat && rightRepeat.length) ? { backgroundImage: `url(${ rightRepeat })` } : {} } />
|
||||
<div className="right position-absolute" style={ (right && right.length) ? { backgroundImage: `url(${ right })` } : {} } /> */}
|
||||
<div className="right-repeat position-absolute" style={ (rightRepeat && rightRepeat.length) ? { backgroundImage: `url(${ rightRepeat })` } : {} } />
|
||||
<div className="right position-absolute" style={ (right && right.length) ? { backgroundImage: `url(${ right })` } : {} } />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
@ -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, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
|
||||
import { IRoomWidgetHandlerManager, RoomWidgetAvatarInfoHandler, RoomWidgetChatHandler, RoomWidgetChatInputHandler, RoomWidgetHandlerManager, RoomWidgetInfostandHandler } from './handlers';
|
||||
import { RoomWidgetRoomToolsHandler } from './handlers/RoomWidgetRoomToolsHandler';
|
||||
import { RoomViewProps } from './RoomView.types';
|
||||
import { RoomWidgetsView } from './widgets/RoomWidgetsView';
|
||||
@ -37,6 +37,8 @@ export const RoomView: FC<RoomViewProps> = props =>
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetAvatarInfoHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetInfostandHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetRoomToolsHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatInputHandler());
|
||||
widgetHandlerManager.registerHandler(new RoomWidgetChatHandler());
|
||||
|
||||
setWidgetHandler(widgetHandlerManager);
|
||||
|
||||
|
20
src/views/room/events/RoomWidgetFloodControlEvent.ts
Normal file
20
src/views/room/events/RoomWidgetFloodControlEvent.ts
Normal 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(seconds: number)
|
||||
{
|
||||
super(RoomWidgetFloodControlEvent.FLOOD_CONTROL);
|
||||
|
||||
this._seconds = seconds;
|
||||
}
|
||||
|
||||
public get seconds(): number
|
||||
{
|
||||
return this._seconds;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
124
src/views/room/events/RoomWidgetUpdateChatEvent.ts
Normal file
124
src/views/room/events/RoomWidgetUpdateChatEvent.ts
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
import { RoomWidgetUpdateEvent } from './RoomWidgetUpdateEvent';
|
||||
|
||||
export class RoomWidgetUpdateChatInputContentEvent extends RoomWidgetUpdateEvent
|
||||
{
|
||||
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(chatMode: string, userName: string)
|
||||
{
|
||||
super(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT);
|
||||
|
||||
this._chatMode = chatMode;
|
||||
this._userName = userName;
|
||||
}
|
||||
|
||||
public get chatMode(): string
|
||||
{
|
||||
return this._chatMode;
|
||||
}
|
||||
|
||||
public get userName(): string
|
||||
{
|
||||
return this._userName;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
11
src/views/room/events/RoomWidgetUpdateUserDataEvent.ts
Normal file
11
src/views/room/events/RoomWidgetUpdateUserDataEvent.ts
Normal file
@ -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);
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
export * from './RoomWidgetAvatarInfoEvent';
|
||||
export * from './RoomWidgetFloodControlEvent';
|
||||
export * from './RoomWidgetObjectNameEvent';
|
||||
export * from './RoomWidgetRoomEngineUpdateEvent';
|
||||
export * from './RoomWidgetRoomObjectUpdateEvent';
|
||||
export * from './RoomWidgetRoomViewUpdateEvent';
|
||||
export * from './RoomWidgetUpdateChatEvent';
|
||||
export * from './RoomWidgetUpdateChatInputContentEvent';
|
||||
export * from './RoomWidgetUpdateDanceStatusEvent';
|
||||
export * from './RoomWidgetUpdateEvent';
|
||||
export * from './RoomWidgetUpdateInfostandEvent';
|
||||
@ -10,4 +12,5 @@ export * from './RoomWidgetUpdateInfostandFurniEvent';
|
||||
export * from './RoomWidgetUpdateInfostandPetEvent';
|
||||
export * from './RoomWidgetUpdateInfostandRentableBotEvent';
|
||||
export * from './RoomWidgetUpdateInfostandUserEvent';
|
||||
export * from './RoomWidgetUserDataUpdateEvent';
|
||||
export * from './RoomWidgetUpdateRentableBotChatEvent';
|
||||
export * from './RoomWidgetUpdateUserDataEvent';
|
||||
|
@ -1,13 +1,13 @@
|
||||
import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer';
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { RoomWidgetUpdateEvent } from '../events';
|
||||
import { RoomWidgetMessage } from '../messages';
|
||||
import { IRoomWidgetHandlerManager } from './IRoomWidgetHandlerManager';
|
||||
|
||||
export interface IRoomWidgetHandler
|
||||
{
|
||||
processEvent: (event: NitroEvent) => void;
|
||||
processWidgetMessage: (message: RoomWidgetMessage) => RoomWidgetUpdateEvent;
|
||||
roomSession: IRoomSession;
|
||||
eventDispatcher: IEventDispatcher;
|
||||
container: IRoomWidgetHandlerManager;
|
||||
eventTypes: string[];
|
||||
messageTypes: string[];
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { IEventDispatcher, NitroEvent } from 'nitro-renderer';
|
||||
import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer';
|
||||
import { RoomWidgetUpdateEvent } from '../events';
|
||||
import { RoomWidgetMessage } from '../messages';
|
||||
import { IRoomWidgetHandler } from './IRoomWidgetHandler';
|
||||
@ -8,5 +8,6 @@ export interface IRoomWidgetHandlerManager
|
||||
registerHandler(handler: IRoomWidgetHandler): void;
|
||||
processEvent(event: NitroEvent): void;
|
||||
processWidgetMessage(message: RoomWidgetMessage): RoomWidgetUpdateEvent;
|
||||
roomSession: IRoomSession;
|
||||
eventDispatcher: IEventDispatcher;
|
||||
}
|
||||
|
@ -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.eventDispatcher.dispatchEvent(new RoomWidgetUserDataUpdateEvent());
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateUserDataEvent());
|
||||
return;
|
||||
case RoomSessionDanceEvent.RSDE_DANCE:
|
||||
const danceEvent = (event as RoomSessionDanceEvent);
|
||||
@ -22,7 +22,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
|
||||
|
||||
if(userData && (userData.roomIndex === danceEvent.roomIndex)) isDancing = (danceEvent.danceId !== 0);
|
||||
|
||||
this.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDanceStatusEvent(isDancing));
|
||||
this.container.eventDispatcher.dispatchEvent(new RoomWidgetUpdateDanceStatusEvent(isDancing));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -68,7 +68,7 @@ export class RoomWidgetAvatarInfoHandler extends RoomWidgetHandler
|
||||
const allowNameChange = GetSessionDataManager().canChangeName;
|
||||
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[]
|
||||
|
205
src/views/room/handlers/RoomWidgetChatHandler.ts
Normal file
205
src/views/room/handlers/RoomWidgetChatHandler.ts
Normal file
@ -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<string, number> = new Map();
|
||||
private _avatarImageCache: Map<string, string> = new Map();
|
||||
private _petImageCache: Map<string, string> = 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<string>(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 [];
|
||||
}
|
||||
}
|
198
src/views/room/handlers/RoomWidgetChatInputHandler.ts
Normal file
198
src/views/room/handlers/RoomWidgetChatInputHandler.ts
Normal file
@ -0,0 +1,198 @@
|
||||
import { AvatarExpressionEnum, HabboClubLevelEnum, NitroEvent, RoomControllerLevel, RoomSessionChatEvent, RoomSettingsComposer, RoomZoomEvent } from 'nitro-renderer';
|
||||
import { GetConnection, GetRoomEngine, GetSessionDataManager } 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);
|
||||
|
||||
this.container.roomSession.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
|
||||
];
|
||||
}
|
||||
}
|
@ -1,35 +1,25 @@
|
||||
import { IEventDispatcher, IRoomSession, NitroEvent } from 'nitro-renderer';
|
||||
import { NitroEvent } from 'nitro-renderer';
|
||||
import { RoomWidgetUpdateEvent } from '../events';
|
||||
import { RoomWidgetMessage } from '../messages';
|
||||
import { IRoomWidgetHandler } from './IRoomWidgetHandler';
|
||||
import { IRoomWidgetHandlerManager } from './IRoomWidgetHandlerManager';
|
||||
|
||||
export abstract class RoomWidgetHandler implements IRoomWidgetHandler
|
||||
{
|
||||
private _roomSession: IRoomSession = null;
|
||||
private _eventDispatcher: IEventDispatcher = null;
|
||||
private _container: IRoomWidgetHandlerManager = null;
|
||||
|
||||
public abstract processEvent(event: NitroEvent): void;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public get eventDispatcher(): IEventDispatcher
|
||||
{
|
||||
return this._eventDispatcher;
|
||||
}
|
||||
|
||||
public set eventDispatcher(eventDispatcher: IEventDispatcher)
|
||||
{
|
||||
this._eventDispatcher = eventDispatcher;
|
||||
this._container = container;
|
||||
}
|
||||
|
||||
public abstract get eventTypes(): string[];
|
||||
|
@ -62,8 +62,7 @@ export class RoomWidgetHandlerManager implements IRoomWidgetHandlerManager
|
||||
}
|
||||
}
|
||||
|
||||
handler.roomSession = this._roomSession;
|
||||
handler.eventDispatcher = this._eventDispatcher;
|
||||
handler.container = this;
|
||||
|
||||
this._handlers.push(handler);
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { GetConnection, GetRoomEngine, GetSessionDataManager, IsOwnerOfFurniture
|
||||
import { WiredSelectObjectEvent } from '../../../events';
|
||||
import { dispatchUiEvent } from '../../../hooks/events';
|
||||
import { LocalizeText } from '../../../utils/LocalizeText';
|
||||
import { 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';
|
||||
|
||||
@ -17,7 +17,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
this.processPetInfoEvent((event as RoomSessionPetInfoUpdateEvent));
|
||||
return;
|
||||
case RoomSessionUserBadgesEvent.RSUBE_BADGES:
|
||||
this.eventDispatcher.dispatchEvent(event);
|
||||
this.container.eventDispatcher.dispatchEvent(event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -50,11 +50,11 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
if(petMessages.indexOf(message.type) >= 0)
|
||||
{
|
||||
userData = this.roomSession.userDataManager.getPetData(userId);
|
||||
userData = this.container.roomSession.userDataManager.getPetData(userId);
|
||||
}
|
||||
else
|
||||
{
|
||||
userData = this.roomSession.userDataManager.getUserData(userId);
|
||||
userData = this.container.roomSession.userDataManager.getUserData(userId);
|
||||
}
|
||||
|
||||
if(!userData) return null;
|
||||
@ -82,7 +82,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
GetSessionDataManager().givePetRespect(userId);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.WHISPER_USER:
|
||||
//this.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);
|
||||
@ -91,27 +91,27 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
GetSessionDataManager().unignoreUser(userData.name);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.KICK_USER:
|
||||
this.roomSession.sendKickMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
this.container.roomSession.sendKickMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.BAN_USER_DAY:
|
||||
case RoomWidgetUserActionMessage.BAN_USER_HOUR:
|
||||
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;
|
||||
case RoomWidgetUserActionMessage.MUTE_USER_2MIN:
|
||||
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 2);
|
||||
this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 2);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.MUTE_USER_5MIN:
|
||||
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 5);
|
||||
this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 5);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.MUTE_USER_10MIN:
|
||||
this.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 10);
|
||||
this.container.roomSession.sendMuteMessage((message as RoomWidgetUserActionMessage).userId, 10);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.GIVE_RIGHTS:
|
||||
this.roomSession.sendGiveRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
this.container.roomSession.sendGiveRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.TAKE_RIGHTS:
|
||||
this.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
this.container.roomSession.sendTakeRightsMessage((message as RoomWidgetUserActionMessage).userId);
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.START_TRADING:
|
||||
//if(userData) this._widget.inventoryTrading.startTrade(userData.roomIndex, userData.name);
|
||||
@ -156,29 +156,29 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
GetConnection().send(new RoomUnitDropHandItemComposer());
|
||||
break;
|
||||
case RoomWidgetUserActionMessage.REQUEST_PET_UPDATE:
|
||||
this.roomSession.userDataManager.requestPetInfo(userId);
|
||||
this.container.roomSession.userDataManager.requestPetInfo(userId);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.REPORT:
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.REPORT_CFH_OTHER:
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_ALERT_USER:
|
||||
this.roomSession.sendAmbassadorAlertMessage(userId);
|
||||
this.container.roomSession.sendAmbassadorAlertMessage(userId);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_KICK_USER:
|
||||
this.roomSession.sendKickMessage(userId);
|
||||
this.container.roomSession.sendKickMessage(userId);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_2MIN:
|
||||
this.roomSession.sendMuteMessage(userId, 2);
|
||||
this.container.roomSession.sendMuteMessage(userId, 2);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_10MIN:
|
||||
this.roomSession.sendMuteMessage(userId, 10);
|
||||
this.container.roomSession.sendMuteMessage(userId, 10);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_60MIN:
|
||||
this.roomSession.sendMuteMessage(userId, 60);
|
||||
this.container.roomSession.sendMuteMessage(userId, 60);
|
||||
return;
|
||||
case RoomWidgetUserActionMessage.AMBASSADOR_MUTE_USER_18HOUR:
|
||||
this.roomSession.sendMuteMessage(userId, 1080);
|
||||
this.container.roomSession.sendMuteMessage(userId, 1080);
|
||||
return;
|
||||
case RoomWidgetFurniActionMessage.ROTATE:
|
||||
GetRoomEngine().processRoomObjectOperation(objectId, category, RoomObjectOperationType.OBJECT_ROTATE_POSITIVE);
|
||||
@ -226,7 +226,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
return;
|
||||
}
|
||||
case RoomWidgetChangeMottoMessage.CHANGE_MOTTO:
|
||||
this.roomSession.sendMottoMessage((message as RoomWidgetChangeMottoMessage).motto);
|
||||
this.container.roomSession.sendMottoMessage((message as RoomWidgetChangeMottoMessage).motto);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -243,7 +243,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
{
|
||||
case RoomObjectCategory.FLOOR:
|
||||
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;
|
||||
|
||||
@ -275,7 +275,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
break;
|
||||
}
|
||||
case RoomObjectCategory.UNIT: {
|
||||
const userData = this.roomSession.userDataManager.getUserDataByIndex(message.id);
|
||||
const userData = this.container.roomSession.userDataManager.getUserDataByIndex(message.id);
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
private processObjectInfoMessage(message: RoomWidgetRoomObjectMessage): RoomWidgetUpdateEvent
|
||||
{
|
||||
const roomId = this.roomSession.roomId;
|
||||
const roomId = this.container.roomSession.roomId;
|
||||
|
||||
switch(message.category)
|
||||
{
|
||||
@ -302,14 +302,14 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
this.processFurniInfoMessage(message, roomId);
|
||||
break;
|
||||
case RoomObjectCategory.UNIT: {
|
||||
const userData = this.roomSession.userDataManager.getUserDataByIndex(message.id);
|
||||
const userData = this.container.roomSession.userDataManager.getUserDataByIndex(message.id);
|
||||
|
||||
if(!userData) break;
|
||||
|
||||
switch(userData.type)
|
||||
{
|
||||
case RoomObjectType.PET:
|
||||
this.roomSession.userDataManager.requestPetInfo(userData.webID);
|
||||
this.container.roomSession.userDataManager.requestPetInfo(userData.webID);
|
||||
break;
|
||||
case RoomObjectType.USER:
|
||||
this.processUserInfoMessage(message, roomId, userData);
|
||||
@ -408,8 +408,8 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
event.image = roomObjectImage.getImage();
|
||||
event.isWallItem = (message.category === RoomObjectCategory.WALL);
|
||||
event.isRoomOwner = this.roomSession.isRoomOwner;
|
||||
event.roomControllerLevel = this.roomSession.controllerLevel;
|
||||
event.isRoomOwner = this.container.roomSession.isRoomOwner;
|
||||
event.roomControllerLevel = this.container.roomSession.controllerLevel;
|
||||
event.isAnyRoomController = GetSessionDataManager().isModerator;
|
||||
event.ownerId = model.getValue<number>(RoomObjectVariable.FURNITURE_OWNER_ID);
|
||||
event.ownerName = model.getValue<string>(RoomObjectVariable.FURNITURE_OWNER_NAME);
|
||||
@ -425,7 +425,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
if(IsOwnerOfFurniture(roomObject)) event.isOwner = true;
|
||||
|
||||
this.eventDispatcher.dispatchEvent(event);
|
||||
this.container.eventDispatcher.dispatchEvent(event);
|
||||
}
|
||||
|
||||
private processUserInfoMessage(message: RoomWidgetRoomObjectMessage, roomId: number, userData: RoomUserData): void
|
||||
@ -436,7 +436,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
const event = new RoomWidgetUpdateInfostandUserEvent(eventType);
|
||||
|
||||
event.isSpectatorMode = this.roomSession.isSpectator;
|
||||
event.isSpectatorMode = this.container.roomSession.isSpectator;
|
||||
event.name = userData.name;
|
||||
event.motto = userData.custom;
|
||||
event.achievementScore = userData.activityPoints;
|
||||
@ -454,9 +454,9 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
event.allowNameChange = GetSessionDataManager().canChangeName;
|
||||
}
|
||||
|
||||
event.amIOwner = this.roomSession.isRoomOwner;
|
||||
event.isGuildRoom = this.roomSession.isGuildRoom;
|
||||
event.roomControllerLevel = this.roomSession.controllerLevel;
|
||||
event.amIOwner = this.container.roomSession.isRoomOwner;
|
||||
event.isGuildRoom = this.container.roomSession.isGuildRoom;
|
||||
event.roomControllerLevel = this.container.roomSession.controllerLevel;
|
||||
event.amIAnyRoomController = GetSessionDataManager().isModerator;
|
||||
event.isAmbassador = GetSessionDataManager().isAmbassador;
|
||||
|
||||
@ -487,7 +487,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
event.respectLeft = GetSessionDataManager().respectsLeft;
|
||||
|
||||
const isShuttingDown = GetSessionDataManager().isSystemShutdown;
|
||||
const tradeMode = this.roomSession.tradeMode;
|
||||
const tradeMode = this.container.roomSession.tradeMode;
|
||||
|
||||
if(isShuttingDown)
|
||||
{
|
||||
@ -527,14 +527,14 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
event.groupId = parseInt(userData.guildId);
|
||||
//event._Str_5235 = GetSessionDataManager()._Str_17173(int(userData._Str_4592));
|
||||
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;
|
||||
//var _local_8:Array = GetSessionDataManager()._Str_18437(userData.webID);
|
||||
//this._Str_16287(userData._Str_2394, _local_8);
|
||||
//this._container._Str_8097._Str_14387(userData.webID);
|
||||
//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
|
||||
@ -551,15 +551,15 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
if(roomObject) event.carryItem = (roomObject.model.getValue<number>(RoomObjectVariable.FIGURE_CARRY_OBJECT) || 0);
|
||||
|
||||
event.amIOwner = this.roomSession.isRoomOwner;
|
||||
event.isGuildRoom = this.roomSession.isGuildRoom;
|
||||
event.roomControllerLevel = this.roomSession.controllerLevel;
|
||||
event.amIOwner = this.container.roomSession.isRoomOwner;
|
||||
event.isGuildRoom = this.container.roomSession.isGuildRoom;
|
||||
event.roomControllerLevel = this.container.roomSession.controllerLevel;
|
||||
event.amIAnyRoomController = GetSessionDataManager().isModerator;
|
||||
event.isAmbassador = GetSessionDataManager().isAmbassador;
|
||||
event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ];
|
||||
event.figure = userData.figure;
|
||||
|
||||
this.eventDispatcher.dispatchEvent(event);
|
||||
this.container.eventDispatcher.dispatchEvent(event);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
event.amIOwner = this.roomSession.isRoomOwner;
|
||||
event.roomControllerLevel = this.roomSession.controllerLevel;
|
||||
event.amIOwner = this.container.roomSession.isRoomOwner;
|
||||
event.roomControllerLevel = this.container.roomSession.controllerLevel;
|
||||
event.amIAnyRoomController = GetSessionDataManager().isModerator;
|
||||
event.badges = [ RoomWidgetUpdateInfostandUserEvent.DEFAULT_BOT_BADGE_ID ];
|
||||
event.figure = userData.figure;
|
||||
|
||||
this.eventDispatcher.dispatchEvent(event);
|
||||
this.container.eventDispatcher.dispatchEvent(event);
|
||||
}
|
||||
|
||||
private processPetInfoEvent(event: RoomSessionPetInfoUpdateEvent): void
|
||||
@ -593,7 +593,7 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
if(!petData) return;
|
||||
|
||||
const roomPetData = this.roomSession.userDataManager.getPetData(petData.id);
|
||||
const roomPetData = this.container.roomSession.userDataManager.getPetData(petData.id);
|
||||
|
||||
if(!roomPetData) return;
|
||||
|
||||
@ -652,10 +652,10 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
}
|
||||
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
|
||||
@ -717,9 +717,9 @@ export class RoomWidgetInfostandHandler extends RoomWidgetHandler
|
||||
|
||||
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;
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
export * from './IRoomWidgetHandler';
|
||||
export * from './IRoomWidgetHandlerManager';
|
||||
export * from './RoomWidgetAvatarInfoHandler';
|
||||
export * from './RoomWidgetChatHandler';
|
||||
export * from './RoomWidgetChatInputHandler';
|
||||
export * from './RoomWidgetHandler';
|
||||
export * from './RoomWidgetHandlerManager';
|
||||
export * from './RoomWidgetInfostandHandler';
|
||||
|
44
src/views/room/messages/RoomWidgetChatMessage.ts
Normal file
44
src/views/room/messages/RoomWidgetChatMessage.ts
Normal 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;
|
||||
}
|
||||
}
|
34
src/views/room/messages/RoomWidgetChatSelectAvatarMessage.ts
Normal file
34
src/views/room/messages/RoomWidgetChatSelectAvatarMessage.ts
Normal 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;
|
||||
}
|
||||
}
|
20
src/views/room/messages/RoomWidgetChatTypingMessage.ts
Normal file
20
src/views/room/messages/RoomWidgetChatTypingMessage.ts
Normal 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;
|
||||
}
|
||||
}
|
10
src/views/room/messages/RoomWidgetRequestWidgetMessage.ts
Normal file
10
src/views/room/messages/RoomWidgetRequestWidgetMessage.ts
Normal 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';
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
export * from './RoomWidgetAvatarExpressionMessage';
|
||||
export * from './RoomWidgetChangeMottoMessage';
|
||||
export * from './RoomWidgetChangePostureMessage';
|
||||
export * from './RoomWidgetChatMessage';
|
||||
export * from './RoomWidgetChatSelectAvatarMessage';
|
||||
export * from './RoomWidgetChatTypingMessage';
|
||||
export * from './RoomWidgetDanceMessage';
|
||||
export * from './RoomWidgetFurniActionMessage';
|
||||
export * from './RoomWidgetMessage';
|
||||
export * from './RoomWidgetRequestWidgetMessage';
|
||||
export * from './RoomWidgetRoomObjectMessage';
|
||||
export * from './RoomWidgetUserActionMessage';
|
||||
export * from './RoomWidgetZoomToggleMessage';
|
||||
|
@ -3,7 +3,7 @@ import { FC, useCallback, useMemo, useState } from 'react';
|
||||
import { GetRoomSession, GetSessionDataManager } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks/events/event-dispatcher.base';
|
||||
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 { AvatarInfoWidgetViewProps } from './AvatarInfoWidgetView.types';
|
||||
import { AvatarInfoWidgetAvatarView } from './views/avatar/AvatarInfoWidgetAvatarView';
|
||||
@ -12,6 +12,7 @@ import { AvatarInfoWidgetNameView } from './views/name/AvatarInfoWidgetNameView'
|
||||
import { AvatarInfoWidgetOwnAvatarView } from './views/own-avatar/AvatarInfoWidgetOwnAvatarView';
|
||||
import { AvatarInfoWidgetOwnPetView } from './views/own-pet/AvatarInfoWidgetOwnPetView';
|
||||
import { AvatarInfoWidgetPetView } from './views/pet/AvatarInfoWidgetPetView';
|
||||
import { AvatarInfoRentableBotChatView } from './views/rentable-bot-chat/AvatarInfoRentableBotChatView';
|
||||
import { AvatarInfoWidgetRentableBotView } from './views/rentable-bot/AvatarInfoWidgetRentableBotView';
|
||||
|
||||
export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
||||
@ -22,6 +23,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
||||
const [ isGameMode, setGameMode ] = useState(false);
|
||||
const [ isDancing, setIsDancing ] = useState(false);
|
||||
const [ isDecorating, setIsDecorating ] = useState(GetRoomSession().isDecorating);
|
||||
const [ rentableBotChatEvent, setRentableBotChatEvent ] = useState<RoomWidgetUpdateRentableBotChatEvent>(null);
|
||||
|
||||
const onRoomWidgetRoomEngineUpdateEvent = useCallback((event: RoomWidgetRoomEngineUpdateEvent) =>
|
||||
{
|
||||
@ -160,6 +162,13 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.USER_ADDED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
CreateEventDispatcherHook(RoomWidgetRoomObjectUpdateEvent.OBJECT_SELECTED, eventDispatcher, onRoomWidgetRoomObjectUpdateEvent);
|
||||
|
||||
const onRoomWidgetUpdateRentableBotChatEvent = useCallback((event: RoomWidgetUpdateRentableBotChatEvent) =>
|
||||
{
|
||||
setRentableBotChatEvent(event);
|
||||
}, []);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateRentableBotChatEvent.UPDATE_CHAT, eventDispatcher, onRoomWidgetUpdateRentableBotChatEvent);
|
||||
|
||||
const decorateView = useMemo(() =>
|
||||
{
|
||||
GetRoomSession().isDecorating = isDecorating;
|
||||
@ -237,6 +246,7 @@ export const AvatarInfoWidgetView: FC<AvatarInfoWidgetViewProps> = props =>
|
||||
return (
|
||||
<>
|
||||
{ currentView }
|
||||
{ rentableBotChatEvent && <AvatarInfoRentableBotChatView chatEvent={ rentableBotChatEvent } /> }
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
@ -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>
|
||||
);
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../events';
|
||||
|
||||
export interface AvatarInfoRentableBotChatViewProps
|
||||
{
|
||||
chatEvent: RoomWidgetUpdateRentableBotChatEvent;
|
||||
}
|
@ -1,19 +1,19 @@
|
||||
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 { CreateMessageHook } from '../../../../../../hooks/messages';
|
||||
import { LocalizeText } from '../../../../../../utils/LocalizeText';
|
||||
import { useRoomContext } from '../../../../context/RoomContext';
|
||||
import { RoomWidgetUpdateRentableBotChatEvent } from '../../../../events';
|
||||
import { ContextMenuView } from '../../../context-menu/ContextMenuView';
|
||||
import { ContextMenuHeaderView } from '../../../context-menu/views/header/ContextMenuHeaderView';
|
||||
import { ContextMenuListItemView } from '../../../context-menu/views/list-item/ContextMenuListItemView';
|
||||
import { BotSkillsEnum } from '../../utils/BotSkillsEnum';
|
||||
import { AvatarInfoWidgetRentableBotViewProps, BotChatOptions } from './AvatarInfoWidgetRentableBotView.types';
|
||||
import { AvatarInfoWidgetRentableBotViewProps } from './AvatarInfoWidgetRentableBotView.types';
|
||||
|
||||
const MODE_NORMAL = 0;
|
||||
const MODE_CHANGE_NAME = 1;
|
||||
const MODE_CHANGE_MOTTO = 2;
|
||||
const MODE_CHANGE_SPEECH = 3;
|
||||
|
||||
export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotViewProps> = props =>
|
||||
{
|
||||
@ -21,9 +21,12 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
||||
const [ mode, setMode ] = useState(MODE_NORMAL);
|
||||
const [ newName, setNewName ] = useState('');
|
||||
const [ newMotto, setNewMotto ] = useState('');
|
||||
const [ newChat, setNewChat ] = useState('');
|
||||
const [ chatOptions, setChatOptions ] = useState<BotChatOptions>({ automaticChat: false, chatDelay: 0, mixSentences: false });
|
||||
const { widgetHandler = null } = useRoomContext();
|
||||
const { eventDispatcher = null } = useRoomContext();
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
setMode(MODE_NORMAL);
|
||||
}, [ rentableBotData ]);
|
||||
|
||||
const onBotCommandConfigurationEvent = useCallback((event: BotCommandConfigurationEvent) =>
|
||||
{
|
||||
@ -49,20 +52,22 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
||||
|
||||
if((pieces.length === 3) || (pieces.length === 4))
|
||||
{
|
||||
setNewChat(pieces[0]);
|
||||
setChatOptions({
|
||||
automaticChat: ((pieces[1].toLowerCase() === 'true') || (pieces[1] === '1')),
|
||||
chatDelay: parseInt(pieces[2]),
|
||||
mixSentences: ((pieces[3]) ? ((pieces[3].toLowerCase() === 'true') || (pieces[3] === '1')) : false)
|
||||
});
|
||||
}
|
||||
eventDispatcher.dispatchEvent(new RoomWidgetUpdateRentableBotChatEvent(
|
||||
rentableBotData.roomIndex,
|
||||
RoomObjectCategory.UNIT,
|
||||
rentableBotData.webID,
|
||||
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;
|
||||
}
|
||||
}
|
||||
}, [ rentableBotData ]);
|
||||
}, [ rentableBotData, eventDispatcher, close ]);
|
||||
|
||||
CreateMessageHook(BotCommandConfigurationEvent, onBotCommandConfigurationEvent);
|
||||
|
||||
@ -176,14 +181,23 @@ export const AvatarInfoWidgetRentableBotView: FC<AvatarInfoWidgetRentableBotView
|
||||
</ContextMenuListItemView> }
|
||||
</> }
|
||||
{ (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>
|
||||
<input type="text" className="form-control form-control-sm mb-2" value={ newName } onChange={ event => setNewName(event.target.value) } />
|
||||
<div className="d-flex justify-content-between align-items-center">
|
||||
<button type="button" className="btn btn-secondary btn-sm" onClick={ event => processAction(null) }>{ LocalizeText('cancel') }</button>
|
||||
<button type="button" className="btn btn-success btn-sm" onClick={ event => processAction('save_bot_name') }>{ LocalizeText('save') }</button>
|
||||
</div>
|
||||
</ContextMenuListItemView> }
|
||||
</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>
|
||||
);
|
||||
}
|
||||
|
@ -4,72 +4,62 @@
|
||||
left: 50%;
|
||||
transform: translateX(-50%);
|
||||
bottom: 65px !important;
|
||||
z-index: $chatinput-zindex;
|
||||
}
|
||||
}
|
||||
|
||||
.nitro-chat-input {
|
||||
pointer-events: none;
|
||||
z-index: $chatinput-zindex;
|
||||
.nitro-chat-input-container {
|
||||
display: flex;
|
||||
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 {
|
||||
position: relative;
|
||||
height: 40px;
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 98%;
|
||||
height: 5px;
|
||||
border-radius: 8px;
|
||||
border: 2px solid rgb(0, 0, 0);
|
||||
background: #EDEDED;
|
||||
pointer-events: all;
|
||||
padding-right: 30px;
|
||||
width: 100%;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
background: rgb(255, 255, 255);
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.input-sizer {
|
||||
display: inline-grid;
|
||||
vertical-align: top;
|
||||
align-items: center;
|
||||
position: relative;
|
||||
height: 100%;
|
||||
padding: 0 10px;
|
||||
.input-sizer {
|
||||
display: inline-grid;
|
||||
vertical-align: top;
|
||||
height: 100%;
|
||||
padding: 0 10px;
|
||||
|
||||
&::after,
|
||||
input,
|
||||
textarea {
|
||||
width: auto;
|
||||
min-width: 1em;
|
||||
grid-area: 1 / 2;
|
||||
margin: 0;
|
||||
resize: none;
|
||||
background: none;
|
||||
appearance: 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;
|
||||
&::after,
|
||||
input,
|
||||
textarea {
|
||||
width: auto;
|
||||
min-width: 1em;
|
||||
grid-area: 1 / 2;
|
||||
margin: 0;
|
||||
resize: none;
|
||||
background: none;
|
||||
appearance: none;
|
||||
border: none;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
&:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 98%;
|
||||
height: 5px;
|
||||
border-radius: 8px;
|
||||
top: 1px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
background: rgb(255, 255, 255);
|
||||
z-index: 1;
|
||||
&::after {
|
||||
content: attr(data-value) ' ';
|
||||
visibility: hidden;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import './style-selector/ChatInputStyleSelectorView';
|
||||
|
@ -1,18 +1,24 @@
|
||||
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 { GetConfiguration, GetRoomSession, SendChatTypingMessage } from '../../../../api';
|
||||
import { GetConfiguration, GetSessionDataManager } from '../../../../api';
|
||||
import { CreateEventDispatcherHook } from '../../../../hooks/events';
|
||||
import { LocalizeText } from '../../../../utils/LocalizeText';
|
||||
import { useRoomContext } from '../../context/RoomContext';
|
||||
import { ChatInputMessageType, ChatInputViewProps } from './ChatInputView.types';
|
||||
|
||||
let lastContent = '';
|
||||
import { RoomWidgetRoomObjectUpdateEvent, RoomWidgetUpdateChatInputContentEvent, RoomWidgetUpdateInfostandUserEvent } from '../../events';
|
||||
import { RoomWidgetChatMessage, RoomWidgetChatTypingMessage } from '../../messages';
|
||||
import { ChatInputViewProps } from './ChatInputView.types';
|
||||
import { ChatInputStyleSelectorView } from './style-selector/ChatInputStyleSelectorView';
|
||||
|
||||
export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
{
|
||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
const [ chatValue, setChatValue ] = useState<string>('');
|
||||
const [ selectedUsername, setSelectedUsername ] = useState('');
|
||||
const [ isTyping, setIsTyping ] = useState(false);
|
||||
const [ typingStartedSent, setTypingStartedSent ] = useState(false);
|
||||
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<HTMLInputElement>();
|
||||
|
||||
const chatModeIdWhisper = useMemo(() =>
|
||||
@ -59,35 +65,24 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
{
|
||||
setChatValue(prevValue =>
|
||||
{
|
||||
if((prevValue !== LocalizeText('widgets.chatinput.mode.whisper')) || !selectedUsername.length) return prevValue;
|
||||
if((prevValue !== chatModeIdWhisper) || !selectedUsername.length) return prevValue;
|
||||
|
||||
return (`${ prevValue } ${ selectedUsername }`);
|
||||
});
|
||||
}, [ selectedUsername ]);
|
||||
}, [ selectedUsername, chatModeIdWhisper ]);
|
||||
|
||||
const sendChat = useCallback((text: string, chatType: number, recipientName: string = '', styleId: number = 0) =>
|
||||
{
|
||||
setChatValue('');
|
||||
|
||||
switch(chatType)
|
||||
{
|
||||
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;
|
||||
}
|
||||
}, []);
|
||||
widgetHandler.processWidgetMessage(new RoomWidgetChatMessage(RoomWidgetChatMessage.MESSAGE_CHAT, text, chatType, recipientName, styleId));
|
||||
}, [ widgetHandler ]);
|
||||
|
||||
const sendChatValue = useCallback((value: string, shiftKey: boolean = false) =>
|
||||
{
|
||||
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;
|
||||
|
||||
const parts = text.split(' ');
|
||||
@ -98,7 +93,7 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
switch(parts[0])
|
||||
{
|
||||
case chatModeIdWhisper:
|
||||
chatType = ChatInputMessageType.CHAT_WHISPER;
|
||||
chatType = RoomWidgetChatMessage.CHAT_WHISPER;
|
||||
recipientName = parts[1];
|
||||
append = (chatModeIdWhisper + ' ' + recipientName + ' ');
|
||||
|
||||
@ -106,12 +101,12 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
parts.shift();
|
||||
break;
|
||||
case chatModeIdShout:
|
||||
chatType = ChatInputMessageType.CHAT_SHOUT;
|
||||
chatType = RoomWidgetChatMessage.CHAT_SHOUT;
|
||||
|
||||
parts.shift();
|
||||
break;
|
||||
case chatModeIdSpeak:
|
||||
chatType = ChatInputMessageType.CHAT_DEFAULT;
|
||||
chatType = RoomWidgetChatMessage.CHAT_DEFAULT;
|
||||
|
||||
parts.shift();
|
||||
break;
|
||||
@ -119,20 +114,38 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
|
||||
text = parts.join(' ');
|
||||
|
||||
setIsTyping(false);
|
||||
setIsIdle(false);
|
||||
|
||||
if(text.length <= maxChatLength)
|
||||
{
|
||||
// if(this.needsStyleUpdate)
|
||||
// {
|
||||
// Nitro.instance.sessionDataManager.sendChatStyleUpdate(this.currentStyle);
|
||||
if(needsChatStyleUpdate)
|
||||
{
|
||||
GetSessionDataManager().sendChatStyleUpdate(chatStyleId);
|
||||
|
||||
// this.needsStyleUpdate = false;
|
||||
// }
|
||||
setNeedsChatStyleUpdate(false);
|
||||
}
|
||||
|
||||
let currentStyle = 1;
|
||||
|
||||
sendChat(text, chatType, recipientName, currentStyle);
|
||||
sendChat(text, chatType, recipientName, chatStyleId);
|
||||
}
|
||||
}, [ chatModeIdWhisper, chatModeIdShout, chatModeIdSpeak, maxChatLength, sendChat ]);
|
||||
|
||||
setChatValue(append);
|
||||
}, [ chatModeIdWhisper, chatModeIdShout, chatModeIdSpeak, maxChatLength, chatStyleId, needsChatStyleUpdate, sendChat ]);
|
||||
|
||||
const updateChatInput = useCallback((value: string) =>
|
||||
{
|
||||
if(!value || !value.length)
|
||||
{
|
||||
setIsTyping(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
setIsTyping(true);
|
||||
setIsIdle(true);
|
||||
}
|
||||
|
||||
setChatValue(value);
|
||||
}, []);
|
||||
|
||||
const onKeyDownEvent = useCallback((event: KeyboardEvent) =>
|
||||
{
|
||||
@ -140,24 +153,106 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
|
||||
if(document.activeElement !== inputRef.current) setInputFocus();
|
||||
|
||||
switch(event.key)
|
||||
const value = (event.target as HTMLInputElement).value;
|
||||
|
||||
switch(event.code)
|
||||
{
|
||||
case 'Space':
|
||||
checkSpecialKeywordForInput();
|
||||
return;
|
||||
case 'NumpadEnter':
|
||||
case 'Enter':
|
||||
sendChatValue((event.target as HTMLInputElement).value, event.shiftKey);
|
||||
sendChatValue(value, event.shiftKey);
|
||||
return;
|
||||
case 'Backspace':
|
||||
if(value)
|
||||
{
|
||||
const parts = value.split(' ');
|
||||
|
||||
if((parts[0] === chatModeIdWhisper) && (parts.length === 3) && (parts[2] === ''))
|
||||
{
|
||||
setChatValue('');
|
||||
}
|
||||
}
|
||||
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 ]);
|
||||
setChatStyleId(styleId);
|
||||
setNeedsChatStyleUpdate(true);
|
||||
}, []);
|
||||
|
||||
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);
|
||||
|
||||
const onRoomWidgetChatInputContentUpdateEvent = useCallback((event: RoomWidgetUpdateChatInputContentEvent) =>
|
||||
{
|
||||
switch(event.chatMode)
|
||||
{
|
||||
case RoomWidgetUpdateChatInputContentEvent.WHISPER: {
|
||||
setChatValue(`${ chatModeIdWhisper } ${ event.userName } `);
|
||||
return;
|
||||
}
|
||||
case RoomWidgetUpdateChatInputContentEvent.SHOUT:
|
||||
return;
|
||||
}
|
||||
}, [ chatModeIdWhisper ]);
|
||||
|
||||
CreateEventDispatcherHook(RoomWidgetUpdateChatInputContentEvent.CHAT_INPUT_CONTENT, eventDispatcher, onRoomWidgetChatInputContentUpdateEvent);
|
||||
|
||||
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(() =>
|
||||
{
|
||||
@ -169,59 +264,13 @@ export const ChatInputView: FC<ChatInputViewProps> = props =>
|
||||
}
|
||||
}, [ 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 (
|
||||
createPortal(
|
||||
<div className="nitro-chat-input">
|
||||
<div className="chatinput-container">
|
||||
<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; setChatValue(event.target.value) } } onMouseDown={ onInputMouseDownEvent } />
|
||||
</div>
|
||||
<div className="nitro-chat-input-container">
|
||||
<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() } />
|
||||
</div>
|
||||
<ChatInputStyleSelectorView onStyleSelected={ onStyleSelected } />
|
||||
</div>, document.getElementById('toolbar-chat-input-container'))
|
||||
);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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%;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -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> }
|
||||
</>
|
||||
)
|
||||
}
|
@ -0,0 +1,4 @@
|
||||
export interface ChatInputStyleSelectorViewProps
|
||||
{
|
||||
onStyleSelected: (styleId: number) => void;
|
||||
}
|
@ -1,36 +1,25 @@
|
||||
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<ChatWidgetViewProps> = props =>
|
||||
{
|
||||
const [ chatMessages, setChatMessages ] = useState<ChatBubbleMessage[]>([]);
|
||||
const { roomSession = null } = useRoomContext();
|
||||
const { roomSession = null, eventDispatcher = null } = useRoomContext();
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const removeFirstHiddenChat = useCallback(() =>
|
||||
const removeHiddenChats = useCallback(() =>
|
||||
{
|
||||
if(!chatMessages.length) return;
|
||||
|
||||
const lastChat = chatMessages[0];
|
||||
const newMessages = chatMessages.filter(chat => ((chat.top > (-(chat.height) * 2))));
|
||||
|
||||
if((lastChat.top > (-(lastChat.height) * 2))) return;
|
||||
|
||||
setChatMessages(prevValue =>
|
||||
{
|
||||
const newMessages = [ ...prevValue ];
|
||||
|
||||
newMessages.shift();
|
||||
|
||||
return newMessages;
|
||||
});
|
||||
if(newMessages.length !== chatMessages.length) setChatMessages(newMessages);
|
||||
}, [ chatMessages ]);
|
||||
|
||||
const moveChatUp = useCallback((chat: ChatBubbleMessage, amount: number) =>
|
||||
@ -42,8 +31,8 @@ export const ChatWidgetView: FC<ChatWidgetViewProps> = props =>
|
||||
{
|
||||
chatMessages.forEach(chat => moveChatUp(chat, amount));
|
||||
|
||||
removeFirstHiddenChat();
|
||||
}, [ chatMessages, moveChatUp, removeFirstHiddenChat ]);
|
||||
removeHiddenChats();
|
||||
}, [ chatMessages, moveChatUp, removeHiddenChats ]);
|
||||
|
||||
const makeRoom = useCallback((chat: ChatBubbleMessage) =>
|
||||
{
|
||||
@ -72,65 +61,21 @@ export const ChatWidgetView: FC<ChatWidgetViewProps> = 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<string>(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) =>
|
||||
{
|
||||
@ -142,7 +87,7 @@ export const ChatWidgetView: FC<ChatWidgetViewProps> = props =>
|
||||
{
|
||||
if(!chat.elementRef) return;
|
||||
|
||||
chat.left = (chat.elementRef.offsetLeft + event.offsetX);
|
||||
chat.left += event.offsetX;
|
||||
});
|
||||
}, [ roomSession, chatMessages ]);
|
||||
|
||||
|
@ -96,7 +96,7 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = props =>
|
||||
{ (chat.imageUrl && (chat.imageUrl !== '')) && <div className="user-image" style={ { backgroundImage: 'url(' + chat.imageUrl + ')' } } /> }
|
||||
</div>
|
||||
<div className="chat-content">
|
||||
<b className="username mr-1">{ chat.username }</b>
|
||||
<b className="username mr-1" dangerouslySetInnerHTML={ {__html: `${ chat.username }: ` } } />
|
||||
{ chat.text }
|
||||
<span className="message"> {
|
||||
messageParts && messageParts.map((part, index) =>
|
||||
|
@ -39,7 +39,7 @@ export class ChatBubbleMessage
|
||||
|
||||
public get left(): number
|
||||
{
|
||||
return this._top;
|
||||
return this._left;
|
||||
}
|
||||
|
||||
public set left(value: number)
|
||||
|
@ -1,6 +1,6 @@
|
||||
.nitro-context-menu {
|
||||
width: 150px;
|
||||
max-width: 150px;
|
||||
width: 125px;
|
||||
max-width: 125px;
|
||||
padding: 2px;
|
||||
background-color: #1c323f;
|
||||
border: 2px solid rgba($white, 0.5);
|
||||
@ -9,16 +9,14 @@
|
||||
z-index: $context-menu-zindex;
|
||||
|
||||
&.name-only {
|
||||
background-color: rgba($black, 0.7);
|
||||
background-color: rgba($black, 0.5);
|
||||
padding: 1px 8px;
|
||||
min-width: 60px;
|
||||
width: unset;
|
||||
max-width: unset;
|
||||
text-align: center;
|
||||
font-size: 18px;
|
||||
}
|
||||
|
||||
&:after {
|
||||
&:not(.name-only):after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
bottom: -7px;
|
||||
@ -39,11 +37,12 @@
|
||||
height: 25px;
|
||||
max-height: 25px;
|
||||
font-size: 16px;
|
||||
margin-bottom: 2px;
|
||||
}
|
||||
|
||||
.menu-list-split-3 {
|
||||
|
||||
.menu-list-item {
|
||||
.menu-item {
|
||||
margin-right: 2px;
|
||||
|
||||
&:nth-child(3n+3) {
|
||||
@ -52,34 +51,42 @@
|
||||
}
|
||||
}
|
||||
|
||||
.menu-list-item {
|
||||
.menu-item {
|
||||
position: relative;
|
||||
height: 24px;
|
||||
max-height: 24px;
|
||||
margin-top: 2px;
|
||||
margin-bottom: 2px;
|
||||
padding: 3px;
|
||||
background: $bg-mirage-split-background;
|
||||
cursor: pointer;
|
||||
overflow: hidden;
|
||||
|
||||
&:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
filter: brightness(0.7);
|
||||
cursor: not-allowed;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
.fas,
|
||||
.nitro-currency-icon {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
&.list-item {
|
||||
height: 24px;
|
||||
max-height: 24px;
|
||||
padding: 3px;
|
||||
background: $bg-mirage-split-background;
|
||||
cursor: pointer;
|
||||
|
||||
&.left {
|
||||
left: 8px;
|
||||
right: unset;
|
||||
&:not(.disabled):hover {
|
||||
background: $bg-cello-split-background;
|
||||
}
|
||||
}
|
||||
|
||||
&:not(.disabled):hover {
|
||||
background: $bg-cello-split-background;
|
||||
.fas,
|
||||
.nitro-currency-icon {
|
||||
position: absolute;
|
||||
right: 8px;
|
||||
|
||||
&.left {
|
||||
left: 8px;
|
||||
right: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,10 +1,11 @@
|
||||
import { FixedSizeStack } from 'nitro-renderer';
|
||||
import { FixedSizeStack, Nitro } from 'nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api';
|
||||
import { ContextMenuViewProps } from './ContextMenuView.types';
|
||||
|
||||
const fadeDelay = 3000;
|
||||
const fadeLength = 75;
|
||||
const SPACE_AROUND_EDGES = 10;
|
||||
|
||||
export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
{
|
||||
@ -46,9 +47,21 @@ export const ContextMenuView: FC<ContextMenuViewProps> = props =>
|
||||
|
||||
if(!bounds || !elementRef.current) return;
|
||||
|
||||
let left = Math.round((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2));
|
||||
let top = Math.round((bounds.top - elementRef.current.offsetHeight) + 20);
|
||||
|
||||
const maxLeft = ((Nitro.instance.width - elementRef.current.offsetWidth) - SPACE_AROUND_EDGES);
|
||||
const maxTop = ((Nitro.instance.height - elementRef.current.offsetHeight) - SPACE_AROUND_EDGES);
|
||||
|
||||
if(left < SPACE_AROUND_EDGES) left = SPACE_AROUND_EDGES;
|
||||
else if(left > maxLeft) left = maxLeft;
|
||||
|
||||
if(top < SPACE_AROUND_EDGES) top = SPACE_AROUND_EDGES;
|
||||
else if(top > maxTop) top = maxTop;
|
||||
|
||||
setPos({
|
||||
x: Math.round(((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2))),
|
||||
y: Math.round((bounds.top - elementRef.current.offsetHeight) + 10)
|
||||
x: left,
|
||||
y: top
|
||||
});
|
||||
}, [ objectId, category, isFading, close ]);
|
||||
|
||||
|
@ -13,7 +13,7 @@ export const ContextMenuListItemView: FC<ContextMenuListItemViewProps> = props =
|
||||
}, [ canSelect, onClick ]);
|
||||
|
||||
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 }
|
||||
</div>
|
||||
)
|
||||
|
@ -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<FurnitureWidgetsViewProps> = props =>
|
||||
{
|
||||
return (
|
||||
<div className="position-absolute nitro-room-widgets t-0 l-0">
|
||||
<FurnitureBackgroundColorView />
|
||||
<FurnitureDimmerView />
|
||||
<FurnitureEngravingLockView />
|
||||
<FurnitureExchangeCreditView />
|
||||
|
@ -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 (
|
||||
<NitroCardView simple={ true }>
|
||||
<NitroCardHeaderView headerText={ LocalizeText('widget.backgroundcolor.title') } onCloseClick={ event => setObjectId(-1) } />
|
||||
<NitroCardContentView>
|
||||
background toner
|
||||
</NitroCardContentView>
|
||||
</NitroCardView>
|
||||
);
|
||||
}
|
@ -5,7 +5,7 @@ import { ObjectLocationViewProps } from './ObjectLocationView.types';
|
||||
|
||||
export const ObjectLocationView: FC<ObjectLocationViewProps> = props =>
|
||||
{
|
||||
const { objectId = -1, category = -1, children = null } = props;
|
||||
const { objectId = -1, category = -1, noFollow = false, children = null } = props;
|
||||
const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1});
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
@ -31,13 +31,24 @@ export const ObjectLocationView: FC<ObjectLocationViewProps> = props =>
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
Nitro.instance.ticker.add(updatePosition);
|
||||
let remove = false;
|
||||
|
||||
if(noFollow)
|
||||
{
|
||||
updatePosition();
|
||||
}
|
||||
else
|
||||
{
|
||||
remove = true;
|
||||
|
||||
Nitro.instance.ticker.add(updatePosition);
|
||||
}
|
||||
|
||||
return () =>
|
||||
{
|
||||
Nitro.instance.ticker.remove(updatePosition);
|
||||
if(remove) Nitro.instance.ticker.remove(updatePosition);
|
||||
}
|
||||
}, [ updatePosition ]);
|
||||
}, [ updatePosition, noFollow ]);
|
||||
|
||||
return (
|
||||
<div ref={ elementRef } className={ 'object-location position-absolute ' + (pos.x > -1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } }>
|
||||
|
@ -2,4 +2,5 @@ export interface ObjectLocationViewProps
|
||||
{
|
||||
objectId: number;
|
||||
category: number;
|
||||
noFollow?: boolean;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user