import { useState, useEffect, useCallback } from 'react'; import { Paper, Typography, Box, Checkbox, Button, FormControlLabel, Alert, Snackbar, } from '@mui/material'; import RefreshIcon from '@mui/icons-material/Refresh'; import WarningIcon from '@mui/icons-material/Warning'; import { storageUtil } from '@/utils/chromeStorage'; import type { StorageCleanerOptions, CleaningResult, StorageCleanerPreferences } from 'types/storage'; import { getCurrentTab, isRestrictedUrl, clearStorage, formatCleaningResult, } from '@/utils/storageCleaner'; const DEFAULT_OPTIONS: StorageCleanerOptions = { localStorage: true, sessionStorage: true, indexedDB: true, cookies: true, cacheStorage: true, serviceWorkers: true, }; const DEFAULT_PREFERENCES: StorageCleanerPreferences = { autoRefresh: true, selectedTypes: DEFAULT_OPTIONS, }; export default function StorageCleanerPage() { const [domain, setDomain] = useState(''); const [error, setError] = useState(''); const [options, setOptions] = useState(DEFAULT_OPTIONS); const [autoRefresh, setAutoRefresh] = useState(true); const [loading, setLoading] = useState(false); const [result, setResult] = useState(null); const [showConfirm, setShowConfirm] = useState(false); const [snackbar, setSnackbar] = useState<{ open: boolean; message: string }>({ open: false, message: '', }); // Load tab info and user preferences useEffect(() => { const loadInfo = async () => { const tab = await getCurrentTab(); if (!tab || !tab.url) { setError('无法获取当前标签页'); return; } if (isRestrictedUrl(tab.url)) { setError('存储清理功能不支持此页面'); return; } setDomain(new URL(tab.url).hostname); // Load user preferences const prefs = await storageUtil.get( 'storageCleaner/preferences', DEFAULT_PREFERENCES, ); setAutoRefresh(prefs?.autoRefresh ?? DEFAULT_PREFERENCES.autoRefresh); setOptions(prefs?.selectedTypes ?? DEFAULT_PREFERENCES.selectedTypes); }; loadInfo(); }, []); const handleOptionChange = useCallback((key: keyof StorageCleanerOptions) => { setOptions((prev) => ({ ...prev, [key]: !prev[key] })); }, []); const handleClean = useCallback(async () => { const tab = await getCurrentTab(); if (!tab || !tab.id || !tab.url) { setSnackbar({ open: true, message: '无法获取当前标签页' }); return; } setLoading(true); try { const cleaningResult = await clearStorage(tab.id, tab.url, options); setResult(cleaningResult); // Save user preferences await storageUtil.set('storageCleaner/preferences', { autoRefresh, selectedTypes: options, }); // Auto refresh if enabled if (autoRefresh && cleaningResult.success && tab.id !== undefined) { setSnackbar({ open: true, message: '页面即将刷新,Popup 将关闭' }); setTimeout(() => { chrome.tabs.reload(tab.id!); }, 1500); } } catch (err) { setSnackbar({ open: true, message: `清理失败: ${String(err)}` }); } finally { setLoading(false); setShowConfirm(false); } }, [options, autoRefresh]); const handleRefresh = useCallback(async () => { const tab = await getCurrentTab(); if (tab?.id !== undefined) { setSnackbar({ open: true, message: '页面即将刷新,Popup 将关闭' }); setTimeout(() => { chrome.tabs.reload(tab.id!); }, 1500); } }, []); if (error) { return ( }> {error} ); } return ( {/* Header */} 存储清理 当前页面: {domain || '加载中...'} {/* Storage Type Options */} 选择要清理的存储类型: handleOptionChange('localStorage')} /> } label="localStorage" /> handleOptionChange('sessionStorage')} /> } label="sessionStorage" /> handleOptionChange('indexedDB')} /> } label="IndexedDB" /> handleOptionChange('cookies')} /> } label="Cookies" /> handleOptionChange('cacheStorage')} /> } label="Cache Storage" /> handleOptionChange('serviceWorkers')} /> } label="Service Workers" /> {/* Auto Refresh Option */} setAutoRefresh(e.target.checked)} /> } label="清理完成后自动刷新页面" /> {/* Action Buttons */} {/* Result Display */} {result && ( {result.success ? formatCleaningResult(result) : result.error || '清理失败'} {!autoRefresh && result.success && ( )} )} {/* Confirmation Dialog */} {showConfirm && ( 确认清理 将清理以下存储类型: {options.localStorage && ( - localStorage )} {options.sessionStorage && ( - sessionStorage )} {options.indexedDB && - IndexedDB} {options.cookies && - Cookies} {options.cacheStorage && ( - Cache Storage )} {options.serviceWorkers && ( - Service Workers )} 此操作不可撤销。 )} {/* Snackbar */} setSnackbar({ ...snackbar, open: false })} > {snackbar.message} ); }