Navigator updates

This commit is contained in:
Bill 2022-03-19 00:26:57 -04:00
parent 7a9fc3df34
commit c2ddd60ff0
23 changed files with 482 additions and 797 deletions

View File

@ -14,7 +14,6 @@
"@fortawesome/fontawesome-svg-core": "^6.1.0", "@fortawesome/fontawesome-svg-core": "^6.1.0",
"@fortawesome/free-solid-svg-icons": "^6.1.0", "@fortawesome/free-solid-svg-icons": "^6.1.0",
"@fortawesome/react-fontawesome": "^0.1.17", "@fortawesome/react-fontawesome": "^0.1.17",
"@nitrots/nitro-renderer": "^1.1.13",
"animate.css": "^4.1.1", "animate.css": "^4.1.1",
"classnames": "^2.3.1", "classnames": "^2.3.1",
"cross-env": "^7.0.3", "cross-env": "^7.0.3",

View File

@ -23,7 +23,10 @@
<script> <script>
const NitroConfig = { const NitroConfig = {
"config.urls": [ '/renderer-config.json', '/ui-config.json' ], "config.urls": [ '/renderer-config.json', '/ui-config.json' ],
"sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null) "sso.ticket": (new URLSearchParams(window.location.search).get('sso') || null),
"forward.type": (new URLSearchParams(window.location.search).get('room') ? 2 : -1),
"forward.id": (new URLSearchParams(window.location.search).get('room') || 0),
"friend.id": (new URLSearchParams(window.location.search).get('friend') || 0),
}; };
</script> </script>
</body> </body>

View File

@ -171,7 +171,7 @@ export const CatalogPurchaseWidgetView: FC<CatalogPurchaseWidgetViewProps> = pro
switch(purchaseState) switch(purchaseState)
{ {
case CatalogPurchaseState.CONFIRM: case CatalogPurchaseState.CONFIRM:
return <Button variant='warning' onClick={ event => purchase() }>{ LocalizeText('catalog.marketplace.confirm_title') }</Button>; return <Button variant="warning" onClick={ event => purchase() }>{ LocalizeText('catalog.marketplace.confirm_title') }</Button>;
case CatalogPurchaseState.PURCHASE: case CatalogPurchaseState.PURCHASE:
return <Button disabled><LayoutLoadingSpinnerView /></Button>; return <Button disabled><LayoutLoadingSpinnerView /></Button>;
case CatalogPurchaseState.FAILED: case CatalogPurchaseState.FAILED:

View File

@ -1,15 +1,34 @@
import { createContext, Dispatch, FC, ProviderProps, useContext } from 'react'; import { NavigatorCategoryDataParser, NavigatorSearchResultSet, NavigatorTopLevelContext } from '@nitrots/nitro-renderer';
import { INavigatorAction, INavigatorState } from './reducers/NavigatorReducer'; import { createContext, Dispatch, FC, MutableRefObject, ProviderProps, SetStateAction, useContext } from 'react';
import { NavigatorData } from './common/NavigatorData';
interface INavigatorContext interface INavigatorContext
{ {
navigatorState: INavigatorState; categories: NavigatorCategoryDataParser[];
dispatchNavigatorState: Dispatch<INavigatorAction>; setCategories: Dispatch<SetStateAction<NavigatorCategoryDataParser[]>>;
topLevelContext: NavigatorTopLevelContext;
setTopLevelContext: Dispatch<SetStateAction<NavigatorTopLevelContext>>;
topLevelContexts: NavigatorTopLevelContext[];
setTopLevelContexts: Dispatch<SetStateAction<NavigatorTopLevelContext[]>>;
navigatorData: NavigatorData;
setNavigatorData: Dispatch<SetStateAction<NavigatorData>>;
searchResult: NavigatorSearchResultSet;
setSearchResult: Dispatch<SetStateAction<NavigatorSearchResultSet>>;
lastSearchValue: MutableRefObject<string>;
} }
const NavigatorContext = createContext<INavigatorContext>({ const NavigatorContext = createContext<INavigatorContext>({
navigatorState: null, categories: null,
dispatchNavigatorState: null setCategories: null,
topLevelContext: null,
setTopLevelContext: null,
topLevelContexts: null,
setTopLevelContexts: null,
navigatorData: null,
setNavigatorData: null,
searchResult: null,
setSearchResult: null,
lastSearchValue: null
}); });
export const NavigatorContextProvider: FC<ProviderProps<INavigatorContext>> = props => export const NavigatorContextProvider: FC<ProviderProps<INavigatorContext>> = props =>

View File

@ -1,14 +1,38 @@
import { CantConnectMessageParser, GenericErrorEvent, GetGuestRoomResultEvent, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, UserInfoEvent } from '@nitrots/nitro-renderer'; import { CantConnectMessageParser, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomResultEvent, HabboWebTools, LegacyExternalInterface, NavigatorCategoriesComposer, NavigatorCategoriesEvent, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSearchEvent, NavigatorSettingsComposer, RoomCreatedEvent, RoomDataParser, RoomDoorbellAcceptedEvent, RoomDoorbellEvent, RoomDoorbellRejectedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomInfoComposer, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback } from 'react'; import { FC, useCallback } from 'react';
import { CreateRoomSession, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, VisitDesktop } from '../../api'; import { CreateLinkEvent, CreateRoomSession, GetConfiguration, GetSessionDataManager, LocalizeText, NotificationAlertType, NotificationUtilities, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api';
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events'; import { UpdateDoorStateEvent } from '../../events';
import { DispatchUiEvent, UseMessageEventHook } from '../../hooks'; import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../hooks';
import { useNavigatorContext } from './NavigatorContext'; import { useNavigatorContext } from './NavigatorContext';
import { NavigatorActions } from './reducers/NavigatorReducer';
export const NavigatorMessageHandler: FC<{}> = props => export const NavigatorMessageHandler: FC<{}> = props =>
{ {
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext(); const { setCategories = null, setTopLevelContext = null, topLevelContexts = null, setTopLevelContexts = null, setNavigatorData = null, setSearchResult = null } = useNavigatorContext();
const onRoomSettingsUpdatedEvent = useCallback((event: RoomSettingsUpdatedEvent) =>
{
const parser = event.getParser();
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, false));
}, []);
UseMessageEventHook(RoomSettingsUpdatedEvent, onRoomSettingsUpdatedEvent);
// const onCanCreateRoomEventEvent = useCallback((event: CanCreateRoomEventEvent) =>
// {
// const parser = event.getParser();
// if(parser.canCreate)
// {
// // show room event cvreate
// return;
// }
// NotificationUtilities.simpleAlert(LocalizeText(`navigator.cannotcreateevent.error.${ parser.errorCode }`), null, null, null, LocalizeText('navigator.cannotcreateevent.title'));
// }, []);
// UseMessageEventHook(CanCreateRoomEventEvent, onCanCreateRoomEventEvent);
const onUserInfoEvent = useCallback((event: UserInfoEvent) => const onUserInfoEvent = useCallback((event: UserInfoEvent) =>
{ {
@ -16,32 +40,51 @@ export const NavigatorMessageHandler: FC<{}> = props =>
SendMessageComposer(new NavigatorSettingsComposer()); SendMessageComposer(new NavigatorSettingsComposer());
}, []); }, []);
const onUserPermissionsEvent = useCallback((event: UserPermissionsEvent) =>
{
const parser = event.getParser();
setNavigatorData(prevValue =>
{
const newValue = { ...prevValue };
newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR);
newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY);
return newValue;
});
}, [ setNavigatorData ]);
const onRoomForwardEvent = useCallback((event: RoomForwardEvent) => const onRoomForwardEvent = useCallback((event: RoomForwardEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, true)); TryVisitRoom(parser.roomId);
}, []); }, []);
const onRoomEntryInfoMessageEvent = useCallback((event: RoomEntryInfoMessageEvent) => const onRoomEntryInfoMessageEvent = useCallback((event: RoomEntryInfoMessageEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
const roomInfoData = navigatorState.roomInfoData; setNavigatorData(prevValue =>
roomInfoData.currentRoomOwner = parser.isOwner; {
roomInfoData.currentRoomId = parser.roomId; const newValue = { ...prevValue };
dispatchNavigatorState({ newValue.enteredGuestRoom = null;
type: NavigatorActions.SET_ROOM_INFO_DATA, newValue.currentRoomOwner = parser.isOwner;
payload: { newValue.currentRoomId = parser.roomId;
roomInfoData: roomInfoData
} return newValue;
}); });
// close room info
// close room settings
// close room filter
SendMessageComposer(new RoomInfoComposer(parser.roomId, true, false)); SendMessageComposer(new RoomInfoComposer(parser.roomId, true, false));
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]); if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]);
}, [ navigatorState, dispatchNavigatorState ]); }, [ setNavigatorData ]);
const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) => const onGetGuestRoomResultEvent = useCallback((event: GetGuestRoomResultEvent) =>
{ {
@ -49,15 +92,29 @@ export const NavigatorMessageHandler: FC<{}> = props =>
if(parser.roomEnter) if(parser.roomEnter)
{ {
const roomInfoData = navigatorState.roomInfoData; setNavigatorData(prevValue =>
roomInfoData.enteredGuestRoom = parser.data; {
const newValue = { ...prevValue };
dispatchNavigatorState({ newValue.enteredGuestRoom = parser.data;
type: NavigatorActions.SET_ROOM_INFO_DATA, //newValue.currentRoomIsStaffPick = parser.staffPick;
payload: {
roomInfoData: roomInfoData const isCreated = (newValue.createdFlatId === parser.data.roomId);
}
}); if(!isCreated && parser.data.displayRoomEntryAd)
{
if(GetConfiguration<boolean>('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd();
}
newValue.createdFlatId = 0;
if(newValue.enteredGuestRoom && (newValue.enteredGuestRoom.habboGroupId > 0))
{
// close event info
}
return newValue;
});
} }
else if(parser.roomForward) else if(parser.roomForward)
{ {
@ -74,21 +131,23 @@ export const NavigatorMessageHandler: FC<{}> = props =>
} }
} }
// if((parser.data.doorMode === RoomDataParser.NOOB_STATE) && !GetSessionDataManager().isAmbassador && !GetSessionDataManager().isRealNoob && !GetSessionDataManager().isModerator) return;
CreateRoomSession(parser.data.roomId); CreateRoomSession(parser.data.roomId);
} }
else else
{ {
const roomInfoData = navigatorState.roomInfoData; setNavigatorData(prevValue =>
roomInfoData.enteredGuestRoom = parser.data; {
const newValue = { ...prevValue };
dispatchNavigatorState({ newValue.enteredGuestRoom = parser.data;
type: NavigatorActions.SET_ROOM_INFO_DATA, //newValue.currentRoomIsStaffPick = parser.staffPick;
payload: {
roomInfoData: roomInfoData return newValue;
} });
});
} }
}, [ dispatchNavigatorState, navigatorState ]); }, [ setNavigatorData ]);
const onRoomScoreEvent = useCallback((event: RoomScoreEvent) => const onRoomScoreEvent = useCallback((event: RoomScoreEvent) =>
{ {
@ -141,37 +200,57 @@ export const NavigatorMessageHandler: FC<{}> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
dispatchNavigatorState({ BatchUpdates(() =>
type: NavigatorActions.SET_TOP_LEVEL_CONTEXTS, {
payload: { setTopLevelContexts(parser.topLevelContexts);
topLevelContexts: parser.topLevelContexts setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
}
}); });
}, [ dispatchNavigatorState ]); }, [ setTopLevelContexts, setTopLevelContext ]);
const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) => const onNavigatorSearchEvent = useCallback((event: NavigatorSearchEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
dispatchNavigatorState({ BatchUpdates(() =>
type: NavigatorActions.SET_SEARCH_RESULT, {
payload: { setTopLevelContext(prevValue =>
searchResult: parser.result {
} let newValue = prevValue;
if(!newValue) newValue = ((topLevelContexts && topLevelContexts.length && topLevelContexts[0]) || null);
if(!newValue) return null;
if((parser.result.code !== newValue.code) && topLevelContexts && topLevelContexts.length)
{
for(const context of topLevelContexts)
{
if(context.code !== parser.result.code) continue;
newValue = context;
}
}
for(const context of topLevelContexts)
{
if(context.code !== parser.result.code) continue;
newValue = context;
}
return newValue;
});
setSearchResult(parser.result);
}); });
}, [ dispatchNavigatorState ]); }, [ topLevelContexts, setTopLevelContext, setSearchResult ]);
const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) => const onNavigatorCategoriesEvent = useCallback((event: NavigatorCategoriesEvent) =>
{ {
const parser = event.getParser(); const parser = event.getParser();
dispatchNavigatorState({ setCategories(parser.categories);
type: NavigatorActions.SET_CATEGORIES, }, [ setCategories ]);
payload: {
categories: parser.categories
}
});
}, [ dispatchNavigatorState ]);
const onRoomCreatedEvent = useCallback((event: RoomCreatedEvent) => const onRoomCreatedEvent = useCallback((event: RoomCreatedEvent) =>
{ {
@ -184,20 +263,63 @@ export const NavigatorMessageHandler: FC<{}> = props =>
{ {
const parser = event.getParser(); const parser = event.getParser();
dispatchNavigatorState({ let prevSettingsReceived = false;
type: NavigatorActions.SET_HOME_ROOM_ID,
payload: { setNavigatorData(prevValue =>
homeRoomId: parser.homeRoomId {
prevSettingsReceived = prevValue.settingsReceived;
const newValue = { ...prevValue };
newValue.homeRoomId = parser.homeRoomId;
newValue.settingsReceived = true;
return newValue;
});
if(prevSettingsReceived)
{
// refresh room info window
return;
}
let forwardType = -1;
let forwardId = -1;
if(GetConfiguration<string>('friend.id') !== undefined)
{
forwardType = 0;
SendMessageComposer(new FollowFriendMessageComposer(parseInt(GetConfiguration<string>('friend.id'))));
}
if((GetConfiguration<number>('forward.type') !== undefined) && (GetConfiguration<number>('forward.id') !== undefined))
{
forwardType = parseInt(GetConfiguration<string>('forward.type'));
forwardId = parseInt(GetConfiguration<string>('forward.id'))
}
if(forwardType === 2)
{
TryVisitRoom(forwardId);
}
else if((forwardType === -1) && (parser.roomIdToEnter > 0))
{
CreateLinkEvent('navigator/close');
CreateRoomSession(parser.roomIdToEnter);
if(parser.roomIdToEnter !== parser.homeRoomId)
{
CreateLinkEvent('navigator/close');
CreateRoomSession(parser.roomIdToEnter);
} }
}); else
}, [ dispatchNavigatorState ]); {
CreateLinkEvent('navigator/close');
const onRoomSettingsUpdatedEvent = useCallback((event: RoomSettingsUpdatedEvent) => CreateRoomSession(parser.homeRoomId);
{ }
const parser = event.getParser(); }
}, [ setNavigatorData ]);
SendMessageComposer(new RoomInfoComposer(parser.roomId, false, false));
}, []);
const onRoomEnterErrorEvent = useCallback((event: RoomEnterErrorEvent) => const onRoomEnterErrorEvent = useCallback((event: RoomEnterErrorEvent) =>
{ {
@ -226,12 +348,13 @@ export const NavigatorMessageHandler: FC<{}> = props =>
VisitDesktop(); VisitDesktop();
}, []); }, []);
const onRoomCreatorEvent = useCallback((event: RoomEnterErrorEvent) => const onRoomCreatorEvent = useCallback((event: NavigatorOpenRoomCreatorEvent) =>
{ {
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.SHOW_ROOM_CREATOR)); CreateLinkEvent('navigator/show');
},[]); }, []);
UseMessageEventHook(UserInfoEvent, onUserInfoEvent); UseMessageEventHook(UserInfoEvent, onUserInfoEvent);
UseMessageEventHook(UserPermissionsEvent, onUserPermissionsEvent);
UseMessageEventHook(RoomForwardEvent, onRoomForwardEvent); UseMessageEventHook(RoomForwardEvent, onRoomForwardEvent);
UseMessageEventHook(RoomEntryInfoMessageEvent, onRoomEntryInfoMessageEvent); UseMessageEventHook(RoomEntryInfoMessageEvent, onRoomEntryInfoMessageEvent);
UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent); UseMessageEventHook(GetGuestRoomResultEvent, onGetGuestRoomResultEvent);
@ -245,7 +368,6 @@ export const NavigatorMessageHandler: FC<{}> = props =>
UseMessageEventHook(NavigatorCategoriesEvent, onNavigatorCategoriesEvent); UseMessageEventHook(NavigatorCategoriesEvent, onNavigatorCategoriesEvent);
UseMessageEventHook(RoomCreatedEvent, onRoomCreatedEvent); UseMessageEventHook(RoomCreatedEvent, onRoomCreatedEvent);
UseMessageEventHook(NavigatorHomeRoomEvent, onNavigatorHomeRoomEvent); UseMessageEventHook(NavigatorHomeRoomEvent, onNavigatorHomeRoomEvent);
UseMessageEventHook(RoomSettingsUpdatedEvent, onRoomSettingsUpdatedEvent);
UseMessageEventHook(RoomEnterErrorEvent, onRoomEnterErrorEvent); UseMessageEventHook(RoomEnterErrorEvent, onRoomEnterErrorEvent);
UseMessageEventHook(NavigatorOpenRoomCreatorEvent, onRoomCreatorEvent); UseMessageEventHook(NavigatorOpenRoomCreatorEvent, onRoomCreatorEvent);

