import { useTranslation } from "react-i18next"; import { useQuery } from "@tanstack/react-query"; import { qk } from "../lib/queryKeys"; import { api, type FeedFilters } from "../lib/api"; import Combobox, { type ComboboxOption } from "./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 channelsQuery = useQuery({ queryKey: qk.channels(), queryFn: api.channels, staleTime: 5 * 60_000, }); 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. const options: ComboboxOption[] = all.map((c) => ({ value: c.id, label: c.title ?? c.id })); const selectedLabels = Object.fromEntries(all.map((c) => [c.id, c.title ?? c.id])); return ( setFilters({ ...filters, channelIds })} loading={channelsQuery.isLoading} emptyText={t("sidebar.noChannelMatch")} selectedLabels={selectedLabels} /> ); }