mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
ee3736474d
P2 core surgery: search result + NavigatorSearchEvent listener + sendSearch + reloadCurrentSearch all leave useNavigatorStore. The new useNavigatorSearch query hook owns the cache. useNavigatorActions is deleted entirely — the only two actions it exposed are gone, and no consumer outside Navigator depended on it. NavigatorMetadataEvent handler now seeds the UI store's currentTabCode on first arrival, activating the query the moment top-level contexts land. useNavigatorData: searchResult removed from closure and return. useNavigatorUiState: currentTabCode + currentFilter added. index.ts: useNavigatorActions removed, useNavigatorSearch added. NavigatorView.tsx is intentionally broken at this commit and gets fixed in the next.
288 lines
12 KiB
TypeScript
288 lines
12 KiB
TypeScript
import { CanCreateRoomEventEvent, CantConnectMessageParser, CreateLinkEvent,
|
|
FavouriteChangedEvent, FavouritesEvent, FlatCreatedEvent,
|
|
FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer,
|
|
GetGuestRoomResultEvent, GetRoomSessionManager, GetSessionDataManager,
|
|
GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer,
|
|
HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser,
|
|
NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent,
|
|
NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSavedSearch,
|
|
NavigatorSearchesEvent,
|
|
NavigatorTopLevelContext, NitroEventType,
|
|
RoomDataParser, RoomEnterErrorEvent, RoomEntryInfoMessageEvent,
|
|
RoomForwardEvent, RoomScoreEvent,
|
|
SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent,
|
|
UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer';
|
|
import { useCallback, useState } from 'react';
|
|
import { CreateRoomSession, GetConfigurationValue, INavigatorData,
|
|
LocalizeText, NotificationAlertType, SendMessageComposer,
|
|
TryVisitRoom, VisitDesktop } from '../../api';
|
|
import { useMessageEvent, useNitroEvent } from '../events';
|
|
import { useNotification } from '../notification';
|
|
import { useNavigatorUiStore } from './navigatorUiStore';
|
|
|
|
export const useNavigatorStore = () =>
|
|
{
|
|
const [ categories, setCategories ] = useState<NavigatorCategoryDataParser[]>(null);
|
|
const [ eventCategories, setEventCategories ] = useState<NavigatorEventCategoryDataParser[]>(null);
|
|
const [ favouriteRoomIds, setFavouriteRoomIds ] = useState<number[]>([]);
|
|
const [ topLevelContext, setTopLevelContext ] = useState<NavigatorTopLevelContext>(null);
|
|
const [ topLevelContexts, setTopLevelContexts ] = useState<NavigatorTopLevelContext[]>(null);
|
|
const [ navigatorSearches, setNavigatorSearches ] = useState<NavigatorSavedSearch[]>(null);
|
|
const [ navigatorData, setNavigatorData ] = useState<INavigatorData>({
|
|
settingsReceived: false,
|
|
homeRoomId: 0,
|
|
enteredGuestRoom: null,
|
|
currentRoomOwner: false,
|
|
currentRoomId: 0,
|
|
currentRoomIsStaffPick: false,
|
|
createdFlatId: 0,
|
|
avatarId: 0,
|
|
roomPicker: false,
|
|
eventMod: false,
|
|
currentRoomRating: 0,
|
|
canRate: true
|
|
});
|
|
|
|
const { simpleAlert = null } = useNotification();
|
|
|
|
useMessageEvent<FavouritesEvent>(FavouritesEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
const favoriteIds = (parser.favoriteRoomIds || []).map((x: any) => Number(x));
|
|
setFavouriteRoomIds(favoriteIds);
|
|
}, []));
|
|
|
|
useMessageEvent<FavouriteChangedEvent>(FavouriteChangedEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
const roomId = Number(parser.flatId);
|
|
const added = !!parser.added;
|
|
setFavouriteRoomIds(prev =>
|
|
{
|
|
const ids = (prev || []).map((x: any) => Number(x));
|
|
if(added) return ids.includes(roomId) ? ids : [ ...ids, roomId ];
|
|
return ids.filter(id => id !== roomId);
|
|
});
|
|
}, []));
|
|
|
|
useMessageEvent<CanCreateRoomEventEvent>(CanCreateRoomEventEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
if(parser.canCreate) return;
|
|
simpleAlert(LocalizeText(`navigator.cannotcreateevent.error.${ parser.errorCode }`), null, null, null, LocalizeText('navigator.cannotcreateevent.title'));
|
|
}, [ simpleAlert ]));
|
|
|
|
useMessageEvent<UserInfoEvent>(UserInfoEvent, useCallback(event =>
|
|
{
|
|
SendMessageComposer(new GetUserFlatCatsMessageComposer());
|
|
SendMessageComposer(new GetUserEventCatsMessageComposer());
|
|
}, []));
|
|
|
|
useMessageEvent<UserPermissionsEvent>(UserPermissionsEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setNavigatorData(prev => ({
|
|
...prev,
|
|
eventMod: parser.securityLevel >= SecurityLevel.MODERATOR,
|
|
roomPicker: parser.securityLevel >= SecurityLevel.COMMUNITY
|
|
}));
|
|
}, []));
|
|
|
|
useMessageEvent<RoomForwardEvent>(RoomForwardEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
TryVisitRoom(parser.roomId);
|
|
}, []));
|
|
|
|
useMessageEvent<RoomEntryInfoMessageEvent>(RoomEntryInfoMessageEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setNavigatorData(prev => ({
|
|
...prev,
|
|
enteredGuestRoom: null,
|
|
currentRoomOwner: parser.isOwner,
|
|
currentRoomId: parser.roomId
|
|
}));
|
|
SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, true, false));
|
|
if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]);
|
|
}, []));
|
|
|
|
useMessageEvent<GetGuestRoomResultEvent>(GetGuestRoomResultEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
if(parser.roomEnter)
|
|
{
|
|
setNavigatorData(prev =>
|
|
{
|
|
const next = { ...prev };
|
|
next.enteredGuestRoom = parser.data;
|
|
next.currentRoomIsStaffPick = parser.staffPick;
|
|
const isCreated = next.createdFlatId === parser.data.roomId;
|
|
if(!isCreated && parser.data.displayRoomEntryAd)
|
|
{
|
|
if(GetConfigurationValue<boolean>('roomenterad.habblet.enabled', false)) HabboWebTools.openRoomEnterAd();
|
|
}
|
|
next.createdFlatId = 0;
|
|
return next;
|
|
});
|
|
return;
|
|
}
|
|
if(parser.roomForward)
|
|
{
|
|
// Door-mode branches (DOORBELL_STATE / PASSWORD_STATE) are handled by useDoorState — skip them here.
|
|
const isOwner = parser.data.ownerName === GetSessionDataManager().userName;
|
|
if(!isOwner && !parser.isGroupMember)
|
|
{
|
|
if(parser.data.doorMode === RoomDataParser.DOORBELL_STATE) return;
|
|
if(parser.data.doorMode === RoomDataParser.PASSWORD_STATE) return;
|
|
}
|
|
if((parser.data.doorMode === RoomDataParser.NOOB_STATE) && !GetSessionDataManager().isAmbassador && !GetSessionDataManager().isRealNoob && !GetSessionDataManager().isModerator) return;
|
|
CreateRoomSession(parser.data.roomId);
|
|
return;
|
|
}
|
|
setNavigatorData(prev => ({
|
|
...prev,
|
|
enteredGuestRoom: parser.data,
|
|
currentRoomIsStaffPick: parser.staffPick
|
|
}));
|
|
}, []));
|
|
|
|
useMessageEvent<RoomScoreEvent>(RoomScoreEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setNavigatorData(prev => ({
|
|
...prev,
|
|
currentRoomRating: parser.totalLikes,
|
|
canRate: parser.canLike
|
|
}));
|
|
}, []));
|
|
|
|
useMessageEvent<GenericErrorEvent>(GenericErrorEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
// -100002 (wrong password) is handled by useDoorState — skip it here.
|
|
switch(parser.errorCode)
|
|
{
|
|
case 4009:
|
|
simpleAlert(LocalizeText('navigator.alert.need.to.be.vip'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title'));
|
|
return;
|
|
case 4010:
|
|
simpleAlert(LocalizeText('navigator.alert.invalid_room_name'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title'));
|
|
return;
|
|
case 4011:
|
|
simpleAlert(LocalizeText('navigator.alert.cannot_perm_ban'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title'));
|
|
return;
|
|
case 4013:
|
|
simpleAlert(LocalizeText('navigator.alert.room_in_maintenance'), NotificationAlertType.DEFAULT, null, null, LocalizeText('generic.alert.title'));
|
|
return;
|
|
}
|
|
}, [ simpleAlert ]));
|
|
|
|
useMessageEvent<NavigatorMetadataEvent>(NavigatorMetadataEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setTopLevelContexts(parser.topLevelContexts);
|
|
setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null);
|
|
// Seed the query's tab code so useNavigatorSearch activates immediately
|
|
useNavigatorUiStore.getState().setTab(parser.topLevelContexts[0]?.code ?? '');
|
|
}, []));
|
|
|
|
useMessageEvent<UserFlatCatsEvent>(UserFlatCatsEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setCategories(parser.categories);
|
|
}, []));
|
|
|
|
useMessageEvent<UserEventCatsEvent>(UserEventCatsEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
setEventCategories(parser.categories);
|
|
}, []));
|
|
|
|
useMessageEvent<FlatCreatedEvent>(FlatCreatedEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
CreateRoomSession(parser.roomId);
|
|
}, []));
|
|
|
|
useNitroEvent(NitroEventType.SOCKET_RECONNECTING, useCallback(() =>
|
|
{
|
|
setNavigatorData(prev => ({ ...prev, settingsReceived: false }));
|
|
}, []));
|
|
|
|
useMessageEvent<NavigatorHomeRoomEvent>(NavigatorHomeRoomEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
let prevSettingsReceived = false;
|
|
setNavigatorData(prev =>
|
|
{
|
|
prevSettingsReceived = prev.settingsReceived;
|
|
return { ...prev, homeRoomId: parser.homeRoomId, settingsReceived: true };
|
|
});
|
|
if(prevSettingsReceived) return;
|
|
if(GetRoomSessionManager().viewerSession) return;
|
|
|
|
let forwardType = -1;
|
|
let forwardId = -1;
|
|
if((GetConfigurationValue<string>('friend.id') !== undefined) && (parseInt(GetConfigurationValue<string>('friend.id')) > 0))
|
|
{
|
|
forwardType = 0;
|
|
SendMessageComposer(new FollowFriendMessageComposer(parseInt(GetConfigurationValue<string>('friend.id'))));
|
|
}
|
|
if((GetConfigurationValue<number>('forward.type') !== undefined) && (GetConfigurationValue<number>('forward.id') !== undefined))
|
|
{
|
|
forwardType = parseInt(GetConfigurationValue<string>('forward.type'));
|
|
forwardId = parseInt(GetConfigurationValue<string>('forward.id'));
|
|
}
|
|
if(forwardType === 2)
|
|
{
|
|
TryVisitRoom(forwardId);
|
|
}
|
|
else if((forwardType === -1) && (parser.roomIdToEnter > 0))
|
|
{
|
|
CreateLinkEvent('navigator/close');
|
|
CreateRoomSession(parser.roomIdToEnter !== parser.homeRoomId ? parser.roomIdToEnter : parser.homeRoomId);
|
|
}
|
|
}, []));
|
|
|
|
useMessageEvent<RoomEnterErrorEvent>(RoomEnterErrorEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
switch(parser.reason)
|
|
{
|
|
case CantConnectMessageParser.REASON_FULL:
|
|
simpleAlert(LocalizeText('navigator.guestroomfull.text'), NotificationAlertType.DEFAULT, null, null, LocalizeText('navigator.guestroomfull.title'));
|
|
break;
|
|
case CantConnectMessageParser.REASON_QUEUE_ERROR:
|
|
simpleAlert(LocalizeText(`room.queue.error.${ parser.parameter }`), NotificationAlertType.DEFAULT, null, null, LocalizeText('room.queue.error.title'));
|
|
break;
|
|
case CantConnectMessageParser.REASON_BANNED:
|
|
simpleAlert(LocalizeText('navigator.banned.text'), NotificationAlertType.DEFAULT, null, null, LocalizeText('navigator.banned.title'));
|
|
break;
|
|
default:
|
|
simpleAlert(LocalizeText('room.queue.error.title'), NotificationAlertType.DEFAULT, null, null, LocalizeText('room.queue.error.title'));
|
|
break;
|
|
}
|
|
if(GetRoomSessionManager().isReconnecting) return;
|
|
VisitDesktop();
|
|
}, [ simpleAlert ]));
|
|
|
|
useMessageEvent<NavigatorOpenRoomCreatorEvent>(NavigatorOpenRoomCreatorEvent, useCallback(_event =>
|
|
{
|
|
CreateLinkEvent('navigator/show');
|
|
}, []));
|
|
|
|
useMessageEvent<NavigatorSearchesEvent>(NavigatorSearchesEvent, useCallback(event =>
|
|
{
|
|
const parser = event.getParser();
|
|
if(!parser) return;
|
|
setNavigatorSearches(parser.searches);
|
|
}, []));
|
|
|
|
return {
|
|
categories, eventCategories, favouriteRoomIds,
|
|
topLevelContext, topLevelContexts,
|
|
navigatorSearches, navigatorData
|
|
};
|
|
};
|