MCPcopy
hub / github.com/truelockmc/streambert / SearchModal

Function SearchModal

src/components/SearchModal.jsx:17–238  ·  view source on GitHub ↗
({ apiKey, onSelect, onClose, offline })

Source from the content-addressed store, hash-verified

15}
16
17export default function SearchModal({ apiKey, onSelect, onClose, offline }) {
18 const [query, setQuery] = useState("");
19 const [results, setResults] = useState([]);
20 const [loading, setLoading] = useState(false);
21 const [history, setHistory] = useState(loadHistory);
22 const inputRef = useRef();
23
24 useEffect(() => {
25 const tid = setTimeout(() => inputRef.current?.focus(), 50);
26 return () => clearTimeout(tid);
27 }, []);
28
29 useEffect(() => {
30 if (!query.trim()) {
31 setResults([]);
32 return;
33 }
34 let mounted = true;
35 const timer = setTimeout(async () => {
36 setLoading(true);
37 try {
38 const data = await tmdbFetch(
39 `/search/multi?query=${encodeURIComponent(query)}&page=1`,
40 apiKey,
41 );
42 if (mounted) {
43 setResults(
44 (data.results || [])
45 .filter((r) => r.media_type !== "person")
46 .slice(0, 12),
47 );
48 }
49 } catch {}
50 if (mounted) setLoading(false);
51 }, 380);
52 return () => {
53 mounted = false;
54 clearTimeout(timer);
55 };
56 }, [query, apiKey]);
57
58 const addToHistory = useCallback((term) => {
59 const trimmed = term.trim();
60 if (!trimmed) return;
61 setHistory((prev) => {
62 const next = [trimmed, ...prev.filter((h) => h !== trimmed)].slice(
63 0,
64 MAX_HISTORY,
65 );
66 saveHistory(next);
67 return next;
68 });
69 }, []);
70
71 const removeFromHistory = useCallback((e, term) => {
72 e.stopPropagation();
73 setHistory((prev) => {
74 const next = prev.filter((h) => h !== term);

Callers

nothing calls this directly

Calls 4

tmdbFetchFunction · 0.90
imgUrlFunction · 0.90
saveHistoryFunction · 0.85
handleSelectFunction · 0.85

Tested by

no test coverage detected