nitro-react/src/views/navigator/NavigatorView.tsx

150 lines
5.9 KiB
TypeScript
Raw Normal View History

import { NavigatorInitComposer, NavigatorSearchComposer, NavigatorSearchResultList, NavigatorTopLevelContext, RoomDataParser, RoomInfoComposer, RoomSessionEvent } from 'nitro-renderer';
import React, { MouseEvent, useCallback, useEffect, useState } from 'react';
import { GetRoomSessionManager } from '../../api';
2021-04-19 18:34:31 +02:00
import { NavigatorEvent } from '../../events';
import { DraggableWindow } from '../../hooks/draggable-window/DraggableWindow';
import { useRoomSessionManagerEvent } from '../../hooks/events/nitro/session/room-session-manager-event';
import { useUiEvent } from '../../hooks/events/ui/ui-event';
2021-04-21 05:36:39 +02:00
import { SendMessageHook } from '../../hooks/messages/message-event';
2021-04-19 18:34:31 +02:00
import { LocalizeText } from '../../utils/LocalizeText';
import { NavigatorLockView } from './lock/NavigatorLockView';
import { NavigatorLockViewStage } from './lock/NavigatorLockView.types';
2021-04-21 05:36:39 +02:00
import { NavigatorMessageHandler } from './NavigatorMessageHandler';
import { INavigatorContext, NavigatorViewProps } from './NavigatorView.types';
2021-04-21 07:50:28 +02:00
import { NavigatorResultListsView } from './result-lists/NavigatorResultListsView';
2021-04-19 18:34:31 +02:00
import { NavigatorTabsView } from './tabs/NavigatorTabsView';
2021-04-18 06:58:57 +02:00
export const NavigatorContext = React.createContext<INavigatorContext>(null);
2021-04-18 06:58:57 +02:00
export function NavigatorView(props: NavigatorViewProps): JSX.Element
{
const [ isVisible, setIsVisible ] = useState(false);
const [ isLoaded, setIsLoaded ] = useState(false);
const [ isLoading, setIsLoading ] = useState(false);
const [ isSearching, setIsSearching ] = useState(false);
const [ isLockVisible, setIsLockVisible ] = useState(false);
const [ lockStage, setLockStage ] = useState<NavigatorLockViewStage>(NavigatorLockViewStage.INIT);
const [ lastRoomVisited, setLastRoomVisited ] = useState<RoomDataParser>(null);
2021-04-19 18:34:31 +02:00
const [ topLevelContexts, setTopLevelContexts ] = useState<NavigatorTopLevelContext[]>(null);
const [ topLevelContext, setTopLevelContext ] = useState<NavigatorTopLevelContext>(null);
const [ searchResults, setSearchResults ] = useState<NavigatorSearchResultList[]>(null);
2021-04-19 18:34:31 +02:00
function hideNavigator(event: MouseEvent = null): void
{
if(event) event.preventDefault();
setIsVisible(false);
}
function hideLock(): void
{
setIsLockVisible(false);
setLockStage(NavigatorLockViewStage.INIT);
}
function showLock(stage: NavigatorLockViewStage = NavigatorLockViewStage.INIT)
{
setLockStage(stage);
setIsLockVisible(true);
}
function visitRoom(roomId: number, password: string = null): void
{
setIsLockVisible(false);
GetRoomSessionManager().createSession(roomId, password);
}
function tryVisitRoom(room: RoomDataParser): void
{
setIsLockVisible(false);
setLastRoomVisited(room);
SendMessageHook(new RoomInfoComposer(room.roomId, false, true));
}
2021-04-19 18:34:31 +02:00
const onNavigatorEvent = useCallback((event: NavigatorEvent) =>
{
switch(event.type)
{
case NavigatorEvent.SHOW_NAVIGATOR:
setIsVisible(true);
return;
case NavigatorEvent.TOGGLE_NAVIGATOR:
setIsVisible(value => !value);
return;
}
}, []);
2021-04-18 06:58:57 +02:00
2021-04-19 18:34:31 +02:00
const onRoomSessionEvent = useCallback((event: RoomSessionEvent) =>
{
switch(event.type)
{
case RoomSessionEvent.CREATED:
setIsVisible(false);
return;
}
}, []);
const search = useCallback((value: string = null) =>
{
if(!topLevelContext) return;
2021-04-21 05:36:39 +02:00
setIsSearching(true);
2021-04-19 18:34:31 +02:00
sendSearch(topLevelContext.code, '');
}, [ topLevelContext ]);
function sendSearch(code: string, query: string): void
{
SendMessageHook(new NavigatorSearchComposer(code, query));
}
useEffect(() =>
{
if(!isVisible) return;
if(!isLoaded)
{
SendMessageHook(new NavigatorInitComposer());
setIsLoaded(true);
}
else
{
search();
}
}, [ isVisible, isLoaded, search ]);
2021-04-21 05:36:39 +02:00
useEffect(() =>
{
setIsSearching(false);
}, [ searchResults ]);
2021-04-19 18:34:31 +02:00
useUiEvent(NavigatorEvent.SHOW_NAVIGATOR, onNavigatorEvent);
useUiEvent(NavigatorEvent.TOGGLE_NAVIGATOR, onNavigatorEvent);
useRoomSessionManagerEvent(RoomSessionEvent.CREATED, onRoomSessionEvent);
2021-04-18 06:58:57 +02:00
return (
2021-04-21 05:36:39 +02:00
<>
<NavigatorContext.Provider value={{ onTryVisitRoom: tryVisitRoom }}>
<NavigatorMessageHandler setTopLevelContext={ setTopLevelContext } setTopLevelContexts={ setTopLevelContexts } setSearchResults={ setSearchResults } showLock={ showLock } hideLock={ hideLock } />
{ isVisible && <DraggableWindow handle=".drag-handler">
<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="h6 m-0">{ LocalizeText((isLoading || isSearching) ? 'navigator.title.is.busy' : 'navigator.title') }</div>
<button type="button" className="close" onClick={ hideNavigator }>
<i className="fas fa-times"></i>
</button>
</div>
<NavigatorTabsView topLevelContext={ topLevelContext } topLevelContexts={ topLevelContexts } setTopLevelContext={ setTopLevelContext } />
<NavigatorResultListsView resultLists={ searchResults } />
2021-04-21 05:36:39 +02:00
</div>
</DraggableWindow> }
{ isLockVisible && <NavigatorLockView roomData={ lastRoomVisited } stage={ lockStage } onHideLock={ hideLock } onVisitRoom={ visitRoom }></NavigatorLockView> }
</NavigatorContext.Provider>
2021-04-21 05:36:39 +02:00
</>
2021-04-18 06:58:57 +02:00
);
}