mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-20 07:26:19 +00:00
🆙 Init V3
This commit is contained in:
@@ -0,0 +1,240 @@
|
||||
import { NitroCard } from '@layout/NitroCard';
|
||||
import { AddLinkEventTracker, ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RemoveLinkEventTracker, RoomSessionEvent } from '@nitrots/nitro-renderer';
|
||||
import { FC, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { FaPlus } from 'react-icons/fa';
|
||||
import { LocalizeText, SendMessageComposer, TryVisitRoom } from '../../api';
|
||||
import { useNavigator, useNitroEvent } from '../../hooks';
|
||||
import { NavigatorDoorStateView } from './views/NavigatorDoorStateView';
|
||||
import { NavigatorRoomCreatorView } from './views/NavigatorRoomCreatorView';
|
||||
import { NavigatorRoomInfoView } from './views/NavigatorRoomInfoView';
|
||||
import { NavigatorRoomLinkView } from './views/NavigatorRoomLinkView';
|
||||
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
|
||||
import { NavigatorSearchResultView } from './views/search/NavigatorSearchResultView';
|
||||
import { NavigatorSearchView } from './views/search/NavigatorSearchView';
|
||||
|
||||
export const NavigatorView: FC<{}> = props =>
|
||||
{
|
||||
const [ isVisible, setIsVisible ] = useState(false);
|
||||
const [ isReady, setIsReady ] = useState(false);
|
||||
const [ isCreatorOpen, setCreatorOpen ] = useState(false);
|
||||
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
|
||||
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
|
||||
const [ isLoading, setIsLoading ] = useState(false);
|
||||
const [ needsInit, setNeedsInit ] = useState(true);
|
||||
const [ needsSearch, setNeedsSearch ] = useState(false);
|
||||
const { searchResult = null, topLevelContext = null, topLevelContexts = null, navigatorData = null } = useNavigator();
|
||||
const pendingSearch = useRef<{ value: string, code: string }>(null);
|
||||
const elementRef = useRef<HTMLDivElement>();
|
||||
|
||||
useNitroEvent<RoomSessionEvent>(RoomSessionEvent.CREATED, event =>
|
||||
{
|
||||
setIsVisible(false);
|
||||
setCreatorOpen(false);
|
||||
});
|
||||
|
||||
const sendSearch = useCallback((searchValue: string, contextCode: string) =>
|
||||
{
|
||||
setCreatorOpen(false);
|
||||
|
||||
SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue));
|
||||
|
||||
setIsLoading(true);
|
||||
}, []);
|
||||
|
||||
const reloadCurrentSearch = useCallback(() =>
|
||||
{
|
||||
if(!isReady)
|
||||
{
|
||||
setNeedsSearch(true);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(pendingSearch.current)
|
||||
{
|
||||
sendSearch(pendingSearch.current.value, pendingSearch.current.code);
|
||||
|
||||
pendingSearch.current = null;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(searchResult)
|
||||
{
|
||||
sendSearch(searchResult.data, searchResult.code);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if(!topLevelContext) return;
|
||||
|
||||
sendSearch('', topLevelContext.code);
|
||||
}, [ isReady, searchResult, topLevelContext, sendSearch ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
const linkTracker: ILinkEventTracker = {
|
||||
linkReceived: (url: string) =>
|
||||
{
|
||||
const parts = url.split('/');
|
||||
|
||||
if(parts.length < 2) return;
|
||||
|
||||
switch(parts[1])
|
||||
{
|
||||
case 'show': {
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
return;
|
||||
}
|
||||
case 'hide':
|
||||
setIsVisible(false);
|
||||
return;
|
||||
case 'toggle': {
|
||||
if(isVisible)
|
||||
{
|
||||
setIsVisible(false);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
return;
|
||||
}
|
||||
case 'toggle-room-info':
|
||||
setRoomInfoOpen(value => !value);
|
||||
return;
|
||||
case 'toggle-room-link':
|
||||
setRoomLinkOpen(value => !value);
|
||||
return;
|
||||
case 'goto':
|
||||
if(parts.length <= 2) return;
|
||||
|
||||
switch(parts[2])
|
||||
{
|
||||
case 'home':
|
||||
if(navigatorData.homeRoomId <= 0) return;
|
||||
|
||||
TryVisitRoom(navigatorData.homeRoomId);
|
||||
break;
|
||||
default: {
|
||||
const roomId = parseInt(parts[2]);
|
||||
|
||||
TryVisitRoom(roomId);
|
||||
}
|
||||
}
|
||||
return;
|
||||
case 'create':
|
||||
setIsVisible(true);
|
||||
setCreatorOpen(true);
|
||||
return;
|
||||
case 'search':
|
||||
if(parts.length > 2)
|
||||
{
|
||||
const topLevelContextCode = parts[2];
|
||||
|
||||
let searchValue = '';
|
||||
|
||||
if(parts.length > 3) searchValue = parts[3];
|
||||
|
||||
pendingSearch.current = { value: searchValue, code: topLevelContextCode };
|
||||
|
||||
setIsVisible(true);
|
||||
setNeedsSearch(true);
|
||||
}
|
||||
return;
|
||||
}
|
||||
},
|
||||
eventUrlPrefix: 'navigator/'
|
||||
};
|
||||
|
||||
AddLinkEventTracker(linkTracker);
|
||||
|
||||
return () => RemoveLinkEventTracker(linkTracker);
|
||||
}, [ isVisible, navigatorData ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!searchResult) return;
|
||||
|
||||
setIsLoading(false);
|
||||
|
||||
if(elementRef && elementRef.current) elementRef.current.scrollTop = 0;
|
||||
}, [ searchResult ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible || !isReady || !needsSearch) return;
|
||||
|
||||
reloadCurrentSearch();
|
||||
|
||||
setNeedsSearch(false);
|
||||
}, [ isVisible, isReady, needsSearch, reloadCurrentSearch ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(isReady || !topLevelContext) return;
|
||||
|
||||
setIsReady(true);
|
||||
}, [ isReady, topLevelContext ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!isVisible || !needsInit) return;
|
||||
|
||||
SendMessageComposer(new NavigatorInitComposer());
|
||||
|
||||
setNeedsInit(false);
|
||||
}, [ isVisible, needsInit ]);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, (k: string, _arg_2: boolean = false, _arg_3: string = null) => SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k)));
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<>
|
||||
{ isVisible &&
|
||||
<NitroCard
|
||||
className="w-navigator-w h-navigator-h min-w-navigator-w min-h-navigator-h"
|
||||
uniqueKey="navigator">
|
||||
<NitroCard.Header
|
||||
headerText={ LocalizeText(isCreatorOpen ? 'navigator.createroom.title' : 'navigator.title') }
|
||||
onCloseClick={ event => setIsVisible(false) } />
|
||||
<NitroCard.Tabs>
|
||||
{ topLevelContexts && (topLevelContexts.length > 0) && topLevelContexts.map((context, index) =>
|
||||
{
|
||||
return (
|
||||
<NitroCard.TabItem
|
||||
key={ index }
|
||||
isActive={ ((topLevelContext === context) && !isCreatorOpen) }
|
||||
onClick={ event => sendSearch('', context.code) }>
|
||||
{ LocalizeText(('navigator.toplevelview.' + context.code)) }
|
||||
</NitroCard.TabItem>
|
||||
);
|
||||
}) }
|
||||
<NitroCard.TabItem
|
||||
isActive={ isCreatorOpen }
|
||||
onClick={ event => setCreatorOpen(true) }>
|
||||
<FaPlus className="fa-icon" />
|
||||
</NitroCard.TabItem>
|
||||
</NitroCard.Tabs>
|
||||
<NitroCard.Content isLoading={ isLoading }>
|
||||
{ !isCreatorOpen &&
|
||||
<>
|
||||
<NavigatorSearchView sendSearch={ sendSearch } />
|
||||
<div ref={ elementRef } className="flex flex-col overflow-auto gap-2">
|
||||
{ (searchResult && searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
|
||||
</div>
|
||||
</> }
|
||||
{ isCreatorOpen && <NavigatorRoomCreatorView /> }
|
||||
</NitroCard.Content>
|
||||
</NitroCard> }
|
||||
<NavigatorDoorStateView />
|
||||
{ isRoomInfoOpen && <NavigatorRoomInfoView onCloseClick={ () => setRoomInfoOpen(false) } /> }
|
||||
{ isRoomLinkOpen && <NavigatorRoomLinkView onCloseClick={ () => setRoomLinkOpen(false) } /> }
|
||||
<NavigatorRoomSettingsView />
|
||||
</>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user