import type { Metadata } from "next"; import { Inter } from "next/font/google"; import "@/styles/globals.css"; import { cn } from "@/lib/utils"; import ClientLayout from "@/components/layout/ClientLayout"; import { PreferencesService } from "@/lib/services/preferences.service"; import { PreferencesProvider } from "@/contexts/PreferencesContext"; import { I18nProvider } from "@/components/providers/I18nProvider"; import { AuthProvider } from "@/components/providers/AuthProvider"; import { cookies, headers } from "next/headers"; import { defaultPreferences } from "@/types/preferences"; import type { UserPreferences } from "@/types/preferences"; import type { NormalizedLibrary, NormalizedSeries } from "@/lib/providers/types"; import logger from "@/lib/logger"; const inter = Inter({ subsets: ["latin"], display: "swap", adjustFontFallback: false, preload: false, }); export const metadata: Metadata = { title: { template: "%s - StripStream", default: "StripStream", }, description: "Votre bibliothèque numérique pour lire vos BD, mangas et comics préférés", manifest: "/manifest.json", keywords: ["comics", "manga", "bd", "reader", "komga", "stripstream"], authors: [{ name: "Julien Froidefond" }], // colorScheme: "dark light", formatDetection: { telephone: false, }, icons: { icon: [ { url: "/favicon.png", type: "image/png", }, { url: "/images/icons/icon-72x72.png", sizes: "72x72", type: "image/png" }, { url: "/images/icons/icon-96x96.png", sizes: "96x96", type: "image/png" }, { url: "/images/icons/icon-128x128.png", sizes: "128x128", type: "image/png" }, { url: "/images/icons/icon-144x144.png", sizes: "144x144", type: "image/png" }, { url: "/images/icons/icon-152x152.png", sizes: "152x152", type: "image/png" }, { url: "/images/icons/icon-192x192.png", sizes: "192x192", type: "image/png" }, { url: "/images/icons/icon-384x384.png", sizes: "384x384", type: "image/png" }, { url: "/images/icons/icon-512x512.png", sizes: "512x512", type: "image/png" }, ], apple: [ { url: "/images/icons/apple-icon-180x180.png", sizes: "180x180", type: "image/png", }, { url: "/images/icons/apple-icon-167x167.png", sizes: "167x167", type: "image/png", }, { url: "/images/icons/apple-icon-152x152.png", sizes: "152x152", type: "image/png", }, ], }, }; export default async function RootLayout({ children }: { children: React.ReactNode }) { const cookieStore = await cookies(); const requestHeaders = await headers(); const locale = cookieStore.get("NEXT_LOCALE")?.value || "fr"; const requestPath = requestHeaders.get("x-request-path") || "unknown"; const requestPathname = requestHeaders.get("x-request-pathname") || "unknown"; let preferences: UserPreferences = defaultPreferences; let userIsAdmin = false; let libraries: NormalizedLibrary[] = []; let favorites: NormalizedSeries[] = []; try { const currentUser = await import("@/lib/auth-utils").then((m) => m.getCurrentUser()); if (currentUser) { const [preferencesData, librariesData, favoritesData] = await Promise.allSettled([ PreferencesService.getPreferences(), import("@/lib/providers/provider.factory") .then((m) => m.getProvider()) .then((provider) => provider?.getLibraries() ?? []), import("@/lib/services/favorites.service").then((m) => m.FavoritesService.getFavorites({ requestPath, requestPathname }) ), ]); userIsAdmin = currentUser.roles.includes("ROLE_ADMIN"); if (preferencesData.status === "fulfilled") { preferences = preferencesData.value; } if (librariesData.status === "fulfilled") { libraries = librariesData.value || []; } if (favoritesData.status === "fulfilled") { favorites = favoritesData.value; } } } catch (error) { logger.error( { err: error, requestPath, requestPathname }, "Erreur lors du chargement des données initiales:" ); } return ( {children} ); }