Navigator updates

This commit is contained in:
Bill 2021-04-21 16:32:31 -04:00
parent f3fb01fc5c
commit 0134b12b9e
19 changed files with 137 additions and 63 deletions

View File

@ -61,7 +61,7 @@
5, 5,
101 101
], ],
"communication.packet.log": true, "communication.packet.log": false,
"communication.pong.manually": true, "communication.pong.manually": true,
"communication.pong.interval.ms": 20000, "communication.pong.interval.ms": 20000,
"avatar.mandatory.libraries": [ "avatar.mandatory.libraries": [

View File

@ -3,6 +3,7 @@
@import './fontawesome/solid'; @import './fontawesome/solid';
@import './fontawesome/brands'; @import './fontawesome/brands';
@import './fontawesome/regular'; @import './fontawesome/regular';
@import './scrollbars';
@import './grid'; @import './grid';
@import './icons'; @import './icons';
@import './utils'; @import './utils';

View File

@ -0,0 +1,17 @@
::-webkit-scrollbar {
width: 4px;
}
::-webkit-scrollbar-track {
background: rgba(transparent, 0.1);
}
::-webkit-scrollbar-thumb {
background: rgba($white, 0.7);
width: 4px;
}
::-webkit-scrollbar-thumb:hover {
background: rgba($white, 1);
}

View File

@ -1,11 +1,53 @@
import { createRef, MouseEvent, useEffect } from 'react';
import Draggable from 'react-draggable'; import Draggable from 'react-draggable';
import { DraggableWindowProps } from './DraggableWindow.types'; import { DraggableWindowProps } from './DraggableWindow.types';
const currentWindows: HTMLDivElement[] = [];
export function DraggableWindow(props: DraggableWindowProps): JSX.Element export function DraggableWindow(props: DraggableWindowProps): JSX.Element
{ {
const elementRef = createRef<HTMLDivElement>();
function bringToTop(): void
{
let zIndex = 400;
console.log(currentWindows);
for(const existingWindow of currentWindows)
{
zIndex += 1;
existingWindow.style.zIndex = zIndex.toString();
}
}
function onMouseDown(event: MouseEvent): void
{
bringToTop();
}
useEffect(() =>
{
const element = elementRef.current;
currentWindows.push(element);
bringToTop();
return () =>
{
const index = currentWindows.indexOf(element);
if(index >= 0) currentWindows.splice(index, 1);
}
}, [ elementRef ]);
return ( return (
<Draggable handle={ props.handle } { ...props.draggableOptions }> <Draggable handle={ props.handle } { ...props.draggableOptions }>
{ props.children } <div ref={ elementRef } className="position-absolute t-0 l-0" onMouseDown={ onMouseDown }>
{ props.children }
</div>
</Draggable> </Draggable>
); );
} }

View File

@ -14,6 +14,7 @@ export class TransitionAnimationTypes
public static BOUNCE: string = 'bounce'; public static BOUNCE: string = 'bounce';
public static SLIDE_LEFT: string = 'slideLeft'; public static SLIDE_LEFT: string = 'slideLeft';
public static FLIP_X: string = 'flipX'; public static FLIP_X: string = 'flipX';
public static FADE_IN: string = 'fadeIn';
public static FADE_DOWN: string = 'fadeDown'; public static FADE_DOWN: string = 'fadeDown';
public static FADE_UP: string = 'fadeUp'; public static FADE_UP: string = 'fadeUp';
public static HEAD_SHAKE: string = 'headShake'; public static HEAD_SHAKE: string = 'headShake';

View File

@ -67,6 +67,21 @@ export function getTransitionAnimationStyle(type: string, transition: Transition
animationDuration: `${ timeout }ms` animationDuration: `${ timeout }ms`
} }
} }
case TransitionAnimationTypes.FADE_IN:
switch(transition)
{
default:
case ENTERING:
return {
animationName: `fadeIn`,
animationDuration: `${ timeout }ms`
}
case EXITING:
return {
animationName: `fadeOut`,
animationDuration: `${ timeout }ms`
}
}
case TransitionAnimationTypes.FADE_DOWN: case TransitionAnimationTypes.FADE_DOWN:
switch(transition) switch(transition)
{ {

View File

@ -6,6 +6,8 @@ import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow';
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event'; import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
import { useUiEvent } from '../../hooks/events/ui/ui-event'; import { useUiEvent } from '../../hooks/events/ui/ui-event';
import { SendMessageHook } from '../../hooks/messages/message-event'; import { SendMessageHook } from '../../hooks/messages/message-event';
import { TransitionAnimation } from '../../transitions/TransitionAnimation';
import { TransitionAnimationTypes } from '../../transitions/TransitionAnimation.types';
import { LocalizeText } from '../../utils/LocalizeText'; import { LocalizeText } from '../../utils/LocalizeText';
import { NavigatorLockView } from './lock/NavigatorLockView'; import { NavigatorLockView } from './lock/NavigatorLockView';
import { NavigatorLockViewStage } from './lock/NavigatorLockView.types'; import { NavigatorLockViewStage } from './lock/NavigatorLockView.types';
@ -127,23 +129,23 @@ export function NavigatorView(props: NavigatorViewProps): JSX.Element
useRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent); useRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
return ( return (
<> <NavigatorContext.Provider value={{ onTryVisitRoom: tryVisitRoom }}>
<NavigatorContext.Provider value={{ onTryVisitRoom: tryVisitRoom }}> <NavigatorMessageHandler setTopLevelContext={ setTopLevelContext } setTopLevelContexts={ setTopLevelContexts } setSearchResults={ setSearchResults } showLock={ showLock } hideLock={ hideLock } />
<NavigatorMessageHandler setTopLevelContext={ setTopLevelContext } setTopLevelContexts={ setTopLevelContexts } setSearchResults={ setSearchResults } showLock={ showLock } hideLock={ hideLock } /> { isVisible && <DraggableWindow handle=".drag-handler">
{ isVisible && <DraggableWindow handle=".drag-handler"> <div className="nitro-navigator d-flex flex-column bg-primary border border-black shadow rounded">
<div className="nitro-navigator d-flex flex-column bg-primary border border-black shadow rounded position-absolute"> <div className="drag-handler d-flex justify-content-between align-items-center px-3 pt-3">
<div className="drag-handler d-flex justify-content-between align-items-center px-3 pt-3"> <div className="h6 m-0">{ LocalizeText((isLoading || isSearching) ? 'navigator.title.is.busy' : 'navigator.title') }</div>
<div className="h6 m-0">{ LocalizeText((isLoading || isSearching) ? 'navigator.title.is.busy' : 'navigator.title') }</div> <button type="button" className="close" onClick={ hideNavigator }>
<button type="button" className="close" onClick={ hideNavigator }> <i className="fas fa-times"></i>
<i className="fas fa-times"></i> </button>
</button>
</div>
<NavigatorTabsView topLevelContext={ topLevelContext } topLevelContexts={ topLevelContexts } setTopLevelContext={ setTopLevelContext } />
<NavigatorResultListsView resultLists={ searchResults } />
</div> </div>
</DraggableWindow> } <NavigatorTabsView topLevelContext={ topLevelContext } topLevelContexts={ topLevelContexts } setTopLevelContext={ setTopLevelContext } />
{ isLockVisible && <NavigatorLockView roomData={ lastRoomVisited } stage={ lockStage } onHideLock={ hideLock } onVisitRoom={ visitRoom }></NavigatorLockView> } <TransitionAnimation className="d-flex px-3 pb-3" type={ TransitionAnimationTypes.FADE_IN } inProp={ (!isSearching && !!searchResults) } timeout={ 300 }>
</NavigatorContext.Provider> <NavigatorResultListsView resultLists={ searchResults } />
</> </TransitionAnimation>
</div>
</DraggableWindow> }
{ isLockVisible && <NavigatorLockView roomData={ lastRoomVisited } stage={ lockStage } onHideLock={ hideLock } onVisitRoom={ visitRoom }></NavigatorLockView> }
</NavigatorContext.Provider>
); );
} }

