import { useTranslation } from "react-i18next"; import type { FeedFilters } from "../lib/api"; import { useChannelNames } from "../lib/useChannelNames"; import Combobox, { type ComboboxOption } from "./ui/Combobox"; // Pick channels to narrow the feed to — several OR together, so every other filter then applies // across all of them. Until this existed the filter was settable only via a shared "?channel=" link: // the panel had a remove button for something nothing could apply. // // It owns its channel query rather than letting the Sidebar hold it: the Sidebar is mounted for the // whole feed page, but SidePanel only renders its children once the panel is open, so keeping the // fetch here means a subscription list of a few hundred loads when the picker is actually looked at. export default function ChannelPicker({ filters, setFilters, }: { filters: FeedFilters; setFilters: (f: FeedFilters) => void; }) { const { t } = useTranslation(); const { query: channelsQuery, names, pending } = useChannelNames(); const all = channelsQuery.data ?? []; // The list order isn't alphabetical — it's the user's channel priority — and Combobox preserves the // options order, so it stays meaningful. selectedLabels keeps a picked channel named even if a later // narrowing ever drops it from the visible rows, and names a reloaded filter before the list lands. const options: ComboboxOption[] = all.map((c) => ({ value: c.id, label: c.title ?? c.id })); return ( setFilters({ ...filters, channelIds })} loading={channelsQuery.isLoading} error={channelsQuery.isError && !channelsQuery.data ? t("common.loadError") : undefined} onRetry={() => void channelsQuery.refetch()} emptyText={t("sidebar.noChannelMatch")} selectedLabels={names} labelsPending={pending} /> ); }