Compare commits

..

2 Commits

Author SHA1 Message Date
8e7c46de23 refactor: unify and enrich default app background styling
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m56s
2026-02-28 22:07:29 +01:00
dc9f90f78f fix: preserve custom backgrounds and home fallback layering 2026-02-28 22:05:07 +01:00
4 changed files with 26 additions and 12 deletions

View File

@@ -44,9 +44,6 @@ export function HomeClientWrapper({ children }: HomeClientWrapperProps) {
isHiding={pullToRefresh.isHiding} isHiding={pullToRefresh.isHiding}
/> />
<main className="relative isolate overflow-hidden"> <main className="relative isolate overflow-hidden">
<div className="pointer-events-none absolute inset-0 -z-10 bg-[linear-gradient(180deg,hsl(var(--background)/0.99)_0%,hsl(var(--background)/0.95)_28%,hsl(var(--background))_100%)]" />
<div className="pointer-events-none absolute inset-0 -z-10 bg-[linear-gradient(128deg,hsl(var(--primary)/0.14)_0%,transparent_36%),linear-gradient(235deg,hsl(185_82%_54%/0.1)_4%,transparent_34%),linear-gradient(320deg,hsl(332_82%_63%/0.08)_8%,transparent_32%)]" />
<div className="container mx-auto space-y-12 px-4 py-8"> <div className="container mx-auto space-y-12 px-4 py-8">
<div className="flex justify-end"> <div className="flex justify-end">
<RefreshButton libraryId="home" refreshLibrary={handleRefresh} /> <RefreshButton libraryId="home" refreshLibrary={handleRefresh} />

View File

@@ -11,6 +11,7 @@ import { NetworkStatus } from "../ui/NetworkStatus";
import { usePreferences } from "@/contexts/PreferencesContext"; import { usePreferences } from "@/contexts/PreferencesContext";
import { ServiceWorkerProvider } from "@/contexts/ServiceWorkerContext"; import { ServiceWorkerProvider } from "@/contexts/ServiceWorkerContext";
import type { KomgaLibrary, KomgaSeries } from "@/types/komga"; import type { KomgaLibrary, KomgaSeries } from "@/types/komga";
import { defaultPreferences } from "@/types/preferences";
import logger from "@/lib/logger"; import logger from "@/lib/logger";
import { getRandomBookFromLibraries } from "@/app/actions/library"; import { getRandomBookFromLibraries } from "@/app/actions/library";
@@ -141,19 +142,24 @@ export default function ClientLayout({
// Ne pas afficher le header et la sidebar sur les routes publiques et le reader // Ne pas afficher le header et la sidebar sur les routes publiques et le reader
const isPublicRoute = publicRoutes.includes(pathname) || pathname.startsWith("/books/"); const isPublicRoute = publicRoutes.includes(pathname) || pathname.startsWith("/books/");
const hasCustomBackground = const hasCustomBackground = Object.keys(backgroundStyle).length > 0;
preferences.background.type === "gradient" || const contentOpacity =
preferences.background.type === "image" || (preferences.background.opacity ?? defaultPreferences.background.opacity ?? 10) / 100;
(preferences.background.type === "komga-random" && randomBookId);
const contentOpacity = (preferences.background.opacity || 100) / 100;
return ( return (
<ThemeProvider attribute="class" defaultTheme="system" enableSystem> <ThemeProvider attribute="class" defaultTheme="system" enableSystem>
<ServiceWorkerProvider> <ServiceWorkerProvider>
{/* Background fixe pour les images et gradients */} {/* Background fixe pour les images et gradients */}
{hasCustomBackground && <div className="fixed inset-0 -z-10" style={backgroundStyle} />} {hasCustomBackground && <div className="fixed inset-0 -z-10" style={backgroundStyle} />}
{!hasCustomBackground && (
<>
<div className="pointer-events-none fixed inset-0 -z-10 bg-[linear-gradient(180deg,hsl(var(--background)/0.99)_0%,hsl(var(--background)/0.94)_42%,hsl(var(--background))_100%)]" />
<div className="pointer-events-none fixed inset-0 -z-10 bg-[radial-gradient(70%_45%_at_12%_0%,hsl(var(--primary)/0.16),transparent_62%),radial-gradient(58%_38%_at_88%_8%,hsl(190_86%_56%/0.14),transparent_65%),radial-gradient(50%_34%_at_50%_100%,hsl(334_72%_62%/0.1),transparent_70%)]" />
<div className="pointer-events-none fixed inset-0 -z-10 bg-[repeating-linear-gradient(0deg,hsl(var(--foreground)/0.02)_0_1px,transparent_1px_24px),repeating-linear-gradient(90deg,hsl(var(--foreground)/0.015)_0_1px,transparent_1px_30px)]" />
</>
)}
<div <div
className={`relative min-h-screen ${hasCustomBackground ? "" : "bg-background"}`} className="relative min-h-screen"
style={ style={
hasCustomBackground hasCustomBackground
? { backgroundColor: `rgba(var(--background-rgb, 255, 255, 255), ${contentOpacity})` } ? { backgroundColor: `rgba(var(--background-rgb, 255, 255, 255), ${contentOpacity})` }

View File

@@ -66,6 +66,7 @@ export function BackgroundSettings({ initialLibraries }: BackgroundSettingsProps
try { try {
await updatePreferences({ await updatePreferences({
background: { background: {
...preferences.background,
type: "gradient", type: "gradient",
gradient, gradient,
}, },
@@ -97,6 +98,7 @@ export function BackgroundSettings({ initialLibraries }: BackgroundSettingsProps
try { try {
await updatePreferences({ await updatePreferences({
background: { background: {
...preferences.background,
type: "image", type: "image",
imageUrl: customImageUrl, imageUrl: customImageUrl,
}, },

View File

@@ -39,7 +39,10 @@ export class PreferencesService {
...displayMode, ...displayMode,
viewMode: displayMode?.viewMode || defaultPreferences.displayMode.viewMode, viewMode: displayMode?.viewMode || defaultPreferences.displayMode.viewMode,
}, },
background: preferences.background as unknown as BackgroundPreferences, background: {
...defaultPreferences.background,
...(preferences.background as unknown as BackgroundPreferences),
},
readerPrefetchCount: preferences.readerPrefetchCount, readerPrefetchCount: preferences.readerPrefetchCount,
}; };
} catch (error) { } catch (error) {
@@ -62,7 +65,10 @@ export class PreferencesService {
updateData.showOnlyUnread = preferences.showOnlyUnread; updateData.showOnlyUnread = preferences.showOnlyUnread;
if (preferences.displayMode !== undefined) updateData.displayMode = preferences.displayMode; if (preferences.displayMode !== undefined) updateData.displayMode = preferences.displayMode;
if (preferences.background !== undefined) { if (preferences.background !== undefined) {
updateData.background = preferences.background as unknown as Prisma.InputJsonValue; updateData.background = {
...defaultPreferences.background,
...(preferences.background as unknown as BackgroundPreferences),
} as unknown as Prisma.InputJsonValue;
} }
if (preferences.readerPrefetchCount !== undefined) if (preferences.readerPrefetchCount !== undefined)
updateData.readerPrefetchCount = preferences.readerPrefetchCount; updateData.readerPrefetchCount = preferences.readerPrefetchCount;
@@ -85,7 +91,10 @@ export class PreferencesService {
showThumbnails: updatedPreferences.showThumbnails, showThumbnails: updatedPreferences.showThumbnails,
showOnlyUnread: updatedPreferences.showOnlyUnread, showOnlyUnread: updatedPreferences.showOnlyUnread,
displayMode: updatedPreferences.displayMode as UserPreferences["displayMode"], displayMode: updatedPreferences.displayMode as UserPreferences["displayMode"],
background: updatedPreferences.background as unknown as BackgroundPreferences, background: {
...defaultPreferences.background,
...(updatedPreferences.background as unknown as BackgroundPreferences),
},
readerPrefetchCount: updatedPreferences.readerPrefetchCount, readerPrefetchCount: updatedPreferences.readerPrefetchCount,
}; };
} catch (error) { } catch (error) {