'use client'; import { useState, useEffect, useRef } from 'react'; import { Box, TextField, InputAdornment, List, ListItem, ListItemButton, ListItemText, Paper, Typography, ClickAwayListener, Fade, Avatar, useTheme, alpha } from '@mui/material'; import SearchIcon from '@mui/icons-material/Search'; import LaunchIcon from '@mui/icons-material/Launch'; import TravelExploreIcon from '@mui/icons-material/TravelExplore'; import sites from '@/constant/sites.json'; import { useTranslation } from 'react-i18next'; export function DatasetSearchBar() { const [searchQuery, setSearchQuery] = useState(''); const [showSuggestions, setShowSuggestions] = useState(false); const [recentSearches, setRecentSearches] = useState([]); const searchRef = useRef(null); const suggestionsRef = useRef(null); const theme = useTheme(); const { t } = useTranslation(); // 从 localStorage 加载最近搜索 useEffect(() => { const savedSearches = localStorage.getItem('recentDatasetSearches'); if (savedSearches) { try { const searches = JSON.parse(savedSearches); setRecentSearches(searches); } catch (e) { console.error('解析最近搜索失败', e); } } }, []); // 处理搜索输入变化 const handleSearchChange = event => { setSearchQuery(event.target.value); if (event.target.value) { setShowSuggestions(true); } else { setShowSuggestions(false); } }; // 处理回车搜索 const handleSearchSubmit = event => { if (event.key === 'Enter' && searchQuery.trim()) { // 默认使用第一个搜索引擎 if (sites.length > 0) { handleSuggestionClick(sites[0]); } } }; // 保存最近搜索 const saveRecentSearch = query => { if (!query.trim()) return; // 添加到最近搜索并去重 const updatedSearches = [query, ...recentSearches.filter(s => s !== query)].slice(0, 5); setRecentSearches(updatedSearches); // 保存到 localStorage try { localStorage.setItem('recentDatasetSearches', JSON.stringify(updatedSearches)); } catch (e) { console.error('保存最近搜索失败', e); } }; // 处理点击搜索建议 const handleSuggestionClick = site => { if (searchQuery.trim()) { // 根据不同网站处理搜索参数 let searchUrl = site.link; // 如果链接中不包含问号,则添加搜索参数 if (site.link.includes('huggingface.co')) { searchUrl = `${site.link}?sort=trending&search=${encodeURIComponent(searchQuery)}`; } else if (site.link.includes('kaggle.com')) { searchUrl = `${site.link}?search=${encodeURIComponent(searchQuery)}`; } else if (site.link.includes('datasetsearch.research.google.com')) { searchUrl = `${site.link}/search?query=${encodeURIComponent(searchQuery)}&src=0`; } else if (site.link.includes('paperswithcode.com')) { searchUrl = `${site.link}?q=${encodeURIComponent(searchQuery)}`; } else if (site.link.includes('modelscope.cn')) { searchUrl = `${site.link}?query=${encodeURIComponent(searchQuery)}`; } else if (site.link.includes('opendatalab.com')) { searchUrl = `${site.link}?keywords=${encodeURIComponent(searchQuery)}`; } else if (site.link.includes('tianchi.aliyun.com')) { searchUrl = `${site.link}?q=${encodeURIComponent(searchQuery)}`; } else { // 默认处理方式,在URL后添加搜索参数 searchUrl = `${site.link}${site.link.includes('?') ? '&' : '?'}search=${encodeURIComponent(searchQuery)}`; } // 保存最近搜索 saveRecentSearch(searchQuery); window.open(searchUrl, '_blank'); } setShowSuggestions(false); }; // 处理点击外部关闭建议 const handleClickAway = event => { // 确保点击的不是建议框本身 if (suggestionsRef.current && !suggestionsRef.current.contains(event.target)) { setShowSuggestions(false); } }; return ( searchQuery && setShowSuggestions(true)} InputProps={{ startAdornment: ( ), sx: { height: 56, borderRadius: 3, backgroundColor: theme.palette.mode === 'dark' ? alpha(theme.palette.background.default, 0.6) : alpha(theme.palette.background.default, 0.8), backdropFilter: 'blur(8px)', px: 2, transition: 'all 0.3s ease', boxShadow: `0 0 0 1px ${alpha(theme.palette.primary.main, 0.15)}`, '&.MuiOutlinedInput-root': { '& fieldset': { borderColor: 'transparent' }, '&:hover fieldset': { borderColor: 'transparent' }, '&.Mui-focused': { boxShadow: `0 0 0 2px ${alpha(theme.palette.primary.main, 0.3)}`, backgroundColor: theme.palette.mode === 'dark' ? alpha(theme.palette.background.paper, 0.8) : alpha(theme.palette.common.white, 0.95) }, '&.Mui-focused fieldset': { borderColor: 'transparent' } } } }} sx={{ mb: 1, '& .MuiInputBase-input': { fontSize: '1rem', fontWeight: 500, color: theme.palette.text.primary }, '& .MuiInputBase-input::placeholder': { color: alpha(theme.palette.text.primary, 0.6), opacity: 0.7 } }} /> {/* 搜索建议下拉框 - 使用绝对定位确保不被裁剪 */} {showSuggestions && searchQuery && ( {sites.slice(0, 5).map((site, index) => ( handleSuggestionClick(site)} sx={{ py: 1.5, '&:hover': { bgcolor: alpha(theme.palette.primary.main, 0.05) } }} > {t('datasetSquare.searchVia')} {site.name} Search "{searchQuery}" } /> ))} )} ); }