feat(notes): liens internes, onglet Réseau, living blocks et consentement IA
Rend les liens entre notes visibles et persistants (sync NoteLink au save, auto-save, graphe réseau rafraîchi), ajoute living blocks, Memory Echo, recherche globale, consentement IA explicite et consolide les prototypes design en architectural-grid. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -11,7 +11,7 @@ import { auth } from "@/auth";
|
||||
import { CookieConsentRoot } from "@/components/legal/cookie-consent-root";
|
||||
import { LanguageProvider } from "@/lib/i18n/LanguageProvider";
|
||||
import Script from "next/script";
|
||||
import { getThemeScript } from "@/lib/theme-script";
|
||||
import type { CSSProperties } from "react";
|
||||
import { normalizeThemeId } from "@/lib/apply-document-theme";
|
||||
|
||||
import { Inter, Manrope, Playfair_Display, JetBrains_Mono } from "next/font/google";
|
||||
@@ -68,27 +68,6 @@ function serverHtmlThemeState(theme?: string | null): { className?: string; data
|
||||
return {}
|
||||
}
|
||||
|
||||
/**
|
||||
* Inline script that runs BEFORE React hydrates.
|
||||
* Reads the user's saved language from localStorage and sets
|
||||
* `dir` on <html> immediately — prevents RTL/LTR flash.
|
||||
*/
|
||||
const directionScript = `
|
||||
(function(){
|
||||
try {
|
||||
var lang = localStorage.getItem('user-language');
|
||||
if (!lang) {
|
||||
var c = document.cookie.split(';').map(function(s){return s.trim()}).find(function(s){return s.startsWith('user-language=')});
|
||||
if (c) lang = c.split('=')[1];
|
||||
}
|
||||
if (lang === 'fa' || lang === 'ar') {
|
||||
document.documentElement.dir = 'rtl';
|
||||
document.documentElement.lang = lang;
|
||||
}
|
||||
} catch(e) {}
|
||||
})();
|
||||
`;
|
||||
|
||||
export default async function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
@@ -103,25 +82,25 @@ export default async function RootLayout({
|
||||
])
|
||||
|
||||
const htmlTheme = serverHtmlThemeState(userSettings.theme)
|
||||
const serverAccent = userSettings.accentColor ?? '#A47148'
|
||||
const serverTheme = normalizeThemeId(userSettings.theme || 'light')
|
||||
const htmlStyle = {
|
||||
'--color-brand-accent': serverAccent,
|
||||
} as CSSProperties
|
||||
|
||||
return (
|
||||
<html
|
||||
suppressHydrationWarning
|
||||
className={htmlTheme.className}
|
||||
data-theme={htmlTheme.dataTheme}
|
||||
data-server-theme={serverTheme}
|
||||
data-server-accent={serverAccent}
|
||||
style={htmlStyle}
|
||||
>
|
||||
<head />
|
||||
<body className={`${inter.className} ${inter.variable} ${manrope.variable} ${playfair.variable} ${jetbrainsMono.variable}`}>
|
||||
<Script
|
||||
id="theme-init"
|
||||
strategy="beforeInteractive"
|
||||
dangerouslySetInnerHTML={{ __html: getThemeScript(userSettings.theme, userSettings.accentColor) }}
|
||||
/>
|
||||
<Script
|
||||
id="sw-cleanup"
|
||||
strategy="afterInteractive"
|
||||
dangerouslySetInnerHTML={{ __html: `if('serviceWorker' in navigator){navigator.serviceWorker.getRegistrations().then(function(rs){rs.forEach(function(r){r.unregister()})})}` }}
|
||||
/>
|
||||
<Script id="theme-init" src="/scripts/theme-init.js" strategy="beforeInteractive" />
|
||||
<Script id="direction-init" src="/scripts/direction-init.js" strategy="beforeInteractive" />
|
||||
<Script id="sw-cleanup" src="/scripts/sw-cleanup.js" strategy="afterInteractive" />
|
||||
<SessionProviderWrapper>
|
||||
<ErrorReporter />
|
||||
<DirectionInitializer />
|
||||
|
||||
Reference in New Issue
Block a user