import { AlertCircle, Database, HardDrive, RefreshCw, Trash2 } from "lucide-react" import { useCallback, useEffect, useRef, useState } from "react" import { useTranslation } from "react-i18next" import { toast } from "sonner" import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Progress } from "@/components/ui/progress" import { Separator } from "@/components/ui/separator" import { formatFileSize } from "@/lib/utils" import { type CacheStatistics, indexedDBCacheService } from "../services/indexeddb-cache-service" /** * Модальное окно настроек кэширования */ export function CacheSettingsModal() { const { t } = useTranslation() const [isLoading, setIsLoading] = useState(false) const [cacheStats, setCacheStats] = useState(null) const [clearingProgress, setClearingProgress] = useState(0) const [isClearing, setIsClearing] = useState(false) const timeoutRef = useRef(null) const intervalRef = useRef(null) // Загрузка статистики кэша const loadCacheStats = useCallback(async () => { setIsLoading(true) try { const stats = await indexedDBCacheService.getCacheStatistics() setCacheStats(stats) } catch (error) { console.error("Ошибка загрузки статистики кэша:", error) toast.error(t("browser.media.cache.errors.loadStats")) } finally { setIsLoading(false) } }, [t]) // Очистка кэша превью const clearPreviewCache = useCallback(async () => { setIsClearing(true) setClearingProgress(0) try { // Показываем прогресс intervalRef.current = setInterval(() => { setClearingProgress((prev) => Math.min(prev + 20, 90)) }, 100) await indexedDBCacheService.clearPreviewCache() if (intervalRef.current) { clearInterval(intervalRef.current) intervalRef.current = null } setClearingProgress(100) toast.success(t("browser.media.cache.success.clearPreview")) await loadCacheStats() } catch (error) { console.error("Ошибка очистки кэша превью:", error) toast.error(t("browser.media.cache.errors.clearPreview")) if (intervalRef.current) { clearInterval(intervalRef.current) intervalRef.current = null } } finally { timeoutRef.current = setTimeout(() => { setClearingProgress(0) setIsClearing(false) timeoutRef.current = null }, 500) } }, [loadCacheStats, t]) // Очистка кэша кадров const clearFrameCache = useCallback(async () => { setIsClearing(true) setClearingProgress(0) try { const progressInterval = setInterval(() => { setClearingProgress((prev) => Math.min(prev + 20, 90)) }, 100) await indexedDBCacheService.clearFrameCache() clearInterval(progressInterval) setClearingProgress(100) toast.success(t("browser.media.cache.success.clearFrames")) await loadCacheStats() } catch (error) { console.error("Ошибка очистки кэша кадров:", error) toast.error(t("browser.media.cache.errors.clearFrames")) } finally { setTimeout(() => { setClearingProgress(0) setIsClearing(false) }, 500) } }, [loadCacheStats, t]) // Очистка кэша распознавания const clearRecognitionCache = useCallback(async () => { setIsClearing(true) setClearingProgress(0) try { const progressInterval = setInterval(() => { setClearingProgress((prev) => Math.min(prev + 20, 90)) }, 100) await indexedDBCacheService.clearRecognitionCache() clearInterval(progressInterval) setClearingProgress(100) toast.success(t("browser.media.cache.success.clearRecognition")) await loadCacheStats() } catch (error) { console.error("Ошибка очистки кэша распознавания:", error) toast.error(t("browser.media.cache.errors.clearRecognition")) } finally { setTimeout(() => { setClearingProgress(0) setIsClearing(false) }, 500) } }, [loadCacheStats, t]) // Очистка всего кэша const clearAllCache = useCallback(async () => { setIsClearing(true) setClearingProgress(0) try { const progressInterval = setInterval(() => { setClearingProgress((prev) => Math.min(prev + 10, 90)) }, 50) await indexedDBCacheService.clearAllCache() clearInterval(progressInterval) setClearingProgress(100) toast.success(t("browser.media.cache.success.clearAll")) await loadCacheStats() } catch (error) { console.error("Ошибка очистки всего кэша:", error) toast.error(t("browser.media.cache.errors.clearAll")) } finally { setTimeout(() => { setClearingProgress(0) setIsClearing(false) }, 500) } }, [loadCacheStats, t]) // Очистка устаревшего кэша const cleanupExpiredCache = useCallback(async () => { try { await indexedDBCacheService.cleanupExpiredCache() toast.success(t("browser.media.cache.success.cleanupExpired")) await loadCacheStats() } catch (error) { console.error("Ошибка очистки устаревшего кэша:", error) toast.error(t("browser.media.cache.errors.cleanupExpired")) } }, [loadCacheStats, t]) // Загрузка статистики при монтировании useEffect(() => { void loadCacheStats() }, [loadCacheStats]) // Очистка таймеров при размонтировании useEffect(() => { return () => { if (timeoutRef.current) { clearTimeout(timeoutRef.current) timeoutRef.current = null } if (intervalRef.current) { clearInterval(intervalRef.current) intervalRef.current = null } } }, []) if (isLoading || !cacheStats) { return (
) } return (
{t("browser.media.cache.title")} {t("browser.media.cache.description")} {/* Общая статистика */}
{t("browser.media.cache.totalSize")} {formatFileSize(cacheStats.totalSize)}

{t("browser.media.cache.usage", { used: formatFileSize(cacheStats.totalSize), total: "500 MB", })}

{/* Кэш превью */}

{t("browser.media.cache.previewCache.title")}

{t("browser.media.cache.previewCache.info", { count: cacheStats.previewCache.count, size: formatFileSize(cacheStats.previewCache.size), })}

{/* Кэш кадров */}

{t("browser.media.cache.frameCache.title")}

{t("browser.media.cache.frameCache.info", { count: cacheStats.frameCache.count, size: formatFileSize(cacheStats.frameCache.size), })}

{/* Кэш распознавания */}

{t("browser.media.cache.recognitionCache.title")}

{t("browser.media.cache.recognitionCache.info", { count: cacheStats.recognitionCache.count, size: formatFileSize(cacheStats.recognitionCache.size), })}

{/* Кэш субтитров */}

{t("browser.media.cache.subtitleCache.title")}

{t("browser.media.cache.subtitleCache.info", { count: cacheStats.subtitleCache.count, size: formatFileSize(cacheStats.subtitleCache.size), })}

{/* Прогресс очистки */} {clearingProgress > 0 && (
{t("browser.media.cache.clearing")} {clearingProgress}%
)} {/* Кнопка очистки всего */}
{t("browser.media.cache.warning")}
{/* Информация о хранилище */} {t("browser.media.cache.storage.title")}
{t("browser.media.cache.storage.technology")} IndexedDB
{t("browser.media.cache.storage.maxSize")} 500 MB
{t("browser.media.cache.storage.autoCleanup")} {t("browser.media.cache.storage.autoCleanupValue")}
) }