import { useState, useEffect } from "react"; import { useAppState } from "@/pages/chat/state"; import { searchUsers, fetchUserPublicKey } from "@/core/api/dmApi"; import { StatusBadge } from "@/core/components/StatusBadge"; import type { User } from "@/core/types"; import { onlineStatusManager } from "@/core/onlineStatusManager"; import { OnlineIndicator } from "@/pages/chat/ui/right/OnlineIndicator"; import defaultAvatar from "@/images/default-avatar.png"; import SearchBar from "@/core/components/SearchBar"; interface SearchUser extends User { publicKey?: string | null; verified?: boolean; } export function UsernameSearch() { const { user, switchToDM } = useAppState(); const [searchQuery, setSearchQuery] = useState(""); const [searchResults, setSearchResults] = useState([]); const [isSearching, setIsSearching] = useState(false); const [isExpanded, setIsExpanded] = useState(false); const [debounceTimeout, setDebounceTimeout] = useState(null); // Debounced search useEffect(() => { if (debounceTimeout) { clearTimeout(debounceTimeout); } if (searchQuery.length > 1) { setIsSearching(true); const newTimeout = setTimeout(async () => { if (user.authToken) { try { const users = await searchUsers(searchQuery, user.authToken); setSearchResults(users); } catch (error) { console.error("Search failed:", error); setSearchResults([]); } finally { setIsSearching(false); } } }, 300); setDebounceTimeout(newTimeout); } else { setSearchResults([]); setIsSearching(false); } return () => { if (debounceTimeout) { clearTimeout(debounceTimeout); } }; }, [searchQuery, user.authToken]); // Subscribe to online status for all search results useEffect(() => { // Subscribe to all search results searchResults.forEach(searchUser => { onlineStatusManager.subscribe(searchUser.id); }); // Cleanup function to unsubscribe from all users return () => { searchResults.forEach(searchUser => { onlineStatusManager.unsubscribe(searchUser.id); }); }; }, [searchResults]); async function handleUserClick(searchUser: SearchUser) { if (!user.authToken) return; try { let publicKey = searchUser.publicKey; if (!publicKey) { const fetchedPublicKey = await fetchUserPublicKey(searchUser.id, user.authToken); publicKey = fetchedPublicKey; } if (publicKey) { switchToDM({ userId: searchUser.id, username: searchUser.username, publicKey: publicKey, profilePicture: searchUser.profile_picture, online: searchUser.online || false }); // Collapse search setIsExpanded(false); setSearchQuery(""); setSearchResults([]); } } catch (error) { console.error("Failed to start DM conversation:", error); } } function handleQueryChange(query: string) { setSearchQuery(query); } function handleToggleExpanded() { if (isExpanded) { // Collapsing setSearchQuery(""); setSearchResults([]); } setIsExpanded(!isExpanded); } return ( { e.stopPropagation(); handleToggleExpanded(); }} type="button" icon="arrow_back--outlined" /> ) : "search--outlined"} > {isSearching && (
Поиск...
)} {!isSearching && searchQuery.length >= 2 && searchResults.length === 0 && (
Пользователи не найдены
)} {!isSearching && searchResults.length > 0 && ( {searchResults.map((searchUser) => ( handleUserClick(searchUser)} style={{ cursor: "pointer" }} >
{searchUser.username}
{searchUser.username} { (e.target as HTMLImageElement).src = defaultAvatar; }} />
))}
)} {!isSearching && searchQuery.length < 2 && (
Введите минимум 2 символа для поиска
)}
); }