import { useTranslation } from "react-i18next"; import { Search, X, Youtube } from "lucide-react"; import type { FeedFilters, Me } from "../lib/api"; import type { Page } from "../lib/urlState"; import { pageTitleKey } from "../lib/pageMeta"; import PageTitle from "./PageTitle"; // Contextual top bar over the content column. Primary navigation, account and the per-user sync // status live in the left NavSidebar; the feed's scope toggle now lives in the filter sidebar. // The header carries just the feed search (or the current page title). export default function Header({ me, filters, setFilters, plexQ, setPlexQ, page, onYtSearch, }: { me: Me; filters: FeedFilters; setFilters: (f: FeedFilters) => void; // Plex has its own ephemeral search term (see App) — the box is shared UI, the state is not. plexQ: string; setPlexQ: (q: string) => void; page: Page; // Trigger a live YouTube search for the current term (hidden for the demo account, which // can't spend the shared quota). onYtSearch: (q: string) => void; }) { const { t } = useTranslation(); const canSearchYt = !me.is_demo; // The search box serves both the YouTube feed and the Plex module (integrated search); the live // YouTube-search escalation (Enter / button) is feed-only. On Plex it drives `plexQ`, on the feed // the persisted `filters.q`. const isSearchPage = page === "feed" || page === "plex"; const isPlex = page === "plex"; const isYtCapable = page === "feed" && canSearchYt; const searchValue = isPlex ? plexQ : filters.q; const trimmedQ = searchValue.trim(); return (
{isSearchPage ? (
{ const q = e.target.value; if (isPlex) { setPlexQ(q); return; } // When a search first appears, rank the feed by relevance — set atomically with // the query (race-free vs. per-keystroke updates). Only overrides the default // "newest" sort; a custom sort the user chose is left alone. Cleared in Feed. const startSearch = !filters.q.trim() && !!q.trim() && filters.sort === "newest"; setFilters({ ...filters, q, ...(startSearch ? { sort: "relevance" } : {}) }); }} onKeyDown={(e) => { // On the feed, Enter escalates the typed term to a live YouTube search (the box // itself filters the local catalog / Plex library as you type). if (e.key === "Enter" && trimmedQ && isYtCapable) onYtSearch(trimmedQ); }} placeholder={page === "plex" ? t("plex.searchPlaceholder") : t("header.searchPlaceholder")} className="w-full bg-card border border-border rounded-full pl-9 pr-9 py-2 text-sm outline-none focus:border-accent" /> {searchValue && ( )}
{trimmedQ && isYtCapable && ( )}
) : (
)}
); }