View File

@ -1,13 +1,13 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorInitComposer, NavigatorSearchComposer, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer'; import { ConvertGlobalRoomIdMessageComposer, HabboWebTools, ILinkEventTracker, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorInitComposer, NavigatorSearchComposer, NavigatorSearchResultSet, NavigatorTopLevelContext, RoomDataParser, RoomSessionEvent } from '@nitrots/nitro-renderer';
import { FC, useCallback, useEffect, useMemo, useReducer, useState } from 'react'; import { FC, useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { AddEventLinkTracker, CreateLinkEvent, GoToDesktop, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api'; import { AddEventLinkTracker, GoToDesktop, LocalizeText, RemoveLinkEventTracker, SendMessageComposer, TryVisitRoom } from '../../api';
import { Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common'; import { Column, NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../common';
import { NavigatorEvent, UpdateDoorStateEvent } from '../../events'; import { UpdateDoorStateEvent } from '../../events';
import { BatchUpdates, UseMountEffect, UseRoomSessionManagerEvent, UseUiEvent } from '../../hooks'; import { BatchUpdates, UseRoomSessionManagerEvent, UseUiEvent } from '../../hooks';
import { NavigatorData } from './common/NavigatorData';
import { NavigatorContextProvider } from './NavigatorContext'; import { NavigatorContextProvider } from './NavigatorContext';
import { NavigatorMessageHandler } from './NavigatorMessageHandler'; import { NavigatorMessageHandler } from './NavigatorMessageHandler';
import { initialNavigator, NavigatorActions, NavigatorReducer } from './reducers/NavigatorReducer';
import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView'; import { NavigatorRoomCreatorView } from './views/creator/NavigatorRoomCreatorView';
import { NavigatorRoomDoorbellView } from './views/room-doorbell/NavigatorRoomDoorbellView'; import { NavigatorRoomDoorbellView } from './views/room-doorbell/NavigatorRoomDoorbellView';
import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView'; import { NavigatorRoomInfoView } from './views/room-info/NavigatorRoomInfoView';
@ -15,7 +15,7 @@ import { NavigatorRoomLinkView } from './views/room-link/NavigatorRoomLinkView';
import { NavigatorRoomPasswordView } from './views/room-password/NavigatorRoomPasswordView'; import { NavigatorRoomPasswordView } from './views/room-password/NavigatorRoomPasswordView';
import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView'; import { NavigatorRoomSettingsView } from './views/room-settings/NavigatorRoomSettingsView';
import { NavigatorSearchResultView } from './views/search-result/NavigatorSearchResultView'; import { NavigatorSearchResultView } from './views/search-result/NavigatorSearchResultView';
import { LAST_SEARCH, NavigatorSearchView } from './views/search/NavigatorSearchView'; import { NavigatorSearchView } from './views/search/NavigatorSearchView';
export const NavigatorView: FC<{}> = props => export const NavigatorView: FC<{}> = props =>
{ {
@ -23,42 +23,25 @@ export const NavigatorView: FC<{}> = props =>
const [ isCreatorOpen, setCreatorOpen ] = useState(false); const [ isCreatorOpen, setCreatorOpen ] = useState(false);
const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false); const [ isRoomInfoOpen, setRoomInfoOpen ] = useState(false);
const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false); const [ isRoomLinkOpen, setRoomLinkOpen ] = useState(false);
const [ needsUpdate, setNeedsUpdate ] = useState(true);
const [ categories, setCategories ] = useState<NavigatorCategoryDataParser[]>(null);
const [ topLevelContext, setTopLevelContext ] = useState<NavigatorTopLevelContext>(null);
const [ topLevelContexts, setTopLevelContexts ] = useState<NavigatorTopLevelContext[]>(null);
const [ navigatorData, setNavigatorData ] = useState<NavigatorData>({
settingsReceived: false,
homeRoomId: 0,
enteredGuestRoom: null,
currentRoomOwner: false,
currentRoomId: 0,
currentRoomIsStaffPick: false,
createdFlatId: 0,
avatarId: 0,
roomPicker: false,
eventMod: false
});
const [ searchResult, setSearchResult ] = useState<NavigatorSearchResultSet>(null);
const [ pendingDoorState, setPendingDoorState ] = useState<{ roomData: RoomDataParser, state: string }>(null); const [ pendingDoorState, setPendingDoorState ] = useState<{ roomData: RoomDataParser, state: string }>(null);
const [ navigatorState, dispatchNavigatorState ] = useReducer(NavigatorReducer, initialNavigator); const lastSearchValue = useRef<string>();
const { needsNavigatorUpdate = true, topLevelContext = null, topLevelContexts = null, homeRoomId } = navigatorState;
const onNavigatorEvent = useCallback((event: NavigatorEvent) =>
{
switch(event.type)
{
case NavigatorEvent.SHOW_NAVIGATOR:
setIsVisible(true);
return;
case NavigatorEvent.HIDE_NAVIGATOR:
setIsVisible(false);
return;
case NavigatorEvent.TOGGLE_NAVIGATOR:
setIsVisible(value => !value);
return;
case NavigatorEvent.TOGGLE_ROOM_INFO:
setRoomInfoOpen(value => !value);
return;
case NavigatorEvent.TOGGLE_ROOM_LINK:
setRoomLinkOpen(value => !value);
return;
case NavigatorEvent.SHOW_ROOM_CREATOR:
setIsVisible(true);
setCreatorOpen(true);
return;
}
}, []);
UseUiEvent(NavigatorEvent.SHOW_NAVIGATOR, onNavigatorEvent);
UseUiEvent(NavigatorEvent.HIDE_NAVIGATOR, onNavigatorEvent);
UseUiEvent(NavigatorEvent.TOGGLE_NAVIGATOR, onNavigatorEvent);
UseUiEvent(NavigatorEvent.TOGGLE_ROOM_INFO, onNavigatorEvent);
UseUiEvent(NavigatorEvent.TOGGLE_ROOM_LINK, onNavigatorEvent);
UseUiEvent(NavigatorEvent.SHOW_ROOM_CREATOR, onNavigatorEvent);
const onUpdateDoorStateEvent = useCallback((event: UpdateDoorStateEvent) => const onUpdateDoorStateEvent = useCallback((event: UpdateDoorStateEvent) =>
{ {
@ -108,8 +91,11 @@ export const NavigatorView: FC<{}> = props =>
switch(event.type) switch(event.type)
{ {
case RoomSessionEvent.CREATED: case RoomSessionEvent.CREATED:
setIsVisible(false); BatchUpdates(() =>
setCreatorOpen(false); {
setIsVisible(false);
setCreatorOpen(false);
});
return; return;
} }
}, []); }, []);
@ -119,15 +105,21 @@ export const NavigatorView: FC<{}> = props =>
const sendSearch = useCallback((searchValue: string, contextCode: string) => const sendSearch = useCallback((searchValue: string, contextCode: string) =>
{ {
setCreatorOpen(false); setCreatorOpen(false);
SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue)); SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue));
}, []); }, []);
const goToHomeRoom = useCallback(() => const closePendingDoorState = useCallback((state: string) =>
{ {
if(homeRoomId <= 0) return; if(state !== null)
{
TryVisitRoom(homeRoomId); setPendingDoorState(prevValue =>
}, [ homeRoomId ]); {
return { roomData: prevValue.roomData, state };
});
}
else setPendingDoorState(null);
}, []);
const linkReceived = useCallback((url: string) => const linkReceived = useCallback((url: string) =>
{ {
@ -137,19 +129,35 @@ export const NavigatorView: FC<{}> = props =>
switch(parts[1]) switch(parts[1])
{ {
case 'show':
setIsVisible(true);
return;
case 'hide':
setIsVisible(false);
return;
case 'toggle':
setIsVisible(prevValue => !prevValue);
return;
case 'toggle-room-info':
setRoomInfoOpen(value => !value);
return;
case 'toggle-room-link':
setRoomLinkOpen(value => !value);
return;
case 'goto': case 'goto':
if(parts.length > 2) if(parts.length <= 2) return;
{
switch(parts[2])
{
case 'home':
goToHomeRoom();
break;
default: {
const roomId = parseInt(parts[2]);
TryVisitRoom(roomId); switch(parts[2])
} {
case 'home':
if(navigatorData.homeRoomId <= 0) return;
TryVisitRoom(navigatorData.homeRoomId);
break;
default: {
const roomId = parseInt(parts[2]);
TryVisitRoom(roomId);
} }
} }
return; return;
@ -174,19 +182,7 @@ export const NavigatorView: FC<{}> = props =>
} }
return; return;
} }
}, [ goToHomeRoom, sendSearch ]); }, [ navigatorData.homeRoomId, sendSearch ]);
const closePendingDoorState = useCallback((state: string) =>
{
if(state !== null)
{
setPendingDoorState(prevValue =>
{
return { roomData: prevValue.roomData, state };
});
}
else setPendingDoorState(null);
}, []);
useEffect(() => useEffect(() =>
{ {
@ -198,52 +194,49 @@ export const NavigatorView: FC<{}> = props =>
AddEventLinkTracker(linkTracker); AddEventLinkTracker(linkTracker);
return () => RemoveLinkEventTracker(linkTracker); return () => RemoveLinkEventTracker(linkTracker);
}, [ linkReceived]); }, [ linkReceived ]);
const enterRoomWebRequest = useCallback((k: string, _arg_2:boolean=false, _arg_3:string=null) => // useEffect(() =>
{ // {
SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k)); // if(!isVisible) return;
}, []);
UseMountEffect(() => // sendSearch(lastSearch)
{ // }, [ isVisible ]);
LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, enterRoomWebRequest);
});
useEffect(() => useEffect(() =>
{ {
if(!needsNavigatorUpdate) return; if(!needsUpdate) return;
dispatchNavigatorState({
type: NavigatorActions.SET_NEEDS_UPDATE,
payload: {
flag: false
}
});
SendMessageComposer(new NavigatorInitComposer()); SendMessageComposer(new NavigatorInitComposer());
}, [ needsNavigatorUpdate ]);
setNeedsUpdate(false);
}, [ needsUpdate ]);
useEffect(() => useEffect(() =>
{ {
if(!isVisible || !topLevelContext) return; LegacyExternalInterface.addCallback(HabboWebTools.OPENROOM, (k: string, _arg_2: boolean = false, _arg_3: string = null) => SendMessageComposer(new ConvertGlobalRoomIdMessageComposer(k)));
}, []);
sendSearch('', topLevelContext.code); // useEffect(() =>
}, [isVisible, sendSearch, topLevelContext]) // {
// if(!isVisible || !topLevelContext) return;
useEffect(() => // sendSearch('', topLevelContext.code);
{ // }, [ isVisible, sendSearch, topLevelContext ])
if(!topLevelContexts || !topLevelContexts.length) return;
sendSearch('', topLevelContexts[0].code); // useEffect(() =>
}, [ topLevelContexts, sendSearch ]); // {
// if(!topLevelContexts || !topLevelContexts.length) return;
useEffect(() => // sendSearch('', topLevelContexts[0].code);
{ // }, [ topLevelContexts, sendSearch ]);
if(!isVisible || !LAST_SEARCH || !LAST_SEARCH.length) return;
CreateLinkEvent(`navigator/search/${ LAST_SEARCH }`); // useEffect(() =>
}, [ isVisible ]); // {
// if(!isVisible || !LAST_SEARCH || !LAST_SEARCH.length) return;
// CreateLinkEvent(`navigator/search/${ LAST_SEARCH }`);
// }, [ isVisible ]);
const getRoomDoorState = useMemo(() => const getRoomDoorState = useMemo(() =>
{ {
@ -264,7 +257,7 @@ export const NavigatorView: FC<{}> = props =>
}, [ pendingDoorState, closePendingDoorState ]); }, [ pendingDoorState, closePendingDoorState ]);
return ( return (
<NavigatorContextProvider value={ { navigatorState, dispatchNavigatorState } }> <NavigatorContextProvider value={ { categories, setCategories, topLevelContext, setTopLevelContext, topLevelContexts, setTopLevelContexts, navigatorData, setNavigatorData, searchResult, setSearchResult, lastSearchValue } }>
<NavigatorMessageHandler /> <NavigatorMessageHandler />
{ getRoomDoorState } { getRoomDoorState }
{ isVisible && { isVisible &&
@ -288,7 +281,7 @@ export const NavigatorView: FC<{}> = props =>
<> <>
<NavigatorSearchView sendSearch={ sendSearch } /> <NavigatorSearchView sendSearch={ sendSearch } />
<Column overflow="auto"> <Column overflow="auto">
{ (navigatorState.searchResult && navigatorState.searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) } { (searchResult && searchResult.results.map((result, index) => <NavigatorSearchResultView key={ index } searchResult={ result } />)) }
</Column> </Column>
</> } </> }
{ isCreatorOpen && <NavigatorRoomCreatorView /> } { isCreatorOpen && <NavigatorRoomCreatorView /> }

View File

@ -0,0 +1,15 @@
import { RoomDataParser } from '@nitrots/nitro-renderer';
export interface NavigatorData
{
homeRoomId: number;
settingsReceived: boolean;
enteredGuestRoom: RoomDataParser;
currentRoomOwner: boolean;
currentRoomId: number;
currentRoomIsStaffPick: boolean;
createdFlatId: number;
avatarId: number;
roomPicker: boolean;
eventMod: boolean;
}

View File

@ -33,7 +33,7 @@ export default class RoomSettingsData
public muteState: number; public muteState: number;
public kickState: number; public kickState: number;
public banState: number; public banState: number;
public bannedUsers: Map<number, string>; public bannedUsers: any[];
public selectedUserToUnban: number; public selectedUserToUnban: number;
constructor(parser: RoomSettingsParser) constructor(parser: RoomSettingsParser)
@ -71,6 +71,6 @@ export default class RoomSettingsData
this.muteState = parser.moderationSettings.allowMute; this.muteState = parser.moderationSettings.allowMute;
this.kickState = parser.moderationSettings.allowKick; this.kickState = parser.moderationSettings.allowKick;
this.banState = parser.moderationSettings.allowBan; this.banState = parser.moderationSettings.allowBan;
this.bannedUsers = new Map<number, string>(); this.bannedUsers = [];
} }
} }

