feat: add global image proxy config

This commit is contained in:
shinya
2025-07-15 22:20:42 +08:00
parent cca4092519
commit 90129c0d69
9 changed files with 165 additions and 16 deletions

View File

@@ -1,3 +1,5 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
'use client';
import { Settings, X } from 'lucide-react';
@@ -10,6 +12,7 @@ export const SettingsButton: React.FC = () => {
const [doubanProxyUrl, setDoubanProxyUrl] = useState('');
const [imageProxyUrl, setImageProxyUrl] = useState('');
const [enableOptimization, setEnableOptimization] = useState(true);
const [enableImageProxy, setEnableImageProxy] = useState(false);
const [mounted, setMounted] = useState(false);
// 确保组件已挂载
@@ -32,9 +35,21 @@ export const SettingsButton: React.FC = () => {
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 =
@@ -74,6 +89,13 @@ export const SettingsButton: React.FC = () => {
}
};
const handleImageProxyToggle = (value: boolean) => {
setEnableImageProxy(value);
if (typeof window !== 'undefined') {
localStorage.setItem('enableImageProxy', JSON.stringify(value));
}
};
const handleSettingsClick = () => {
setIsOpen(!isOpen);
};
@@ -82,6 +104,30 @@ export const SettingsButton: React.FC = () => {
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 = (
<>
@@ -95,9 +141,18 @@ export const SettingsButton: React.FC = () => {
<div className='fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-white dark:bg-gray-900 rounded-xl shadow-xl z-[1001] p-6'>
{/* 标题栏 */}
<div className='flex items-center justify-between mb-6'>
<h3 className='text-xl font-bold text-gray-800 dark:text-gray-200'>
</h3>
<div className='flex items-center gap-3'>
<h3 className='text-xl font-bold text-gray-800 dark:text-gray-200'>
</h3>
<button
onClick={handleResetSettings}
className='px-2 py-1 text-xs text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 border border-red-200 hover:border-red-300 dark:border-red-800 dark:hover:border-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors'
title='重置为默认设置'
>
</button>
</div>
<button
onClick={handleClosePanel}
className='w-8 h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors'
@@ -176,22 +231,51 @@ export const SettingsButton: React.FC = () => {
/>
</div>
{/* 图片代理设置 */}
{/* 图片代理开关 */}
<div className='flex items-center justify-between'>
<div>
<h4 className='text-sm font-medium text-gray-700 dark:text-gray-300'>
</h4>
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
</p>
</div>
<label className='flex items-center cursor-pointer'>
<div className='relative'>
<input
type='checkbox'
className='sr-only peer'
checked={enableImageProxy}
onChange={(e) => handleImageProxyToggle(e.target.checked)}
/>
<div className='w-11 h-6 bg-gray-300 rounded-full peer-checked:bg-green-500 transition-colors dark:bg-gray-600'></div>
<div className='absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5'></div>
</div>
</label>
</div>
{/* 图片代理地址设置 */}
<div className='space-y-3'>
<div>
<h4 className='text-sm font-medium text-gray-700 dark:text-gray-300'>
</h4>
<p className='text-xs text-gray-500 dark:text-gray-400 mt-1'>
URL以加速图片加载
</p>
</div>
<input
type='text'
className='w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent'
className={`w-full px-3 py-2 border rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent transition-colors ${
enableImageProxy
? 'border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400'
: 'border-gray-200 dark:border-gray-700 bg-gray-50 dark:bg-gray-800/50 text-gray-400 dark:text-gray-500 placeholder-gray-400 dark:placeholder-gray-600 cursor-not-allowed'
}`}
placeholder='例如: https://imageproxy.example.com/?url='
value={imageProxyUrl}
onChange={(e) => handleImageProxyUrlChange(e.target.value)}
disabled={!enableImageProxy}
/>
</div>
</div>