mirror of
https://github.com/billsonnn/nitro-react.git
synced 2025-01-19 05:46:27 +01:00
Chats move
This commit is contained in:
parent
dfaf239052
commit
37d614e168
41
src/views/room/events/RoomWidgetRoomViewUpdateEvent.ts
Normal file
41
src/views/room/events/RoomWidgetRoomViewUpdateEvent.ts
Normal file
@ -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;
|
||||
}
|
||||
}
|
@ -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';
|
||||
|
@ -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<ChatWidgetViewProps> = props =>
|
||||
{
|
||||
const { eventDispatcher = null, widgetHandler = null } = useRoomContext();
|
||||
const [ chatMessages, setChatMessages ] = useState<ChatBubbleMessage[]>([]);
|
||||
const { roomSession = null } = useRoomContext();
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
const removeFirstHiddenChat = useCallback(() =>
|
||||
@ -20,7 +21,7 @@ export const ChatWidgetView: FC<ChatWidgetViewProps> = 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<ChatWidgetViewProps> = 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<ChatWidgetViewProps> = 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<ChatWidgetViewProps> = 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<ChatWidgetViewProps> = props =>
|
||||
{
|
||||
setChatMessages(prevValue =>
|
||||
{
|
||||
return [ ...prevValue, chat ]
|
||||
return [ ...prevValue, chat ];
|
||||
});
|
||||
}, []);
|
||||
|
||||
@ -80,11 +79,6 @@ export const ChatWidgetView: FC<ChatWidgetViewProps> = 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<ChatWidgetViewProps> = 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 (
|
||||
<div ref={ elementRef } className="nitro-chat-widget">
|
||||
{ chatMessages && (chatMessages.length > 0) && chatMessages.map((chat, index) =>
|
||||
{ chatMessages.map(chat =>
|
||||
{
|
||||
return <ChatWidgetMessageView key={ index } chat={ chat } makeRoom={ makeRoom } />
|
||||
return <ChatWidgetMessageView key={ chat.id } chat={ chat } makeRoom={ makeRoom } />
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
|
@ -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<ChatWidgetMessageViewProps> = 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<HTMLDivElement>();
|
||||
|
||||
@ -14,37 +13,37 @@ export const ChatWidgetMessageView: FC<ChatWidgetMessageViewProps> = 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<ChatWidgetMessageViewProps> = 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 (
|
||||
<div ref={ elementRef } className="bubble-container" style={ { visibility: (isVisible ? 'visible' : 'hidden') } }>
|
||||
@ -96,7 +96,9 @@ 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><span className="message"> {
|
||||
<b className="username mr-1">{ chat.username }</b>
|
||||
{ chat.text }
|
||||
<span className="message"> {
|
||||
messageParts && messageParts.map((part, index) =>
|
||||
{
|
||||
return <span key={ index } className={ part.className } style={ part.style } onClick={ part.onClick }>{ part.text }</span>
|
||||
|
@ -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');
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user