View File

@ -1,7 +1,7 @@
.nitro-navigator-result-lists { .nitro-navigator-result-lists {
height: 400px; height: 400px;
max-height: 400px; max-height: 400px;
overflow-y: scroll; overflow-y: auto;
} }
@import './result-list/NavigatorResultListView'; @import './result-list/NavigatorResultListView';

View File

@ -6,7 +6,7 @@ export function NavigatorResultListsView(props: NavigatorResultListsViewProps):
const { resultLists = null } = props; const { resultLists = null } = props;
return ( return (
<div className="nitro-navigator-result-lists px-3 pb-3"> <div className="nitro-navigator-result-lists w-100">
{ resultLists && resultLists.length && resultLists.map((resultList, index) => { resultLists && resultLists.length && resultLists.map((resultList, index) =>
{ {
return <NavigatorResultListView key={ index } resultList={ resultList } isLast={ index + 1 === resultLists.length } /> return <NavigatorResultListView key={ index } resultList={ resultList } isLast={ index + 1 === resultLists.length } />

View File

@ -37,17 +37,16 @@ export function NavigatorResultListView(props: NavigatorResultListViewProps): JS
} }
return ( return (
<div> <div className="p-2">
<div className="d-flex"> <div className="d-flex mb-2">
<div className=" mr-2" onClick={ toggleList }><i className={classNames({ 'fas': true, 'fa-plus': !isExtended, 'fa-minus': isExtended })}></i></div> <i className={ "fas " + classNames({ 'fa-plus': !isExtended, 'fa-minus': isExtended })} onClick={ toggleList }></i>
<div className="align-self-center w-100">{ LocalizeText(getListCode()) }</div> <div className="align-self-center w-100 ml-2">{ LocalizeText(getListCode()) }</div>
</div> </div>
{ isExtended && resultList && resultList.rooms.map((room, index) => { isExtended && resultList && resultList.rooms.map((room, index) =>
{ {
return <NavigatorResultView key={ index } result={ room } /> return <NavigatorResultView key={ index } result={ room } />
}) })
} }
{ !isLast && <hr className="mb-2" /> }
</div> </div>
); );
} }

View File

@ -1,3 +1,11 @@
.nitro-navigator-result:nth-child(even) { .nitro-navigator-result {
background: $secondary;
&:hover {
cursor: pointer;
}
&:nth-child(even) {
border-radius: $border-radius;
background: $secondary !important;
}
} }

View File

@ -39,24 +39,22 @@ export function NavigatorResultView(props: NavigatorResultViewProps): JSX.Elemen
return ( return (
<NavigatorContext.Consumer> <NavigatorContext.Consumer>
{ navigatorContext => { { navigatorContext => {
return <div className="nitro-navigator-result rounded mt-1 py-1 px-2" onClick={ () => navigatorContext.onTryVisitRoom(result) }> return <div className="d-flex flex-column justify-content-center align-items-center nitro-navigator-result" onClick={ () => navigatorContext.onTryVisitRoom(result) }>
<div className="d-flex"> <div className="d-flex justify-content-between w-100 px-2 py-1">
<div className="mr-2 align-self-center"> <div className="d-flex justify-content-center flex-grow-1 overflow-hidden">
<div className={'badge badge-sm ' + getUserCounterColor() }><i className="fas fa-user"></i> { result.userCount }</div> <div className={ "d-flex justify-content-center align-items-center badge text-center " + getUserCounterColor() }>
<i className="fas fa-user mr-1 small"></i> { result.userCount }
</div>
<div className="d-flex flex-column justify-content-center align-items-start flex-grow-1 px-2 overflow-hidden">
<span className="d-block text-truncate" style={ { maxWidth: '95%' } }>{ result.roomName }</span>
</div>
</div> </div>
<div className="w-100 align-self-center">{ result.roomName }</div> <div className="d-flex flex-row-reverse align-items-center">
{ result.doorMode !== RoomDataParser.OPEN_STATE && <i className="fas fa-info-circle small" onClick={ openInfo }></i>
<div className="ml-2 small align-self-center"> { result.habboGroupId > 0 && <i className="fas fa-users mr-2 small"></i> }
<i className={classNames({'fas': true, 'fa-lock': result.doorMode === RoomDataParser.DOORBELL_STATE, 'fa-key': result.doorMode === RoomDataParser.PASSWORD_STATE})}></i> { result.doorMode !== RoomDataParser.OPEN_STATE &&
</div> <i className={ "mr-2 fas small" + classNames( {'fa-lock': result.doorMode === RoomDataParser.DOORBELL_STATE, 'fa-key': result.doorMode === RoomDataParser.PASSWORD_STATE })}></i>
} }
{ result.habboGroupId > 0 &&
<div className="ml-2 small align-self-center">
<i className="fas fa-users"></i>
</div>
}
<div className="ml-2 small align-self-center" onClick={ openInfo }>
<i className="fas fa-info-circle"></i>
</div> </div>
</div> </div>
</div> </div>

View File

@ -8,7 +8,7 @@ export function NavigatorTabsView(props: NavigatorTabsViewProps): JSX.Element
return ( return (
<div className="d-flex flex-column p-3"> <div className="d-flex flex-column p-3">
{ topLevelContexts && topLevelContexts.length && { topLevelContexts && topLevelContexts.length &&
<div className="btn-group w-100 mb-2"> <div className="btn-group w-100">
{ topLevelContexts.map((context, index) => { topLevelContexts.map((context, index) =>
{ {
return <NavigatorTabView key={ index } context={ context } isActive={ context === topLevelContext } setTopLevelContext={ setTopLevelContext } /> return <NavigatorTabView key={ index } context={ context } isActive={ context === topLevelContext } setTopLevelContext={ setTopLevelContext } />

View File

@ -13,6 +13,6 @@ export function NavigatorTabView(props: NavigatorTabViewProps): JSX.Element
} }
return ( return (
<button type="button" className={classNames({ 'btn': true, 'btn-primary': true, 'active': isActive })} onClick={ onClick }>{ LocalizeText(('navigator.toplevelview.' + context.code)) }</button> <button type="button" className={ "btn btn-secondary btn-sm " + classNames({ 'active': isActive })} onClick={ onClick }>{ LocalizeText(('navigator.toplevelview.' + context.code)) }</button>
); );
} }

View File

@ -147,7 +147,7 @@ export function RoomHostView(props: RoomHostViewProps): JSX.Element
useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent); useRoomSessionManagerEvent(RoomSessionEvent.ENDED, onRoomSessionEvent);
return ( return (
<div className="nitro-room-host"> <div className="nitro-room-host w-100 h-100">
<RoomErrorHandler /> <RoomErrorHandler />
<RoomView events={ eventDispatcher } roomSession={ roomSession } /> <RoomView events={ eventDispatcher } roomSession={ roomSession } />
</div> </div>

View File

@ -1,14 +1 @@
.nitro-room {
z-index: 0;
width: 100%;
height: 100%;
.nitro-room-container {
.client-canvas {
position: absolute;
}
}
}
@import './widgets/Widgets'; @import './widgets/Widgets';

View File

@ -81,7 +81,7 @@ export function RoomView(props: RoomViewProps): JSX.Element
if(!roomSession) return null; if(!roomSession) return null;
return ( return (
<div className="nitro-room"> <div className="nitro-room w-100 h-100">
{ roomSession && <div id="room-view" className="nitro-room-container"></div> } { roomSession && <div id="room-view" className="nitro-room-container"></div> }
{ roomSession && events && roomCanvas && { roomSession && events && roomCanvas &&
createPortal(props.children, document.getElementById('room-view').appendChild(roomCanvas)) && createPortal(props.children, document.getElementById('room-view').appendChild(roomCanvas)) &&

View File

@ -9,7 +9,7 @@ export function FurnitureWidgetsView(props: FurnitureWidgetsViewProps): JSX.Elem
const { events } = props; const { events } = props;
return ( return (
<div className="nitro-room-widgets"> <div className="position-absolute nitro-room-widgets t-0 l-0">
<FurnitureHighScoreView events={ events } /> <FurnitureHighScoreView events={ events } />
<FurnitureMannequinView events={ events } /> <FurnitureMannequinView events={ events } />
<FurniturePresentView events={ events } /> <FurniturePresentView events={ events } />

View File

@ -1,6 +1,9 @@
.nitro-stickie { .nitro-stickie {
position: relative;
width: 185px; width: 185px;
height: 178px; height: 178px;
top: 25px;
left: 25px;
padding: 1px; padding: 1px;
.stickie-header { .stickie-header {
@ -42,6 +45,7 @@
outline: none; outline: none;
box-shadow: none; box-shadow: none;
resize: none; resize: none;
font-style: italic;
&:active { &:active {
border: 0; border: 0;