/* eslint-disable @typescript-eslint/no-explicit-any */ 'use client'; import { Settings, X } from 'lucide-react'; import { useEffect, useState } from 'react'; import { createPortal } from 'react-dom'; export const SettingsButton: React.FC = () => { const [isOpen, setIsOpen] = useState(false); const [defaultAggregateSearch, setDefaultAggregateSearch] = useState(true); const [doubanProxyUrl, setDoubanProxyUrl] = useState(''); const [imageProxyUrl, setImageProxyUrl] = useState(''); const [enableOptimization, setEnableOptimization] = useState(true); const [enableImageProxy, setEnableImageProxy] = useState(false); const [mounted, setMounted] = useState(false); // 确保组件已挂载 useEffect(() => { setMounted(true); }, []); // 从 localStorage 读取设置 useEffect(() => { if (typeof window !== 'undefined') { const savedAggregateSearch = localStorage.getItem( 'defaultAggregateSearch' ); if (savedAggregateSearch !== null) { setDefaultAggregateSearch(JSON.parse(savedAggregateSearch)); } const savedDoubanProxyUrl = localStorage.getItem('doubanProxyUrl'); if (savedDoubanProxyUrl !== null) { setDoubanProxyUrl(savedDoubanProxyUrl); } const savedEnableImageProxy = localStorage.getItem('enableImageProxy'); const defaultImageProxy = (window as any).RUNTIME_CONFIG?.IMAGE_PROXY || ''; if (savedEnableImageProxy !== null) { setEnableImageProxy(JSON.parse(savedEnableImageProxy)); } else if (defaultImageProxy) { // 如果有默认图片代理配置,则默认开启 setEnableImageProxy(true); } const savedImageProxyUrl = localStorage.getItem('imageProxyUrl'); if (savedImageProxyUrl !== null) { setImageProxyUrl(savedImageProxyUrl); } else if (defaultImageProxy) { setImageProxyUrl(defaultImageProxy); } const savedEnableOptimization = localStorage.getItem('enableOptimization'); if (savedEnableOptimization !== null) { setEnableOptimization(JSON.parse(savedEnableOptimization)); } } }, []); // 保存设置到 localStorage const handleAggregateToggle = (value: boolean) => { setDefaultAggregateSearch(value); if (typeof window !== 'undefined') { localStorage.setItem('defaultAggregateSearch', JSON.stringify(value)); } }; const handleDoubanProxyUrlChange = (value: string) => { setDoubanProxyUrl(value); if (typeof window !== 'undefined') { localStorage.setItem('doubanProxyUrl', value); } }; const handleImageProxyUrlChange = (value: string) => { setImageProxyUrl(value); if (typeof window !== 'undefined') { localStorage.setItem('imageProxyUrl', value); } }; const handleOptimizationToggle = (value: boolean) => { setEnableOptimization(value); if (typeof window !== 'undefined') { localStorage.setItem('enableOptimization', JSON.stringify(value)); } }; const handleImageProxyToggle = (value: boolean) => { setEnableImageProxy(value); if (typeof window !== 'undefined') { localStorage.setItem('enableImageProxy', JSON.stringify(value)); } }; const handleSettingsClick = () => { setIsOpen(!isOpen); }; const handleClosePanel = () => { setIsOpen(false); }; // 重置所有设置为默认值 const handleResetSettings = () => { const defaultImageProxy = (window as any).RUNTIME_CONFIG?.IMAGE_PROXY || ''; // 重置所有状态 setDefaultAggregateSearch(true); setEnableOptimization(true); setDoubanProxyUrl(''); setEnableImageProxy(!!defaultImageProxy); setImageProxyUrl(defaultImageProxy); // 保存到 localStorage if (typeof window !== 'undefined') { localStorage.setItem('defaultAggregateSearch', JSON.stringify(true)); localStorage.setItem('enableOptimization', JSON.stringify(true)); localStorage.setItem('doubanProxyUrl', ''); localStorage.setItem( 'enableImageProxy', JSON.stringify(!!defaultImageProxy) ); localStorage.setItem('imageProxyUrl', defaultImageProxy); } }; // 设置面板内容 const settingsPanel = ( <> {/* 背景遮罩 */}
{/* 设置面板 */}
{/* 标题栏 */}

本地设置

{/* 设置项 */}
{/* 默认聚合搜索结果 */}

默认聚合搜索结果

搜索时默认按标题和年份聚合显示结果

{/* 优选和测速 */}

启用优选和测速

如出现播放器劫持问题可关闭

{/* 豆瓣代理设置 */}

豆瓣数据代理

设置代理URL以绕过豆瓣访问限制,留空则使用服务端API

handleDoubanProxyUrlChange(e.target.value)} />
{/* 图片代理开关 */}

启用图片代理

启用后,所有图片加载将通过代理服务器

{/* 图片代理地址设置 */}

图片代理地址

仅在启用图片代理时生效

handleImageProxyUrlChange(e.target.value)} disabled={!enableImageProxy} />
{/* 底部说明 */}

这些设置保存在本地浏览器中

); return ( <> {/* 使用 Portal 将设置面板渲染到 document.body */} {isOpen && mounted && createPortal(settingsPanel, document.body)} ); };