增加动漫磁力搜索

This commit is contained in:
mtvpls
2025-12-28 14:55:35 +08:00
parent ab856a02cf
commit 20021dce19
10 changed files with 724 additions and 24 deletions
+111 -9
View File
@@ -1,7 +1,7 @@
/* eslint-disable react-hooks/exhaustive-deps, @typescript-eslint/no-explicit-any,@typescript-eslint/no-non-null-assertion,no-empty */
'use client';
import { ChevronUp, RefreshCw, Search, X, Film, HardDrive } from 'lucide-react';
import { ChevronUp, RefreshCw, Search, X, Film, HardDrive, Magnet } from 'lucide-react';
import { useRouter, useSearchParams } from 'next/navigation';
import React, { startTransition, Suspense, useEffect, useMemo, useRef, useState } from 'react';
@@ -13,12 +13,14 @@ import {
subscribeToDataUpdates,
} from '@/lib/db.client';
import { SearchResult } from '@/lib/types';
import { getAuthInfoFromBrowserCookie } from '@/lib/auth';
import PageLayout from '@/components/PageLayout';
import SearchResultFilter, { SearchFilterCategory } from '@/components/SearchResultFilter';
import SearchSuggestions from '@/components/SearchSuggestions';
import VideoCard, { VideoCardHandle } from '@/components/VideoCard';
import PansouSearch from '@/components/PansouSearch';
import AcgSearch from '@/components/AcgSearch';
import CapsuleSwitch from '@/components/CapsuleSwitch';
function SearchPageClient() {
@@ -26,10 +28,14 @@ function SearchPageClient() {
const [searchHistory, setSearchHistory] = useState<string[]>([]);
// 返回顶部按钮显示状态
const [showBackToTop, setShowBackToTop] = useState(false);
// 选项卡状态: 'video' 或 'pansou'
const [activeTab, setActiveTab] = useState<'video' | 'pansou'>('video');
// 选项卡状态: 'video' 或 'pansou' 或 'acg'
const [activeTab, setActiveTab] = useState<'video' | 'pansou' | 'acg'>('video');
// Pansou 搜索触发标志
const [triggerPansouSearch, setTriggerPansouSearch] = useState(false);
// ACG 搜索触发标志
const [triggerAcgSearch, setTriggerAcgSearch] = useState(false);
// 用户权限
const [userRole, setUserRole] = useState<'owner' | 'admin' | 'user' | null>(null);
const router = useRouter();
const searchParams = useSearchParams();
@@ -393,12 +399,48 @@ function SearchPageClient() {
if (activeTab === 'pansou' && searchQuery.trim() && showResults) {
setTriggerPansouSearch(prev => !prev);
}
// 如果切换到 ACG 磁力搜索选项卡,且有搜索关键词,且已显示结果,则触发搜索
if (activeTab === 'acg' && searchQuery.trim() && showResults) {
setTriggerAcgSearch(prev => !prev);
}
}, [activeTab]);
useEffect(() => {
// 从 URL 读取搜索类型参数
const typeParam = searchParams.get('type');
const query = searchParams.get('q');
if (typeParam === 'pansou' || typeParam === 'acg') {
setActiveTab(typeParam);
// 如果有搜索关键词且显示结果,触发对应的搜索
if (query && query.trim()) {
setSearchQuery(query);
setShowResults(true);
// 延迟触发搜索,确保组件已经切换到正确的标签页
setTimeout(() => {
if (typeParam === 'pansou') {
setTriggerPansouSearch(prev => !prev);
} else if (typeParam === 'acg') {
setTriggerAcgSearch(prev => !prev);
}
}, 100);
}
} else if (typeParam === 'video') {
setActiveTab('video');
} else if (!typeParam && query) {
// 如果没有 type 参数但有查询,默认为 video
setActiveTab('video');
}
// 无搜索参数时聚焦搜索框
!searchParams.get('q') && document.getElementById('searchInput')?.focus();
// 获取用户权限
const authInfo = getAuthInfoFromBrowserCookie();
setUserRole(authInfo?.role || null);
// 初始加载搜索历史
getSearchHistory().then(setSearchHistory);
@@ -710,11 +752,16 @@ function SearchPageClient() {
// 根据当前选项卡执行不同的搜索
if (activeTab === 'video') {
// 影视搜索
router.push(`/search?q=${encodeURIComponent(trimmed)}`);
router.push(`/search?q=${encodeURIComponent(trimmed)}&type=video`);
// 其余由 searchParams 变化的 effect 处理
} else if (activeTab === 'pansou') {
// 网盘搜索 - 触发搜索
router.push(`/search?q=${encodeURIComponent(trimmed)}&type=pansou`);
setTriggerPansouSearch(prev => !prev); // 切换状态来触发搜索
} else if (activeTab === 'acg') {
// ACG 磁力搜索 - 触发搜索
router.push(`/search?q=${encodeURIComponent(trimmed)}&type=acg`);
setTriggerAcgSearch(prev => !prev);
}
};
@@ -725,8 +772,20 @@ function SearchPageClient() {
// 自动执行搜索
setShowResults(true);
router.push(`/search?q=${encodeURIComponent(suggestion)}`);
// 其余由 searchParams 变化的 effect 处理
// 根据当前选项卡执行不同的搜索
if (activeTab === 'video') {
// 影视搜索
router.push(`/search?q=${encodeURIComponent(suggestion)}&type=video`);
// 其余由 searchParams 变化的 effect 处理
} else if (activeTab === 'pansou') {
// 网盘搜索 - 触发搜索
router.push(`/search?q=${encodeURIComponent(suggestion)}&type=pansou`);
setTriggerPansouSearch(prev => !prev);
} else if (activeTab === 'acg') {
// ACG 磁力搜索 - 触发搜索
router.push(`/search?q=${encodeURIComponent(suggestion)}&type=acg`);
setTriggerAcgSearch(prev => !prev);
}
};
// 返回顶部功能
@@ -743,6 +802,17 @@ function SearchPageClient() {
}
};
// 处理标签切换
const handleTabChange = (newTab: 'video' | 'pansou' | 'acg') => {
setActiveTab(newTab);
// 如果有搜索关键词,更新 URL
const currentQuery = searchParams.get('q');
if (currentQuery) {
router.push(`/search?q=${encodeURIComponent(currentQuery)}&type=${newTab}`);
}
};
return (
<PageLayout activePath='/search'>
<div className='px-4 sm:px-10 py-4 sm:py-8 overflow-visible mb-10'>
@@ -814,9 +884,19 @@ function SearchPageClient() {
value: 'pansou',
icon: <HardDrive size={16} />,
},
// 仅管理员和站长显示 ACG 磁力搜索
...(userRole === 'admin' || userRole === 'owner'
? [
{
label: '动漫磁力',
value: 'acg' as const,
icon: <Magnet size={16} />,
},
]
: []),
]}
active={activeTab}
onChange={(value) => setActiveTab(value as 'video' | 'pansou')}
onChange={(value) => handleTabChange(value as 'video' | 'pansou' | 'acg')}
/>
</div>
</div>
@@ -975,7 +1055,7 @@ function SearchPageClient() {
</div>
)}
</>
) : (
) : activeTab === 'pansou' ? (
<>
{/* 网盘搜索结果 */}
<div className='mb-4'>
@@ -988,6 +1068,19 @@ function SearchPageClient() {
triggerSearch={triggerPansouSearch}
/>
</>
) : (
<>
{/* ACG 磁力搜索结果 */}
<div className='mb-4'>
<h2 className='text-xl font-bold text-gray-800 dark:text-gray-200'>
</h2>
</div>
<AcgSearch
keyword={searchQuery}
triggerSearch={triggerAcgSearch}
/>
</>
)}
</section>
) : searchHistory.length > 0 ? (
@@ -1018,11 +1111,20 @@ function SearchPageClient() {
if (activeTab === 'video') {
// 影视搜索
router.push(
`/search?q=${encodeURIComponent(item.trim())}`
`/search?q=${encodeURIComponent(item.trim())}&type=video`
);
} else if (activeTab === 'pansou') {
// 网盘搜索
router.push(
`/search?q=${encodeURIComponent(item.trim())}&type=pansou`
);
setTriggerPansouSearch(prev => !prev);
} else if (activeTab === 'acg') {
// ACG 磁力搜索
router.push(
`/search?q=${encodeURIComponent(item.trim())}&type=acg`
);
setTriggerAcgSearch(prev => !prev);
}
}}
className='px-4 py-2 bg-gray-500/10 hover:bg-gray-300 rounded-full text-sm text-gray-700 transition-colors duration-200 dark:bg-gray-700/50 dark:hover:bg-gray-600 dark:text-gray-300'