From 1148c0a628ee47e2ed62332e8df6bee8cdbf797b Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 27 May 2026 19:01:48 +0200 Subject: [PATCH] refactor(navigator): remove deprecated useNavigator god-hook P1 complete. All 13 consumers migrated to the wired-tools-style split: - useNavigatorData / useNavigatorUiState / useNavigatorActions (filters) - useNavigatorStore (internal useBetween closure with sendSearch + reloadCurrentSearch) - navigatorUiStore (Zustand for 9 UI flags) - useDoorState (extracted to src/hooks/rooms/widgets) Spec: docs/superpowers/specs/2026-05-26-navigator-modernization-p1-design.md Plan: docs/superpowers/plans/2026-05-26-navigator-modernization-p1.md Next phases (separate specs/plans): P2 (TanStack Query for search), P3 (reactive favourites via snapshot), P4 (visual rework + virtualization + persistence). --- src/hooks/navigator/useNavigator.ts | 492 ---------------------------- 1 file changed, 492 deletions(-) delete mode 100644 src/hooks/navigator/useNavigator.ts diff --git a/src/hooks/navigator/useNavigator.ts b/src/hooks/navigator/useNavigator.ts deleted file mode 100644 index a934aff..0000000 --- a/src/hooks/navigator/useNavigator.ts +++ /dev/null @@ -1,492 +0,0 @@ -import { CanCreateRoomEventEvent, CantConnectMessageParser, CreateLinkEvent, DoorbellMessageEvent, FavouriteChangedEvent, FavouritesEvent, FlatAccessDeniedMessageEvent, FlatCreatedEvent, FollowFriendMessageComposer, GenericErrorEvent, GetGuestRoomMessageComposer, GetGuestRoomResultEvent, GetRoomSessionManager, GetSessionDataManager, GetUserEventCatsMessageComposer, GetUserFlatCatsMessageComposer, HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSavedSearch, NavigatorSearchesEvent, NavigatorSearchEvent, NavigatorSearchResultSet, NavigatorTopLevelContext, NitroEventType, RoomDataParser, RoomDoorbellAcceptedEvent, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, RoomForwardEvent, RoomScoreEvent, RoomSettingsUpdatedEvent, SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer'; -import { useState } from 'react'; -import { useBetween } from 'use-between'; -import { CreateRoomSession, DoorStateType, GetConfigurationValue, INavigatorData, LocalizeText, NotificationAlertType, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api'; -import { useMessageEvent, useNitroEvent } from '../events'; -import { useNotification } from '../notification'; - -const useNavigatorState = () => -{ - const [ categories, setCategories ] = useState(null); - const [ eventCategories, setEventCategories ] = useState(null); - const [ favouriteRoomIds, setFavouriteRoomIds ] = useState([]); - const [ topLevelContext, setTopLevelContext ] = useState(null); - const [ topLevelContexts, setTopLevelContexts ] = useState(null); - const [ doorData, setDoorData ] = useState<{ roomInfo: RoomDataParser, state: number }>({ roomInfo: null, state: DoorStateType.NONE }); - const [ searchResult, setSearchResult ] = useState(null); - const [ navigatorSearches, setNavigatorSearches ] = useState(null); - const [ navigatorData, setNavigatorData ] = useState({ - 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, event => - { - const parser = event.getParser(); - const favoriteIds = (parser.favoriteRoomIds || []).map((x: any) => Number(x)); - setFavouriteRoomIds(favoriteIds); - }); - - useMessageEvent(FavouriteChangedEvent, 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(RoomSettingsUpdatedEvent, event => - { - const parser = event.getParser(); - - SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, false, false)); - }); - - useMessageEvent(CanCreateRoomEventEvent, event => - { - const parser = event.getParser(); - - if(parser.canCreate) - { - // show room event cvreate - - return; - } - - simpleAlert(LocalizeText(`navigator.cannotcreateevent.error.${ parser.errorCode }`), null, null, null, LocalizeText('navigator.cannotcreateevent.title')); - }); - - useMessageEvent(UserInfoEvent, event => - { - SendMessageComposer(new GetUserFlatCatsMessageComposer()); - SendMessageComposer(new GetUserEventCatsMessageComposer()); - }); - - useMessageEvent(UserPermissionsEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.eventMod = (parser.securityLevel >= SecurityLevel.MODERATOR); - newValue.roomPicker = (parser.securityLevel >= SecurityLevel.COMMUNITY); - - return newValue; - }); - }); - - useMessageEvent(RoomForwardEvent, event => - { - const parser = event.getParser(); - - TryVisitRoom(parser.roomId); - }); - - useMessageEvent(RoomEntryInfoMessageEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = null; - newValue.currentRoomOwner = parser.isOwner; - newValue.currentRoomId = parser.roomId; - - return newValue; - }); - - // close room info - // close room settings - // close room filter - - SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, true, false)); - - if(LegacyExternalInterface.available) LegacyExternalInterface.call('legacyTrack', 'navigator', 'private', [ parser.roomId ]); - }); - - useMessageEvent(GetGuestRoomResultEvent, event => - { - const parser = event.getParser(); - - if(parser.roomEnter) - { - setDoorData({ roomInfo: null, state: DoorStateType.NONE }); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; - - const isCreated = (newValue.createdFlatId === parser.data.roomId); - - if(!isCreated && parser.data.displayRoomEntryAd) - { - if(GetConfigurationValue('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) - { - if((parser.data.ownerName !== GetSessionDataManager().userName) && !parser.isGroupMember) - { - switch(parser.data.doorMode) - { - case RoomDataParser.DOORBELL_STATE: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_DOORBELL; - - return newValue; - }); - return; - case RoomDataParser.PASSWORD_STATE: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.roomInfo = parser.data; - newValue.state = DoorStateType.START_PASSWORD; - - return newValue; - }); - return; - } - } - - if((parser.data.doorMode === RoomDataParser.NOOB_STATE) && !GetSessionDataManager().isAmbassador && !GetSessionDataManager().isRealNoob && !GetSessionDataManager().isModerator) return; - - CreateRoomSession(parser.data.roomId); - } - else - { - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.enteredGuestRoom = parser.data; - newValue.currentRoomIsStaffPick = parser.staffPick; - - return newValue; - }); - } - }); - - useMessageEvent(RoomScoreEvent, event => - { - const parser = event.getParser(); - - setNavigatorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.currentRoomRating = parser.totalLikes; - newValue.canRate = parser.canLike; - - return newValue; - }); - }); - - useMessageEvent(DoorbellMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_WAITING; - - return newValue; - }); - } - }); - - useMessageEvent(RoomDoorbellAcceptedEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_ACCEPTED; - - return newValue; - }); - } - }); - - useMessageEvent(FlatAccessDeniedMessageEvent, event => - { - const parser = event.getParser(); - - if(!parser.userName || (parser.userName.length === 0)) - { - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_NO_ANSWER; - - return newValue; - }); - } - }); - - useMessageEvent(GenericErrorEvent, event => - { - const parser = event.getParser(); - - switch(parser.errorCode) - { - case -100002: - setDoorData(prevValue => - { - const newValue = { ...prevValue }; - - newValue.state = DoorStateType.STATE_WRONG_PASSWORD; - - return newValue; - }); - return; - 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; - } - }); - - useMessageEvent(NavigatorMetadataEvent, event => - { - const parser = event.getParser(); - - setTopLevelContexts(parser.topLevelContexts); - setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null); - }); - - useMessageEvent(NavigatorSearchEvent, event => - { - const parser = event.getParser(); - - setTopLevelContext(prevValue => - { - 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); - }); - - useMessageEvent(UserFlatCatsEvent, event => - { - const parser = event.getParser(); - - setCategories(parser.categories); - }); - - useMessageEvent(UserEventCatsEvent, event => - { - const parser = event.getParser(); - - setEventCategories(parser.categories); - }); - - useMessageEvent(FlatCreatedEvent, event => - { - const parser = event.getParser(); - - CreateRoomSession(parser.roomId); - }); - - // When reconnection starts, reset settingsReceived so the login sequence's - // NavigatorHomeRoomEvent is treated as a fresh login. Without this, the - // prevSettingsReceived check blocks home room navigation after reconnection, - // leaving the user stuck on hotel view. - useNitroEvent(NitroEventType.SOCKET_RECONNECTING, () => - { - setNavigatorData(prevValue => ({ ...prevValue, settingsReceived: false })); - }); - - useMessageEvent(NavigatorHomeRoomEvent, event => - { - const parser = event.getParser(); - - let prevSettingsReceived = false; - - setNavigatorData(prevValue => - { - prevSettingsReceived = prevValue.settingsReceived; - - const newValue = { ...prevValue }; - - newValue.homeRoomId = parser.homeRoomId; - newValue.settingsReceived = true; - - return newValue; - }); - - if(prevSettingsReceived) - { - // refresh room info window - return; - } - - // If a room session was already restored (from a network disconnect reload), - // skip the normal home room navigation to avoid overriding it. - if(GetRoomSessionManager().viewerSession) return; - - let forwardType = -1; - let forwardId = -1; - - if((GetConfigurationValue('friend.id') !== undefined) && (parseInt(GetConfigurationValue('friend.id')) > 0)) - { - forwardType = 0; - SendMessageComposer(new FollowFriendMessageComposer(parseInt(GetConfigurationValue('friend.id')))); - } - - if((GetConfigurationValue('forward.type') !== undefined) && (GetConfigurationValue('forward.id') !== undefined)) - { - forwardType = parseInt(GetConfigurationValue('forward.type')); - forwardId = parseInt(GetConfigurationValue('forward.id')); - } - - if(forwardType === 2) - { - TryVisitRoom(forwardId); - } - - else if((forwardType === -1) && (parser.roomIdToEnter > 0)) - { - CreateLinkEvent('navigator/close'); - - if(parser.roomIdToEnter !== parser.homeRoomId) - { - CreateRoomSession(parser.roomIdToEnter); - } - else - { - CreateRoomSession(parser.homeRoomId); - } - } - }); - - useMessageEvent(RoomEnterErrorEvent, 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; - } - - // During reconnection, don't navigate to desktop — the reconnection guard - // will handle retrying or cleaning up. Calling VisitDesktop here would - // remove the session from the map and send the user to hotel view. - if(GetRoomSessionManager().isReconnecting) return; - - VisitDesktop(); - }); - - useMessageEvent(NavigatorOpenRoomCreatorEvent, event => CreateLinkEvent('navigator/show')); - - useMessageEvent(NavigatorSearchesEvent, event => - { - const parser = event.getParser(); - if(!parser) return; - setNavigatorSearches(parser.searches); - }); - - return { categories, doorData, setDoorData, topLevelContext, topLevelContexts, searchResult, navigatorData, favouriteRoomIds, navigatorSearches }; -}; - -export const useNavigator = () => useBetween(useNavigatorState);