Let the server set the theme based on the cookie sent at request time, which should stop flashing
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
|
import { cookies } from "next/headers";
|
||||||
import "@/scss/nbn.scss";
|
import "@/scss/nbn.scss";
|
||||||
import NavbarClient from "@/components/Navbar";
|
import NavbarClient from "@/components/Navbar";
|
||||||
|
|
||||||
@@ -9,25 +10,35 @@ export const metadata: Metadata = {
|
|||||||
formatDetection: { email: false, address: false, telephone: false },
|
formatDetection: { email: false, address: false, telephone: false },
|
||||||
};
|
};
|
||||||
|
|
||||||
const noFlashThemeScript = `
|
function themeInitScript() {
|
||||||
(function() {
|
return `(function(){
|
||||||
try {
|
try {
|
||||||
var cookieMatch = document.cookie.match(/(?:^|; )theme=([^;]+)/);
|
var cookie = document.cookie.split('; ').find(function(c){return c.indexOf('NBN-theme=')===0});
|
||||||
var stored = cookieMatch ? decodeURIComponent(cookieMatch[1]) : null;
|
var value = cookie ? decodeURIComponent(cookie.split('=').slice(1).join('=')) : null;
|
||||||
|
var theme;
|
||||||
|
if (value === 'light' || value === 'dark') {
|
||||||
|
theme = value;
|
||||||
|
} else {
|
||||||
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
var prefersDark = window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||||
var effective = (stored === 'light' || stored === 'dark') ? stored : (prefersDark ? 'dark' : 'light');
|
theme = prefersDark ? 'dark' : 'light';
|
||||||
var el = document.documentElement;
|
}
|
||||||
if (el.getAttribute('data-bs-theme') !== effective) {
|
var html = document.documentElement;
|
||||||
el.setAttribute('data-bs-theme', effective);
|
if (html.getAttribute('data-bs-theme') !== theme) {
|
||||||
|
html.setAttribute('data-bs-theme', theme);
|
||||||
}
|
}
|
||||||
} catch(_) {}
|
} catch(_) {}
|
||||||
})();`;
|
})();`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
const cookieStore = await cookies();
|
||||||
|
const stored = cookieStore.get("NBN-theme")?.value;
|
||||||
|
const serverTheme = stored === "light" || stored === "dark" ? stored : "light";
|
||||||
|
|
||||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" data-bs-theme={serverTheme}>
|
||||||
<head>
|
<head>
|
||||||
<script dangerouslySetInnerHTML={{ __html: noFlashThemeScript }} />
|
<script dangerouslySetInnerHTML={{ __html: themeInitScript() }} />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<NavbarClient />
|
<NavbarClient />
|
||||||
|
|||||||
@@ -25,13 +25,13 @@ export default function ThemeDropdown() {
|
|||||||
|
|
||||||
const apply = useCallback((t: Theme) => {
|
const apply = useCallback((t: Theme) => {
|
||||||
const effective = t === "auto" ? (prefersDark() ? "dark" : "light") : t;
|
const effective = t === "auto" ? (prefersDark() ? "dark" : "light") : t;
|
||||||
|
|
||||||
document.documentElement.setAttribute("data-bs-theme", effective);
|
document.documentElement.setAttribute("data-bs-theme", effective);
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setMounted(true);
|
setMounted(true);
|
||||||
const v = getCookie(COOKIE);
|
const v = getCookie(COOKIE);
|
||||||
console.log("Cookie:", v);
|
|
||||||
const initial: Theme = v === "light" || v === "dark" || v === "auto" ? (v as Theme) : "auto";
|
const initial: Theme = v === "light" || v === "dark" || v === "auto" ? (v as Theme) : "auto";
|
||||||
setTheme(initial);
|
setTheme(initial);
|
||||||
// Important: apply immediately so “auto” reflects system after hydration
|
// Important: apply immediately so “auto” reflects system after hydration
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ export const parseDescriptionDefault = (reg: Register, description: string) => {
|
|||||||
// });
|
// });
|
||||||
} else if (trimmedLine.startsWith('*')) {
|
} else if (trimmedLine.startsWith('*')) {
|
||||||
const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/);
|
const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/);
|
||||||
console.log("NOTE MATCH",noteMatch);
|
|
||||||
if (noteMatch) {
|
if (noteMatch) {
|
||||||
accessData.notes.push({
|
accessData.notes.push({
|
||||||
ref: noteMatch[1],
|
ref: noteMatch[1],
|
||||||
@@ -89,8 +88,6 @@ export const parseDescriptionDefault = (reg: Register, description: string) => {
|
|||||||
reg.text += `${line}\n`;
|
reg.text += `${line}\n`;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// console.log("LINE",line);
|
|
||||||
console.log(line.match(/^\s+/), line);
|
|
||||||
if (line.match(/^\s+/) && accessData.operations.length > 0) {
|
if (line.match(/^\s+/) && accessData.operations.length > 0) {
|
||||||
accessData.operations[accessData.operations.length - 1].description += `\n${line}`;
|
accessData.operations[accessData.operations.length - 1].description += `\n${line}`;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ export const parseDescriptionF0 = (reg: Register, description: string) => {
|
|||||||
|
|
||||||
if(spaces_at_start == 2) {
|
if(spaces_at_start == 2) {
|
||||||
if (trimmedLine.startsWith('*')) {
|
if (trimmedLine.startsWith('*')) {
|
||||||
console.log("PARENT",trimmedLine);
|
|
||||||
const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/);
|
const noteMatch = trimmedLine.match(/^(\*+)\s*(.*)/);
|
||||||
if (noteMatch) {
|
if (noteMatch) {
|
||||||
reg.notes.push({
|
reg.notes.push({
|
||||||
@@ -88,7 +87,6 @@ export const parseDescriptionF0 = (reg: Register, description: string) => {
|
|||||||
const footnoteMatch = bitDescription.match(/(\*+)$/);
|
const footnoteMatch = bitDescription.match(/(\*+)$/);
|
||||||
let footnoteRef: string | undefined = undefined;
|
let footnoteRef: string | undefined = undefined;
|
||||||
if (footnoteMatch) {
|
if (footnoteMatch) {
|
||||||
console.log("FOOTNOTE",footnoteMatch);
|
|
||||||
footnoteRef = footnoteMatch[1];
|
footnoteRef = footnoteMatch[1];
|
||||||
bitDescription = bitDescription.substring(0, bitDescription.length - footnoteRef.length).trim();
|
bitDescription = bitDescription.substring(0, bitDescription.length - footnoteRef.length).trim();
|
||||||
}
|
}
|
||||||
@@ -112,7 +110,6 @@ export const parseDescriptionF0 = (reg: Register, description: string) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (trimmedLine) {
|
} else if (trimmedLine) {
|
||||||
console.log("LINE", trimmedLine);
|
|
||||||
if (line.match(/^\s+/) && accessData.operations.length > 0) {
|
if (line.match(/^\s+/) && accessData.operations.length > 0) {
|
||||||
accessData.operations[accessData.operations.length - 1].description += `\n${line}`;
|
accessData.operations[accessData.operations.length - 1].description += `\n${line}`;
|
||||||
} else {
|
} else {
|
||||||
@@ -125,7 +122,6 @@ export const parseDescriptionF0 = (reg: Register, description: string) => {
|
|||||||
}
|
}
|
||||||
if (currentAccess) {
|
if (currentAccess) {
|
||||||
detail[currentAccess] = accessData;
|
detail[currentAccess] = accessData;
|
||||||
console.log("FINAL",detail,currentAccess);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Push the parsed detail into modes
|
// Push the parsed detail into modes
|
||||||
|
|||||||
Reference in New Issue
Block a user