5180 fichiers 38.5 Mo 0 téléchargements 236 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / hooks / navigator / useNavigatorSearch.ts
useNavigatorSearch.ts 3.4 Ko Télécharger le fichier
import { FlatCreatedEvent, NavigatorSearchComposer, NavigatorSearchEvent, NavigatorSearchResultSet, RoomSettingsSavedEvent } from '@octane/renderer';
import { useEffect, useState } from 'react';
import { SendMessageComposer } from '../../api';
import { useMessageEvent } from '../events';
import { useNavigatorUiStore } from './navigatorUiStore';

const NAVIGATOR_USER_COUNT_REFRESH_MS = 15000;
const MY_ROOMS_TAB_CODE = 'myworld_view';
/** The server keeps the first 64 characters of a search and echoes those back. */
const SERVER_MAX_QUERY_LENGTH = 64;

/**
 * Whether a search reply answers the search on screen: same tab and same filter. Only the tab was compared, so while
 * typing a reply for an older filter (or a poll sent before the change) could replace the newer results.
 */
export const isReplyForSearch = (code: string, data: string, tabCode: string, filter: string): boolean => {
    if (!tabCode || code !== tabCode) return false;

    const expected = (filter ?? '').slice(0, SERVER_MAX_QUERY_LENGTH);

    return (data ?? '') === expected;
};

export const useNavigatorSearch = () => {
    const tabCode = useNavigatorUiStore((s) => s.currentTabCode);
    const filter = useNavigatorUiStore((s) => s.currentFilter);
    const isVisible = useNavigatorUiStore((s) => s.isVisible);
    const needsSearch = useNavigatorUiStore((s) => s.needsSearch);
    const consumeSearchRequest = useNavigatorUiStore((s) => s.consumeSearchRequest);

    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]);

    useEffect(() => {
        if (!needsSearch || !tabCode) return;

        consumeSearchRequest();
        setIsFetching(true);
        SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
    }, [needsSearch, tabCode, filter, consumeSearchRequest]);

    useEffect(() => {
        if (!isVisible || !tabCode) return;

        const timer = setInterval(() => {
            SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
        }, NAVIGATOR_USER_COUNT_REFRESH_MS);

        return () => clearInterval(timer);
    }, [isVisible, tabCode, filter]);

    useMessageEvent<NavigatorSearchEvent>(NavigatorSearchEvent, (event) => {
        const result = event.getParser()?.result;
        if (!result) return;

        if (!isReplyForSearch(result.code, result.data, tabCode, filter)) return;

        setSearchResult(result);
        setIsFetching(false);
    });

    useMessageEvent<FlatCreatedEvent>(FlatCreatedEvent, () => {
        if (!tabCode) return;

        setIsFetching(true);
        SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
    });

    // AIR (navigator IncomingMessages.onRoomSettingsSaved) reloads the own rooms list, so a renamed room shows its new name.
    useMessageEvent<RoomSettingsSavedEvent>(RoomSettingsSavedEvent, () => {
        if (tabCode !== MY_ROOMS_TAB_CODE) return;

        setIsFetching(true);
        SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
    });

    return {
        searchResult,
        isFetching,
        refetch: () => {
            if (!tabCode) return;
            setIsFetching(true);
            SendMessageComposer(new NavigatorSearchComposer(tabCode, filter));
        }
    };
};
15Sujets
1Dépôts
20Membres
2En ligne
Profile
Inscrit
Dernière visite
Messages
0
Votes positifs
0
Votes négatifs
0

Nous utilisons des cookies pour assurer le bon fonctionnement du site et améliorer votre expérience. en savoir plus

Autoriser