diff --git a/src/api/nitro/GetTicker.ts b/src/api/nitro/GetTicker.ts new file mode 100644 index 00000000..eaab9664 --- /dev/null +++ b/src/api/nitro/GetTicker.ts @@ -0,0 +1,6 @@ +import { Nitro } from 'nitro-renderer'; + +export function GetTicker() +{ + return Nitro.instance.ticker; +} diff --git a/src/api/nitro/index.ts b/src/api/nitro/index.ts index c0347237..e59ad817 100644 --- a/src/api/nitro/index.ts +++ b/src/api/nitro/index.ts @@ -1,5 +1,6 @@ export * from './avatar'; export * from './camera'; export * from './GetConnection'; +export * from './GetTicker'; export * from './room'; export * from './session'; diff --git a/src/api/nitro/room/GetRoomObjectBounds.ts b/src/api/nitro/room/GetRoomObjectBounds.ts new file mode 100644 index 00000000..5c55764d --- /dev/null +++ b/src/api/nitro/room/GetRoomObjectBounds.ts @@ -0,0 +1,7 @@ +import { NitroRectangle } from 'nitro-renderer'; +import { GetRoomEngine } from './GetRoomEngine'; + +export function GetRoomObjectBounds(roomId: number, objectId: number, category: number, canvasId = 1): NitroRectangle +{ + return GetRoomEngine().getRoomObjectBoundingRectangle(roomId, objectId, category, canvasId); +} diff --git a/src/api/nitro/room/index.ts b/src/api/nitro/room/index.ts index f0122ddf..a3b38b42 100644 --- a/src/api/nitro/room/index.ts +++ b/src/api/nitro/room/index.ts @@ -2,6 +2,7 @@ export * from './DispatchMouseEvent'; export * from './DispatchResizeEvent'; export * from './DispatchTouchEvent'; export * from './GetRoomEngine'; +export * from './GetRoomObjectBounds'; export * from './InitializeRoomInstanceRenderingCanvas'; export * from './IsFurnitureSelectionDisabled'; export * from './ProcessRoomObjectOperation'; diff --git a/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.tsx b/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.tsx index 9a968995..0cb6d0fc 100644 --- a/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.tsx +++ b/src/views/room/widgets/avatar-info/views/name/AvatarInfoWidgetNameView.tsx @@ -1,16 +1,21 @@ -import { FC } from 'react'; -import { ObjectLocationView } from '../../../object-location/ObjectLocationView'; +import { FC, useCallback } from 'react'; +import { ContextMenuView } from '../../../context-menu/ContextMenuView'; import { AvatarInfoWidgetNameViewProps } from './AvatarInfoWidgetNameView.types'; export const AvatarInfoWidgetNameView: FC = props => { const { event = null } = props; + const onClose = useCallback(() => + { + + }, []); + return ( - +
{ event.name }
-
+ ); } diff --git a/src/views/room/widgets/context-menu/ContextMenu.scss b/src/views/room/widgets/context-menu/ContextMenu.scss new file mode 100644 index 00000000..3c393d9b --- /dev/null +++ b/src/views/room/widgets/context-menu/ContextMenu.scss @@ -0,0 +1,3 @@ +.nitro-context-menu { + +} diff --git a/src/views/room/widgets/context-menu/ContextMenuView.tsx b/src/views/room/widgets/context-menu/ContextMenuView.tsx new file mode 100644 index 00000000..57cbbeba --- /dev/null +++ b/src/views/room/widgets/context-menu/ContextMenuView.tsx @@ -0,0 +1,47 @@ +import { FC, useCallback, useEffect, useRef, useState } from 'react'; +import { GetRoomObjectBounds, GetRoomSession, GetTicker } from '../../../../api'; +import { ContextMenuViewFadeOptions, ContextMenuViewProps } from './ContextMenuView.types'; + +export const ContextMenuView: FC = props => +{ + const { objectId = -1, category = -1, fades = false, onClose = null, children = null } = props; + const [ pos, setPos ] = useState<{ x: number, y: number }>({ x: -1, y: -1}); + const [ opacity, setOpacity ] = useState(1); + const [ fadeOptions, setFadeOptions ] = useState({ + firstFadeStarted: false, + fadeAfterDelay: true, + fadeLength: 75, + fadeTime: 0, + fadeStartDelay: 3000, + fadingOut: false + }); + const elementRef = useRef(); + + const update = useCallback((time: number) => + { + const bounds = GetRoomObjectBounds(GetRoomSession().roomId, objectId, category); + + if(!bounds || !elementRef.current) return; + + setPos({ + x: Math.round(((bounds.left + (bounds.width / 2)) - (elementRef.current.offsetWidth / 2))), + y: Math.round((bounds.top - elementRef.current.offsetHeight) + 10) + }); + }, [ objectId, category ]); + + useEffect(() => + { + GetTicker().add(update); + + return () => + { + GetTicker().remove(update); + } + }, [ update ]); + + return ( +
-1 ? 'visible' : 'invisible') } style={ { left: pos.x, top: pos.y } }> + { children } +
+ ); +} diff --git a/src/views/room/widgets/context-menu/ContextMenuView.types.ts b/src/views/room/widgets/context-menu/ContextMenuView.types.ts new file mode 100644 index 00000000..698a55b9 --- /dev/null +++ b/src/views/room/widgets/context-menu/ContextMenuView.types.ts @@ -0,0 +1,17 @@ +export interface ContextMenuViewProps +{ + objectId: number; + category: number; + fades?: boolean; + onClose: () => void; +} + +export interface ContextMenuViewFadeOptions +{ + firstFadeStarted: boolean; + fadeAfterDelay: boolean; + fadeLength: number; + fadeTime: number; + fadeStartDelay: number; + fadingOut: boolean; +}