"use client"; import { useState, useEffect } from "react"; import { useTranslate } from "@/hooks/useTranslate"; import { useToast } from "@/components/ui/use-toast"; import { Trash2, Loader2, HardDrive } from "lucide-react"; import { CacheModeSwitch } from "@/components/settings/CacheModeSwitch"; import { Label } from "@/components/ui/label"; import type { TTLConfigData } from "@/types/komga"; import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card"; interface CacheSettingsProps { initialTTLConfig: TTLConfigData | null; } interface CacheSizeInfo { sizeInBytes: number; itemCount: number; } export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) { const { t } = useTranslate(); const { toast } = useToast(); const [isCacheClearing, setIsCacheClearing] = useState(false); const [isServiceWorkerClearing, setIsServiceWorkerClearing] = useState(false); const [serverCacheSize, setServerCacheSize] = useState(null); const [swCacheSize, setSwCacheSize] = useState(null); const [isLoadingCacheSize, setIsLoadingCacheSize] = useState(true); const [ttlConfig, setTTLConfig] = useState( initialTTLConfig || { defaultTTL: 5, homeTTL: 5, librariesTTL: 1440, seriesTTL: 5, booksTTL: 5, imagesTTL: 1440, } ); const formatBytes = (bytes: number): string => { if (bytes === 0) return "0 B"; const k = 1024; const sizes = ["B", "KB", "MB", "GB"]; const i = Math.floor(Math.log(bytes) / Math.log(k)); return `${(bytes / Math.pow(k, i)).toFixed(2)} ${sizes[i]}`; }; const fetchCacheSize = async () => { setIsLoadingCacheSize(true); try { // Récupérer la taille du cache serveur const serverResponse = await fetch("/api/komga/cache/size"); if (serverResponse.ok) { const serverData = await serverResponse.json(); setServerCacheSize({ sizeInBytes: serverData.sizeInBytes, itemCount: serverData.itemCount, }); } // Calculer la taille du cache Service Worker if ("caches" in window) { const cacheNames = await caches.keys(); let totalSize = 0; for (const cacheName of cacheNames) { const cache = await caches.open(cacheName); const requests = await cache.keys(); for (const request of requests) { const response = await cache.match(request); if (response) { const blob = await response.clone().blob(); totalSize += blob.size; } } } setSwCacheSize(totalSize); } } catch (error) { console.error("Erreur lors de la récupération de la taille du cache:", error); } finally { setIsLoadingCacheSize(false); } }; useEffect(() => { fetchCacheSize(); }, []); const handleClearCache = async () => { setIsCacheClearing(true); try { const response = await fetch("/api/komga/cache/clear", { method: "POST", }); if (!response.ok) { const data = await response.json(); throw new Error(data.error || t("settings.cache.error.message")); } toast({ title: t("settings.cache.title"), description: t("settings.cache.messages.cleared"), }); // Rafraîchir la taille du cache await fetchCacheSize(); } catch (error) { console.error("Erreur:", error); toast({ variant: "destructive", title: t("settings.cache.error.title"), description: t("settings.cache.error.message"), }); } finally { setIsCacheClearing(false); } }; const handleClearServiceWorkerCache = async () => { setIsServiceWorkerClearing(true); try { if ("serviceWorker" in navigator && "caches" in window) { const cacheNames = await caches.keys(); await Promise.all(cacheNames.map((cacheName) => caches.delete(cacheName))); toast({ title: t("settings.cache.title"), description: t("settings.cache.messages.serviceWorkerCleared"), }); // Rafraîchir la taille du cache await fetchCacheSize(); } } catch (error) { console.error("Erreur lors de la suppression des caches:", error); toast({ variant: "destructive", title: t("settings.cache.error.title"), description: t("settings.cache.error.serviceWorkerMessage"), }); } finally { setIsServiceWorkerClearing(false); } }; const handleTTLChange = (event: React.ChangeEvent) => { const { name, value } = event.target; setTTLConfig((prev) => ({ ...prev, [name]: parseInt(value || "0", 10), })); }; const handleSaveTTL = async (event: React.FormEvent) => { event.preventDefault(); try { const response = await fetch("/api/komga/ttl-config", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify(ttlConfig), }); if (!response.ok) { const data = await response.json(); throw new Error(data.error || t("settings.cache.error.message")); } toast({ title: t("settings.cache.title"), description: t("settings.cache.messages.ttlSaved"), }); } catch (error) { console.error("Erreur lors de la sauvegarde:", error); toast({ variant: "destructive", title: t("settings.cache.error.title"), description: t("settings.cache.error.messagettl"), }); } }; return ( {t("settings.cache.title")} {t("settings.cache.description")}

{t("settings.cache.mode.description")}

{/* Informations sur la taille du cache */}
{t("settings.cache.size.title")}
{isLoadingCacheSize ? (
{t("settings.cache.size.loading")}
) : (
{t("settings.cache.size.server")}
{serverCacheSize ? (
{formatBytes(serverCacheSize.sizeInBytes)}
{t("settings.cache.size.items", { count: serverCacheSize.itemCount })}
) : (
{t("settings.cache.size.error")}
)}
{t("settings.cache.size.serviceWorker")}
{swCacheSize !== null ? (
{formatBytes(swCacheSize)}
) : (
{t("settings.cache.size.error")}
)}
)}
{/* Formulaire TTL */}
); }