chore: update various components and services for improved functionality and consistency, including formatting adjustments and minor refactors
This commit is contained in:
@@ -129,7 +129,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
if (response) {
|
||||
const blob = await response.clone().blob();
|
||||
totalSize += blob.size;
|
||||
|
||||
|
||||
// Calculer la taille du cache API séparément
|
||||
if (cacheName.includes("api")) {
|
||||
apiSize += blob.size;
|
||||
@@ -214,19 +214,24 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
try {
|
||||
const urlObj = new URL(url);
|
||||
const path = urlObj.pathname;
|
||||
const segments = path.split('/').filter(Boolean);
|
||||
|
||||
if (segments.length === 0) return '/';
|
||||
|
||||
const segments = path.split("/").filter(Boolean);
|
||||
|
||||
if (segments.length === 0) return "/";
|
||||
|
||||
// Pour /api/komga/images, grouper par type (series/books)
|
||||
if (segments[0] === 'api' && segments[1] === 'komga' && segments[2] === 'images' && segments[3]) {
|
||||
if (
|
||||
segments[0] === "api" &&
|
||||
segments[1] === "komga" &&
|
||||
segments[2] === "images" &&
|
||||
segments[3]
|
||||
) {
|
||||
return `/${segments[0]}/${segments[1]}/${segments[2]}/${segments[3]}`;
|
||||
}
|
||||
|
||||
|
||||
// Pour les autres, garder juste le premier segment
|
||||
return `/${segments[0]}`;
|
||||
} catch {
|
||||
return 'Autres';
|
||||
return "Autres";
|
||||
}
|
||||
};
|
||||
|
||||
@@ -255,8 +260,8 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
// Trier par date (le plus récent en premier) basé sur le paramètre v
|
||||
Object.keys(grouped).forEach((key) => {
|
||||
grouped[key].sort((a, b) => {
|
||||
const aVersion = new URL(a.url).searchParams.get('v') || '0';
|
||||
const bVersion = new URL(b.url).searchParams.get('v') || '0';
|
||||
const aVersion = new URL(a.url).searchParams.get("v") || "0";
|
||||
const bVersion = new URL(b.url).searchParams.get("v") || "0";
|
||||
return Number(bVersion) - Number(aVersion);
|
||||
});
|
||||
});
|
||||
@@ -363,13 +368,13 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
if ("serviceWorker" in navigator && "caches" in window) {
|
||||
const cacheNames = await caches.keys();
|
||||
await Promise.all(cacheNames.map((cacheName) => caches.delete(cacheName)));
|
||||
|
||||
|
||||
// Forcer la mise à jour du service worker
|
||||
const registrations = await navigator.serviceWorker.getRegistrations();
|
||||
for (const registration of registrations) {
|
||||
await registration.unregister();
|
||||
}
|
||||
|
||||
|
||||
toast({
|
||||
title: t("settings.cache.title"),
|
||||
description: t("settings.cache.messages.serviceWorkerCleared"),
|
||||
@@ -383,7 +388,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
if (showSwEntries) {
|
||||
await fetchSwCacheEntries();
|
||||
}
|
||||
|
||||
|
||||
// Recharger la page après 1 seconde pour réenregistrer le SW
|
||||
setTimeout(() => {
|
||||
window.location.reload();
|
||||
@@ -458,7 +463,6 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
<CardDescription>{t("settings.cache.description")}</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-4">
|
||||
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<div className="space-y-0.5">
|
||||
<Label htmlFor="cache-mode">{t("settings.cache.mode.label")}</Label>
|
||||
@@ -488,7 +492,9 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground">{t("settings.cache.size.error")}</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{t("settings.cache.size.error")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -497,7 +503,9 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
{swCacheSize !== null ? (
|
||||
<div className="text-sm text-muted-foreground">{formatBytes(swCacheSize)}</div>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground">{t("settings.cache.size.error")}</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{t("settings.cache.size.error")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@@ -506,7 +514,9 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
{apiCacheSize !== null ? (
|
||||
<div className="text-sm text-muted-foreground">{formatBytes(apiCacheSize)}</div>
|
||||
) : (
|
||||
<div className="text-sm text-muted-foreground">{t("settings.cache.size.error")}</div>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{t("settings.cache.size.error")}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
@@ -525,11 +535,7 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
<List className="h-4 w-4" />
|
||||
{t("settings.cache.entries.serverTitle")}
|
||||
</span>
|
||||
{showEntries ? (
|
||||
<ChevronUp className="h-4 w-4" />
|
||||
) : (
|
||||
<ChevronDown className="h-4 w-4" />
|
||||
)}
|
||||
{showEntries ? <ChevronUp className="h-4 w-4" /> : <ChevronDown className="h-4 w-4" />}
|
||||
</Button>
|
||||
|
||||
{showEntries && (
|
||||
@@ -569,7 +575,10 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
>
|
||||
{getTimeRemaining(entry.expiry)}
|
||||
</div>
|
||||
<div className="text-muted-foreground/70" title={formatDate(entry.expiry)}>
|
||||
<div
|
||||
className="text-muted-foreground/70"
|
||||
title={formatDate(entry.expiry)}
|
||||
>
|
||||
{new Date(entry.expiry).toLocaleDateString()}
|
||||
</div>
|
||||
</div>
|
||||
@@ -649,72 +658,90 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
<div className="space-y-1 pl-2">
|
||||
{(() => {
|
||||
const versionGroups = groupVersions(entries);
|
||||
return Object.entries(versionGroups).map(([baseUrl, versions]) => {
|
||||
const hasMultipleVersions = versions.length > 1;
|
||||
const isVersionExpanded = expandedVersions[baseUrl];
|
||||
const totalSize = versions.reduce((sum, v) => sum + v.size, 0);
|
||||
return Object.entries(versionGroups).map(
|
||||
([baseUrl, versions]) => {
|
||||
const hasMultipleVersions = versions.length > 1;
|
||||
const isVersionExpanded = expandedVersions[baseUrl];
|
||||
const totalSize = versions.reduce(
|
||||
(sum, v) => sum + v.size,
|
||||
0
|
||||
);
|
||||
|
||||
if (!hasMultipleVersions) {
|
||||
const entry = versions[0];
|
||||
return (
|
||||
<div key={baseUrl} className="py-1">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-mono text-xs truncate text-muted-foreground" title={entry.url}>
|
||||
{entry.url.replace(/^https?:\/\/[^/]+/, "")}
|
||||
if (!hasMultipleVersions) {
|
||||
const entry = versions[0];
|
||||
return (
|
||||
<div key={baseUrl} className="py-1">
|
||||
<div className="flex items-start justify-between gap-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div
|
||||
className="font-mono text-xs truncate text-muted-foreground"
|
||||
title={entry.url}
|
||||
>
|
||||
{entry.url.replace(/^https?:\/\/[^/]+/, "")}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground whitespace-nowrap">
|
||||
{formatBytes(entry.size)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground whitespace-nowrap">
|
||||
{formatBytes(entry.size)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={baseUrl} className="py-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleVersions(baseUrl)}
|
||||
className="w-full flex items-start justify-between gap-2 hover:bg-muted/30 rounded p-1 -m-1 transition-colors"
|
||||
>
|
||||
<div className="flex-1 min-w-0 flex items-center gap-1">
|
||||
{isVersionExpanded ? (
|
||||
<ChevronDown className="h-3 w-3 flex-shrink-0" />
|
||||
) : (
|
||||
<ChevronUp className="h-3 w-3 flex-shrink-0" />
|
||||
)}
|
||||
<div
|
||||
className="font-mono text-xs truncate text-muted-foreground"
|
||||
title={baseUrl}
|
||||
>
|
||||
{baseUrl}
|
||||
</div>
|
||||
<span className="inline-flex items-center rounded-full bg-orange-500/10 px-1.5 py-0.5 text-xs font-medium text-orange-600 dark:text-orange-400 flex-shrink-0">
|
||||
{versions.length} versions
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground whitespace-nowrap font-medium">
|
||||
{formatBytes(totalSize)}
|
||||
</div>
|
||||
</button>
|
||||
{isVersionExpanded && (
|
||||
<div className="pl-4 mt-1 space-y-1">
|
||||
{versions.map((version, vIdx) => (
|
||||
<div
|
||||
key={vIdx}
|
||||
className="py-0.5 flex items-start justify-between gap-2"
|
||||
>
|
||||
<div className="flex-1 min-w-0">
|
||||
<div
|
||||
className="font-mono text-xs truncate text-muted-foreground/70"
|
||||
title={version.url}
|
||||
>
|
||||
{new URL(version.url).search ||
|
||||
"(no version)"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground/70 whitespace-nowrap">
|
||||
{formatBytes(version.size)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={baseUrl} className="py-1">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleVersions(baseUrl)}
|
||||
className="w-full flex items-start justify-between gap-2 hover:bg-muted/30 rounded p-1 -m-1 transition-colors"
|
||||
>
|
||||
<div className="flex-1 min-w-0 flex items-center gap-1">
|
||||
{isVersionExpanded ? (
|
||||
<ChevronDown className="h-3 w-3 flex-shrink-0" />
|
||||
) : (
|
||||
<ChevronUp className="h-3 w-3 flex-shrink-0" />
|
||||
)}
|
||||
<div className="font-mono text-xs truncate text-muted-foreground" title={baseUrl}>
|
||||
{baseUrl}
|
||||
</div>
|
||||
<span className="inline-flex items-center rounded-full bg-orange-500/10 px-1.5 py-0.5 text-xs font-medium text-orange-600 dark:text-orange-400 flex-shrink-0">
|
||||
{versions.length} versions
|
||||
</span>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground whitespace-nowrap font-medium">
|
||||
{formatBytes(totalSize)}
|
||||
</div>
|
||||
</button>
|
||||
{isVersionExpanded && (
|
||||
<div className="pl-4 mt-1 space-y-1">
|
||||
{versions.map((version, vIdx) => (
|
||||
<div key={vIdx} className="py-0.5 flex items-start justify-between gap-2">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="font-mono text-xs truncate text-muted-foreground/70" title={version.url}>
|
||||
{new URL(version.url).search || "(no version)"}
|
||||
</div>
|
||||
</div>
|
||||
<div className="text-xs text-muted-foreground/70 whitespace-nowrap">
|
||||
{formatBytes(version.size)}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
);
|
||||
})()}
|
||||
</div>
|
||||
)}
|
||||
@@ -833,12 +860,24 @@ export function CacheSettings({ initialTTLConfig }: CacheSettingsProps) {
|
||||
onChange={handleTTLChange}
|
||||
className="flex h-9 w-full rounded-md border border-input bg-background/70 backdrop-blur-md px-3 py-1 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
>
|
||||
<option value="0">{t("settings.cache.ttl.imageCacheMaxAge.options.noCache")}</option>
|
||||
<option value="3600">{t("settings.cache.ttl.imageCacheMaxAge.options.oneHour")}</option>
|
||||
<option value="86400">{t("settings.cache.ttl.imageCacheMaxAge.options.oneDay")}</option>
|
||||
<option value="604800">{t("settings.cache.ttl.imageCacheMaxAge.options.oneWeek")}</option>
|
||||
<option value="2592000">{t("settings.cache.ttl.imageCacheMaxAge.options.oneMonth")}</option>
|
||||
<option value="31536000">{t("settings.cache.ttl.imageCacheMaxAge.options.oneYear")}</option>
|
||||
<option value="0">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.noCache")}
|
||||
</option>
|
||||
<option value="3600">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.oneHour")}
|
||||
</option>
|
||||
<option value="86400">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.oneDay")}
|
||||
</option>
|
||||
<option value="604800">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.oneWeek")}
|
||||
</option>
|
||||
<option value="2592000">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.oneMonth")}
|
||||
</option>
|
||||
<option value="31536000">
|
||||
{t("settings.cache.ttl.imageCacheMaxAge.options.oneYear")}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user