import { useState } from "react"; import { useTranslation } from "react-i18next"; import { useQuery } from "@tanstack/react-query"; import { qk } from "../lib/queryKeys"; import { X } from "lucide-react"; import { api, type FeedFilters } from "../lib/api"; import { useScrollFade } from "../lib/useScrollFade"; import { inputCls } from "./ui/form"; // 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, setQuery] = useState(""); // Same edge-fade affordance the nav rail and the panel body use to hint at more content. const fade = useScrollFade(); const channelsQuery = useQuery({ queryKey: qk.channels(), queryFn: api.channels, staleTime: 5 * 60_000, }); const q = query.trim().toLowerCase(); const all = channelsQuery.data ?? []; const matches = q ? all.filter((c) => (c.title ?? c.id).toLowerCase().includes(q)) : all; const picked = filters.channelIds; const nameOf = (id: string) => all.find((c) => c.id === id)?.title ?? id; const toggle = (id: string) => setFilters({ ...filters, channelIds: picked.includes(id) ? picked.filter((x) => x !== id) : [...picked, id], }); return ( <> {/* The picks sit above the list so they stay visible once the list scrolls away. */} {picked.length > 0 && (