76 lines
3.0 KiB
TypeScript
76 lines
3.0 KiB
TypeScript
import type { Metadata } from "next";
|
|
import { GeistSans } from "geist/font/sans";
|
|
import { GeistMono } from "geist/font/mono";
|
|
import "./globals.css";
|
|
import { TopNav } from "@/components/shell/TopNav";
|
|
import path from "node:path";
|
|
import { SelectionProvider } from "@/components/select/SelectionProvider";
|
|
import { SelectionBar } from "@/components/select/SelectionBar";
|
|
import { UndoDeleteToastProvider } from "@/components/select/UndoDeleteToast";
|
|
import { SettingsProvider } from "@/components/settings/SettingsProvider";
|
|
import { SettingsPanelProvider } from "@/components/settings/SettingsPanelProvider";
|
|
import { SettingsPanel } from "@/components/settings/SettingsPanel";
|
|
import { TrashPanelProvider } from "@/components/trash/TrashPanelProvider";
|
|
import { TrashPanel } from "@/components/trash/TrashPanel";
|
|
import { WatchQueueProvider } from "@/components/queue/WatchQueueProvider";
|
|
import { QueuePanelProvider } from "@/components/queue/QueuePanelProvider";
|
|
import { QueuePanel } from "@/components/queue/QueuePanel";
|
|
import { VideoIndexProvider } from "@/components/video/VideoIndexProvider";
|
|
import { getAllAppSettings } from "@/lib/db/appSettings";
|
|
import { libraryStats, listTrashedImages } from "@/lib/db/queries";
|
|
import { BRAND } from "@/lib/brand";
|
|
|
|
export const metadata: Metadata = {
|
|
title: BRAND.name,
|
|
description: BRAND.description,
|
|
};
|
|
|
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
const settings = getAllAppSettings();
|
|
const stats = libraryStats();
|
|
const panelData = {
|
|
defaultSort: settings.defaultSort,
|
|
stats,
|
|
libraryRoot: path.join(process.cwd(), "library"),
|
|
dbPath: path.join(process.cwd(), "data", "library.db"),
|
|
};
|
|
const trashData = {
|
|
images: listTrashedImages(),
|
|
retentionDays: settings.trashRetentionDays,
|
|
};
|
|
return (
|
|
<html
|
|
lang="en"
|
|
className={`${GeistSans.variable} ${GeistMono.variable}`}
|
|
data-fade={settings.fadeTransitions ? "on" : "off"}
|
|
style={{ "--fade-duration": `${settings.fadeDurationMs}ms` } as React.CSSProperties}
|
|
>
|
|
<body className="min-h-screen relative">
|
|
<div className="grid-noise fixed inset-0 -z-10" aria-hidden />
|
|
<SettingsProvider initial={settings}>
|
|
<SettingsPanelProvider>
|
|
<TrashPanelProvider>
|
|
<UndoDeleteToastProvider>
|
|
<SelectionProvider>
|
|
<WatchQueueProvider>
|
|
<QueuePanelProvider>
|
|
<VideoIndexProvider>
|
|
<TopNav />
|
|
<main className="relative pb-6">{children}</main>
|
|
<SelectionBar />
|
|
<SettingsPanel data={panelData} />
|
|
<TrashPanel data={trashData} />
|
|
<QueuePanel />
|
|
</VideoIndexProvider>
|
|
</QueuePanelProvider>
|
|
</WatchQueueProvider>
|
|
</SelectionProvider>
|
|
</UndoDeleteToastProvider>
|
|
</TrashPanelProvider>
|
|
</SettingsPanelProvider>
|
|
</SettingsProvider>
|
|
</body>
|
|
</html>
|
|
);
|
|
}
|