diff --git a/src/app/search/page.tsx b/src/app/search/page.tsx index fbb1b31..bce9bee 100644 --- a/src/app/search/page.tsx +++ b/src/app/search/page.tsx @@ -30,23 +30,19 @@ function SearchPageClient() { const searchInputRef = useRef(null); // 视图模式:聚合(agg) 或 全部(all),默认值由环境变量 NEXT_PUBLIC_AGGREGATE_SEARCH_RESULT 决定 - const [viewMode, setViewMode] = useState<'agg' | 'all'>(() => { - const envVal = process.env.NEXT_PUBLIC_AGGREGATE_SEARCH_RESULT; - // 默认聚合('agg')。当显式设置为 'false' 或 '0' 时使用 'all' - if (envVal === 'false' || envVal === '0') { - return 'all'; - } - return 'agg'; - }); + const [viewMode, setViewMode] = useState<'agg' | 'all'>( + process.env.NEXT_PUBLIC_AGGREGATE_SEARCH_RESULT === 'false' || + process.env.NEXT_PUBLIC_AGGREGATE_SEARCH_RESULT === '0' + ? 'all' + : 'agg' + ); // 聚合后的结果(按标题和年份分组) const aggregatedResults = useMemo(() => { const map = new Map(); searchResults.forEach((item) => { - // 使用 title + year 作为键,若 year 不存在则使用 'unknown' - const key = `${item.title}-${item.year || 'unknown'}-${ - item.episodes.length === 1 ? 'movie' : 'tv' - }`; + // 使用 title + year + id 作为键,若 year 不存在则使用 'unknown' + const key = `${item.title}-${item.year || 'unknown'}-${item.id}`; const arr = map.get(key) || []; arr.push(item); map.set(key, arr); @@ -55,16 +51,9 @@ function SearchPageClient() { }, [searchResults]); useEffect(() => { - // 自动聚焦搜索框:仅当 URL 中没有搜索参数时 - if (!searchParams.get('q')) { - searchInputRef.current?.focus(); - } - - // 加载搜索历史 - (async () => { - const history = await getSearchHistory(); - setSearchHistory(history); - })(); + // 无搜索参数时聚焦搜索框 + !searchParams.get('q') && searchInputRef.current?.focus(); + getSearchHistory().then(setSearchHistory); }, []); useEffect(() => { @@ -172,13 +161,13 @@ function SearchPageClient() {
{viewMode === 'agg' ? aggregatedResults.map((group) => { const key = `${group[0].title}-${ group[0].year || 'unknown' - }`; + }-${group[0].id}`; return (
跳到第一个源播放 * 点击卡片其他区域 -> 跳到聚合详情页 (/aggregate) */ @@ -161,9 +161,9 @@ const AggregateCard: React.FC = ({
- {/* 集数矩形展示框 - 不透明,无hover效果 */} + {/* 集数矩形展示框 */} {mostFrequentEpisodes && mostFrequentEpisodes > 1 && ( -
+
{mostFrequentEpisodes} diff --git a/src/components/DemoCard.tsx b/src/components/DemoCard.tsx index 26ae4d3..839c7ee 100644 --- a/src/components/DemoCard.tsx +++ b/src/components/DemoCard.tsx @@ -1,7 +1,7 @@ import { Link as LinkIcon, Search } from 'lucide-react'; import Image from 'next/image'; import { useRouter } from 'next/navigation'; -import React from 'react'; +import React, { useState } from 'react'; interface DemoCardProps { id: string; @@ -45,6 +45,7 @@ function SearchCircle({ } const DemoCard = ({ id, title, poster, rate, type }: DemoCardProps) => { + const [hover, setHover] = useState(false); const router = useRouter(); const handleClick = () => { @@ -57,7 +58,7 @@ const DemoCard = ({ id, title, poster, rate, type }: DemoCardProps) => { onClick={handleClick} > {/* 海报图片区域 */} -
+
{title} { )} {/* 悬浮层 - 搜索按钮 */} -
-
- +
+
setHover(true)} + onMouseLeave={() => setHover(false)} + className={`transition-all duration-300 cubic-bezier(0.4, 0, 0.2, 1) ${ + hover ? 'scale-110 rotate-12' : 'scale-90' + }`} + > +
diff --git a/src/components/VideoCard.tsx b/src/components/VideoCard.tsx index 492f681..0e75bdd 100644 --- a/src/components/VideoCard.tsx +++ b/src/components/VideoCard.tsx @@ -111,12 +111,6 @@ export default function VideoCard({ e.preventDefault(); e.stopPropagation(); - // 如果是从收藏夹移除,立即更新UI - if (favorited && from === 'favorites') { - setIsDeleting(true); - onDelete?.(); - } - try { const newState = await toggleFavorite(source, id, { title, @@ -237,23 +231,23 @@ export default function VideoCard({
- {/* 集数矩形展示框 - 增加条件判断:仅当有多个集数且已播放时显示 */} + {/* 继续观看 - 集数矩形展示框 */} {episodes && episodes > 1 && currentEpisode && (
{currentEpisode} + / - / {episodes}
)} - {/* 集数圆形展示框 - 无当前集数且总集数大于 1 时展示 */} - {episodes && episodes > 1 && !currentEpisode && ( -
- + {/* 搜索非聚合 - 集数圆形展示框 */} + {from === 'search' && ( +
+ {episodes}