import { useState, useRef, useEffect } from "react"; import { useMessageStore } from "../stores/message.ts"; interface MessageSearchProps { channelId: string; channelName: string; onClose: () => void; onJump?: (messageId: string) => void; } export function MessageSearch({ channelId, channelName, onClose, onJump }: MessageSearchProps) { const [query, setQuery] = useState(""); const [selectedIndex, setSelectedIndex] = useState(0); const results = useMessageStore((s) => s.searchResultsByChannel[channelId] || []); const searchMessages = useMessageStore((s) => s.searchMessages); const inputRef = useRef(null); useEffect(() => { inputRef.current?.focus(); }, []); useEffect(() => { const t = setTimeout(() => { if (query.trim()) { searchMessages(channelId, query.trim()); setSelectedIndex(0); } }, 200); return () => clearTimeout(t); }, [query, channelId, searchMessages]); useEffect(() => { const handler = (e: KeyboardEvent) => { if (e.key === "Escape") { onClose(); return; } if (results.length === 0) return; if (e.key === "ArrowDown") { e.preventDefault(); setSelectedIndex((i) => (i + 1) % results.length); } else if (e.key === "ArrowUp") { e.preventDefault(); setSelectedIndex((i) => (i - 1 + results.length) % results.length); } else if (e.key === "Enter") { e.preventDefault(); const msg = results[selectedIndex]; if (msg && onJump) { onJump(msg.id); } onClose(); } }; window.addEventListener("keydown", handler); return () => window.removeEventListener("keydown", handler); }, [results, selectedIndex, onClose, onJump]); return (
SEARCH #{channelName.toUpperCase()}
setQuery(e.target.value)} placeholder="search messages..." className="terminal-input w-full text-sm" />
{results.length === 0 && query.trim() && (
[no results]
)} {results.map((msg, idx) => ( ))}
); }