View File

@ -1,11 +1,10 @@
export function GetMaxVisitorsList(): number[] const BuildMaxVisitorsList = () =>
{ {
const list: number[] = []; const list: number[] = [];
for(let i = 10; i <= 100; i = i + 10) for(let i = 10; i <= 100; i = i + 10) list.push(i);
{
list.push(i);
}
return list; return list;
} }
export const GetMaxVisitorsList = BuildMaxVisitorsList();

View File

@ -1,115 +0,0 @@
import { NavigatorCategoryDataParser, NavigatorSearchResultSet, NavigatorTopLevelContext } from '@nitrots/nitro-renderer';
import { Reducer } from 'react';
import { RoomInfoData } from '../common/RoomInfoData';
export interface INavigatorState
{
needsNavigatorUpdate: boolean;
topLevelContext: NavigatorTopLevelContext;
topLevelContexts: NavigatorTopLevelContext[];
searchResult: NavigatorSearchResultSet;
categories: NavigatorCategoryDataParser[];
roomInfoData: RoomInfoData;
homeRoomId: number;
}
export interface INavigatorAction
{
type: string;
payload: {
flag?: boolean;
topLevelContext?: NavigatorTopLevelContext;
topLevelContexts?: NavigatorTopLevelContext[];
searchResult?: NavigatorSearchResultSet;
categories?: NavigatorCategoryDataParser[];
roomInfoData?: RoomInfoData;
homeRoomId?: number;
}
}
export class NavigatorActions
{
public static SET_NEEDS_UPDATE: string = 'NA_SET_NEEDS_UPDATE';
public static SET_TOP_LEVEL_CONTEXT: string = 'NA_SET_TOP_LEVEL_CONTEXT';
public static SET_TOP_LEVEL_CONTEXTS: string = 'NA_SET_TOP_LEVEL_CONTEXTS';
public static SET_SEARCH_RESULT: string = 'NA_SET_SEARCH_RESULT';
public static SET_CATEGORIES: string = 'NA_SET_CATEGORIES';
public static SET_ROOM_INFO_DATA: string = 'NA_SET_ROOM_INFO_DATA';
public static SET_HOME_ROOM_ID: string = 'NA_SET_HOME_ROOM_ID';
}
export const initialNavigator: INavigatorState = {
needsNavigatorUpdate: true,
topLevelContext: null,
topLevelContexts: null,
searchResult: null,
categories: null,
roomInfoData: new RoomInfoData(),
homeRoomId: null
}
export const NavigatorReducer: Reducer<INavigatorState, INavigatorAction> = (state, action) =>
{
switch(action.type)
{
case NavigatorActions.SET_NEEDS_UPDATE:
return { ...state, needsNavigatorUpdate: (action.payload.flag || false) };
case NavigatorActions.SET_TOP_LEVEL_CONTEXT: {
let topLevelContext = (action.payload.topLevelContext || state.topLevelContext || null);
let index = 0;
if(topLevelContext)
{
const foundIndex = state.topLevelContexts.indexOf(topLevelContext);
if(foundIndex > -1) index = foundIndex;
}
topLevelContext = (state.topLevelContexts[index] || null);
return { ...state, topLevelContext };
}
case NavigatorActions.SET_TOP_LEVEL_CONTEXTS: {
const topLevelContexts = (action.payload.topLevelContexts || state.topLevelContexts || null);
const topLevelContext = topLevelContexts[0];
return { ...state, topLevelContext, topLevelContexts };
}
case NavigatorActions.SET_SEARCH_RESULT: {
const searchResult = (action.payload.searchResult || state.searchResult || null);
const searchCode = searchResult.code;
let topLevelContext = state.topLevelContext;
if(searchCode !== topLevelContext.code)
{
for(const existingContext of state.topLevelContexts)
{
if(existingContext.code !== searchCode) continue;
topLevelContext = existingContext;
}
}
return { ...state, topLevelContext, searchResult };
}
case NavigatorActions.SET_CATEGORIES: {
const categories = (action.payload.categories || state.categories || null);
return { ...state, categories };
}
case NavigatorActions.SET_ROOM_INFO_DATA: {
const roomInfoData = (action.payload.roomInfoData || state.roomInfoData || null);
return { ...state, roomInfoData };
}
case NavigatorActions.SET_HOME_ROOM_ID: {
const homeRoomId = (action.payload.homeRoomId || state.homeRoomId || null);
return { ...state, homeRoomId };
}
default:
return state;
}
}

View File

