diff --git a/src/components/PansouSearch.tsx b/src/components/PansouSearch.tsx index b9136c5..915b6db 100644 --- a/src/components/PansouSearch.tsx +++ b/src/components/PansouSearch.tsx @@ -5,6 +5,7 @@ import { AlertCircle, Copy, ExternalLink, Loader2, RefreshCw } from 'lucide-reac import { useRouter } from 'next/navigation'; import { useCallback, useEffect, useState } from 'react'; +import Toast, { ToastProps } from '@/components/Toast'; import { PansouLink, PansouSearchResult } from '@/lib/pansou.client'; interface PansouSearchProps { @@ -60,6 +61,7 @@ export default function PansouSearch({ const [selectedType, setSelectedType] = useState('all'); // 'all' 表示显示全部 const [transferingUrl, setTransferingUrl] = useState(null); const [playingUrl, setPlayingUrl] = useState(null); + const [toast, setToast] = useState(null); // 提取搜索函数,以便在重试时调用 const searchPansou = useCallback(async () => { @@ -141,9 +143,17 @@ export default function PansouSearch({ throw new Error(data.error || '转存失败'); } - window.alert(`转存成功,已保存到:${data.targetPath}`); + setToast({ + message: `转存成功,已保存到:${data.targetPath}`, + type: 'success', + onClose: () => setToast(null), + }); } catch (err: any) { - window.alert(err?.message || '转存失败'); + setToast({ + message: err?.message || '转存失败', + type: 'error', + onClose: () => setToast(null), + }); } finally { setTransferingUrl(null); } @@ -173,230 +183,245 @@ export default function PansouSearch({ `/play?source=quark-temp&id=${encodeURIComponent(data.id)}&title=${encodeURIComponent(data.title || keyword)}` ); } catch (err: any) { - window.alert(err?.message || '立即播放失败'); + setToast({ + message: err?.message || '立即播放失败', + type: 'error', + onClose: () => setToast(null), + }); } finally { setPlayingUrl(null); } }; - if (loading) { - return ( -
-
- -

- 正在搜索网盘资源... -

+ const renderBody = () => { + if (loading) { + return ( +
+
+ +

+ 正在搜索网盘资源... +

+
-
- ); - } + ); + } + + if (error) { + return ( +
+
+ +

{error}

+ +
+
+ ); + } + + if (!results || results.total === 0 || !results.merged_by_type) { + return ( +
+
+ +

+ 未找到相关资源 +

+
+
+ ); + } + + const cloudTypes = Object.keys(results.merged_by_type || {}); + + // 过滤显示的网盘类型 + const filteredCloudTypes = selectedType === 'all' + ? cloudTypes + : cloudTypes.filter(type => type === selectedType); + + // 计算每种网盘类型的数量 + const typeStats = cloudTypes.map(type => ({ + type, + count: results.merged_by_type?.[type]?.length || 0, + })); - if (error) { return ( -
-
- -

{error}

+ <> + {/* 搜索结果统计 */} +
+ 找到 {results.total} 个资源 +
+ + {/* 网盘类型过滤器 */} +
+ {typeStats.map(({ type, count }) => { + const typeName = CLOUD_TYPE_NAMES[type] || type; + + return ( + + ); + })}
-
- ); - } - if (!results || results.total === 0 || !results.merged_by_type) { - return ( -
-
- -

- 未找到相关资源 -

-
-
- ); - } + {/* 按网盘类型分类显示 */} + {filteredCloudTypes.map((cloudType) => { + const links = results.merged_by_type?.[cloudType]; + if (!links || links.length === 0) return null; - const cloudTypes = Object.keys(results.merged_by_type || {}); - - // 过滤显示的网盘类型 - const filteredCloudTypes = selectedType === 'all' - ? cloudTypes - : cloudTypes.filter(type => type === selectedType); - - // 计算每种网盘类型的数量 - const typeStats = cloudTypes.map(type => ({ - type, - count: results.merged_by_type?.[type]?.length || 0, - })); - - return ( -
- {/* 搜索结果统计 */} -
- 找到 {results.total} 个资源 -
- - {/* 网盘类型过滤器 */} -
- - {typeStats.map(({ type, count }) => { - const typeName = CLOUD_TYPE_NAMES[type] || type; + const typeName = CLOUD_TYPE_NAMES[cloudType] || cloudType; + const typeColor = CLOUD_TYPE_COLORS[cloudType] || CLOUD_TYPE_COLORS.others; return ( - +
+ {/* 网盘类型标题 */} +
+ + {typeName} + + + {links.length} 个链接 + +
+ + {/* 链接列表 */} +
+ {links.map((link: PansouLink, index: number) => ( +
+ {/* 资源标题 */} + {link.note && ( +
+ {link.note} +
+ )} + + {/* 链接和密码 */} +
+
+
+ {link.url} +
+ {link.password && ( +
+ 提取码: {link.password} +
+ )} +
+ + {/* 操作按钮 */} +
+ {cloudType === 'quark' && ( + <> + + + + )} + + +
+
+ + {/* 来源和时间 */} +
+ {link.source && ( + 来源: {link.source} + )} + {link.datetime && ( + {new Date(link.datetime).toLocaleDateString()} + )} +
+ + {/* 图片预览 */} + {link.images && link.images.length > 0 && ( +
+ {link.images.map((img, imgIndex) => ( + + ))} +
+ )} +
+ ))} +
+
); })} + + ); + }; + + return ( + <> +
+ {renderBody()}
- - {/* 按网盘类型分类显示 */} - {filteredCloudTypes.map((cloudType) => { - const links = results.merged_by_type?.[cloudType]; - if (!links || links.length === 0) return null; - - const typeName = CLOUD_TYPE_NAMES[cloudType] || cloudType; - const typeColor = CLOUD_TYPE_COLORS[cloudType] || CLOUD_TYPE_COLORS.others; - - return ( -
- {/* 网盘类型标题 */} -
- - {typeName} - - - {links.length} 个链接 - -
- - {/* 链接列表 */} -
- {links.map((link: PansouLink, index: number) => ( -
- {/* 资源标题 */} - {link.note && ( -
- {link.note} -
- )} - - {/* 链接和密码 */} -
-
-
- {link.url} -
- {link.password && ( -
- 提取码: {link.password} -
- )} -
- - {/* 操作按钮 */} -
- {cloudType === 'quark' && ( - <> - - - - )} - - -
-
- - {/* 来源和时间 */} -
- {link.source && ( - 来源: {link.source} - )} - {link.datetime && ( - {new Date(link.datetime).toLocaleDateString()} - )} -
- - {/* 图片预览 */} - {link.images && link.images.length > 0 && ( -
- {link.images.map((img, imgIndex) => ( - - ))} -
- )} -
- ))} -
-
- ); - })} -
+ {toast && } + ); }