diff --git a/src/views/room/events/RoomWidgetRoomViewUpdateEvent.ts b/src/views/room/events/RoomWidgetRoomViewUpdateEvent.ts new file mode 100644 index 00000000..4e2a2a13 --- /dev/null +++ b/src/views/room/events/RoomWidgetRoomViewUpdateEvent.ts @@ -0,0 +1,41 @@ +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; + } +} diff --git a/src/views/room/events/index.ts b/src/views/room/events/index.ts index 8691caae..defef32d 100644 --- a/src/views/room/events/index.ts +++ b/src/views/room/events/index.ts @@ -2,6 +2,7 @@ export * from './RoomWidgetAvatarInfoEvent'; export * from './RoomWidgetObjectNameEvent'; export * from './RoomWidgetRoomEngineUpdateEvent'; export * from './RoomWidgetRoomObjectUpdateEvent'; +export * from './RoomWidgetRoomViewUpdateEvent'; export * from './RoomWidgetUpdateDanceStatusEvent'; export * from './RoomWidgetUpdateEvent'; export * from './RoomWidgetUpdateInfostandEvent'; diff --git a/src/views/room/widgets/chat/ChatWidgetView.tsx b/src/views/room/widgets/chat/ChatWidgetView.tsx index 5c0c1470..77a39660 100644 --- a/src/views/room/widgets/chat/ChatWidgetView.tsx +++ b/src/views/room/widgets/chat/ChatWidgetView.tsx @@ -1,6 +1,7 @@ -import { RoomObjectCategory, RoomSessionChatEvent } from 'nitro-renderer'; +import { RoomDragEvent, RoomObjectCategory, RoomSessionChatEvent } 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 { useRoomContext } from '../../context/RoomContext'; import { ChatWidgetViewProps } from './ChatWidgetView.types'; @@ -10,8 +11,8 @@ import { GetBubbleLocation } from './utils/ChatWidgetUtilities'; export const ChatWidgetView: FC = props => { - const { eventDispatcher = null, widgetHandler = null } = useRoomContext(); const [ chatMessages, setChatMessages ] = useState([]); + const { roomSession = null } = useRoomContext(); const elementRef = useRef(); const removeFirstHiddenChat = useCallback(() => @@ -20,7 +21,7 @@ export const ChatWidgetView: FC = props => const lastChat = chatMessages[0]; - if((lastChat.lastTop > (-(lastChat.height) * 2))) return; + if((lastChat.top > (-(lastChat.height) * 2))) return; setChatMessages(prevValue => { @@ -34,9 +35,7 @@ export const ChatWidgetView: FC = props => const moveChatUp = useCallback((chat: ChatBubbleMessage, amount: number) => { - chat.lastTop -= amount; - - if(chat.elementRef) chat.elementRef.style.top = (chat.lastTop + 'px'); + chat.top -= amount; }, []); const moveAllChatsUp = useCallback((amount: number) => @@ -48,7 +47,7 @@ export const ChatWidgetView: FC = props => const makeRoom = useCallback((chat: ChatBubbleMessage) => { - const lowestPoint = ((chat.lastTop + chat.height) - 1); + const lowestPoint = ((chat.top + chat.height) - 1); const requiredSpace = (chat.height + 1); const spaceAvailable = (elementRef.current.offsetHeight - lowestPoint); @@ -56,11 +55,11 @@ export const ChatWidgetView: FC = props => { const amount = (requiredSpace - spaceAvailable); - chatMessages.forEach((existingChat, index) => + chatMessages.forEach(existingChat => { if(existingChat === chat) return; - moveChatUp(existingChat, amount) + moveChatUp(existingChat, amount); }); } }, [ chatMessages, moveChatUp ]); @@ -69,7 +68,7 @@ export const ChatWidgetView: FC = props => { setChatMessages(prevValue => { - return [ ...prevValue, chat ] + return [ ...prevValue, chat ]; }); }, []); @@ -80,11 +79,6 @@ export const ChatWidgetView: FC = props => if(!roomObject) return; const canvasId = 1; - - const roomGeometry = GetRoomEngine().getRoomInstanceGeometry(event.session.roomId, canvasId); - - if(!roomGeometry) return; - const objectLocation = roomObject.getLocation(); const bubbleLocation = GetBubbleLocation(event.session.roomId, objectLocation, canvasId); const userData = GetRoomSession().userDataManager.getUserDataByIndex(event.objectId); @@ -138,31 +132,37 @@ export const ChatWidgetView: FC = props => useRoomSessionManagerEvent(RoomSessionChatEvent.CHAT_EVENT, onRoomSessionChatEvent); - // useEffect(() => - // { - // const interval = setInterval(() => moveAllChatsUp(15), 500); + const onRoomDragEvent = useCallback((event: RoomDragEvent) => + { + if(!chatMessages.length) return; - // return () => - // { - // if(interval) clearInterval(interval); - // } - // }, [ chatMessages, moveAllChatsUp ]); + if(event.roomId !== roomSession.roomId) return; + + chatMessages.forEach(chat => + { + if(!chat.elementRef) return; + + chat.left = (chat.elementRef.offsetLeft + event.offsetX); + }); + }, [ roomSession, chatMessages ]); + + useRoomEngineEvent(RoomDragEvent.ROOM_DRAG, onRoomDragEvent); useEffect(() => { - const interval = setInterval(() => removeFirstHiddenChat(), 1000); + const interval = setInterval(() => moveAllChatsUp(15), 4500); return () => { if(interval) clearInterval(interval); } - }, [ removeFirstHiddenChat ]); + }, [ chatMessages, moveAllChatsUp ]); return (
- { chatMessages && (chatMessages.length > 0) && chatMessages.map((chat, index) => + { chatMessages.map(chat => { - return + return })}
); diff --git a/src/views/room/widgets/chat/message/ChatWidgetMessageView.tsx b/src/views/room/widgets/chat/message/ChatWidgetMessageView.tsx index 1bf2756d..8dc4fd2e 100644 --- a/src/views/room/widgets/chat/message/ChatWidgetMessageView.tsx +++ b/src/views/room/widgets/chat/message/ChatWidgetMessageView.tsx @@ -1,11 +1,10 @@ import { FC, MouseEvent, useCallback, useEffect, useRef, useState } from 'react'; -import { GetSessionDataManager } from '../../../../../api'; import { ChatWidgetMessageViewProps } from './ChatWidgetMessageView.types'; export const ChatWidgetMessageView: FC = props => { const { chat = null, makeRoom = null } = props; - const [ isVisible, setIsVisible ] = useState(true); + const [ isVisible, setIsVisible ] = useState(false); const [ messageParts, setMessageParts ] = useState<{text: string, className?: string, style?: any, onClick?: () => void}[]>(null); const elementRef = useRef(); @@ -14,37 +13,37 @@ export const ChatWidgetMessageView: FC = props => }, []); - useEffect(() => - { - if(messageParts) return; + // useEffect(() => + // { + // if(messageParts) return; - const userNameMention = '@' + GetSessionDataManager().userName; + // const userNameMention = '@' + GetSessionDataManager().userName; - const matches = [...chat.text.matchAll(new RegExp(userNameMention + '\\b', 'gi'))]; + // const matches = [...chat.text.matchAll(new RegExp(userNameMention + '\\b', 'gi'))]; - if(matches.length > 0) - { - const prevText = chat.text.substr(0, matches[0].index); - const postText = chat.text.substring(matches[0].index + userNameMention.length, chat.text.length); + // if(matches.length > 0) + // { + // const prevText = chat.text.substr(0, matches[0].index); + // const postText = chat.text.substring(matches[0].index + userNameMention.length, chat.text.length); - setMessageParts( - [ - { text: prevText }, - { text: userNameMention, className: 'chat-mention', onClick: () => {alert('I clicked in the mention')}}, - { text: postText } - ] - ); - } - else - { - setMessageParts( - [ - { text: chat.text } - ] - ); - } + // setMessageParts( + // [ + // { text: prevText }, + // { text: userNameMention, className: 'chat-mention', onClick: () => {alert('I clicked in the mention')}}, + // { text: postText } + // ] + // ); + // } + // else + // { + // setMessageParts( + // [ + // { text: chat.text } + // ] + // ); + // } - }, [ chat ]); + // }, [ chat ]); useEffect(() => { @@ -59,34 +58,35 @@ export const ChatWidgetMessageView: FC = props => chat.height = height; chat.elementRef = element; - let left = chat.lastLeft; - let top = chat.lastTop; + let left = chat.left; + let top = chat.top; if(!left && !top) { left = (chat.location.x - (width / 2)); top = (element.parentElement.offsetHeight - height); - chat.lastLeft = left; - chat.lastTop = top; + chat.left = left; + chat.top = top; } - element.style.left = (left + 'px'); - element.style.top = (top + 'px'); - if(!chat.visible) { makeRoom(chat); - } - chat.visible = true; - //setIsVisible(true); + chat.visible = true; + } return () => { chat.elementRef = null; } - }, [ elementRef, isVisible, chat, makeRoom ]); + }, [ elementRef, chat, makeRoom ]); + + useEffect(() => + { + setIsVisible(chat.visible); + }, [ chat.visible ]); return (
@@ -96,7 +96,9 @@ export const ChatWidgetMessageView: FC = props => { (chat.imageUrl && (chat.imageUrl !== '')) &&
}
- { chat.username } { + { chat.username } + { chat.text } + { messageParts && messageParts.map((part, index) => { return { part.text } diff --git a/src/views/room/widgets/chat/utils/ChatBubbleMessage.ts b/src/views/room/widgets/chat/utils/ChatBubbleMessage.ts index 24570213..c5fb72b8 100644 --- a/src/views/room/widgets/chat/utils/ChatBubbleMessage.ts +++ b/src/views/room/widgets/chat/utils/ChatBubbleMessage.ts @@ -2,15 +2,16 @@ import { INitroPoint } from 'nitro-renderer'; export class ChatBubbleMessage { - public static BUBBLE_COUNTER: number = -1; + public static BUBBLE_COUNTER: number = 0; public id: number = -1; public width: number = 0; public height: number = 0; - public lastTop: number = 0; - public lastLeft: number = 0; public elementRef: HTMLDivElement = null; public visible: boolean = false; + + private _top: number = 0; + private _left: number = 0; constructor( public text: string = '', @@ -23,4 +24,28 @@ export class ChatBubbleMessage ) { this.id = ++ChatBubbleMessage.BUBBLE_COUNTER; } + + public get top(): number + { + return this._top; + } + + public set top(value: number) + { + this._top = value; + + if(this.elementRef) this.elementRef.style.top = (this._top + 'px'); + } + + public get left(): number + { + return this._top; + } + + public set left(value: number) + { + this._left = value; + + if(this.elementRef) this.elementRef.style.left = (this._left + 'px'); + } } diff --git a/src/views/room/widgets/context-menu/ContextMenu.scss b/src/views/room/widgets/context-menu/ContextMenu.scss index e31271cb..a7c8a0b4 100644 --- a/src/views/room/widgets/context-menu/ContextMenu.scss +++ b/src/views/room/widgets/context-menu/ContextMenu.scss @@ -6,6 +6,7 @@ border: 2px solid rgba($white, 0.5); border-radius: $border-radius; font-size: $font-size-sm; + z-index: $context-menu-zindex; &.name-only { background-color: rgba($black, 0.7);