@ -16,8 +16,7 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
const [ visitorsCount, setVisitorsCount ] = useState<number>(null); const [ visitorsCount, setVisitorsCount ] = useState<number>(null);
const [ tradesSetting, setTradesSetting ] = useState<number>(0); const [ tradesSetting, setTradesSetting ] = useState<number>(0);
const [ selectedModelName, setSelectedModelName ] = useState<string>(RoomModels[0].name); const [ selectedModelName, setSelectedModelName ] = useState<string>(RoomModels[0].name);
const { navigatorState = null } = useNavigatorContext(); const { categories = null } = useNavigatorContext();
const { categories = null } = navigatorState;
const getRoomModelImage = (name: string) => GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`; const getRoomModelImage = (name: string) => GetConfiguration<string>('images.url') + `/navigator/models/model_${ name }.png`;
@ -64,7 +63,7 @@ export const NavigatorRoomCreatorView: FC<{}> = props =>
</Column> </Column>
<Column grow gap={ 1 }> <Column grow gap={ 1 }>
<Text>{ LocalizeText('navigator.createroom.roomdescinfo') }</Text> <Text>{ LocalizeText('navigator.createroom.roomdescinfo') }</Text>
<textarea className="flex-grow-1 form-control w-100" maxLength={255} onChange={event => setDescription(event.target.value)} placeholder={ LocalizeText('navigator.createroom.roomdescinfo') } /> <textarea className="flex-grow-1 form-control form-control-sm w-100" maxLength={255} onChange={event => setDescription(event.target.value)} placeholder={ LocalizeText('navigator.createroom.roomdescinfo') } />
</Column> </Column>
<Column gap={ 1 }> <Column gap={ 1 }>
<Text>{ LocalizeText('navigator.category') }</Text> <Text>{ LocalizeText('navigator.category') }</Text>

View File

@ -2,12 +2,11 @@ import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer'; import { RoomMuteComposer, RoomSettingsComposer, RoomStaffPickComposer, SecurityLevel, UserHomeRoomComposer } from '@nitrots/nitro-renderer';
import classNames from 'classnames'; import classNames from 'classnames';
import { FC, useEffect, useState } from 'react'; import { FC, useEffect, useState } from 'react';
import { GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../../api'; import { CreateLinkEvent, GetGroupInformation, GetSessionDataManager, LocalizeText, SendMessageComposer } from '../../../../api';
import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../../common'; import { Button, Column, Flex, LayoutBadgeImageView, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text, UserProfileIconView } from '../../../../common';
import { FloorplanEditorEvent, NavigatorEvent, RoomWidgetThumbnailEvent } from '../../../../events'; import { FloorplanEditorEvent, RoomWidgetThumbnailEvent } from '../../../../events';
import { BatchUpdates, DispatchUiEvent } from '../../../../hooks'; import { BatchUpdates, DispatchUiEvent } from '../../../../hooks';
import { useNavigatorContext } from '../../NavigatorContext'; import { useNavigatorContext } from '../../NavigatorContext';
import { NavigatorActions } from '../../reducers/NavigatorReducer';
export class NavigatorRoomInfoViewProps export class NavigatorRoomInfoViewProps
{ {
@ -20,15 +19,14 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
const [ roomThumbnail, setRoomThumbnail ] = useState(null); const [ roomThumbnail, setRoomThumbnail ] = useState(null);
const [ isRoomPicked, setIsRoomPicked ] = useState(false); const [ isRoomPicked, setIsRoomPicked ] = useState(false);
const [ isRoomMuted, setIsRoomMuted ] = useState(false); const [ isRoomMuted, setIsRoomMuted ] = useState(false);
const { navigatorState = null, dispatchNavigatorState = null } = useNavigatorContext(); const { navigatorData = null } = useNavigatorContext();
const { roomInfoData = null, homeRoomId = null } = navigatorState;
const hasPermission = (permission: string) => const hasPermission = (permission: string) =>
{ {
switch(permission) switch(permission)
{ {
case 'settings': case 'settings':
return GetSessionDataManager().securityLevel >= SecurityLevel.MODERATOR || roomInfoData.currentRoomOwner; return (GetSessionDataManager().userId === navigatorData.enteredGuestRoom.ownerId);
case 'staff_pick': case 'staff_pick':
return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY; return GetSessionDataManager().securityLevel >= SecurityLevel.COMMUNITY;
default: return false; default: return false;
@ -37,25 +35,18 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
const processAction = (action: string, value?: string) => const processAction = (action: string, value?: string) =>
{ {
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return; if(!navigatorData || !navigatorData.enteredGuestRoom) return;
switch(action) switch(action)
{ {
case 'set_home_room': case 'set_home_room':
let newRoomId = -1; let newRoomId = -1;
if(homeRoomId !== roomInfoData.enteredGuestRoom.roomId) if(navigatorData.homeRoomId !== navigatorData.enteredGuestRoom.roomId)
{ {
newRoomId = roomInfoData.enteredGuestRoom.roomId; newRoomId = navigatorData.enteredGuestRoom.roomId;
} }
dispatchNavigatorState({
type: NavigatorActions.SET_HOME_ROOM_ID,
payload: {
homeRoomId: newRoomId
}
});
SendMessageComposer(new UserHomeRoomComposer(newRoomId)); SendMessageComposer(new UserHomeRoomComposer(newRoomId));
return; return;
case 'navigator_search_tag': case 'navigator_search_tag':
@ -64,17 +55,17 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
DispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL)); DispatchUiEvent(new RoomWidgetThumbnailEvent(RoomWidgetThumbnailEvent.TOGGLE_THUMBNAIL));
return; return;
case 'open_group_info': case 'open_group_info':
GetGroupInformation(roomInfoData.enteredGuestRoom.habboGroupId); GetGroupInformation(navigatorData.enteredGuestRoom.habboGroupId);
return; return;
case 'toggle_room_link': case 'toggle_room_link':
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)); CreateLinkEvent('navigator/toggle-room-link');
return; return;
case 'open_room_settings': case 'open_room_settings':
SendMessageComposer(new RoomSettingsComposer(roomInfoData.enteredGuestRoom.roomId)); SendMessageComposer(new RoomSettingsComposer(navigatorData.enteredGuestRoom.roomId));
return; return;
case 'toggle_pick': case 'toggle_pick':
setIsRoomPicked(value => !value); setIsRoomPicked(value => !value);
SendMessageComposer(new RoomStaffPickComposer(roomInfoData.enteredGuestRoom.roomId)); SendMessageComposer(new RoomStaffPickComposer(navigatorData.enteredGuestRoom.roomId));
return; return;
case 'toggle_mute': case 'toggle_mute':
setIsRoomMuted(value => !value); setIsRoomMuted(value => !value);
@ -92,49 +83,49 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
useEffect(() => useEffect(() =>
{ {
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return; if(!navigatorData) return;
BatchUpdates(() => BatchUpdates(() =>
{ {
setIsRoomPicked(roomInfoData.enteredGuestRoom.roomPicker); setIsRoomPicked(navigatorData.currentRoomIsStaffPick);
setIsRoomMuted(roomInfoData.enteredGuestRoom.allInRoomMuted); if(navigatorData.enteredGuestRoom) setIsRoomMuted(navigatorData.enteredGuestRoom.allInRoomMuted);
}); });
}, [ roomInfoData ]); }, [ navigatorData ]);
if(!roomInfoData) return null; if(!navigatorData.enteredGuestRoom) return null;
return ( return (
<NitroCardView className="nitro-room-info" theme="primary-slim"> <NitroCardView className="nitro-room-info" theme="primary-slim">
<NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } /> <NitroCardHeaderView headerText={ LocalizeText('navigator.roomsettings.roominfo') } onCloseClick={ () => processAction('close') } />
<NitroCardContentView className="text-black"> <NitroCardContentView className="text-black">
{ roomInfoData.enteredGuestRoom && { navigatorData.enteredGuestRoom &&
<> <>
<Flex gap={ 2 } overflow="hidden"> <Flex gap={ 2 } overflow="hidden">
<LayoutRoomThumbnailView roomId={ roomInfoData.enteredGuestRoom.roomId } customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef }> <LayoutRoomThumbnailView roomId={ navigatorData.enteredGuestRoom.roomId } customUrl={ navigatorData.enteredGuestRoom.officialRoomPicRef }>
{ hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer top-0" onClick={ () => processAction('open_room_thumbnail_camera') } /> } { hasPermission('settings') && <i className="icon icon-camera-small position-absolute b-0 r-0 m-1 cursor-pointer top-0" onClick={ () => processAction('open_room_thumbnail_camera') } /> }
</LayoutRoomThumbnailView> </LayoutRoomThumbnailView>
<Column grow gap={ 1 } overflow="hidden"> <Column grow gap={ 1 } overflow="hidden">
<Flex gap={ 1 }> <Flex gap={ 1 }>
<Column grow gap={ 1 }> <Column grow gap={ 1 }>
<Flex gap={ 1 }> <Flex gap={ 1 }>
<i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': homeRoomId !== roomInfoData.enteredGuestRoom.roomId }) } /> <i onClick={ () => processAction('set_home_room') } className={ 'flex-shrink-0 icon icon-house-small cursor-pointer' + classNames({ ' gray': navigatorData.homeRoomId !== navigatorData.enteredGuestRoom.roomId }) } />
<Text bold>{ roomInfoData.enteredGuestRoom.roomName }</Text> <Text bold>{ navigatorData.enteredGuestRoom.roomName }</Text>
</Flex> </Flex>
{ roomInfoData.enteredGuestRoom.showOwner && { navigatorData.enteredGuestRoom.showOwner &&
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
<Text variant="muted">{ LocalizeText('navigator.roomownercaption') }</Text> <Text variant="muted">{ LocalizeText('navigator.roomownercaption') }</Text>
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
<UserProfileIconView userId={ roomInfoData.enteredGuestRoom.ownerId } /> <UserProfileIconView userId={ navigatorData.enteredGuestRoom.ownerId } />
<Text>{ roomInfoData.enteredGuestRoom.ownerName }</Text> <Text>{ navigatorData.enteredGuestRoom.ownerName }</Text>
</Flex> </Flex>
</Flex> } </Flex> }
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
<Text variant="muted">{ LocalizeText('navigator.roomrating') }</Text> <Text variant="muted">{ LocalizeText('navigator.roomrating') }</Text>
<Text>{ roomInfoData.enteredGuestRoom.score }</Text> <Text>{ navigatorData.enteredGuestRoom.score }</Text>
</Flex> </Flex>
{ (roomInfoData.enteredGuestRoom.tags.length > 0) && { (navigatorData.enteredGuestRoom.tags.length > 0) &&
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
{ roomInfoData.enteredGuestRoom.tags.map(tag => { navigatorData.enteredGuestRoom.tags.map(tag =>
{ {
return <Text key={ tag } pointer className="bg-muted rounded p-1" onClick={ event => processAction('navigator_search_tag', tag) }>#{ tag }</Text> return <Text key={ tag } pointer className="bg-muted rounded p-1" onClick={ event => processAction('navigator_search_tag', tag) }>#{ tag }</Text>
}) } }) }
@ -143,15 +134,15 @@ export const NavigatorRoomInfoView: FC<NavigatorRoomInfoViewProps> = props =>
<Column alignItems="center" gap={ 1 }> <Column alignItems="center" gap={ 1 }>
{ hasPermission('settings') && { hasPermission('settings') &&
<i className="icon icon-cog cursor-pointer" title={ LocalizeText('navigator.room.popup.info.room.settings') } onClick={ event => processAction('open_room_settings') } /> } <i className="icon icon-cog cursor-pointer" title={ LocalizeText('navigator.room.popup.info.room.settings') } onClick={ event => processAction('open_room_settings') } /> }
<FontAwesomeIcon icon="link" title={ LocalizeText('navigator.embed.caption') } className="cursor-pointer" onClick={ event => DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)) } /> <FontAwesomeIcon icon="link" title={ LocalizeText('navigator.embed.caption') } className="cursor-pointer" onClick={ event => CreateLinkEvent('navigator/toggle-room-link') } />
</Column> </Column>
</Flex> </Flex>
<Text overflow="auto" style={ { maxHeight: 50 } }>{ roomInfoData.enteredGuestRoom.description }</Text> <Text overflow="auto" style={ { maxHeight: 50 } }>{ navigatorData.enteredGuestRoom.description }</Text>
{ (roomInfoData.enteredGuestRoom.habboGroupId > 0) && { (navigatorData.enteredGuestRoom.habboGroupId > 0) &&
<Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }> <Flex pointer alignItems="center" gap={ 1 } onClick={ () => processAction('open_group_info') }>
<LayoutBadgeImageView className="flex-none" badgeCode={ roomInfoData.enteredGuestRoom.groupBadgeCode } isGroup={ true } /> <LayoutBadgeImageView className="flex-none" badgeCode={ navigatorData.enteredGuestRoom.groupBadgeCode } isGroup={ true } />
<Text underline> <Text underline>
{ LocalizeText('navigator.guildbase', ['groupName'], [roomInfoData.enteredGuestRoom.groupName]) } { LocalizeText('navigator.guildbase', ['groupName'], [navigatorData.enteredGuestRoom.groupName]) }
</Text> </Text>
</Flex> } </Flex> }
</Column> </Column>

View File

@ -1,5 +1,5 @@
import { FC, useCallback, useEffect, useRef, useState } from 'react'; import { FC } from 'react';
import { GetConfiguration, GetNitroInstance, LocalizeText } from '../../../../api'; import { GetConfiguration, LocalizeText } from '../../../../api';
import { Column, Flex, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common'; import { Column, Flex, LayoutRoomThumbnailView, NitroCardContentView, NitroCardHeaderView, NitroCardView, Text } from '../../../../common';
import { useNavigatorContext } from '../../NavigatorContext'; import { useNavigatorContext } from '../../NavigatorContext';
@ -11,55 +11,20 @@ export class NavigatorRoomLinkViewProps
export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props => export const NavigatorRoomLinkView: FC<NavigatorRoomLinkViewProps> = props =>
{ {
const { onCloseClick = null } = props; const { onCloseClick = null } = props;
const [ roomThumbnail, setRoomThumbnail ] = useState(null); const { navigatorData = null } = useNavigatorContext();
const [ roomLink, setRoomLink ] = useState(null);
const { navigatorState = null } = useNavigatorContext();
const { roomInfoData = null } = navigatorState;
const elementRef = useRef<HTMLInputElement>();
useEffect(() =>
{
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
if(roomInfoData.enteredGuestRoom.officialRoomPicRef) if(!navigatorData.enteredGuestRoom) return null;
{
setRoomThumbnail(GetConfiguration<string>('image.library.url') + roomInfoData.enteredGuestRoom.officialRoomPicRef);
}
const roomLinkRaw = GetNitroInstance().core.configuration.interpolate(LocalizeText('navigator.embed.src', ['roomId'], [roomInfoData.enteredGuestRoom.roomId.toString()]));
setRoomLink(roomLinkRaw);
}, [ roomInfoData ]);
const processAction = useCallback((action: string) =>
{
if(!roomInfoData || !roomInfoData.enteredGuestRoom) return;
switch(action)
{
case 'copy_room_link':
elementRef.current.select();
document.execCommand('copy');
return;
case 'close':
onCloseClick();
return;
}
}, [onCloseClick, roomInfoData]);
if(!roomInfoData) return null;
return ( return (
<NitroCardView className="nitro-room-link" theme="primary-slim"> <NitroCardView className="nitro-room-link" theme="primary-slim">
<NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ onCloseClick } /> <NitroCardHeaderView headerText={ LocalizeText('navigator.embed.title') } onCloseClick={ onCloseClick } />
<NitroCardContentView className="text-black d-flex align-items-center"> <NitroCardContentView className="text-black d-flex align-items-center">
<Flex gap={ 2 }> <Flex gap={ 2 }>
<LayoutRoomThumbnailView roomId={ roomInfoData.enteredGuestRoom.roomId } customUrl={ roomInfoData.enteredGuestRoom.officialRoomPicRef } /> <LayoutRoomThumbnailView roomId={ navigatorData.enteredGuestRoom.roomId } customUrl={ navigatorData.enteredGuestRoom.officialRoomPicRef } />
<Column> <Column>
<Text bold fontSize={ 5 }>{ LocalizeText('navigator.embed.headline') }</Text> <Text bold fontSize={ 5 }>{ LocalizeText('navigator.embed.headline') }</Text>
<Text>{ LocalizeText('navigator.embed.info') }</Text> <Text>{ LocalizeText('navigator.embed.info') }</Text>
{ roomLink && <input ref={ elementRef } type="text" readOnly className="form-control form-control-sm" value={ roomLink } /> } <input type="text" readOnly className="form-control form-control-sm" value={ GetConfiguration<string>('navigator.embed.src').replace('%roomId%', navigatorData.enteredGuestRoom.roomId.toString()) } />
</Column> </Column>
</Flex> </Flex>
</NitroCardContentView> </NitroCardContentView>

View File

@ -1,4 +1,4 @@
import { RoomBannedUsersComposer, RoomBannedUsersEvent, RoomSettingsEvent, RoomUsersWithRightsComposer, RoomUsersWithRightsEvent, SaveRoomSettingsComposer } from '@nitrots/nitro-renderer'; import { RoomBannedUsersComposer, RoomSettingsEvent, RoomUsersWithRightsComposer, SaveRoomSettingsComposer } from '@nitrots/nitro-renderer';
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { LocalizeText, SendMessageComposer } from '../../../../api'; import { LocalizeText, SendMessageComposer } from '../../../../api';
import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common'; import { NitroCardContentView, NitroCardHeaderView, NitroCardTabsItemView, NitroCardTabsView, NitroCardView } from '../../../../common';
@ -23,6 +23,59 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null); const [ roomSettingsData, setRoomSettingsData ] = useState<RoomSettingsData>(null);
const [ currentTab, setCurrentTab ] = useState(TABS[0]); const [ currentTab, setCurrentTab ] = useState(TABS[0]);
// const onFlatControllersEvent = useCallback((event: FlatControllersEvent) =>
// {
// const parser = event.getParser();
// if(!parser || !roomSettingsData) return;
// if(roomSettingsData.roomId !== parser.roomId) return;
// const data = Object.assign({}, roomSettingsData);
// data.usersWithRights = new Map(parser.users);
// setRoomSettingsData(data);
// }, [ roomSettingsData] );
// UseMessageEventHook(FlatControllersEvent, onFlatControllersEvent);
// const onFlatControllerAddedEvent = useCallback((event: FlatControllerAddedEvent) =>
// {
// const parser = event.getParser();
// if(!parser || !roomSettingsData) return;
// if(roomSettingsData.roomId !== parser.roomId) return;
// const data = Object.assign({}, roomSettingsData);
// // add new controller
// setRoomSettingsData(data);
// }, [ roomSettingsData] );
// UseMessageEventHook(FlatControllerAddedEvent, onFlatControllerAddedEvent);
// const onFlatControllerRemovedEvent = useCallback((event: FlatControllerRemovedEvent) =>
// {
// const parser = event.getParser();
// if(!parser || !roomSettingsData) return;
// if(roomSettingsData.roomId !== parser.roomId) return;
// const data = Object.assign({}, roomSettingsData);
// // remove controller
// setRoomSettingsData(data);
// }, [ roomSettingsData] );
// UseMessageEventHook(FlatControllerRemovedEvent, onFlatControllerRemovedEvent);
const updateSettings = useCallback((roomSettings: RoomSettingsData) => const updateSettings = useCallback((roomSettings: RoomSettingsData) =>
{ {
setRoomSettingsData(roomSettings); setRoomSettingsData(roomSettings);
@ -39,39 +92,24 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
SendMessageComposer(new RoomBannedUsersComposer(parser.roomId)); SendMessageComposer(new RoomBannedUsersComposer(parser.roomId));
}, []); }, []);
const onRoomUsersWithRightsEvent = useCallback((event: RoomUsersWithRightsEvent) =>
{
const parser = event.getParser();
if(!parser || !roomSettingsData) return;
if(roomSettingsData.roomId !== parser.roomId) return;
const data = Object.assign({}, roomSettingsData);
data.usersWithRights = new Map(parser.users);
setRoomSettingsData(data);
}, [roomSettingsData]);
const onRoomBannedUsersEvent = useCallback((event: RoomBannedUsersEvent) =>
{
const parser = event.getParser();
if(!parser || !roomSettingsData) return;
if(roomSettingsData.roomId !== parser.roomId) return;
const data = Object.assign({}, roomSettingsData);
data.bannedUsers = new Map(parser.users);
setRoomSettingsData(data);
}, [roomSettingsData]);
UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent); UseMessageEventHook(RoomSettingsEvent, onRoomSettingsEvent);
UseMessageEventHook(RoomUsersWithRightsEvent, onRoomUsersWithRightsEvent);
UseMessageEventHook(RoomBannedUsersEvent, onRoomBannedUsersEvent); // const onBannedUsersFromRoomEvent = useCallback((event: BannedUsersFromRoomEvent) =>
// {
// const parser = event.getParser();
// if(!parser || !roomSettingsData) return;
// if(roomSettingsData.roomId !== parser.roomId) return;
// const data = Object.assign({}, roomSettingsData);
// data.bannedUsers = parser.bannedUsers;
// setRoomSettingsData(data);
// }, [roomSettingsData]);
// UseMessageEventHook(BannedUsersFromRoomEvent, onBannedUsersFromRoomEvent);
const saveSettings = useCallback((data: RoomSettingsData) => const saveSettings = useCallback((data: RoomSettingsData) =>
{ {
@ -196,10 +234,13 @@ export const NavigatorRoomSettingsView: FC<{}> = props =>
roomSettings.chatDistance = Number(value); roomSettings.chatDistance = Number(value);
save = false; save = false;
break; break;
case 'unban_user': case 'unban_user': {
roomSettings.bannedUsers.delete(Number(value)); const index = roomSettings.bannedUsers.findIndex(user => (user.userId === Number(value)))
if(index > -1) roomSettings.bannedUsers.splice(index, 1);
save = false; save = false;
break; break;
}
case 'remove_rights_user': case 'remove_rights_user':
roomSettings.usersWithRights.delete(Number(value)); roomSettings.usersWithRights.delete(Number(value));
save = false; save = false;

View File

@ -1,6 +1,6 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { RoomDeleteComposer } from '@nitrots/nitro-renderer'; import { RoomDeleteComposer } from '@nitrots/nitro-renderer';
import { FC, useState } from 'react'; import { FC } from 'react';
import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../../api'; import { CreateLinkEvent, LocalizeText, NotificationUtilities, SendMessageComposer } from '../../../../../api';
import { Base, Flex, Text } from '../../../../../common'; import { Base, Flex, Text } from '../../../../../common';
import RoomSettingsData from '../../../common/RoomSettingsData'; import RoomSettingsData from '../../../common/RoomSettingsData';
@ -20,9 +20,7 @@ interface NavigatorRoomSettingsTabViewProps
export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props => export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewProps> = props =>
{ {
const { roomSettingsData = null, handleChange = null, close = null } = props; const { roomSettingsData = null, handleChange = null, close = null } = props;
const [ maxVisitorsList, setMaxVisitorsList ] = useState(GetMaxVisitorsList()); const { categories = null } = useNavigatorContext();
const { navigatorState = null } = useNavigatorContext();
const { categories = null } = navigatorState;
const deleteRoom = () => const deleteRoom = () =>
{ {
@ -50,19 +48,13 @@ export const NavigatorRoomSettingsBasicTabView: FC<NavigatorRoomSettingsTabViewP
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
<Text className="col-3">{ LocalizeText('navigator.category') }</Text> <Text className="col-3">{ LocalizeText('navigator.category') }</Text>
<select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ event => handleChange('category', event.target.value) }> <select className="form-select form-select-sm" value={ roomSettingsData.categoryId } onChange={ event => handleChange('category', event.target.value) }>
{ categories && categories.map(category => { categories && categories.map(category => <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>) }
{
return <option key={ category.id } value={ category.id }>{ LocalizeText(category.name) }</option>
}) }
</select> </select>
</Flex> </Flex>
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>
<Text className="col-3">{ LocalizeText('navigator.maxvisitors') }</Text> <Text className="col-3">{ LocalizeText('navigator.maxvisitors') }</Text>
<select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ event => handleChange('max_visitors', event.target.value) }> <select className="form-select form-select-sm" value={ roomSettingsData.userCount } onChange={ event => handleChange('max_visitors', event.target.value) }>
{ maxVisitorsList && maxVisitorsList.map(value => { GetMaxVisitorsList && GetMaxVisitorsList.map(value => <option key={ value } value={ value }>{ value }</option>) }
{
return <option key={ value } value={ value }>{ value }</option>
}) }
</select> </select>
</Flex> </Flex>
<Flex alignItems="center" gap={ 1 }> <Flex alignItems="center" gap={ 1 }>

View File

@ -26,19 +26,19 @@ export const NavigatorRoomSettingsModTabView: FC<NavigatorRoomSettingsTabViewPro
return ( return (
<Grid overflow="auto"> <Grid overflow="auto">
<Column size={ 6 }> <Column size={ 6 }>
<Text bold>{ LocalizeText('navigator.roomsettings.moderation.banned.users') } ({ roomSettingsData.bannedUsers.size })</Text> <Text bold>{ LocalizeText('navigator.roomsettings.moderation.banned.users') } ({ roomSettingsData.bannedUsers.length })</Text>
<Column className="bg-white rounded" overflow="hidden"> <Column className="bg-white rounded" overflow="hidden">
<Base className="list-container" overflow="auto"> <Base className="list-container" overflow="auto">
{ Array.from(roomSettingsData.bannedUsers.entries()).map(([id, name], index) => { roomSettingsData.bannedUsers.map((user, index) =>
{ {
return <Text key={index} className={ ((id === selectedUserId) ? 'selected' : '') } onClick={ event => setSelectedUserId(id)}> { name }</Text> return <Text key={ index } className={ ((user.userId === selectedUserId) ? 'selected' : '') } onClick={ event => setSelectedUserId(user.userId)}>{ user.userName }</Text>
}) } }) }
</Base> </Base>
</Column> </Column>
</Column> </Column>
<Column size={ 6 } justifyContent="end"> <Column size={ 6 } justifyContent="end">
<Button disabled={ (selectedUserId < 1) } onClick={ event => unBanUser(selectedUserId) }> <Button disabled={ (selectedUserId < 1) } onClick={ event => unBanUser(selectedUserId) }>
{ LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId) } {/* { LocalizeText('navigator.roomsettings.moderation.unban')} {selectedUserId > 0 && roomSettingsData.bannedUsers.get(selectedUserId) } */}
</Button> </Button>
</Column> </Column>
</Grid> </Grid>

View File

@ -1,5 +1,5 @@
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { FC, KeyboardEvent, useCallback, useEffect, useState } from 'react'; import React, { FC, KeyboardEvent, useState } from 'react';
import { LocalizeText } from '../../../../api'; import { LocalizeText } from '../../../../api';
import { Button } from '../../../../common/Button'; import { Button } from '../../../../common/Button';
import { Flex } from '../../../../common/Flex'; import { Flex } from '../../../../common/Flex';
@ -11,18 +11,15 @@ export interface NavigatorSearchViewProps
sendSearch: (searchValue: string, contextCode: string) => void; sendSearch: (searchValue: string, contextCode: string) => void;
} }
export let LAST_SEARCH: string = null;
export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props => export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
{ {
const { sendSearch = null } = props; const { sendSearch = null } = props;
const [ searchFilterIndex, setSearchFilterIndex ] = useState(0); const [ searchFilterIndex, setSearchFilterIndex ] = useState(0);
const [ searchValue, setSearchValue ] = useState(''); const [ searchValue, setSearchValue ] = useState('');
const [ lastSearchQuery, setLastSearchQuery ] = useState(''); const [ lastSearchQuery, setLastSearchQuery ] = useState('');
const { navigatorState = null } = useNavigatorContext(); const { topLevelContext = null, lastSearchValue = null } = useNavigatorContext();
const { topLevelContext = null, searchResult = null } = navigatorState;
const processSearch = useCallback(() => const processSearch = () =>
{ {
if(!topLevelContext) return; if(!topLevelContext) return;
@ -36,7 +33,9 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
setLastSearchQuery(searchQuery); setLastSearchQuery(searchQuery);
sendSearch((searchQuery || ''), topLevelContext.code); sendSearch((searchQuery || ''), topLevelContext.code);
}, [ lastSearchQuery, searchFilterIndex, searchValue, topLevelContext, sendSearch ]);
lastSearchValue.current = (searchQuery || '');
}
const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) => const handleKeyDown = (event: KeyboardEvent<HTMLInputElement>) =>
{ {
@ -45,23 +44,6 @@ export const NavigatorSearchView: FC<NavigatorSearchViewProps> = props =>
processSearch(); processSearch();
}; };
useEffect(() =>
{
if(!searchResult || !searchResult.data) return;
const searchResultDataParts = searchResult.data.split(':');
LAST_SEARCH = `${ topLevelContext.code }/${ searchResult.data }`;
if(searchResultDataParts.length === 2)
{
let searchFilterIndex = SearchFilterOptions.findIndex(option => (option.query === searchResultDataParts[0]));
if(searchFilterIndex > -1) setSearchFilterIndex(searchFilterIndex);
setSearchValue(searchResultDataParts[1]);
}
}, [ searchResult, topLevelContext ]);
return ( return (
<Flex fullWidth gap={ 1 }> <Flex fullWidth gap={ 1 }>
<Flex shrink> <Flex shrink>

View File

@ -4,8 +4,6 @@ import { GetRoomEngine, LocalizeText } from '../../../../../api';
import { Column, Flex, Text } from '../../../../../common'; import { Column, Flex, Text } from '../../../../../common';
import { UseRoomEngineEvent } from '../../../../../hooks'; import { UseRoomEngineEvent } from '../../../../../hooks';
import { useRoomContext } from '../../../RoomContext'; import { useRoomContext } from '../../../RoomContext';
import { ContextMenuHeaderView } from '../../context-menu/ContextMenuHeaderView';
import { ContextMenuListView } from '../../context-menu/ContextMenuListView';
import { ObjectLocationView } from '../../object-location/ObjectLocationView'; import { ObjectLocationView } from '../../object-location/ObjectLocationView';
const SCORE_TYPES = ['perteam', 'mostwins', 'classic']; const SCORE_TYPES = ['perteam', 'mostwins', 'classic'];
@ -56,12 +54,12 @@ export const FurnitureHighScoreView: FC<{}> = props =>
if((objectId === -1) || !stuffData) return null; if((objectId === -1) || !stuffData) return null;
return ( return (
<ObjectLocationView objectId={ objectId } category={ RoomObjectCategory.FLOOR }> <ObjectLocationView objectId={ objectId } category={ RoomObjectCategory.FLOOR } overflow="hidden">
<div className="nitro-widget-high-score nitro-context-menu"> <div className="nitro-widget-high-score nitro-context-menu">
<ContextMenuHeaderView> {/* <ContextMenuHeaderView>
{ LocalizeText('high.score.display.caption', [ 'scoretype', 'cleartype' ], [ LocalizeText(`high.score.display.scoretype.${ SCORE_TYPES[stuffData.scoreType] }`), LocalizeText(`high.score.display.cleartype.${ CLEAR_TYPES[stuffData.clearType] }`)]) } { LocalizeText('high.score.display.caption', [ 'scoretype', 'cleartype' ], [ LocalizeText(`high.score.display.scoretype.${ SCORE_TYPES[stuffData.scoreType] }`), LocalizeText(`high.score.display.cleartype.${ CLEAR_TYPES[stuffData.clearType] }`)]) }
</ContextMenuHeaderView> </ContextMenuHeaderView> */}
<ContextMenuListView overflow="hidden" gap={ 1 }> <Column gap={ 1 } overflow="hidden">
<Column gap={ 1 }> <Column gap={ 1 }>
<Flex alignItems="center"> <Flex alignItems="center">
<Text center bold variant="white" className="col-8"> <Text center bold variant="white" className="col-8">
@ -73,7 +71,7 @@ export const FurnitureHighScoreView: FC<{}> = props =>
</Flex> </Flex>
<hr className="m-0" /> <hr className="m-0" />
</Column> </Column>
<Column overflow="auto" gap={ 1 }> <Column gap={ 1 } overflow="auto">
{ stuffData.entries.map((entry, index) => { stuffData.entries.map((entry, index) =>
{ {
return ( return (
@ -88,7 +86,7 @@ export const FurnitureHighScoreView: FC<{}> = props =>
); );
}) } }) }
</Column> </Column>
</ContextMenuListView> </Column>
</div> </div>
</ObjectLocationView> </ObjectLocationView>

View File

@ -3,8 +3,7 @@ import classNames from 'classnames';
import { FC, useCallback, useEffect, useState } from 'react'; import { FC, useCallback, useEffect, useState } from 'react';
import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage, SendMessageComposer } from '../../../../api'; import { CreateLinkEvent, LocalizeText, RoomWidgetZoomToggleMessage, SendMessageComposer } from '../../../../api';
import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common'; import { Base, Column, Flex, Text, TransitionAnimation, TransitionAnimationTypes } from '../../../../common';
import { NavigatorEvent } from '../../../../events'; import { BatchUpdates, UseMessageEventHook } from '../../../../hooks';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook } from '../../../../hooks';
import { useRoomContext } from '../../RoomContext'; import { useRoomContext } from '../../RoomContext';
export const RoomToolsWidgetView: FC<{}> = props => export const RoomToolsWidgetView: FC<{}> = props =>
@ -23,7 +22,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
switch(action) switch(action)
{ {
case 'settings': case 'settings':
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_INFO)); CreateLinkEvent('navigator/toggle-room-info');
return; return;
case 'zoom': case 'zoom':
widgetHandler.processWidgetMessage(new RoomWidgetZoomToggleMessage(!isZoomedIn)); widgetHandler.processWidgetMessage(new RoomWidgetZoomToggleMessage(!isZoomedIn));
@ -39,7 +38,7 @@ export const RoomToolsWidgetView: FC<{}> = props =>
setIsLiked(true); setIsLiked(true);
return; return;
case 'toggle_room_link': case 'toggle_room_link':
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_ROOM_LINK)); CreateLinkEvent('navigator/toggle-room-link');
return; return;
} }
} }

View File

@ -2,7 +2,7 @@ import { Dispose, DropBounce, EaseOut, FigureUpdateEvent, JumpBy, Motions, Nitro
import { FC, useCallback, useState } from 'react'; import { FC, useCallback, useState } from 'react';
import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api'; import { CreateLinkEvent, GetSessionDataManager, GetUserProfile, OpenMessengerChat, VisitDesktop } from '../../api';
import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common'; import { Base, Flex, LayoutAvatarImageView, LayoutItemCountView, TransitionAnimation, TransitionAnimationTypes } from '../../common';
import { AchievementsUIEvent, AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, NavigatorEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events'; import { AchievementsUIEvent, AchievementsUIUnseenCountEvent, FriendsEvent, FriendsMessengerIconEvent, FriendsRequestCountEvent, GuideToolEvent, InventoryEvent, ModToolsEvent, UnseenItemTrackerUpdateEvent, UserSettingsUIEvent } from '../../events';
import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks'; import { BatchUpdates, DispatchUiEvent, UseMessageEventHook, UseRoomEngineEvent, UseUiEvent } from '../../hooks';
import { ToolbarViewItems } from './common/ToolbarViewItems'; import { ToolbarViewItems } from './common/ToolbarViewItems';
import { ToolbarMeView } from './ToolbarMeView'; import { ToolbarMeView } from './ToolbarMeView';
@ -135,7 +135,7 @@ export const ToolbarView: FC<ToolbarViewProps> = props =>
switch(item) switch(item)
{ {
case ToolbarViewItems.NAVIGATOR_ITEM: case ToolbarViewItems.NAVIGATOR_ITEM:
DispatchUiEvent(new NavigatorEvent(NavigatorEvent.TOGGLE_NAVIGATOR)); CreateLinkEvent('navigator/toggle');
return; return;
case ToolbarViewItems.INVENTORY_ITEM: case ToolbarViewItems.INVENTORY_ITEM:
DispatchUiEvent(new InventoryEvent(InventoryEvent.TOGGLE_INVENTORY)); DispatchUiEvent(new InventoryEvent(InventoryEvent.TOGGLE_INVENTORY));

View File

@ -1,33 +0,0 @@
import { NitroEvent } from '@nitrots/nitro-renderer';
export class NavigatorEvent extends NitroEvent
{
public static SHOW_NAVIGATOR: string = 'NE_SHOW_NAVIGATOR';
public static HIDE_NAVIGATOR: string = 'NE_HIDE_NAVIGATOR';
public static TOGGLE_NAVIGATOR: string = 'NE_TOGGLE_NAVIGATOR';
public static TOGGLE_ROOM_INFO: string = 'NE_TOGGLE_ROOM_INFO';
public static TOGGLE_ROOM_LINK: string = 'NE_TOGGLE_ROOM_LINK';
public static TOGGLE_ROOM_SETTINGS: string = 'NE_TOGGLE_ROOM_SETTINGS';
public static SHOW_ROOM_CREATOR: string = 'NE_TOGGLE_CREATOR';
private _roomId: number;
private _password: string;
constructor(type: string, roomId: number = -1, password = null)
{
super(type);
this._roomId = roomId;
this._password = password;
}
public get roomId(): number
{
return this._roomId;
}
public get password(): string
{
return this._password;
}
}

View File

@ -1,2 +1 @@
export * from './NavigatorEvent';
export * from './UpdateDoorStateEvent'; export * from './UpdateDoorStateEvent';

283
yarn.lock
View File

@ -1426,18 +1426,6 @@
"@jridgewell/resolve-uri" "^3.0.3" "@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10" "@jridgewell/sourcemap-codec" "^1.4.10"
"@nitrots/nitro-renderer@^1.1.13":
version "1.1.13"
resolved "https://registry.yarnpkg.com/@nitrots/nitro-renderer/-/nitro-renderer-1.1.13.tgz#0173ebda69c41031903461a21a4b3dfa0bd6fcaa"
integrity sha512-LGk8514m+/+Y50kOdkP7dVG9DXTNPM3kD/U+wDJBw6MPkxe0R2blhwPoELK02jO6Ehfoz5v+nlhNeUTHzRZzeg==
dependencies:
"@pixi/canvas-renderer" "^6.2.2"
"@pixi/extract" "^6.2.2"
"@pixi/filter-adjustment" "^4.1.3"
"@pixi/tilemap" "^3.2.2"
pako "^2.0.4"
pixi.js "^6.2.2"
"@nodelib/fs.scandir@2.1.5": "@nodelib/fs.scandir@2.1.5":
version "2.1.5" version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5" resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@ -1475,206 +1463,6 @@
mkdirp "^1.0.4" mkdirp "^1.0.4"
rimraf "^3.0.2" rimraf "^3.0.2"
"@pixi/accessibility@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/accessibility/-/accessibility-6.2.2.tgz#0c46b59d11c3e4b841bff5153116e2d17d028a24"
integrity sha512-/mXRXCw67bmPY/OZ1Y1p747h3SSg7eqacIChAUJohjbcJK0R2EJRD2uVTspVIUpHPJA0ECNGBpKqk0C1Yzkj2w==
"@pixi/app@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/app/-/app-6.2.2.tgz#45c3dba327a6500d6b9322048950499a5588ec22"
integrity sha512-YBzVaSZGA842w2gsgqzxYwQMXeu2JZmSyiybi4raFsA35iOeMurXy7sEs5NP9JO+cjobJyx6echuHzZpKUjWsQ==
"@pixi/canvas-renderer@^6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/canvas-renderer/-/canvas-renderer-6.2.2.tgz#01b7be3f91c66d527713feb3dd52f128d61dd908"
integrity sha512-GIGUhA9bzodom8oslIYEq9KWB+ko6IJCY+WmzBxvaH2TBKQQ85k6vipTCp+w/ZgNnezhcA/eFRQoqFFM4ob7+A==
"@pixi/compressed-textures@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/compressed-textures/-/compressed-textures-6.2.2.tgz#8860283058ab931c26dde27daa328e0a7de11a65"
integrity sha512-ZjiqYCE6nGtsKTRa6w4W6Krh3vo4M3WT6lrP+VW6BfgUx3quEURt5GVFsFZrJpWF4yI1fShFmjBUOerrTLJGRQ==
"@pixi/constants@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/constants/-/constants-6.2.2.tgz#53a2d0e7f3d16d0400985d81005a076c25b0b32a"
integrity sha512-BKSoj/5SI+pQEatuCG5kXXWtCZmZZNMhfhXeqvYO/WNZ+LDxm6F4pllf0t7KjGs1ZBpNxVf6fyngF9Q5r3MgJQ==
"@pixi/core@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/core/-/core-6.2.2.tgz#badf9c03e3a07835b92d1a3868363d8e5083cf13"
integrity sha512-XAqgdJ1w9k1ZUBXECm19rcnN2ngm+tOP74HkGw4qQay0biM3JS+wtX4fWQmZNGr8krf6lJrNbsghbtUy70uUaw==
"@pixi/display@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/display/-/display-6.2.2.tgz#6e8ef26f2ed686c03d71d8bb5b92e6222cb23563"
integrity sha512-8a0R+9rjlUUjb13nBA6ZNj9gygJqt38B63uIZ2inkhxpIQf0CLo2hNxkqCqXiMeRuGmOw1n6neEDMnHO1Ks+xA==
"@pixi/extract@6.2.2", "@pixi/extract@^6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/extract/-/extract-6.2.2.tgz#f8d682dbf4c29ad2bbbed0bf710c63fcfdcadc7c"
integrity sha512-w3gW1/VoHNqFEUNGRQBKm8dCdg816etbpbLExWctmPpNdyxos5N7DF44UMRFg40GPVBBNzYissrH/ojca4PFIA==
"@pixi/filter-adjustment@^4.1.3":
version "4.1.3"
resolved "https://registry.yarnpkg.com/@pixi/filter-adjustment/-/filter-adjustment-4.1.3.tgz#61e34b4dd9766ccf40463f0538201bf68f78df66"
integrity sha512-W+NhPiZRYKoRToa5+tkU95eOw8gnS5dfIp3ZP+pLv2mdER9RI+4xHxp1uLHMqUYZViTaMdZIIoVOuCgHFPYCbQ==
"@pixi/filter-alpha@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-alpha/-/filter-alpha-6.2.2.tgz#4c39d67deaf99d979019252ea6dab69d853bae84"
integrity sha512-CijLcgFdmivmSyZuM5Yyeo6R+PwalZp9OSoard1Oh5DBVvcRDn4m3cBM+nimR4YJbr0kiMbK4Ja8r+e2vwFVjA==
"@pixi/filter-blur@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-blur/-/filter-blur-6.2.2.tgz#bc0f0d0fe2d7095d3fd8924dd013f154a7436e68"
integrity sha512-ApFqn2fMIipr3mRp/8dZ74qraGGzzPO/EzvltDqJLru9vGlbX6dKLXZ6w5H8D/uN6aQW1e4N1Nrtzk5mvJVQ3g==
"@pixi/filter-color-matrix@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-color-matrix/-/filter-color-matrix-6.2.2.tgz#9eb4c55ae37b2d6e221ef7bb1781c58fb33890ad"
integrity sha512-fQWbtKFWV29jKkq4d6TknEfQ5sF5OxcbJeZo0HJmgoV3FLZ0t21XE991CFI/TqDBo8U3wzUPZVbXxiFoDKmJ8w==
"@pixi/filter-displacement@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-displacement/-/filter-displacement-6.2.2.tgz#6eaa737b1c055c5daff77e384f6d2f728f2a93f3"
integrity sha512-cd9um4kNNIeqKA/wVZw+iha+XVbBOYBC8En5hk3ZXAIXxCHxOCz3KS+aOVejXH5EB/gMDPvNNwygn0SCpSGdKA==
"@pixi/filter-fxaa@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-fxaa/-/filter-fxaa-6.2.2.tgz#fea85d68414f9ee7f417d7e54791ccbaccd861c4"
integrity sha512-e4qekMlsiEcjV0JRoqH3b34sk8yzT4jsROYPHzk0IiafE+nNNcF3vQmcmnfC0aGIyODzmNdzFLjlFkRRSviydA==
"@pixi/filter-noise@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/filter-noise/-/filter-noise-6.2.2.tgz#a4617a279e968628d7e088b36bf28c8c7cf85fb9"
integrity sha512-Jp4L6winS6ZGKpp76x3JyfEWnUMY44fQ90Ts3R3vKkZZFNDd3T4uisZ7YwvDKOhmSo5hY3lQkXaCg/YO5feXbw==
"@pixi/graphics@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/graphics/-/graphics-6.2.2.tgz#bffa1b6ab75a2c5ca54a83444e5cafe6e68dd7c7"
integrity sha512-mQyd6ef6/EF5nt7M1OObBEb9FCXxIP6AT30H01Z2wnnCgu4qj8MHrJxTkQxSHynQ+eVVPswzpVizUQZHlIYZNw==
"@pixi/interaction@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/interaction/-/interaction-6.2.2.tgz#31abd2ed0b810570ff487dd7595b755b76f5a3ba"
integrity sha512-gpNLCPc+j+RZSZqbKbzVRf4fSlOlYm0xqUVn6JtNH1kc+d9AV7Nmw9but4osP/eodDWsWPQ+7sPKClHY36bKRA==
"@pixi/loaders@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/loaders/-/loaders-6.2.2.tgz#b4fdf00f193733c14d499d4ae74fedc9063a6270"
integrity sha512-jwFM59GeMQpzuniw5PlC7kCoXZEaKrw31/ecR1sXKWDtHRyMtvXTuf+R+tSol/1ISQ55c0JBTuUbLPwp7hPvFQ==
"@pixi/math@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/math/-/math-6.2.2.tgz#dfbeeb03de765fa6e1fcfbd2058ed0037d945a86"
integrity sha512-TtsaooRRMc/WAZ4LKUDhP/d14BZElLjRNa2gopwTKUtrDa1KvzAMr8WJ8P+gaXl4DJ8B/MlgESdPhRUqVSUw0A==
"@pixi/mesh-extras@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/mesh-extras/-/mesh-extras-6.2.2.tgz#127280bcb686896b62a9b26f69681a60ecc9f3c2"
integrity sha512-HFYWhWcV6gY7VYnMhz9OSEN14PPfVqLzWnglbegGEMqCbY/ZGsD8X99x/HLGQGd6L4FFto382q0Fj1xu+y/brg==
"@pixi/mesh@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/mesh/-/mesh-6.2.2.tgz#f301bbf888ca36994b8edb30a590fbe4a035dd6f"
integrity sha512-CsKFgTu2MP756sHeoCr9s4tHy2VmnDZPnvZ0ThV8QMnb5w3Z2qRDKlXSSIdNaQOxoAPKkqxIu0JbLK8kyX0oqw==
"@pixi/mixin-cache-as-bitmap@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/mixin-cache-as-bitmap/-/mixin-cache-as-bitmap-6.2.2.tgz#4c0cdddeba91578f6e58a48df7c27743bcfc8f84"
integrity sha512-t3jZKGa/qoRMetMWmGkXz8Kp1Uzmb+2y4/adqu+RdIeG3D1oItuGux+R36ZQO6dVRv3R8s2/Dex0aACek171zw==
"@pixi/mixin-get-child-by-name@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/mixin-get-child-by-name/-/mixin-get-child-by-name-6.2.2.tgz#154d8f0d8324d0cbd84a695babd960a0c35b6c10"
integrity sha512-BBrniLAkzDex4HyvVdE/DjphzQu4pZ8Nc5aDRIbiS1s283/IXr2oTcoaW23kCjhX0xgu++XcJQQMMyv3mlblZQ==
"@pixi/mixin-get-global-position@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/mixin-get-global-position/-/mixin-get-global-position-6.2.2.tgz#361c4d9889a0b9a724e0cc92fb01d7705b1edb3e"
integrity sha512-Rz7DHn6koYFEeVG36rKiMwoTD+elJKqwQ24HHw0BAKz1VwGagBi0ZTcJ+nWplBOrw6ZPKfdOBwGQLXD7ODg8lQ==
"@pixi/particle-container@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/particle-container/-/particle-container-6.2.2.tgz#ff6b4c5da58b052b177a8504ab2a3a53851c460c"
integrity sha512-DYbSCcUiVLeM4sKZkzAp3F6dz3idyP1jecxbFqNmRjWRyMv7uXIO42rxGJMrd6BzA5j7DkywI3X0SqhhSZP7Ag==
"@pixi/polyfill@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/polyfill/-/polyfill-6.2.2.tgz#18c0a2e7273fcd505f78aa08ee4c10010dca3314"
integrity sha512-Fd5KnjrqG9Vwgl9sDfPvNeqW3/d+hG9Du7H3y5PmItBnu9wXldTtA+I5D0BLsL/wjjjCQLbPVFKwCJj511XfBw==
dependencies:
object-assign "^4.1.1"
promise-polyfill "^8.2.0"
"@pixi/prepare@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/prepare/-/prepare-6.2.2.tgz#7dd53bc2415d371113806700c103e074615f14a8"
integrity sha512-kJojn/6zEcao+XQyU+zWkBmQr0Tgeju3F9JYBpPQ8MKIUJYvDQDtRxYo9A6Xzxk8FJ373s2Ext/OelX2FcR3HQ==
"@pixi/runner@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/runner/-/runner-6.2.2.tgz#ac253ee250198437b7a7182078a90e1e752f8ada"
integrity sha512-q7bc6Eu2XplGzCQBOhbv32P0z48ixW/Su6epT9IOfDi2iTiPjB5Sxp9e+DZDFIzvkfLzgr67Ddy51YMvOp5sQg==
"@pixi/settings@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/settings/-/settings-6.2.2.tgz#1984a9a233b5e78c3cf564fed5a2cde3012b754c"
integrity sha512-eQv0ykSwnJUd/LF4MuaFoL+eBNG+EUPAVfsnlsez/Y09aqwIzJyAjRx+uGp9adQ3XHXwYt2l2wINn+foF1y/8A==
dependencies:
ismobilejs "^1.1.0"
"@pixi/sprite-animated@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/sprite-animated/-/sprite-animated-6.2.2.tgz#8006a943834fbb5059800e0b57b08c890524a264"
integrity sha512-MNkVIuC06aXn8bgfWyqQE8vmclCVLgmHB//hssr/1IFCVmnEEYZLyeWErkIA87grY3iV7tGOILEYSa3pod4XEg==
"@pixi/sprite-tiling@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/sprite-tiling/-/sprite-tiling-6.2.2.tgz#2447fd92af3e9ddf2bdaa143018eb4f721fc0714"
integrity sha512-HQ9RVObmwyPq+PM2wm2UEIMdsvWg96ymSz0NOh9bOfMSme18vSWv0Rbidv/FziQT8x6MpoLpYke0DYMGtbu0tA==
"@pixi/sprite@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/sprite/-/sprite-6.2.2.tgz#a699e95f3da0f290e798a076ff30c4ec0cc6f263"
integrity sha512-Imr+sJWFh5GtarW3FBBUzedSexfijg7OL0A6qwMDHA011gjyVeRZ15uXP8fgIwUoHoMLsU6xk85jcucM9RfWuw==
"@pixi/spritesheet@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/spritesheet/-/spritesheet-6.2.2.tgz#84013fff2f7a6b50f1403484d7cb445a4510198c"
integrity sha512-TZodC/pf+CW/8kZN+RPzObXWSPgYv1pp+foUnOHb7w8AyFnMljeqBPiUfLQaMzw91TI9AHLihoeeofqZ4wMpww==
"@pixi/text-bitmap@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/text-bitmap/-/text-bitmap-6.2.2.tgz#26f2838a06edc2e17659d6e02d4244b714e4b61d"
integrity sha512-pJZM0o68n6cUFUdolvpuuloMccdQqvTc3CLzhLu9xW9HLx7NeFjZEQWTGQea8GXsGa1RhvlMd9x3AiVSNMI2FA==
"@pixi/text@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/text/-/text-6.2.2.tgz#bf4bd0e9fdf9041e3516bbaae2094f6ab8b4ee26"
integrity sha512-Hi6MO/QhllZ4IWkr7MBzImzHB88XXKlF5E9xt1vUBhdZb3KsQD+cPx+bNCFWn6ZMWDmOloJekzRkkSl3KrfBSw==
"@pixi/ticker@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/ticker/-/ticker-6.2.2.tgz#3170ce5f44c56ac1bdb1a66a1f393d023c9cbb4e"
integrity sha512-tF3cRtcYnj3U3HFQ0IJKvAxFU1YUM96T0p8Qh478xZhvGxYGnjrQDPmjXePb4NocAdG5adb6//2uvQOd7o4rHg==
"@pixi/tilemap@^3.2.2":
version "3.2.2"
resolved "https://registry.yarnpkg.com/@pixi/tilemap/-/tilemap-3.2.2.tgz#8327e5d7007a90be640a0b1eb9943a1e405b57e4"
integrity sha512-svdmMyJP63vdae3t66tCmE8IWeO/6lD1xXU+5gzfxqxJS5seTp2bm8mQok2c8PF0O6l/NYlLz6BRklOuEuHboQ==
"@pixi/utils@6.2.2":
version "6.2.2"
resolved "https://registry.yarnpkg.com/@pixi/utils/-/utils-6.2.2.tgz#cf292ceb494992e7974982043b214617615ce335"
integrity sha512-rpS6QolFuRmm/QcKm5PYHOCkX6okl9a00u2osaMbmPP+l7XLATTxSsFhw64UbSNR+zmzsrhreRFBVFn3tf8K6w==
dependencies:
"@types/earcut" "^2.1.0"
earcut "^2.2.2"
eventemitter3 "^3.1.0"
url "^0.11.0"
"@pmmmwh/react-refresh-webpack-plugin@0.4.3": "@pmmmwh/react-refresh-webpack-plugin@0.4.3":
version "0.4.3" version "0.4.3"
resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766" resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766"
@ -1933,11 +1721,6 @@
dependencies: dependencies:
"@babel/types" "^7.3.0" "@babel/types" "^7.3.0"
"@types/earcut@^2.1.0":
version "2.1.1"
resolved "https://registry.yarnpkg.com/@types/earcut/-/earcut-2.1.1.tgz#573a0af609f17005c751f6f4ffec49cfe358ea51"
integrity sha512-w8oigUCDjElRHRRrMvn/spybSMyX8MTkKA5Dv+tS1IE/TgmNZPqUYtvYBXGY8cieSE66gm+szeK+bnbxC2xHTQ==
"@types/eslint@^7.28.2": "@types/eslint@^7.28.2":
version "7.29.0" version "7.29.0"
resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78" resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-7.29.0.tgz#e56ddc8e542815272720bb0b4ccc2aff9c3e1c78"
@ -4648,11 +4431,6 @@ duplexify@^3.4.2, duplexify@^3.6.0:
readable-stream "^2.0.0" readable-stream "^2.0.0"
stream-shift "^1.0.0" stream-shift "^1.0.0"
earcut@^2.2.2:
version "2.2.3"
resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.2.3.tgz#d44ced2ff5a18859568e327dd9c7d46b16f55cf4"
integrity sha512-iRDI1QeCQIhMCZk48DRDMVgQSSBDmbzzNhnxIo+pwx3swkfjMh6vh0nWLq1NdvGHLKH6wIrAM3vQWeTj6qeoug==
ecc-jsbn@~0.1.1: ecc-jsbn@~0.1.1:
version "0.1.2" version "0.1.2"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9" resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz#3a83a904e54353287874c564b7549386849a98c9"
@ -5144,11 +4922,6 @@ etag@~1.8.1:
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc= integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
eventemitter3@^3.1.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-3.1.2.tgz#2d3d48f9c346698fce83a85d7d664e98535df6e7"
integrity sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q==
eventemitter3@^4.0.0: eventemitter3@^4.0.0:
version "4.0.7" version "4.0.7"
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
@ -6732,11 +6505,6 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA= integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
ismobilejs@^1.1.0:
version "1.1.1"
resolved "https://registry.yarnpkg.com/ismobilejs/-/ismobilejs-1.1.1.tgz#c56ca0ae8e52b24ca0f22ba5ef3215a2ddbbaa0e"
integrity sha512-VaFW53yt8QO61k2WJui0dHf4SlL8lxBofUuUmwBo0ljPk0Drz2TiuDW4jo3wDcv41qy/SxrJ+VAzJ/qYqsmzRw==
isobject@^2.0.0: isobject@^2.0.0:
version "2.1.0" version "2.1.0"
resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89"
@ -8562,11 +8330,6 @@ p-try@^2.0.0:
resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6"
integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==
pako@^2.0.4:
version "2.0.4"
resolved "https://registry.yarnpkg.com/pako/-/pako-2.0.4.tgz#6cebc4bbb0b6c73b0d5b8d7e8476e2b2fbea576d"
integrity sha512-v8tweI900AUkZN6heMU/4Uy4cXRc2AYNRggVmTR+dEncawDJgCdLMximOVA2p4qO57WMynangsfGRb5WD6L1Bg==
pako@~1.0.5: pako@~1.0.5:
version "1.0.11" version "1.0.11"
resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf"
@ -8761,47 +8524,6 @@ pirates@^4.0.1:
resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b"
integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==
pixi.js@^6.2.2:
version "6.2.2"
resolved "https://registry.yarnpkg.com/pixi.js/-/pixi.js-6.2.2.tgz#bc8319f007e48c0d5190b32b3e4f1d5bee0677e4"
integrity sha512-/xCnJUsWTZuacR6JYTnRbUb+5grzlqpp2O1Ub7bCZCE3FApTCs7nMNYeLfdeP+np/MlGaM+SsPh2cXcafR3OZw==
dependencies:
"@pixi/accessibility" "6.2.2"
"@pixi/app" "6.2.2"
"@pixi/compressed-textures" "6.2.2"
"@pixi/constants" "6.2.2"
"@pixi/core" "6.2.2"
"@pixi/display" "6.2.2"
"@pixi/extract" "6.2.2"
"@pixi/filter-alpha" "6.2.2"
"@pixi/filter-blur" "6.2.2"
"@pixi/filter-color-matrix" "6.2.2"
"@pixi/filter-displacement" "6.2.2"
"@pixi/filter-fxaa" "6.2.2"
"@pixi/filter-noise" "6.2.2"
"@pixi/graphics" "6.2.2"
"@pixi/interaction" "6.2.2"
"@pixi/loaders" "6.2.2"
"@pixi/math" "6.2.2"
"@pixi/mesh" "6.2.2"
"@pixi/mesh-extras" "6.2.2"
"@pixi/mixin-cache-as-bitmap" "6.2.2"
"@pixi/mixin-get-child-by-name" "6.2.2"
"@pixi/mixin-get-global-position" "6.2.2"
"@pixi/particle-container" "6.2.2"
"@pixi/polyfill" "6.2.2"
"@pixi/prepare" "6.2.2"
"@pixi/runner" "6.2.2"
"@pixi/settings" "6.2.2"
"@pixi/sprite" "6.2.2"
"@pixi/sprite-animated" "6.2.2"
"@pixi/sprite-tiling" "6.2.2"
"@pixi/spritesheet" "6.2.2"
"@pixi/text" "6.2.2"
"@pixi/text-bitmap" "6.2.2"
"@pixi/ticker" "6.2.2"
"@pixi/utils" "6.2.2"
pkg-dir@^3.0.0: pkg-dir@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3" resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-3.0.0.tgz#2749020f239ed990881b1f71210d51eb6523bea3"
@ -9568,11 +9290,6 @@ promise-inflight@^1.0.1:
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM= integrity sha1-mEcocL8igTL8vdhoEputEsPAKeM=
promise-polyfill@^8.2.0:
version "8.2.3"
resolved "https://registry.yarnpkg.com/promise-polyfill/-/promise-polyfill-8.2.3.tgz#2edc7e4b81aff781c88a0d577e5fe9da822107c6"
integrity sha512-Og0+jCRQetV84U8wVjMNccfGCnMQ9mGs9Hv78QFe+pSDD3gWTpz0y+1QCuxy5d/vBFuZ3iwP2eycAkvqIMPmWg==
promise@^8.1.0: promise@^8.1.0:
version "8.1.0" version "8.1.0"
resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e" resolved "https://registry.yarnpkg.com/promise/-/promise-8.1.0.tgz#697c25c3dfe7435dd79fcd58c38a135888eaf05e"