mirror of
https://github.com/duckietm/Nitro-V3.git
synced 2026-06-19 15:06:20 +00:00
🆙 Small fix for the navigator
This mirrors what the old god-hook used to do and what the rest of the codebase still uses for everything else. The TanStack one-shot listener pattern (awaitNitroResponse registers a listener, awaits one matching response, removes itself) is fragile against renderer-bundle quirks — the parser fires but the listener never matches, so the promise never resolves and query.data stays undefined forever. That's exactly the symptom you saw: server logs show the response arriving, client UI stays blank.
This commit is contained in:
@@ -1,47 +1,45 @@
|
||||
import { FlatCreatedEvent, NavigatorSearchComposer, NavigatorSearchEvent,
|
||||
NavigatorSearchResultSet, RoomSettingsUpdatedEvent } from '@nitrots/nitro-renderer';
|
||||
import { useNitroEventInvalidator, useNitroQuery } from '../../api/nitro-query';
|
||||
import { NavigatorSearchComposer, NavigatorSearchEvent, NavigatorSearchResultSet } from '@nitrots/nitro-renderer';
|
||||
import { useEffect, useState } from 'react';
|
||||
import { SendMessageComposer } from '../../api';
|
||||
import { useMessageEvent } from '../events';
|
||||
import { useNavigatorUiStore } from './navigatorUiStore';
|
||||
|
||||
const SEARCH_BASE_KEY = [ 'navigator', 'search' ] as const;
|
||||
|
||||
/**
|
||||
* TanStack Query wrapper for navigator search.
|
||||
*
|
||||
* Cache key: ['navigator', 'search', tabCode, filter]
|
||||
* - Fires NavigatorSearchComposer(tabCode, filter) on miss.
|
||||
* - Listens for NavigatorSearchEvent and resolves with the result.
|
||||
* - accept-filter: rejects events whose result.code !== tabCode (defends
|
||||
* against server-side cross-tab pushes resolving the wrong query slot).
|
||||
* - Disabled when tabCode is '' (initial state, before metadata arrives).
|
||||
* - Invalidates on FlatCreatedEvent (new room created) and
|
||||
* RoomSettingsUpdatedEvent (room renamed / settings changed).
|
||||
*/
|
||||
export const useNavigatorSearch = () =>
|
||||
{
|
||||
const tabCode = useNavigatorUiStore(s => s.currentTabCode);
|
||||
const filter = useNavigatorUiStore(s => s.currentFilter);
|
||||
|
||||
const query = useNitroQuery<NavigatorSearchEvent, NavigatorSearchResultSet | null>({
|
||||
key: [ ...SEARCH_BASE_KEY, tabCode, filter ],
|
||||
request: () => new NavigatorSearchComposer(tabCode, filter),
|
||||
parser: NavigatorSearchEvent,
|
||||
select: e => e.getParser()?.result ?? null,
|
||||
accept: e =>
|
||||
{
|
||||
const result = e.getParser()?.result;
|
||||
return !!result && result.code === tabCode;
|
||||
},
|
||||
enabled: !!tabCode,
|
||||
staleTime: 30_000
|
||||
const [ searchResult, setSearchResult ] = useState<NavigatorSearchResultSet | null>(null);
|
||||
const [ isFetching, setIsFetching ] = useState(false);
|
||||
|
||||
useEffect(() =>
|
||||
{
|
||||
if(!tabCode) return;
|
||||
|
||||
setIsFetching(true);
|
||||
SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
|
||||
}, [ tabCode, filter ]);
|
||||
|
||||
useMessageEvent<NavigatorSearchEvent>(NavigatorSearchEvent, event =>
|
||||
{
|
||||
const result = event.getParser()?.result;
|
||||
if(!result) return;
|
||||
|
||||
if(tabCode && result.code !== tabCode) return;
|
||||
|
||||
setSearchResult(result);
|
||||
setIsFetching(false);
|
||||
});
|
||||
|
||||
useNitroEventInvalidator(FlatCreatedEvent, [ ...SEARCH_BASE_KEY ]);
|
||||
useNitroEventInvalidator(RoomSettingsUpdatedEvent, [ ...SEARCH_BASE_KEY ]);
|
||||
|
||||
return {
|
||||
searchResult: query.data ?? null,
|
||||
isFetching: query.isFetching,
|
||||
refetch: query.refetch
|
||||
searchResult,
|
||||
isFetching,
|
||||
refetch: () =>
|
||||
{
|
||||
if(!tabCode) return;
|
||||
setIsFetching(true);
|
||||
SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user