From ee3736474ddd404e65a63c5c6ffd0054fc45f093 Mon Sep 17 00:00:00 2001 From: simoleo89 Date: Wed, 27 May 2026 19:20:27 +0200 Subject: [PATCH] refactor(navigator): remove search ownership from useNavigatorStore MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/hooks/navigator/index.ts | 2 +- src/hooks/navigator/useNavigatorActions.ts | 8 -- src/hooks/navigator/useNavigatorData.ts | 4 +- .../navigator/useNavigatorStore.test.tsx | 14 +--- src/hooks/navigator/useNavigatorStore.ts | 75 ++----------------- src/hooks/navigator/useNavigatorUiState.ts | 5 +- 6 files changed, 18 insertions(+), 90 deletions(-) delete mode 100644 src/hooks/navigator/useNavigatorActions.ts diff --git a/src/hooks/navigator/index.ts b/src/hooks/navigator/index.ts index c621851..67660d0 100644 --- a/src/hooks/navigator/index.ts +++ b/src/hooks/navigator/index.ts @@ -1,5 +1,5 @@ -export { useNavigatorActions } from './useNavigatorActions'; export { useNavigatorData } from './useNavigatorData'; +export { useNavigatorSearch } from './useNavigatorSearch'; export { useNavigatorUiState } from './useNavigatorUiState'; export { useNavigatorUiStore } from './navigatorUiStore'; export { useDoorState } from '../rooms/widgets/useDoorState'; diff --git a/src/hooks/navigator/useNavigatorActions.ts b/src/hooks/navigator/useNavigatorActions.ts deleted file mode 100644 index 6a88e43..0000000 --- a/src/hooks/navigator/useNavigatorActions.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { useBetween } from 'use-between'; -import { useNavigatorStore } from './useNavigatorStore'; - -export const useNavigatorActions = () => -{ - const { sendSearch, reloadCurrentSearch } = useBetween(useNavigatorStore); - return { sendSearch, reloadCurrentSearch }; -}; diff --git a/src/hooks/navigator/useNavigatorData.ts b/src/hooks/navigator/useNavigatorData.ts index aeb05b7..500fb9e 100644 --- a/src/hooks/navigator/useNavigatorData.ts +++ b/src/hooks/navigator/useNavigatorData.ts @@ -6,12 +6,12 @@ export const useNavigatorData = () => const { categories, eventCategories, favouriteRoomIds, topLevelContext, topLevelContexts, - searchResult, navigatorSearches, navigatorData + navigatorSearches, navigatorData } = useBetween(useNavigatorStore); return { categories, eventCategories, favouriteRoomIds, topLevelContext, topLevelContexts, - searchResult, navigatorSearches, navigatorData + navigatorSearches, navigatorData }; }; diff --git a/src/hooks/navigator/useNavigatorStore.test.tsx b/src/hooks/navigator/useNavigatorStore.test.tsx index a9040f4..2e09036 100644 --- a/src/hooks/navigator/useNavigatorStore.test.tsx +++ b/src/hooks/navigator/useNavigatorStore.test.tsx @@ -1,6 +1,6 @@ import { renderHook } from '@testing-library/react'; import { describe, expect, it } from 'vitest'; -import { useNavigatorActions, useNavigatorData, useNavigatorUiState } from './index'; +import { useNavigatorData, useNavigatorUiState } from './index'; describe('navigator filter shapes (smoke)', () => { @@ -10,24 +10,18 @@ describe('navigator filter shapes (smoke)', () => expect(Object.keys(result.current).sort()).toEqual([ 'categories', 'eventCategories', 'favouriteRoomIds', 'navigatorData', 'navigatorSearches', - 'searchResult', 'topLevelContext', 'topLevelContexts' + 'topLevelContext', 'topLevelContexts' ].sort()); }); - it('useNavigatorUiState returns the 9 documented flags', () => + it('useNavigatorUiState returns the 11 documented flags', () => { const { result } = renderHook(() => useNavigatorUiState()); expect(Object.keys(result.current).sort()).toEqual([ + 'currentFilter', 'currentTabCode', 'isCreatorOpen', 'isLoading', 'isOpenSavesSearches', 'isReady', 'isRoomInfoOpen', 'isRoomLinkOpen', 'isVisible', 'needsInit', 'needsSearch' ].sort()); }); - - it('useNavigatorActions returns sendSearch + reloadCurrentSearch', () => - { - const { result } = renderHook(() => useNavigatorActions()); - expect(typeof result.current.sendSearch).toBe('function'); - expect(typeof result.current.reloadCurrentSearch).toBe('function'); - }); }); diff --git a/src/hooks/navigator/useNavigatorStore.ts b/src/hooks/navigator/useNavigatorStore.ts index e3165d9..bf1a513 100644 --- a/src/hooks/navigator/useNavigatorStore.ts +++ b/src/hooks/navigator/useNavigatorStore.ts @@ -6,13 +6,13 @@ import { CanCreateRoomEventEvent, CantConnectMessageParser, CreateLinkEvent, HabboWebTools, LegacyExternalInterface, NavigatorCategoryDataParser, NavigatorEventCategoryDataParser, NavigatorHomeRoomEvent, NavigatorMetadataEvent, NavigatorOpenRoomCreatorEvent, NavigatorSavedSearch, - NavigatorSearchComposer, NavigatorSearchesEvent, NavigatorSearchEvent, - NavigatorSearchResultSet, NavigatorTopLevelContext, NitroEventType, + NavigatorSearchesEvent, + NavigatorTopLevelContext, NitroEventType, RoomDataParser, RoomEnterErrorEvent, RoomEntryInfoMessageEvent, - RoomForwardEvent, RoomScoreEvent, RoomSettingsUpdatedEvent, + RoomForwardEvent, RoomScoreEvent, SecurityLevel, UserEventCatsEvent, UserFlatCatsEvent, UserInfoEvent, UserPermissionsEvent } from '@nitrots/nitro-renderer'; -import { useCallback, useRef, useState } from 'react'; +import { useCallback, useState } from 'react'; import { CreateRoomSession, GetConfigurationValue, INavigatorData, LocalizeText, NotificationAlertType, SendMessageComposer, TryVisitRoom, VisitDesktop } from '../../api'; @@ -27,7 +27,6 @@ export const useNavigatorStore = () => const [ favouriteRoomIds, setFavouriteRoomIds ] = useState([]); const [ topLevelContext, setTopLevelContext ] = useState(null); const [ topLevelContexts, setTopLevelContexts ] = useState(null); - const [ searchResult, setSearchResult ] = useState(null); const [ navigatorSearches, setNavigatorSearches ] = useState(null); const [ navigatorData, setNavigatorData ] = useState({ settingsReceived: false, @@ -44,41 +43,8 @@ export const useNavigatorStore = () => canRate: true }); - // Refs let handlers stay [] deps without losing access to fresh state. - const topLevelContextsRef = useRef(topLevelContexts); - topLevelContextsRef.current = topLevelContexts; - const topLevelContextRef = useRef(topLevelContext); - topLevelContextRef.current = topLevelContext; - const searchResultRef = useRef(searchResult); - searchResultRef.current = searchResult; - const { simpleAlert = null } = useNotification(); - const sendSearch = useCallback((searchValue: string, contextCode: string) => - { - useNavigatorUiStore.getState().closeCreator(); - SendMessageComposer(new NavigatorSearchComposer(contextCode, searchValue)); - useNavigatorUiStore.getState().setLoading(true); - }, []); - - const reloadCurrentSearch = useCallback(() => - { - if(!useNavigatorUiStore.getState().isReady) - { - useNavigatorUiStore.getState().requestSearch(); - return; - } - const sr = searchResultRef.current; - if(sr) - { - sendSearch(sr.data, sr.code); - return; - } - const ctx = topLevelContextRef.current; - if(!ctx) return; - sendSearch('', ctx.code); - }, [ sendSearch ]); - useMessageEvent(FavouritesEvent, useCallback(event => { const parser = event.getParser(); @@ -99,12 +65,6 @@ export const useNavigatorStore = () => }); }, [])); - useMessageEvent(RoomSettingsUpdatedEvent, useCallback(event => - { - const parser = event.getParser(); - SendMessageComposer(new GetGuestRoomMessageComposer(parser.roomId, false, false)); - }, [])); - useMessageEvent(CanCreateRoomEventEvent, useCallback(event => { const parser = event.getParser(); @@ -223,28 +183,8 @@ export const useNavigatorStore = () => const parser = event.getParser(); setTopLevelContexts(parser.topLevelContexts); setTopLevelContext(parser.topLevelContexts.length ? parser.topLevelContexts[0] : null); - }, [])); - - useMessageEvent(NavigatorSearchEvent, useCallback(event => - { - const parser = event.getParser(); - const contexts = topLevelContextsRef.current; - setTopLevelContext(prev => - { - let next = prev; - if(!next) next = (contexts && contexts.length && contexts[0]) || null; - if(!next) return null; - if(contexts && contexts.length) - { - for(const ctx of contexts) - { - if(ctx.code === parser.result.code) next = ctx; - } - } - return next; - }); - setSearchResult(parser.result); - useNavigatorUiStore.getState().setLoading(false); + // Seed the query's tab code so useNavigatorSearch activates immediately + useNavigatorUiStore.getState().setTab(parser.topLevelContexts[0]?.code ?? ''); }, [])); useMessageEvent(UserFlatCatsEvent, useCallback(event => @@ -342,7 +282,6 @@ export const useNavigatorStore = () => return { categories, eventCategories, favouriteRoomIds, topLevelContext, topLevelContexts, - searchResult, navigatorSearches, navigatorData, - sendSearch, reloadCurrentSearch + navigatorSearches, navigatorData }; }; diff --git a/src/hooks/navigator/useNavigatorUiState.ts b/src/hooks/navigator/useNavigatorUiState.ts index 3c0868a..d811f0c 100644 --- a/src/hooks/navigator/useNavigatorUiState.ts +++ b/src/hooks/navigator/useNavigatorUiState.ts @@ -11,8 +11,11 @@ export const useNavigatorUiState = () => const isLoading = useNavigatorUiStore(s => s.isLoading); const needsInit = useNavigatorUiStore(s => s.needsInit); const needsSearch = useNavigatorUiStore(s => s.needsSearch); + const currentTabCode = useNavigatorUiStore(s => s.currentTabCode); + const currentFilter = useNavigatorUiStore(s => s.currentFilter); return { isVisible, isReady, isCreatorOpen, isRoomInfoOpen, isRoomLinkOpen, - isOpenSavesSearches, isLoading, needsInit, needsSearch + isOpenSavesSearches, isLoading, needsInit, needsSearch, + currentTabCode, currentFilter }; };