5180 fichiers 38.5 Mo 0 téléchargements 221 vues mis à jour il y a 5 heures ui
nitro-v36-with-renderer-v36 / src / hooks / variables-explorer / useVariablesExplorerHolders.ts
useVariablesExplorerHolders.ts 3.6 Ko Télécharger le fichier
import type { IWiredVariableHolder } from '@octane/renderer';
import { useEffect, useRef, useState } from 'react';
import {
    EXPLORER_SORT_OPTIONS,
    explorerErrorMessage,
    sortOptionById,
    targetKindsOf,
    VariablesWebApiClient,
    WebApiHolderScope,
    WebApiTargetKind,
    webApiEntryToHolder
} from '../../api';
import { calculateLastPage, NO_PAGE } from '../../components/wired-tools/WiredPaging.helpers';
import { useWiredPageRequests } from '../wired-tools/useWiredPageRequests';

export const VARIABLES_EXPLORER_PAGE_SIZE = 50;
/** Keeps paging well under the API's 60 requests per 10 s per key. */
const REQUEST_PAGE_RATELIMIT = 400;

interface HoldersPage {
    page: number;
    total: number;
    holders: IWiredVariableHolder[];
}

/** One page at a time of who holds a variable, read over the Variables Web API. */
export const useVariablesExplorerHolders = (client: VariablesWebApiClient, scope: WebApiHolderScope, name: string) => {
    const [targetKind, setTargetKind] = useState<WebApiTargetKind>(targetKindsOf(scope)[0]);
    const [sortId, setSortId] = useState(EXPLORER_SORT_OPTIONS[0].id);
    const [page, setPage] = useState<HoldersPage | null>(null);
    const [scrollKey, setScrollKey] = useState(0);
    const [status, setStatus] = useState('');
    const requestId = useRef(0);
    const total = useRef<number | null>(null);

    const load = async (requested: number, kind: WebApiTargetKind, sort: string) => {
        const id = ++requestId.current;
        const option = sortOptionById(sort);

        try {
            // Habbo's pages carry no total: count on the first page of a filter, then keep it.
            const knownTotal = requested > 1 ? total.current : null;
            const [result, count] = await Promise.all([
                client.listEntries(scope, name, kind, requested, VARIABLES_EXPLORER_PAGE_SIZE, option.sort, option.order),
                knownTotal === null ? client.countEntries(scope, name, kind) : Promise.resolve(knownTotal)
            ]);

            if (id !== requestId.current) return;

            const entries = result?.entries ?? [];

            total.current = Math.max(count, (requested - 1) * VARIABLES_EXPLORER_PAGE_SIZE + entries.length);
            setPage({
                page: result?.page ?? requested,
                total: total.current,
                holders: entries.map((entry) => webApiEntryToHolder(entry, scope, kind))
            });
            setScrollKey((key) => key + 1);
            setStatus('');
        } catch (error) {
            if (id !== requestId.current) return;

            setStatus(explorerErrorMessage(error));
        }
    };

    useEffect(() => {
        const kind = targetKindsOf(scope)[0];

        setTargetKind(kind);
        setSortId(EXPLORER_SORT_OPTIONS[0].id);
        setPage(null);
        void load(1, kind, EXPLORER_SORT_OPTIONS[0].id);
    }, [client, scope, name]);

    const currentPage = page?.page ?? NO_PAGE;
    const lastPage = page ? calculateLastPage(page.total, VARIABLES_EXPLORER_PAGE_SIZE) : NO_PAGE;

    const requests = useWiredPageRequests({
        currentPage,
        lastPage,
        pageKey: page,
        ratelimit: REQUEST_PAGE_RATELIMIT,
        onRequestPage: (requested) => void load(requested, targetKind, sortId)
    });

    const changeFilters = (kind: WebApiTargetKind, sort: string) => {
        if (!requests.canRequestNewPage(false)) return;

        setTargetKind(kind);
        setSortId(sort);
        void load(1, kind, sort);
    };

    return { targetKind, sortId, page, currentPage, lastPage, scrollKey, status, setStatus, requests, changeFilters };
};
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