ChemPal Documentation - v1.6.0
    Preparing search index...

    Function useBadgeController

    • Mount-once hook that subscribes to all search-lifecycle events plus IDB_SEARCH_RESULTS_CLEARED, runs them through reduceBadge, and applies the result to the badge. Call this exactly once, near the top of App, before any code that emits search events.

      Returns void

      function App() {
      useBadgeController();
      // …
      }
      export function useBadgeController(): void {
      useEffect(() => {
      // Badge state is external; keep it in the closure, not React state.
      let state = initialBadgeState;
      // Skip re-emitting an identical output (e.g. repeated mid-search 0 → animate).
      let lastOutput: BadgeOutput | null = null;
      // Serialize applies so their async getBadgeText reads don't interleave.
      let applyChain: Promise<void> = Promise.resolve();

      const handle = (event: BadgeEvent) => {
      const result = reduceBadge(state, event);
      state = result.state;
      if (isSameBadgeOutput(lastOutput, result.output)) return;
      lastOutput = result.output;
      const output = result.output;
      applyChain = applyChain.then(() => applyBadgeOutput(output));
      };

      const unsubscribers = [
      onSearchEvent(SearchEvent.STARTED, () => handle({ type: SearchEvent.STARTED })),
      onSearchEvent(SearchEvent.RESULTS_COUNT, ({ count }) =>
      handle({ type: SearchEvent.RESULTS_COUNT, count }),
      ),
      onSearchEvent(SearchEvent.COMPLETED, ({ count }) =>
      handle({ type: SearchEvent.COMPLETED, count }),
      ),
      onSearchEvent(SearchEvent.ABORTED, () => handle({ type: SearchEvent.ABORTED })),
      onSearchEvent(SearchEvent.FAILED, () => handle({ type: SearchEvent.FAILED })),
      ];

      const onResultsCleared = () => handle({ type: IDB_SEARCH_RESULTS_CLEARED });
      window.addEventListener(IDB_SEARCH_RESULTS_CLEARED, onResultsCleared);

      return () => {
      for (const unsubscribe of unsubscribers) unsubscribe();
      window.removeEventListener(IDB_SEARCH_RESULTS_CLEARED, onResultsCleared);
      };
      }, []);
      }