use-inbox-compiled-queries.ts2.4 KBView on GitHub
import { useMemo } from 'react';

import { useInboxes } from '@/modules/threads/hooks/use-inboxes';
import { useLabels } from '@/modules/labels/hooks/use-labels';
import { useActiveConnection } from '@/hooks/use-connections';
import { buildInboxCompiledQuery } from '@/modules/threads/lib/inbox-compiled-query';

export type InboxCompiledQuery = {
  compiledQuery: string;
  queryHash: string;
  inboxName: string;
};

/**
 * The compiled Gmail query for EVERY inbox, keyed by inbox id — system tabs
 * included.
 *
 * The system tabs are the reason this exists as a shared hook. `Important` /
 * `Other` / `Inbox` are local stubs (`{ id: 'important', name: 'Important', … }`)
 * with no `query` and no `compiledQuery` of their own: what they MEAN is computed,
 * from the Important signal, the connection identity, and the set of splits to
 * subtract. Any surface that reads `inbox.compiledQuery` straight off the record
 * therefore gets `undefined` for exactly those three tabs and silently falls back
 * to something else — which is how the unified inbox ended up serving `Important`
 * as a plain `in:important` (splits NOT subtracted, so a Calendar split's mail came
 * right back) and `Other` as `in:other`, a label no Gmail account has, so the tab
 * held no email at all.
 *
 * Consumers: the tab-count badges, which need EVERY inbox's query at once. A single
 * route's query comes from `useRouteInbox` instead — the shared resolver the email list
 * and the unified feed both read, so the two cannot disagree about the open tab.
 */
export function useInboxCompiledQueries(): Record<string, InboxCompiledQuery> {
  const { data: activeConnection } = useActiveConnection();
  const { systemLabels } = useLabels();
  const { inboxes, importantSignal } = useInboxes();

  const hasCategoryPersonal = useMemo(
    () => systemLabels.some((label) => label.name.toLowerCase() === 'personal'),
    [systemLabels],
  );

  return useMemo(() => {
    const byId: Record<string, InboxCompiledQuery> = {};
    for (const inbox of inboxes) {
      byId[inbox.id] = buildInboxCompiledQuery({
        inbox,
        inboxes,
        hasCategoryPersonal,
        connectionEmail: activeConnection?.email,
        sessionName: activeConnection?.name,
        importantSignal,
      });
    }
    return byId;
  }, [
    inboxes,
    hasCategoryPersonal,
    activeConnection?.email,
    activeConnection?.name,
    importantSignal,
  ]);
}